diff options
| author | Alexander Pickering <Alexander.Pickering@anondomain.site90.net> | 2016-01-07 21:31:55 -0500 |
|---|---|---|
| committer | Alexander Pickering <Alexander.Pickering@anondomain.site90.net> | 2016-01-07 21:31:55 -0500 |
| commit | 790e96ffa5cb5e9eb3c44f6ede09612bafda2239 (patch) | |
| tree | 63cad5072bd20dcdb769ecd4905b4ec1fa0ec845 | |
| parent | 406a4148506be540bcdac0f10f2256320c5c2771 (diff) | |
| parent | 08331347cfc619852a177f9c120bf7328cd89d70 (diff) | |
| download | wintersurvival2-790e96ffa5cb5e9eb3c44f6ede09612bafda2239.tar.gz wintersurvival2-790e96ffa5cb5e9eb3c44f6ede09612bafda2239.tar.bz2 wintersurvival2-790e96ffa5cb5e9eb3c44f6ede09612bafda2239.zip | |
Merge branch 'queue' of ssh://ssh.cogarr.org:43/home/git/wintersurvival2 into queue
| -rw-r--r-- | content/materials/wintersurvival2/hud/ws2_icons/icon_chitin.png | bin | 0 -> 9905 bytes | |||
| -rw-r--r-- | entities/entities/ws_arrow/init.lua | 16 | ||||
| -rw-r--r-- | entities/entities/ws_npc_ambient/init.lua | 61 | ||||
| -rw-r--r-- | entities/entities/ws_npc_ambient/shared.lua | 76 | ||||
| -rw-r--r-- | gamemode/itemsystem/items/chitin.lua | 5 | ||||
| -rw-r--r-- | gamemode/npcsystem/aidirector.lua | 52 | ||||
| -rw-r--r-- | gamemode/npcsystem/npcs/antlion1.lua | 137 | ||||
| -rw-r--r-- | gamemode/npcsystem/npcs/antlion2.lua | 164 | ||||
| -rw-r--r-- | gamemode/npcsystem/npcs/base.lua | 27 | ||||
| -rw-r--r-- | gamemode/npcsystem/npcs/bird.lua | 123 | ||||
| -rw-r--r-- | gamemode/npcsystem/npcs/zombie.lua | 115 |
11 files changed, 661 insertions, 115 deletions
diff --git a/content/materials/wintersurvival2/hud/ws2_icons/icon_chitin.png b/content/materials/wintersurvival2/hud/ws2_icons/icon_chitin.png Binary files differnew file mode 100644 index 0000000..a8a05a6 --- /dev/null +++ b/content/materials/wintersurvival2/hud/ws2_icons/icon_chitin.png diff --git a/entities/entities/ws_arrow/init.lua b/entities/entities/ws_arrow/init.lua index e27dda9..63bfa6e 100644 --- a/entities/entities/ws_arrow/init.lua +++ b/entities/entities/ws_arrow/init.lua @@ -13,9 +13,9 @@ function ENT:Initialize() self:SetCollisionGroup(COLLISION_GROUP_INTERACTIVE)
self:PhysWake()
self:SetUseType(SIMPLE_USE)
-
+
util.SpriteTrail( self, 0, Ab, true, 1, 0, 1, 1, "sprites/smoke_trail.vmt" )
-
+
self:NextThink(CurTime()+10)
end
@@ -24,4 +24,16 @@ function ENT:Think() return true
end
+function ENT:PhysicsCollide(data, phys)
+ if phys:GetEntity():IsPlayer() or phys:GetEntity():IsNPC() then
+ print("We hit something!")
+ else
+ end
+end
+function ENT:Use(activator, caller, usetype, value)
+ if caller:IsPigeon() then return end
+ print("Trying to pick up an arrow!")
+ caller:AddItem("Arrow",1)
+ self:Remove()
+end
diff --git a/entities/entities/ws_npc_ambient/init.lua b/entities/entities/ws_npc_ambient/init.lua index 485b6c9..523333c 100644 --- a/entities/entities/ws_npc_ambient/init.lua +++ b/entities/entities/ws_npc_ambient/init.lua @@ -6,8 +6,20 @@ include('shared.lua') function ENT:Initialize()
--print("NPC spawned!")
+ --self:SetMoveType(MOVETYPE_STEP)
+ self:SetSolid(SOLID_NONE)
+ --self:SetCollisionGroup(COLLISION_GROUP_INTERACTIVE)
+
if(self.Model) then self:SetModel(self.Model)
else print("NPC created without model, this might be a bug!") end
+ if(self.Stats["Vitality"]) then
+ self:SetHealth(self.Stats["Vitality"])
+ print("Helath set to " .. self.Stats["Vitality"])
+ else print("NPC created with no stat for vitality, this might be a bug!")end
+ if(self.Stats["Accel"]) then self.loco:SetAcceleration(self.Stats["Accel"])end
+ if(self.Stats["Decel"]) then self.loco:SetDeceleration(self.Stats["Decel"]) end
+ if(self.Stats["Step"]) then self.loco:SetJumpHeight(self.Stats["Step"]) end
+ if(self.OnSpawn) then self:OnSpawn() end
--self:SetModel( "models/Humans/Group01/Female_01.mdl" )
--[[
self:SetHullType( HULL_HUMAN );
@@ -25,27 +37,36 @@ end function ENT:OnInjured(dmg)
--print("Taking some dammage")
local itempos = self:GetPos()
- self:SetHealth(self:Health() - dmg:GetDamage())
+ print("Takeing " .. dmg:GetDamage() .. " health from our " .. self:Health())
+ --self:SetHealth(self:Health() - dmg:GetDamage())
+ print("Health is now" .. self:Health())
if self.OnDammage != nil then self:OnDammage(dmg) end
- if self:Health() <= 0 then //run on death
- if(CLIENT) then return end
- if not self.Drops then return end
- --print("Looks like we have some drops")
+end
+
+function ENT:OnContact(ent)
+ if(ent:GetClass() == "ws_arrow") then
+ self:TakeDamage(30)
+ ent:SetParent(self)
+ end
+end
+
+function ENT:OnKilled(dmg)
+ if(CLIENT) then return end
+ if not self.Drops then return end
+ --print("Looks like we have some drops")
+ for k,v in pairs(self.Drops) do
local rng = math.random(0,100)
- for k,v in pairs(self.Drops) do
- local itemname = self.Drops[k][1]
- local itemchance = self.Drops[k][2]
- local heightoffset = 10
- if rng < itemchance then
- --print("Createing a " .. itemname)
- local drop = ents.Create("ws_item")
- drop.Item = GetItemByName(itemname)
- drop:SetModel(drop.Item.Model)
- drop:SetPos(itempos + (self:GetUp()*heightoffset))
- drop:Spawn()
- heightoffset = heightoffset + 10
- end
+ local itemname = self.Drops[k][1]
+ local itemchance = self.Drops[k][2]
+ local heightoffset = 10
+ if rng < itemchance then
+ local drop = ents.Create("ws_item")
+ drop.Item = GetItemByName(itemname)
+ drop:SetModel(drop.Item.Model)
+ drop:SetPos(self:GetPos() + (self:GetUp()*heightoffset))
+ drop:Spawn()
+ heightoffset = heightoffset + 10
end
- --self:SetSchedule( SCHED_FALL_TO_GROUND )
- end
+ end
+ self:BecomeRagdoll( dmg )
end
diff --git a/entities/entities/ws_npc_ambient/shared.lua b/entities/entities/ws_npc_ambient/shared.lua index ba65e2b..c84245c 100644 --- a/entities/entities/ws_npc_ambient/shared.lua +++ b/entities/entities/ws_npc_ambient/shared.lua @@ -3,7 +3,6 @@ ENT.Base = "base_nextbot" //WS stuff
ENT.Drops = nil
ENT.OnDammage = nil
-ENT.Vitality = 1
ENT.Speed = 0
ENT.Model = nil
@@ -17,6 +16,79 @@ ENT.Act = nil function ENT:OnRemove()
end
+function ENT:DefaultBehaviour()
+ while ( true ) do
+ --Main loop for ai
+
+ --Update aware enemies
+ local players = ents.FindByClass("Player")
+ for k,v in pairs(players) do
+ if(v:IsPigeon()) then continue end
+ local dist = v:GetPos():Distance(self:GetPos())
+ if( dist < self.Stats["AwareDist"]) then
+ table.insert(self.AwareEnemies,v)
+ end
+ end
+
+ --Find the enemy with the highest priority
+ local maxpriority = -1
+ local maxprioritytarget = nil
+ for k,v in pairs(self.AwareEnemies) do
+ local priority = self:AttackPriority(v)
+ if(priority > maxpriority) then
+ maxpriority = priority
+ maxprioritytarget = v
+ end
+ end
+ self.Target = maxprioritytarget
+
+ --If we can't find anyone to attack, just stay idle
+ if(self.Target == nil) then
+ print("Couldn't find anyone to attack!")
+ --Play an idle sequence
+ local randanim = math.Round(math.Rand(0,#self.IdleSequences))
+ self:PlaySequenceAndWait( self.IdleSequences[randanim] )
+ self:StartActivity( ACT_IDLE )
+ --If there's noone within 4000 units, just remove ourselves to save server resources
+ local closest = 5000
+ for k,v in pairs(player.GetAll()) do
+ local thisdist = self:GetPos():Distance(v:GetPos())
+ if(thisdist > closest) then
+ closest = thisdist
+ end
+ end
+ if(closest > 4000) then self:BecomeRagdoll(DamageInfo()) end
+ else
+ --We have a target to attack!
+
+ --Find which attack will do the most dammage
+ local maxdammage = -1
+ local maxdammagefunc = nil
+ for k,v in pairs(self.Attacks) do
+ local dammagefunc = nil
+ local attackfunc = nil
+ for i,j in pairs(v) do
+ dammagefunc = i
+ attackfunc = j
+ end
+ local dammage = dammagefunc(self, self.Target)
+ if(dammage > maxdammage) then
+ maxdammage = dammage
+ maxdammagefunc = attackfunc
+ end
+ end
+
+ --Do that attack
+ if(maxdammagefunc) then
+ maxdammagefunc(self, self.Target)
+ end
+ end
+ coroutine.yield()
+ end
+
+ coroutine.yield()
+end
+
function ENT:BehaveAct()
if(self.Act) then
self:Act()
@@ -29,6 +101,6 @@ function ENT:RunBehaviour() if(self.Behave) then
self:Behave()
else
- print("NPC spawned without a Behave function, this might be an error!")
+ self:DefaultBehaviour()
end
end
diff --git a/gamemode/itemsystem/items/chitin.lua b/gamemode/itemsystem/items/chitin.lua new file mode 100644 index 0000000..3ae082e --- /dev/null +++ b/gamemode/itemsystem/items/chitin.lua @@ -0,0 +1,5 @@ +ITEM.Name = "Chitin" +ITEM.Class = "resource" +ITEM.Desc = "Some hard outer-skeleton" +ITEM.Model = "models/props_junk/Rock001a.mdl" +ITEM.Icon = Material("wintersurvival2/hud/ws2_icons/icon_chitin.png") diff --git a/gamemode/npcsystem/aidirector.lua b/gamemode/npcsystem/aidirector.lua index 073eea7..04e645d 100644 --- a/gamemode/npcsystem/aidirector.lua +++ b/gamemode/npcsystem/aidirector.lua @@ -8,21 +8,29 @@ concommand.Add("ws_spawnbird",function(ply,cmd,args) SpawnNpcByName("Bird",ply:GetPos())
end)
+concommand.Add("ws_spawnnpc",function(ply,cmd,args)
+ if(!args[1]) then print("You must enter the name of an npc")
+ return end
+
+ local npc = GetNpcByName(args[1])
+ if(npc == nil) then print("Not a valid name!")
+ return end
+ SpawnNpcByName(args[1],ply:GetPos())
+end)
+
function SpawnNpcByName(name, position)
if(CLIENT) then return end
entdata = GetNpcByName(name)
+ if not entdata then
+ print("Could not find npc data for name " .. name)
+ return
+ end
ent = ents.Create("ws_npc_ambient")
ent:SetPos(position)
- if(entdata.Speed) then
- ent.Speed = entdata.Speed
- end
if(entdata.Model) then
ent.Model = entdata.Model
end
- if(entdata.vitality) then
- ent:SetHealth(entdata.vitality)
- end
if(entdata.Drops) then
ent.Drops = entdata.Drops
end
@@ -35,6 +43,24 @@ function SpawnNpcByName(name, position) if(entdata.Act) then
ent.Act = entdata.Act
end
+ if(entdata.Stats) then
+ ent.Stats = entdata.Stats
+ end
+ if(entdata.IdleSequences) then
+ ent.IdleSequences = entdata.IdleSequences
+ end
+ if(entdata.Attacks) then
+ ent.Attacks = entdata.Attacks
+ end
+ if(entdata.AttackPriority) then
+ ent.AttackPriority = entdata.AttackPriority
+ end
+ if(entdata.AwareEnemies) then
+ ent.AwareEnemies = entdata.AwareEnemies
+ end
+ if(entdata.OnSpawn) then
+ ent.OnSpawn = entdata.OnSpawn
+ end
ent:Spawn()
end
@@ -43,7 +69,13 @@ local traceline = util.TraceLine local contents = util.PointContents
local Up = Vector(0,0,1)
---Randomly spawn bird npc's around?
+--Randomly spawn npc's around?
+local ambientnpcs = {
+ [0] = "Bird",
+ [1] = "Zombie",
+ [2] = "Antlion Scout",
+ [3] = "Antlion Pouncer"
+}
local Tick = CurTime()
hook.Add("Tick","SpawnAmbient",function()
if(CLIENT) then return end
@@ -75,7 +107,11 @@ hook.Add("Tick","SpawnAmbient",function() if (C != CONTENTS_WATER and C != CONTENTS_WATER+CONTENTS_TRANSLUCENT) then
--print("Appropriate place found, spawning bird)")
- SpawnNpcByName("Bird",Pos)
+ local randnpcnum = math.Round(math.Rand(0, #ambientnpcs))
+ local npc = GetNpcByName(ambientnpcs[randnpcnum])
+ if(npc:SpawnLocations(Pos)) then
+ SpawnNpcByName(ambientnpcs[randnpcnum],Pos)
+ end
break
end
end
diff --git a/gamemode/npcsystem/npcs/antlion1.lua b/gamemode/npcsystem/npcs/antlion1.lua new file mode 100644 index 0000000..1b0a38f --- /dev/null +++ b/gamemode/npcsystem/npcs/antlion1.lua @@ -0,0 +1,137 @@ +NPC.Name = "Antlion Scout" +NPC.Desc = "A fearsome monster!" +NPC.Class = "Agressive" --Ambient, Agressive, Boss +NPC.Model = "models/antlion.mdl" +NPC.Icon = Material("wintersurvival2/hud/ws1_icons/icon_rock") + +NPC.Social = "Solo" --Solo, Pack + +NPC.Stats = { + ["Vitality"] = 150, + ["Speed"] = 800, + ["AwareDist"] = 1000, + ["Accel"] = 400, + ["Decel"] = 400, + ["Step"] = 20, --Step height + ["Hull"] = HULL_MEDIUM +} + +--Drops should be formated as [index]={["item name"], percent_drop} where percent_drop is a number from 0 to 100 +NPC.Drops = { + [0] = {"Meat",100}, + [1] = {"Meat",100}, + [2] = {"Meat",80}, + [3] = {"Meat",50}, + [4] = {"Chitin",80}, + [5] = {"Chitin",50}, +} + +--Some npc's like birds have diffent names for their idle sequences +NPC.IdleSequences = { + [0] = "Idle", +} + +--Distance to be made aware of players + +--Attacks should be formated as [i]={function (return int dammage) canattack(ply) = function doattack(ply)} +--NPC will do the most dammage possible per attack +local checkmele = function(self, ply) + if(ply:GetPos():Distance(self:GetPos()) < 100) then return 20 end + return -1 +end + +local domele = function(self, ply) + self:StartActivity(ACT_MELEE_ATTACK1) + --Antlion has 6 attack animations + local attackanim = math.Round(math.Rand(1,6)) + coroutine.wait(0.5) + --If the player is still in front of us after the animation, they didn't dodge! apply dammage! + if(ply:GetPos():Distance(self:GetPos()) < 100) then + ply:TakeDamage(20) + end + --Finish up the animation + coroutine.wait(0.25) +end + +local checkrun = function(self, ply) return 0 end + +local dorun = function(self, ply) + local navarea = navmesh.GetNavArea(self:GetPos(), 100) + self.loco:SetDesiredSpeed(self.Stats["Speed"] ) + if navarea:IsValid() then + local moveop = {} + moveop.tolerance = 50 + moveop.repath = 2 + moveop.lookahead = 3 + moveop.draw = true + self:StartActivity(ACT_WALK) + self:MoveToPos(ply:GetPos(),moveop) + else + print("Could not find valid navmesh, suicideing to prevent server crash!") + self:BecomeRagdoll(DamageInfo()) + end +end + +NPC.Attacks = { + [1] = { --A mele attack + [checkmele] = domele + }, + + [2] = {--Move to the player + [checkrun] = dorun + + }, + + +} + +--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) + local dist = ply:GetPos():Distance(self:GetPos()) + return self.Stats["AwareDist"] - dist +end + +--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 = {} + +--What to replace the ENT:BehaveAct with +function NPC:Act() +end + +--What to replace ENT:OnStuck with +function NPC:Stuck() + --If we're stuck, jump backwards +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() +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 +*/ diff --git a/gamemode/npcsystem/npcs/antlion2.lua b/gamemode/npcsystem/npcs/antlion2.lua new file mode 100644 index 0000000..738bb7e --- /dev/null +++ b/gamemode/npcsystem/npcs/antlion2.lua @@ -0,0 +1,164 @@ +NPC.Name = "Antlion Pouncer" +NPC.Desc = "A fearsome monster!" +NPC.Class = "Agressive" --Ambient, Agressive, Boss +NPC.Model = "models/antlion.mdl" +NPC.Icon = Material("wintersurvival2/hud/ws1_icons/icon_rock") + +NPC.Social = "Solo" --Solo, Pack + +NPC.Stats = { + ["Vitality"] = 150, + ["Speed"] = 800, + ["AwareDist"] = 1000, + ["Accel"] = 400, + ["Decel"] = 400, + ["Step"] = 20, --Step height + ["Hull"] = HULL_MEDIUM +} + +--Drops should be formated as [index]={["item name"], percent_drop} where percent_drop is a number from 0 to 100 +NPC.Drops = { + [0] = {"Meat",100}, + [1] = {"Meat",100}, + [2] = {"Meat",80}, + [3] = {"Meat",50}, + [4] = {"Chitin",80}, + [5] = {"Chitin",50}, +} + +--Some npc's like birds have diffent names for their idle sequences +NPC.IdleSequences = { + [0] = "Idle", +} + +--Distance to be made aware of players + +--Attacks should be formated as [i]={function (return int dammage) canattack(ply) = function doattack(ply)} +--NPC will do the most dammage possible per attack +local checkmele = function(self, ply) + if(ply:GetPos():Distance(self:GetPos()) < 100) then return 20 end + return -1 +end + +local domele = function(self, ply) + self:StartActivity(ACT_MELEE_ATTACK1) + --Antlion has 6 attack animations + local attackanim = math.Round(math.Rand(1,6)) + coroutine.wait(0.5) + --If the player is still in front of us after the animation, they didn't dodge! apply dammage! + if(ply:GetPos():Distance(self:GetPos()) < 100) then + ply:TakeDamage(20) + end + --Finish up the animation + coroutine.wait(0.25) +end + +local checkpounce = function(self, ply) + if(ply:GetPos():Distance(self:GetPos())) < 200 then return 15 end + return -1 +end + +local dopounce = function(self,ply) + local randanim = math.Round(math.Rand(0,1)) + if(randanim) then + self:SetSequence("pounce") + else + self:SetSequence("pounce2") + end + coroutine.wait(0.23) + if(ply:GetPos():Distance(self:GetPos()) < 200) then + ply:TakeDamage(15) + end + coroutine.wait(0.15) +end + +local checkrun = function(self, ply) return 0 end + +local dorun = function(self, ply) + local navarea = navmesh.GetNavArea(self:GetPos(), 100) + self.loco:SetDesiredSpeed(self.Stats["Speed"]) + if navarea:IsValid() then + local moveop = {} + moveop.tolerance = 50 + moveop.repath = 2 + moveop.lookahead = 3 + moveop.draw = true + self:StartActivity(ACT_WALK) + self:MoveToPos(ply:GetPos(),moveop) + else + print("Could not find valid navmesh, suicideing to prevent server crash!") + self:BecomeRagdoll(DamageInfo()) + end +end + +NPC.Attacks = { + [1] = { --A mele attack + [checkmele] = domele + }, + + [2] = {--Move to the player + [checkrun] = dorun + + }, + + [3] = { + [checkpounce] = dopounce + }, + +} + +--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) + local dist = ply:GetPos():Distance(self:GetPos()) + return self.Stats["AwareDist"] - dist +end + +--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 = {} + +--What to replace the ENT:BehaveAct with +function NPC:Act() +end + +--What to replace ENT:OnStuck with +function NPC:Stuck() + --If we're stuck, jump backwards +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:SetSkin(2) +end + +/* +function NPC:OnSpawn() +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 +*/ diff --git a/gamemode/npcsystem/npcs/base.lua b/gamemode/npcsystem/npcs/base.lua index 7afb4fe..880e4a5 100644 --- a/gamemode/npcsystem/npcs/base.lua +++ b/gamemode/npcsystem/npcs/base.lua @@ -6,16 +6,37 @@ NPC.Icon = Material("wintersurvival2/hud/ws1_icons/icon_rock") NPC.Social = "Pack" --Solo, Pack
-NPC.Vitality = 0
-NPC.Speed = 0
+NPC.Stats = {
+ ["Vitality"] = 1,
+ ["Speed"] = 1,
+ ["AwareDist"] = 1,
+ ["Accel"] = 1,
+ ["Decel"] = 1,
+ ["Step"] = 1, --Step height
+ ["Hull"] = HULL_HUMAN
+}
+
+--Some npc's like birds have diffent names for their idle sequence
+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 = nil
--Attacks should be formated as [i]={function attackpriority() = function doattack()}
NPC.Attacks = nil
+--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)
+ local dist = ply:GetPos():Distance(self:GetPos())
+ return self.Stats["AwareDist"] - dist
+end
+
--A function that takes a position and returns true if this is an acceptable place to spawn
-NPC.SpawnLocations = nil
+function NPC:SpawnLocations(pos)
+ return true
+end
--The entity that is this npc's current target, if it has one
NPC.Target = nil
diff --git a/gamemode/npcsystem/npcs/bird.lua b/gamemode/npcsystem/npcs/bird.lua index fa3ad8d..7b19457 100644 --- a/gamemode/npcsystem/npcs/bird.lua +++ b/gamemode/npcsystem/npcs/bird.lua @@ -6,9 +6,24 @@ NPC.Icon = Material("wintersurvival2/hud/ws1_icons/icon_rock") NPC.Social = "Pack" --Solo, Pack
-NPC.Vitality = 10
-NPC.Speed = 100
+NPC.Stats = {
+ ["Vitality"] = 10,
+ ["Speed"] = 400,
+ ["AwareDist"] = 1000,
+ ["Accel"] = 200,
+ ["Decel"] = 200,
+ ["Step"] = 20, --Step height
+ ["Hull"] = HULL_TINY
+}
+
+--Some npc's like birds have diffent names for their idle sequences
+NPC.IdleSequences = {
+ [0] = "Idle01",
+ [1] = "Eat_A",
+}
+
--Drops should be formated as [index]={["item name"], percent_drop} where percent_drop is a number from 0 to 100
+
NPC.Drops = {
[0] = {"Meat",100},--Birds will drop at least 1 meat, and have a 50% chance of dropping 2
[1] = {"Meat",50},
@@ -16,16 +31,51 @@ NPC.Drops = { }
--Attacks should be formated as [i]={function attackpriority() = function doattack()}
-NPC.Attacks = nil
+local checkrun = function(self,ply)
+ --If we're aware of any enemies, run away!
+ return 1
+end
+local dorun = function(self,ply)
+ self:StartActivity(ACT_FLY)
+ self:PlaySequenceAndWait( "Fly01" )
+
+ --Find a position in roughly the oposite direction of the player
+ local tpos = self:GetPos()
+ local ppos = ply:GetPos()
+ local direction = Vector(tpos.x - ppos.x, tpos.y - ppos.y, tpos.z - ppos.z)
+ direction:Normalize()
+ local addition = direction * 1000
+ local topos = self:GetPos() + addition
+ local navarea = navmesh.GetNavArea(self:GetPos(), 100)
+ if navarea:IsValid() then
+ self:MoveToPos(topos)
+ else
+ print("Suicideing a bird to prevent server crash!")
+ self:BecomeRagdoll(DamageInfo())
+ end
+end
+NPC.Attacks = {
+ [1] = {--run away from the player
+ [checkrun] = dorun
+ },
+}
--A function that takes a position and returns true if this is an acceptable place to spawn
-NPC.SpawnLocations = nil
+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 = nil
+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)
+ local dist = ply:GetPos():Distance(self:GetPos())
+ return self.Stats["AwareDist"] - dist
+end
--What to replace the ENT:BehaveAct with
function NPC:Act()
@@ -36,69 +86,6 @@ function NPC:Stuck() end
---What to replace ENT:RunBehaviour with
-function NPC:Behave()
- --print("Going into bird's custom behaviour")
- while ( true ) do
- self:StartActivity( ACT_IDLE ) -- walk anims
- self:PlaySequenceAndWait( "Idle01" ) -- Sit on the floor
- --Check if there are any players nearby
- local players = ents.FindByClass("Player")
- local playernearby = false
- for k,v in pairs(players) do
- local fardist = 800
- local closedist = 300
- local removedist = 2000
- local iscrouched = v:Crouching()
- local dist = v:GetPos():Distance(self:GetPos())
- --Remove ourselves if there's noone nearby
- if(dist > 2000) then
- playernearby = true
- end
- --Keep flying away as long as we're being chased
- while((dist < fardist and not iscrouched) or (dist < closedist)) do
- self:StartActivity(ACT_FLY)
- self:PlaySequenceAndWait( "Fly01" )
-
- --Find a position in roughly the oposite direction of the player
- local tpos = self:GetPos()
- local ppos = v:GetPos()
- local direction = Vector(tpos.x - ppos.x, tpos.y - ppos.y, tpos.z - ppos.z)
- direction:Normalize()
- local addition = direction * 1000
- local topos = self:GetPos() + addition
-
- --Check to make sure we can make it somewhere, so we don't crash
- --[[
- if not self.loco:IsAreaTraversable(navmesh.GetNavArea(self:GetPos(),100)) then
- print("No way to go forward!")
- break
- end
- --]]
- local navarea = navmesh.GetNavArea(self:GetPos(), 100)
-
- if navarea:IsValid() then
- --print("Looks like nav area is valid")
- self:MoveToPos(topos)
- else
- --print("Looks like nav area is invalid")
- self:BecomeRagdoll(DamageInfo())
- end
-
-
-
- --Check to see if we're being chased
- iscrouched = v:Crouching()
- dist = v:GetPos():Distance(self:GetPos())
- end
- end
- if not playernearby then
- self:BecomeRagdoll(DamageInfo())
- end
- end
- coroutine.yield()
-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()
diff --git a/gamemode/npcsystem/npcs/zombie.lua b/gamemode/npcsystem/npcs/zombie.lua index 0980cdc..5914c04 100644 --- a/gamemode/npcsystem/npcs/zombie.lua +++ b/gamemode/npcsystem/npcs/zombie.lua @@ -1,26 +1,117 @@ NPC.Name = "Zombie"
-NPC.Desc = "Ahh! The Undead!!"
-NPC.Class = "Other" --Ambient, Agressive, Boss
-NPC.Model = "models/props_combine/breenlight.mdl"
+NPC.Desc = "A fearsome monster!"
+NPC.Class = "Agressive" --Ambient, Agressive, Boss
+NPC.Model = "models/Zombie/Classic.mdl"
NPC.Icon = Material("wintersurvival2/hud/ws1_icons/icon_rock")
-NPC.Vitality = 100
-NPC.Speed = 100
+NPC.Social = "Solo" --Solo, Pack
+
+NPC.Stats = {
+ ["Vitality"] = 200,
+ ["Speed"] = 50,
+ ["AwareDist"] = 1000,
+ ["Accel"] = 100,
+ ["Decel"] = 200,
+ ["Step"] = 20, --Step height
+ ["Hull"] = HULL_HUMAN
+}
+
--Drops should be formated as [index]={["item name"], percent_drop} where percent_drop is a number from 0 to 100
-NPC.Drops = nil
+NPC.Drops = {
+ [0] = {"Meat",100},
+ [1] = {"Meat",100},
+ [2] = {"Meat",100},
+ [3] = {"Meat",100},
+ [4] = {"Meat",80},
+ [5] = {"Meat",40},
+ [6] = {"Meat",10},
+}
+
+--Some npc's like birds have diffent names for their idle sequences
+NPC.IdleSequences = {
+ [0] = "Idle",
+}
+
+--Distance to be made aware of players
+
+--Attacks should be formated as [i]={function (return int dammage) canattack(ply) = function doattack(ply)}
+--NPC will do the most dammage possible per attack
+local checkmele = function(self, ply)
+ if(ply:GetPos():Distance(self:GetPos()) < 100) then return 20 end
+ return -1
+end
+
+local domele = function(self, ply)
+ self:StartActivity(ACT_MELEE_ATTACK1)
+ --Antlion has 6 attack animations
+ local attackanim = math.Round(math.Rand(1,6))
+ coroutine.wait(0.75)
+ --If the player is still in front of us after the animation, they didn't dodge! apply dammage!
+ if(ply:GetPos():Distance(self:GetPos()) < 100) then
+ ply:TakeDamage(20)
+ end
+ --Finish up the animation
+ coroutine.wait(0.25)
+end
+
+local checkrun = function(self, ply) return 0 end
+
+local dorun = function(self, ply)
+ local navarea = navmesh.GetNavArea(self:GetPos(), 100)
+ self.loco:SetDesiredSpeed( 50 )
+ if navarea:IsValid() then
+ local moveop = {}
+ moveop.tolerance = 50
+ moveop.repath = 2
+ moveop.lookahead = 3
+ moveop.draw = true
+ self:StartActivity(ACT_WALK)
+ self:MoveToPos(ply:GetPos(),moveop)
+ else
+ print("Could not find valid navmesh, suicideing to prevent server crash!")
+ self:BecomeRagdoll(DamageInfo())
+ end
+end
+
+NPC.Attacks = {
+ [1] = { --A mele attack
+ [checkmele] = domele
+ },
---Attacks should be formated as [range]={index = function doattack(target)}
---Where range is the range of the target, and doattack(target) is the function called to attack
-NPC.Attacks = nil
+ [2] = {--Move to the player
+ [checkrun] = dorun
+
+ },
+
+
+}
+
+--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)
+ local dist = ply:GetPos():Distance(self:GetPos())
+ return self.Stats["AwareDist"] - dist
+end
--A function that takes a position and returns true if this is an acceptable place to spawn
-NPC.SpawnLocations = function(pos) return true end
+function NPC:SpawnLocations(pos)
+ return true
+end
---The entity that is this npc's current target, if it has one
+--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 = nil
+NPC.AwareEnemies = {}
+
+--What to replace the ENT:BehaveAct with
+function NPC:Act()
+end
+
+--What to replace ENT:OnStuck with
+function NPC:Stuck()
+ --If we're stuck, jump backwards
+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()
|
