diff options
Diffstat (limited to 'gamemode/npcsystem/sv_zombie.lua')
| -rw-r--r-- | gamemode/npcsystem/sv_zombie.lua | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/gamemode/npcsystem/sv_zombie.lua b/gamemode/npcsystem/sv_zombie.lua new file mode 100644 index 0000000..7f7e496 --- /dev/null +++ b/gamemode/npcsystem/sv_zombie.lua @@ -0,0 +1,187 @@ +local n = nrequire("sv_npcsystem.lua") +local ncom = nrequire("sv_common.lua") +local NPC = {} +NPC.Name = "Zombie" +NPC.Desc = "The living dead, argh!" +NPC.Class = "Ambient" --Ambient, Agressive, Boss +NPC.Model = "models/Zombie/Classic.mdl" +--[[ +models/Zombie/Fast.mdl +models/Zombie/Poison.mdl +models/Humans/corpse1.mdl +models/Humans/Charple01.mdl +models/fallout/tunneler.mdl +models/fallout/streettrog.mdl +models/fallout/deathclaw.mdl +models/fallout/deathclaw_alphamale.mdl +models/fallout/deathclaw_baby.mdl +models/fallout/deathclaw_mother.mdl +models/fallout/gecko.mdl +models/fallout/giantrat.mdl +models/fallout/sporecarrier.mdl +]] + +NPC.Stats = { + ["Vitality"] = 400, + ["Speed"] = 40, + ["AwareDist"] = 1000, + ["Accel"] = 25, + ["Decel"] = 40, + ["Step"] = 20, --Step height + ["Hull"] = HULL_HUMAN +} + +--Some npc's like birds have diffent names for their idle sequences +NPC.IdleSequences = { + [0] = "idle", +} + +--Drops should be formated as [index]={["item name"], percent_drop} where percent_drop is a number from 0 to 100 + +NPC.Drops = { + [0] = {"Rat Meat",100},--Rats will drop at least 1 meat, and have a 50% chance of dropping 2 + [1] = {"Rat Meat",50}, +} + +local checkattack = function(self,ply) + print("Checking attack") + if not ply or not self then return -1 end + local pp,sp = ply:GetPos(),self:GetPos() + local isnear = (pp:Distance(sp) < 100) and (math.abs(pp.z - sp.z) < 20) + local canattack = CurTime() - self.lastattack > 2 + if isnear and canattack then + local tr = util.TraceLine({ + start = self:GetPos() + Vector(0,0,50), + endpos = ply:GetPos() + Vector(0,0,50), + filter = self, + }) + if tr.Hit and tr.Entity == ply then + return 2 + else + return 0 + end + else + return 0 + end +end + +local doattack = function(self,ply) + print("Doing attack") + self.lastattack = CurTime() + self:StartActivity(ACT_MELEE_ATTACK1) + timer.Simple(1,function() --It looks like you're hit about 1/2s after animation start + if (not IsValid(self)) or( not IsValid(ply)) then return end --Make sure we're both still alive! + local sp,pp = self:GetPos(),ply:GetPos() + local cross = sp:Cross(pp) + local fppj = cross:GetNormalized():Dot(self:GetForward()) + if math.abs(fppj) < 0.1 and sp:Distance(pp) < 75 then --If the player is still in front of us, do a trace + local tr = util.TraceLine({ + start = sp + Vector(0,0,50), + endpos = pp + Vector(0,0,50), + filter = self, + }) + if tr.Hit and tr.Entity == ply then + ply:TakeDamage(20,self,self) + else + print("tr.hit was",tr.Hit,"entity was",tr.Entity) + end + else + print('Player was not in front, or distance too great') + print(fppj) + print(sp:Distance(pp)) + end + end) +end + +--At least 1 check function must return greater than -1 +local checkrun = function(self,ply) + local isnearby = (1000 - ply:GetPos():Distance(self:GetPos()))/1000 --Zombies work on smell or something, idk, line of sight is hard to do cheaply + --But we want attack priority to override this, so only return a max of 1 + return isnearby +end + +local dorun = function(self,ply) + if CurTime() - self.lastwalk > 3 then + self:StartActivity( ACT_WALK ) + self.lastwalk = CurTime() + end + if not ply or not ply:IsValid() then return end + local ppos = ply:GetPos() + self.TargetPos = ppos + if self.TargetPos ~= nil then + self.loco:Approach(self.TargetPos,1) + end +end + +NPC.Attacks = { + [1] = {--attack the player if they're in front of us + [checkattack] = doattack + }, + [2] = {--Run at the player + [checkrun] = dorun + } +} + +--A function that takes a position and returns true if this is an acceptable place to spawn +function NPC:SpawnLocations(pos) + return true +end + +--The entity that is this npc's current target, if it has one. Nil otherwise +NPC.Target = nil + +--All enemies that this NPC is aware of +NPC.AwareEnemies = {} +--Attack priority is a fucntion that takes a player, and returns an int describing it's prority to attack (higher = more important) NPC will always attack the player with the highest priority +function NPC:AttackPriority(ply) + if not ply then return 0 end + local plypos = ply:GetPos() + local mypos = self:GetPos() + if not plypos then return 0 end + local dist = plypos:Distance(mypos) + return self.Stats["AwareDist"] - dist +end + +--What to replace the ENT:RunBehaviour with +function NPC:Act(deltat) +end + +--What to replace ENT:OnStuck with +function NPC:Stuck() + --Find out what we're stuck on + local tr = util.TraceLine({ + start = self:GetPos() + Vector(0,0,50), --Start at about waist height + endpos =( self:GetForward()*50) + self:GetPos() + Vector(0,0,50), + filter = self + }) + +end + +--These are just here to tell the editors/develoeprs what functions are available.. dont un-comment them out, as this could affect all the items. + +function NPC:OnSpawn() + self.lastattack = CurTime() + self.lastwalk = CurTime() +end +/* +--If we need to do more than just reduce health on dammage +function NPC:OnDammage(ammount) +end + +--If we need to do more than just drop items on death +function NPC:OnDeath() +end + +--A particular spell was cast on this npc by player +function NPC:OnSpell(spell, player) +end + +function NPC:OnFindEnemy(enemy) +end + +--Called when the npc is attacking anything with any attack +function NPC:OnAttack(target) +end +*/ + +n.RegisterNPC(NPC) |
