diff options
| author | Alexander Pickering <alexandermpickering@gmail.com> | 2017-04-02 20:05:56 -0400 |
|---|---|---|
| committer | Alexander Pickering <alexandermpickering@gmail.com> | 2017-04-02 20:05:56 -0400 |
| commit | 191ba416c8b611ea4901cead138789a357c56134 (patch) | |
| tree | b30ae3473c16028a14d3ed0c80633f360cc1c914 /gamemode/core | |
| parent | a22cbeddc5f8fb61e87a30aa14ba354de5cf4431 (diff) | |
| download | artery-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.lua | 3 | ||||
| -rw-r--r-- | gamemode/core/database/sv_queries.lua | 51 | ||||
| -rw-r--r-- | gamemode/core/database/sv_setup.lua | 67 | ||||
| -rw-r--r-- | gamemode/core/inventory/common/items.lua | 31 | ||||
| -rw-r--r-- | gamemode/core/inventory/common/weapons.lua | 126 | ||||
| -rw-r--r-- | gamemode/core/inventory/inventory.lua | 33 | ||||
| -rw-r--r-- | gamemode/core/inventory/item.lua | 8 | ||||
| -rw-r--r-- | gamemode/core/inventory/sv_invtracker.lua | 78 | ||||
| -rw-r--r-- | gamemode/core/mapstich/cl_mapstich.lua | 12 | ||||
| -rw-r--r-- | gamemode/core/mapstich/sv_mapstich.lua | 70 | ||||
| -rw-r--r-- | gamemode/core/npc/cl_shop.lua | 141 | ||||
| -rw-r--r-- | gamemode/core/npc/sv_shop.lua | 58 | ||||
| -rw-r--r-- | gamemode/core/pac/sv_pac.lua | 2 |
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 |
