diff options
Diffstat (limited to 'gamemode')
| -rw-r--r-- | gamemode/cl_init.lua | 9 | ||||
| -rw-r--r-- | gamemode/client/cl_inventory.lua | 2 | ||||
| -rw-r--r-- | gamemode/client/cl_legs.lua | 1 | ||||
| -rw-r--r-- | gamemode/config/sv_newplayer.lua | 3 | ||||
| -rw-r--r-- | gamemode/core/combat/cl_weaponswing.lua | 57 | ||||
| -rw-r--r-- | gamemode/core/combat/sv_weaponswing.lua | 99 | ||||
| -rw-r--r-- | gamemode/core/database/sv_setup.lua | 13 | ||||
| -rw-r--r-- | gamemode/core/inventory/common/items.lua | 5 | ||||
| -rw-r--r-- | gamemode/core/inventory/sv_invtracker.lua | 36 | ||||
| -rw-r--r-- | gamemode/core/npc/sv_common.lua | 38 | ||||
| -rw-r--r-- | gamemode/core/npc/sv_huntingspawner.lua | 118 | ||||
| -rw-r--r-- | gamemode/core/npc/sv_npcsystem.lua | 40 | ||||
| -rw-r--r-- | gamemode/core/pac/cl_pac.lua | 10 | ||||
| -rw-r--r-- | gamemode/core/pac/sv_pac.lua | 6 | ||||
| -rw-r--r-- | gamemode/init.lua | 23 | ||||
| -rw-r--r-- | gamemode/inventorysystem/cl_common.lua | 4 | ||||
| -rw-r--r-- | gamemode/itemsystem/weapons/rustyaxe.lua | 31 | ||||
| -rw-r--r-- | gamemode/npcsystem/sv_blockingdummy.lua | 4 | ||||
| -rw-r--r-- | gamemode/npcsystem/sv_dummy.lua | 8 | ||||
| -rw-r--r-- | gamemode/npcsystem/sv_zombie.lua | 187 |
20 files changed, 632 insertions, 62 deletions
diff --git a/gamemode/cl_init.lua b/gamemode/cl_init.lua index 6b5d18a..2f80ddd 100644 --- a/gamemode/cl_init.lua +++ b/gamemode/cl_init.lua @@ -1 +1,10 @@ +--Find out where all our prints are comming from! +local oldprint = print +print = function(...) + oldprint(unpack({...})) + oldprint(debug.traceback()) +end + include( "shared.lua" ) + +print = oldprint diff --git a/gamemode/client/cl_inventory.lua b/gamemode/client/cl_inventory.lua index 0c84e5c..7fab07c 100644 --- a/gamemode/client/cl_inventory.lua +++ b/gamemode/client/cl_inventory.lua @@ -10,7 +10,7 @@ ]] local qinv = nrequire("cl_qinventory.lua") local state = nrequire("cl_state.lua") --Holds weather or not player is in inventory -local itm = nrequire("core/inventory/item.lua") +local itm = nrequire("core/inventory/common/items.lua") --local qpray = nrequire("cl_qprayers.lua") local inv = {} diff --git a/gamemode/client/cl_legs.lua b/gamemode/client/cl_legs.lua index c9703e1..506a0a9 100644 --- a/gamemode/client/cl_legs.lua +++ b/gamemode/client/cl_legs.lua @@ -1,3 +1,4 @@ +do return end --[[ The purpose of this file is to render the client's legs diff --git a/gamemode/config/sv_newplayer.lua b/gamemode/config/sv_newplayer.lua index 9bb1420..fc66c82 100644 --- a/gamemode/config/sv_newplayer.lua +++ b/gamemode/config/sv_newplayer.lua @@ -5,7 +5,8 @@ local itm = nrequire("inventory/item.lua") np.newdata = function() return { inventories = { - {"Equipment", inv.CreateInventory("Equipment"):Serialize()} + {"Equipment", inv.CreateInventory("Equipment"):Serialize()}, + {"Shaped Inventory",inv.CreateInventory("Shaped Inventory"):Serialize()} }, skills = {}, prayers = {}, diff --git a/gamemode/core/combat/cl_weaponswing.lua b/gamemode/core/combat/cl_weaponswing.lua new file mode 100644 index 0000000..8ed9637 --- /dev/null +++ b/gamemode/core/combat/cl_weaponswing.lua @@ -0,0 +1,57 @@ +local CLIENT_PAC_DIR = "artery/client/pacs" + +local ball +function finddmgpoint(name) + local filepath = string.format(CLIENT_PAC_DIR .. "/%s.txt",name) + local filetext = file.Read(filepath,"DATA") + local outfit = CompileString(string.format("return {%s}",filetext),name)() + ball = LocalPlayer():FindPACPart(outfit, "wep_point") + print("point is",ball,type(ball)) +end + +local swingtbl = {} +local tracking = false + +net.Receive("artery_doanimation",function() + local animname = net.ReadString() + local animtime = net.ReadDouble() + local wepname = net.ReadString() + local animdir = net.ReadString() + + swingtbl = {} + tracking = true + finddmgpoint(wepname) + print("Doing animation:",animname,animtime,echoname) + LocalPlayer():SetLuaAnimation(animname) + timer.Simple(animtime,function() + tracking = false + LocalPlayer():StopLuaAnimation(animname) + net.Start("artery_notifyserverofswing") + net.WriteString(wepname) + net.WriteString(animdir) + print("Seding swingtbl:") + PrintTable(swingtbl) + net.WriteTable(swingtbl) + net.SendToServer() + end) +end) + +concommand.Add("artery_startanimation",function(ply,cmd,args) + swingtbl = {} + ply:SetLuaAnimation(args[1]) + timer.Simple(args[2],function() + ply:StopLuaAnimation(args[1]) + end) +end) + +local lastpos +hook.Add("Tick","trace_weppos",function() + if not ball then return end + if lastpos == nil then lastpos = ball.Entity:GetPos() end + --`print("Distance between ", ball.Entity:GetPos(), "and", lastpos, " is" ,ball.Entity:GetPos():Distance(lastpos)) + if ball.Entity:GetPos():Distance(lastpos) > 2 and tracking then + swingtbl[#swingtbl + 1] = ball.Entity:GetPos() - LocalPlayer():GetPos() + print(ball.Entity:GetPos() - LocalPlayer():GetPos()) + end + lastpos = ball.Entity:GetPos() +end) diff --git a/gamemode/core/combat/sv_weaponswing.lua b/gamemode/core/combat/sv_weaponswing.lua new file mode 100644 index 0000000..f238497 --- /dev/null +++ b/gamemode/core/combat/sv_weaponswing.lua @@ -0,0 +1,99 @@ +--[[ + This file tells you what weapons need their swings recalculated +]] +local itm = nrequire("core/inventory/item.lua") +local ws = {} + +--Cache swing hits, if we used one once, we'll probably use it again soon +local swingcache_size = 30 +local swingcache = {} --Swing arc cache + +--A table of all the items that are swingable +local swingable = {} + +util.AddNetworkString("artery_notifyserverofswing") +util.AddNetworkString("artery_doanimation") + +net.Receive("artery_notifyserverofswing",function() + local weapon = net.ReadString() + local anim = net.ReadString() + local data = net.ReadTable() + + print("Got swing data for ",weapon,anim) + PrintTable(data) + + --Get the data that already exists for this weapon + local olddata = file.Read("artery/dynamic/swingdata/" .. weapon .. ".txt","DATA") + if olddata == nil then olddata = {} + else olddata = util.JSONToTable(util.Decompress(olddata)) end + + --Add our new data + olddata[anim] = data + + --And save back + file.Write("artery/dynamic/swingdata/" .. weapon .. ".txt",util.Compress(util.TableToJSON(olddata))) +end) + +function ws.makeSwingable(tbl) + assert(tbl.Name,"Tried to make a swingable weapon out of an item with no name!") + assert(tbl.attacks,"Tried to make a swingable weapon out of an item with no attacks! See rustyaxe.lua for example") + assert(tbl.pacname,"Tried to make a swingable weapon without a pac name! see rustyaxe.lua for example") + swingable[tbl.Name] = tbl +end + +concommand.Add("artery_recordanimations",function(ply,cmd,args) + local animqueuetime = 0 + for k,v in pairs(swingable) do + --equip the right item + print("equipable inventory:") + local eqi = ply.data.inventories[1] + print(ply.data.inventories[1]) + local itm = eqi:Get({v.Equipable}) + if itm ~= nil then + eqi:Remove({v.Equipable}) + end + eqi:Put({v.Equipable},v) + + --queue up each attack for the player to do + for i,j in pairs(v.attacks) do + timer.Simple(animqueuetime,function() + print("Doing attack:") + print(i,":",j) + net.Start("artery_doanimation") + net.WriteString(j.anim) + net.WriteDouble(j.time) + net.WriteString(v.Name) + net.WriteString(i) + net.Send(ply) + end) + animqueuetime = animqueuetime + j.time + 1 + end + + end +end) + + + +concommand.Add("artery_checkSwingable",function(ply,cmd,args) + local nitms = 0 + local noswingdata = {} + for k,v in pairs(swingable) do + --Make sure we have a weapon path for everything + if file.Exists( "artery/dynamic/swingdata/" .. k, "DATA" ) then + MsgC(Color(0,255,0),"Found data for " .. k .. "\n") + else + MsgC(Color(255,0,0),"Couldn't find data for " .. k .. "\n") + noswingdata[#noswingdata + 1] = k + end + nitms = nitms + 1 + end + + print("Scanned ",nitms,"swingable items, could not find data for:\n\t",table.concat(noswingdata,"\n\t")) +end) + +concommand.Add("artery_clearswingable",function(ply,cmd,args) + swingable = {} +end) + + +return ws diff --git a/gamemode/core/database/sv_setup.lua b/gamemode/core/database/sv_setup.lua index 2fb7ed7..2cb69d1 100644 --- a/gamemode/core/database/sv_setup.lua +++ b/gamemode/core/database/sv_setup.lua @@ -34,13 +34,18 @@ local function connect() MySQLite.initialize(config) end hook.Add("DatabaseInitialized","setup_table",function() + assert(MySQLite.isMySQL(),"Database wasn't mysqloo, something is probably wrong!") local setup_success = function(res,li) print("Set up connection to db") end print("Setup query:",setup_db) MySQLite.query(setup_db,setup_success,q_fai) end) -connect() + +hook.Add("Initialize","initalizedbconnection",function() + connect() +end) + --Retruns (PlayerData, MetaData) or nil function sql.GetPlayerData(ply) @@ -65,7 +70,7 @@ function sql.GetPlayerData(ply) return end print("We were on the right server") - --[[ + print("Before finding data in the metatable, mtbl was ") PrintTable(mtbl) print(type(mtbl.lastlocation)) @@ -74,8 +79,8 @@ function sql.GetPlayerData(ply) for k,v in pairs(vec) do vec[k] = tonumber(v) end print("setting player pos to") PrintTable(vec) - ]] - ply:SetPos(mtbl.lastlocation) + + ply:SetPos(Vector(unpack(vec))) q.deserialize_player(ply,plyd) end end diff --git a/gamemode/core/inventory/common/items.lua b/gamemode/core/inventory/common/items.lua index 03113f5..95a507c 100644 --- a/gamemode/core/inventory/common/items.lua +++ b/gamemode/core/inventory/common/items.lua @@ -14,15 +14,18 @@ local function drop_self(tbl) end +--Client requests the item be droped from the ent, invid, and inv position function items.DropItem(ent_or_tbl,invid,frompos) + --[[ if type(ent_or_tbl) == "table" then drop_self(ent_or_tbl) else drop_provided(ent_or_tbl,invid,frompos) end + ]] assert(CLIENT,"requested to drop an item when we are not the client!") net.Start("art_RequestInvDrop") - net.WriteEntity(ent) + net.WriteEntity(ent_or_tbl) net.WriteUInt(invid,32) net.WriteTable(frompos) net.SendToServer() diff --git a/gamemode/core/inventory/sv_invtracker.lua b/gamemode/core/inventory/sv_invtracker.lua index 4c1fc1b..47dd164 100644 --- a/gamemode/core/inventory/sv_invtracker.lua +++ b/gamemode/core/inventory/sv_invtracker.lua @@ -63,19 +63,47 @@ net.Receive("art_RequestInvMove",function(len,ply) toinv:Put(topos,item) end) +function track.DropItem(item,pos) + local e = ents.Create("art_droppeditem") + e.Item = {Name = item.Name, Data = item:Serialize()} + e:SetPos(pos) + e:Spawn() +end + net.Receive("art_RequestInvDrop",function(len,ply) local froment = net.ReadEntity() local frominvid = net.ReadUInt(32) local frompos = net.ReadTable() assert(not froment:IsPlayer() or froment == ply, "Player tried to drop an item that was from another players inventory") + print("Using data for drop:") + PrintTable({ + ["froment"] = froment, + ["frominvid"] = frominvid, + ["frompos"] = frompos + }) + print("Player's data is:") + PrintTable(froment.data) local frominv = froment.data.inventories[frominvid] local item = frominv:Get(frompos) frominv:Remove(frompos) - local e = ents.Create("art_droppeditem") - e.Item = {Name = item.Name, Data = item:Serialize()} - e:SetPos((ply:GetForward() * 20) + ply:GetPos()) - e:Spawn() + local placetodrop + --Find somewhere to drop this + local tr = ply:GetEyeTrace() + if tr.Hit then + if tr.HitPos:Distance(ply:GetPos()) < 200 then + placetodrop = tr.HitPos + else + local tr2 = util.TraceLine({ + start = (tr.Normal*200) + tr.StartPos, + endpos = ((tr.Normal*200) + tr.StartPos) + Vector(-2000), + }) + placetodrop = tr2.HitPos + end + else + placetodrop = ply:GetForward() * 200 + end + track.DropItem(item,placetodrop) end) function track.ClearInventories(ply) diff --git a/gamemode/core/npc/sv_common.lua b/gamemode/core/npc/sv_common.lua new file mode 100644 index 0000000..e37a5f8 --- /dev/null +++ b/gamemode/core/npc/sv_common.lua @@ -0,0 +1,38 @@ +--[[ + Some common functions that a lot of npcs use, take out here to make fixing bugs easier. +]] + +local com = {} + +com.pausefor10sec = function(npc) + npc.StartActionTime = CurTime() + 10 + npc:SetSequence(npc:LookupSequence("idle")) + npc.loco:FaceTowards(Vector(-343, 148, 565)) + local oyaw,oacc = npc.loco:GetMaxYawRate(), npc.loco:GetAcceleration() + timer.Simple(0,function() + npc.loco:SetMaxYawRate(0) + npc.loco:SetAcceleration(0) + npc.loco:SetVelocity(Vector(0,0,0)) + end) + timer.Simple(10, function() + npc.loco:SetMaxYawRate(oyaw) + npc.loco:SetAcceleration(oacc) + end) +end + +com.is10secdone = function(npc) + return npc.StartActionTime < CurTime() +end + +com.Rumors = { + "This is a rumor!", + "Here is another!", + "And yet another!", +} + +com.GetRumor = function() + local rng = math.random(#com.Rumors) + return com.Rumors[rng] +end + +return com diff --git a/gamemode/core/npc/sv_huntingspawner.lua b/gamemode/core/npc/sv_huntingspawner.lua new file mode 100644 index 0000000..283b27f --- /dev/null +++ b/gamemode/core/npc/sv_huntingspawner.lua @@ -0,0 +1,118 @@ +--[[ + This file spawns the huntable npc's in their zones. +]] +local track = nrequire("core/inventory/sv_invtracker.lua") +local itm = nrequire("core/inventory/item.lua") +local o = {} + +local huntablenodes = {} +function o.CreateSpawnNode(tbl) + huntablenodes[#huntablenodes+1] = tbl + local e = ents.Create("info_huntablespawn") + e:SetPos(tbl.Position) +end + +local function SpawnMonsterFor(ply,zone) + --Check what hunting ground we're in + print("I want to attack",ply) + if zone == nil then return end + print("I am in a zone!") + local possiblenpcs = zone.npctbl + PrintTable(possiblenpcs) + + local randnum = math.random(0,100) + print("Random num was",randnum) + local npctype + for k,v in pairs(possiblenpcs) do + randnum = randnum - v + print("Subtracting ", v , " for ",k) + if randnum < 0 then + npctype = k + break + end + end + + if npctype == nil then + print(ply,"got lucky this time...") + return + end + print("I will spawn a ",npctype,"to attack ",ply,"!") + + --Find a place for the npc to spawn that's out of sight! + local potentialspots = ents.FindInSphere( ply:GetPos(), 4000 ) + for k,v in pairs(potentialspots) do + print("Checking spot",v) + if v:GetClass() ~= "info_huntablespawn" then + print("Was not an info_huntablespawn") + potentialspots[k] = nil + else + local tr = util.TraceLine({ + start = v:GetPos() + Vector(0,0,50), + endpos = ply:GetPos() + Vector(0,0,64), + }) + if tr.Hit and tr.Entity == ply then + potentialspots[k] = nil + print("Player could see this point") + end + end + end + + local a = {} + for k,v in pairs(potentialspots) do a[#a+1] = v end + + --Choose a random spot! + local spawnpos = a[math.random(1,#a)] + + print("I want to spawn a monster at", spawnpos) + if spawnpos == nil then + print("Couldn't find a spot to spawn an NPC around",ply,"at",ply:GetPos(),"make sure there are enough info_huntablespawn entities around in little corners and stuff") + return + end + --Do a trace up to hit the skybox, + local npc = ents.Create(npctype) + npc:SetPos(spawnpos:GetPos()) + npc:SetEnemy(ply) + npc:Spawn() +end + +local lastspawned = {} +for k,v in pairs(player.GetAll()) do lastspawned[v] = CurTime() end +hook.Add("PlayerInitialSpawn","add_to_huntable_tbl",function(ply) + lastspawned[ply] = CurTime() +end) +hook.Add("Tick","occasionally_spawn_monsters",function() + for _,ply in pairs(player.GetAll()) do + local zone = ply:GetCurrentZone( "artery_huntingground" ) + if zone == nil then continue end + if CurTime() - lastspawned[ply] > zone.SpawnRate then + SpawnMonsterFor(ply,zone) + lastspawned[ply] = CurTime() + end + end +end) + +local external_drops = {} +function o.RegisterDrops(npcname,tbl) + assert(external_drops[npcname] == nil, string.format("Tried to register 2 drop tables for the npc %q",npcname)) + external_drops[npcname] = tbl +end + +hook.Add("OnNPCKilled","droplootforexnpcs",function(npc,attacker,inflictor) + local d = external_drops[npc:GetClass()] + if d == nil then return end + + for k, v in pairs(d) do + local rng = math.random(0, 100) + local itemname = v[1] + local itemchance = v[2] + local heightoffset = 10 + + if rng < itemchance then + local drop = itm.GetItemByName(itemname) + print("Createing a drop of",drop) + track.CreateDroppedItem(drop, self:GetPos()+Vector(math.random(20),math.random(20),20)) + end + end +end) + +return o diff --git a/gamemode/core/npc/sv_npcsystem.lua b/gamemode/core/npc/sv_npcsystem.lua index 1abbc67..78b041f 100644 --- a/gamemode/core/npc/sv_npcsystem.lua +++ b/gamemode/core/npc/sv_npcsystem.lua @@ -11,6 +11,7 @@ function n.RegisterNPC(npc) end function n.CreateNPCByName(npcname, pos) + assert(npcs[npcname],string.format("No npc named %q, valid names are:\n%s",npcname,table.concat(table.GetKeys(npcs),"\n"))) print("Createing a ", npcname, " at ", pos) local npctbl = npcs[npcname] local npc = ents.Create("npc_huntable") @@ -66,23 +67,32 @@ for k, v in pairs(removeents) do end end -local mapfields = {"navnodes", "npcs"} +local function ExecuteOnFolder(dir, recursive, func) + local path = "" + local fpath = table.concat({path,dir,"/*"}) + local files, directories = file.Find(fpath,"DATA") + for k,v in pairs(files) do + local callpath = table.concat({path,dir,"/",v}) + func(callpath) + end + if not recursive then return end + for k,v in pairs(directories) do + local npath = table.concat({dir,"/",v}) + ExecuteOnFolder(npath,true,func) + end +end --- "chests", local function loadMap() - for k, v in ipairs(mapfields) do - local mapname = game.GetMap() - local fpath = string.format("artery/maps/%s/%s/*", mapname, v) - local files, dirs = file.Find(fpath, "DATA") - - for i, j in pairs(files) do - if string.GetExtensionFromFilename(j) ~= "lua" then continue end - local itempath = string.format("artery/maps/%s/%s/%s", mapname, v, j) - local itemtxt = file.Read(itempath, "DATA") - assert(itemtxt ~= nil, "Found a file, but it looks like it can't be compiled:" .. itempath) - CompileString(itemtxt, itempath)() - end - end + local mapname = game.GetMap() + + local foldername = "artery/maps/" .. mapname + ExecuteOnFolder(foldername,true,function(path) + print("I want to run",path) + local filetxt = file.Read(path,"DATA") + print("File text is", filetxt) + CompileString(filetxt,path)() + print("I want to execute",path) + end) end hook.Add("InitPostEntity", "artery_spawnmapnpcs", function() diff --git a/gamemode/core/pac/cl_pac.lua b/gamemode/core/pac/cl_pac.lua index 9163d82..4f1890c 100644 --- a/gamemode/core/pac/cl_pac.lua +++ b/gamemode/core/pac/cl_pac.lua @@ -27,11 +27,13 @@ timer.Simple(0,function() net.SendToServer() end) -file.CreateDir("artery/pacs") +local CLIENT_PAC_DIR = "artery/client/pacs" + +file.CreateDir(CLIENT_PAC_DIR) local function loadpac(ent,name,hash) print("Told to apply pac", name, "to ent", ent) - local filepath = string.format("artery/pacs/%s.txt",name) + local filepath = string.format(CLIENT_PAC_DIR .. "/%s.txt",name) local filetext = file.Read(filepath,"DATA") if ent.AttachPACPart == nil then pac.SetupENT(ent) @@ -52,7 +54,7 @@ local function loadpac(ent,name,hash) end local function unloadpac(ent,name,hash) - local filepath = string.format("artery/pacs/%s.txt",name) + local filepath = string.format(CLIENT_PAC_DIR .. "/%s.txt",name) local filetext = file.Read(filepath,"DATA") local pactbl = CompileString(string.format("return {%s}",filetext),name)() ent:RemovePACPart(pactbl) @@ -62,7 +64,7 @@ net.Receive("artery_downloadpac",function() local pac_name = net.ReadString() local pac_txt = net.ReadString() local pac_hash = net.ReadUInt(32) - local filepath = string.format("artery/pacs/%s.txt",pac_name) + local filepath = string.format(CLIENT_PAC_DIR .."/%s.txt",pac_name) file.Write(filepath,pac_txt) end) diff --git a/gamemode/core/pac/sv_pac.lua b/gamemode/core/pac/sv_pac.lua index 3c5c6be..482dea6 100644 --- a/gamemode/core/pac/sv_pac.lua +++ b/gamemode/core/pac/sv_pac.lua @@ -108,12 +108,16 @@ local function cacheload(key) --If it's already in the cache, just update the time it was last used and return the pac. if pac_cache[key] ~= nil then pac_cache[key].time = CurTime() + if pac_cache[key].pac == nil then + PrintTable(pac_cache) + error("Pac was loaded, but the txt was nil!") + end return pac_cache[key].pac end --Otherwise, we need to load it. local pacpath = string.format("artery/pacs/%s.txt",key) - local pacfile = file.Read(pacpath,"LUA") + local pacfile = file.Read(pacpath,"DATA") --If we haven't reached max cache yet, just put it in if pacs_in_cache < max_pacs_in_cache then diff --git a/gamemode/init.lua b/gamemode/init.lua index 5b28d32..ac530f1 100644 --- a/gamemode/init.lua +++ b/gamemode/init.lua @@ -4,25 +4,4 @@ AddCSLuaFile( "cl_init.lua" ) AddCSLuaFile("nrequire.lua") include( "shared.lua" ) -local pmeta = FindMetaTable("Player") - ---- Loads a player's inventory --- @param json The JSON string to create the player's inventory from -function pmeta:LoadInventory(json) - local reinv = util.JSONToTable(json) - for k,v in pairs(reinv) do - self.Inventory[k] = v - end - print("After loading inventory, player's inventory was") - PrintTable(self.Inventory) - self:SynchronizeInventory() - self:SynchPrayers() - if self:HasPrayer("Noob Help") then - print("Player had Noob Help, equiping!") - net.Start("equiphelpprayer") - net.Send(self) - else - error("Player did not have noob help, inventory was:") - PrintTable(self.Inventory) - end -end +print("Hello from init.lua") diff --git a/gamemode/inventorysystem/cl_common.lua b/gamemode/inventorysystem/cl_common.lua index 15f67b4..5b461d3 100644 --- a/gamemode/inventorysystem/cl_common.lua +++ b/gamemode/inventorysystem/cl_common.lua @@ -8,9 +8,11 @@ function com.CreateMenuFor(menu, tbl) for k,v in pairs(tbl) do if isfunction(v) then --This is a dead-end, add the menu menu:AddOption(k,v) - else --Otherwise it should be a table, recursively call to create + elseif istable(v) then --Otherwise it should be a table, recursively call to create local submenu = menu:AddSubMenu(k) CreateMenuFor(submenu,v) + else + error("I got wanted to make a menu for something not a function or a table:" + type(v)) end end end diff --git a/gamemode/itemsystem/weapons/rustyaxe.lua b/gamemode/itemsystem/weapons/rustyaxe.lua index 00547c8..4f613de 100644 --- a/gamemode/itemsystem/weapons/rustyaxe.lua +++ b/gamemode/itemsystem/weapons/rustyaxe.lua @@ -1,15 +1,17 @@ --[[ An axe that you can swing around! ]] -local pac +local pac,swi if SERVER then pac = nrequire("core/pac/sv_pac.lua") + swi = nrequire("core/combat/sv_weaponswing.lua") end local reg = nrequire("core/inventory/item.lua") local com = nrequire("core/inventory/common/weapons.lua") local itm = nrequire("core/inventory/common/items.lua") + local item = {} --Required, a name, all item names must be unique @@ -56,6 +58,29 @@ item.Shape = { --Optional, If this item can be equiped in any player slots, put them here. item.Equipable = "Right Hand" +item.attacks = { + ["forward"] = { + time = 2.33, + anim = "axe_swing_up", + }, + ["left"] = { + time = 2.33, + anim = "axe_swing_left", + }, + ["left"] = { + time = 2.33, + anim = "axe_swing_right", + }, +} + +--The path garrysmod/data/artery/pacs/<pacname>.txt must be a pac file +item.pacname = "rustyaxe" + +if SERVER then + --Before makeSwingable is called, an item needs a .Name field and a .attacks field and a .pacname field + swi.makeSwingable(item) +end +--[[ local swingdata = { ["fwd"] = { {0.011,Vector(-25,-3,-11)}, @@ -212,7 +237,9 @@ item.onClick = function(self,owner) print("At time of doing playermovedir, com is", com) movementtbl[com.playermovedir(owner)]() end +]] +--[[ --Optional, if we should do something special on equip(like draw the PAC for this weapon) item.onEquip = function(self,who) print("onEquip",who) @@ -234,7 +261,7 @@ item.onUnEquip = function(self,who) who:GetActiveWeapon():SetHoldType("normal") if SERVER then pac.RemovePac(who,"rustyaxe") end end - +]] item.onDropped = function(self, ent) if SERVER then pac.ApplyPac(ent,"rustyaxe") end end diff --git a/gamemode/npcsystem/sv_blockingdummy.lua b/gamemode/npcsystem/sv_blockingdummy.lua index 2b98b97..c40fc54 100644 --- a/gamemode/npcsystem/sv_blockingdummy.lua +++ b/gamemode/npcsystem/sv_blockingdummy.lua @@ -29,7 +29,7 @@ NPC.Drops = { --Attacks should be formated as [i]={function attackpriority() = function doattack()} local checknothing = function(self,ply) - return 1 + return -1 end local donothing = function(self,ply) @@ -79,7 +79,7 @@ function NPC:OnDammage(ammount) print("Blocking is now",self.Blocking) 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. +--These are just here to tell the editors/develoeprs what functions are available. /* function NPC:OnSpawn() end diff --git a/gamemode/npcsystem/sv_dummy.lua b/gamemode/npcsystem/sv_dummy.lua index 6c5acae..0bfa063 100644 --- a/gamemode/npcsystem/sv_dummy.lua +++ b/gamemode/npcsystem/sv_dummy.lua @@ -4,7 +4,7 @@ local NPC = {} NPC.Name = "Training Dummy" NPC.Desc = "A man made of straw. His dream is to have a brain." NPC.Class = "Ambient" --Ambient, Agressive, Boss -NPC.Model = "models/headcrab.mdl" +NPC.Model = "models/props/tools/humans/training_dummy/training_dummy.mdl" NPC.Stats = { ["Vitality"] = 100000, @@ -18,8 +18,7 @@ NPC.Stats = { --Some npc's like birds have diffent names for their idle sequences NPC.IdleSequences = { - [0] = "lookaround", - [1] = "Idle01", + [0] = "idle", } --Drops should be formated as [index]={["item name"], percent_drop} where percent_drop is a number from 0 to 100 @@ -88,7 +87,8 @@ end function NPC:OnFindEnemy(enemy) end - +c:\program files (x86)\steam\steamapps\common\garrysmod\garrysmod\addons\fantasy_rp_content_6_520361093\materials\models\training_dummy\training_dummy.vtf +682 Kb 1024x1024 DXT1 --Called when the npc is attacking anything with any attack function NPC:OnAttack(target) end 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) |
