diff options
| author | Alexander Pickering <alexandermpickering@gmail.com> | 2017-08-07 18:22:29 -0400 |
|---|---|---|
| committer | Alexander Pickering <alexandermpickering@gmail.com> | 2017-08-07 18:22:29 -0400 |
| commit | daa59a7835c350a09dcb207c714acf57828137f3 (patch) | |
| tree | ae2c00da0e546447ca17a9c5d8492310e5e93f27 /lua/entities | |
| download | artery_editor-daa59a7835c350a09dcb207c714acf57828137f3.tar.gz artery_editor-daa59a7835c350a09dcb207c714acf57828137f3.tar.bz2 artery_editor-daa59a7835c350a09dcb207c714acf57828137f3.zip | |
Inital Commit
Diffstat (limited to 'lua/entities')
| -rw-r--r-- | lua/entities/info_edit_townienode/cl_init.lua | 74 | ||||
| -rw-r--r-- | lua/entities/info_edit_townienode/init.lua | 54 | ||||
| -rw-r--r-- | lua/entities/info_edit_townienode/shared.lua | 13 | ||||
| -rw-r--r-- | lua/entities/info_huntablespawn/cl_init.lua | 71 | ||||
| -rw-r--r-- | lua/entities/info_huntablespawn/init.lua | 18 | ||||
| -rw-r--r-- | lua/entities/info_huntablespawn/shared.lua | 27 | ||||
| -rw-r--r-- | lua/entities/info_programmable_base/cl_init.lua | 124 | ||||
| -rw-r--r-- | lua/entities/info_programmable_base/init.lua | 148 | ||||
| -rw-r--r-- | lua/entities/info_programmable_base/shared.lua | 12 | ||||
| -rw-r--r-- | lua/entities/info_townieshop/cl_init.lua | 173 | ||||
| -rw-r--r-- | lua/entities/info_townieshop/init.lua | 59 | ||||
| -rw-r--r-- | lua/entities/info_townieshop/shared.lua | 13 | ||||
| -rw-r--r-- | lua/entities/info_towniespawn/cl_init.lua | 109 | ||||
| -rw-r--r-- | lua/entities/info_towniespawn/init.lua | 125 | ||||
| -rw-r--r-- | lua/entities/info_towniespawn/shared.lua | 12 | ||||
| -rw-r--r-- | lua/entities/npc_huntable/cl_init.lua | 66 | ||||
| -rw-r--r-- | lua/entities/npc_huntable/init.lua | 80 | ||||
| -rw-r--r-- | lua/entities/npc_huntable/shared.lua | 180 |
18 files changed, 1358 insertions, 0 deletions
diff --git a/lua/entities/info_edit_townienode/cl_init.lua b/lua/entities/info_edit_townienode/cl_init.lua new file mode 100644 index 0000000..87d4201 --- /dev/null +++ b/lua/entities/info_edit_townienode/cl_init.lua @@ -0,0 +1,74 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +include("shared.lua") + +ENT.RenderGroup = RENDERGROUP_BOTH + +function ENT:Draw() + render.SetColorMaterial() + render.DrawSphere( self:GetPos(), 10, 30, 30, Color( 0, 175, 175, 100 ) ) + +end + +local function syncentity(ent,data) + print("sending data to server") + net.Start("edit_townienode_update") + net.WriteEntity(ent) + net.WriteTable(data) + net.SendToServer() +end + +net.Receive("edit_navnode",function() + local who = net.ReadEntity() + local data = net.ReadTable() + + local editorframe = vgui.Create("DFrame") + editorframe:SetSize(640,480) + editorframe:SetDraggable(true) + editorframe:MakePopup() + editorframe.OnClose = function(self) + syncentity(who,data) + end + + local editor = vgui.Create("DPanel",editorframe) + editor:Dock(FILL) + + local namelabel = vgui.Create("DLabel",editor) + namelabel:SetText("Name:") + namelabel:SetDark(true) + namelabel:Dock(TOP) + local nametext = vgui.Create("DTextEntry",editor) + nametext:Dock(TOP) + nametext:SetText(data.Name) + nametext:SetUpdateOnType(true) + nametext.OnValueChange = function(self,value) + data.Name = value + end + + local onreachedlabel = vgui.Create("DLabel",editor) + onreachedlabel:SetText("OnReached()") + onreachedlabel:SetDark(true) + onreachedlabel:Dock(TOP) + local onreachedtext = vgui.Create("DTextEntry",editor) + onreachedtext:SetHeight(150) + onreachedtext:Dock(TOP) + onreachedtext:SetMultiline(true) + onreachedtext:SetText(data.OnReached) + onreachedtext:SetTabbingDisabled(true) + onreachedtext.OnValueChange = function(self,value) + data.OnReached = value + end + + local isfinlabel = vgui.Create("DLabel",editor) + isfinlabel:SetText("IsFinished()") + isfinlabel:SetDark(true) + isfinlabel:Dock(TOP) + local isfintext = vgui.Create("DTextEntry",editor) + isfintext:SetHeight(150) + isfintext:Dock(TOP) + isfintext:SetMultiline(true) + isfintext:SetText(data.IsDone) + isfintext.OnValueChange = function(self,value) + data.IsDone = value + end +end) diff --git a/lua/entities/info_edit_townienode/init.lua b/lua/entities/info_edit_townienode/init.lua new file mode 100644 index 0000000..e4702da --- /dev/null +++ b/lua/entities/info_edit_townienode/init.lua @@ -0,0 +1,54 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +AddCSLuaFile( "cl_init.lua" ) -- Make sure clientside +AddCSLuaFile( "shared.lua" ) -- and shared scripts are sent. + +include('shared.lua') + +ENT.default_data = { + Model = "models/humans/Group02/Male_03.mdl", + NavNodes = {}, + Pos = nil +} + +ENT.edit_data = { + Size = HULL_TINY, + Type = "navnode", + Model = "models/editor/ground_node.mdl", + get_default_code = function(who) + local default_navnode = [[ + + + + +local node = { + ["Name"] = "%s", --@tagname + ["Position"] = Vector(%f, %f, %f), --@tagpos + ["OnReached"] = function(npc) + + end, + ["IsDone"] = function(npc) + + end, +} +nrequire("sv_npcsystem.lua").CreateNavNode(node) + ]] + local pos = who:GetPos() + local name = "Default Node" + return string.format(default_navnode,name,pos.x,pos.y,pos.z) + end +} +local init = ENT.Initalize +function ENT:Initalize() + print("In towniespawn's initalize") + init(self) +end + +function ENT:OnSave() + print("Node's OnSave was called") + local newtxt = file.Read(self.File,"DATA") + print("new text was",newtxt) + local newname = newtxt:match("%[\"Name\"%] = \"(.-)\", %-%-@tagname") + print("new name is,",newname) + self.Name = newname +end diff --git a/lua/entities/info_edit_townienode/shared.lua b/lua/entities/info_edit_townienode/shared.lua new file mode 100644 index 0000000..2197cb6 --- /dev/null +++ b/lua/entities/info_edit_townienode/shared.lua @@ -0,0 +1,13 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +ENT.Type = "anim" +ENT.Base = "info_programmable_base" + +ENT.PrintName= "Townie Node" +ENT.Author= "Apickx" +ENT.Contact= "cogarr.net" +ENT.Purpose= "Set a point of intrest" +ENT.Instructions= "Make sure the npc knows to go to this node" +ENT.Spawnable = true +ENT.AdminSpawnable = false +ENT.Category = "Artery" diff --git a/lua/entities/info_huntablespawn/cl_init.lua b/lua/entities/info_huntablespawn/cl_init.lua new file mode 100644 index 0000000..6a96b80 --- /dev/null +++ b/lua/entities/info_huntablespawn/cl_init.lua @@ -0,0 +1,71 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +include('shared.lua') + +ENT.RenderGroup = RENDERGROUP_BOTH + +/*--------------------------------------------------------- + Name: Draw + Desc: Draw it! +---------------------------------------------------------*/ +function ENT:Draw() + --self:DrawModel() + render.SetColorMaterial() + render.DrawSphere( self:GetPos(), 10, 30, 30, Color( 255, 0, 0, 100 ) ) + +end + +/*--------------------------------------------------------- + Name: DrawTranslucent + Desc: Draw translucent +---------------------------------------------------------*/ +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 + +/*--------------------------------------------------------- + Name: BuildBonePositions + Desc: +---------------------------------------------------------*/ +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 + + + +/*--------------------------------------------------------- + Name: SetRagdollBones + Desc: +---------------------------------------------------------*/ +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 + + +/*--------------------------------------------------------- + Name: DoRagdollBone + Desc: +---------------------------------------------------------*/ +function ENT:DoRagdollBone( PhysBoneNum, BoneNum ) + + // self:SetBonePosition( BoneNum, Pos, Angle ) + +end diff --git a/lua/entities/info_huntablespawn/init.lua b/lua/entities/info_huntablespawn/init.lua new file mode 100644 index 0000000..20cac81 --- /dev/null +++ b/lua/entities/info_huntablespawn/init.lua @@ -0,0 +1,18 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +--[[ + This entity gives townies things to do +]] +AddCSLuaFile( "cl_init.lua" ) +AddCSLuaFile( "shared.lua" ) + +include("shared.lua") + +function ENT:Initialize() + self:SetModel("models/error.mdl") + self:SetMoveType(MOVETYPE_NONE) + self:SetSolid(SOLID_NONE) + self:SetCollisionGroup(COLLISION_GROUP_INTERACTIVE) + --self:SetNoDraw(true) + self:SetPos(self.Position) +end diff --git a/lua/entities/info_huntablespawn/shared.lua b/lua/entities/info_huntablespawn/shared.lua new file mode 100644 index 0000000..4fd0019 --- /dev/null +++ b/lua/entities/info_huntablespawn/shared.lua @@ -0,0 +1,27 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +ENT.Base = "base_entity" + +//WS stuff +ENT.Drops = nil +ENT.OnDammage = nil +ENT.Speed = 0 +ENT.Model = nil + +ENT.Behave = nil +ENT.Act = nil + +ENT.Editable = true + +/*--------------------------------------------------------- + Name: OnRemove + Desc: Called just before entity is deleted +---------------------------------------------------------*/ +function ENT:OnRemove() +end + +function ENT:DoActivity(npc) + if not self.onActivity() then + print("Node without activity, this might be an error!") + end +end diff --git a/lua/entities/info_programmable_base/cl_init.lua b/lua/entities/info_programmable_base/cl_init.lua new file mode 100644 index 0000000..fc1ada0 --- /dev/null +++ b/lua/entities/info_programmable_base/cl_init.lua @@ -0,0 +1,124 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +include('shared.lua') + +--Don't draw our hull model +function ENT:Draw() +end + +local function draw_edit_panel(filename,who) + if not GCompute then error("GCompute not installed!") end + if not GCompute.IDE then error("GCompute was initalized wrong or has changed, update this file!") end + local inst = GCompute.IDE.GetInstance() + inst:SetVisible (true) + + print("Opening file browser!") + + --Remove donation panel + for k,v in pairs(inst.ViewManager.Views) do + if type(k) == "table" and k.Title == "Donate!" then + k:SetVisible(false) + end + end + + local fileuri = "game/data/" .. filename + print("Trying to open","game/data/" .. filename) + + --Open up this npc's file + inst:OpenFile(fileuri,function(succ,res,view) + view:Select() + end) + + --Set our file browser to the right place + for k,v in pairs(inst.ViewManager.Views) do + if k.Title == "File Browser" then + + k.FolderListView:SetPath(string.GetPathFromFilename(fileuri)) + end + end + + --Detour it's save to let the server know the file was saved. + local doc = inst.DocumentManager.DocumentsByUri[fileuri] + print("Doc was",doc) + doc:AddEventListener("Saved",function() + print("Saved",doc) + net.Start("edit_sendsave") + net.WriteString(doc.Uri) + net.WriteEntity(who) + net.SendToServer() + end) + + +end + +function Reload_Gcompute(what) + print("attempting to refresh instances of ", what) + local inst = GCompute.IDE:GetInstance() + for k,v in pairs(inst.ViewManager.ViewsById) do + if v.Title == what then + v:CreateFileChangeNotificationBar () + v.FileChangeNotificationBar:DispatchEvent("ReloadRequested") + local oldvisible = v.FileChangeNotificationBar.SetVisible + v.FileChangeNotificationBar.SetVisible = function(self,bool) + if bool then + self.SetVisible = oldvisible + end + end + break + end + end +end + +net.Receive("edit_notify_file_changed",function() + local what = net.ReadString() + Reload_Gcompute(what) +end) + +net.Receive("edit_confirmremove",function() + local who = net.ReadString() + local frame = vgui.Create( "DFrame" ) + frame:SetSize( 300, 250 ) + frame:Center() + frame:MakePopup() + + local but = vgui.Create( "DButton", frame ) + but:SetText( "\nYes, I want to remove\n" .. who .. "\n") + but:Dock(TOP) + but.DoClick = function() // A custom function run when clicked ( note the . instead of : ) + net.Start("edit_removeconfirmed") + net.WriteString(who) + net.SendToServer() + frame:Close() + end + + local but2 = vgui.Create("DButton",frame) + but2:SetText("\nNo I don't want to remove\n" .. who .. "\n") + but2:Dock(BOTTOM) + but2.DoClick = function() // A custom function run when clicked ( note the . instead of : ) + net.Start("edit_removedeny") + net.WriteString(who) + net.SendToServer() + frame:Close() + end + but:SizeToContents() + but2:SizeToContents() +end) + +net.Receive("edit_sendopen",function() + + print('got request to edit someone') + local file = net.ReadString() + local who = net.ReadEntity() + print(file) + draw_edit_panel(file,who) +end) + +hook.Add( "Think", "edit_type_tip", function() + local tr = LocalPlayer():GetEyeTrace() + local e = tr.Entity + if e.Entity then + AddWorldTip( nil, e:GetClass(), nil, tr.HitPos, e ) + end + + +end ) diff --git a/lua/entities/info_programmable_base/init.lua b/lua/entities/info_programmable_base/init.lua new file mode 100644 index 0000000..9fed830 --- /dev/null +++ b/lua/entities/info_programmable_base/init.lua @@ -0,0 +1,148 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +AddCSLuaFile( "cl_init.lua" ) -- Make sure clientside +AddCSLuaFile( "shared.lua" ) -- and shared scripts are sent. + +include('shared.lua') + +local file_base = string.format("artery/maps/%s",game.GetMap()) + +local hulls = { + [HULL_HUMAN] = { + Model = "models/props_phx/construct/metal_tubex2.mdl", + Angle = Angle(0,0,0) + }, + [HULL_TINY] = { + Model = "models/props_phx/construct/metal_tube.mdl", + Angle = Angle(0,0,0) + } +} + +function ENT:Initialize() + --The hull + local thull = hulls[self.edit_data.Size] + self:SetModel(thull.Model) + self:SetAngles(thull.Angle) + + --The entity + self:PhysicsInit( SOLID_VPHYSICS ) -- Make us work with physics, + self:SetMoveType( MOVETYPE_VPHYSICS ) -- after all, gmod is a physics + self:SetSolid( SOLID_VPHYSICS ) -- Toolbox + --[[ + local phys = self:GetPhysicsObject() + if (phys:IsValid()) then + phys:Wake() + end + ]] + self:SetCollisionGroup(COLLISION_GROUP_WORLD) + self:SetUseType(SIMPLE_USE) + + print("My edit data:",self) + PrintTable(self.edit_data) + + --The visual + local e = ents.Create("prop_dynamic") + e:SetPos(self:GetPos()) + e:SetModel(self.edit_data.Model) + if self.edit_data.OnSpawn ~= nil then + self.edit_data.OnSpawn(self) + end + e:SetParent(self) + e:Spawn() + + --Make sure the folder we want to be in exists + local grouping = self.edit_data.Type or "" + local folder = string.format("%s/%s",file_base,grouping) + if not file.Exists(folder,"DATA") then + print("Createing dir",folder) + file.CreateDir(folder) + end + + --Make sure whoever made us has attached a file + if self.File == nil then + print("Createing a new file for",self) + local c = self:GetClass() + local ind = #ents.FindByClass(c) + print("Found",ind,"number of",c) + self.File = string.format("%s/%s_%d.txt",folder,c,ind) + end + assert(self.File, "A programmable entity was made without a file attached!") + +end + +hook.Add("OnPhysgunFreeze","programmable_freezer",function(wep,phys,ent,ply) + print("I want to do something to ",ent) + if ent.RefreshChangeables ~= nil then + ent:RefreshChangeables() + end +end) + +util.AddNetworkString("edit_notify_file_changed") +function ENT:notify_file_changed(what) + net.Start("edit_notify_file_changed") + net.WriteString(string.GetFileFromFilename(what)) + net.Broadcast() +end + +function ENT:RefreshChangeables() + print("I",self,"Want to refresh my changeables in",self.File) + local filetxt = file.Read(self.File,"DATA") + print("filetxt was",filetxt) + if not filetxt then return end --We haven't pressed e to generate the file yet + --Oh god this is one hell of a pattern. Just trust that it works I guess + local pos = self:GetPos() + local ang = self:GetAngles() + local ntxt = filetxt + :gsub("Vector[^\n]*%-%-@tagpos",string.format("Vector(%f,%f,%f), --@tagpos",pos.x,pos.y,pos.z)) + :gsub("Angle[^\n]*%-%-@tagang",string.format("Angle(%f,%f,%f), --@tagang",ang.p,ang.y,ang.r)) + print("Writeing to",self.File,ntxt) + file.Write(self.File,ntxt) + self:notify_file_changed(self.File) +end + +util.AddNetworkString("edit_confirmremove") +util.AddNetworkString("edit_removeconfirmed") +util.AddNetworkString("edit_removedeny") +function ENT:OnRemove() + net.Start("edit_confirmremove") + net.WriteString(self.File) + net.Send(Entity(1)) + return false +end +net.Receive("edit_removeconfirmed",function() + local who = net.ReadString() + file.Delete(who) +end) +net.Receive("edit_removedeny",function() + local who = net.ReadString() + loadtownies() +end) + +util.AddNetworkString("edit_sendopen") +function ENT:Use( activator, caller ) + --Open up the npc's file (create it if it dosen't already exist) + if not file.Exists(self.File, "DATA") then + file.Write(self.File,self.edit_data.get_default_code(self)) + end + + net.Start("edit_sendopen"); + net.WriteString(self.File) + net.WriteEntity(self) + net.Send(caller) +end + +util.AddNetworkString("edit_sendsave") +net.Receive("edit_sendsave",function() + local file = net.ReadString() + local who = net.ReadEntity() + print("I got a save for", file, who) + who:OnSave() +end) + +function ENT:OnSave() + print("On save was called!") +end + +function ENT:Think() +-- We don't need to think, we are just a prop after all! +end diff --git a/lua/entities/info_programmable_base/shared.lua b/lua/entities/info_programmable_base/shared.lua new file mode 100644 index 0000000..86de4d2 --- /dev/null +++ b/lua/entities/info_programmable_base/shared.lua @@ -0,0 +1,12 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +ENT.Base = "base_entity" + +ENT.PrintName= "Programmable base" +ENT.Author= "Apickx" +ENT.Contact= "cogarr.net" +ENT.Purpose= "A base for other programmables" +ENT.Instructions= "Don't use this probably!" +ENT.Spawnable = false +ENT.AdminSpawnable = false +ENT.Category = "Artery" diff --git a/lua/entities/info_townieshop/cl_init.lua b/lua/entities/info_townieshop/cl_init.lua new file mode 100644 index 0000000..2caccd4 --- /dev/null +++ b/lua/entities/info_townieshop/cl_init.lua @@ -0,0 +1,173 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +include('shared.lua') + +function ENT:Draw() + --self:DrawModel() -- Draws Model Client Side +end + +function ENT:Hint() + AddWorldTip( self:EntIndex(), "Spawnpoint", 0.5, self:GetPos(), self ) +end + +local function syncentity(ent,data) + print("sending data to server") + PrintTable(data) + net.Start("edit_towniespawn_update") + net.WriteEntity(ent) + net.WriteTable(data) + net.SendToServer() +end + +local navnode_info = {} + +concommand.Add("artery_getnavnodes",function() + net.Start("edit_requestnavnodes") + net.SendToServer() +end) + +net.Receive("edit_respondnavnodes",function() + navnode_info = net.ReadTable() + print("client received navnode info:") + PrintTable(navnode_info) +end) + +local function draw_edit_panel(who, data) + if not GCompute then error("GCompute not installed!") end + if not GCompute.IDE then error("GCompute was initalized wrong or has changed, update this file!") end + local inst = GCompute.IDE.GetInstance() + inst:SetVisible (true) + + print("Opening file browser!") + PrintTable(data) + + --Remove donation panel + for k,v in pairs(inst.ViewManager.Views) do + if type(k) == "Table" and k.Title == "Donate!" then + k:SetVisible(false) + end + end + + --Open up the npc's file (create it if it dosen't already exist) + local filename = "artery/maps/" .. game.GetMap() .. "/npcs/" .. data.Name .. ".txt" + if not file.Exists(filename, "DATA") then + local pos = who:GetPos() + local npctxt = string.format(default_townie,pos.x,pos.y,pos.z,data.Model,data.Name,table.concat(data.NavNodes),data.Name) + file.Write(filename,npctxt) + end + + --Open up this npc's file + inst:OpenUri("game/data/" .. filename,function(succ,res,view) + view:Select() + end) + + --Set our file browser to the right place + for k,v in pairs(inst.ViewManager.Views) do + if k.Title == "File Browser" then + k.FolderListView:SetPath("/game/data/artery/maps/" .. game.GetMap() .. "/npcs") + end + end + + --Add a list of nav nodes we found + local p = ents.FindByClass("info_townienode") + +end + +net.Receive("edit_towniespawn",function() + + print('got request to edit someone') + local who = net.ReadEntity() + local data = net.ReadTable() + + draw_edit_panel(who,data) + + --[[ + local editorframe = vgui.Create("DFrame") + editorframe.OnClose = function(self) + syncentity(who,data) + end + editorframe:SetSize(640,640) + editorframe:SetTitle("Townie spawn") + editorframe:SetDraggable(true) + editorframe:MakePopup() + local editor = vgui.Create("DPanel",editorframe) + editor:Dock(FILL) + + --Edit name + local namelabel = vgui.Create("DLabel",editor) + namelabel:SetText("Townie Name:") + namelabel:Dock(TOP) + namelabel:SetDark(true) + local nameentry = vgui.Create("DTextEntry",editor) + nameentry:Dock(TOP) + nameentry:SetText(data.Name) + nameentry:SetUpdateOnType(true) + nameentry.OnValueChange = function(self,value) + data.Name = value + end + + --Edit model + local modellabel = vgui.Create("DLabel",editor) + modellabel:SetText("Townie Model:") + modellabel:Dock(TOP) + modellabel:SetDark(true) + local modelentry = vgui.Create("DTextEntry",editor) + modelentry:Dock(TOP) + modelentry:SetText(data.Model) + modelentry:SetUpdateOnType(true) + modelentry.OnValueChange = function(self,value) + data.Model = value + end + + --Edit navnodes + local navnodelist = vgui.Create("DListLayout",editor) + navnodelist:Dock(FILL) + local allnavents = ents.FindByClass("info_townienode") + + local function create_navnode_panel(v) + local navnodeitm = vgui.Create("DPanel") + + local navname = vgui.Create("DComboBox",navnodeitm) + for i,j in pairs(navnode_info) do + navname:AddChoice(j.Name) + end + navname:SetValue(v) + navname:Dock(LEFT) + navname.OnSelect = function(self,index,value) + data.NavNodes[index] = value + end + + local navdelete = vgui.Create("DButton",navnodeitm) + navdelete:SetText("-") + navdelete.DoClick = function() + print('Tryint to get rid of nav node', v) + --delete it from the data + for i,j in pairs(data.NavNodes) do + if j == v then + for k = i, #data.NavNodes do + data.NavNodes[i] = data.NavNodes[i+1] + end + break + end + end + --and remove the panel + navnodeitm:Remove() + end + navdelete:Dock(RIGHT) + + return navnodeitm + end + + for k,v in pairs(data.NavNodes) do + local navnodeitm = create_navnode_panel(v) + navnodelist:Add(navnodeitm) + end + local addbutton = vgui.Create("DButton",editor) + addbutton:SetText("+") + addbutton.DoClick = function() + local navnodeitm = create_navnode_panel("select") + navnodelist:Add(navnodeitm) + end + addbutton:Dock(BOTTOM) + ]] +end) diff --git a/lua/entities/info_townieshop/init.lua b/lua/entities/info_townieshop/init.lua new file mode 100644 index 0000000..1e93d93 --- /dev/null +++ b/lua/entities/info_townieshop/init.lua @@ -0,0 +1,59 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +AddCSLuaFile( "cl_init.lua" ) -- Make sure clientside +AddCSLuaFile( "shared.lua" ) -- and shared scripts are sent. + +include('shared.lua') + +ENT.default_data = { + Model = "models/humans/Group02/Male_03.mdl", + NavNodes = {}, + Pos = nil +} + +ENT.edit_data = { + Size = HULL_HUMAN, + Type = "npc", + Model = "models/editor/playerstart.mdl", + get_default_code = function(who) + local default_townie = [[ + + + + +local npc = { + ["Pos"] = Vector(%f,%f,%f), + ["Model"] = %q, + ["Name"] = "%s", + ["NavNodes"] = {}, + ["OnSpawn"] = function(nnpc) + print("At time onspawn was called, nnpc was",nnpc) + nnpc:StartActivity(ACT_IDLE) + end +} + +npc.shopitems = { + {"Scrap Hammer",10}, --Items of the form {string_itemname,number_cost} + {"Rat Meat",5}, +} + +nrequire("sv_npcsystem.lua").CreateShop(npc) + ]] + local pos = who:GetPos() + local model = "models/humans/Group02/Male_03.mdl" + local name = "Default Shopkeep" + return string.format(default_townie,pos.x,pos.y,pos.z,model,name,"{}",name) + end +} +--[[ +local init = ENT.Initalize +function ENT:Initalize() + print("In towniespawn's initalize") + init(self) +end +]] + +hook.Add("OnPhysgunFreeze",function(wep,phys,ent,ply) + print("Detected freeze") + --See if we should update position and andgle +end) diff --git a/lua/entities/info_townieshop/shared.lua b/lua/entities/info_townieshop/shared.lua new file mode 100644 index 0000000..8202b26 --- /dev/null +++ b/lua/entities/info_townieshop/shared.lua @@ -0,0 +1,13 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +ENT.Type = "anim" +ENT.Base = "info_progammable_base" + +ENT.PrintName= "Townie Shopkeep" +ENT.Author= "Apickx" +ENT.Contact= "cogarr.net" +ENT.Purpose= "Set a spawn point" +ENT.Instructions= "Make sure there's a 32x32 box for players to spawn!" +ENT.Spawnable = true +ENT.AdminSpawnable = false +ENT.Category = "Artery" diff --git a/lua/entities/info_towniespawn/cl_init.lua b/lua/entities/info_towniespawn/cl_init.lua new file mode 100644 index 0000000..178160c --- /dev/null +++ b/lua/entities/info_towniespawn/cl_init.lua @@ -0,0 +1,109 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +include('shared.lua') + +function ENT:Draw() + --self:DrawModel() -- Draws Model Client Side +end + +function ENT:Hint() + AddWorldTip( self:EntIndex(), "Spawnpoint", 0.5, self:GetPos(), self ) +end + +local navnodes = {} +local selectors = {} + +local function sync_navnode_table(who) + print("Synching navnodes, table is") + PrintTable(navnodes) + net.Start("edit_townie_navchange") + net.WriteEntity(who) + net.WriteTable(navnodes) + net.SendToServer() +end + +local function add_nav_item(layout,name,elist,who) + print("Adding nav item",layout,name,elist) + local holder = vgui.Create("DPanel",layout) + + local selector = vgui.Create("DComboBox",holder) + selector.num = #navnodes + 1 + print("adding the ", selector.num, "selector") + selectors[selector.num] = selector + selector:Dock(FILL) + for k,v in pairs(elist) do + print("Adding option",v) + selector:AddChoice(v) + end + if name ~= nil then + selector:SetValue(name) + navnodes[#navnodes+1] = name + end + + selector:SetWidth(150) + + selector.OnSelect = function(self,index,value) + print(value,"selected","on",selector.num) + navnodes[selector.num] = value + sync_navnode_table(who) + end + + local delete = vgui.Create("DButton",holder) + delete:Dock(RIGHT) + delete:SetText("-") + delete.DoClick = function(self) + for i = selector.num,#navnodes do + navnodes[i] = navnodes[i+1] + selectors[i] = selectors[i+1] + if IsValid(selectors[i]) then + selectors[i].num = selectors[i].num - 1 + end + end + holder:Remove() + sync_navnode_table(who) + end + + layout:Add(holder) +end + +net.Receive("edit_townie_use",function() + print("I want to make the edit panel for a townie") + navnodes = {} + local who = net.ReadEntity() + local tbl = net.ReadTable() --Current nav nodes for this townie + local posi = net.ReadTable() --A list of all nav nodes in the map + local editorframe = vgui.Create( "DFrame" ) + editorframe:SetPos( 100, 100 ) + editorframe:SetSize( 300, 200 ) + editorframe:SetTitle( "Edit" .. tostring(who) ) + editorframe:SetDraggable( true ) + editorframe:MakePopup() + + local editor = vgui.Create("DPanel",editorframe) + editor:Dock(FILL) + + local layout = vgui.Create( "DListLayout", editor ) + layout:Dock(FILL) + + print("Already setup navnodes:",tbl) + PrintTable(tbl) + + for k,v in pairs(tbl) do + print("adding",layout,v,slist) + add_nav_item(layout,v,posi,who) + end + + print("After creation, navnodes are") + PrintTable(navnodes) + + local addbutton = vgui.Create("DButton",layout) + addbutton:Dock(BOTTOM) + addbutton:SetText("+") + addbutton.DoClick = function() + add_nav_item(layout,nil,posi,who) + end + + layout:SetSize( 100, 100 ) + layout:SetPos( 20, 50 ) + +end) diff --git a/lua/entities/info_towniespawn/init.lua b/lua/entities/info_towniespawn/init.lua new file mode 100644 index 0000000..a785212 --- /dev/null +++ b/lua/entities/info_towniespawn/init.lua @@ -0,0 +1,125 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +AddCSLuaFile( "cl_init.lua" ) -- Make sure clientside +AddCSLuaFile( "shared.lua" ) -- and shared scripts are sent. + +include('shared.lua') + +ENT.default_data = { + Model = "models/humans/Group02/Male_03.mdl", + NavNodes = {}, + Pos = nil +} + +ENT.edit_data = { + Size = HULL_HUMAN, + Type = "npc", + Model = "models/editor/playerstart.mdl", + get_default_code = function(who) + local default_townie = [[ + + + + +local function ChatGreat(ply) + return { + Name = "You can change the name midway!", + Message = "That's wonderful!", + Options = {} + } +end + +local npc = { + ["Pos"] = Vector(%f,%f,%f), --@tagpos + ["Ang"] = Angle(%f,%f,%f), --@tagang + ["Model"] = %q, + ["Name"] = "%s", + ["NavNodes"] = { --@tagnodes + + }, + ["getDialogFor"] = function(ply) + return { + ["Name"] = "%s", + ["Message"] = "Hey, how are you doing," .. ply:Nick(), + ["Options"] = { + ["Great!"] = ChatGreat + } + } + end +} +nrequire("sv_npcsystem.lua").CreateTownie(npc) + ]] + local pos = who:GetPos() + local ang = who:GetAngles() + local model = "models/humans/Group02/Male_03.mdl" + local name = "Default Townie" + return string.format(default_townie,pos.x,pos.y,pos.z,ang.p,ang.y,ang.r,model,name,name) + end, + OnSpawn = function(self) + print("Onspawn of", self, "called") + if not self.data then self.data = {} end + end +} + +local last_townie_use = CurTime() +hook.Add("FindUseEntity","hook_towniespawn_use",function(ply,defaultent) + --print("Looking at", IsValid(defaultent), ":", defaultent:GetClass(), ":", last_townie_use + 2, CurTime()) + if not IsValid(defaultent) or defaultent:GetClass() ~= "info_towniespawn" or last_townie_use + 2 > CurTime() then return end + print("Townie's use is called!") + net.Start("edit_townie_use") + net.WriteEntity(defaultent) + local ntbl = {} + for k,v in pairs(defaultent.data) do + ntbl[#ntbl+1] = v + end + print("Sending data to client:") + PrintTable(ntbl) + net.WriteTable(ntbl) + local allnodes = ents.FindByClass("info_edit_townienode") + local stbl = {} + for k,v in pairs(allnodes) do + stbl[#stbl+1] = v.Name + end + net.WriteTable(stbl) + net.Send(ply) + last_townie_use = CurTime() +end) + +util.AddNetworkString("edit_townie_navchange") +net.Receive("edit_townie_navchange",function() + local who = net.ReadEntity() + local newnodes = net.ReadTable() + local thisfile = who.File + assert(thisfile,"Failed to find file for entity!") + local filetxt = file.Read(thisfile) + assert(filetxt,"No such file:" .. thisfile) + local stbl = {} + print("newnodes is:") + PrintTable(newnodes) + for k,v in pairs(newnodes) do + stbl[#stbl + 1] = string.format("[\"%s\"] = true",v) + end + print("nanodes to format are:") + PrintTable(stbl) + local nntxt = table.concat(stbl,",\n\t\t") + print("nntxt is", nntxt) + local subtxt = string.format([[ +["NavNodes"] = { --@tagnodes + %s + }]],nntxt) + local newtxt, count = filetxt:gsub("%[\"NavNodes\"%] = { %-%-@tagnodes.-}",subtxt) + assert(count > 0, "Failed to find text to replace.") + print("I want to write",newtxt) + file.Write(who.File,newtxt) + who.data = newnodes + who:notify_file_changed(who.File) +end) + +util.AddNetworkString("edit_townie_use") +--[[ +local init = ENT.Initalize +function ENT:Initalize() + print("In towniespawn's initalize") + init(self) +end +]] diff --git a/lua/entities/info_towniespawn/shared.lua b/lua/entities/info_towniespawn/shared.lua new file mode 100644 index 0000000..ea7ac99 --- /dev/null +++ b/lua/entities/info_towniespawn/shared.lua @@ -0,0 +1,12 @@ +if engine.ActiveGamemode() ~= "sandbox" then return end + +ENT.Base = "info_programmable_base" + +ENT.PrintName= "Townie Spawn" +ENT.Author= "Apickx" +ENT.Contact= "cogarr.net" +ENT.Purpose= "Set a spawn point" +ENT.Instructions= "Make sure there's a 32x32 box for players to spawn!" +ENT.Spawnable = true +ENT.AdminSpawnable = false +ENT.Category = "Artery" diff --git a/lua/entities/npc_huntable/cl_init.lua b/lua/entities/npc_huntable/cl_init.lua new file mode 100644 index 0000000..f941737 --- /dev/null +++ b/lua/entities/npc_huntable/cl_init.lua @@ -0,0 +1,66 @@ +include('shared.lua') + +ENT.RenderGroup = RENDERGROUP_BOTH + +/*--------------------------------------------------------- + Name: Draw + Desc: Draw it! +---------------------------------------------------------*/ +function ENT:Draw() + self:DrawModel() +end + +/*--------------------------------------------------------- + Name: DrawTranslucent + Desc: Draw translucent +---------------------------------------------------------*/ +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 + +/*--------------------------------------------------------- + Name: BuildBonePositions + Desc: +---------------------------------------------------------*/ +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 + + + +/*--------------------------------------------------------- + Name: SetRagdollBones + Desc: +---------------------------------------------------------*/ +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 + + +/*--------------------------------------------------------- + Name: DoRagdollBone + Desc: +---------------------------------------------------------*/ +function ENT:DoRagdollBone( PhysBoneNum, BoneNum ) + + // self:SetBonePosition( BoneNum, Pos, Angle ) + +end diff --git a/lua/entities/npc_huntable/init.lua b/lua/entities/npc_huntable/init.lua new file mode 100644 index 0000000..fcc8532 --- /dev/null +++ b/lua/entities/npc_huntable/init.lua @@ -0,0 +1,80 @@ +AddCSLuaFile("cl_init.lua") +AddCSLuaFile("shared.lua") +include("shared.lua") +local applyfields = {"Model", "Stats"} + +function ENT:Initialize() + --print("NPC spawned!") + --self:SetMoveType(MOVETYPE_STEP) + --self:SetSolid(SOLID_OBB) + --self:SetCollisionGroup(COLLISION_GROUP_PUSHAWAY ) + + --self:SetCollisionGroup(COLLISION_GROUP_INTERACTIVE) + for _, v in pairs(applyfields) do + assert(self[v], "NPC created without " .. v .. " this might be a bug!") + end + + self:SetModel(self.Model) + + if (self.Stats["Vitality"]) then + self:SetHealth(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.Stats["Speed"] then + self.loco:SetDesiredSpeed(self.Stats["Speed"]) + end + + if (self.OnSpawn) then + self:OnSpawn() + end +end + +function ENT:OnInjured(dmg) + print("Ent OnInjured fired! dmg was", dmg) + if self.OnDammage ~= nil then + self:OnDammage(dmg) + end +end + +function ENT:OnContact(ent) + if self.OnCollide ~= nil then + self:OnCollide(ent) + 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") + --error("You need to code how item drops work!") + local itemstodrop = {} + + 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 = ART.GetItemByName(itemname) + --print("Createing a drop of",drop) + --ART.CreateDroppedItem(drop, self:GetPos()) + end + end + + self:BecomeRagdoll(dmg) +end diff --git a/lua/entities/npc_huntable/shared.lua b/lua/entities/npc_huntable/shared.lua new file mode 100644 index 0000000..e42c100 --- /dev/null +++ b/lua/entities/npc_huntable/shared.lua @@ -0,0 +1,180 @@ +ENT.Base = "base_nextbot" +--ART stuff +ENT.Drops = nil +ENT.OnDammage = nil +ENT.Speed = 0 +ENT.Model = nil +ENT.Behave = nil +ENT.Act = nil +ENT.AutomaticFrameAdvance = true + +--[[--------------------------------------------------------- +Name: OnRemove +Desc: Called just before entity is deleted +---------------------------------------------------------]] +function ENT:OnRemove() +end + + +function ENT:DefaultBehaviour() + print("In default behavior") + self.lastrun = CurTime() + + --Set some stuff up for navigation + local path = Path( "Follow" ) + path:SetMinLookAheadDistance( self.lookahead or 300 ) + path:SetGoalTolerance( self.goaltolarance or 100) + path:Draw() + local delta = CurTime() - self.lastrun + self:AI(delta) + while (true) do + --print("Inside defaultbehaviour's while") + + --Sets all the values needed for the rest of this function to do it's thing + --Main loop for ai + + --print("Going into behavior for " .. self.Name) + --Update aware enemies + delta = CurTime() - self.lastrun + --print("delta was", delta) + if delta > 0.1 then + --print('Running ai') + self:AI(delta) + self.lastrun = CurTime() + end + + if self.TargetPos ~= nil then + if ( !path:IsValid() ) then print("Path wasn't valid!") end + if ( path:GetAge() > 0.1 ) then -- Since we are following the player we have to constantly repath + path:Compute( self, self.TargetPos ) -- Compute the path towards the enemy's position again + path:Update( self ) -- This function moves the bot along the path + end + + + if ( true ) then path:Draw() end + -- If we're stuck then call the HandleStuck function and abandon + if ( self.loco:IsStuck() ) then + --self:HandleStuck() + --return "stuck" + end + + --return "ok" + end + coroutine.yield() + end + + coroutine.yield() +end + + +function ENT:AI(num) + --print("Inside ai") + local players = player.GetAll() + + for k, v in pairs(players) do + 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 == nil) then + --print("Nill priority hit after ") + --PrintTable(self) + end + + if (priority > maxpriority) then + maxpriority = priority + maxprioritytarget = v + end + end + + self.Target = maxprioritytarget + --print("My target is",self.Target) + --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(1, #self.IdleSequences)) + print("Playing sequence",self.IdleSequences[randanim]) + self:PlaySequenceAndWait(self.IdleSequences[randanim]) + self:StartActivity(ACT_IDLE) + print("Acting 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 + --print("Closes player is " .. closest .. " removeing self...") + 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 + + --[[ + print("Before running, behavethread was", self.BehaveThread) + local ok, message = coroutine.resume( self.BehaveThread ) + if not ok then + self.BehaveThread = nil + Msg( self, "error: ", message, "\n" ); + end + ]] + + if (self.Act) then + self:Act(num) + else + print("NPC spawned without an Act function, this might be an error!") + end + +end + +function ENT:RunBehaviour() + print("Running behavior") + if (self.Behave) then + print("Doing self.behave") + self:Behave() + else + print("Doing default behavior") + self:DefaultBehaviour() + end +end |
