aboutsummaryrefslogtreecommitdiff
path: root/gamemode/core
diff options
context:
space:
mode:
authorAlexander Pickering <alexandermpickering@gmail.com>2017-04-02 20:05:56 -0400
committerAlexander Pickering <alexandermpickering@gmail.com>2017-04-02 20:05:56 -0400
commit191ba416c8b611ea4901cead138789a357c56134 (patch)
treeb30ae3473c16028a14d3ed0c80633f360cc1c914 /gamemode/core
parenta22cbeddc5f8fb61e87a30aa14ba354de5cf4431 (diff)
downloadartery-191ba416c8b611ea4901cead138789a357c56134.tar.gz
artery-191ba416c8b611ea4901cead138789a357c56134.tar.bz2
artery-191ba416c8b611ea4901cead138789a357c56134.zip
I finally had some time to work on this... dependency added on bobbleheadbob's zone addon
Diffstat (limited to 'gamemode/core')
-rw-r--r--gamemode/core/clienteffects/blocked.lua3
-rw-r--r--gamemode/core/database/sv_queries.lua51
-rw-r--r--gamemode/core/database/sv_setup.lua67
-rw-r--r--gamemode/core/inventory/common/items.lua31
-rw-r--r--gamemode/core/inventory/common/weapons.lua126
-rw-r--r--gamemode/core/inventory/inventory.lua33
-rw-r--r--gamemode/core/inventory/item.lua8
-rw-r--r--gamemode/core/inventory/sv_invtracker.lua78
-rw-r--r--gamemode/core/mapstich/cl_mapstich.lua12
-rw-r--r--gamemode/core/mapstich/sv_mapstich.lua70
-rw-r--r--gamemode/core/npc/cl_shop.lua141
-rw-r--r--gamemode/core/npc/sv_shop.lua58
-rw-r--r--gamemode/core/pac/sv_pac.lua2
13 files changed, 599 insertions, 81 deletions
diff --git a/gamemode/core/clienteffects/blocked.lua b/gamemode/core/clienteffects/blocked.lua
new file mode 100644
index 0000000..fa2352c
--- /dev/null
+++ b/gamemode/core/clienteffects/blocked.lua
@@ -0,0 +1,3 @@
+--[[
+ Return a function that will get called when our attack is blocked (client side)
+]]
diff --git a/gamemode/core/database/sv_queries.lua b/gamemode/core/database/sv_queries.lua
new file mode 100644
index 0000000..4e48255
--- /dev/null
+++ b/gamemode/core/database/sv_queries.lua
@@ -0,0 +1,51 @@
+--[[
+ Some helper functions for building sql queries
+]]
+
+local fn = nrequire("utility/fn.lua")
+local track = nrequire("core/inventory/sv_invtracker.lua")
+
+local q = {}
+
+function q.serialize_player(ply)
+ local sdata = {}
+ local invs = {}
+ for k,v in pairs(ply.data.inventories) do
+ invs[k] = {v.Name,v:Serialize()}
+ end
+ sdata.inventories = invs
+ sdata.skills = ply.data.skills
+ sdata.quests = ply.data.quests
+ sdata.prayers = ply.data.prayers
+ sdata.credits = ply.data.credits
+ return util.TableToJSON(sdata)
+end
+
+function q.deserialize_player(ply,str)
+ print("Deseriailizeing player",ply," with ", str)
+ track.ClearInventories(ply)
+ local tbl = util.JSONToTable(str)
+ local invs = tbl.inventories
+ print("Inventories was", invs)
+ PrintTable(invs)
+ for k,v in pairs(invs) do
+ print("Giveing inventory",v[1],v[2])
+ track.GiveInventoryWithData(ply,v[1],v[2])
+ end
+ ply.data = ply.data or {}
+ ply.data.skills = tbl.skills or {}
+ ply.data.quests = tbl.quests or {}
+ ply.data.prayers = tbl.prayers or {}
+ ply.data.credits = tbl.credits or 100
+ print("After deserializeing player, their .data is",ply.data)
+ PrintTable(ply.data)
+ track.SendPlayerData(ply)
+end
+
+function q.s_fmt(fmt,...)
+ local args = {...}
+ fn.map(args,MySQLite.SQLStr)
+ return string.format(fmt,unpack(args))
+end
+
+return q
diff --git a/gamemode/core/database/sv_setup.lua b/gamemode/core/database/sv_setup.lua
index 0d0eb74..2fb7ed7 100644
--- a/gamemode/core/database/sv_setup.lua
+++ b/gamemode/core/database/sv_setup.lua
@@ -2,10 +2,8 @@
nrequire("sv_mysqlite.lua")
local config = nrequire("config/sv_sql.lua")
local data = nrequire("config/sv_newplayer.lua")
-local fn = nrequire("fn.lua")
-local col = nrequire("colortheme.lua")
-local inv = nrequire("inventory/inventory.lua")
-local track = nrequire("sv_invtracker.lua")
+local col = nrequire("config/colortheme.lua")
+local q = nrequire("core/database/sv_queries.lua")
local sql = {}
--Setup the database if it's not already
@@ -14,7 +12,7 @@ CREATE TABLE IF NOT EXISTS playerdata(SteamID bigint primary key, PlayerData jso
--Create a new player
local create_player_query = [[
-INSERT INTO playerdata (`SteamID`,`PlayerData`,`MetaData`) VALUES(%.0f,%q,%q)]]
+INSERT INTO playerdata (`SteamID`,`PlayerData`,`MetaData`) VALUES(%.0f,'%s','%s')]]
--Get a player's data from the database
local fetch_player_query = [[
@@ -22,48 +20,14 @@ SELECT PlayerData, MetaData FROM playerdata WHERE SteamID=%.0f
]]
local save_player_query = [[
-UPDATE playerdata SET MetaData=%q PlayerData=%q WHERE SteamID=%.0f
+UPDATE playerdata SET MetaData="%s" PlayerData="%s" WHERE SteamID=%.0f
]]
-local s_fmt = function(fmt,...)
- local args = {...}
- fn.map(args,MySQLite.SQLStr)
- return string.format(fmt,unpack(args))
-end
-
local function q_fai(err,query)
- MsgC(col.console.red,string.format("Error executing %q, error:%s",query,err))
+ MsgC(col.console.red,string.format("Error executing %s, error:%s",query,err))
end
-local function serialize_player(ply)
- local sdata = {}
- local invs = {}
- for k,v in pairs(ply.data.inventories) do
- invs[k] = {v.Name,v:Serialize()}
- end
- sdata.inventories = invs
- sdata.skills = ply.data.skills
- sdata.quests = ply.data.quests
- sdata.prayers = ply.data.prayers
- return util.TableToJSON(sdata)
-end
-local function deserialize_player(ply,str)
- print("Deseriailizeing player",ply," with ", str)
- track.ClearInventories(ply)
- local tbl = util.JSONToTable(str)
- local invs = tbl.inventories
- print("Inventories was", invs)
- PrintTable(invs)
- for k,v in pairs(invs) do
- print("Giveing inventory",v[1],v[2])
- track.GiveInventoryWithData(ply,v[1],v[2])
- end
- ply.data.skills = tbl.skills or {}
- ply.data.quests = tbl.quests or {}
- ply.data.prayers = tbl.prayers or {}
- track.SendPlayerData(ply)
-end
local function connect()
print("Connecting to the database...")
@@ -81,7 +45,7 @@ connect()
--Retruns (PlayerData, MetaData) or nil
function sql.GetPlayerData(ply)
local s64 = ply:SteamID64()
- local q_str = s_fmt(fetch_player_query,s64)
+ local q_str = q.s_fmt(fetch_player_query,s64)
local q_suc = function(res,li)
print("Got player's data:",res,type(res))
if res == nil then
@@ -101,13 +65,18 @@ function sql.GetPlayerData(ply)
return
end
print("We were on the right server")
- local _,_,x,y,z = mtbl.lastlocation:find("([%d%.]+) ([%d%.]+) ([%d%.]+)")
+ --[[
+ print("Before finding data in the metatable, mtbl was ")
+ PrintTable(mtbl)
+ print(type(mtbl.lastlocation))
+ local _,_,x,y,z = string.find(mtbl.lastlocation,"([-%d%.]+) ([-%d%.]+) ([-%d%.]+)")
local vec = {x,y,z}
for k,v in pairs(vec) do vec[k] = tonumber(v) end
print("setting player pos to")
PrintTable(vec)
- ply:SetPos(Vector(unpack(vec)))
- deserialize_player(ply,plyd)
+ ]]
+ ply:SetPos(mtbl.lastlocation)
+ q.deserialize_player(ply,plyd)
end
end
print("doing query",q_str)
@@ -122,7 +91,7 @@ function sql.CreatePlayerTable(ply)
local plymet = data.newmeta()
local plydata = util.TableToJSON(plytbl)
local metdata = util.TableToJSON(plymet)
- local q_str = s_fmt(create_player_query,s64,plydata,metdata)
+ local q_str = q.s_fmt(create_player_query,s64,plydata,metdata)
local q_suc = function(res,li)
print("Inserted new player",ply)
sql.GetPlayerData(ply)
@@ -133,12 +102,12 @@ end
function sql.SendPlayerToInstance(ply,ls,ll)
local s64 = ply:SteamID64()
- local plydata = serialize_player(ply)
+ local plydata = q.serialize_player(ply)
local plymeta = util.TableToJSON({
lastserver = ls,
lastlocation = ll
})
- local q_str = s_fmt(save_player_query,plymeta,plydata,s64)
+ local q_str = q.s_fmt(save_player_query,plymeta,plydata,s64)
local q_suc = function(res,li)
print("Successfully saved player data")
end
@@ -157,4 +126,6 @@ concommand.Add("DoQuery",function(ply,cmd,args)
end
end)
+print("In sv_setup.lua, sql before returning is", sql)
+
return sql
diff --git a/gamemode/core/inventory/common/items.lua b/gamemode/core/inventory/common/items.lua
new file mode 100644
index 0000000..03113f5
--- /dev/null
+++ b/gamemode/core/inventory/common/items.lua
@@ -0,0 +1,31 @@
+
+local items = {}
+
+local function drop_provided(ent,invid,frompos)
+ assert(CLIENT,"requested to drop an item when we are not the client!")
+ net.Start("art_RequestInvDrop")
+ net.WriteEntity(ent)
+ net.WriteUInt(invid,32)
+ net.WriteTable(frompos)
+ net.SendToServer()
+end
+
+local function drop_self(tbl)
+
+end
+
+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.WriteUInt(invid,32)
+ net.WriteTable(frompos)
+ net.SendToServer()
+end
+
+return items
diff --git a/gamemode/core/inventory/common/weapons.lua b/gamemode/core/inventory/common/weapons.lua
new file mode 100644
index 0000000..9e6eead
--- /dev/null
+++ b/gamemode/core/inventory/common/weapons.lua
@@ -0,0 +1,126 @@
+--[[
+ Some common functionality that many weapons need
+]]
+
+local com = {}
+
+--- Finds the direction a player is moveing.
+-- @param player The player to find the move direction of
+-- @return The string "forward", "backward", "right", or "left"
+function com.playermovedir(player)
+ local vel = player:GetVelocity():GetNormalized()
+ vel.z = 0
+ local swings = {
+ {player:GetForward(),"forward"},
+ {-player:GetForward(),"backward"},
+ {player:GetRight(),"right"},
+ {-player:GetRight(),"left"}
+ }
+ table.sort(swings,function(a,b)
+ return vel:Dot(a[1]) > vel:Dot(b[1])
+ end)
+ return swings[1][2]
+end
+
+--- The arc swing of a weapon.
+-- Finds anything that a weapon should hit in it's swing, and calls a function on it.
+-- @param player The player that's swinging the weapon
+-- @param tiems A table of times that the trace calculations should be done at, this table needs to be the same length as the positions table
+-- @param positions The position offsets from the player that swung that should be the start/end points of the arc
+-- @param onhit A function to call on any entities that were hit in the swing of the weapon.
+function com.swingarc(player,times,positions,onhit)
+ local positionpoints = {}
+ --table.insert(positionset,positionpoints)
+ for k,v in ipairs(times) do
+ timer.Simple(v,function()
+ ART.TraceWeapon = true
+ ART.TraceStart = CurTime()
+ local add = Vector(0,0,64)
+ if player:Crouching() then
+ add = Vector(0,0,32)
+ end
+ print("positions[k]",positions[k],"playerpos",player:GetPos(),"add",add)
+ local weaponpos = positions[k] + player:GetPos() + add
+ table.insert(positionpoints,weaponpos)
+ if #positionpoints > 1 then
+ --print("Trace from ", positionpoints[#positionpoints-1], " to ", positionpoints[#positionpoints])
+ local tr = util.TraceLine({
+ start = positionpoints[#positionpoints-1],
+ endpos = positionpoints[#positionpoints],
+ })
+ onhit(tr)
+ end
+ end)
+ end
+ timer.Simple(times[#times],function()
+ net.Start("setwepswing")
+ net.WriteTable(positionpoints)
+ net.Broadcast()
+ --print("Inserted swing, drawn positions are now:")
+ --PrintTable(positionset)
+ ART.TraceWeapon = false
+ end)
+end
+
+--Creates a table of ["forward|backward|left|right"] = function()
+--When called, the function does an attack.
+function com.createattackstable(tbl_attackdata,attacker)
+ local movementtbl = {}
+ for k,v in pairs(tbl_attackdata) do
+ movementtbl[k] = function()
+ attacker:SetLuaAnimation(v.anim)
+ timer.Simple(v.animtime,function()
+ attacker:StopLuaAnimation(v.anim)
+ end)
+ local times, pos = {},{}
+ for i,j in pairs(v.data) do
+ times[i] = 1 + j[1]
+ pos[i] = Vector(j[2])
+ pos[i]:Rotate(attacker:GetAimVector():Angle())
+ end
+ if pos[1] == nil then return end
+ com.swingarc(attacker,times,pos,function(tr)
+ if not tr.Hit then return end
+ if tr.Entity.Blocking ~= nil and tr.Entity.Blocking == k then
+ eff()
+ elseif tr.Entity.TakeDamage ~= nil and tr.Entity ~= attacker then
+ tr.Entity:TakeDamage(v.dammage,attacker,attacker:GetActiveWeapon())
+ end
+ end)
+ end
+ end
+
+ --Empty functions for attacks not defined
+ for k,v in pairs({"left","right","forward","backward"}) do
+ if movementtbl[k] == nil then
+ movementtbl[k] = function() end
+ end
+ end
+
+ return movementtbl
+end
+
+if SERVER then
+ util.AddNetworkString("setwepswing")
+end
+local positionset = {}
+
+net.Receive("setwepswing",function()
+ positionset = net.ReadTable()
+ print("Got message to read positionset, is now")
+ PrintTable(positionset)
+end)
+
+hook.Add( "HUDPaint", "weaponswings", function()
+ cam.Start3D() -- Start the 3D function so we can draw onto the screen.
+ local v = positionset
+ for i = 1,#v-1 do
+ render.DrawLine( v[i], v[i + 1], Color(255,0,0,255), false )
+ render.DrawLine( v[i], v[i] + Vector(0,0,20),Color(0,255,0,255),false)
+ end
+ --render.SetMaterial( material ) -- Tell render what material we want, in this case the flash from the gravgun
+ --render.DrawSprite( pos, 16, 16, white ) -- Draw the sprite in the middle of the map, at 16x16 in it's original colour with full alpha.
+ cam.End3D()
+end )
+
+return com
diff --git a/gamemode/core/inventory/inventory.lua b/gamemode/core/inventory/inventory.lua
index b4c025c..6b6f6f4 100644
--- a/gamemode/core/inventory/inventory.lua
+++ b/gamemode/core/inventory/inventory.lua
@@ -1,20 +1,33 @@
--[[
Public functions:
RegisterInventory(tbl_inventory) ::nil
+ Registers a new inventory prototype, see below
CreateInventory(string_name) ::table_inventory
+ Creates a new inventory be sure to set the .owner and .id fields!
CreateInventoryFromData(string_name,string_data)::table_inventory)
+ Just deserializes an inventory. You still need to set .owner and .id!
DeriveInventory(string_name) ::table_inventory
+ Creates a new inventory from an old, allows for heiarchy.
Inventories have the following structure
- field returns description
- inv.Name ::string The name!
- inv:FindPlaceFor(item) ::table_position or nil Finds a place for the item
- inv:CanFitIn(table_position,item) ::boolean Check if the item can fit in the position
- inv:Put(table_position,item) ::nil Put an item in at the position
- inv:Has(string_or_compare_func) ::table_position or nil find an item in the inventory
- inv:Remove(position) ::table_item Remove an item from the position
- inv:Get(position) ::table_item Get the item at a position
- inv:Serialize() ::string Serialize the item to store it in a db
- inv:DeSerialize(str) ::table_inventory recreate the item from data in serialize
+ field returns
+ inv.Name ::string
+ The name!
+ inv:FindPlaceFor(item) ::table_position or nil
+ Finds a place for the item
+ inv:CanFitIn(table_position,item) ::boolean
+ Check if the item can fit in the position
+ inv:Put(table_position,item) ::nil
+ Put an item in at the position
+ inv:Has(string_or_compare_func) ::table_position or nil
+ find an item in the inventory
+ inv:Remove(position) ::table_item
+ Remove an item from the position
+ inv:Get(position) ::table_item
+ Get the item at a position
+ inv:Serialize() ::string
+ Serialize the item to store it in a db
+ inv:DeSerialize(str) ::table_inventory
+ recreate the item from data in serialize
The above fields must be defined for new inventories.
-----------------------------------------------------
The below are automatically made if they do not exist.
diff --git a/gamemode/core/inventory/item.lua b/gamemode/core/inventory/item.lua
index dd788d6..103da7f 100644
--- a/gamemode/core/inventory/item.lua
+++ b/gamemode/core/inventory/item.lua
@@ -35,7 +35,13 @@ end
function itm.GetItemByName(name)
assert(items[name] ~= nil,string.format("Attempted to get item with invalid name %q Valid item names are:\n\t%s",name,table.concat(table.GetKeys(items),"\n\t")))
- return items[name]
+ local item
+ if items[name].init then
+ item = items[name]:init()
+ else
+ item = table.Copy(items[name])
+ end
+ return item
end
function itm.GetItemFromData(name,data)
diff --git a/gamemode/core/inventory/sv_invtracker.lua b/gamemode/core/inventory/sv_invtracker.lua
index 5331261..4c1fc1b 100644
--- a/gamemode/core/inventory/sv_invtracker.lua
+++ b/gamemode/core/inventory/sv_invtracker.lua
@@ -12,6 +12,7 @@ for k,v in pairs({
"art_CloseInventory",
"art_load_player_data",
"art_RequestInvMove",
+ "art_RequestInvDrop",
}) do util.AddNetworkString(v) end
--[[
net.Receive("art_ObserveInventory",function()
@@ -62,6 +63,21 @@ net.Receive("art_RequestInvMove",function(len,ply)
toinv:Put(topos,item)
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")
+ 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()
+
+end)
+
function track.ClearInventories(ply)
ply.data = {}
ply.data.inventories = {}
@@ -150,7 +166,7 @@ end
local plymeta = FindMetaTable("Player")
function plymeta:HasItem(str)
- for k,v in pairs(self.inventories) do
+ for k,v in pairs(self.data.inventories) do
local p = v:Has(str)
if type(p) == "table" then
return {k,p}
@@ -160,23 +176,52 @@ function plymeta:HasItem(str)
end
function plymeta:RemoveItem(tbl)
+ print("Got remove table, it was",tbl)
+ PrintTable(tbl)
local nid = tbl[1]
local pos = tbl[2]
- self.inventories[nid]:Remove(pos)
+ print("Self inventory was")
+ PrintTable(self.data.inventories[nid])
+ self.data.inventories[nid]:Remove(pos)
+end
+
+function plymeta:GiveItem(tbl)
+ for k,v in pairs(self.data.inventories) do
+ local p = v:FindPlaceFor(tbl)
+ if type(p) == "table" then
+ v:Put(p,tbl)
+ return
+ end
+ end
+ error("Unable to find place to put item")
+end
+
+function plymeta:GetCredits()
+ return self.data.credits
+end
+
+function plymeta:SetCredits(num)
+ print("Set credits called")
+ self.data.credits = num
+ net.Start("art_load_player_data")
+ net.WriteTable({
+ credits = num
+ })
+ net.Send(self)
end
function track.SendPlayerData(ply)
net.Start("art_load_player_data")
- net.WriteTable({})
+ net.WriteTable({
+ credits = ply.data.credits
+ })
net.Send(ply)
end
concommand.Add("SendMeData",function(ply,cmd,args)
track.ClearInventories(ply)
track.GiveInventoryTo(ply,"Equipment")
- net.Start("art_load_player_data")
- net.WriteTable({})
- net.Send(ply)
+ track.SendPlayerData(ply)
end)
concommand.Add("ShowMyInventories",function(ply,cmd,args)
@@ -188,22 +233,11 @@ concommand.Add("AddInventory",function(ply,cmd,args)
end)
concommand.Add("GiveItem",function(ply,cmd,args)
- local itmname = args[1]
- local item = itm.GetItemByName(itmname)
- local foundplacefor = false
- for k,v in pairs(ply.data.inventories) do
- print("Trying to find a place in ", v.Name)
- local pf = v:FindPlaceFor(item)
- print("It returned ", pf)
- if pf ~= nil then
- v:Put(pf,item)
- foundplacefor = true
- break
- end
- end
- if not foundplacefor then
- print("I couldn't find a place to put it!")
- end
+ xpcall(function()
+ ply:GiveItem(itm.GetItemByName(args[1]))
+ end,function()
+ print("Could not find a position to put that in!")
+ end)
end)
return track
diff --git a/gamemode/core/mapstich/cl_mapstich.lua b/gamemode/core/mapstich/cl_mapstich.lua
new file mode 100644
index 0000000..65a5208
--- /dev/null
+++ b/gamemode/core/mapstich/cl_mapstich.lua
@@ -0,0 +1,12 @@
+--[[
+ The client constantly cheks to see if we're in a serverchnage zone
+]]
+
+hook.Add("Think","artery_checklevelchange",function()
+ local z = LocalPlayer():GetCurrentZone()
+ --print("looks like i'm in zone",z)
+ if z then
+ net.Start("art_zonechange")
+ net.SendToServer()
+ end
+end)
diff --git a/gamemode/core/mapstich/sv_mapstich.lua b/gamemode/core/mapstich/sv_mapstich.lua
new file mode 100644
index 0000000..93f8667
--- /dev/null
+++ b/gamemode/core/mapstich/sv_mapstich.lua
@@ -0,0 +1,70 @@
+--Make sure zones are loaded already
+nrequire("sv_mysqlite.lua")
+local q = nrequire("core/database/sv_queries.lua")
+--if not zones then error("This thing needs zones to function!") end
+
+print("Hello from sv_mapstich.lua")
+util.AddNetworkString("art_zonechange")
+
+local dontupdatedisconnect = {}
+
+local function SavePlayerData(ply)
+ local query
+ local pdat = q.serialize_player(ply)
+ if dontupdatedisconnect[ply] then
+ dontupdatedisconnect[ply] = nil
+ query = [[
+ UPDATE playerdata SET PlayerData='%s' WHERE SteamID=%.0f
+ ]]
+ query = q.s_fmt(query,pdat,ply:SteamID64())
+ else
+ query = [[
+ UPDATE playerdata SET PlayerData='%s' MetaData='%s' WHERE SteamID=%.0f
+ ]]
+ local pmet = util.TableToJSON({
+ lastserver = game.GetIPAddress(),
+ lastlocation = ply:GetPos()
+ })
+ query = q.s_fmt(query,pdat,pmet,ply:SteamID64())
+ end
+ MySQLite.query(query,function(data)
+
+ end,function(err,sql)
+ print("Query error:")
+ print("Query",sql)
+ print("Error",err)
+ end)
+end
+
+net.Receive("art_zonechange",function(len,ply)
+
+ timer.Simple(0.5,function()
+ local zone = ply:GetCurrentZone("artery_serverchange")
+ if zone then
+ dontupdatedisconnect[ply] = true
+
+ local query = [[
+ UPDATE playerdata SET PlayerData='%s',MetaData='%s' WHERE SteamID=%.0f
+ ]]
+ local pdat = util.TableToJSON(ply.data)
+ local pmet = util.TableToJSON({
+ lastserver = zone.toserver,
+ lastlocation = zone.topos
+ })
+ print("pdat is", pdat)
+ print("pmet is", pmet)
+ local fquery = q.s_fmt(query,pdat,pmet,ply:SteamID64())
+ print("fquery was", fquery)
+ print("Running query:",qc)
+ MySQLite.query(fquery,function(data)
+ ply:ConCommand("connect " .. zone.toserver)
+ end,function(err,sql)
+ print("Query error:")
+ print("Query",sql)
+ print("Error",err)
+ end)
+
+ SavePlayerData(ply)
+ end
+ end)
+end)
diff --git a/gamemode/core/npc/cl_shop.lua b/gamemode/core/npc/cl_shop.lua
new file mode 100644
index 0000000..fa076ce
--- /dev/null
+++ b/gamemode/core/npc/cl_shop.lua
@@ -0,0 +1,141 @@
+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
+
+ local shape = itemtbl.Shape
+ local twidth,theight = 0,#shape
+ for k = 1,#shape do
+ twidth = math.max(twidth,#shape[k])
+ end
+
+ local slotsize = math.Round(w / 32)
+ local backgrid = vgui.Create( "DGrid", dp )
+ backgrid:SetPos( 10, 30 )
+ backgrid:SetCols( twidth )
+ backgrid:SetColWide( theight )
+ backgrid:Dock(LEFT)
+
+ local shopicon = vgui.Create( "DImageButton", dp )
+ shopicon:SetSize(slotsize * twidth, slotsize * theight)
+ shopicon:SetPos(0,0)
+ shopicon:SetText(itemtbl.Name)
+ if itemtbl.Tooltip then
+ shopicon:SetTooltip(itemtbl.Tooltip)
+ end
+ if itemtbl.Paint then
+ shopicon.Paint = itemtbl.Paint
+ end
+ if itemtbl.DoOnPanel then
+ itemtbl.DoOnPanel(shopicon)
+ end
+ shopicon.Paint = function(self, wi, hi)
+ surface.SetDrawColor( 0, 0, 0, 255 )
+ surface.DrawOutlinedRect( 0, 0, wi, hi)
+ end
+ shopicon.DoClick = function()
+ print("You cliked me!")
+ end
+ shopicon.Item = itemtbl
+ shopicon.Cost = cost
+ shopicon.ondropped = function(back,j,i,item)
+ print("ondropped was called!")
+ print("back",back,"j",j,"i",i,"item",item)
+ PrintTable(item)
+ net.Start("buyitem")
+ net.WriteString(item.Name)
+ net.WriteUInt(back,8)
+ net.WriteUInt(j,8)
+ net.WriteUInt(i,8)
+ net.SendToServer()
+ end
+
+ print("Displaying shape:")
+ PrintTable(shape)
+ for k = 1, twidth do
+ for i = 1, theight do
+ if not shape[k][i] then
+ print("Found false spot:",k,i)
+ local emptyslot = vgui.Create("DPanel", dp)
+ emptyslot:SetSize(slotsize,slotsize)
+ emptyslot:SetPos(slotsize * (i - 1) + 2, slotsize * (k - 1) + 2)
+ end
+ end
+ end
+
+ local buybutton = vgui.Create("DButton",dp)
+ buybutton:Dock(RIGHT)
+ buybutton:SetText("Buy\n(" .. cost .. ")")
+ buybutton.DoClick = function()
+ net.Start("art_buyitem")
+ net.WriteString(itemtbl.Name)
+ net.SendToServer()
+ end
+
+end
+
+local slotsize = math.Round(w / 32)
+
+local function DrawShopOnDPanel(dp,items)
+ --This gets pretty involved, lets try to not make it a clusterfuck.
+ dp.Paint = function(self, wi, hi) draw.RoundedBox(4, 0,0,wi,hi,Color(100,0,0)) end
+ print("dp",dp)
+ local scrollpanel = vgui.Create( "DScrollPanel",dp )
+ print("scollpanel",scrollpanel)
+ scrollpanel.Paint = function(self, wi, hi) draw.RoundedBox(4, 0,0,wi,hi,Color(0,0,100)) end
+ scrollpanel:Dock(FILL)
+ for k,v in pairs(items) do
+ local itemtbl = itm.GetItemByName(v[1])
+ local invpanel = vgui.Create( "DPanel", scollpanel)
+ invpanel.Paint = function(self, wi, hi)
+ draw.RoundedBox(4, 1,1,wi-4,hi-4,Color(50,50,50))
+ draw.RoundedBox(4, 2,2,wi-5,hi-5,Color(100,100,100))
+ end
+ print("invpanel",invpanel)
+ DrawShopItemOnDPanel(invpanel,itemtbl,v[2])
+ scrollpanel:AddItem(invpanel)
+ invpanel:Dock(TOP)
+ local x,_ = invpanel:GetSize()
+ print("item is",v)
+ PrintTable(v)
+ invpanel:SetSize(x,slotsize * (#itemtbl.Shape) + 4)
+ invpanel:Dock(TOP)
+
+ end
+
+end
+
+local shopwindow,shoppanel
+
+local function createshopwindow()
+ print("Createing shopwindow")
+ shopwindow = vgui.Create( "DFrame" )
+ shopwindow:SetPos( w - (w / 4), 0 )
+ shopwindow:SetSize( w / 4, h )
+ shopwindow:SetTitle( "Unset shop" )
+ shopwindow:SetDraggable( true )
+ shopwindow.OnClose = function(self)
+ self:SetVisible(false)
+ print("After onclose, shopwindow was",shopwindow)
+ end
+ shopwindow:SetVisible(false)
+
+ shoppanel = vgui.Create( "DPanel",shopwindow)
+ shoppanel:SetPos( 10, 30 ) -- Set the position of the panel
+ shoppanel:Dock(FILL)
+end
+createshopwindow()
+
+net.Receive("art_openshop",function()
+ print("shopwindows was ",shopwindow)
+ if not shopwindow:IsValid() then createshopwindow() end
+ assert(shopwindow,"Shopwindow was not created, even after re-createing!")
+ print("inv was", inv)
+ inv.ShowInventory()
+ shopwindow:SetVisible(true)
+ local stock = net.ReadTable()
+ DrawShopOnDPanel(shoppanel,stock)
+ shopwindow:MakePopup()
+end)
diff --git a/gamemode/core/npc/sv_shop.lua b/gamemode/core/npc/sv_shop.lua
index 2e54f7e..2825996 100644
--- a/gamemode/core/npc/sv_shop.lua
+++ b/gamemode/core/npc/sv_shop.lua
@@ -2,8 +2,28 @@
Create a shop npc
]]
+local itm = nrequire("core/inventory/item.lua")
+
local shop = {}
+for k,v in pairs({
+ "art_openshop",
+ "art_buyitem",
+ "art_sellitem",
+}) do
+ util.AddNetworkString(v)
+end
+
+function shop.OpenShop(tbl, ply)
+ print("Called openshop!")
+ print("tbl was")
+ PrintTable(tbl)
+ if CLIENT then return end
+ net.Start("art_openshop")
+ net.WriteTable(tbl)
+ net.Send(ply)
+end
+
function shop.CreateShop(npc)
print("Createing shop npc")
local npcent = ents.Create("npc_shop")
@@ -14,4 +34,42 @@ function shop.CreateShop(npc)
print("Called spawn")
end
+net.Receive("art_buyitem",function(len,ply)
+ local itemname = net.ReadString()
+
+ --Find the shop near the player
+ local es = ents.FindInSphere(ply:GetPos(),500)
+ local shop
+ for k,v in pairs(es) do
+ if IsValid(v) and v:GetClass() == "npc_shop" then
+ shop = v
+ break
+ end
+ end
+ print("Shop was", shop)
+ print("Items:", shop.shopitems)
+ PrintTable(shop.shopitems)
+
+ --Find the price of the item we want to buy
+ local price
+ for k,v in pairs(shop.shopitems) do
+ if v[1] == itemname then
+ price = v[2]
+ break
+ end
+ end
+
+ --Make sure we have enough credits to buy it
+ if ply:GetCredits() < price then
+ print(ply, " didn't have enough credits to buy a ", itemname, "(" .. price .. ")")
+ else
+ xpcall(function()
+ ply:GiveItem(itm.GetItemByName(itemname))
+ ply:SetCredits(ply:GetCredits() - price)
+ end,function(err)
+ print("Coulden't fit a " , itemname, " into ", ply, "'s inventory: ", err)
+ end)
+ end
+end)
+
return shop
diff --git a/gamemode/core/pac/sv_pac.lua b/gamemode/core/pac/sv_pac.lua
index 5a82607..3c5c6be 100644
--- a/gamemode/core/pac/sv_pac.lua
+++ b/gamemode/core/pac/sv_pac.lua
@@ -64,6 +64,7 @@ loadhashes()
local appliedpacs = {}
function p3.ApplyPac(what, name)
+ print("Applying pac", what, "to",name)
appliedpacs[what] = appliedpacs[what] or {}
appliedpacs[what][name] = pachashes[name]
net.Start("artery_applypac")
@@ -74,6 +75,7 @@ function p3.ApplyPac(what, name)
end
function p3.RemovePac(what, name)
+ print("Removeing pac",what,"from",name)
assert(appliedpacs[what][name],"Attempted to remove a pac that an entity is not wearing!")
appliedpacs[what][name] = nil
if #appliedpacs[what] == 0 then