aboutsummaryrefslogtreecommitdiff
path: root/gamemode/ents
diff options
context:
space:
mode:
Diffstat (limited to 'gamemode/ents')
-rw-r--r--gamemode/ents/art_npc/cl_art_npc.lua139
-rw-r--r--gamemode/ents/art_npc/sh_art_npc.lua14
-rw-r--r--gamemode/ents/art_npc/sv_art_npc.lua180
3 files changed, 333 insertions, 0 deletions
diff --git a/gamemode/ents/art_npc/cl_art_npc.lua b/gamemode/ents/art_npc/cl_art_npc.lua
new file mode 100644
index 0000000..0233666
--- /dev/null
+++ b/gamemode/ents/art_npc/cl_art_npc.lua
@@ -0,0 +1,139 @@
+local ENT = nrequire("sh_art_npc.lua")
+local e = nrequire("editor.lua")
+local col = nrequire("colortheme.lua")
+print("in cl_art_npc, ENT loaded from sh_art_npc is", ENT)
+
+ENT.RenderGroup = RENDERGROUP_BOTH
+
+
+local function get_settings_info(what)
+ -- Settings to display next to an npc
+ local settings = {}
+
+ settings["Model"] = what:GetModel()
+
+ -- Classes that this npc inherits from, in the order it inherits
+ local sinh = {}
+ local sinhc = 1 -- Keep going, even if we encounter nil
+ local cursor = what
+ sinh[sinhc] = cursor.Name
+ while cursor do
+ cursor = getmetatable(cursor)
+ if type(cursor) == "table" then
+ sinh[sinhc] = cursor.Name or "nil"
+ else
+ sinh[sinhc] = tostring(cursor)
+ end
+ sinhc = sinhc + 1
+ end
+ settings["Inherits from"] = string.format("[%s]",table.concat(sinh,", "))
+
+ return settings
+end
+
+local settings_info = nil
+function ENT:Draw()
+ if e.Enabled then --What to draw when "Editor" is enabled
+ self:DrawModel()
+
+ if settings_info == nil then
+ settings_info = get_settings_info(self)
+ end
+ local pos,ang = (self:GetRight() * -32) + (self:GetUp() * 72) + self:GetPos() , self:GetAngles()
+
+ cam.Start3D2D( pos, ang + Angle(0, 90, 90), 0.2 )
+ local line = 0
+ for k,v in pairs(settings_info) do
+ draw.DrawText(string.format("%s:%s",k,tostring(v)), "Default", 0, line * 20, col.game.npcsettings )
+ line = line + 1
+ end
+
+ cam.End3D2D()
+ else
+ self:DrawModel()
+ end
+end
+
+function ENT:DrawTranslucent()
+
+ -- This is here just to make it backwards compatible.
+ -- You shouldn't really be drawing your model here unless it's translucent
+
+ self:Draw()
+
+end
+
+function ENT:BuildBonePositions( NumBones, NumPhysBones )
+
+ -- You can use this section to position the bones of
+ -- any animated model using self:SetBonePosition( BoneNum, Pos, Angle )
+
+ -- This will override any animation data and isn't meant as a
+ -- replacement for animations. We're using this to position the limbs
+ -- of ragdolls.
+
+end
+
+function ENT:SetRagdollBones( bIn )
+
+ -- If this is set to true then the engine will call
+ -- DoRagdollBone (below) for each ragdoll bone.
+ -- It will then automatically fill in the rest of the bones
+
+ self.m_bRagdollSetup = bIn
+
+end
+
+function ENT:DoRagdollBone( PhysBoneNum, BoneNum )
+
+ -- self:SetBonePosition( BoneNum, Pos, Angle )
+
+end
+
+local chatframe = nil
+
+net.Receive("art_opennpcdialog",function()
+ if chatframe ~= nil and chatframe:IsValid() then
+ chatframe:Remove()
+ chatframe = nil
+ end
+ local width, height = ScrW(), ScrH()
+ local who = net.ReadEntity()
+ local chattbl = net.ReadTable()
+ chatframe = vgui.Create( "DFrame" )
+ chatframe:SetPos( (width / 2) - (width / 4), height - (height / 4) )
+ chatframe:SetSize( width / 2, height / 4 )
+ chatframe:SetTitle( chattbl["Name"] )
+ chatframe:SetDraggable( true )
+ chatframe.OnClose = function()
+ net.Start("art_closenpcdialog")
+ net.WriteEntity(who)
+ net.SendToServer()
+ end
+
+ local chattxt = vgui.Create( "DLabel", chatframe )
+ --chattxt:SetPos( 40, 40 )
+ chattxt:SetText(chattbl["Message"])
+ chattxt:Dock(TOP)
+
+ for k,v in pairs(chattbl["Options"]) do
+ local chatbutton = vgui.Create( "DButton",chatframe )
+ --chatbutton:SetPos( 40, 40 )
+ chatbutton:SetText( v )
+ --chatbutton:SetSize( 120, 60 )
+ chatbutton.DoClick = function()
+ net.Start("art_updatenpcdialog")
+ net.WriteEntity(who)
+ net.WriteString(v)
+ net.SendToServer()
+ end
+ chatbutton:Dock(BOTTOM)
+ end
+ chattxt:Dock(FILL)
+
+
+
+ chatframe:MakePopup()
+end)
+
+scripted_ents.Register(ENT, "art_npc")
diff --git a/gamemode/ents/art_npc/sh_art_npc.lua b/gamemode/ents/art_npc/sh_art_npc.lua
new file mode 100644
index 0000000..c7d549c
--- /dev/null
+++ b/gamemode/ents/art_npc/sh_art_npc.lua
@@ -0,0 +1,14 @@
+local ENT = {}
+local base = nrequire("sh_basenpc.lua")
+
+ENT.Type = "anim"
+ENT.Base = "base_nextbot"
+
+local ent_m = {__index = base}
+
+hook.Add("artery_core_loaded","load_ent_art_npc",function()
+ print("At the time artery_core_loaded is called, ENT is", ENT)
+ setmetatable(ENT,ent_m)
+end)
+
+return ENT
diff --git a/gamemode/ents/art_npc/sv_art_npc.lua b/gamemode/ents/art_npc/sv_art_npc.lua
new file mode 100644
index 0000000..9c24e9d
--- /dev/null
+++ b/gamemode/ents/art_npc/sv_art_npc.lua
@@ -0,0 +1,180 @@
+local ENT = nrequire("sh_art_npc.lua")
+local log = nrequire("log.lua")
+
+util.AddNetworkString( "art_opennpcdialog" )
+util.AddNetworkString( "art_closenpcdialog" )
+util.AddNetworkString( "art_updatenpcdialog")
+
+local oinit = ENT.Initalize
+function ENT:Initialize()
+ --self:SetMoveType(MOVETYPE_VPHYSICS)
+ self:SetSolid(SOLID_BBOX)
+ self:SetCollisionGroup(COLLISION_GROUP_NPC)
+
+ self:SetHealth(50)
+
+ -- self.loco:SetDeathDropHeight(500) --default 200
+ -- self.loco:SetAcceleration(400) --default 400
+ -- self.loco:SetDeceleration(400) --default 400
+ -- self.loco:SetStepHeight(18) --default 18
+ -- self.loco:SetJumpHeight(25) --default 58
+ -- self.loco:SetDesiredSpeed( 50 )
+
+ self.nodereached = false
+
+ self.lastdooropen = CurTime()
+
+ if self.Model then self:SetModel(self.Model)
+ else log.error("NPC created without model, this might be a bug!") end
+
+ if self.Pos then self:SetPos(self.Pos)
+ else log.error("NPC created without a position, this might be a bug!") end
+
+ self.talking = false
+
+ if self.Name then self:SetName(self.Name)
+ else log.error("NPC created without a name! They won't be able to open doors!") end
+
+ if self.Ang then self:SetAngles(self.Ang) end
+
+ if self.OnSpawn then self.OnSpawn(self) end
+
+ self.allowedNodes = {}
+ self.NavNodes = self.NavNodes or {}
+
+ for k,v in pairs(ents.FindByClass( "info_townienode" ) ) do
+ if self.NavNodes[v.Name] then
+ table.insert(self.allowedNodes,v)
+ end
+ end
+
+ self:SetUseType( SIMPLE_USE )
+
+ self.DialogCursors = {}
+ if oinit then
+ oinit(self)
+ end
+end
+
+function ENT:OnInjured(dmg)
+ if self.OnDammage ~= nil then self:OnDammage(dmg) end
+end
+
+local removeblock = {
+ ["prop_door_rotating"] = function(bot,ent)
+ ent:Fire("OpenAwayFrom",bot:GetName())
+ timer.Simple(3,function()
+ ent:Fire("Close")
+ end)
+ end
+}
+
+function ENT:BehaveUpdate(num)
+ if not self.BehaveThread then return end
+ if self.curnode and self.curnode:IsValid() and self.curnode:GetPos():Distance(self:GetPos()) < 5 then
+ if self.nodereached == false then
+ self.curnode.OnReached(self)
+ self.nodereached = true
+ else
+ if self.curnode.IsDone(self) then
+ --error("Finished action")
+ self.curnode = self:selectNewNode()
+ self.nodereached = false
+ end
+ end
+ end
+ local trdata = {
+ ["start"] = self:GetPos() + (self:GetUp() * 72),
+ ["endpos"] = self:GetPos() + (self:GetUp() * 72) + (self:GetForward() * 32),
+ ["filter"] = self
+ }
+ local tr = util.TraceLine(trdata)
+ local ecl
+ if (tr ~= nil) and (tr.Entity ~= nil) and tr.Entity:IsValid() then
+ ecl = tr.Entity:GetClass()
+ end
+ if tr.Hit and removeblock[ecl] ~= nil then
+ removeblock[ecl](self,tr.Entity)
+ end
+ local ok, message = coroutine.resume( self.BehaveThread )
+ if not ok then
+ self.BehaveThread = nil
+ Msg( self, "error: ", message, "\n" );
+ end
+
+end
+
+function ENT:OnKilled(dmg)
+ if not self.Drops then return end
+ for k,v in pairs(self.Drops) do
+ local rng = math.random(0,100)
+ 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
+ end
+ self:BecomeRagdoll( dmg )
+end
+
+local devs = {}
+concommand.Add("artery_develop",function(ply,cmd,args)
+ if not ply:IsAdmin() then return end
+ if devs[ply] then
+ devs[ply] = nil
+ else
+ devs[ply] = true
+ end
+end)
+
+--Fix the dialog so we aren't sending functions
+local function SendableDialog(tbl)
+ local ntbl = table.Copy(tbl)
+ ntbl["Options"] = table.GetKeys(tbl["Options"])
+ return ntbl
+end
+
+function ENT:Use(ply)
+ if devs[ply] then
+
+ else
+
+ self.DialogCursors[ply] = self.getDialogFor(ply)
+ --
+ -- if self.oyaw ~= 0 and self.oacc ~= 0 then
+ -- self.oyaw, self.oacc,self.onod = self.loco:GetMaxYawRate(), self.loco:GetAcceleration(), self.curnode
+ -- end
+ -- self.loco:SetAcceleration(0)
+ -- self.loco:SetVelocity(Vector(0,0,0))
+ -- self.loco:SetMaxYawRate(9999990)
+ -- self.loco:FaceTowards(ply:GetPos())
+ -- self.loco:SetMaxYawRate(0)
+ timer.Simple(0.5,function()
+ --self.loco:FaceTowards(ply:GetPos())
+
+
+ end)
+ net.Start("art_opennpcdialog")
+ net.WriteEntity(self)
+ net.WriteTable(SendableDialog(self.DialogCursors[ply]))
+ net.Send(ply)
+ end
+end
+
+net.Receive("art_updatenpcdialog",function(len,ply)
+ local npc = net.ReadEntity()
+ local option = net.ReadString()
+ npc.DialogCursors[ply] = npc.DialogCursors[ply]["Options"][option](ply)
+ net.Start("art_opennpcdialog")
+ net.WriteEntity(npc)
+ net.WriteTable(SendableDialog(npc.DialogCursors[ply]))
+ net.Send(ply)
+end)
+
+scripted_ents.Register(ENT, "art_npc")