From 81d3d4eb333e226432a591461b84ed12f5ac9a3f Mon Sep 17 00:00:00 2001 From: Alexander Pickering Date: Sat, 21 Jul 2018 19:08:34 -0400 Subject: Various updates * Animation api now allows sequences to be played * items now have a .inv attribute that is set when they are added to shaped or equipment inventories * Refactored the way skill inventory is structured * Added some more methods to cl_common to move items around on a player * Minor update to nrequire to display purple message when asked to include a file that dosn't exist. --- gamemode/core/animation/cl_animate.lua | 23 +++++++++++++++ gamemode/core/animation/sh_animations.lua | 20 +++++++++++++ gamemode/core/animation/sv_animate.lua | 33 ++++++++++++++++++++++ gamemode/core/inventory/cl_invtracker.lua | 3 +- gamemode/core/inventory/sv_invtracker.lua | 14 +++++++++ gamemode/core/pac/cl_pac.lua | 8 ++++-- gamemode/inventorysystem/cl_common.lua | 21 ++++++++++++++ .../inventorysystem/equipment/cl_equipment.lua | 4 +-- .../inventorysystem/equipment/sh_equipment.lua | 6 ++-- gamemode/inventorysystem/quests/cl_quests.lua | 12 -------- .../inventorysystem/shapedinventory/sh_shaped.lua | 2 ++ gamemode/inventorysystem/skills/cl_skills.lua | 13 +-------- gamemode/inventorysystem/skills/sh_skillcommon.lua | 17 +++++++++++ gamemode/inventorysystem/skills/sh_skills.lua | 12 ++++++-- gamemode/nrequire.lua | 9 +++++- 15 files changed, 161 insertions(+), 36 deletions(-) (limited to 'gamemode') diff --git a/gamemode/core/animation/cl_animate.lua b/gamemode/core/animation/cl_animate.lua index fd322a1..c7dc19d 100644 --- a/gamemode/core/animation/cl_animate.lua +++ b/gamemode/core/animation/cl_animate.lua @@ -11,3 +11,26 @@ net.Receive("art_stop_animation",function() local anim = net.ReadString() what:StopLuaAnimation(anim) end) + +local sequences = {} +net.Receive("art_start_sequence",function() + local who = net.ReadEntity() + local seq = net.ReadUInt(31) + local time = net.ReadFloat() + local untilstoped = net.ReadBool() + local speed = net.ReadFloat() + sequences[who] = sequences[who] or {} + who:SetCycle(0) + if untilstoped then + sequences[who] = {CurTime() + 9999999, seq, speed} + else + sequences[who] = {CurTime() + time, seq, speed} + end +end) + +net.Receive("art_end_sequence",function() + local who = net.ReadEntity() + sequences[who] = nil +end) + +return sequences diff --git a/gamemode/core/animation/sh_animations.lua b/gamemode/core/animation/sh_animations.lua index 3846fcc..a1430a5 100644 --- a/gamemode/core/animation/sh_animations.lua +++ b/gamemode/core/animation/sh_animations.lua @@ -2,3 +2,23 @@ if not RegisterLuaAnimation then error("JetBoom's libanimbone is required for animations. (It's bundeled with PAC3)") return end + +local sequences +local log = nrequire("log.lua") +if SERVER then + sequences = nrequire("core/animation/sv_animate.lua") +else -- CLIENT + sequences = nrequire("core/animation/cl_animate.lua") +end + +hook.Add("UpdateAnimation","art_updateanim",function(ply,vel,mgs) + if sequences and ply and sequences[ply] and CurTime() < sequences[ply][1] then + ply:SetPlaybackRate(sequences[ply][3]) + end +end) + +hook.Add("CalcMainActivity","art_swing",function(ply,vel) + if sequences and ply and sequences[ply] and CurTime() < sequences[ply][1] then + return -1, sequences[ply][2] + end +end) diff --git a/gamemode/core/animation/sv_animate.lua b/gamemode/core/animation/sv_animate.lua index 24d0ed0..b8cec56 100644 --- a/gamemode/core/animation/sv_animate.lua +++ b/gamemode/core/animation/sv_animate.lua @@ -5,6 +5,8 @@ local meta = FindMetaTable("Player") util.AddNetworkString("art_start_animation") util.AddNetworkString("art_stop_animation") +util.AddNetworkString("art_start_sequence") +util.AddNetworkString("art_end_sequence") function meta:StartAnimation(name) net.Start("art_start_animation") @@ -19,3 +21,34 @@ function meta:StopAnimation(name) net.WriteString(name) net.Broadcast() end + +local sequences = {} + +function meta:StartSequence(name,untilstoped,speed) + untilstoped = untilstoped or false + speed = speed or 1 + local seq, time = self:LookupSequence(name) + sequences[self] = sequences[self] or {} + if untilstoped then + sequences[self] = {CurTime() + 9999999, seq, speed} + else + sequences[self] = {CurTime() + time, seq, speed} + end + self:SetCycle(0) + net.Start("art_start_sequence") + net.WriteEntity(self) + net.WriteUInt(seq,31) + net.WriteFloat(time) + net.WriteBool(untilstoped) + net.WriteFloat(speed) + net.Broadcast() +end + +function meta:EndSequence(name) + sequences[self] = nil + net.Start("art_end_sequence") + net.WriteEntity(self) + net.Broadcast() +end + +return sequences diff --git a/gamemode/core/inventory/cl_invtracker.lua b/gamemode/core/inventory/cl_invtracker.lua index dac1cc2..e6633f9 100644 --- a/gamemode/core/inventory/cl_invtracker.lua +++ b/gamemode/core/inventory/cl_invtracker.lua @@ -4,7 +4,7 @@ local inv = nrequire("inventory/inventory.lua") local itm = nrequire("item.lua") -nrequire("cl_loadglobals.lua") +-- nrequire("cl_loadglobals.lua") --local state = nrequire("cl_state.lua") local q = {} @@ -98,6 +98,7 @@ net.Receive("art_UpdateInventory",function() local item_data = net.ReadData(net.ReadUInt(32)) local item = itm.GetItemFromData(item_name,item_data) known_inventories[id]:Put(position,item) + item.inv = known_inventories[id] --print("Inventorie's observers:") --PrintTable(known_inventories[id].observers) --print("Inventory is now") diff --git a/gamemode/core/inventory/sv_invtracker.lua b/gamemode/core/inventory/sv_invtracker.lua index ed5da4a..b6f6b52 100644 --- a/gamemode/core/inventory/sv_invtracker.lua +++ b/gamemode/core/inventory/sv_invtracker.lua @@ -223,6 +223,20 @@ function plymeta:HasItem(ptr) return false end +--- Gets a refrence to an item without removeing it +-- Gets an item, if you want to look at the fields without changing them. +-- If you do need to change fields, remove the item, change the field, then +-- re-give the item. +--@metamethod player:GetItem(loc) +--@tparam table loc The position of the item (returned by plymeta:HasItem()) +--@treturn itemtbl The item at the location +function plymeta:GetItem(loc) + local nid = loc[1] + local pos = loc[2] + local item = self.data.inventories[nid]:Get(pos) + return item +end + ---A shortcut to remove an item from a player. -- Removes an item from a player and returns the item --@metamethod player:RemoveItem(tbl) diff --git a/gamemode/core/pac/cl_pac.lua b/gamemode/core/pac/cl_pac.lua index 477d65d..69e993a 100644 --- a/gamemode/core/pac/cl_pac.lua +++ b/gamemode/core/pac/cl_pac.lua @@ -1,4 +1,5 @@ +local log = nrequire("log.lua") --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. @@ -42,12 +43,12 @@ local function loadpac(ent,name,hash) return end end - if filetext and (tonumber(util.CRC(filetext)) == hash) then + if filetext and tonumber(util.CRC(filetext)) then print("The file on our local system is up to date, applying!") local pactbl = CompileString(string.format("return {%s}",filetext),name)() ent:AttachPACPart(pactbl) else--Cache is old, download the new pac! - print("The file on our local system was out of date! Downloading...") + log.debug(string.format("File out of date (%d vs %d) Re-downloading...", filetext and tonumber(util.CRC(filetext)) or 0 , hash)) net.Start("artery_requestpac") net.WriteString(name) net.SendToServer() @@ -68,7 +69,8 @@ end net.Receive("artery_downloadpac",function() local pac_name = net.ReadString() local pac_txt = net.ReadString() - --local pac_hash = net.ReadUInt(32) + local pac_hash = net.ReadUInt(32) + log.debug(string.format("Received file %s with hash %d", pac_name, pac_hash)) local filepath = string.format(CLIENT_PAC_DIR .. "/%s.txt",pac_name) file.Write(filepath,pac_txt) end) diff --git a/gamemode/inventorysystem/cl_common.lua b/gamemode/inventorysystem/cl_common.lua index 559c8f0..bf9fb6f 100644 --- a/gamemode/inventorysystem/cl_common.lua +++ b/gamemode/inventorysystem/cl_common.lua @@ -2,6 +2,7 @@ A bunch of functions that a lot of inventories have in common, dragged out here so bugfixing is easier ]] +local log = nrequire("log.lua") local com = {} --Displays a dropdown of options under the players mouse, if the option is clicked, does the function @@ -20,6 +21,26 @@ function com.CreateMenuFor(menu, tbl) end end +-- Move an item internally between two inventories +function com.MoveItem(f,frominv,toinv) + local frompos = frominv:Has(f) + assert(frompos,string.format("Failed to find item %q in inventory %q",tostring(f),frominv.Name)) + log.debug("Returned position:" .. frompos[1]) + local item = frominv:Get(frompos) + assert(item,string.format("Failed to get item %q out of %q",tostring(f),frominv.Name)) + local topos = toinv:FindPlaceFor(item) + assert(topos,string.format("Failed to find a place in %q to put a %q",toinv.Name,tostring(f))) + + net.Start("art_RequestInvMove") + net.WriteEntity(LocalPlayer()) + net.WriteEntity(LocalPlayer()) + net.WriteUInt(frominv.id,32) + net.WriteUInt(toinv.id,32) + net.WriteTable(frompos) + net.WriteTable(topos) + net.SendToServer() +end + function com.generatereceiver() return function(self,panels,dropped,index,cx,cy) if dropped then diff --git a/gamemode/inventorysystem/equipment/cl_equipment.lua b/gamemode/inventorysystem/equipment/cl_equipment.lua index 8d06594..58fc3f9 100644 --- a/gamemode/inventorysystem/equipment/cl_equipment.lua +++ b/gamemode/inventorysystem/equipment/cl_equipment.lua @@ -118,7 +118,7 @@ inv.DrawOnDPanel = function(self,panel) if self.equiped[k].GetOptions then pn.DoClick = function() local dm = DermaMenu() - com.CreateMenuFor(dm,self.equiped[k].GetOptions()) + com.CreateMenuFor(dm,self.equiped[k]:GetOptions()) dm:Open() end end @@ -153,7 +153,7 @@ inv.DrawOnDPanel = function(self,panel) if item.GetOptions then self[position[1]].DoClick = function() local dm = DermaMenu() - com.CreateMenuFor(dm,item.GetOptions()) + com.CreateMenuFor(dm,item:GetOptions()) dm:Open() end end diff --git a/gamemode/inventorysystem/equipment/sh_equipment.lua b/gamemode/inventorysystem/equipment/sh_equipment.lua index b27dd08..a9b6f83 100644 --- a/gamemode/inventorysystem/equipment/sh_equipment.lua +++ b/gamemode/inventorysystem/equipment/sh_equipment.lua @@ -77,17 +77,18 @@ end inv.Put = function(self,position,item) self.equiped[position[1]] = item if item.onEquip then item:onEquip(self.Owner) end + item.inv = self end inv.Has = function(self,string_or_compare_func) if type(string_or_compare_func) == "string" then for k,v in pairs(self.equiped) do - if v.Name == string_or_compare_func then return k end + if v.Name == string_or_compare_func then return {k} end end return nil elseif type(string_or_compare_func) == "function" then for k,v in pairs(self.equiped) do - if string_or_compare_func(v.Name) then return k end + if string_or_compare_func(v.Name) then return {k} end end return nil end @@ -99,6 +100,7 @@ inv.Remove = function(self,position) if not item then return end --Make sure we'r enot dragging an empty space if item.onUnEquip then item:onUnEquip(self.Owner) end self.equiped[position[1]] = nil + item.inv = nil end inv.Get = function(self,position) diff --git a/gamemode/inventorysystem/quests/cl_quests.lua b/gamemode/inventorysystem/quests/cl_quests.lua index 9ad8eb1..e485109 100644 --- a/gamemode/inventorysystem/quests/cl_quests.lua +++ b/gamemode/inventorysystem/quests/cl_quests.lua @@ -23,19 +23,10 @@ local hh = (scrh - 100) / 2 inv.DrawOnDPanel = function(self,panel) local spanel = vgui.Create("DPanel", panel) spanel:Dock(FILL) - function spanel:Paint(w,h) - draw.RoundedBox( 8, 0, 0, w, h, Color( 255, 0, 0 ) ) - end local qls = vgui.Create("DScrollPanel", spanel) - function qls:Paint(w,h) - draw.RoundedBox( 8, 0, 0, w, h, Color( 0, 255, 0 ) ) - end qls:SetSize((scrw/4) - 40, hh) inv.qls = qls local sls = vgui.Create("DScrollPanel", spanel) - function sls:Paint(w,h) - draw.RoundedBox( 8, 0, 0, w, h, Color( 0, 0, 255 ) ) - end sls:SetSize((scrw/4) - 40, hh) sls:SetPos(0,hh) inv.sls = sls @@ -43,9 +34,6 @@ inv.DrawOnDPanel = function(self,panel) questlist:SetCols(4) questlist:SetColWide(((scrw/4) - 40) /4) questlist:SetSize((scrw/4) - 50, hh) - function questlist:Paint(w,h) - draw.RoundedBox( 8, 0, 0, w, h, Color( 0, 255, 255 ) ) - end inv.questlist = questlist inv.questlog = questlog questlog = vgui.Create("DLabel", sls) diff --git a/gamemode/inventorysystem/shapedinventory/sh_shaped.lua b/gamemode/inventorysystem/shapedinventory/sh_shaped.lua index 42edaa6..1e87e42 100644 --- a/gamemode/inventorysystem/shapedinventory/sh_shaped.lua +++ b/gamemode/inventorysystem/shapedinventory/sh_shaped.lua @@ -66,6 +66,7 @@ function inv:Put(tbl,item) --Now set the item in the correct slot local slot = calcposition(self.width,self.height,tbl[1],tbl[2]) self.tracker[slot] = item + item.inv = self end function inv:Has(ptr) @@ -97,6 +98,7 @@ function inv:Remove(tbl) end end end + item.inv = nil return item end diff --git a/gamemode/inventorysystem/skills/cl_skills.lua b/gamemode/inventorysystem/skills/cl_skills.lua index 31d4470..b5e4620 100644 --- a/gamemode/inventorysystem/skills/cl_skills.lua +++ b/gamemode/inventorysystem/skills/cl_skills.lua @@ -4,19 +4,8 @@ local sc = nrequire("sh_skillcommon.lua") --the gui elements local elements = {} ---return level, frac -local xpmult = 1.5 --the lower, the more lvl per xp -local levelfunc = function(val) - local curlvl = math.log(val,xpmult) - local prevlvlxp = xpmult ^ math.floor(curlvl) - local nextlvlxp = xpmult ^ (math.floor(curlvl) + 1) - local sp = nextlvlxp - prevlvlxp - local frac = (val - prevlvlxp) / ((sp ~= 0) and sp or 1) --don't divide by 0 - return math.floor(curlvl), frac -end - local set_xp_of = function(name,ammt) - local lvl,frac = levelfunc(ammt) + local lvl,frac = sc.levelfunc(ammt) elements[name].label:SetText(string.format("%s : %d (%2.5f%%)",name,lvl,frac)) elements[name].bar:SetFraction(frac) end diff --git a/gamemode/inventorysystem/skills/sh_skillcommon.lua b/gamemode/inventorysystem/skills/sh_skillcommon.lua index 9c022eb..e0db95a 100644 --- a/gamemode/inventorysystem/skills/sh_skillcommon.lua +++ b/gamemode/inventorysystem/skills/sh_skillcommon.lua @@ -73,4 +73,21 @@ function lib.SkillList() return skills end +local xpmult = 1.5 --the lower, the more lvl per xp +function lib.levelfunc(val) + local curlvl = math.log(val,xpmult) + local prevlvlxp = xpmult ^ math.floor(curlvl) + local nextlvlxp = xpmult ^ (math.floor(curlvl) + 1) + local sp = nextlvlxp - prevlvlxp + local frac = (val - prevlvlxp) / ((sp ~= 0) and sp or 1) --don't divide by 0 + return math.floor(curlvl), frac +end + +function pmeta:GetSkill(name) + local loc = self:HasItem(name) + if not loc then return 0 end + local item = self:GetItem(loc) + return lib.levelfunc(item.ammt) +end + return lib diff --git a/gamemode/inventorysystem/skills/sh_skills.lua b/gamemode/inventorysystem/skills/sh_skills.lua index 3c212bf..43137a8 100644 --- a/gamemode/inventorysystem/skills/sh_skills.lua +++ b/gamemode/inventorysystem/skills/sh_skills.lua @@ -117,10 +117,13 @@ end inv.Has = function(self,string_or_compare_func) local socf = string_or_compare_func if type(socf) == "string" and self.skills[socf] then - return self.skills[socf] + return {socf} elseif type(socf) == "function" then + local fi = {} for k,v in pairs(self.skills) do - if socf(v) then return k end + fi.name = k + fi.ammt = v + if socf(fi) then return {k} end end else return nil @@ -132,7 +135,10 @@ inv.Remove = function(self,position) end inv.Get = function(self,position) - return self.skills[position[1]] + local fi = {} + fi.name = position[1] + fi.ammt = self.skills[position[1]] + return fi end inv.Serialize = function(self) diff --git a/gamemode/nrequire.lua b/gamemode/nrequire.lua index af066f0..7be9772 100644 --- a/gamemode/nrequire.lua +++ b/gamemode/nrequire.lua @@ -127,6 +127,10 @@ function nrequire(req,...) else tpath = scan(ntbl,req) end + if tpath == nil then + MsgC(Color(209,96,196), "Unable to find file for include:" .. req) + error(debug.traceback()) + end -- local tpath = scan(ntbl,req) -- Find the full path for the nrequired() module local trace = debug.getinfo(2,"flnSu") @@ -372,7 +376,7 @@ else net.Receive("art_downloadfiles",function(ln,pl) local clientfiles = net.ReadTable() local todownload = {} - + local needs_restart = false for k,v in pairs(clientfiles) do local fullpath = "artery/client/" .. v.directory .. "/" .. v.name .. ".txt" if not file.Exists(fullpath,"DATA") then @@ -381,12 +385,14 @@ else directory = v.directory } todownload[#todownload + 1] = thisdownload + needs_restart = true elseif util.CRC(file.Read(fullpath,"DATA")) ~= v.hash then local thisdownload = { name = v.name, directory = v.directory } todownload[#todownload + 1] = thisdownload + needs_restart = true -- else file is up to date and dosn't need re-downloading. end end @@ -413,6 +419,7 @@ else file.CreateDir(path) print("Writing to ", fullpath) file.Write(fullpath,tbl.text) + timer.Simple(10,function() RunConsoleCommand("retry") end) end) net.Receive("artery_downloadfile",function(ln,pl) -- cgit v1.2.3-70-g09d2