aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--entities/entities/art_chest/init.lua122
-rw-r--r--entities/entities/npc_shop/init.lua20
-rw-r--r--entities/entities/npc_townie/init.lua174
-rw-r--r--entities/entities/npc_townie/shared.lua82
-rw-r--r--entities/weapons/hands.lua101
-rw-r--r--gamemode/client/cl_inventory.lua21
-rw-r--r--gamemode/client/cl_state.lua9
-rw-r--r--gamemode/client/hud/cl_healthbar.lua197
-rw-r--r--gamemode/client/qtabs/cl_qinventory.lua51
-rw-r--r--gamemode/config/sv_newplayer.lua23
-rw-r--r--gamemode/config/sv_sql.lua26
-rw-r--r--gamemode/core/database/sv_mysqlite.lua387
-rw-r--r--gamemode/core/database/sv_setup.lua160
-rw-r--r--gamemode/core/inventory/inventory.lua30
-rw-r--r--gamemode/core/inventory/item.lua5
-rw-r--r--gamemode/core/inventory/sv_invtracker.lua84
-rw-r--r--gamemode/core/npc/sv_npcsystem.lua93
-rw-r--r--gamemode/core/npc/sv_shop.lua17
-rw-r--r--gamemode/core/pac/cl_pac.lua90
-rw-r--r--gamemode/core/pac/sv_pac.lua167
-rw-r--r--gamemode/inventorysystem/cl_common.lua17
-rw-r--r--gamemode/inventorysystem/equipment/cl_equipment.lua26
-rw-r--r--gamemode/inventorysystem/equipment/sh_equipment.lua5
-rw-r--r--gamemode/inventorysystem/shapedinventory/cl_shaped.lua11
-rw-r--r--gamemode/inventorysystem/shapedinventory/sh_shaped.lua2
-rw-r--r--gamemode/itemsystem/armor/balaclava.lua2
-rw-r--r--gamemode/itemsystem/exampleitem.lua2
-rw-r--r--gamemode/itemsystem/weapons/rustyaxe.lua20
-rw-r--r--gamemode/nrequire.lua30
-rw-r--r--gamemode/server/sv_database.lua2
-rw-r--r--gamemode/server/sv_loadplayer.lua4
-rw-r--r--gamemode/server/sv_mapconfig.lua2
-rw-r--r--gamemode/shared/sh_pac.lua137
-rw-r--r--gamemode/utility/svg/cl_svg.lua8
34 files changed, 1539 insertions, 588 deletions
diff --git a/entities/entities/art_chest/init.lua b/entities/entities/art_chest/init.lua
index cd39eab..f33b57a 100644
--- a/entities/entities/art_chest/init.lua
+++ b/entities/entities/art_chest/init.lua
@@ -1,88 +1,62 @@
-AddCSLuaFile( "cl_init.lua" )
-AddCSLuaFile( "shared.lua" )
-
+AddCSLuaFile("cl_init.lua")
+AddCSLuaFile("shared.lua")
include("shared.lua")
-local invfuncs = include("../../../gamemode/shared/inventory_common.lua")
+local inv = nrequire("inventory/inventory.lua")
+local track = nrequire("inventory/sv_invtracker.lua")
+--local invfuncs = include("../../../gamemode/shared/inventory_common.lua")
function ENT:Initialize()
- self.Openedby = {}
- self:SetModel("models/props_junk/Rock001a.mdl")
- self:PhysicsInit( SOLID_VPHYSICS )
- self:SetMoveType( MOVETYPE_NONE )
- self:SetSolid( SOLID_VPHYSICS )
- self:SetCollisionGroup( COLLISION_GROUP_INTERACTIVE )
- self:SetUseType(SIMPLE_USE)
-
- local phys = self:GetPhysicsObject()
- self.Inventory = {}
- self.Inventory.Backpacks = {}
- self.Inventory.Backpacks[1] = invfuncs.CreateBackpack("Chest",3,3)
-
- phys:EnableMotion(false)
- phys:Sleep()
-
- self.StoredItems = {}
+ self.Openedby = {}
+ self:SetModel("models/props_junk/Rock001a.mdl")
+ self:PhysicsInit(SOLID_VPHYSICS)
+ self:SetMoveType(MOVETYPE_NONE)
+ self:SetSolid(SOLID_VPHYSICS)
+ self:SetCollisionGroup(COLLISION_GROUP_INTERACTIVE)
+ self:SetUseType(SIMPLE_USE)
+ local phys = self:GetPhysicsObject()
+ phys:EnableMotion(false)
+ phys:Sleep()
+
+ self.data = {
+ inventories = {}
+ }
+
+ local myinv = inv.CreateInventory("Shaped Inventory")
+ myinv.Owner = self
+
+ timer.Simple(0, function()
+ print("Chest has creation id", self:GetCreationID())
+ myinv.id = self:GetCreationID()
+ self.data.inventories[myinv.id] = myinv
+ end) --Wait until the entity is initalized
+
+ self.Observers = {}
end
-local uans = {
- "openchestinv",
- "closechestinv",
- "requestchestinv",
- "requestchestname",
- "informchestname",
-}
-for k,v in pairs(uans) do
- util.AddNetworkString(v)
-end
+local uans = {"openchestinv", "closechestinv"}
-net.Receive("requestchestname",function(ln,ply)
- local e = net.ReadEntity()
- local s = e:GetName()
- net.Start("informchestname")
- net.WriteEntity(e)
- net.WriteString(s)
- net.Send(ply)
-end)
-
-net.Receive("requestchestinv",function(ln,ply)
- print("Received request for chest")
- local chest = net.ReadEntity()
- print("Chest:",chest)
- chest:SendInventory(ply)
-end)
+for k, v in pairs(uans) do
+ util.AddNetworkString(v)
+end
-net.Receive("closechestinv",function(ln,ply)
- local chest = net.ReadEntity()
- print("closeing chest of ", ply,chest)
- chest.Openedby[ply] = nil
+net.Receive("closechestinv", function(ln, ply)
+ local chest = net.ReadEntity()
+ print("closeing chest of ", ply, chest)
+ local obsid = chest.Observers[ply]
+ chest.data.inventories[chest:GetCreationID()]:RemoveObserver(obsid)
+ chest.Observers[ply] = nil
end)
+--NOTE:Why is it important to allow a table to this argument?
function ENT:SendInventory(towho)
- print("Sending inventory to",towho,type(towho))
- if type(towho) == "table" then
- print("who:")
- PrintTable(towho)
- print("opendby:")
- PrintTable(self.Openedby)
- assert(#towho != 0,"Sending inventory to no players!")
- else
- print("towho is not a table!")
- self.Openedby[towho] = true
- end
- print("about to start net message")
- net.Start("openchestinv")
- net.WriteEntity(self)
- invfuncs.SerializeBackpack(self.Inventory.Backpacks[1])
- net.Send(towho)
-end
-
-function ENT:SynchronizeInventory()
- print("Entity synchronize called")
- self:SendInventory(table.GetKeys(self.Openedby))
+ print("Sending inventory to ", towho)
+ local observer = track.MakeInventoryObserver(towho, self:GetCreationID())
+ local obsid = self.data.inventories[self:GetCreationID()]:AddObserver(observer)
+ self.Observers[towho] = obsid
+ track.NotifyPlayerOfInventory(towho, self.data.inventories[self:GetCreationID()])
end
function ENT:Use(ply)
- print("Ply opened:",ply)
- self.Openedby[ply] = true
- self:SendInventory(ply)
+ print("Ply opened:", ply)
+ self:SendInventory(ply)
end
diff --git a/entities/entities/npc_shop/init.lua b/entities/entities/npc_shop/init.lua
index a6d49d3..796b389 100644
--- a/entities/entities/npc_shop/init.lua
+++ b/entities/entities/npc_shop/init.lua
@@ -3,8 +3,12 @@ AddCSLuaFile( "shared.lua" )
include("shared.lua")
-function CreateRandomLoot(time)
-
+for k,v in pairs({
+ "art_openshop",
+ "art_buyitem",
+ "art_sellitem",
+}) do
+ util.AddNetworkString(v)
end
function ENT:Initialize()
@@ -35,7 +39,17 @@ function ENT:Initialize()
self:SetUseType( SIMPLE_USE )
end
+function 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 ENT:Use(ply)
--TODO:Fix shop
- ART.OpenShop(self.shopitems,ply)
+ OpenShop(self.shopitems,ply)
end
diff --git a/entities/entities/npc_townie/init.lua b/entities/entities/npc_townie/init.lua
index a444348..a110699 100644
--- a/entities/entities/npc_townie/init.lua
+++ b/entities/entities/npc_townie/init.lua
@@ -2,79 +2,147 @@
AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )
-include('shared.lua')
+include("shared.lua")
+
+util.AddNetworkString( "opennpcdialog" )
+util.AddNetworkString( "closenpcdialog" )
+util.AddNetworkString( "updatenpcdialog")
function ENT:Initialize()
- --print("NPC spawned!")
- --self:SetMoveType(MOVETYPE_VPHYSICS)
- self:SetSolid(SOLID_BBOX )
- self:SetCollisionGroup(COLLISION_GROUP_NPC )
+ --print("NPC spawned!")
+ --self:SetMoveType(MOVETYPE_VPHYSICS)
+ self:SetSolid(SOLID_BBOX )
+ self:SetCollisionGroup(COLLISION_GROUP_NPC )
self:SetHealth(50)
- self.loco:SetDeathDropHeight(500) //default 200
- self.loco:SetAcceleration(400) //default 400
- self.loco:SetDeceleration(400) //default 400
- self.loco:SetStepHeight(18) //default 18
- self.loco:SetJumpHeight(25) //default 58
- self.loco:SetDesiredSpeed( 50 )
+ self.loco:SetDeathDropHeight(500) --default 200
+ self.loco:SetAcceleration(400) --default 400
+ self.loco:SetDeceleration(400) --default 400
+ self.loco:SetStepHeight(18) --default 18
+ self.loco:SetJumpHeight(25) --default 58
+ self.loco:SetDesiredSpeed( 50 )
- self.nodereached = false
+ self.nodereached = false
- self.lastdooropen = CurTime()
+ self.lastdooropen = CurTime()
- if(self.Model) then self:SetModel(self.Model)
- else print("NPC created without model, this might be a bug!") end
+ if self.Model then self:SetModel(self.Model)
+ else print("NPC created without model, this might be a bug!") end
- if self.Pos then self:SetPos(self.Pos)
- else print("NPC created without a position, this might be a bug!") end
+ if self.Pos then self:SetPos(self.Pos)
+ else print("NPC created without a position, this might be a bug!") end
- self.talking = false
+ self.talking = false
- if self.Name then self:SetName(self.Name)
- else print("NPC created without a name! They won't be able to open doors!") end
+ if self.Name then self:SetName(self.Name)
+ else print("NPC created without a name! They won't be able to open doors!") end
- if self.OnSpawn then self.OnSpawn(self) end
+ if self.OnSpawn then self.OnSpawn(self) end
- self.allowedNodes = {}
+ self.allowedNodes = {}
- for k,v in pairs(ents.FindByClass( "info_townienode" ) ) do
- if self.NavNodes[v.Name] then
- table.insert(self.allowedNodes,v)
- end
- end
+ for k,v in pairs(ents.FindByClass( "info_townienode" ) ) do
+ if self.NavNodes[v.Name] then
+ table.insert(self.allowedNodes,v)
+ end
+ end
- self:SetUseType( SIMPLE_USE )
+ self:SetUseType( SIMPLE_USE )
- self.DialogCursors = {}
+ self.DialogCursors = {}
end
function ENT:OnInjured(dmg)
- --print("Taking some dammage")
- local itempos = self:GetPos()
- --print("Takeing " .. dmg:GetDamage() .. " health from our " .. self:Health())
- --self:SetHealth(self:Health() - dmg:GetDamage())
- --print("Health is now" .. self:Health())
- if self.OnDammage != nil then self:OnDammage(dmg) end
+ if self.OnDammage ~= nil then self:OnDammage(dmg) end
+end
+
+local removeblock = {
+ ["prop_door_rotating"] = function(bot,ent)
+ ent:Fire("OpenAwayFrom",bot:GetName())
+ timer.Simple(3,function()
+ ent:Fire("Close")
+ end)
+ end
+}
+
+function ENT:BehaveUpdate(num)
+ if not self.BehaveThread then return end
+ if self.curnode and self.curnode:IsValid() then
+ if self.curnode:GetPos():Distance(self:GetPos()) < 5 then
+ if self.nodereached == false then
+ self.curnode.OnReached(self)
+ self.nodereached = true
+ else
+ if self.curnode.IsDone(self) then
+ print("Finished action")
+ self.curnode = self:selectNewNode()
+ self.nodereached = false
+ end
+ end
+ end
+ end
+ local trdata = {
+ ["start"] = self:GetPos() + (self:GetUp() * 72),
+ ["endpos"] = self:GetPos() + (self:GetUp() * 72) + (self:GetForward() * 32),
+ ["filter"] = self
+ }
+ local tr = util.TraceLine(trdata)
+ local ecl
+ --print("tr",tr,"tr.entity",tr.Entity)
+ if (tr ~= nil) and (tr.Entity ~= nil) and tr.Entity:IsValid() then
+ --print("Not returning")
+ ecl = tr.Entity:GetClass()
+ end
+ if tr.Hit and removeblock[ecl] ~= nil then
+ removeblock[ecl](self,tr.Entity)
+ end
+ local ok, message = coroutine.resume( self.BehaveThread )
+ if not ok then
+ self.BehaveThread = nil
+ Msg( self, "error: ", message, "\n" );
+ end
+
end
function ENT:OnKilled(dmg)
- if(CLIENT) then return end
- if not self.Drops then return end
- --print("Looks like we have some drops")
- for k,v in pairs(self.Drops) do
- local rng = math.random(0,100)
- local itemname = self.Drops[k][1]
- local itemchance = self.Drops[k][2]
- local heightoffset = 10
- if rng < itemchance then
- local drop = ents.Create("ws_item")
- drop.Item = GetItemByName(itemname)
- drop:SetModel(drop.Item.Model)
- drop:SetPos(self:GetPos() + (self:GetUp()*heightoffset))
- drop:Spawn()
- heightoffset = heightoffset + 10
- end
- end
- self:BecomeRagdoll( dmg )
+ if not self.Drops then return end
+ --print("Looks like we have some drops")
+ for k,v in pairs(self.Drops) do
+ local rng = math.random(0,100)
+ local itemname = self.Drops[k][1]
+ local itemchance = self.Drops[k][2]
+ local heightoffset = 10
+ if rng < itemchance then
+ local drop = ents.Create("ws_item")
+ drop.Item = GetItemByName(itemname)
+ drop:SetModel(drop.Item.Model)
+ drop:SetPos(self:GetPos() + (self:GetUp() * heightoffset))
+ drop:Spawn()
+ heightoffset = heightoffset + 10
+ end
+ end
+ self:BecomeRagdoll( dmg )
+end
+
+function ENT:Use(ply)
+ self.DialogCursors[ply] = self.getDialogFor(ply)
+ --
+ if self.oyaw ~= 0 and self.oacc ~= 0 then
+ self.oyaw, self.oacc,self.onod = self.loco:GetMaxYawRate(), self.loco:GetAcceleration(), self.curnode
+ end
+ self.loco:SetAcceleration(0)
+ self.loco:SetVelocity(Vector(0,0,0))
+ self.loco:SetMaxYawRate(9999990)
+ self.loco:FaceTowards(ply:GetPos())
+ self.loco:SetMaxYawRate(0)
+ timer.Simple(0.5,function()
+ --self.loco:FaceTowards(ply:GetPos())
+
+
+ end)
+ net.Start("opennpcdialog")
+ net.WriteEntity(self)
+ net.WriteTable(SendableDialog(self.DialogCursors[ply]))
+ net.Send(ply)
end
diff --git a/entities/entities/npc_townie/shared.lua b/entities/entities/npc_townie/shared.lua
index e7f02c7..bb07b51 100644
--- a/entities/entities/npc_townie/shared.lua
+++ b/entities/entities/npc_townie/shared.lua
@@ -27,62 +27,18 @@ function ENT:selectNewNode()
return rnode
end
-local removeblock = {
- ["prop_door_rotating"] = function(bot,ent)
- ent:Fire("OpenAwayFrom",bot:GetName())
- timer.Simple(3,function()
- ent:Fire("Close")
- end)
- end
-}
-
-function ENT:BehaveUpdate(num)
- if not self.BehaveThread then return end
- if self.curnode and self.curnode:IsValid() then
- if self.curnode:GetPos():Distance(self:GetPos()) < 5 then
- if self.nodereached == false then
- self.curnode.OnReached(self)
- self.nodereached = true
- else
- if self.curnode.IsDone(self) then
- print("Finished action")
- self.curnode = self:selectNewNode()
- self.nodereached = false
- end
- end
- end
- end
- local trdata = {
- ["start"] = self:GetPos() + (self:GetUp()*72),
- ["endpos"] = self:GetPos() + (self:GetUp()*72) + (self:GetForward()*32),
- ["filter"] = self
- }
- local tr = util.TraceLine(trdata)
- local ecl
- --print("tr",tr,"tr.entity",tr.Entity)
- if (tr ~= nil) and (tr.Entity ~= nil) and tr.Entity:IsValid() then
- --print("Not returning")
- ecl = tr.Entity:GetClass()
- end
- if tr.Hit and removeblock[ecl] ~= nil then
- removeblock[ecl](self,tr.Entity)
- end
- local ok, message = coroutine.resume( self.BehaveThread )
- if not ok then
- self.BehaveThread = nil
- Msg( self, "error: ", message, "\n" );
- end
-end
+
+
function ENT:RunBehaviour()
while true do
--print("In runbehaviour")
- local opts = { lookahead = 300,
+ local opts = { lookahead = 50,
tolerance = 20,
- draw = true,
+ draw = false,
maxage = 1,
- repath = 0.1 }
+ repath = 10 }
if self.curnode == nil or not self.curnode:IsValid() or self.curnode:GetPos():Distance(self:GetPos()) < 5 then
self.curnode = self:selectNewNode()
end
@@ -101,11 +57,7 @@ function ENT:RunBehaviour()
end
end
-if SERVER then
- util.AddNetworkString( "opennpcdialog" )
- util.AddNetworkString( "closenpcdialog" )
- util.AddNetworkString( "updatenpcdialog")
-end
+
--Fix the dialog so we aren't sending functions
function SendableDialog(tbl)
@@ -137,28 +89,6 @@ net.Receive("updatenpcdialog",function(len,ply)
net.Send(ply)
end)
-function ENT:Use(ply)
- self.DialogCursors[ply] = self.getDialogFor(ply)
- --
- if self.oyaw ~= 0 and self.oacc ~= 0 then
- self.oyaw, self.oacc,self.onod = self.loco:GetMaxYawRate(), self.loco:GetAcceleration(), self.curnode
- end
- self.loco:SetAcceleration(0)
- self.loco:SetVelocity(Vector(0,0,0))
- self.loco:SetMaxYawRate(9999990)
- self.loco:FaceTowards(ply:GetPos())
- self.loco:SetMaxYawRate(0)
- timer.Simple(0.5,function()
- --self.loco:FaceTowards(ply:GetPos())
-
-
- end)
- net.Start("opennpcdialog")
- net.WriteEntity(self)
- net.WriteTable(SendableDialog(self.DialogCursors[ply]))
- net.Send(ply)
-end
-
function ENT:OnClose()
self.loco:SetMaxYawRate(self.oyaw)
self.loco:SetAcceleration(self.oacc)
diff --git a/entities/weapons/hands.lua b/entities/weapons/hands.lua
index d55c416..1354941 100644
--- a/entities/weapons/hands.lua
+++ b/entities/weapons/hands.lua
@@ -36,81 +36,38 @@ function SWEP:ShouldDropOnDie()
return false
end
-local Box = Vector(8,8,8)
-
function SWEP:PrimaryAttack()
- if not self.Owner.Inventory then return end
- local rightitem = self.Owner.Inventory.Equiped["Left"]
- if rightitem ~= false and rightitem.onClick ~= nil then
- rightitem:onClick(self.Owner)
- end
- --[[
- if (CLIENT and !IsFirstTimePredicted()) then return end
- if (!self.Owner.Weapons or !self.Owner.Weapons[self.Owner.Select]) then return end
- if (self.Owner.CD and self.Owner.CD > CurTime()) then return end
-
- local item = self.Owner.Weapons[self.Owner.Select].Item
-
- if (!item or !item.OnPrimary) then return end
-
- self.Owner:SetAnimation( PLAYER_ATTACK1 )
-
- local Trace = {
- start = self.Owner:GetShootPos(),
- endpos = self.Owner:GetShootPos()+self.Owner:GetAimVector()*item.Range,
- filter = self.Owner,
- mins = Box*-1,
- maxs = Box,
- }
-
- local Tr = util.TraceHull(Trace)
-
- item:OnPrimary(self.Owner,Tr)
-
- self.Owner.CD = CurTime()+item.CD
- ]]
+ if CLIENT then return end
+
+ --Make sure we have an equipment inventory
+ if not self.Owner then return end
+ if not self.Owner.data then return end
+ if not self.Owner.data.inventories then return end
+ if not self.Owner.data.inventories[1] then return end
+ local eqpd = self.Owner.data.inventories[1]
+
+ --Get the weapon we want to fire, and fire it!
+ local weapon = eqpd:Get({"Left Hand"}) or eqpd:Get({"Dual"})
+ if not weapon then return end --Make sure we have a weapon
+ if weapon.onClick ~= nil then
+ weapon:onClick(self.Owner)
+ end
end
function SWEP:SecondaryAttack()
- local rightitem = self.Owner.Inventory.Equiped["Right"]
- if rightitem ~= false and rightitem.onClick ~= nil then
- rightitem:onClick(self.Owner)
- end
-end
-
-if (CLIENT) then
- local Zero = Vector(1,1,1)
- --[[
- function SWEP:DrawWorldModel()
- if (!self.Owner.Weapons or !self.Owner.Weapons[self.Owner.Select]) then return end
-
- local item = self.Owner.Weapons[self.Owner.Select].Item
-
- for k,v in pairs(item.Structure) do
- local ID = self.Owner:LookupBone(v.Bone)
- local Pos,Ang = self.Owner:GetBonePosition(ID)
-
- local Offset = v.Pos*1
- Offset:Rotate(Ang)
- Pos = Pos + Offset
-
- local Dang = Ang*1
-
- Ang:RotateAroundAxis(Dang:Right(),v.Ang.p)
- Ang:RotateAroundAxis(Dang:Up(),v.Ang.y)
- Ang:RotateAroundAxis(Dang:Forward(),v.Ang.r)
-
- self.MOB:SetModel(v.Model)
- self.MOB:SetRenderOrigin(Pos)
- self.MOB:SetRenderAngles(Ang)
-
- local mat = Matrix()
- mat:Scale( v.Size or Zero )
-
- self.MOB:EnableMatrix( "RenderMultiply", mat )
- self.MOB:SetupBones()
- self.MOB:DrawModel()
- end
+ if CLIENT then return end
+
+ --Make sure we have an equipment inventory
+ if not self.Owner then return end
+ if not self.Owner.data then return end
+ if not self.Owner.data.inventories then return end
+ if not self.Owner.data.inventories[1] then return end
+ local eqpd = self.Owner.data.inventories[1]
+
+ --Get the weapon we want to fire, and fire it!
+ local weapon = eqpd:Get({"Right Hand"}) or eqpd:Get({"Dual"})
+ if not weapon then return end --Make sure we have a weapon
+ if weapon.onClick ~= nil then
+ weapon:onClick(self.Owner)
end
- ]]
end
diff --git a/gamemode/client/cl_inventory.lua b/gamemode/client/cl_inventory.lua
index 0e14d50..b1f5728 100644
--- a/gamemode/client/cl_inventory.lua
+++ b/gamemode/client/cl_inventory.lua
@@ -9,6 +9,7 @@
4 - Quests
]]
local qinv = nrequire("cl_qinventory.lua")
+local state = nrequire("cl_state.lua") --Holds weather or not player is in inventory
--local qpray = nrequire("cl_qprayers.lua")
print("Hello from cl_inventory.lua")
@@ -25,9 +26,6 @@ end)
local lastpanel = lastpanel or 1
---Wether the player is in the inventory or not
-local plyisininventory = false
-
local qframe = nil --The master frame
local qtabs = {} --The tabs
@@ -53,7 +51,12 @@ local function BuildInventory()
qframe:SetDraggable(true)
qframe:MakePopup()
qframe.OnClose = function(self)
- plyisininventory = false
+ state.invopen = false
+ self:Hide()
+ return
+ end
+ qframe.Remove = function(self)
+ state.invopen = false
self:Hide()
return
end
@@ -75,14 +78,14 @@ local function ShowInventory()
print("qframe is ", qframe)
if not qframe then BuildInventory()
else qframe:Show() end
- plyisininventory = true
+ state.invopen = true
end
hook.Add("OnSpawnMenuOpen","ArteryOpenInventory",ShowInventory)
hook.Add("OnSpawnMenuClose","ArteryCloseInventory",function()
- plyisininventory = false
+ state.invopen = false
qframe:Hide()
if (not sheet) or (not sheet:GetActiveTab()) or (not sheet:GetActiveTab():GetPanel()) then return end
lastpanel = sheet:GetActiveTab():GetPanel().sheetnum
@@ -106,7 +109,7 @@ hook.Add("CalcView","ArteryInventoryView",function(ply,pos,ang,fov,nearz,farz)
local view = {}
--view.origin = LocalPlayer():GetBonePosition(bone) + LocalPlayer():GetUp() * 2
view.origin = pos
- if plyisininventory then
+ if state.invopen then
local trot = math.rad(CurTime() * rotatespeed)
local xoff = viewdistance * math.sin(trot)
local yoff = viewdistance * math.cos(trot)
@@ -116,12 +119,12 @@ hook.Add("CalcView","ArteryInventoryView",function(ply,pos,ang,fov,nearz,farz)
end
view.angles = ang
view.fov = fov
- if not plyisininventory then
+ if not state.invopen then
LocalPlayer():ManipulateBoneScale(bone,Vector(0,0,0))
else
LocalPlayer():ManipulateBoneScale(bone,previousheadscale)
end
- view.drawviewer = plyisininventory
+ view.drawviewer = state.invopen
return view
end)
diff --git a/gamemode/client/cl_state.lua b/gamemode/client/cl_state.lua
new file mode 100644
index 0000000..f5677e9
--- /dev/null
+++ b/gamemode/client/cl_state.lua
@@ -0,0 +1,9 @@
+--[[
+ Holds some information about client state, this is in a seperate file so I don't have circular dependancies.
+]]
+
+local state = {}
+
+state.invopen = false
+
+return state
diff --git a/gamemode/client/hud/cl_healthbar.lua b/gamemode/client/hud/cl_healthbar.lua
index 67a3090..5655b1c 100644
--- a/gamemode/client/hud/cl_healthbar.lua
+++ b/gamemode/client/hud/cl_healthbar.lua
@@ -1,50 +1,63 @@
-
-hook.Add( "HUDShouldDraw", "HideHUD", function( name )
+hook.Add("HUDShouldDraw", "HideHUD", function(name)
if name == "CHudHealth" then return false end
-end )
+end)
+--[[
--A function that rotates a point around another point
-local function rotatepoint(x,y,cx,cy,rot)
+local function rotatepoint(x, y, cx, cy, rot)
rot = math.rad(rot)
- local cs,sn = math.cos(rot),math.sin(rot)
- local px = x * cs - y * sn;
- local py = x * sn + y * cs;
- return px,py
+ local cs, sn = math.cos(rot), math.sin(rot)
+ local px = x * cs - y * sn
+ local py = x * sn + y * cs
+
+ return px, py
end
+]]
--Add a function to the draw library to draw elipses for blood
local segments = 20
local fade = 0.5
-function draw.DrawElipse(x,y,radius,elong,rotation)
+
+function draw.DrawElipse(x, y, radius, elong, rotation)
rotation = math.rad(rotation)
local cir = {}
- table.insert( cir, { x = x, y = y, u = fade, v = fade } )
+
+ table.insert(cir, {
+ x = x,
+ y = y,
+ u = fade,
+ v = fade
+ })
+
for i = 0, segments do
- local a = math.rad( ( i / segments ) * -360 )
- local xu,yu = math.sin(a),math.cos(a)
+ local a = math.rad((i / segments) * -360)
+ local xu, yu = math.sin(a), math.cos(a)
local xpos = xu * radius * elong
local ypos = yu * radius
- local cs,sn = math.cos(rotation),math.sin(rotation)
- xpos,ypos = xpos * cs - ypos * sn, xpos * sn + ypos * cs
- table.insert( cir, {
+ local cs, sn = math.cos(rotation), math.sin(rotation)
+ xpos, ypos = xpos * cs - ypos * sn, xpos * sn + ypos * cs
+
+ table.insert(cir, {
x = x + xpos,
y = y + ypos,
u = 1,
- v = 1 } )
+ v = 1
+ })
end
- surface.DrawPoly( cir )
+
+ surface.DrawPoly(cir)
end
-local width,height = ScrW(),ScrH()
+local width, height = ScrW(), ScrH()
local padding = height / 32
local barheight = height / 16
local bubbles = {}
local blobs = {}
-local lastpos = 0
-local bubbleradius = height/64
+local bubbleradius = height / 64
local delpoint = height
-hook.Add( "Tick", "Hudpaintbloodtick",function()
- for k,v in pairs(blobs) do
+
+hook.Add("Tick", "Hudpaintbloodtick", function()
+ for k, v in pairs(blobs) do
if v.y > delpoint then
blobs[k] = nil
else
@@ -52,102 +65,114 @@ hook.Add( "Tick", "Hudpaintbloodtick",function()
["x"] = v.x + v.xv,
["y"] = v.y + v.yv,
["xv"] = v.xv,
- ["yv"] = v.yv + 1,
+ ["yv"] = v.yv + 1
}
end
end
- for k,v in pairs(bubbles) do
- if v.y < height - padding - barheight -bubbleradius then
- bubbles[k] = nil
- else
- local subheight = v.y - (1.5 + math.sin((v.y/4) + (v.x*10)))/5
- bubbles[k].y = subheight
- end
- end
+
+ for k, v in pairs(bubbles) do
+ if v.y < height - padding - barheight - bubbleradius then
+ bubbles[k] = nil
+ else
+ local subheight = v.y - (1.5 + math.sin((v.y / 4) + (v.x * 10))) / 5
+ bubbles[k].y = subheight
+ end
+ end
end)
local lasthealth
local obarlength = width / 4
local barlength = obarlength
-local xs,ys = padding,height - padding - barheight
-local bubblespawnrate,bubblespawnchance = 1,0.7
-
-timer.Create("Healthbar_bubble_timer",bubblespawnrate,0,function()
- if math.random() < bubblespawnchance then
- local newbubble = {
- ["x"] = math.random(xs + bubbleradius,barlength-bubbleradius),
- ["y"] = height - padding + bubbleradius
- }
- table.insert(bubbles,newbubble)
- end
-end)
+local xs, ys = padding, height - padding - barheight
+local bubblespawnrate, bubblespawnchance = 1, 0.7
+
+timer.Create("Healthbar_bubble_timer", bubblespawnrate, 0, function()
+ if math.random() < bubblespawnchance then
+ local newbubble = {
+ ["x"] = math.random(xs + bubbleradius, barlength - bubbleradius),
+ ["y"] = height - padding + bubbleradius
+ }
-hook.Add( "HUDPaint", "HUD_DrawHealth", function()
+ table.insert(bubbles, newbubble)
+ end
+end)
+hook.Add("HUDPaint", "HUD_DrawHealth", function()
--Spawn a bunch of blobs if our health has changed
local health = LocalPlayer():Health()
+
if lasthealth == nil then
lasthealth = health
end
+
if health ~= lasthealth then
local difference = lasthealth - health
- barlength = obarlength * (health/100)
- for i=0,difference*3 do
+ barlength = obarlength * (health / 100)
+
+ for i = 0, difference * 3 do
local rtime = math.random()
- timer.Simple(rtime,function()
+
+ timer.Simple(rtime, function()
local yvel = -20 + math.random(10)
- local xvel = (math.random()*5)
+ local xvel = math.random() * 5
local xpos = padding + xs + barlength - difference - 5
local ypos = ys + (math.random() * barheight)
- table.insert(blobs,{
+
+ table.insert(blobs, {
x = xpos,
y = ypos,
xv = xvel,
- yv = yvel,
+ yv = yvel
})
end)
end
+
lasthealth = health
end
+
--Draw the current health thing
- --Background
- surface.SetDrawColor(100,100,100,100)
- surface.DrawRect( xs, ys, obarlength, barheight)
- --Foreground
- surface.SetDrawColor( 150, 0, 0, 255 )
- surface.DrawRect( xs, ys, barlength, barheight )
-
- --Heighlighting/shadows
- local heighlightheight = barheight/3
- for k = 1, heighlightheight do
- local perc = Lerp(k/heighlightheight,100,0)
- surface.SetDrawColor( 150+perc, perc, perc, 255)
- surface.DrawRect( xs, ys+k, barlength, 1)
- end
- for k = 1, heighlightheight do
- local perc = Lerp(k/heighlightheight,0,100)
- surface.SetDrawColor( 150 - perc, 0, 0, 255)
- surface.DrawRect(xs, ys+k+(2*heighlightheight), barlength, 1)
- end
-
- --Draw bubbles
- render.SetScissorRect( xs, ys, xs + barlength, ys + barheight, true ) -- Enable the rect
- surface.SetDrawColor(250,150,150,10)
- for k,v in pairs(bubbles) do
- surface.DrawCircle(v.x,v.y,bubbleradius,250,150,150,30)
- draw.DrawElipse(v.x,v.y,bubbleradius,1,0)
- end
- render.SetScissorRect( 0, 0, 0, 0, false ) -- Disable after you are done
+ --Background
+ surface.SetDrawColor(100, 100, 100, 100)
+ surface.DrawRect(xs, ys, obarlength, barheight)
+ --Foreground
+ surface.SetDrawColor(150, 0, 0, 255)
+ surface.DrawRect(xs, ys, barlength, barheight)
+ --Heighlighting/shadows
+ local heighlightheight = barheight / 3
+
+ for k = 1, heighlightheight do
+ local perc = Lerp(k / heighlightheight, 100, 0)
+ surface.SetDrawColor(150 + perc, perc, perc, 255)
+ surface.DrawRect(xs, ys + k, barlength, 1)
+ end
+
+ for k = 1, heighlightheight do
+ local perc = Lerp(k / heighlightheight, 0, 100)
+ surface.SetDrawColor(150 - perc, 0, 0, 255)
+ surface.DrawRect(xs, ys + k + (2 * heighlightheight), barlength, 1)
+ end
+
+ --Draw bubbles
+ render.SetScissorRect(xs, ys, xs + barlength, ys + barheight, true) -- Enable the rect
+ surface.SetDrawColor(250, 150, 150, 10)
+ for k, v in pairs(bubbles) do
+ if k > 50 then break end
+ surface.DrawCircle(v.x, v.y, bubbleradius, 250, 150, 150, 30)
+ draw.DrawElipse(v.x, v.y, bubbleradius, 1, 0)
+ end
+
+ render.SetScissorRect(0, 0, 0, 0, false) -- Disable after you are done
--Draw the animation for blobs
- surface.SetDrawColor(150,0,0,255)
- for k,v in pairs(blobs) do
+ surface.SetDrawColor(150, 0, 0, 255)
+
+ for k, v in pairs(blobs) do
--Elongation is based on velocity
- local elong = (v.yv^2 + v.xv^2)^0.5
- elong = elong/5
- elong = math.Clamp(elong,1,3)
+ local elong = (v.yv ^ 2 + v.xv ^ 2) ^ 0.5
+ elong = elong / 5
+ elong = math.Clamp(elong, 1, 3)
--Rotation is also based on velcotiy
- local rot = math.deg(math.atan(v.yv/v.xv))
- draw.DrawElipse(v.x,v.y,10/elong,elong, rot)
+ local rot = math.deg(math.atan(v.yv / v.xv))
+ draw.DrawElipse(v.x, v.y, 10 / elong, elong, rot)
end
-end )
+end)
diff --git a/gamemode/client/qtabs/cl_qinventory.lua b/gamemode/client/qtabs/cl_qinventory.lua
index e60424f..e4dfaa8 100644
--- a/gamemode/client/qtabs/cl_qinventory.lua
+++ b/gamemode/client/qtabs/cl_qinventory.lua
@@ -3,13 +3,44 @@
]]
local inv = nrequire("inventory/inventory.lua")
local itm = nrequire("item.lua")
+--local state = nrequire("cl_state.lua")
local q = {}
local known_inventories = {}
local inventory_frames = {}
local invsheet
+
+local drawfloatinginventory = function(id, inventory)
+ print("Drawing a floating inventory!")
+ local frame = vgui.Create("DFrame")
+ frame:SetPos( 100, 100 )
+ frame:SetSize( 300, 200 )
+ frame:SetTitle( "My new Derma frame" )
+ frame:SetDraggable( true )
+ local panel = vgui.Create("DPanel",frame)
+ panel:Dock(FILL)
+ if inventory.DrawOnDPanel then
+ local prox = inventory:DrawOnDPanel(panel)
+ frame.id = known_inventories[id]:AddObserver(prox)
+ else
+ error("Inventory needs a DrawOnDPanel method!")
+ end
+ frame:MakePopup()
+ frame.OnClose = function(self)
+ print("Closeing chest id", id)
+ print("entity is", known_inventories[id].Owner)
+ known_inventories[id]:RemoveObserver(self.id)
+ net.Start("closechestinv")
+ net.WriteEntity(known_inventories[id].Owner)
+ net.SendToServer()
+ known_inventories[id] = nil
+ self:Remove()
+ end
+end
+
local drawsheeton = function(id,inventory)
+ print("Drawing an inventory on a sheet!")
if invsheet == nil then return end
local tpanel = vgui.Create( "DPanel", invsheet )
--tpanel.Paint = function( self, w, h )
@@ -34,15 +65,20 @@ net.Receive("art_ObserveInventory",function()
local datalen = net.ReadUInt(32)
local inital_data = net.ReadData(datalen)
local ownent = net.ReadEntity()
+ print("Owning ent of this inventory is", ownent)
+ assert(known_inventories[id] == nil, "Trying to observe the same inventory twice!",id)
local tinv = inv.CreateInventoryFromData(inv_type,inital_data)
- tinv.owner = ownent
+ tinv.Owner = ownent
tinv.id = id
print("Created new inventory:")
PrintTable(tinv)
known_inventories[id] = tinv
- drawsheeton(id,tinv)
- print("known inventories is now:")
- PrintTable(known_inventories)
+ if id > 10 then
+ drawfloatinginventory(id,tinv)
+ hook.Call("OnSpawnMenuOpen")
+ else
+ drawsheeton(id,tinv)
+ end
end)
net.Receive("art_UpdateInventory",function()
@@ -81,7 +117,12 @@ q.CreateInventorySheet = function(dpanel_parent)
invsheet:Dock( FILL )
for k,v in pairs(known_inventories) do
- drawsheeton(k,v)
+ print("This inventory id in known_inventories is", k)
+ if k <= 10 then
+ drawsheeton(k,v)
+ else
+ drawfloatinginventory(k,v)
+ end
--[[
local tpanel = vgui.Create( "DPanel", invsheet )
tpanel.Paint = function( self, w, h )
diff --git a/gamemode/config/sv_newplayer.lua b/gamemode/config/sv_newplayer.lua
new file mode 100644
index 0000000..9bb1420
--- /dev/null
+++ b/gamemode/config/sv_newplayer.lua
@@ -0,0 +1,23 @@
+local np = {}
+local inv = nrequire("inventory/inventory.lua")
+local itm = nrequire("inventory/item.lua")
+
+np.newdata = function()
+ return {
+ inventories = {
+ {"Equipment", inv.CreateInventory("Equipment"):Serialize()}
+ },
+ skills = {},
+ prayers = {},
+ quests = {},
+ }
+end
+
+np.newmeta = function()
+ return {
+ lastserver = "67.163.245.187:27015",
+ lastlocation = "185 310 524"
+ }
+end
+
+return np
diff --git a/gamemode/config/sv_sql.lua b/gamemode/config/sv_sql.lua
new file mode 100644
index 0000000..1c02a3c
--- /dev/null
+++ b/gamemode/config/sv_sql.lua
@@ -0,0 +1,26 @@
+local sql = {}
+
+--SQL stuff, be careful to keep this secret!
+
+local parse = {
+ ["EnableMySQL"] = tobool,
+ ["Host"] = tostring,
+ ["Username"] = tostring,
+ ["Password"] = tostring,
+ ["Database_name"] = tostring,
+ ["Database_port"] = tonumber,
+ ["Preferred_module"] = tostring,
+ [""] = function() return nil end
+}
+
+local mysqlconfig = file.Read("artery/mysql.txt")
+for _,line in pairs(string.Explode("\n",mysqlconfig,false)) do
+ local key, value = unpack(string.Explode("=",line,false))
+ assert(parse[key],string.format("SQL field unknown:%q known fields:\n\t%s",key,table.concat(table.GetKeys(parse),"\n\t")))
+ sql[key] = parse[key](value)
+end
+
+print("After parseing mysql config, it is")
+PrintTable(sql)
+
+return sql
diff --git a/gamemode/core/database/sv_mysqlite.lua b/gamemode/core/database/sv_mysqlite.lua
new file mode 100644
index 0000000..82a2830
--- /dev/null
+++ b/gamemode/core/database/sv_mysqlite.lua
@@ -0,0 +1,387 @@
+--[[
+ MySQLite - Abstraction mechanism for SQLite and MySQL
+
+ Why use this?
+ - Easy to use interface for MySQL
+ - No need to modify code when switching between SQLite and MySQL
+ - Queued queries: execute a bunch of queries in order an run the callback when all queries are done
+
+ License: LGPL V2.1 (read here: https://www.gnu.org/licenses/lgpl-2.1.html)
+
+ Supported MySQL modules:
+ - MySQLOO
+ - tmysql4
+
+ Note: When both MySQLOO and tmysql4 modules are installed, MySQLOO is used by default.
+
+ /*---------------------------------------------------------------------------
+ Documentation
+ ---------------------------------------------------------------------------*/
+
+ MySQLite.initialize([config :: table]) :: No value
+ Initialize MySQLite. Loads the config from either the config parameter OR the MySQLite_config global.
+ This loads the module (if necessary) and connects to the MySQL database (if set up).
+ The config must have this layout:
+ {
+ EnableMySQL :: Bool - set to true to use MySQL, false for SQLite
+ Host :: String - database hostname
+ Username :: String - database username
+ Password :: String - database password (keep away from clients!)
+ Database_name :: String - name of the database
+ Database_port :: Number - connection port (3306 by default)
+ Preferred_module :: String - Preferred module, case sensitive, must be either "mysqloo" or "tmysql4"
+ MultiStatements :: Bool - Only available in tmysql4: allow multiple SQL statements per query
+ }
+
+ ----------------------------- Utility functions -----------------------------
+ MySQLite.isMySQL() :: Bool
+ Returns whether MySQLite is set up to use MySQL. True for MySQL, false for SQLite.
+ Use this when the query syntax between SQLite and MySQL differs (example: AUTOINCREMENT vs AUTO_INCREMENT)
+
+ MySQLite.SQLStr(str :: String) :: String
+ Escapes the string and puts it in quotes.
+ It uses the escaping method of the module that is currently being used.
+
+ MySQLite.tableExists(tbl :: String, callback :: function, errorCallback :: function)
+ Checks whether table tbl exists.
+
+ callback format: function(res :: Bool)
+ res is a boolean indicating whether the table exists.
+
+ The errorCallback format is the same as in MySQLite.query.
+
+ ----------------------------- Running queries -----------------------------
+ MySQLite.query(sqlText :: String, callback :: function, errorCallback :: function) :: No value
+ Runs a query. Calls the callback parameter when finished, calls errorCallback when an error occurs.
+
+ callback format:
+ function(result :: table, lastInsert :: number)
+ Result is the table with results (nil when there are no results or when the result list is empty)
+ lastInsert is the row number of the last inserted value (use with AUTOINCREMENT)
+
+ Note: lastInsert is NOT supported when using SQLite.
+
+ errorCallback format:
+ function(error :: String, query :: String) :: Bool
+ error is the error given by the database module.
+ query is the query that triggered the error.
+
+ Return true to suppress the error!
+
+ MySQLite.queryValue(sqlText :: String, callback :: function, errorCallback :: function) :: No value
+ Runs a query and returns the first value it comes across.
+
+ callback format:
+ function(result :: any)
+ where the result is either a string or a number, depending on the requested database field.
+
+ The errorCallback format is the same as in MySQLite.query.
+
+ ----------------------------- Transactions -----------------------------
+ MySQLite.begin() :: No value
+ Starts a transaction. Use in combination with MySQLite.queueQuery and MySQLite.commit.
+
+ MySQLite.queueQuery(sqlText :: String, callback :: function, errorCallback :: function) :: No value
+ Queues a query in the transaction. Note: a transaction must be started with MySQLite.begin() for this to work.
+ The callback will be called when this specific query has been executed successfully.
+ The errorCallback function will be called when an error occurs in this specific query.
+
+ See MySQLite.query for the callback and errorCallback format.
+
+ MySQLite.commit(onFinished)
+ Commits a transaction and calls onFinished when EVERY queued query has finished.
+ onFinished is NOT called when an error occurs in one of the queued queries.
+
+ onFinished is called without arguments.
+
+ ----------------------------- Hooks -----------------------------
+ DatabaseInitialized
+ Called when a successful connection to the database has been made.
+]]
+
+local bit = bit
+local debug = debug
+local error = error
+local ErrorNoHalt = ErrorNoHalt
+local hook = hook
+local include = include
+local pairs = pairs
+local require = require
+local sql = sql
+local string = string
+local table = table
+local timer = timer
+local tostring = tostring
+local GAMEMODE = GM or GAMEMODE
+local mysqlOO
+local TMySQL
+local _G = _G
+
+local multistatements
+
+local MySQLite_config = MySQLite_config or RP_MySQLConfig or FPP_MySQLConfig
+local moduleLoaded
+
+local function loadMySQLModule()
+ if moduleLoaded or not MySQLite_config or not MySQLite_config.EnableMySQL then return end
+
+ local moo, tmsql = file.Exists("bin/gmsv_mysqloo_*.dll", "LUA"), file.Exists("bin/gmsv_tmysql4_*.dll", "LUA")
+
+ if not moo and not tmsql then
+ error("Could not find a suitable MySQL module. Supported modules are MySQLOO and tmysql4.")
+ end
+ moduleLoaded = true
+
+ require(moo and tmsql and MySQLite_config.Preferred_module or
+ moo and "mysqloo" or
+ "tmysql4")
+
+ multistatements = CLIENT_MULTI_STATEMENTS
+
+ mysqlOO = mysqloo
+ TMySQL = tmysql
+end
+loadMySQLModule()
+
+module("MySQLite")
+
+
+function initialize(config)
+ MySQLite_config = config or MySQLite_config
+
+ if not MySQLite_config then
+ ErrorNoHalt("Warning: No MySQL config!")
+ end
+
+ loadMySQLModule()
+
+ if MySQLite_config.EnableMySQL then
+ connectToMySQL(MySQLite_config.Host, MySQLite_config.Username, MySQLite_config.Password, MySQLite_config.Database_name, MySQLite_config.Database_port)
+ else
+ timer.Simple(0, function()
+ GAMEMODE.DatabaseInitialized = GAMEMODE.DatabaseInitialized or function() end
+ hook.Call("DatabaseInitialized", GAMEMODE)
+ end)
+ end
+end
+
+local CONNECTED_TO_MYSQL = false
+local msOOConnect
+databaseObject = nil
+
+local queuedQueries
+local cachedQueries
+
+function isMySQL()
+ return CONNECTED_TO_MYSQL
+end
+
+function begin()
+ if not CONNECTED_TO_MYSQL then
+ sql.Begin()
+ else
+ if queuedQueries then
+ debug.Trace()
+ error("Transaction ongoing!")
+ end
+ queuedQueries = {}
+ end
+end
+
+function commit(onFinished)
+ if not CONNECTED_TO_MYSQL then
+ sql.Commit()
+ if onFinished then onFinished() end
+ return
+ end
+
+ if not queuedQueries then
+ error("No queued queries! Call begin() first!")
+ end
+
+ if #queuedQueries == 0 then
+ queuedQueries = nil
+ if onFinished then onFinished() end
+ return
+ end
+
+ -- Copy the table so other scripts can create their own queue
+ local queue = table.Copy(queuedQueries)
+ queuedQueries = nil
+
+ -- Handle queued queries in order
+ local queuePos = 0
+ local call
+
+ -- Recursion invariant: queuePos > 0 and queue[queuePos] <= #queue
+ call = function(...)
+ queuePos = queuePos + 1
+
+ if queue[queuePos].callback then
+ queue[queuePos].callback(...)
+ end
+
+ -- Base case, end of the queue
+ if queuePos + 1 > #queue then
+ if onFinished then onFinished() end -- All queries have finished
+ return
+ end
+
+ -- Recursion
+ local nextQuery = queue[queuePos + 1]
+ query(nextQuery.query, call, nextQuery.onError)
+ end
+
+ query(queue[1].query, call, queue[1].onError)
+end
+
+function queueQuery(sqlText, callback, errorCallback)
+ if CONNECTED_TO_MYSQL then
+ table.insert(queuedQueries, {query = sqlText, callback = callback, onError = errorCallback})
+ return
+ end
+ -- SQLite is instantaneous, simply running the query is equal to queueing it
+ query(sqlText, callback, errorCallback)
+end
+
+local function msOOQuery(sqlText, callback, errorCallback, queryValue)
+ local query = databaseObject:query(sqlText)
+ local data
+ query.onData = function(Q, D)
+ data = data or {}
+ data[#data + 1] = D
+ end
+
+ query.onError = function(Q, E)
+ if databaseObject:status() == mysqlOO.DATABASE_NOT_CONNECTED then
+ table.insert(cachedQueries, {sqlText, callback, queryValue})
+
+ -- Immediately try reconnecting
+ msOOConnect(MySQLite_config.Host, MySQLite_config.Username, MySQLite_config.Password, MySQLite_config.Database_name, MySQLite_config.Database_port)
+ return
+ end
+
+ local supp = errorCallback and errorCallback(E, sqlText)
+ if not supp then error(E .. " (" .. sqlText .. ")") end
+ end
+
+ query.onSuccess = function()
+ local res = queryValue and data and data[1] and table.GetFirstValue(data[1]) or not queryValue and data or nil
+ if callback then callback(res, query:lastInsert()) end
+ end
+ query:start()
+end
+
+local function tmsqlQuery(sqlText, callback, errorCallback, queryValue)
+ local call = function(res)
+ res = res[1] -- For now only support one result set
+ if not res.status then
+ local supp = errorCallback and errorCallback(res.error, sqlText)
+ if not supp then error(res.error .. " (" .. sqlText .. ")") end
+ return
+ end
+
+ if not res.data or #res.data == 0 then res.data = nil end -- compatibility with other backends
+ if queryValue and callback then return callback(res.data and res.data[1] and table.GetFirstValue(res.data[1]) or nil) end
+ if callback then callback(res.data, res.lastid) end
+ end
+
+ databaseObject:Query(sqlText, call)
+end
+
+local function SQLiteQuery(sqlText, callback, errorCallback, queryValue)
+ sql.m_strError = "" -- reset last error
+
+ local lastError = sql.LastError()
+ local Result = queryValue and sql.QueryValue(sqlText) or sql.Query(sqlText)
+
+ if sql.LastError() and sql.LastError() ~= lastError then
+ local err = sql.LastError()
+ local supp = errorCallback and errorCallback(err, sqlText)
+ if supp == false then error(err .. " (" .. sqlText .. ")", 2) end
+ return
+ end
+
+ if callback then callback(Result) end
+ return Result
+end
+
+function query(sqlText, callback, errorCallback)
+ local qFunc = (CONNECTED_TO_MYSQL and ((mysqlOO and msOOQuery) or (TMySQL and tmsqlQuery))) or SQLiteQuery
+ return qFunc(sqlText, callback, errorCallback, false)
+end
+
+function queryValue(sqlText, callback, errorCallback)
+ local qFunc = (CONNECTED_TO_MYSQL and ((mysqlOO and msOOQuery) or (TMySQL and tmsqlQuery))) or SQLiteQuery
+ return qFunc(sqlText, callback, errorCallback, true)
+end
+
+local function onConnected()
+ CONNECTED_TO_MYSQL = true
+
+ -- Run the queries that were called before the connection was made
+ for k, v in pairs(cachedQueries or {}) do
+ cachedQueries[k] = nil
+ if v[3] then
+ queryValue(v[1], v[2])
+ else
+ query(v[1], v[2])
+ end
+ end
+ cachedQueries = {}
+
+ hook.Call("DatabaseInitialized", GAMEMODE.DatabaseInitialized and GAMEMODE or nil)
+end
+
+msOOConnect = function(host, username, password, database_name, database_port)
+ databaseObject = mysqlOO.connect(host, username, password, database_name, database_port)
+
+ if timer.Exists("darkrp_check_mysql_status") then timer.Remove("darkrp_check_mysql_status") end
+
+ databaseObject.onConnectionFailed = function(_, msg)
+ timer.Simple(5, function()
+ msOOConnect(MySQLite_config.Host, MySQLite_config.Username, MySQLite_config.Password, MySQLite_config.Database_name, MySQLite_config.Database_port)
+ end)
+ error("Connection failed! " .. tostring(msg) .. "\nTrying again in 5 seconds.")
+ end
+
+ databaseObject.onConnected = onConnected
+
+ databaseObject:connect()
+end
+
+local function tmsqlConnect(host, username, password, database_name, database_port)
+ local db, err = TMySQL.initialize(host, username, password, database_name, database_port, nil, MySQLite_config.MultiStatements and multistatements or nil)
+ if err then error("Connection failed! " .. err .. "\n") end
+
+ databaseObject = db
+ onConnected()
+end
+
+function connectToMySQL(host, username, password, database_name, database_port)
+ database_port = database_port or 3306
+ local func = mysqlOO and msOOConnect or TMySQL and tmsqlConnect or function() end
+ func(host, username, password, database_name, database_port)
+end
+
+function SQLStr(str)
+ local escape =
+ not CONNECTED_TO_MYSQL and sql.SQLStr or
+ mysqlOO and function(str) return "\"" .. databaseObject:escape(tostring(str)) .. "\"" end or
+ TMySQL and function(str) return "\"" .. databaseObject:Escape(tostring(str)) .. "\"" end
+
+ return escape(str)
+end
+
+function tableExists(tbl, callback, errorCallback)
+ if not CONNECTED_TO_MYSQL then
+ local exists = sql.TableExists(tbl)
+ callback(exists)
+
+ return exists
+ end
+
+ queryValue(string.format("SHOW TABLES LIKE %s", SQLStr(tbl)), function(v)
+ callback(v ~= nil)
+ end, errorCallback)
+end
diff --git a/gamemode/core/database/sv_setup.lua b/gamemode/core/database/sv_setup.lua
new file mode 100644
index 0000000..0d0eb74
--- /dev/null
+++ b/gamemode/core/database/sv_setup.lua
@@ -0,0 +1,160 @@
+--Adds the MySQLite global
+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 sql = {}
+
+--Setup the database if it's not already
+local setup_db = [[
+CREATE TABLE IF NOT EXISTS playerdata(SteamID bigint primary key, PlayerData json, MetaData json)]]
+
+--Create a new player
+local create_player_query = [[
+INSERT INTO playerdata (`SteamID`,`PlayerData`,`MetaData`) VALUES(%.0f,%q,%q)]]
+
+--Get a player's data from the database
+local fetch_player_query = [[
+SELECT PlayerData, MetaData FROM playerdata WHERE SteamID=%.0f
+]]
+
+local save_player_query = [[
+UPDATE playerdata SET MetaData=%q PlayerData=%q 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))
+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...")
+ MySQLite.initialize(config)
+end
+hook.Add("DatabaseInitialized","setup_table",function()
+ local setup_success = function(res,li)
+ print("Set up connection to db")
+ end
+ print("Setup query:",setup_db)
+ MySQLite.query(setup_db,setup_success,q_fai)
+end)
+connect()
+
+--Retruns (PlayerData, MetaData) or nil
+function sql.GetPlayerData(ply)
+ local s64 = ply:SteamID64()
+ local q_str = s_fmt(fetch_player_query,s64)
+ local q_suc = function(res,li)
+ print("Got player's data:",res,type(res))
+ if res == nil then
+ print("Was nil, createing player data")
+ sql.CreatePlayerTable(ply)
+ else
+ PrintTable(res)
+ assert(#res == 1,"Not unique!")
+ print("Was unique!")
+ local meta = res[1].MetaData
+ local plyd = res[1].PlayerData
+ local mtbl = util.JSONToTable(meta)
+ print("About to check if we are on the right server")
+ if mtbl.lastserver ~= game.GetIPAddress() then
+ print("Connecting player to ", mtbl.lastserver, " was on ", game.GetIPAddress())
+ ply:ConCommand("connect " .. mtbl.lastserver)
+ return
+ end
+ print("We were on the right server")
+ local _,_,x,y,z = mtbl.lastlocation:find("([%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)
+ end
+ end
+ print("doing query",q_str)
+ MySQLite.query(q_str,q_suc,q_fai)
+end
+
+function sql.CreatePlayerTable(ply)
+ print("Createing player table....")
+ local s64 = ply:SteamID64()
+ print("steamid was", s64)
+ local plytbl = data.newdata()
+ 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_suc = function(res,li)
+ print("Inserted new player",ply)
+ sql.GetPlayerData(ply)
+ end
+ print("doing query", q_str)
+ MySQLite.query(q_str,q_suc,q_fai)
+end
+
+function sql.SendPlayerToInstance(ply,ls,ll)
+ local s64 = ply:SteamID64()
+ local plydata = serialize_player(ply)
+ local plymeta = util.TableToJSON({
+ lastserver = ls,
+ lastlocation = ll
+ })
+ local q_str = 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)
+ if args[1] == "create" then
+ sql.CreatePlayerTable(ply)
+ elseif args[1] == "get" then
+ sql.GetPlayerData(ply)
+ elseif args[1] == "send" then
+ sql.SendPlayerToInstance(ply,args[2],args[3])
+ else
+ error("Command not understood:" .. args[1] .. "!")
+ end
+end)
+
+return sql
diff --git a/gamemode/core/inventory/inventory.lua b/gamemode/core/inventory/inventory.lua
index 47a7eb3..b4c025c 100644
--- a/gamemode/core/inventory/inventory.lua
+++ b/gamemode/core/inventory/inventory.lua
@@ -5,20 +5,21 @@
CreateInventoryFromData(string_name,string_data)::table_inventory)
DeriveInventory(string_name) ::table_inventory
Inventories have the following structure
- inv.Name ::string
- inv:FindPlaceFor(item) ::table_position or nil
- inv:CanFitIn(table_position,item) ::true or string_explanation
- inv:Put(table_position,item) ::nil
- inv:Has(string_or_compare_func) ::table_position or nil
- inv:Remove(position) ::table_item
- inv:Get(position) ::table_item
- inv:Serialize() ::string
- inv:DeSerialize(str) ::table_inventory
+ 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
The above fields must be defined for new inventories.
-----------------------------------------------------
The below are automatically made if they do not exist.
- inv:AddObserver(tbl_other) ::number_id
- inv:RemoveObserver(number_id) ::nil
+ inv:AddObserver(tbl_other) ::number_id Whenever put or remove is called on this inventory, tbl_other's put() and remove() is also called, for easy networking to whoever needs it
+ inv:RemoveObserver(number_id) ::nil Removes an observer from the inventory
------------------------------------------------------
These fields should be defined when an inventory is created, before it can be used
inv.Owner ::entity
@@ -31,9 +32,6 @@
Serialize() should take this inventories contents and return a string that it can recreate this inventory from. DeSerialize should create a self.Copy() with the appropriate fields set. Take advantage of the fact that items must also have Serialize() and DeSerialize() methods.
]]
-local thm = nrequire("colortheme.lua")
-local log = nrequire("log.lua")
-
local inv = {}
--Creates a partial copy of a table(tables are copied, functions are not)
@@ -64,7 +62,7 @@ local function DefaultAddObserver(self,tbl)
end
local function DefaultRemoveObserver(self,observer_id)
for i = observer_id, #self.observers do
- self.observers[i] = self.observers + 1
+ self.observers[i] = self.observers[i + 1]
end
end
local function SetDefaultObservers(tbl)
@@ -117,7 +115,7 @@ function inv.RegisterInventory(tbl)
SetDefaultObservers(tbl)
end
inventories[tbl.Name] = tbl
- log.debug("Registered inventory: " .. tbl.Name .. "\n")
+ print("Registered inventory: " .. tbl.Name)
end
--Create an inventory
diff --git a/gamemode/core/inventory/item.lua b/gamemode/core/inventory/item.lua
index 354472a..dd788d6 100644
--- a/gamemode/core/inventory/item.lua
+++ b/gamemode/core/inventory/item.lua
@@ -17,9 +17,6 @@
The above must be defined for every item
Items may also have methods from one or more interfaces registered with RegisterInterface
]]
-local log = nrequire("log.lua")
-print("in item.lua, log is:")
-PrintTable(log)
local itm = {}
local required_fields = {
@@ -33,7 +30,7 @@ function itm.RegisterItem(tbl)
end
assert(items[tbl.Name] == nil, string.format("Attempted to register 2 items with the same name %q",tbl.Name))
items[tbl.Name] = tbl
- log.debug("Registered item: " .. tbl.Name .. "\n")
+ print("Registered item: " .. tbl.Name)
end
function itm.GetItemByName(name)
diff --git a/gamemode/core/inventory/sv_invtracker.lua b/gamemode/core/inventory/sv_invtracker.lua
index 98e0268..5331261 100644
--- a/gamemode/core/inventory/sv_invtracker.lua
+++ b/gamemode/core/inventory/sv_invtracker.lua
@@ -4,6 +4,7 @@
local inv = nrequire("inventory/inventory.lua")
local itm = nrequire("item.lua")
+local track = {}
for k,v in pairs({
"art_ObserveInventory",
@@ -41,8 +42,15 @@ net.Receive("art_RequestInvMove",function(len,ply)
print("froment",froment)
print("froment.data:",froment.data)
print("froment.data.inventories",froment.data.inventories)
+ PrintTable(froment.data.inventories)
print("invid:",froment.data.inventories[frominvid])
assert(froment.data ~= nil and froment.data.inventories ~= nil and froment.data.inventories[frominvid] ~= nil, "From entity did not have that inventory!")
+ print("toent",toent)
+ print("toent.data",toent.data)
+ print("toent.data.inventories",toent.data.inventories)
+ PrintTable(toent.data.inventories)
+ print("toinvid",toinvid)
+ print("toent.data.inventories[invid]",toent.data.inventories[toinvid])
assert(toent.data ~= nil and toent.data.inventories ~= nil and toent.data.inventories[toinvid] ~= nil, "To entity did not have that inventory!")
local frominv = froment.data.inventories[frominvid]
local toinv = toent.data.inventories[toinvid]
@@ -54,13 +62,13 @@ net.Receive("art_RequestInvMove",function(len,ply)
toinv:Put(topos,item)
end)
-local function ClearInventories(ply)
+function track.ClearInventories(ply)
ply.data = {}
ply.data.inventories = {}
end
--Updates the client side inventory whenever the inventory is updated server side
-local function MakeInventoryObserver(ply,invid)
+function track.MakeInventoryObserver(ply,invid)
local observer = {}
observer.Put = function(self,pos,item)
print("In observer, item was", item)
@@ -86,13 +94,25 @@ local function MakeInventoryObserver(ply,invid)
return observer
end
-local function GiveInventoryTo(ply,name)
+function track.NotifyPlayerOfInventory(ply,inv)
+ local initaldat = inv:Serialize()
+ net.Start("art_ObserveInventory")
+ net.WriteUInt(inv.id,32)
+ net.WriteString(inv.Name)
+ net.WriteUInt(#initaldat,32)
+ net.WriteData(initaldat,#initaldat)
+ print("Before sending, inv owner is", inv.Owner)
+ net.WriteEntity(inv.Owner)
+ net.Send(ply)
+end
+
+function track.GiveInventoryTo(ply,name)
local i = inv.CreateInventory(name)
- i.owner = ply
+ i.Owner = ply
local nid = #ply.data.inventories + 1
i.id = nid
local dat = i:Serialize()
- local observer = MakeInventoryObserver(ply,nid)
+ local observer = track.MakeInventoryObserver(ply,nid)
i:AddObserver(observer)
ply.data.inventories[nid] = i
@@ -101,13 +121,59 @@ local function GiveInventoryTo(ply,name)
net.WriteString(name)
net.WriteUInt(#dat,32)
net.WriteData(dat,#dat)
+ net.WriteEntity(i.Owner)
+ net.Send(ply)
+end
+
+function track.GiveInventoryWithData(ply,name,data)
+ print("Giveing inventory with data")
+ local i = inv.CreateInventoryFromData(name,data)
+ local nid = #ply.data.inventories + 1
+ local observer = track.MakeInventoryObserver(ply,nid)
+ i.Owner = ply
+ i.id = nid
+ i:AddObserver(observer)
+ ply.data.inventories[nid] = i
+
+ net.Start("art_ObserveInventory")
+ net.WriteUInt(nid,32)
+ net.WriteString(name)
+ net.WriteUInt(#data,32)
+ net.WriteData(data,#data)
net.WriteEntity(ply)
net.Send(ply)
end
+
+
+--A shortcut for finding if a player has an item
+local plymeta = FindMetaTable("Player")
+
+function plymeta:HasItem(str)
+ for k,v in pairs(self.inventories) do
+ local p = v:Has(str)
+ if type(p) == "table" then
+ return {k,p}
+ end
+ end
+ return false
+end
+
+function plymeta:RemoveItem(tbl)
+ local nid = tbl[1]
+ local pos = tbl[2]
+ self.inventories[nid]:Remove(pos)
+end
+
+function track.SendPlayerData(ply)
+ net.Start("art_load_player_data")
+ net.WriteTable({})
+ net.Send(ply)
+end
+
concommand.Add("SendMeData",function(ply,cmd,args)
- ClearInventories(ply)
- GiveInventoryTo(ply,"Equipment")
+ track.ClearInventories(ply)
+ track.GiveInventoryTo(ply,"Equipment")
net.Start("art_load_player_data")
net.WriteTable({})
net.Send(ply)
@@ -118,7 +184,7 @@ concommand.Add("ShowMyInventories",function(ply,cmd,args)
end)
concommand.Add("AddInventory",function(ply,cmd,args)
- GiveInventoryTo(ply,args[1])
+ track.GiveInventoryTo(ply,args[1])
end)
concommand.Add("GiveItem",function(ply,cmd,args)
@@ -139,3 +205,5 @@ concommand.Add("GiveItem",function(ply,cmd,args)
print("I couldn't find a place to put it!")
end
end)
+
+return track
diff --git a/gamemode/core/npc/sv_npcsystem.lua b/gamemode/core/npc/sv_npcsystem.lua
index b41f4e6..1abbc67 100644
--- a/gamemode/core/npc/sv_npcsystem.lua
+++ b/gamemode/core/npc/sv_npcsystem.lua
@@ -1,4 +1,3 @@
-
local f = nrequire("concommands.lua")
local n = {}
local npcs = {} --Master table of npcs
@@ -12,28 +11,100 @@ function n.RegisterNPC(npc)
end
function n.CreateNPCByName(npcname, pos)
- print("Createing a " ,npcname ," at ", pos)
+ print("Createing a ", npcname, " at ", pos)
local npctbl = npcs[npcname]
local npc = ents.Create("npc_huntable")
npc:SetPos(pos)
- for k,v in pairs(npctbl) do
+
+ for k, v in pairs(npctbl) do
npc[k] = v
end
+
npc:Spawn()
+
return npc
end
+--Creates a shop npc with this tbl
+function n.CreateShop(npc)
+ print("Createing shop npc")
+ local npcent = ents.Create("npc_shop")
+ for k,v in pairs(npc) do
+ npcent[k] = v
+ end
+ npcent:Spawn()
+ print("Called spawn")
+end
-if SERVER then
- autocompletef = nil
-else
- autocompletef = f.AutocompleteFunction(npcs)
+--Creates a townie npc with this tbl
+function n.CreateTownie(tbl)
+ local npcent = ents.Create("npc_townie")
+ for k, v in pairs(tbl) do
+ npcent[k] = v
+ end
+ npcent:Spawn()
+end
+
+--Creates a new navigation node for npc's
+function n.CreateNavNode(tbl)
+ local nodeent = ents.Create("info_townienode")
+ assert(tbl ~= nil, "Tried to create a nil navnode")
+ for k, v in pairs(tbl) do
+ nodeent[k] = v
+ end
+ nodeent:Spawn()
+end
+
+--Ents to remove when refreshing the npc map
+local removeents = {"npc_townie", "info_townienode", "npc_shop"}
+
+-- "art_chest",
+for k, v in pairs(removeents) do
+ local eot = ents.FindByClass(v)
+ for i, j in pairs(eot) do
+ j:Remove()
+ end
+end
+
+local mapfields = {"navnodes", "npcs"}
+
+-- "chests",
+local function loadMap()
+ for k, v in ipairs(mapfields) do
+ local mapname = game.GetMap()
+ local fpath = string.format("artery/maps/%s/%s/*", mapname, v)
+ local files, dirs = file.Find(fpath, "DATA")
+
+ for i, j in pairs(files) do
+ if string.GetExtensionFromFilename(j) ~= "lua" then continue end
+ local itempath = string.format("artery/maps/%s/%s/%s", mapname, v, j)
+ local itemtxt = file.Read(itempath, "DATA")
+ assert(itemtxt ~= nil, "Found a file, but it looks like it can't be compiled:" .. itempath)
+ CompileString(itemtxt, itempath)()
+ end
+ end
end
-concommand.Add("artery_makenpc",function(ply,cmd,args)
+
+hook.Add("InitPostEntity", "artery_spawnmapnpcs", function()
+ loadMap()
+end)
+
+concommand.Add("artery_reloadmap", function()
+ for k, v in pairs(removeents) do
+ local eot = ents.FindByClass(v)
+
+ for i, j in pairs(eot) do
+ j:Remove()
+ end
+ end
+
+ loadMap()
+end)
+
+concommand.Add("artery_makenpc", function(ply, cmd, args)
if not ply:IsAdmin() then return end
local na = args[1]
- n.CreateNPCByName(na,ply:GetEyeTrace().HitPos)
-end,
-autocompletef)
+ n.CreateNPCByName(na, ply:GetEyeTrace().HitPos)
+end, autocompletef)
return n
diff --git a/gamemode/core/npc/sv_shop.lua b/gamemode/core/npc/sv_shop.lua
new file mode 100644
index 0000000..2e54f7e
--- /dev/null
+++ b/gamemode/core/npc/sv_shop.lua
@@ -0,0 +1,17 @@
+--[[
+ Create a shop npc
+]]
+
+local shop = {}
+
+function shop.CreateShop(npc)
+ print("Createing shop npc")
+ local npcent = ents.Create("npc_shop")
+ for k,v in pairs(npc) do
+ npcent[k] = v
+ end
+ npcent:Spawn()
+ print("Called spawn")
+end
+
+return shop
diff --git a/gamemode/core/pac/cl_pac.lua b/gamemode/core/pac/cl_pac.lua
new file mode 100644
index 0000000..9163d82
--- /dev/null
+++ b/gamemode/core/pac/cl_pac.lua
@@ -0,0 +1,90 @@
+--[[
+ A lazy loader for pac3 costumes, used for weapons/armor/ect.
+]]
+
+--As soon as the client connects, request the names of all the pac's on the server
+
+--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!)")
+ end
+ local networkmsgs = {
+ "artery_downloadpac",
+ "artery_applypac",
+ "artery_giveworldpacs",
+ "artery_removepac"
+ }
+ for k,v in pairs(networkmsgs) do
+ net.Receive(v,no_pac_panic)
+ end
+ no_pac_panic()
+ return --Don't execute this file!
+end
+
+timer.Simple(0,function()
+ net.Start("artery_getworldpacs")
+ net.SendToServer()
+end)
+
+file.CreateDir("artery/pacs")
+
+local function loadpac(ent,name,hash)
+ print("Told to apply pac", name, "to ent", ent)
+ local filepath = string.format("artery/pacs/%s.txt",name)
+ local filetext = file.Read(filepath,"DATA")
+ if ent.AttachPACPart == nil then
+ pac.SetupENT(ent)
+ assert(ent.AttachPACPart ~= nil,"Failed to set up ent",ent)
+ end
+ if filetext and (tonumber(util.CRC(filetext)) == hash) then
+ local pactbl = CompileString(string.format("return {%s}",filetext),name)()
+ ent:AttachPACPart(pactbl)
+ else--Cache is old, download the new pac!
+ net.Start("artery_requestpac")
+ net.WriteString(name)
+ net.SendToServer()
+ --1 second is probably long enough to download a pac, right?
+ timer.Simple(1,function()
+ loadpac(ent,name,hash)
+ end)
+ end
+end
+
+local function unloadpac(ent,name,hash)
+ local filepath = string.format("artery/pacs/%s.txt",name)
+ local filetext = file.Read(filepath,"DATA")
+ local pactbl = CompileString(string.format("return {%s}",filetext),name)()
+ ent:RemovePACPart(pactbl)
+end
+
+net.Receive("artery_downloadpac",function()
+ local pac_name = net.ReadString()
+ local pac_txt = net.ReadString()
+ local pac_hash = net.ReadUInt(32)
+ local filepath = string.format("artery/pacs/%s.txt",pac_name)
+ file.Write(filepath,pac_txt)
+end)
+
+net.Receive("artery_applypac",function()
+ local pac_ent = net.ReadEntity()
+ local pac_name = net.ReadString()
+ local pac_hash = net.ReadUInt(32)
+ loadpac(pac_ent,pac_name,pac_hash)
+end)
+
+net.Receive("artery_giveworldpacs",function()
+ local pactbl = net.ReadTable()
+ for ent,pacnames in pairs(pactbl) do
+ for name, hash in pairs(pacnames) do
+ loadpac(ent,name,hash)
+ end
+ end
+end)
+
+net.Receive("artery_removepac",function()
+ local pac_ent = net.ReadEntity()
+ local pac_name = net.ReadString()
+ local pac_hash = net.ReadUInt(32)
+ unloadpac(pac_ent,pac_name,pac_hash)
+end)
diff --git a/gamemode/core/pac/sv_pac.lua b/gamemode/core/pac/sv_pac.lua
new file mode 100644
index 0000000..5a82607
--- /dev/null
+++ b/gamemode/core/pac/sv_pac.lua
@@ -0,0 +1,167 @@
+--[[
+ The server side lazy loader for pac3 costumes
+ PAC3 outfits are not downloaded until they are needed, we can keep the inital download to join the server pretty small this way.
+ The downside is that the game might lag a little when someone wears something that is rare/new and everyone has to download it.
+
+ Console Commands:
+ artery_reload_pacs
+ The server will cache PAC's so it dosen't need to read form disk every time. If you're live editing pac's on the server, and are wondering why your changes aren't showing, use this command. There is no command to clear client cache, because applying a pac also sends a hash of the pac to the client, and the client re-downloads if the hashes are different.
+
+
+ Functions:
+ entity:ApplyPac(String costume) :: nil
+ Find the file /data/pacs/<costume>.pac (on the server) and tell clients to apply it to ent. This will automatically download the pac to any clients nessessary.
+
+ entity:RemovePac(String costume) :: nil
+ Remove the pac from the entity.
+
+ entity:GetPacs() :: table
+ Retreives a list of the pacs an entity is wearing, as strings
+
+ Network Strings:
+ "artery_getworldpacs",
+ "artery_giveworldpacs",
+ "artery_applypac",
+ "artery_removepac",
+ "artery_requestpac",
+ "artery_downloadpac"
+]]
+
+local p3 = {}
+
+local nwstrings = {
+ "artery_getworldpacs",
+ "artery_giveworldpacs",
+ "artery_applypac",
+ "artery_removepac",
+ "artery_requestpac",
+ "artery_downloadpac"
+}
+for _,v in pairs(nwstrings) do
+ util.AddNetworkString(v)
+end
+
+--If the server has pac installed, restrict player's from putting on their own pacs
+hook.Add("PrePACConfigApply", "stoppacs", function(ply, outfit_data)
+ if not ply:IsAdmin() then
+ return false, "You don't have permission to do that!"
+ end
+end)
+
+--When the server starts, get all the pacs and calculate their hashes so we can index them quickly without haveing to read from disk each time.
+local pachashes = {}
+local function loadhashes()
+ local files,_ = file.Find("artery/pacs/*","DATA")
+ for _,v in ipairs(files) do
+ local filepath = string.format("artery/pacs/%s",v)
+ local filetext = file.Read(filepath,"DATA")
+ local filehash = util.CRC(filetext)
+ pachashes[string.StripExtension(v)] = tonumber(filehash)
+ end
+end
+loadhashes()
+
+local appliedpacs = {}
+
+function p3.ApplyPac(what, name)
+ appliedpacs[what] = appliedpacs[what] or {}
+ appliedpacs[what][name] = pachashes[name]
+ net.Start("artery_applypac")
+ net.WriteEntity(what)
+ net.WriteString(name)
+ net.WriteUInt(pachashes[name],32)
+ net.Broadcast()
+end
+
+function p3.RemovePac(what, 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
+ appliedpacs[what] = nil
+ end
+ net.Start("artery_removepac")
+ net.WriteEntity(what)
+ net.WriteString(name)
+ net.WriteUInt(pachashes[name],32)
+ net.Broadcast()
+end
+
+function p3.GetPacs(what)
+ return appliedpacs[what] or {}
+end
+
+--If a player joins the server, tell them all about the pacs that are applied
+net.Receive("artery_getworldpacs",function(ln,ply)
+ net.Start("artery_giveworldpacs")
+ net.WriteTable(appliedpacs)
+ net.Send(ply)
+end)
+
+local max_pacs_in_cache = 10
+local pacs_in_cache = 0
+local pac_cache = {}
+
+--Load something from our cache
+local function cacheload(key)
+ --If it's already in the cache, just update the time it was last used and return the pac.
+ if pac_cache[key] ~= nil then
+ pac_cache[key].time = CurTime()
+ return pac_cache[key].pac
+ end
+
+ --Otherwise, we need to load it.
+ local pacpath = string.format("artery/pacs/%s.txt",key)
+ local pacfile = file.Read(pacpath,"LUA")
+
+ --If we haven't reached max cache yet, just put it in
+ if pacs_in_cache < max_pacs_in_cache then
+ pac_cache[key] = {
+ ["pac"] = pacfile,
+ ["time"] = CurTime()
+ }
+ pacs_in_cache = pacs_in_cache + 1
+ return pacfile
+ else
+ --We have max pac's, delete the oldest one, and put the new one in.
+ local oldest,oldstr = CurTime(),""
+ for k,v in pairs(pac_cache) do
+ if v.time < oldest then
+ oldest = v.time
+ oldstr = k
+ end
+ end
+ pac_cache[oldstr] = nil
+ pac_cache[key] = {
+ ["pac"] = pacfile,
+ ["time"] = CurTime()
+ }
+ return pacfile
+ end
+end
+
+net.Receive("artery_requestpac",function(ln,ply)
+ local pac_name = net.ReadString()
+
+ --Double check that we're not executing a directory traversal attack https://www.owasp.org/index.php/Path_Traversal
+ if string.find(pac_name,"..",1,true) then
+ Report(string.format("Directory traversal attack attempted by %s:%s using artery_requestpac string %q",ply:Nick(),ply:SteamID64(),pac_name))
+ end
+
+ local pac_txt = cacheload(pac_name)
+
+ net.Start("artery_downloadpac")
+ net.WriteString(pac_name)
+ net.WriteString(pac_txt)
+ net.WriteUInt(pachashes[pac_name],32)
+ net.Send(ply)
+
+end)
+
+--Does all the things needed to edit pac's live
+concommand.Add("artery_reload_pacs",function()
+ pac_cache = {}
+ pacs_in_cache = 0
+ loadhashes()
+end)
+
+return p3
diff --git a/gamemode/inventorysystem/cl_common.lua b/gamemode/inventorysystem/cl_common.lua
index 07fc786..15f67b4 100644
--- a/gamemode/inventorysystem/cl_common.lua
+++ b/gamemode/inventorysystem/cl_common.lua
@@ -24,6 +24,9 @@ function com.generatereceiver()
local frominv,toinv = panels[1].info.inv,self.info.inv
print("Something was dropped on:",x,y)
PrintTable(panels)
+ print("self is", self)
+ print("self.info is", self.info)
+ PrintTable(self.info)
print("froment:",froment)
print("toent:",toent)
print("fromid",fromid)
@@ -34,6 +37,20 @@ function com.generatereceiver()
PrintTable(self.info.pos)
print("frominv",frominv)
print("toinv",toinv)
+
+ --Do nothing if we don't actually want to move anything anywhere
+ local posequal = true
+ if (froment ~= toent) or (fromid ~= toid) or (frominv ~= toinv) then posequal = false end
+ if posequal then
+ for k,v in pairs(frompos) do
+ if topos[k] ~= v then
+ posequal = false
+ break
+ end
+ end
+ end
+ if posequal then return end
+
local item = frominv:Get(frompos)
print("item was", item)
--Fake remove the item, in case the position we want to move it to overlaps with where it is now.
diff --git a/gamemode/inventorysystem/equipment/cl_equipment.lua b/gamemode/inventorysystem/equipment/cl_equipment.lua
index 7abd27a..22458c7 100644
--- a/gamemode/inventorysystem/equipment/cl_equipment.lua
+++ b/gamemode/inventorysystem/equipment/cl_equipment.lua
@@ -7,64 +7,66 @@ local inv = {}
local width, height = (ScrW() / 4) - 25, ScrH()
local iconsize = width / 5
-local ringmat = svg.MaterialFromSVG("materials/svg/delapouite/originals/svg/000000/transparent/ring.svg")
+local ucol = col.console.black
+
+local ringmat = svg.MaterialFromSVG("materials/svg/delapouite/originals/svg/000000/transparent/ring.svg", nil, ucol)
--Positions for the eqipment inventory
local eqp = {
["Head"] = {
x = (width / 2) - (iconsize / 2),
y = 0,
- img = svg.MaterialFromSVG("materials/svg/lorc/originals/svg/000000/transparent/cracked-helm.svg"),
+ img = svg.MaterialFromSVG("materials/svg/lorc/originals/svg/000000/transparent/cracked-helm.svg", nil, ucol),
},
["Shoulders"] = {
x = (width / 2) - (iconsize / 2),
y = iconsize,
- img = svg.MaterialFromSVG("materials/svg/skoll/originals/svg/000000/transparent/pauldrons.svg")
+ img = svg.MaterialFromSVG("materials/svg/skoll/originals/svg/000000/transparent/pauldrons.svg", nil, ucol)
},
["Chest"] = {
x = width / 2,
y = iconsize * 2,
- img = svg.MaterialFromSVG("materials/svg/willdabeast/deviations/svg/000000/transparent/chain-mail.svg")
+ img = svg.MaterialFromSVG("materials/svg/willdabeast/deviations/svg/000000/transparent/chain-mail.svg", nil, ucol)
},
["Back"] = {
x = (width / 2) - iconsize,
y = iconsize * 2,
- img = svg.MaterialFromSVG("materials/svg/lorc/originals/svg/000000/transparent/knapsack.svg"),
+ img = svg.MaterialFromSVG("materials/svg/lorc/originals/svg/000000/transparent/knapsack.svg", nil, ucol),
},
["Arms"] = {
x = (width / 2) - (iconsize / 2),
y = iconsize * 3,
- img = svg.MaterialFromSVG("materials/svg/skoll/originals/svg/000000/transparent/bracers.svg")
+ img = svg.MaterialFromSVG("materials/svg/skoll/originals/svg/000000/transparent/bracers.svg", nil, ucol)
},
["Belt"] = {
x = (width / 2) - (iconsize * 1.5),
y = iconsize * 3,
- img = svg.MaterialFromSVG("materials/svg/lucasms/equipment/svg/000000/transparent/belt.svg")
+ img = svg.MaterialFromSVG("materials/svg/lucasms/equipment/svg/000000/transparent/belt.svg", nil, ucol)
},
["Gloves"] = {
x = (width / 2) + (iconsize / 2),
y = iconsize * 3,
- img = svg.MaterialFromSVG("materials/svg/delapouite/originals/svg/000000/transparent/gloves.svg")
+ img = svg.MaterialFromSVG("materials/svg/delapouite/originals/svg/000000/transparent/gloves.svg", nil, ucol)
},
["Left Hand"] = {
x = width / 2,
y = iconsize * 4,
- img = svg.MaterialFromSVG("materials/svg/sbed/originals/svg/000000/transparent/shield.svg")
+ img = svg.MaterialFromSVG("materials/svg/sbed/originals/svg/000000/transparent/shield.svg", nil, ucol)
},
["Right Hand"] = {
x = (width / 2) - iconsize,
y = iconsize * 4,
- img = svg.MaterialFromSVG("materials/svg/delapouite/originals/svg/000000/transparent/thor-hammer.svg")
+ img = svg.MaterialFromSVG("materials/svg/delapouite/originals/svg/000000/transparent/thor-hammer.svg", nil, ucol)
},
["Legs"] = {
x = (width / 2) - iconsize,
y = iconsize * 5,
- img = svg.MaterialFromSVG("materials/svg/irongamer/originals/svg/000000/transparent/armored-pants.svg")
+ img = svg.MaterialFromSVG("materials/svg/irongamer/originals/svg/000000/transparent/armored-pants.svg", nil, ucol)
},
["Feet"] = {
x = width / 2,
y = iconsize * 5,
- img = svg.MaterialFromSVG("materials/svg/lorc/originals/svg/000000/transparent/boots.svg"),
+ img = svg.MaterialFromSVG("materials/svg/lorc/originals/svg/000000/transparent/boots.svg", nil, ucol),
},
["Ring 1"] = {
x = 0,
diff --git a/gamemode/inventorysystem/equipment/sh_equipment.lua b/gamemode/inventorysystem/equipment/sh_equipment.lua
index 3c30df15..793eeac 100644
--- a/gamemode/inventorysystem/equipment/sh_equipment.lua
+++ b/gamemode/inventorysystem/equipment/sh_equipment.lua
@@ -4,6 +4,7 @@
local itm = nrequire("item.lua")
local ste = nrequire("utility/stream.lua")
local inventory = nrequire("inventory/inventory.lua")
+local col = nrequire("config/colortheme.lua")
print("Got invnetory table, it is:")
PrintTable(inventory)
local slots = {
@@ -77,7 +78,7 @@ end
inv.Put = function(self,position,item)
self.equiped[position[1]] = item
- if item.onEquip then item:onEquip(self.owner) end
+ if item.onEquip then item:onEquip(self.Owner) end
end
inv.Has = function(self,string_or_compare_func)
@@ -97,7 +98,7 @@ end
inv.Remove = function(self,position)
local item = self.equiped[position[1]]
- if item.onUnEquip then item:onUnEquip(self.owner) end
+ if item.onUnEquip then item:onUnEquip(self.Owner) end
self.equiped[position[1]] = nil
end
diff --git a/gamemode/inventorysystem/shapedinventory/cl_shaped.lua b/gamemode/inventorysystem/shapedinventory/cl_shaped.lua
index 3bd84c2..c40ffa0 100644
--- a/gamemode/inventorysystem/shapedinventory/cl_shaped.lua
+++ b/gamemode/inventorysystem/shapedinventory/cl_shaped.lua
@@ -1,5 +1,6 @@
local com = nrequire("cl_common.lua")
+local col = nrequire("config/colortheme.lua")
local inv = {}
@@ -8,7 +9,9 @@ local width = ScrW()
local iconsize = width / 40
local function default_paint(self,w,h)
- draw.RoundedBox( 8, 0, 0, w, h, Color( 0, 0, 0 ) )
+ --Draw a box
+ surface.SetDrawColor(col.ui.border)
+ surface.DrawOutlinedRect( 0, 0, w, h )
end
--[[
@@ -44,6 +47,7 @@ end
local function drawitemat(self,x,y,item)
print("Drawing item at ",x,y)
local tp = self.gridpanels[x][y]
+ tp:Droppable("item")
runonshape(self,item.Shape,x,y,function(panel)
panel:SetVisible(false)
end)
@@ -60,6 +64,7 @@ end
--Reset the position, using the item and it's shape
local function undrawitemat(self,x,y)
local item = self:Get({x,y})
+ self.gridpanels[x][y]:Droppable("")
runonshape(self,item.Shape,x,y,function(panel)
panel:SetVisible(true)
panel:SetSize(iconsize,iconsize)
@@ -132,10 +137,10 @@ inv.DrawOnDPanel = function(self,panel)
local dp = vgui.Create("DButton")
dp:SetSize(iconsize,iconsize)
dp.Paint = default_paint
- dp:Droppable("item")
+ --dp:Droppable("item")
dp:Receiver("item",com.generatereceiver(),{"one","two","three"})
dp.info = {}
- dp.info.owner = LocalPlayer()
+ dp.info.owner = self.Owner
dp.info.id = self.id
dp.info.pos = {x,y}
dp.info.inv = self
diff --git a/gamemode/inventorysystem/shapedinventory/sh_shaped.lua b/gamemode/inventorysystem/shapedinventory/sh_shaped.lua
index de7ccd9..00beb7f 100644
--- a/gamemode/inventorysystem/shapedinventory/sh_shaped.lua
+++ b/gamemode/inventorysystem/shapedinventory/sh_shaped.lua
@@ -24,7 +24,7 @@ local function canfitin(self,x,y,shape)
local absx,absy = x + rn - 1, y + cn - 1
local slot = calcposition(self.dimx,self.dimy,absx,absy)
print("Checking slot", slot)
- if col and ((self.tracker[slot] ~= nil) or (slot > self.dimx * self.dimy)) then
+ if col and ((self.tracker[slot] ~= nil) or (absx > self.dimx) or (absy > self.dimy)) then
return false
end
end
diff --git a/gamemode/itemsystem/armor/balaclava.lua b/gamemode/itemsystem/armor/balaclava.lua
index dd0ec83..1ea094b 100644
--- a/gamemode/itemsystem/armor/balaclava.lua
+++ b/gamemode/itemsystem/armor/balaclava.lua
@@ -11,7 +11,7 @@ item.Tooltip = "Something to cover your face"
--Required Returns the data needed to rebuild this item, should only contain the minimum data nessessary since this gets sent over the network
item.Serialize = function(self)
- print("Trying to serailize!")
+ print("Trying to Serialize!")
return ""
end
diff --git a/gamemode/itemsystem/exampleitem.lua b/gamemode/itemsystem/exampleitem.lua
index ab7dc50..a56151f 100644
--- a/gamemode/itemsystem/exampleitem.lua
+++ b/gamemode/itemsystem/exampleitem.lua
@@ -86,7 +86,7 @@ item.onUnEquip = function(self,who)
print("Aw, I'm being stored :(")
end
---Technically optional, but item will display as a rock if you don't have it. If you want to do something other than drop on dropped, remove ent.
+--Technically optional, but item will display as a rock if you don't apply a pac to it. If you want to do something other than drop on dropped, remove ent.
item.onDropped = function(self,ent)
print("I've been dropped!(BUVVV WUB WUB WUB WUB WUB)")
end
diff --git a/gamemode/itemsystem/weapons/rustyaxe.lua b/gamemode/itemsystem/weapons/rustyaxe.lua
index 04e54de..c19a24a 100644
--- a/gamemode/itemsystem/weapons/rustyaxe.lua
+++ b/gamemode/itemsystem/weapons/rustyaxe.lua
@@ -1,6 +1,12 @@
--[[
An example item
]]
+local pac
+if SERVER then
+ pac = nrequire("core/pac/sv_pac.lua")
+ print("in rustyaxe.lua, pac is", pac)
+end
+local reg = nrequire("item.lua")
local item = {}
--Required, a name, all item names must be unique
@@ -47,7 +53,7 @@ item.Shape = {
}
--Optional, If this item can be equiped in any player slots, put them here.
-item.Equipable = "Right"
+item.Equipable = "Right Hand"
local swingdata = {
["fwd"] = {
@@ -205,9 +211,10 @@ item.onEquip = function(self,who)
print("onEquip",who)
if CLIENT then print("onEquip client!") end
if SERVER then
+ print("pac is", pac)
PrintTable(pac)
who:GetActiveWeapon():SetHoldType("melee")
- ART.ApplyPAC(who,"rustyaxe")
+ pac.ApplyPac(who,"rustyaxe")
--local outfit = pac.luadata.ReadFile("pac3/mech.txt")
--who:AttachPACPart(outfit)
--print("onEquip server!")
@@ -216,14 +223,15 @@ end
--Optional, if we should do something speical on unequip(like setting animations back to normal)
item.onUnEquip = function(self,who)
+ print("Unequiping axe")
who:GetActiveWeapon():SetHoldType("normal")
- ART.RemovePAC(who,"rustyaxe")
+ if SERVER then pac.RemovePac(who,"rustyaxe") end
end
item.onDropped = function(self, ent)
- ART.ApplyPAC(ent,"rustyaxe")
+ if SERVER then pac.ApplyPac(ent,"rustyaxe") end
end
-print("Hello from scrapgun.lua")
+print("Hello from rustyaxe.lua")
--Don't forget to register the item!
-nrequire("item.lua").RegisterItem(item)
+reg.RegisterItem(item)
diff --git a/gamemode/nrequire.lua b/gamemode/nrequire.lua
index 702790c..d437a5e 100644
--- a/gamemode/nrequire.lua
+++ b/gamemode/nrequire.lua
@@ -179,12 +179,40 @@ local function doincludes()
end
end
+local function refresh(filename)
+ local filepath = scan(ntbl,filename)
+ if filepath:match("/?sv_[%w_]+%.lua$") then
+ if SERVER then
+ reqtbl[filepath] = nil
+ nrequire(filepath)
+ end
+ elseif filepath:match("/?cl_[%w_]+%.lua$") then
+ if CLIENT then
+ reqtbl[filepath] = nil
+ nrequire(filepath)
+ end
+ else
+ reqtbl[filepath] = nil
+ nrequire(filepath)
+ end
+end
+
doincludes() --Do it the first time through
+
+--Totaly refresh all files server and client side
if SERVER then util.AddNetworkString("art_refresh") end
if CLIENT then net.Receive("art_refresh",doincludes) end
-
concommand.Add("art_manualrefresh",function(ply,cmd,args)
doincludes()
net.Start("art_refresh")
net.Broadcast()
end)
+
+if SERVER then util.AddNetworkString("art_reffile") end
+if CLIENT then net.Receive("art_reffile",function() refresh(net.ReadString()) end) end
+concommand.Add("art_refreshfile", function(ply,cmd,args)
+ refresh(args[1])
+ net.Start("art_reffile")
+ net.WriteString(args[1])
+ net.Broadcast()
+end)
diff --git a/gamemode/server/sv_database.lua b/gamemode/server/sv_database.lua
index 55c5346..4a72c68 100644
--- a/gamemode/server/sv_database.lua
+++ b/gamemode/server/sv_database.lua
@@ -1,4 +1,6 @@
--One-type setup stuff
+
+do return end
print("Hello from database.lua!!")
require("mysqloo")
diff --git a/gamemode/server/sv_loadplayer.lua b/gamemode/server/sv_loadplayer.lua
index 86673a7..ee4eee6 100644
--- a/gamemode/server/sv_loadplayer.lua
+++ b/gamemode/server/sv_loadplayer.lua
@@ -1,4 +1,4 @@
-
+local sql = nrequire("core/database/sv_setup.lua")
local models = {}
for k = 1,9 do
models[#models + 1] = "models/player/Group01/male_0" .. k .. ".mdl"
@@ -7,7 +7,7 @@ end
local function delayplayerload(ply)
if ply:Alive() then
- ART.loadPlayerData(ply)
+ sql.GetPlayerData(ply)
else
timer.Simple(1,function()
delayplayerload(ply)
diff --git a/gamemode/server/sv_mapconfig.lua b/gamemode/server/sv_mapconfig.lua
index 7117a07..2448e27 100644
--- a/gamemode/server/sv_mapconfig.lua
+++ b/gamemode/server/sv_mapconfig.lua
@@ -1,5 +1,5 @@
--Loads map config form a file
-
+do return end
function ART.CreateTownie(tbl)
local npcent = ents.Create("npc_townie")
for k,v in pairs(tbl) do
diff --git a/gamemode/shared/sh_pac.lua b/gamemode/shared/sh_pac.lua
deleted file mode 100644
index 1d4da41..0000000
--- a/gamemode/shared/sh_pac.lua
+++ /dev/null
@@ -1,137 +0,0 @@
---[[
- All the functions related to networking pac's
-]]
-if CLIENT then
- local what
- local function applypac(who,pacname)
- local pactxt = file.Read("artery/pacs/"..pacname..".txt","DATA")
- print("got pac txt",pactxt)
- if pactxt == nil then
- print("requesting pac")
- net.Start("requestpac")
- net.WriteString(pacname)
- net.SendToServer()
- timer.Simple(5,function() --5 seconds is probably enough time to load a pac, right?
- print("trying to re-apply pac")
- applypac(who,pacname)
- end)
- else
- if who.AttachPACPart == nil then
- print("setting up ent for pac")
- pac.SetupENT(who)
- end
- print("pactxt was",pactxt)
- local pactbl = CompileString("return {"..pactxt.."}",pacname)()
- print("pactbl is")
- PrintTable(pactbl)
- print("who is",who)
- who:AttachPACPart(pactbl)
- print("Pac Equiped!")
-
- what = who:FindPACPart(pactbl, "ball")
- print("what was", what)
- if what ~= nil then
- print("What's position:")
- for k,v in pairs(what) do
- print(k,":",v)
- end
- print(what:GetDrawPosition(),type(what:GetDrawPosition()))
- end
- end
- end
-
- local RecordTrace = false
- local swingtime
- hook.Add("Tick","weapon_trace",function()
- if what ~= nil and ART.TraceWeapon and RecordTrace then
- local pos = what:GetDrawPosition()
- local ppos = LocalPlayer():GetPos()
- for k = 1,3 do pos[k] = pos[k] - ppos[k] end -- Now is a local vector, player is the origin
- print(string.format("{%1.3f,Vector(%d,%d,%d)},",swingtime/1000,pos[1],pos[2],pos[3]-64))
- swingtime = swingtime + util.TimerCycle()
- else
- swingtime = util.TimerCycle()
- end
- end)
-
- concommand.Add("artery_dev_traceweapons",function(ply,cmd,args)
- RecordTrace = args[1] == "1"
- end)
-
- local function removepac(who,pacname)
- local pactxt = file.Read("artery/pacs/"..pacname..".txt","DATA")
- assert(pactxt ~= nil, "Attempted to remove a pac that dosn't exist")
- assert(who.RemovePACPart ~= nil,"That entity isn't set up to have pacs!")
- local pactbl = CompileString("return {" .. pactxt .. "}", pacname)()
- who:RemovePACPart(pactbl)
- end
-
- net.Receive("loadpac",function()
- local pacname = net.ReadString()
- local pacdata = util.Decompress(net.ReadString())
- file.Write("artery/pacs/"..pacname..".txt",pacdata)
- end)
-
- net.Receive("applypac",function()
- print("apply ing pac")
- local towho = net.ReadEntity()
- local pacname = net.ReadString()
- applypac(towho,pacname)
- end)
-
- net.Receive("removepac",function()
- local towho = net.ReadEntity()
- local pacname = net.ReadString()
- removepac(towho,pacname)
- end)
-else
- for _,v in pairs({
- "applypac",
- "removepac",
- "requestpac",
- "loadpac",
- })do util.AddNetworkString(v) end
-
- net.Receive("requestpac",function(ln,ply)
- local pacname = net.ReadString()
- local pacdata = file.Read("artery/pacs/"..pacname..".txt","DATA")
- assert(pacdata ~= nil,string.format("Client %q requested pac that dosn't exist %q",ply:Nick(),pacname))
- net.Start("loadpac")
- net.WriteString(pacname)
- net.WriteString(util.Compress(pacdata))
- net.Send(ply)
- end)
-
- local playerpacs = {}
- ART.ApplyPAC = function(to,pacname)
- print("Applying pac")
- net.Start("applypac")
- net.WriteEntity(to)
- net.WriteString(pacname)
- net.Broadcast()
- playerpacs[to] = playerpacs[to] or {}
- table.insert(playerpacs[to],pacname)
- end
-
- hook.Add( "PlayerInitialSpawn", "loadpacs", function(ply)
- timer.Simple(5,function() --Wait 5 seconds, hopefully they're ok to go by then
- for k,v in pairs(playerpacs) do
- for i,j in pairs(v) do
- net.Start("applypac")
- net.WriteEntity(k)
- net.WriteString(j)
- net.Send(ply)
- end
- end
- end)
- end)
-
- ART.RemovePAC = function(to,pacname)
- net.Start("removepac")
- net.WriteEntity(to)
- net.WriteString(pacname)
- net.Broadcast()
- table.RemoveByValue(playerpacs[to], pacname)
- end
-end
-local paclist
diff --git a/gamemode/utility/svg/cl_svg.lua b/gamemode/utility/svg/cl_svg.lua
index 623c9e1..52b8556 100644
--- a/gamemode/utility/svg/cl_svg.lua
+++ b/gamemode/utility/svg/cl_svg.lua
@@ -1,5 +1,5 @@
local svg = {}
-local fn = nrequire("fn.lua")
+--local fn = nrequire("fn.lua")
local file_cache_max_size = 100
local file_cache_size = 0
local file_cache = {}
@@ -63,7 +63,7 @@ function svg.MaterialFromSVG(spath,background,foreground)
end
html:SetHTML(string.format([[
<style>%s%sbody{overflow:hidden}</style><body>%s</body>
-]],bgf,fgf,svgdata))
+]],background and bgf or "",fgf and foreground or "",svgdata))
local mat = {}
toprocess[#toprocess + 1] = {mat,html}
return mat
@@ -85,8 +85,8 @@ function svg.SvgOnDpanel(spath,background,foreground,dpanel)
local ret = {}
ret.html = vgui.Create("DHTML",dpanel)
ret.path = spath
- ret.fg = foreground
- ret.bg = background
+ ret.fg = foreground or Color(0,0,0,255)
+ ret.bg = background or Color(255,255,255,0)
ret.UpdateForeground = updatesvgfg
ret.UpdateBackground = updatesvgbg
ret.UpdateImage = updatesvgimg