aboutsummaryrefslogtreecommitdiff
path: root/gamemode
diff options
context:
space:
mode:
authorAlexander Pickering <alexandermpickering@gmail.com>2017-11-04 22:42:24 -0400
committerAlexander Pickering <alexandermpickering@gmail.com>2017-11-04 22:42:24 -0400
commit5d77d8475af7aff27eb026a4b56065387c024165 (patch)
treeccdd061e5654288ab53134be52e8b1ef194d5ebc /gamemode
parent40080dcfde028c64c4f6f51792b928ee91677bc6 (diff)
downloadartery-5d77d8475af7aff27eb026a4b56065387c024165.tar.gz
artery-5d77d8475af7aff27eb026a4b56065387c024165.tar.bz2
artery-5d77d8475af7aff27eb026a4b56065387c024165.zip
Massive changes
* New error messages for missing dependencies * Removed useless art_serverchanger entity * Added a sweet ascii logo * Added Skills * Minor fixes to cl_inventory tracker * Changed a few prints to use logging module
Diffstat (limited to 'gamemode')
-rw-r--r--gamemode/client/cl_inventory.lua20
-rw-r--r--gamemode/client/qtabs/cl_qprayers.lua2
-rw-r--r--gamemode/core/animation/sh_animations.lua4
-rw-r--r--gamemode/core/combat/sv_weaponswing.lua8
-rw-r--r--gamemode/core/database/sv_queries.lua6
-rw-r--r--gamemode/core/database/sv_setup.lua31
-rw-r--r--gamemode/core/dataloader/cl_loadglobals.lua9
-rw-r--r--gamemode/core/dataloader/sv_loadglobals.lua34
-rw-r--r--gamemode/core/inventory/cl_invtracker.lua20
-rw-r--r--gamemode/core/inventory/common/animations/sh_swing_mele.lua4
-rw-r--r--gamemode/core/inventory/sv_invtracker.lua3
-rw-r--r--gamemode/core/logo.lua16
-rw-r--r--gamemode/core/mapstich/cl_mapstich.lua9
-rw-r--r--gamemode/core/mapstich/sv_mapstich.lua2
-rw-r--r--gamemode/core/npc/cl_npcmap.lua19
-rw-r--r--gamemode/core/npc/cl_shop.lua1
-rw-r--r--gamemode/core/npc/sv_huntingspawner.lua3
-rw-r--r--gamemode/core/pac/cl_pac.lua2
-rw-r--r--gamemode/core/zones/sh_zones.lua611
-rw-r--r--gamemode/init.lua2
-rw-r--r--gamemode/inventorysystem/prayers/cl_prayers.lua31
-rw-r--r--gamemode/inventorysystem/prayers/sh_prayers.lua5
-rw-r--r--gamemode/inventorysystem/shapedinventory/sh_shaped.lua4
-rw-r--r--gamemode/inventorysystem/skills/cl_skills.lua67
-rw-r--r--gamemode/inventorysystem/skills/sh_skillcommon.lua68
-rw-r--r--gamemode/inventorysystem/skills/sh_skills.lua76
-rw-r--r--gamemode/itemsystem/exampleitem.lua3
-rw-r--r--gamemode/nrequire.lua3
-rw-r--r--gamemode/shared.lua3
-rw-r--r--gamemode/shared/animations/move_evade.lua2
-rw-r--r--gamemode/shared/animations/swing_axe.lua2
-rw-r--r--gamemode/shared/animations/swing_fists.lua2
-rw-r--r--gamemode/shared/animations/swing_hammer.lua2
-rw-r--r--gamemode/shared/animations/swing_knife.lua2
-rw-r--r--gamemode/shared/animations/swing_mele.lua2
-rw-r--r--gamemode/shared/log.lua49
-rw-r--r--gamemode/zones.lua611
37 files changed, 945 insertions, 793 deletions
diff --git a/gamemode/client/cl_inventory.lua b/gamemode/client/cl_inventory.lua
index 4e2545d..df0f453 100644
--- a/gamemode/client/cl_inventory.lua
+++ b/gamemode/client/cl_inventory.lua
@@ -54,6 +54,7 @@ end)
local function CreateSheetTree(tabs,dpropertysheet)
print("Createing sheet tree!")
PrintTable(tabs)
+ local observers = {}
for k,v in pairs(tabs) do
if type(k) == "string" then
print("Makeing inventory ", k)
@@ -64,7 +65,8 @@ local function CreateSheetTree(tabs,dpropertysheet)
print("Makeing inventory number ", k)
local tsheet = vgui.Create("DPanel")
dpropertysheet:AddSheet(v.Name,tsheet,"icon16/user.png")
- v:DrawOnDPanel(tsheet)
+ local prox = v:DrawOnDPanel(tsheet)
+ v:AddObserver(prox)
else
error("k was not a number or string, it was a " .. type(k))
end
@@ -114,7 +116,8 @@ local function BuildInventory()
initalsheet:Dock(FILL)
CreateSheetTree(clt.known_inventories,initalsheet)
-
+ print("After createing sheet tree, known inventories was")
+ PrintTable(clt.known_inventories)
end
function inv.ShowInventory()
@@ -140,10 +143,7 @@ function inv.ShowInventory()
end,{})
end
-
-
-hook.Add("OnSpawnMenuOpen","ArteryOpenInventory",inv.ShowInventory)
-hook.Add("OnSpawnMenuClose","ArteryCloseInventory",function()
+function inv.HideInventory()
droppanel:Remove()
state.invopen = false
qframe:Hide()
@@ -155,14 +155,18 @@ hook.Add("OnSpawnMenuClose","ArteryCloseInventory",function()
v.panel:Close()
LocalPlayer().invdisplays[k] = nil
end
-end)
+end
+
+
+hook.Add("OnSpawnMenuOpen","ArteryOpenInventory",inv.ShowInventory)
+hook.Add("OnSpawnMenuClose","ArteryCloseInventory",inv.HideInventory)
concommand.Add("showinventory",inv.ShowInventory)
local viewdistance = 100
local rotatespeed = 65
local bone = nil
local previousheadscale = Vector(1,1,1)
-local toggle_arteryview = true
+local toggle_arteryview = false
hook.Add("CalcView","ArteryInventoryView",function(ply,pos,ang,fov,nearz,farz)
if not toggle_arteryview then return end
if bone == nil then
diff --git a/gamemode/client/qtabs/cl_qprayers.lua b/gamemode/client/qtabs/cl_qprayers.lua
index 9f1b9ab..af2b29f 100644
--- a/gamemode/client/qtabs/cl_qprayers.lua
+++ b/gamemode/client/qtabs/cl_qprayers.lua
@@ -1,4 +1,4 @@
-
+do return end
local p = {}
function p.CreatePrayerSheet(dpanel_parent)
diff --git a/gamemode/core/animation/sh_animations.lua b/gamemode/core/animation/sh_animations.lua
new file mode 100644
index 0000000..3846fcc
--- /dev/null
+++ b/gamemode/core/animation/sh_animations.lua
@@ -0,0 +1,4 @@
+if not RegisterLuaAnimation then
+ error("JetBoom's libanimbone is required for animations. (It's bundeled with PAC3)")
+ return
+end
diff --git a/gamemode/core/combat/sv_weaponswing.lua b/gamemode/core/combat/sv_weaponswing.lua
index ea43f0b..2d45d31 100644
--- a/gamemode/core/combat/sv_weaponswing.lua
+++ b/gamemode/core/combat/sv_weaponswing.lua
@@ -26,8 +26,8 @@ net.Receive("artery_notifyserverofswing",function()
local anim = net.ReadString()
local data = net.ReadTable()
- print("Got swing data for ",weapon,anim)
- PrintTable(data)
+ --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")
@@ -42,8 +42,8 @@ net.Receive("artery_notifyserverofswing",function()
end)
function ws.makeSwingable(tbl)
- print("Makeing a swingable out of:")
- PrintTable(tbl)
+ --print("Makeing a swingable out of:")
+ --PrintTable(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")
diff --git a/gamemode/core/database/sv_queries.lua b/gamemode/core/database/sv_queries.lua
index 07b54ac..6ef1201 100644
--- a/gamemode/core/database/sv_queries.lua
+++ b/gamemode/core/database/sv_queries.lua
@@ -4,7 +4,7 @@
local fn = nrequire("utility/fn.lua")
local track = nrequire("core/inventory/sv_invtracker.lua")
-
+local log = nrequire("log.lua")
local q = {}
function q.serialize_player(ply)
@@ -25,10 +25,14 @@ function q.serialize_player(ply)
end
function q.deserialize_player(ply,str)
+ log.debug("Deserializing player's data : " .. ply:Nick() .. "\n" .. str)
track.ClearInventories(ply)
ply.data = ply.data or {}
ply.data.inventories = ply.data.inventories or {}
local tbl = util.JSONToTable(str)
+ if not tbl then
+ log.error("Failed to deserialize player " .. ply:Nick() .. "\n" .. str)
+ end
local invs = tbl.inventories
print("Inventories was", invs)
PrintTable(invs)
diff --git a/gamemode/core/database/sv_setup.lua b/gamemode/core/database/sv_setup.lua
index 756fb20..1fac11f 100644
--- a/gamemode/core/database/sv_setup.lua
+++ b/gamemode/core/database/sv_setup.lua
@@ -57,6 +57,7 @@ function sql.GetPlayerData(ply)
print("Was nil, createing player data")
sql.CreatePlayerTable(ply)
else
+ PrintTable(res)
assert(#res == 1,"Not unique!")
local meta = res[1].MetaData
local plyd = res[1].PlayerData
@@ -68,7 +69,7 @@ function sql.GetPlayerData(ply)
net.Start("art_sendtoserver")
net.WriteString(mtbl.lastserver)
net.Send(ply)
- return
+ return nil
end
local _,_,x,y,z = string.find(mtbl.lastlocation,"([-%d%.]+) ([-%d%.]+) ([-%d%.]+)")
local vec = {x,y,z}
@@ -92,7 +93,11 @@ function sql.CreatePlayerTable(ply)
--print("steamid was", s64)
local plytbl = data.newdata()
local plymet = data.newmeta()
- local plydata = util.TableToJSON(plytbl)
+ print("creating player, before uttj, plytbl is")
+ PrintTable(plytbl)
+ local plydata =util.TableToJSON(plytbl)
+ print("after, plydata is")
+ print(plydata)
local metdata = util.TableToJSON(plymet)
print("plydata", plydata)
print("metdata", metdata)
@@ -106,17 +111,17 @@ function sql.CreatePlayerTable(ply)
end
function sql.SendPlayerToInstance(ply,ls,ll)
-local s64 = ply:SteamID64()
-local plydata = q.serialize_player(ply)
-local plymeta = util.TableToJSON({
- lastserver = ls,
- lastlocation = ll
-})
-local q_str = q.s_fmt(save_player_query,plymeta,plydata,s64)
-local q_suc = function(res,li)
- --print("Successfully saved player data")
-end
-MySQLite.query(q_str,q_suc,q_fai)
+ local s64 = ply:SteamID64()
+ local plydata = q.serialize_player(ply)
+ local plymeta = util.TableToJSON({
+ lastserver = ls,
+ lastlocation = ll
+ })
+ local q_str = q.s_fmt(save_player_query,plymeta,plydata,s64)
+ local q_suc = function(res,li)
+ --print("Successfully saved player data")
+ end
+ MySQLite.query(q_str,q_suc,q_fai)
end
concommand.Add("DoQuery",function(ply,cmd,args)
diff --git a/gamemode/core/dataloader/cl_loadglobals.lua b/gamemode/core/dataloader/cl_loadglobals.lua
index 3c15e63..d286f36 100644
--- a/gamemode/core/dataloader/cl_loadglobals.lua
+++ b/gamemode/core/dataloader/cl_loadglobals.lua
@@ -1,4 +1,4 @@
-
+local log = nrequire("log.lua")
net.Receive("artery_respondfile",function()
local filename = net.ReadString()
local filetext = net.ReadString()
@@ -27,6 +27,11 @@ net.Receive("artery_loadfile",function()
net.SendToServer()
else
assert(#cache > 0, "File was size 0 on: " .. filename)
- CompileString(cache,filename)()
+ local err = CompileString(cache,filename,false)
+ if type(err) == "function" then
+ err()
+ else
+ log.error(err)
+ end
end
end)
diff --git a/gamemode/core/dataloader/sv_loadglobals.lua b/gamemode/core/dataloader/sv_loadglobals.lua
index cf6f838..7689c54 100644
--- a/gamemode/core/dataloader/sv_loadglobals.lua
+++ b/gamemode/core/dataloader/sv_loadglobals.lua
@@ -5,6 +5,11 @@ local function ExecuteOnFolder(dir, recursive, func)
local path = "data/artery/"
local fpath = table.concat({path,dir,"/*"})
local files, directories = file.Find(fpath,"GAME")
+ print("Looking for files in ", fpath, "Found:")
+ print("files:")
+ PrintTable(files)
+ print("dirs:")
+ PrintTable(directories)
for k,v in pairs(files) do
local callpath = table.concat({path,dir,"/",v})
func(callpath)
@@ -25,17 +30,30 @@ local co
local function loadglobals()
co = coroutine.create(function()
ExecuteOnFolder("global",true,function(f)
- print("Loading global file:", f)
+ log.debug("Loading global file : " .. f)
local filetxt = file.Read(f,"GAME")
local filename = string.GetFileFromFilename(f)
if string.find(filename,"^cl_") then
- print("Added",f,"to be loaded clientside")
coroutine.yield(f,filetxt)
elseif string.find(filename,"^sv_") then
- CompileString(filetxt,f)()
+ local func = CompileString(filetxt,f,false)
+ if type(func) == "function" then
+ xpcall(func,function(e)
+ log.error(string.format("%s : %s",f,e))
+ end)
+ else
+ log.error(string.format("Failed to compile file %s :\n%s"),filename,func)
+ end
coroutine.yield()
else
- CompileString(filetxt,f)()
+ local func = CompileString(filetxt,f,false)
+ if type(func) == "function" then
+ xpcall(func,function(e)
+ log.error(string.format("%s : %s",f,e))
+ end)
+ else
+ log.error(string.format("Failed to compile file %s :\n%s",filename,func))
+ end
coroutine.yield(f,filetxt)
end
end)
@@ -44,12 +62,11 @@ end
local csco = {}
local function load_cs_files(ply)
- print("Told to load csfiles for", ply:Nick())
+ log.debug("Told to load csfiles for", ply:Nick())
csco[ply] = coroutine.create(function()
- print("Loading cs files, toload is")
for k,v in pairs(toload) do print(k) end
for k,v in pairs(toload) do
- print("Loading cs file:", k,"for",ply:Nick())
+ log.debug("Loading cs file:", k,"for",ply:Nick())
net.Start("artery_loadfile")
net.WriteString(k)
local hash = util.CRC(v)
@@ -64,7 +81,6 @@ local state = "done"
local n
timer.Create("inc_load_timer",0.1,0,function()
if state == "loading_sv" then
- print("co is", co)
if coroutine.status(co) == "suspended" then
local _,fn,t = coroutine.resume(co)
if fn and t then
@@ -106,7 +122,7 @@ end)
loadglobals()
state = "loading_sv"
hook.Add("PlayerInitialSpawn","artery_loadglobals",function(ply)
- print("Doing player inital span, loading globals for " , ply:Nick())
+ log.debug("Doing player inital spawn, loading globals for " , ply:Nick())
timer.Simple(1,function()
load_cs_files(ply)
state = "loading_cl"
diff --git a/gamemode/core/inventory/cl_invtracker.lua b/gamemode/core/inventory/cl_invtracker.lua
index 258a271..1e75ef2 100644
--- a/gamemode/core/inventory/cl_invtracker.lua
+++ b/gamemode/core/inventory/cl_invtracker.lua
@@ -48,13 +48,13 @@ local drawsheeton = function(id,inventory,higharchy)
-- draw.RoundedBox( 4, 0, 0, w, h, Color( 0, 128, 255 ) )
--end
if inventory.DrawOnDPanel then
- --print("Has drawondpanel")
+ print("Has drawondpanel")
local prox = inventory:DrawOnDPanel(tpanel)
- --print("Prox returned was",prox)
- --PrintTable(prox)
+ print("Prox returned was",prox)
+ PrintTable(prox)
known_inventories[id]:AddObserver(prox)
- --print("Oservers is now")
- --PrintTable(known_inventories[id].observers)
+ print("Oservers is now")
+ PrintTable(known_inventories[id].observers)
end
invsheet:AddSheet( inventory.Name, tpanel, "icon16/tab.png" )
end
@@ -91,17 +91,23 @@ net.Receive("art_UpdateInventory",function()
local position = net.ReadTable()
if isput then
local item_name = net.ReadString()
- --print("Putting ", item_name, "into inventory ",id, " at position")
- --PrintTable(position)
+ print("Putting ", item_name, "into inventory ",id, " at position")
+ PrintTable(position)
local item_data = net.ReadData(net.ReadUInt(32))
local item = itm.GetItemFromData(item_name,item_data)
known_inventories[id]:Put(position,item)
+ for k,v in pairs(known_inventories[id].observers) do
+ v:Put(position,item)
+ end
--print("Inventorie's observers:")
--PrintTable(known_inventories[id].observers)
--print("Inventory is now")
--PrintTable(known_inventories[id])
else
known_inventories[id]:Remove(position)
+ for k,v in pairs(known_inventories[id].observers) do
+ v:Remove(position)
+ end
end
end)
diff --git a/gamemode/core/inventory/common/animations/sh_swing_mele.lua b/gamemode/core/inventory/common/animations/sh_swing_mele.lua
index 4521ddd..09f79e7 100644
--- a/gamemode/core/inventory/common/animations/sh_swing_mele.lua
+++ b/gamemode/core/inventory/common/animations/sh_swing_mele.lua
@@ -1,5 +1,5 @@
-print("Hello from sh_swing_mele.lua!")
-
+nrequire("sh_animations.lua")
+
RegisterLuaAnimation('swing_onehand_left', {
FrameData = {
{
diff --git a/gamemode/core/inventory/sv_invtracker.lua b/gamemode/core/inventory/sv_invtracker.lua
index 7df4175..f1f3c3d 100644
--- a/gamemode/core/inventory/sv_invtracker.lua
+++ b/gamemode/core/inventory/sv_invtracker.lua
@@ -226,8 +226,11 @@ function plymeta:GiveItem(tbl)
if type(p) == "table" then
v:Put(p,tbl)
return
+ else
+ log.debug("inventory " .. k .. " couldn't fit it...")
end
end
+ PrintTable(tbl)
error("Unable to find place to put item")
end
diff --git a/gamemode/core/logo.lua b/gamemode/core/logo.lua
new file mode 100644
index 0000000..05c8841
--- /dev/null
+++ b/gamemode/core/logo.lua
@@ -0,0 +1,16 @@
+local ngm = GM or GAMEMODE
+timer.Simple(5,function()
+ local logo = [[
+ ___
+ - -_, ,
+( ~/|| ||
+( / || ,._-_ =||= _-_ ,._-_ '\\/\\
+ \/==|| || || || \\ || || ;'
+ /_ _|| || || ||/ || ||/
+( - \\, \\, \\, \\,/ \\, |/
+ (
+ -_-
+ ]]
+ print(logo)
+ print(string.format("Version %d.%d.%d",unpack(ngm.Version)))
+end)
diff --git a/gamemode/core/mapstich/cl_mapstich.lua b/gamemode/core/mapstich/cl_mapstich.lua
index 62cad3f..6f85eeb 100644
--- a/gamemode/core/mapstich/cl_mapstich.lua
+++ b/gamemode/core/mapstich/cl_mapstich.lua
@@ -1,9 +1,14 @@
--[[
The client constantly cheks to see if we're in a serverchnage zone
]]
-nrequire("sh_zones.lua")
+if not nrequire("sh_zones.lua") then return end
hook.Add("Think","artery_checklevelchange",function()
- local z = LocalPlayer():GetCurrentZone()
+ local z
+ pcall(function()
+ z = LocalPlayer():GetCurrentZone()
+ end,function()
+ --This happens ocasionally when the player has loaded, and is running lua, but the LocalPlayer() entity isn't valid yet.
+ end)
--print("looks like i'm in zone",z)
if z then
net.Start("art_zonechange")
diff --git a/gamemode/core/mapstich/sv_mapstich.lua b/gamemode/core/mapstich/sv_mapstich.lua
index 0a20828..91b4ec2 100644
--- a/gamemode/core/mapstich/sv_mapstich.lua
+++ b/gamemode/core/mapstich/sv_mapstich.lua
@@ -1,6 +1,6 @@
--Make sure zones are loaded already
nrequire("sv_mysqlite.lua")
-nrequire("sh_zones.lua")
+if not nrequire("sh_zones.lua") then return end
local q = nrequire("core/database/sv_queries.lua")
--if not zones then error("This thing needs zones to function!") end
diff --git a/gamemode/core/npc/cl_npcmap.lua b/gamemode/core/npc/cl_npcmap.lua
index ddbd3cd..8e4477d 100644
--- a/gamemode/core/npc/cl_npcmap.lua
+++ b/gamemode/core/npc/cl_npcmap.lua
@@ -1,14 +1,12 @@
--local tblf = include("/../gamemodes/artery/gamemode/utility/mapfuncs.lua")
-print("Hello from cl_ncpmap in core")
+local log = nrequire("log.lua")
local drawmap = false
hook.Add( "ScoreboardShow", "ShowNPCMap", function()
- print("Showing npc map")
drawmap = true
return true
end )
hook.Add( "ScoreboardHide", "ShowNPCMap", function()
- print("Hiding npc map")
drawmap = false
end )
local white = Color( 255, 255, 255, 255 )
@@ -26,16 +24,11 @@ local mapicons = --[[mapicons or]] {
hook.Add( "HUDPaint", "paintsprites", function()
local function drawsubarea(node)
- print("drawing")
- PrintTable(node)
if node.isleaf then
render.SetMaterial( node.material )
render.DrawSprite( node.pos, 64, 64, white )
- print("Actually drawing")
- PrintTable(node)
else
if not node.icons then
- print("found area without any icons!")
for k,v in pairs(node) do print(k,":",v) end
end
for k,v in pairs(node.icons or {}) do
@@ -44,11 +37,9 @@ hook.Add( "HUDPaint", "paintsprites", function()
end
end
if drawmap then
- print("starting this draw")
cam.Start3D()
drawsubarea(mapicons["global"])
cam.End3D()
- print("done with this draw")
end
end )
@@ -91,8 +82,7 @@ end)
--Add an icon to the map
local function addmapicon(material, subarea, position)
- print("adding map icon, material:",material,"subarea:",subarea,"bordertbl:",bordertbl)
- print("mat",material,"subarea",subarea,"position",position)
+ log.debug("adding map icon, material:",material,"subarea:",subarea,"bordertbl:",bordertbl)
local parts = string.Explode(":",subarea)
-- print("parts:",parts)
-- PrintTable(parts)
@@ -156,17 +146,14 @@ addmaparea("","global",{
]]
net.Receive("addmapicon",function()
- print("got recieve for map icon")
local matstr = net.ReadString()
local subarea = net.ReadString()
local matpos = net.ReadVector()
addmapicon(matstr,subarea,matpos)
- print("MapIcons is now")
- PrintTable(mapicons)
end)
net.Receive("addmaparea",function()
- print("got receive for map area")
+ --print("got receive for map area")
-- local matstr = net.ReadString()
-- local subarea = net.ReadString()
-- local boarders = net.ReadTable()
diff --git a/gamemode/core/npc/cl_shop.lua b/gamemode/core/npc/cl_shop.lua
index 873a37c..9c5ffb2 100644
--- a/gamemode/core/npc/cl_shop.lua
+++ b/gamemode/core/npc/cl_shop.lua
@@ -1,6 +1,5 @@
local inv = nrequire("client/cl_inventory.lua")
local itm = nrequire("core/inventory/item.lua")
-print("in cl_shop inv is", inv)
local w,h = ScrW(),ScrH()
local function DrawShopItemOnDPanel(dp,itemtbl,cost)
--An item is a string, and int cost
diff --git a/gamemode/core/npc/sv_huntingspawner.lua b/gamemode/core/npc/sv_huntingspawner.lua
index 279d834..153b961 100644
--- a/gamemode/core/npc/sv_huntingspawner.lua
+++ b/gamemode/core/npc/sv_huntingspawner.lua
@@ -1,6 +1,7 @@
--[[
This file spawns the huntable npc's in their zones.
]]
+if not nrequire("sh_zones.lua") then return end
local track = nrequire("core/inventory/sv_invtracker.lua")
local itm = nrequire("core/inventory/item.lua")
local o = {}
@@ -34,7 +35,7 @@ local function SpawnMonsterFor(ply,zone)
end
if npctype == nil then
- print(ply,"got lucky this time...")
+ --print(ply,"got lucky this time...")
return
end
--print("I will spawn a ",npctype,"to attack ",ply,"!")
diff --git a/gamemode/core/pac/cl_pac.lua b/gamemode/core/pac/cl_pac.lua
index fc55eb1..063e1b1 100644
--- a/gamemode/core/pac/cl_pac.lua
+++ b/gamemode/core/pac/cl_pac.lua
@@ -7,7 +7,7 @@
--If the player dosen't have PAC3 installed, then overwrite all pac-related network events to display an error.
if pac == nil then
local function no_pac_panic()
- error("This gamemode require PAC3 to display armor/cloths, please be sure clients are downloading this addon from somewhere (perferably the workshop!)")
+ error("CapsAdmin's PAC3 is required for items, please download it from somewhere (perferably the workshop!)")
end
local networkmsgs = {
"artery_downloadpac",
diff --git a/gamemode/core/zones/sh_zones.lua b/gamemode/core/zones/sh_zones.lua
index ca66abb..69c6e04 100644
--- a/gamemode/core/zones/sh_zones.lua
+++ b/gamemode/core/zones/sh_zones.lua
@@ -1,611 +1,6 @@
-local version = 1.20 -- Older versions will not run if a newer version is used in another script.
---[[
- ZONES - by Bobbleheadbob with help from Zeh Matt
- WARNING: If you edit any of these files, make them use a different namespace. Multiple scripts may depend on this library so modifying it can break other scripts.
-
- Purpose:
- For easy in-game designation of persistent polygonal zones which are used by any script.
-
- How to Use:
- All zones are saved in zones.List; see an example below.
- Zone creation is handled with weapon_zone_designator and ent_zone_point, but can be done in code as well.
- When a zone is created, changed, or removed all zones are synced to clients. When clients join they are also synced.
- Any extra details can be saved to a zone. Everything is written to a txt file and is persistent to the map.
-
- Since multiple scripts might use the zones system, don't assume that every zone is related to your script.
- To register a zone class, use zones.RegisterClass(class, color); use a unique string like "Scriptname Room".
- When a zone class is registered, admins can use the tool to create new ones.
- When a new zone is created, the "OnZoneCreated" hook is called serverside. See the example file for documentation.
- When a zone is loaded into the game, the "OnZoneLoaded" hook is called serverside. See the example file for documentation.
- When a player edits a zone's properties, the "ShowZoneOptions" hook is called clientside. See the example file for documentation.
-
- Use zones.FindByClass() to find all zones which are of a given class.
- Use ply:GetCurrentZone() to find the zone that a player is standing in.
-
- Installation:
- This is a shared file so include it in any shared environment. Also include ent_zone_point and weapon_zone_designator as a shared ent and weapon.
- You should not put this file directly in lua/autorun.
-
- License:
- YOU MAY use/edit this however you want, as long as you give proper attribution.
- YOU MAY distribute this with other scripts whether they are paid or free.
- YOU MAY NOT distribute this on its own. It must accompany another script.
-
- Enjoy! ~Bobbleheadbob
-]]
-
-local table, math, Vector, pairs, ipairs, ents, bit = table, math, Vector, pairs, ipairs, ents, bit
-
-if zones then
- local diff = math.abs(math.floor(version)-math.floor(zones.version)) > 0
- if diff then
- ErrorNoHalt("WARNING! Two scripts use VERY different versions of the zones API. Please tell one of them to update their script!\n")
- end
- if zones.version > version then
- if diff then
- print("The outdated version of zones is located at: "..debug.getinfo(1,"S").short_src)
- end
- print("A new version of zones exists. Using version "..zones.version.." instead of "..version)
- return
- elseif zones.version < version then
- if diff then
- print("The outdated version of zones is located at: "..debug.getinfo(zones.RegisterClass,"S").short_src)
- end
- print("A new version of zones exists. Using version "..version.." instead of "..zones.version)
- end
-
-else
- print("Loaded zones " ..version)
-end
-
-zones = zones or {}
-zones.version = version
-
-zones.Classes = zones.Classes or {}
-zones.List = zones.List or {}
-zones.Map = zones.Map or {}
-
-
-//Common interface functions:
-
--- Registers a zone class which can then be created using weapon_zone_designator
-function zones.RegisterClass(class,color)
- zones.Classes[class] = color
-end
-
-
-local plymeta = FindMetaTable("Player")
---returns one of the zones a player is found in. Also returns that zone's ID. Class is optional to filter the search.
-function plymeta:GetCurrentZone(class)
- local c = zones.Cache[self][class or "___"]
- if c then return unpack(c) end
- local z,id = zones.GetZoneAt(self:GetPos(), class)
- zones.Cache[self][class or "___"] = {z,id}
- return z,id
-end
-
---returns a table of zones the player is in. Class is optional to filter the search.
-function plymeta:GetCurrentZones(class)
- return zones.GetZonesAt(self:GetPos(),class)
-end
-
-function zones.GetZoneAt(pos,class) --works like above, except uses any point.
-
- local nearby = zones.GetNearbyZones(pos)
-
- for k,zone in pairs(nearby) do
-
- if class and class != zone.class then continue end
- if not pos:WithinAABox(zone.bounds.mins, zone.bounds.maxs) then
- continue
- end
-
- for k1, points in pairs(zone.points) do
- if zones.PointInPoly(pos,points) then
- local z = points[1].z
- if pos.z >= z and pos.z < z + zone.height[k1] then
- return zone,k
- end
- end
- end
- end
-
- return nil, -1
-
-end
-
-function zones.GetZonesAt(pos,class) --works like above, except uses any point.
- local tbl = {}
- local nearby = zones.GetNearbyZones(pos)
- for k,zone in pairs(nearby) do
- if class and class != zone.class then continue end
- if not pos:WithinAABox(zone.bounds.mins,zone.bounds.maxs) then continue end
- for k1, points in pairs(zone.points) do
- if zones.PointInPoly(pos,points) then
- local z = points[1].z
- if pos.z >= z and pos.z < z + zone.height[k1] then
- tbl[k] = zone
- end
- end
- end
- end
- return tbl
-end
-
---Gets a list of all zones which are of the specified class.
-function zones.FindByClass(class)
- local tbl = {}
-
- for k,v in pairs(zones.List) do
- if v.class == class then
- tbl[k] = v
- end
- end
-
- return tbl
-end
-
---Returns the numerical ID of a zone.
-function zones.GetID(zone)
- return table.KeyFromValue(zones.List,zone)
-end
-
-
-
-
-//Getting into the meat of the API:
-local mapMins = -16000
-local mapMaxs = 16000
-local mapSize = 32000
-local chunkSize = 128
-
-local function GetZoneIndex(pos)
-
- local x = pos.x + mapMaxs
- local y = pos.y + mapMaxs
- local z = pos.z + mapMaxs
-
- local idxX = math.floor(x / chunkSize)
- local idxY = math.floor(y / chunkSize)
- local idxZ = math.floor(z / chunkSize)
- local idx = bit.bor(bit.lshift(idxX, 24), bit.lshift(idxY, 14), idxZ)
-
- return idx
-
-end
-
-local function Floor(x,to)
- return math.floor(x / to) * to
-end
-local function Ceil(x,to)
- return math.ceil(x / to) * to
-end
-
-function zones.CreateZoneMapping()
- zones.Map = {}
- for _, zone in pairs(zones.List) do
- local mins = zone.bounds.mins
- local maxs = zone.bounds.maxs
- for x = Floor(mins.x,chunkSize), Ceil(maxs.x + 1,chunkSize), chunkSize do
- for y = Floor(mins.y,chunkSize), Ceil(maxs.y + 1,chunkSize), chunkSize do
- for z = Floor(mins.z,chunkSize), Ceil(maxs.z + 1,chunkSize), chunkSize do
- local idx = GetZoneIndex(Vector(x, y, z))
- zones.Map[idx] = zones.Map[idx] or {}
- table.insert(zones.Map[idx], zone)
- end
- end
- end
- end
-end
-
-function zones.GetNearbyZones(pos)
- //This system isn't working.
- -- local idx = GetZoneIndex(pos)
- -- return zones.Map[idx] or {}
- return zones.List
-end
-
-zones.Cache = {}
-local function ClearCache()
- for k,v in pairs(player.GetAll()) do
- zones.Cache[v] = {}
- end
-end
-ClearCache()
-hook.Add("Tick","zones_cache",ClearCache)
-
-if SERVER then
- util.AddNetworkString("zones_sync")
- util.AddNetworkString("zones_class")
-
- function zones.SaveZones()
- if not file.Exists("zones","DATA") then
- file.CreateDir("zones")
- end
- file.Write("zones/"..game.GetMap():gsub("_","-"):lower()..".txt", util.TableToJSON(zones.List))
- end
- concommand.Add("zone_save",function(ply,c,a)
- if not ply:IsAdmin() then return end
- zones.SaveZones()
- end)
-
- function zones.LoadZones()
- local tbl = file.Read("zones/"..game.GetMap():gsub("_","-"):lower()..".txt", "DATA")
- zones.List = tbl and util.JSONToTable(tbl) or {}
-
- //Update legacy files:
- for k,v in pairs(zones.List)do
- if not v.bounds then
- zones.CalcBounds(v)
- end
-
- hook.Run("OnZoneLoaded",v,v.class,k)
- end
- end
-
- local sync = false
- local syncply
-
- function zones.Sync(ply)
- sync = true
- syncply = ply
- end
-
- hook.Add("Tick","zones_sync",function()
- if sync then
- net.Start("zones_sync")
- net.WriteTable(zones.List)
- if syncply then
- net.Send(syncply)
- syncply = nil
- else
- net.Broadcast()
- zones.CreateZoneMapping()
- end
- sync = false
- end
- end)
-
- function zones.CreateZoneFromPoint(ent)
-
- local zone = {
- points = {{}}, --only 1 area when creating a new zone.
- height = {ent:GetTall()},
- class = ent:GetZoneClass(),
- bounds = {}
- }
-
- local id = table.maxn(zones.List) + 1
- local cur = ent
- repeat
- local pos = cur:GetPos() - Vector(0,0,2)
- zone.points[1][#zone.points[1]+1] = pos
-
- cur:SetZoneID(id)
- cur = cur:GetNext()
-
- until (cur == ent)
-
- zones.CalcBounds(zone,true)
-
- zones.List[id] = zone
- hook.Run("OnZoneCreated",zone,zone.class,id)
-
- zones.Sync()
-
-
- return zone, id
-
- end
-
- function zones.CalcBounds(zone,newZone)
- local mins,maxs = Vector(10000000,10000000,10000000), Vector(-10000000,-10000000,-10000000)
- for areanum,area in pairs(zone.points)do
- for k,pos in pairs(area) do
- maxs.x = math.max(pos.x, maxs.x)
- maxs.y = math.max(pos.y, maxs.y)
- maxs.z = math.max(pos.z+zone.height[areanum], maxs.z)
- mins.x = math.min(pos.x, mins.x)
- mins.y = math.min(pos.y, mins.y)
- mins.z = math.min(pos.z, mins.z)
- end
- end
- zone.bounds = {["mins"]=mins,["maxs"]=maxs}
- if not newZone then
- hook.Run("OnZoneChanged",zone,zone.class,zones.GetID(zone))
- end
- end
-
- function zones.Remove(id)
- hook.Run("OnZoneRemoved",zones.List[id],zones.List[id].class,id)
- zones.List[id] = nil
- zones.Sync()
- end
-
- function zones.CreatePointEnts(removeThese) --removeThese is optional.
- for k,v in pairs(removeThese or ents.FindByClass("ent_zone_point")) do --remove old
- v:Remove()
- end
-
- --create new
- for id,zone in pairs(zones.List)do
-
- for k, area in pairs(zone.points) do
-
- local first
- local curr
- for k2,point in ipairs(area)do
-
- local next = ents.Create("ent_zone_point")
-
- if IsValid(curr) then
- next:SetPos(point+Vector(0,0,1))
- curr:SetNext(next)
- -- curr:DeleteOnRemove(next)
- else
- first = next
- next:SetPos(point+Vector(0,0,1))
- end
-
- next.LastPoint = curr
- curr = next
- next:SetTall(zone.height[k])
- next:SetZoneClass(zone.class)
- next:Spawn()
- next:SetZoneID(id)
- next:SetAreaNumber(k)
-
- end
-
- curr:SetNext(first)
- -- curr:DeleteOnRemove(first)
- first.LastPoint = curr
-
- end
- end
-
- end
-
- function zones.Merge(from,to)
-
- local zfrom, zto = zones.List[from], zones.List[to]
-
- table.Add(zto.points, zfrom.points)
- table.Add(zto.height, zfrom.height)
-
- zones.CalcBounds(zto)
- zones.Remove(from)
-
- hook.Run("OnZoneMerged",zto,zto.class,to,zfrom,zfrom.class,from)
-
- zones.Sync()
-
- end
-
- function zones.Split(id,areanum)
- local zone = zones.List[id]
- local pts, h, bound = zone.points[areanum], zone.height[areanum]
-
- table.remove(zone.points,areanum)
- table.remove(zone.height,areanum)
-
- if #zone.points == 0 then
- zones.Remove(id)
- end
-
- local new = table.Copy(zone)
- new.points = {pts}
- new.height = {h}
-
- local id = table.maxn(zones.List)+1
- zones.List[id] = new
-
- zones.CalcBounds(zone)
- zones.CalcBounds(new)
-
- hook.Run("OnZoneSplit",new,new.class,id,zone,id)
-
- zones.Sync()
-
- return new,id
-
- end
-
- function zones.ChangeClass(id,class)
- local zone,new = zones.List[id],{}
- new.points = zone.points
- new.height = zone.height
- new.bounds = zone.bounds
- new.class = class
-
- zones.List[id] = new
-
- hook.Run("OnZoneCreated",new,class,id)
-
- zones.Sync()
- end
-
-
- local mapMins = -16000
- local mapMaxs = 16000
- local mapSize = 32000
- local chunkSize = 128
-
- function zones.GetZoneIndex(pos)
-
- local x = math.Remap(pos.x, mapMins, mapMaxs, 0, mapSize)
- local y = math.Remap(pos.y, mapMins, mapMaxs, 0, mapSize)
- local z = math.Remap(pos.z, mapMins, mapMaxs, 0, mapSize)
-
- local idxX = math.floor(x / chunkSize)
- local idxY = math.floor(y / chunkSize)
- local idxZ = math.floor(z / chunkSize)
- local idx = bit.bor(bit.lshift(idxX, 24), bit.lshift(idxY, 14), idxZ)
-
- return idx
-
- end
-
- hook.Add("InitPostEntity","zones_load",function()
- zones.LoadZones()
- end)
- hook.Add("PlayerInitialSpawn","zones_sync",function(ply)
- zones.Sync(ply)
- end)
-
- net.Receive("zones_class",function(len,ply)
- if not ply:IsAdmin() then return end
- local id = net.ReadFloat()
- local class = net.ReadString()
-
- for k,v in pairs(ents.FindByClass("ent_zone_point"))do
- if v:GetZoneID() == id then
- v:SetZoneClass(class)
- end
- end
-
- zones.ChangeClass(id,class)
-
- end)
-
-else
- net.Receive("zones_sync",function(len)
- zones.List = net.ReadTable()
- zones.CreateZoneMapping()
- end)
-
- function zones.ShowOptions(id)
-
- local zone = zones.List[id]
- local class = zone.class
-
- local frame = vgui.Create("DFrame")
- zones.optionsFrame = frame
- frame:MakePopup()
- frame:SetTitle("Zone Settings")
-
- local ztitle = vgui.Create("DLabel",frame)
- ztitle:Dock(TOP)
- ztitle:DockMargin(2,0,5,5)
- ztitle:SetText("Zone Class:")
- ztitle:SizeToContents()
-
- local zclass = vgui.Create("DComboBox",frame)
- zclass:Dock(TOP)
- zclass:DockMargin(0,0,0,5)
- for k,v in pairs(zones.Classes) do
- zclass:AddChoice(k,nil,k == class)
- end
- function zclass:OnSelect(i,class)
- net.Start("zones_class")
- net.WriteFloat(id)
- net.WriteString(class)
- net.SendToServer()
-
- frame.content:Remove()
-
- frame.content = vgui.Create("DPanel",frame)
- frame.content:Dock(FILL)
- frame.content:DockPadding(5,5,5,5)
-
- local w,h = hook.Run("ShowZoneOptions",zone,class,frame.content,id,frame)
- frame:SizeTo((w or 100)+8,(h or 2)+78, .2)
- frame:MoveTo(ScrW()/2-((w or 292)+8)/2,ScrH()/2-((h or 422)+78)/2, .2)
- end
-
- frame.content = vgui.Create("DPanel",frame)
- frame.content:Dock(FILL)
- frame.content:DockPadding(5,5,5,5)
-
- local w,h = hook.Run("ShowZoneOptions",zone,class,frame.content,id,frame)
- frame:SetSize((w or 100)+8,(h or 2)+78)
- frame:Center()
-
- end
-
-end
-
-
-
-//returns the point of intersection between two infinite lines.
-local function IntersectPoint(line1, line2)
-
- local x1,y1,x2,y2,x3,y3,x4,y4 = line1.x1,line1.y1,line1.x2,line1.y2,line2.x1,line2.y1,line2.x2,line2.y2
-
- local m1,m2 = (y1-y2)/((x1-x2)+.001),(y3-y4)/((x3-x4)+.001) --get the slopes
- local yint1,yint2 = (-m1*x1)+y1,(-m2*x3)+y3 --get the y-intercepts
- local x = (yint1-yint2)/(m2-m1) --calculate x pos
- local y = m1*x+yint1 --plug in x pos to get y pos
-
- return x,y
-
-end
-//Returns a bool if two SEGEMENTS intersect or not.
-local function Intersect(line1, line2)
-
- local x,y = IntersectPoint(line1, line2)
-
- local sx,sy = tostring(x), tostring(y)
- if (sx == "-inf" or sx == "inf" or sx == "nan") then
- return false
- end
-
- local minx1, maxx1 = math.min(line1.x1,line1.x2)-.1, math.max(line1.x1,line1.x2)+.1
- local minx2, maxx2 = math.min(line2.x1,line2.x2)-.1, math.max(line2.x1,line2.x2)+.1
- local miny1, maxy1 = math.min(line1.y1,line1.y2)-.1, math.max(line1.y1,line1.y2)+.1
- local miny2, maxy2 = math.min(line2.y1,line2.y2)-.1, math.max(line2.y1,line2.y2)+.1
-
- if (x >= minx1) and (x <= maxx1) and (x >= minx2) and (x <= maxx2) then
-
- if (y >= miny1) and (y <= maxy1) and (y >= miny2) and (y <= maxy2) then
-
- --debugoverlay.Sphere( Vector(x,y,LocalPlayer():GetPos().z), 3, FrameTime()+.01, Color(255,0,0), true)
-
- return true
-
- end
-
- end
-
+if not zones then
+ error("Bobbleheadbob's Zone's api is required for cross-server teleportation and npc spawning")
return false
-
end
-function zones.PointInPoly(point,poly) //True if point is within a polygon.
-
- local ray = {
- x1 = point.x,
- y1 = point.y,
- x2 = 100000,
- y2 = 100000
- }
-
- local inside = false
-
- local line = {
- x1 = 0,
- y1 = 0,
- x2 = 0,
- y2 = 0
- }
-
- //Perform ray test
- for k1, v in pairs(poly) do
- local v2 = poly[k1+1]
- if not v2 then
- v2 = poly[1]
- end
-
- line["x1"] = v.x
- line["y1"] = v.y
- line["x2"] = v2.x
- line["y2"] = v2.y
-
- if Intersect(ray,line) then
- inside = !inside
- end
-
- end
-
- return inside
-end
+return true
diff --git a/gamemode/init.lua b/gamemode/init.lua
index ac530f1..15f9885 100644
--- a/gamemode/init.lua
+++ b/gamemode/init.lua
@@ -3,5 +3,3 @@ AddCSLuaFile( "shared.lua" )
AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile("nrequire.lua")
include( "shared.lua" )
-
-print("Hello from init.lua")
diff --git a/gamemode/inventorysystem/prayers/cl_prayers.lua b/gamemode/inventorysystem/prayers/cl_prayers.lua
index aba778e..afea1cc 100644
--- a/gamemode/inventorysystem/prayers/cl_prayers.lua
+++ b/gamemode/inventorysystem/prayers/cl_prayers.lua
@@ -20,6 +20,13 @@ function pray:DrawOnDPanel(panel)
local ap = self.activeprayers[i]
explain:SetText(ap ~= nil and ap.Description or "Select a prayer")
end
+ rec:Receiver("prayer",function(s,tbl,dropped,mi,x,y)
+ if not dropped then return end
+ self.activeprayers[i] = tbl.item
+ if tbl.item.DoOnPanel then
+ tbl.item.DoOnPanel(s)
+ end
+ end,{})
agrid:AddItem(rec)
end
agrid:Dock(TOP)
@@ -38,15 +45,31 @@ function pray:DrawOnDPanel(panel)
grid:SetCols(4)
grid:SetColWide(w)
grid:SetRowHeight(w)
- for k,v in pairs(self.track) do
+ local function drawprayer(prayer)
local rec = vgui.Create("DImageButton",grid)
- rec:SetText(v.Name)
+ rec:SetText(prayer.Name)
rec:SetSize(w,w)
- if(v.DoOnPanel) then
- v:DoOnPanel(rec)
+ if(prayer.DoOnPanel) then
+ prayer:DoOnPanel(rec)
end
+ rec.item = prayer
+ rec:Droppable("prayer")
grid:AddItem(rec)
end
+
+ for k,v in pairs(self.track) do
+ drawprayer(v)
+ end
+
+ local observer = {}
+ observer.Put = function(obs,pos,item)
+ print("Prayer observer got request to put")
+ drawprayer(item)
+ end
+ observer.Remove = function(obs,pos,item)
+ print("I should never remove a prayer!")
+ end
+ return observer
end
--Rebind f1, f2, f3, f4 to prayers
diff --git a/gamemode/inventorysystem/prayers/sh_prayers.lua b/gamemode/inventorysystem/prayers/sh_prayers.lua
index 15cd2af..e1e7347 100644
--- a/gamemode/inventorysystem/prayers/sh_prayers.lua
+++ b/gamemode/inventorysystem/prayers/sh_prayers.lua
@@ -14,7 +14,10 @@ end
inv.Name = "Prayers"
inv.track = {}
function inv:FindPlaceFor(item)
- return {#track}
+ if item.isprayer then
+ return {#self.track}
+ end
+ return nil
end
function inv:CanFitIn(pos,item)
return pos[1] == #self.track
diff --git a/gamemode/inventorysystem/shapedinventory/sh_shaped.lua b/gamemode/inventorysystem/shapedinventory/sh_shaped.lua
index 66aa24b..69e18ca 100644
--- a/gamemode/inventorysystem/shapedinventory/sh_shaped.lua
+++ b/gamemode/inventorysystem/shapedinventory/sh_shaped.lua
@@ -11,7 +11,7 @@ if CLIENT then inv = nrequire("cl_shaped.lua") end
inv.Name = "Shaped Inventory"
inv.tracker = {}
inv.width = 5
-inv.height = 5
+inv.height = 10
local function calcposition(width,height,row,col)
return ((row-1) * width) + col
@@ -32,6 +32,7 @@ local function canfitin(self,arow,acol,shape)
end
function inv:FindPlaceFor(item)
+ if item.Shape == nil then return nil end
for row = 1, self.height do
for col = 1, self.width do
if canfitin(self,row,col,item.Shape) then
@@ -43,6 +44,7 @@ function inv:FindPlaceFor(item)
end
function inv:CanFitIn(tbl,item)
+ if item.Shape == nil then return false end
if canfitin(self,tbl[1],tbl[2],item.Shape) then
return true
else
diff --git a/gamemode/inventorysystem/skills/cl_skills.lua b/gamemode/inventorysystem/skills/cl_skills.lua
index c324a49..d4dbf65 100644
--- a/gamemode/inventorysystem/skills/cl_skills.lua
+++ b/gamemode/inventorysystem/skills/cl_skills.lua
@@ -1,53 +1,6 @@
local inv = {}
---[[
-inv.allskills = {
- ["forageing"] = {
- "hunting",
- "butchering",
- "woodcutting",
- "plant identification",
- },
- ["farming"] = {
- "domestication",
- "sowing",
- "arboriculture",
- "apiarism",
- "reaping",
- "fishing",
- },
- ["artisanship"] = {
- "pottery",
- "glass blowing",
- "cooking",
- "tanning",
- "tailoring",
- "metalworking",
- "lockpicking",
- "herbalism",
- "alchemy",
- "jewlery",
- },
- ["culture"] = {
- "litteracy",
- "writeing",
- "speech",
- "negotiation",
- "painting",
- "performing",
- },
- ["adventuring"] = {
- "polearm",
- "axeplay",
- "swordplay",
- "knifeing",
- "fenceing",
- "lockpicking",
- "archery",
- "throwing",
- },
-}
-]]
+local sc = nrequire("sh_skillcommon.lua")
--the gui elements
local elements = {}
@@ -63,17 +16,21 @@ local levelfunc = function(val)
end
local set_xp_of = function(name,ammt)
+ print("setting xp of", name," to ", ammt)
local lvl,frac = levelfunc(ammt)
- elements[name].label:SetText(string.format("%s : %d (%d%%)",name,lvl,frac))
+ elements[name].label:SetText(string.format("%s : %d (%2.5f%%)",name,lvl,frac))
elements[name].bar:SetFraction(frac)
end
inv.DrawOnDPanel = function(self,panel)
print("Drawing skills on panel")
+ PrintTable(sc.SkillList())
+ print("with")
+ PrintTable(self.skills)
local sheet = vgui.Create( "DColumnSheet", panel )
sheet:Dock( FILL )
- for k,v in pairs(self.allskills) do
+ for k,v in pairs(sc.SkillList()) do
local spanel = vgui.Create("DPanel", sheet)
spanel:Dock(FILL)
local layout = vgui.Create("DListLayout", spanel)
@@ -89,7 +46,7 @@ inv.DrawOnDPanel = function(self,panel)
["label"] = label,
["bar" ] = bar,
}
- set_xp_of(j,self.skills[j])
+ set_xp_of(j,self.skills[j] or 0)
ipanel:Add(label)
ipanel:Add(bar)
ipanel:InvalidateLayout()
@@ -102,11 +59,15 @@ inv.DrawOnDPanel = function(self,panel)
local prox = {}
prox.Put = function(s,position,item)
- set_xp_of(position[1],s[position[1]])
+ print("Calling inventory's put")
+ print("At time of call, skill was")
+ PrintTable(self)
+ set_xp_of(position[1],self.skills[position[1]])
end
prox.Remove = function(s,position)
- set_xp_of(position[1],s[position[1]])
+ print("Calling inventory's remove")
+ set_xp_of(position[1],self.skills[position[1]])
end
return prox
diff --git a/gamemode/inventorysystem/skills/sh_skillcommon.lua b/gamemode/inventorysystem/skills/sh_skillcommon.lua
new file mode 100644
index 0000000..d48fb98
--- /dev/null
+++ b/gamemode/inventorysystem/skills/sh_skillcommon.lua
@@ -0,0 +1,68 @@
+--[[
+ Common functions since skills are a special inventory, adding skills need to be a special item
+]]
+local itm = nrequire("item.lua")
+
+--Common things
+--Make sure items have a "name" and "ammt" attribute
+local item = {}
+
+item.Name = "Skill"
+
+item.isskill = true
+
+item.Serialize = function(self)
+ return util.TableToJSON({
+ name = self.name,
+ ammt = self.ammt
+ })
+end
+
+item.DeSerialize = function(self,data)
+ local tbl = util.JSONToTable(data)
+ tbl.isskill = true
+ return tbl
+end
+
+itm.RegisterItem(item)
+
+local pmeta = FindMetaTable("Player")
+
+function pmeta:AddSkill(name, ammt)
+ local item = itm.GetItemByName("Skill")
+ item.name = name
+ item.ammt = ammt
+ self:GiveItem(item)
+end
+
+local lib = {}
+local skills = {}
+--Skillname is a table of {string_group,string_name}
+function lib.RegisterSkill(skillname)
+ print("funcs.RegisterSkill called with")
+ PrintTable(skillname)
+ local group,name = skillname[1],skillname[2]
+ if not skills[group] then
+ skills[group] = {}
+ end
+ local alin = false
+ for k,v in pairs(skills[group]) do
+ if v == name then
+ alin = true
+ break
+ end
+ end
+ if alin then
+ log.warn("Re-registering skill: " .. skillname)
+ else
+ skills[group][#skills[group] + 1] = name
+ end
+ print("After registering skill, skills is")
+ PrintTable(skills)
+end
+
+function lib.SkillList()
+ return skills
+end
+
+return lib
diff --git a/gamemode/inventorysystem/skills/sh_skills.lua b/gamemode/inventorysystem/skills/sh_skills.lua
index 27c3bad..9b6edd5 100644
--- a/gamemode/inventorysystem/skills/sh_skills.lua
+++ b/gamemode/inventorysystem/skills/sh_skills.lua
@@ -4,23 +4,29 @@
--local itm = nrequire("item.lua")
--local ste = nrequire("utility/stream.lua")
local inventory = nrequire("inventory/inventory.lua")
+local log = nrequire("log.lua")
--local col = nrequire("config/colortheme.lua")
+local sc = nrequire("skills/sh_skillcommon.lua")
local inv = {}
if CLIENT then inv = nrequire("cl_skills.lua") end
-inv.allskills = {
+--TODO: uncomment these as their minigames are implemented
+inv.allskills = {}
+--[[
["forageing"] = {
- "hunting",
- "butchering",
- "woodcutting",
- "plant identification",
- "archery",
+-- "Hunting",
+-- "Butchering",
+-- "Woodcutting",
+-- "plant identification",
+-- "archery",
+-- "fishing",
+-- "Mineing",
},
["farming"] = {
- "domestication",
- "sowing",
- "arboriculture",
- "apiarism",
- "reaping",
+-- "domestication",
+-- "sowing",
+-- "arboriculture",
+-- "apiarism",
+-- "reaping",
},
["artisanship"] = {
"pottery",
@@ -44,6 +50,8 @@ inv.allskills = {
"painting",
"performing",
"faith",
+ "engraving",
+ "architect",
},
["adventuring"] = {
"evasion",
@@ -51,6 +59,7 @@ inv.allskills = {
"lockpicking",
"willpower",
"dexterity",
+ "swimming",
"sailing",
},
["fighting"] = {
@@ -66,14 +75,20 @@ inv.allskills = {
"archery",
}
}
-
+]]
inv.Name = "Skills"
inv.skills = {}
-for k,v in pairs(inv.allskills) do
- for i,j in pairs(v) do
- inv.skills[j] = 0
+local function calculate_skills()
+ for k,v in pairs(sc.SkillList()) do
+ for i,j in pairs(v) do
+ print("settings inv's skills' ", j, " to 0")
+ inv.skills[j] = 0
+ end
end
+ print("After calculating skills, inv was")
+ PrintTable(inv)
end
+calculate_skills()
--[[
item should be
@@ -84,11 +99,16 @@ item should be
}
]]
inv.FindPlaceFor = function(self, item)
- if item.isskill == nil then
+ print("finding place for ")
+ PrintTable(item)
+ if not item.isskill then
return nil
end
-
- if self.skills[item.name] then
+ print("Skill inventory trying to find place for, looking in ")
+ PrintTable(inv.skills)
+ print("for")
+ print(item.name)
+ if inv.skills[item.name] then
return {item.name}
else
return nil
@@ -96,11 +116,13 @@ inv.FindPlaceFor = function(self, item)
end
inv.CanFitIn = function(self,position,item)
- return self.skills[position[1]] != nil
+ return sc.SkillList()[position[1]] != nil
end
inv.Put = function(self,position,item)
- self.skills[position[1]] = self.skills[position[1]] + item.ammt
+ print("item is")
+ PrintTable(item)
+ self.skills[position[1]] = (self.skills[position[1]] or 0) + item.ammt
end
inv.Has = function(self,string_or_compare_func)
@@ -130,10 +152,20 @@ end
inv.DeSerialize = function(self,data)
if data == nil or data == '' then
- return table.Copy(self)
+ return table.Copy(inv)
end
+ calculate_skills()
+ print("At the time we deserialized, sc.skilllist was")
+ PrintTable(sc.SkillList())
+ print("Before making a copy of, inv is")
+ PrintTable(inv)
local cpy = table.Copy(self)
- cpy.skills = util.JSONToTable(data)
+ local gen = util.JSONToTable(data)
+ for k,v in pairs(gen) do
+ cpy.skills[k] = v
+ end
+ print("AFter deserializing inventory, it is")
+ PrintTable(cpy)
return cpy
end
diff --git a/gamemode/itemsystem/exampleitem.lua b/gamemode/itemsystem/exampleitem.lua
index d7af511..269e2d6 100644
--- a/gamemode/itemsystem/exampleitem.lua
+++ b/gamemode/itemsystem/exampleitem.lua
@@ -3,6 +3,9 @@
]]
local item = {}
+--Make sure we identify ourselves as a prayer
+item.isprayer = true
+
--Required, a name, all item names must be unique
item.Name = "Test item"
diff --git a/gamemode/nrequire.lua b/gamemode/nrequire.lua
index 1ec4fb7..29e350d 100644
--- a/gamemode/nrequire.lua
+++ b/gamemode/nrequire.lua
@@ -6,7 +6,6 @@
]]
--Don't run ourselves, or we'll get stuck in a recursive loop!
if nrequire ~= nil then return end
-print("hello from nrequire!")
local path = (GM or GAMEMODE).Folder:gsub("gamemodes/","") .. "/gamemode"
--[[
Calls func on all the files under dir.
@@ -161,6 +160,7 @@ function nrequire(req)
--Deal with bookkeeping dealing with circular dependancies, and include
pathstack[#pathstack + 1] = tpath
reqtbl[tpath] = include(tpath)
+ hook.Call("artery_file_included",nil,tpah)
--[[
co = coroutine.create(function()
reqtbl[tpath] = include(tpath)
@@ -192,7 +192,6 @@ hook.Call("artery_nrequire_defined")
If the file starts with cl_ it will only be included on the client, if it starts with sv_ it will only be included on the server. If it starts with anything else, it will be shared. Will detect and error on circuar dependancy.
]]
local function doincludes()
- print("doing includes")
paths = {}
TraverseFolder("",ins)
ntbl = rebuild_include_table(paths)
diff --git a/gamemode/shared.lua b/gamemode/shared.lua
index 588b81f..6304bce 100644
--- a/gamemode/shared.lua
+++ b/gamemode/shared.lua
@@ -1,6 +1,7 @@
include("nrequire.lua")
local ngm = GM or GAMEMODE
+ngm.Version = {0,7,2}
ngm.Name = "Artery"
ngm.Author = "Alexander \"Apickx\" Pickering"
-ngm.Email = "apickx@cogarr.org"
+ngm.Email = "alex@cogarr.net"
ngm.Website = "cogarr.net"
diff --git a/gamemode/shared/animations/move_evade.lua b/gamemode/shared/animations/move_evade.lua
index a5595aa..c4afa59 100644
--- a/gamemode/shared/animations/move_evade.lua
+++ b/gamemode/shared/animations/move_evade.lua
@@ -1,3 +1,5 @@
+nrequire("sh_animations.lua")
+
RegisterLuaAnimation('evade_left', {
FrameData = {
{
diff --git a/gamemode/shared/animations/swing_axe.lua b/gamemode/shared/animations/swing_axe.lua
index 60133b5..9e8ddb4 100644
--- a/gamemode/shared/animations/swing_axe.lua
+++ b/gamemode/shared/animations/swing_axe.lua
@@ -1,3 +1,5 @@
+nrequire("sh_animations.lua")
+
RegisterLuaAnimation('axe_swing_up', {
FrameData = {
{
diff --git a/gamemode/shared/animations/swing_fists.lua b/gamemode/shared/animations/swing_fists.lua
index b0c77b5..8c0f106 100644
--- a/gamemode/shared/animations/swing_fists.lua
+++ b/gamemode/shared/animations/swing_fists.lua
@@ -1,3 +1,5 @@
+nrequire("sh_animations.lua")
+
RegisterLuaAnimation('fist_swing_up', {
FrameData = {
{
diff --git a/gamemode/shared/animations/swing_hammer.lua b/gamemode/shared/animations/swing_hammer.lua
index efb8e34..2152709 100644
--- a/gamemode/shared/animations/swing_hammer.lua
+++ b/gamemode/shared/animations/swing_hammer.lua
@@ -1,3 +1,5 @@
+nrequire("sh_animations.lua")
+
RegisterLuaAnimation('hammer_swing_up', {
FrameData = {
{
diff --git a/gamemode/shared/animations/swing_knife.lua b/gamemode/shared/animations/swing_knife.lua
index f0bdec1..cf78bb5 100644
--- a/gamemode/shared/animations/swing_knife.lua
+++ b/gamemode/shared/animations/swing_knife.lua
@@ -1,3 +1,5 @@
+nrequire("sh_animations.lua")
+
RegisterLuaAnimation('knife_swing_up', {
FrameData = {
{
diff --git a/gamemode/shared/animations/swing_mele.lua b/gamemode/shared/animations/swing_mele.lua
index a0cd065..4a38876 100644
--- a/gamemode/shared/animations/swing_mele.lua
+++ b/gamemode/shared/animations/swing_mele.lua
@@ -1,3 +1,5 @@
+nrequire("sh_animations.lua")
+
RegisterLuaAnimation('swing_onehand_left', {
FrameData = {
{
diff --git a/gamemode/shared/log.lua b/gamemode/shared/log.lua
index 92bb349..618fd0c 100644
--- a/gamemode/shared/log.lua
+++ b/gamemode/shared/log.lua
@@ -2,39 +2,28 @@
local fn = nrequire("fn.lua")
local col = nrequire("colortheme.lua")
local log = {}
+local domain
+if SERVER then
+ domain = "[SERVER]"
+elseif CLIENT then
+ domain = "[CLIENT]"
+end
-log.debug = fn.compose(
- fn.curry(
- MsgC,
- col.console.cyan
- ),
- fn.curry(
- string.format,
- "[DEBUG] %s\n"
- )
-)
+function log.debug(...)
+ MsgC(col.console.gray,domain,"[DEBUG]",...,"\n")
+end
-log.info = fn.compose(
- fn.curry(
- MsgC,
- col.console.blue
- ),
- fn.curry(
- string.format,
- "[INFO] %s\n"
- )
-)
+function log.info(...)
+ MsgC(col.console.cyan,domain,"[INFO]",...,"\n")
+end
-log.warn = fn.compose(
- fn.curry(
- MsgC,
- col.console.yellow
- ),
- fn.curry(
- string.format,
- "[WARNING] %s\n"
- )
-)
+function log.warn(...)
+ MsgC(col.console.yellow,domain,"[WARNING]",...,"\n")
+end
+
+function log.error(...)
+ MsgC(col.console.red,domain,"[ERROR]",...,"\n")
+end
log.report = fn.curry(
file.Append,
diff --git a/gamemode/zones.lua b/gamemode/zones.lua
new file mode 100644
index 0000000..f95d6f2
--- /dev/null
+++ b/gamemode/zones.lua
@@ -0,0 +1,611 @@
+local version = 1.20 -- Older versions will not run if a newer version is used in another script.
+--[[
+ ZONES - by Bobbleheadbob with help from Zeh Matt
+ WARNING: If you edit any of these files, make them use a different namespace. Multiple scripts may depend on this library so modifying it can break other scripts.
+
+ Purpose:
+ For easy in-game designation of persistent polygonal zones which are used by any script.
+
+ How to Use:
+ All zones are saved in zones.List; see an example below.
+ Zone creation is handled with weapon_zone_designator and ent_zone_point, but can be done in code as well.
+ When a zone is created, changed, or removed all zones are synced to clients. When clients join they are also synced.
+ Any extra details can be saved to a zone. Everything is written to a txt file and is persistent to the map.
+
+ Since multiple scripts might use the zones system, don't assume that every zone is related to your script.
+ To register a zone class, use zones.RegisterClass(class, color); use a unique string like "Scriptname Room".
+ When a zone class is registered, admins can use the tool to create new ones.
+ When a new zone is created, the "OnZoneCreated" hook is called serverside. See the example file for documentation.
+ When a zone is loaded into the game, the "OnZoneLoaded" hook is called serverside. See the example file for documentation.
+ When a player edits a zone's properties, the "ShowZoneOptions" hook is called clientside. See the example file for documentation.
+
+ Use zones.FindByClass() to find all zones which are of a given class.
+ Use ply:GetCurrentZone() to find the zone that a player is standing in.
+
+ Installation:
+ This is a shared file so include it in any shared environment. Also include ent_zone_point and weapon_zone_designator as a shared ent and weapon.
+ You should not put this file directly in lua/autorun.
+
+ License:
+ YOU MAY use/edit this however you want, as long as you give proper attribution.
+ YOU MAY distribute this with other scripts whether they are paid or free.
+ YOU MAY NOT distribute this on its own. It must accompany another script.
+
+ Enjoy! ~Bobbleheadbob
+]]
+
+local table, math, Vector, pairs, ipairs, ents, bit = table, math, Vector, pairs, ipairs, ents, bit
+
+if zones then
+ local diff = math.abs(math.floor(version)-math.floor(zones.version)) > 0
+ if diff then
+ ErrorNoHalt("WARNING! Two scripts use VERY different versions of the zones API. Please tell one of them to update their script!\n")
+ end
+ if zones.version > version then
+ if diff then
+ print("The outdated version of zones is located at: "..debug.getinfo(1,"S").short_src)
+ end
+ print("A new version of zones exists. Using version "..zones.version.." instead of "..version)
+ return
+ elseif zones.version < version then
+ if diff then
+ print("The outdated version of zones is located at: "..debug.getinfo(zones.RegisterClass,"S").short_src)
+ end
+ print("A new version of zones exists. Using version "..version.." instead of "..zones.version)
+ end
+
+else
+ print("Loaded zones " ..version)
+end
+
+zones = zones or {}
+zones.version = version
+
+zones.Classes = zones.Classes or {}
+zones.List = zones.List or {}
+zones.Map = zones.Map or {}
+
+
+//Common interface functions:
+
+-- Registers a zone class which can then be created using weapon_zone_designator
+function zones.RegisterClass(class,color)
+ zones.Classes[class] = color
+end
+
+
+local plymeta = FindMetaTable("Player")
+--returns one of the zones a player is found in. Also returns that zone's ID. Class is optional to filter the search.
+function plymeta:GetCurrentZone(class)
+ local c = zones.Cache[self][class or "___"]
+ if c then return unpack(c) end
+ local z,id = zones.GetZoneAt(self:GetPos(), class)
+ zones.Cache[self][class or "___"] = {z,id}
+ return z,id
+end
+
+--returns a table of zones the player is in. Class is optional to filter the search.
+function plymeta:GetCurrentZones(class)
+ return zones.GetZonesAt(self:GetPos(),class)
+end
+
+function zones.GetZoneAt(pos,class) --works like above, except uses any point.
+
+ local nearby = zones.GetNearbyZones(pos)
+
+ for k,zone in pairs(nearby) do
+
+ if class and class != zone.class then continue end
+ if not pos:WithinAABox(zone.bounds.mins, zone.bounds.maxs) then
+ continue
+ end
+
+ for k1, points in pairs(zone.points) do
+ if zones.PointInPoly(pos,points) then
+ local z = points[1].z
+ if pos.z >= z and pos.z < z + zone.height[k1] then
+ return zone,k
+ end
+ end
+ end
+ end
+
+ return nil, -1
+
+end
+
+function zones.GetZonesAt(pos,class) --works like above, except uses any point.
+ local tbl = {}
+ local nearby = zones.GetNearbyZones(pos)
+ for k,zone in pairs(nearby) do
+ if class and class != zone.class then continue end
+ if not pos:WithinAABox(zone.bounds.mins,zone.bounds.maxs) then continue end
+ for k1, points in pairs(zone.points) do
+ if zones.PointInPoly(pos,points) then
+ local z = points[1].z
+ if pos.z >= z and pos.z < z + zone.height[k1] then
+ tbl[k] = zone
+ end
+ end
+ end
+ end
+ return tbl
+end
+
+--Gets a list of all zones which are of the specified class.
+function zones.FindByClass(class)
+ local tbl = {}
+
+ for k,v in pairs(zones.List) do
+ if v.class == class then
+ tbl[k] = v
+ end
+ end
+
+ return tbl
+end
+
+--Returns the numerical ID of a zone.
+function zones.GetID(zone)
+ return table.KeyFromValue(zones.List,zone)
+end
+
+
+
+
+//Getting into the meat of the API:
+local mapMins = -16000
+local mapMaxs = 16000
+local mapSize = 32000
+local chunkSize = 128
+
+local function GetZoneIndex(pos)
+
+ local x = pos.x + mapMaxs
+ local y = pos.y + mapMaxs
+ local z = pos.z + mapMaxs
+
+ local idxX = math.floor(x / chunkSize)
+ local idxY = math.floor(y / chunkSize)
+ local idxZ = math.floor(z / chunkSize)
+ local idx = bit.bor(bit.lshift(idxX, 24), bit.lshift(idxY, 14), idxZ)
+
+ return idx
+
+end
+
+local function Floor(x,to)
+ return math.floor(x / to) * to
+end
+local function Ceil(x,to)
+ return math.ceil(x / to) * to
+end
+
+function zones.CreateZoneMapping()
+ zones.Map = {}
+ for _, zone in pairs(zones.List) do
+ local mins = zone.bounds.mins
+ local maxs = zone.bounds.maxs
+ for x = Floor(mins.x,chunkSize), Ceil(maxs.x + 1,chunkSize), chunkSize do
+ for y = Floor(mins.y,chunkSize), Ceil(maxs.y + 1,chunkSize), chunkSize do
+ for z = Floor(mins.z,chunkSize), Ceil(maxs.z + 1,chunkSize), chunkSize do
+ local idx = GetZoneIndex(Vector(x, y, z))
+ zones.Map[idx] = zones.Map[idx] or {}
+ table.insert(zones.Map[idx], zone)
+ end
+ end
+ end
+ end
+end
+
+function zones.GetNearbyZones(pos)
+ //This system isn't working.
+ -- local idx = GetZoneIndex(pos)
+ -- return zones.Map[idx] or {}
+ return zones.List
+end
+
+zones.Cache = {}
+local function ClearCache()
+ for k,v in pairs(player.GetAll()) do
+ zones.Cache[v] = {}
+ end
+end
+ClearCache()
+hook.Add("Tick","zones_cache",ClearCache)
+
+if SERVER then
+ util.AddNetworkString("zones_sync")
+ util.AddNetworkString("zones_class")
+
+ function zones.SaveZones()
+ if not file.Exists("zones","DATA") then
+ file.CreateDir("zones")
+ end
+ file.Write("zones/"..game.GetMap():gsub("_","-"):lower()..".txt", util.TableToJSON(zones.List))
+ end
+ concommand.Add("zone_save",function(ply,c,a)
+ if not ply:IsAdmin() then return end
+ zones.SaveZones()
+ end)
+
+ function zones.LoadZones()
+ local tbl = file.Read("zones/"..game.GetMap():gsub("_","-"):lower()..".txt", "DATA")
+ zones.List = tbl and util.JSONToTable(tbl) or {}
+
+ //Update legacy files:
+ for k,v in pairs(zones.List)do
+ if not v.bounds then
+ zones.CalcBounds(v)
+ end
+
+ hook.Run("OnZoneLoaded",v,v.class,k)
+ end
+ end
+
+ local sync = false
+ local syncply
+
+ function zones.Sync(ply)
+ sync = true
+ syncply = ply
+ end
+
+ hook.Add("Tick","zones_sync",function()
+ if sync then
+ net.Start("zones_sync")
+ net.WriteTable(zones.List)
+ if syncply then
+ net.Send(syncply)
+ syncply = nil
+ else
+ net.Broadcast()
+ zones.CreateZoneMapping()
+ end
+ sync = false
+ end
+ end)
+
+ function zones.CreateZoneFromPoint(ent)
+
+ local zone = {
+ points = {{}}, --only 1 area when creating a new zone.
+ height = {ent:GetTall()},
+ class = ent:GetZoneClass(),
+ bounds = {}
+ }
+
+ local id = table.maxn(zones.List) + 1
+ local cur = ent
+ repeat
+ local pos = cur:GetPos() - Vector(0,0,2)
+ zone.points[1][#zone.points[1]+1] = pos
+
+ cur:SetZoneID(id)
+ cur = cur:GetNext()
+
+ until (cur == ent)
+
+ zones.CalcBounds(zone,true)
+
+ zones.List[id] = zone
+ hook.Run("OnZoneCreated",zone,zone.class,id)
+
+ zones.Sync()
+
+
+ return zone, id
+
+ end
+
+ function zones.CalcBounds(zone,newZone)
+ local mins,maxs = Vector(10000000,10000000,10000000), Vector(-10000000,-10000000,-10000000)
+ for areanum,area in pairs(zone.points)do
+ for k,pos in pairs(area) do
+ maxs.x = math.max(pos.x, maxs.x)
+ maxs.y = math.max(pos.y, maxs.y)
+ maxs.z = math.max(pos.z+zone.height[areanum], maxs.z)
+ mins.x = math.min(pos.x, mins.x)
+ mins.y = math.min(pos.y, mins.y)
+ mins.z = math.min(pos.z, mins.z)
+ end
+ end
+ zone.bounds = {["mins"]=mins,["maxs"]=maxs}
+ if not newZone then
+ hook.Run("OnZoneChanged",zone,zone.class,zones.GetID(zone))
+ end
+ end
+
+ function zones.Remove(id)
+ hook.Run("OnZoneRemoved",zones.List[id],zones.List[id].class,id)
+ zones.List[id] = nil
+ zones.Sync()
+ end
+
+ function zones.CreatePointEnts(removeThese) --removeThese is optional.
+ for k,v in pairs(removeThese or ents.FindByClass("ent_zone_point")) do --remove old
+ v:Remove()
+ end
+
+ --create new
+ for id,zone in pairs(zones.List)do
+
+ for k, area in pairs(zone.points) do
+
+ local first
+ local curr
+ for k2,point in ipairs(area)do
+
+ local next = ents.Create("ent_zone_point")
+
+ if IsValid(curr) then
+ next:SetPos(point+Vector(0,0,1))
+ curr:SetNext(next)
+ -- curr:DeleteOnRemove(next)
+ else
+ first = next
+ next:SetPos(point+Vector(0,0,1))
+ end
+
+ next.LastPoint = curr
+ curr = next
+ next:SetTall(zone.height[k])
+ next:SetZoneClass(zone.class)
+ next:Spawn()
+ next:SetZoneID(id)
+ next:SetAreaNumber(k)
+
+ end
+
+ curr:SetNext(first)
+ -- curr:DeleteOnRemove(first)
+ first.LastPoint = curr
+
+ end
+ end
+
+ end
+
+ function zones.Merge(from,to)
+
+ local zfrom, zto = zones.List[from], zones.List[to]
+
+ table.Add(zto.points, zfrom.points)
+ table.Add(zto.height, zfrom.height)
+
+ zones.CalcBounds(zto)
+ zones.Remove(from)
+
+ hook.Run("OnZoneMerged",zto,zto.class,to,zfrom,zfrom.class,from)
+
+ zones.Sync()
+
+ end
+
+ function zones.Split(id,areanum)
+ local zone = zones.List[id]
+ local pts, h, bound = zone.points[areanum], zone.height[areanum]
+
+ table.remove(zone.points,areanum)
+ table.remove(zone.height,areanum)
+
+ if #zone.points == 0 then
+ zones.Remove(id)
+ end
+
+ local new = table.Copy(zone)
+ new.points = {pts}
+ new.height = {h}
+
+ local id = table.maxn(zones.List)+1
+ zones.List[id] = new
+
+ zones.CalcBounds(zone)
+ zones.CalcBounds(new)
+
+ hook.Run("OnZoneSplit",new,new.class,id,zone,id)
+
+ zones.Sync()
+
+ return new,id
+
+ end
+
+ function zones.ChangeClass(id,class)
+ local zone,new = zones.List[id],{}
+ new.points = zone.points
+ new.height = zone.height
+ new.bounds = zone.bounds
+ new.class = class
+
+ zones.List[id] = new
+
+ hook.Run("OnZoneCreated",new,class,id)
+
+ zones.Sync()
+ end
+
+
+ local mapMins = -16000
+ local mapMaxs = 16000
+ local mapSize = 32000
+ local chunkSize = 128
+
+ function zones.GetZoneIndex(pos)
+
+ local x = math.Remap(pos.x, mapMins, mapMaxs, 0, mapSize)
+ local y = math.Remap(pos.y, mapMins, mapMaxs, 0, mapSize)
+ local z = math.Remap(pos.z, mapMins, mapMaxs, 0, mapSize)
+
+ local idxX = math.floor(x / chunkSize)
+ local idxY = math.floor(y / chunkSize)
+ local idxZ = math.floor(z / chunkSize)
+ local idx = bit.bor(bit.lshift(idxX, 24), bit.lshift(idxY, 14), idxZ)
+
+ return idx
+
+ end
+
+ hook.Add("InitPostEntity","zones_load",function()
+ zones.LoadZones()
+ end)
+ hook.Add("PlayerInitialSpawn","zones_sync",function(ply)
+ zones.Sync(ply)
+ end)
+
+ net.Receive("zones_class",function(len,ply)
+ if not ply:IsAdmin() then return end
+ local id = net.ReadFloat()
+ local class = net.ReadString()
+
+ for k,v in pairs(ents.FindByClass("ent_zone_point"))do
+ if v:GetZoneID() == id then
+ v:SetZoneClass(class)
+ end
+ end
+
+ zones.ChangeClass(id,class)
+
+ end)
+
+else
+ net.Receive("zones_sync",function(len)
+ zones.List = net.ReadTable()
+ zones.CreateZoneMapping()
+ end)
+
+ function zones.ShowOptions(id)
+
+ local zone = zones.List[id]
+ local class = zone.class
+
+ local frame = vgui.Create("DFrame")
+ zones.optionsFrame = frame
+ frame:MakePopup()
+ frame:SetTitle("Zone Settings")
+
+ local ztitle = vgui.Create("DLabel",frame)
+ ztitle:Dock(TOP)
+ ztitle:DockMargin(2,0,5,5)
+ ztitle:SetText("Zone Class:")
+ ztitle:SizeToContents()
+
+ local zclass = vgui.Create("DComboBox",frame)
+ zclass:Dock(TOP)
+ zclass:DockMargin(0,0,0,5)
+ for k,v in pairs(zones.Classes) do
+ zclass:AddChoice(k,nil,k == class)
+ end
+ function zclass:OnSelect(i,class)
+ net.Start("zones_class")
+ net.WriteFloat(id)
+ net.WriteString(class)
+ net.SendToServer()
+
+ frame.content:Remove()
+
+ frame.content = vgui.Create("DPanel",frame)
+ frame.content:Dock(FILL)
+ frame.content:DockPadding(5,5,5,5)
+
+ local w,h = hook.Run("ShowZoneOptions",zone,class,frame.content,id,frame)
+ frame:SizeTo((w or 100)+8,(h or 2)+78, .2)
+ frame:MoveTo(ScrW()/2-((w or 292)+8)/2,ScrH()/2-((h or 422)+78)/2, .2)
+ end
+
+ frame.content = vgui.Create("DPanel",frame)
+ frame.content:Dock(FILL)
+ frame.content:DockPadding(5,5,5,5)
+
+ local w,h = hook.Run("ShowZoneOptions",zone,class,frame.content,id,frame)
+ frame:SetSize((w or 100)+8,(h or 2)+78)
+ frame:Center()
+
+ end
+
+end
+
+
+
+//returns the point of intersection between two infinite lines.
+local function IntersectPoint(line1, line2)
+
+ local x1,y1,x2,y2,x3,y3,x4,y4 = line1.x1,line1.y1,line1.x2,line1.y2,line2.x1,line2.y1,line2.x2,line2.y2
+
+ local m1,m2 = (y1-y2)/((x1-x2)+.001),(y3-y4)/((x3-x4)+.001) --get the slopes
+ local yint1,yint2 = (-m1*x1)+y1,(-m2*x3)+y3 --get the y-intercepts
+ local x = (yint1-yint2)/(m2-m1) --calculate x pos
+ local y = m1*x+yint1 --plug in x pos to get y pos
+
+ return x,y
+
+end
+//Returns a bool if two SEGEMENTS intersect or not.
+local function Intersect(line1, line2)
+
+ local x,y = IntersectPoint(line1, line2)
+
+ local sx,sy = tostring(x), tostring(y)
+ if (sx == "-inf" or sx == "inf" or sx == "nan") then
+ return false
+ end
+
+ local minx1, maxx1 = math.min(line1.x1,line1.x2)-.1, math.max(line1.x1,line1.x2)+.1
+ local minx2, maxx2 = math.min(line2.x1,line2.x2)-.1, math.max(line2.x1,line2.x2)+.1
+ local miny1, maxy1 = math.min(line1.y1,line1.y2)-.1, math.max(line1.y1,line1.y2)+.1
+ local miny2, maxy2 = math.min(line2.y1,line2.y2)-.1, math.max(line2.y1,line2.y2)+.1
+
+ if (x >= minx1) and (x <= maxx1) and (x >= minx2) and (x <= maxx2) then
+
+ if (y >= miny1) and (y <= maxy1) and (y >= miny2) and (y <= maxy2) then
+
+ --debugoverlay.Sphere( Vector(x,y,LocalPlayer():GetPos().z), 3, FrameTime()+.01, Color(255,0,0), true)
+
+ return true
+
+ end
+
+ end
+
+ return false
+
+end
+function zones.PointInPoly(point,poly) //True if point is within a polygon.
+
+ local ray = {
+ x1 = point.x,
+ y1 = point.y,
+ x2 = 100000,
+ y2 = 100000
+ }
+
+ local inside = false
+
+ local line = {
+ x1 = 0,
+ y1 = 0,
+ x2 = 0,
+ y2 = 0
+ }
+
+ //Perform ray test
+ for k1, v in pairs(poly) do
+
+ local v2 = poly[k1+1]
+ if not v2 then
+ v2 = poly[1]
+ end
+
+ line["x1"] = v.x
+ line["y1"] = v.y
+ line["x2"] = v2.x
+ line["y2"] = v2.y
+
+ if Intersect(ray,line) then
+ inside = !inside
+ end
+
+ end
+
+ return inside
+end \ No newline at end of file