AddCSLuaFile( "cl_init.lua" ) AddCSLuaFile( "shared.lua" ) include('shared.lua') ENT.Alerted = false ENT.bleeds = 1 ENT.Grenades = 2 ENT.StartHealth = 125 ENT.PlayerFriendly = 1 ENT.AttackingMelee = false ENT.Commander = false ENT.LookedForCover = false ENT.hurtsound1 = "" ENT.hurtsound2 = "" ENT.alert1 = "tau/tau_alert1.wav" ENT.alert2 = "tau/tau_alert2.wav" ENT.alert3 = "tau/tau_alert3.wav" ENT.alert4 = "tau/tau_alert3.wav" ENT.idle1 = "tau/tau_idle1.wav" ENT.idle2 = "tau/tau_idle2.wav" ENT.idle3 = "tau/tau_idle3.wav" ENT.idle4 = "tau/tau_idle1.wav" ENT.idle5 = "tau/tau_idle2.wav" ENT.idle6 = "tau/tau_idle3.wav" ENT.attack1 = "tau/tau_attack1.wav" ENT.attack2 = "tau/tau_attack2.wav" ENT.attack3 = "tau/tau_movingout.wav" ENT.attack4 = "tau/tau_attack1.wav" ENT.attack5 = "tau/tau_takeit.wav" ENT.die1 = "tau/tau_die1.wav" ENT.die2 = "tau/tau_die2.wav" ENT.seen_grenade = true ENT.TakingCover = false ENT.FindingLOS = false ENT.CanSeeEnemy = false ENT.TimeToTakeCover = 0 ENT.OutOfAmmo = false ENT.GotACloseOne = false ENT.dead = false ENT.squad = NULL ENT.speaktime = 0 function ENT:Initialize() if self:GetActiveWeapon() == nil then self:GetOwner():PrintMessage( HUD_PRINTNOTIFY, "This entity needs a weapon!" ) self:Give("weapon_smg1") end self:SetModel( "models/tau/tau_firewarrior.mdl" ) self:SetHullType( HULL_HUMAN ) self:SetHullSizeNormal(); self:SetSolid( SOLID_BBOX ) self:SetMoveType( MOVETYPE_STEP ) self:CapabilitiesAdd( CAP_MOVE_GROUND | CAP_OPEN_DOORS | CAP_ANIMATEDFACE | CAP_SQUAD | CAP_USE_WEAPONS | CAP_DUCK | CAP_MOVE_SHOOT | CAP_TURN_HEAD | CAP_USE_SHOT_REGULATOR | CAP_AIM_GUN ) self:SetMaxYawSpeed( 5000 ) //self:Give("cse_mp5_fear") self.Friends = {"monster_replica"} self.Monsters = {"npc_antlion", "npc_antlion_worker", "npc_antlionguard", "npc_stalker", "monster_alien_controller", "monster_alien_grunt", "monster_alien_slave", "npc_headcrab", "npc_headcrab_black", "npc_headcrab_poison", "npc_headcrab_fast", "monster_babycrab", "monster_headcrab", "monster_bigmomma", "npc_hunter", "npc_rollermine", "npc_clawscanner", "npc_cscanner", "npc_manhack", "npc_fastzombie_torso", "npc_fastzombie", "npc_poisonzombie", "npc_zombie", "npc_zombie_torso", "npc_zombine", "monster_zombie", "npc_vortigaunt", "monster_bullchicken", "monster_gargantua", "monster_houndeye", "monster_ichthyosaur", "monster_archer", "monster_panthereye", "monster_snark", "monster_parasite","npc_xenomorph","npc_facehugger", "npc_st_insect", "npc_dan_zombie", "npc_raptor"} self.Scary_Things = { "npc_combinedropship", "npc_combinegunship", "npc_helicopter", "npc_strider", "npc_sniper" } //self:Give("cse_mp5_fear") //Sets the entity values self:SetHealth(self.StartHealth) self:Fire("setsquad","TauSquad1",0) self:SetEnemy(NULL) end function ENT:OnTakeDamage(dmg) //if (self.TakingCover == false) then // self:SetSchedule(SCHED_SMALL_FLINCH) //end self:SpawnBlood(dmg) self:SetHealth(self:Health() - dmg:GetDamage()) //if math.random(4) == 1 then if math.random(4) == 1 then print("Got Hurt!!!") self:StopSpeechSounds() local sound_seed = math.random(1,7) if sound_seed == 1 then self:EmitSound( self.hurtsound1, 400, 100) elseif sound_seed == 2 then self:EmitSound( self.hurtsound2, 400, 100) end //self:SetSchedule(SCHED_ALERT_FACE) end if dmg:GetAttacker():GetClass() != self:GetClass() && math.random(1,7) == 1 then self:ResetEnemy() self:AddEntityRelationship( dmg:GetAttacker(), 1, 10 ) self:SetEnemy(dmg:GetAttacker()) self:CallForHelp() end if ((self.TakingCover == false) || self.Alerted == false) && self.LookedForCover == false then self.TakingCover = true self.LookedForCover = true self:SetSchedule(SCHED_TAKE_COVER_FROM_ENEMY) end self.Alerted = true if self:Health() <= 0 && self.dead == false then //run on death self.dead = true; self:KilledDan() end end function ENT:Think() local function setmeleefalse() self.MeleeAttacking = false end local function Attack_Melee() local entstoattack = ents.FindInSphere(self:GetPos() + self:GetForward()*75,74) if entstoattack != nil then self:EmitSound( "physics/body/body_medium_impact_hard"..math.random(1,6)..".wav", 400, 100) for _,v in pairs(entstoattack) do if ( (v:IsNPC() || ( v:IsPlayer() && v:Alive())) && (v != self) || (v:GetClass() == "prop_physics")) then v:TakeDamage( 4, self ) v:SetVelocity(self:GetForward()*100) end end else self:EmitSound( "zombie/claw_miss1.wav", 400, 100) //add miss stuff here end timer.Create( "melee_done_timer" .. self.Entity:EntIndex( ), 0.25, 1, setmeleefalse ) end //print(self.TakingCover) if self:Health() > 0 then //print( "Think start" ); //Get all the npc's and other entities. local enttable = ents.FindByClass("npc_*") local monstertable = ents.FindByClass("monster_*") table.Add(monstertable,enttable)//merge //sort through each ent. for _, x in pairs(monstertable) do if (!ents) then print( "No Entities!" ); return end if (x:GetClass() != self:GetClass() && x:GetClass() != "npc_grenade_frag" && x:IsNPC()) then if x:GetClass() != "npc_tank" && x:GetClass() != "npc_tank_turrent" && x:GetClass() != "npc_citizen" && x:GetClass() != "npc_barney" && x:GetClass() != "npc_eli" && x:GetClass() != "npc_monk" && x:GetClass() != "npc_alyx" && x:GetClass() != "npc_mossman" && x:GetClass() != "npc_vortigaunt" && x:GetClass() != "npc_dog" then x:AddEntityRelationship( self, 1, 10 ) else x:AddEntityRelationship( self, 3, 10 ) end end end //print( "Think end" ); //self:AddRelationship("player D_HT 10") if self.TakingCover == false then self:GetBoomers()//grenades are top priority. if(math.random(1,20) == 1) then self:FindCloseEnemies()//get guys close to me end end //Hit them. if self:GetEnemy() != nil then if (self:GetEnemy():GetPos():Distance(self:GetPos()) < 70) then if self.MeleeAttacking == false then self:SetSchedule( SCHED_MELEE_ATTACK1 ) timer.Create( "melee_attack_timer" .. self.Entity:EntIndex( ), 0.25, 1, Attack_Melee ) self.MeleeAttacking = true; end else self.MeleeAttacking = false end end local friends = ents.FindByClass("npc_tank") for _, x in pairs(friends) do x:AddEntityRelationship( self, 3, 10 ) end local friends = ents.FindByClass("npc_tank_turrent") for _, x in pairs(friends) do x:AddEntityRelationship( self, 3, 10 ) end local friends = ents.FindByClass("npc_citizen") for _, x in pairs(friends) do x:AddEntityRelationship( self, 3, 10 ) end local friends = ents.FindByClass("npc_eli") for _, x in pairs(friends) do x:AddEntityRelationship( self, 3, 10 ) end local friends = ents.FindByClass("npc_alyx") for _, x in pairs(friends) do x:AddEntityRelationship( self, 3, 10 ) end local friends = ents.FindByClass("npc_monk") for _, x in pairs(friends) do x:AddEntityRelationship( self, 3, 10 ) end local friends = ents.FindByClass("npc_barney") for _, x in pairs(friends) do x:AddEntityRelationship( self, 3, 10 ) end local friends = ents.FindByClass("npc_mossman") for _, x in pairs(friends) do x:AddEntityRelationship( self, 3, 10 ) end local friends = ents.FindByClass("npc_vortigaunt") for _, x in pairs(friends) do x:AddEntityRelationship( self, 3, 10 ) end local friends = ents.FindByClass("npc_dog") for _, x in pairs(friends) do x:AddEntityRelationship( self, 3, 10 ) end end print(self:GetEnemy()) print(self.TakingCover) end function ENT:SelectSchedule() if self:Health() > 0 then //makes it never run out of ammo... :D //self:GetActiveWeapon():SetClip1(45) local haslos = self:HasLOS() local distance = 0 local enemy_pos = 0 if self:GetEnemy() == nil then//no enemy self:FindEnemyDan() //print( "No Enemy!" ); self:SetSchedule(SCHED_COMBAT_PATROL)//patrol# self.TakingCover = false //play idle sounds every now and then local random_s = math.random(1,150) if random_s == 1 then self:StopSpeechSounds() self:EmitSound( self.idle1, 400, 100) elseif random_s == 2 then self:StopSpeechSounds() self:EmitSound( self.idle2, 400, 100) elseif random_s == 3 then self:StopSpeechSounds() self:EmitSound( self.idle3, 400, 100) elseif random_s == 4 then self:StopSpeechSounds() self:EmitSound( self.idle4, 400, 100) elseif random_s == 5 then self:StopSpeechSounds() self:EmitSound( self.idle5, 400, 100) elseif random_s == 6 then self:StopSpeechSounds() self:EmitSound( self.idle6, 400, 100) print( "Finished No Enemy!" ); end else //print( "Enemy!" ); //print(self:GetEnemy()) enemy_pos = self:GetEnemy():GetPos() distance = self:GetPos():Distance(enemy_pos) //distance = 4000 if distance > 2500 then//if too far away print( "Find him!" ); self:SetSchedule(SCHED_CHASE_ENEMY)//move to enemy elseif distance < 2500 && distance > 400 then//if in reasonable distance if self:Health() < (self.StartHealth*0.35) then//if damaged > 75% and not in cover if self.TakingCover == false then if self.TakenCover == true then self:SetSchedule(SCHED_COMBAT_STAND ) return end self.TakingCover = true self.TakenCover = true self:SetSchedule( SCHED_TAKE_COVER_FROM_ENEMY )//avoid melee attack end else self.TakingCover = false self.TakenCover = false if CurTime() > self.speaktime then self.speaktime = CurTime() + 6 local randomsound = math.random(1,6) if randomsound == 1 then self:StopSpeechSounds() self:EmitSound( self.attack1, 400, 100) elseif randomsound == 2 then self:StopSpeechSounds() self:EmitSound( self.attack2, 400, 100) elseif randomsound == 3 then self:StopSpeechSounds() self:EmitSound( self.attack3, 400, 100) elseif randomsound == 4 then self:StopSpeechSounds() self:EmitSound( self.attack4, 400, 100) elseif randomsound == 5 then self:StopSpeechSounds() self:EmitSound( self.attack5, 400, 100) elseif randomsound == 6 then self:StopSpeechSounds() self:EmitSound( self.attack6, 400, 100) end end if haslos then //&& distance > 1000 then self:SetSchedule(SCHED_COMBAT_STAND) else //if math.random(1,2) == 1 then self:SetSchedule(SCHED_ESTABLISH_LINE_OF_FIRE)//move to shoot enemy //else //self:SetSchedule(SCHED_CHASE_ENEMY)//otherwise go to them. //end end if math.random(1,80) < 3 then print("Reloading") self:SetSchedule(SCHED_RELOAD) //give the ILLUSION of reloading. :D end //self:SetSchedule(SCHED_RANGE_ATTACK1) end else//if too close if (haslos == true) then if self.TakingCover == false then self.TakingCover = true self:SetSchedule( SCHED_TAKE_COVER_FROM_ENEMY )//avoid melee attack else //self.TakingCover = false self:SetSchedule( SCHED_COMBAT_STAND ) end else self.TakingCover = false self:SetSchedule( SCHED_ESTABLISH_LINE_OF_FIRE )//move to shoot enemy end end end end end function ENT:FindEnemyDan() local MyNearbyTargets = ents.FindInCone(self:GetPos(),self:GetForward(),10000,57) //local ClosestDistance = 3000 if (!MyNearbyTargets) then print( "No Targets!" ); return end for k,v in pairs(MyNearbyTargets) do if v:Disposition(self) == 1 || (v:IsPlayer() && self.PlayerFriendly == 0 && GetConVarNumber("ai_ignoreplayers") == 0) then //if (v:GetClass() == "npc_*" || v:GetClass() == "monster_*") && v:GetClass() != self:GetClass() then print(v:GetClass()) self:StopSpeechSounds() self:ResetEnemy() self:AddEntityRelationship( v, 1, 10 ) self:SetEnemy(v) local distance = self:GetPos():Distance(v:GetPos()) local randomsound = math.random(1,5) //self:SetSchedule(SCHED_ALERT_FACE) //alerted if self.Alerted == false then if (distance > 400) then if randomsound == 1 then self:EmitSound( self.alert1, 400, 100) elseif randomsound == 2 then self:EmitSound( self.alert2, 400, 100) elseif randomsound == 3 then self:EmitSound( self.alert3, 400, 100) elseif randomsound == 4 then self:EmitSound( self.alert4, 400, 100) end end end self.Alerted = true return end end //if ClosestDistance == 4000 then self:SetEnemy(NULL) //end end function ENT:StopSpeechSounds() self:StopSound(self.alert1) self:StopSound(self.alert2) self:StopSound(self.alert3) self:StopSound(self.alert4) self:StopSound(self.idle1) self:StopSound(self.idle2) self:StopSound(self.idle3) self:StopSound(self.attack1) self:StopSound(self.attack2) self:StopSound(self.attack3) self:StopSound(self.attack4) end function ENT:StopHurtSounds() self:StopSound(self.hurtsound1) self:StopSound(self.hurtsound2) end function ENT:SpawnBlood(dmg) if (self.bleeds > 0) then local bloodeffect = ents.Create( "info_particle_system" ) bloodeffect:SetKeyValue( "effect_name", "blood_impact_red_01" ) bloodeffect:SetPos( dmg:GetDamagePosition() ) bloodeffect:Spawn() bloodeffect:Activate() bloodeffect:Fire( "Start", "", 0 ) bloodeffect:Fire( "Kill", "", 0.1 ) end end function ENT:GetBoomers() local nearbygrenades = ents.FindByClass("npc_grenade_frag") for k,v in pairs(nearbygrenades) do if self:GetPos():Distance(v:GetPos()) < 400 then self:StopSpeechSounds() self:ResetEnemy() self:AddEntityRelationship( v, 3, 10 ) //self:SetEnemy(v) self.seen_grenade = true self.TakingCover = true self:SetSchedule(SCHED_HIDE_AND_RELOAD) return end end end function ENT:KilledDan() /*I Took some of silverlan's code for ragdolling, cause I didn't want to recode it :P*/ //emit cry of death self:StopSpeechSounds() self:StopHurtSounds() local deathseed = math.random(1,2) if deathseed == 1 then self:EmitSound( self.die1, 500, 100) elseif deathseed == 2 then self:EmitSound( self.die2, 500, 100) end //create ragdoll local ragdoll = ents.Create( "prop_ragdoll" ) ragdoll:SetModel( self:GetModel() ) ragdoll:SetPos( self:GetPos() ) ragdoll:SetAngles( self:GetAngles() ) ragdoll:Spawn() ragdoll:SetSkin( self:GetSkin() ) ragdoll:SetColor( self:GetColor() ) ragdoll:SetMaterial( self:GetMaterial() ) //my code undo.ReplaceEntity(self,ragdoll) cleanup.ReplaceEntity(self,ragdoll) //ignight ragdoll if on fire. if self:IsOnFire() then ragdoll:Ignite( math.Rand( 8, 10 ), 0 ) end local entvel local entphys = self:GetPhysicsObject() if entphys:IsValid() then entvel = entphys:GetVelocity() else entvel = self:GetVelocity() end //position bones the same way. for i=1,128 do local bone = ragdoll:GetPhysicsObjectNum( i ) if ValidEntity( bone ) then local bonepos, boneang = self:GetBonePosition( ragdoll:TranslatePhysBoneToBone( i ) ) bone:SetPos( bonepos ) bone:SetAngle( boneang ) end end if( GetConVarNumber("ai_keepragdolls") == 0 ) then ragdoll:SetCollisionGroup( 1 )//COLLISION_GROUP_DEBRIS ) ragdoll:Fire( "FadeAndRemove", "", 7) end self:Remove() end function ENT:CallForHelp() end function ENT:ResetEnemy() end function ENT:FindCloseEnemies() local MyNearbyTargets = ents.FindInCone(self:GetPos(),self:GetForward(),300,50) //local ClosestDistance = 3000 if (!MyNearbyTargets) then print( "No Targets!" ); return end for k,v in pairs(MyNearbyTargets) do if v:Disposition(self) == 1 || (v:IsPlayer() && self.PlayerFriendly == 0 && GetConVarNumber("ai_ignoreplayers") == 0) then print(v:GetClass()) self:StopSpeechSounds() self:ResetEnemy() self:AddEntityRelationship( v, 1, 10 ) self:SetEnemy(v) //if (self.TakingCover == false) || self.Alerted == false then // self.TakingCover = true // self:SetSchedule(SCHED_TAKE_COVER_FROM_ENEMY) //end local randomsound = math.random(1,90) self.Alerted = true return end end end function ENT:OnRemove() timer.Remove("melee_attack_timer" .. self.Entity:EntIndex( )) timer.Remove("melee_done_timer" .. self.Entity:EntIndex( )) end function ENT:HasLOS() if self:GetEnemy() != nil then //local shootpos = self:GetAimVector()*(self:GetPos():Distance(self:GetEnemy():GetPos())) + self:GetPos() //local shootpos = self:GetEnemy():GetPos() local tracedata = {} tracedata.start = self:GetPos() tracedata.endpos = self:GetEnemy():GetPos() tracedata.filter = self local trace = util.TraceLine(tracedata) if trace.HitWorld == false then print("returned true!") return true else return false end end print ("no enemy!") return false end