Fixed: Workshop ID utilizing number value overflow

Fixed: Some drawing methods not having a draw method
Added: Extension `Anyone's Horrible Trackpack` tracks
Updated: TWEAK_PANEL action
This commit is contained in:
Deyan Dobromirov 2021-01-07 14:16:10 +02:00
parent 709ff5f2f1
commit 0e5566b014
5 changed files with 459 additions and 42 deletions

View File

@ -0,0 +1,366 @@
--[[
* The purpose of this Lua file is to add your track pack pieces to the
* track assembly tool, so they can appear in the tool selection menu.
* Why the name starts with /z/ you may ask. When Gmod loads the game
* it goes trough all the Lua addons alphabetically.
* That means your file name ( The file you are reading right now )
* must be greater alphabetically than /trackasmlib/, so the API of the
* module can be loaded before you can use it like seen below.
]]--
-- Local reference to the module.
local asmlib = trackasmlib
-- Change this to your addon name.
local myAddon = "Anyone's Horrible Trackpack" -- Your addon name goes here
--[[
* Change this if you want to use different in-game type
* You can also use multiple types myType1, myType2,
* myType3, ... myType/n when your addon contains
* multiple model packs.
]]--
local myType = myAddon -- The type your addon resides in the tool with
--[[
* For actually produce an error you can replace the /print/
* statement with one of following API calls:
* http://wiki.garrysmod.com/page/Global/error
* http://wiki.garrysmod.com/page/Global/Error
* http://wiki.garrysmod.com/page/Global/ErrorNoHalt
]]
local myError = ErrorNoHalt
-- This is used for addon relation prefix. Fingers away from it
local myPrefix = myAddon:gsub("[^%w]","_") -- Addon prefix
-- This is the script path. It tells TA who wants to add these models
-- Do not touch this also, it is used for debugging
local myScript = tostring(debug.getinfo(1).source or "N/A")
myScript = "@"..myScript:gsub("^%W+", ""):gsub("\\","/")
--[[
* This function defines what happens when there is an error present
* Usually you can tell Gmod that you want it to generate an error
* and throw the message to the log also. In this case you will not
* have to change the function name in lots of places
* when you need it to do something else.
--]]
local function myThrowError(vMesg)
local sMesg = tostring(vMesg) -- Make sure the message is string
if(asmlib) then asmlib.LogInstance(sMesg) end -- Output the message into the logs
myError(myScript.." > ("..myAddon.."): "..sMesg) -- Generate an error in the console ( optional )
end
if(asmlib) then
-- Store a reference to disable symbol
local gsMissDB = asmlib.GetOpVar("MISS_NOSQL")
local gsToolPF = asmlib.GetOpVar("TOOLNAME_PU")
local gsSymOff = asmlib.GetOpVar("OPSYM_DISABLE")
local gsFormPF = asmlib.GetOpVar("FORM_PREFIXDSV")
-- This is the path to your DSV
local myDsv = asmlib.GetOpVar("DIRPATH_BAS")..
asmlib.GetOpVar("DIRPATH_DSV")..
gsFormPF:format(myPrefix, gsToolPF.."PIECES")
--[[
* This flag is used when the track pieces list needs to be processed.
* It generally represents the locking file persistence flag. It is
* bound to finding a "PIECES" DSV external database for the prefix
* of your addon. You can use it for boolean value deciding whenever
* or not to run certain events. For example you can stop exporting
* your local database every time Gmod loads, but then the user will
* skip the available updates of your addon until he/she deletes the DSVs.
]]--
local myFlag = file.Exists(myDsv, "DATA")
-- Tell TA what custom script we just called don't touch it
asmlib.LogInstance(">>> "..myScript.." ("..tostring(myFlag).."): {"..myAddon..", "..myPrefix.."}")
--[[
* Register the addon to the auto-load prefix list when the
* PIECES file is missing. The auto-load list is located in
* (/garrysmod/data/trackassembly/trackasmlib_dsv.txt)
* a.k.a the DATA folder of Garry's mod.
*
* @bSuccess = RegisterDSV(sProg, sPref, sDelim)
* sProg > The program which registered the DSV
* sPref > The external data prefix to be added ( default instance prefix )
* sDelim > The delimiter to be used for processing ( default tab )
* bSkip > Skip addition for the DSV prefix if exists ( default `false` )
]]--
asmlib.LogInstance("RegisterDSV start <"..myPrefix..">")
if(myFlag) then -- Your DSV must be registered only once when loading for the first time
asmlib.LogInstance("RegisterDSV skip <"..myPrefix..">")
else -- If the locking file is not located that means this is the first run of your script
if(not asmlib.RegisterDSV(myScript, myPrefix)) then -- Register the DSV prefix and check for error
myThrowError("Failed to register DSV") -- Throw the error if fails
end -- Third argument is the delimiter. The default tab is used
asmlib.LogInstance("RegisterDSV done <"..myPrefix..">")
end
--[[
* This is used if you want to make internal categories for your addon
* You must make a function as a string under the hash of your addon
* The function must take only one argument and that is the model
* For every sub-category of your track pieces, you must return a table
* with that much elements or return a /nil/ value to add the piece to
* the root of your branch. You can also return a second value if you
* want to override the track piece name. If you need to use categories
* for multiple track types, just put their hashes in the table below
* and make every track point to its dedicated category handler.
]]--
local myCategory = {
[myType] = {Txt = [[
function(m) local c
local r = m:gsub("anytracks/", "")
if(r:find("straight")) then c = "straight"
elseif(r:find("curve")) then c = "curve"
elseif(r:find("%dx")) then c = "straight"
end; c = (c and c:gsub("^%l", string.upper) or nil) return c end
]]}
}
--[[
* This logic statement is needed for reporting the error in the console if the
* process fails.
*
@ bSuccess = ExportCategory(nInd, tData, sPref)
* nInd > The index equal indent format to be stored with ( generally = 3 )
* tData > The category functional definition you want to use to divide your stuff with
* sPref > An export file custom prefix. For synchronizing
* it must be related to your addon ( default is instance prefix )
]]--
asmlib.LogInstance("ExportCategory start <"..myPrefix..">")
if(CLIENT) then -- Category handling is client side only
if(not asmlib.IsEmpty(myCategory)) then
if(not asmlib.ExportCategory(3, myCategory, myPrefix)) then
myThrowError("Failed to synchronize category")
end; asmlib.LogInstance("ExportCategory done <"..myPrefix..">")
else asmlib.LogInstance("ExportCategory skip <"..myPrefix..">") end
else asmlib.LogInstance("ExportCategory server <"..myPrefix..">") end
--[[
* Create a table and populate it as shown below
* In the square brackets goes your MODEL,
* and then for every active point, you must have one array of
* strings, where the elements match the following data settings.
* You can use the disable event /#/ to make TA auto-fill
* the value provided and you can also add multiple track types myType[1-n].
* If you need to use piece origin/angle with model attachment, you must use
* the attachment extraction event /!/. The model attachment format is
* /!<attachment_name>/ and it depends what attachment name you gave it when you
* created the model. If you need TA to extract the origin/angle from an attachment named
* /test/ for example, you just need to put the string /!test/ in the origin/angle column for that model.
* {MODEL, TYPE, NAME, LINEID, POINT, ORIGIN, ANGLE, CLASS}
* MODEL > This string contains the path to your /*.mdl/ file. It is mandatory and
* taken in pairs with LINEID, it forms the unique identifier of every record.
* When used in /DSV/ mode ( like seen below ) is is used as a hash index.
* TYPE > This string is the name of the type your stuff will reside in the panel.
* Disabling this, makes it use the value of the /DEFAULT_TYPE/ variable.
* If it is empty uses the string /TYPE/, so make sure you fill this.
* NAME > This is the name of your track piece. Put /#/ here to be auto-generated from
* the model ( from the last slash to the file extension ).
* LINEID > This is the ID of the point that can be selected for building. They must be
* sequential and mandatory. If provided, the ID must the same as the row index under
* a given model key. Disabling this, makes it use the the index of the current line.
* Use that to swap the active points around by only moving the desired row up or down.
* For the example table definition below, the line ID in the database will be the same.
* POINT > This is the local position vector that TA searches and selects the related
* ORIGIN for. An empty string is treated as taking the ORIGIN.
* Disabling this using the disable event makes it hidden when the active point is searched for
* ORIGIN > This is the origin relative to which the next track piece position is calculated
* An empty string is treated as {0,0,0}. Disabling this makes it non-selectable by the holder
* You can also fill it with attachment event /!/ followed by your attachment name.
* ANGLE > This is the angle relative to which the forward and up vectors are calculated.
* An empty string is treated as {0,0,0}. Disabling this also makes it use {0,0,0}
* You can also fill it with attachment event /!/ followed by your attachment name.
* CLASS > This string is populated up when your entity class is not /prop_physics/ but something else
* used by ents.Create of the gmod ents API library. Keep this empty if your stuff is a normal prop.
]]--
local myPieces = {
["models/anytracks/straight/hs_1024.mdl"] = {
{myType, "Hs 1024", gsSymOff, gsMissDB, "0,512,4", "0,90,0", gsMissDB},
{myType, "Hs 1024", gsSymOff, gsMissDB, "0,-512,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/hs_128.mdl"] = {
{myType, "Hs 128", gsSymOff, gsMissDB, "0,64,4", "0,90,0", gsMissDB},
{myType, "Hs 128", gsSymOff, gsMissDB, "0,-64,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/hs_2048.mdl"] = {
{myType, "Hs 2048", gsSymOff, gsMissDB, "0,1024,4", "0,90,0", gsMissDB},
{myType, "Hs 2048", gsSymOff, gsMissDB, "0,-1024,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/hs_256.mdl"] = {
{myType, "Hs 256", gsSymOff, gsMissDB, "0,128,4", "0,90,0", gsMissDB},
{myType, "Hs 256", gsSymOff, gsMissDB, "0,-128,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/hs_32.mdl"] = {
{myType, "Hs 32", gsSymOff, "30,0,4", "0,16,4", "0,90,0", gsMissDB},
{myType, "Hs 32", gsSymOff, "-30,0,4", "0,-16,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/hs_4096.mdl"] = {
{myType, "Hs 4096", gsSymOff, gsMissDB, "0,2048,4", "0,90,0", gsMissDB},
{myType, "Hs 4096", gsSymOff, gsMissDB, "0,-2048,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/hs_512.mdl"] = {
{myType, "Hs 512", gsSymOff, gsMissDB, "0,256,4", "0,90,0", gsMissDB},
{myType, "Hs 512", gsSymOff, gsMissDB, "0,-256,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/hs_64.mdl"] = {
{myType, "Hs 64", gsSymOff, gsMissDB, "0,32,4", "0,90,0", gsMissDB},
{myType, "Hs 64", gsSymOff, gsMissDB, "0,-32,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/hs_8192.mdl"] = {
{myType, "Hs 8192", gsSymOff, gsMissDB, "0,4096,4", "0,90,0", gsMissDB},
{myType, "Hs 8192", gsSymOff, gsMissDB, "0,-4096,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/s_1024.mdl"] = {
{myType, "S 1024", gsSymOff, gsMissDB, "0,512,4", "0,90,0", gsMissDB},
{myType, "S 1024", gsSymOff, gsMissDB, "0,-512,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/s_128.mdl"] = {
{myType, "S 128", gsSymOff, gsMissDB, "0,64,4", "0,90,0", gsMissDB},
{myType, "S 128", gsSymOff, gsMissDB, "0,-64,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/s_2048.mdl"] = {
{myType, "S 2048", gsSymOff, gsMissDB, "0,1024,4", "0,90,0", gsMissDB},
{myType, "S 2048", gsSymOff, gsMissDB, "0,-1024,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/s_256.mdl"] = {
{myType, "S 256", gsSymOff, gsMissDB, "0,128,4", "0,90,0", gsMissDB},
{myType, "S 256", gsSymOff, gsMissDB, "0,-128,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/s_32.mdl"] = {
{myType, "S 32", gsSymOff, "30,0,4", "0,16,4", "0,90,0", gsMissDB},
{myType, "S 32", gsSymOff, "-30,0,4", "0,-16,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/s_4096.mdl"] = {
{myType, "S 4096", gsSymOff, gsMissDB, "0,2048,4", "0,90,0", gsMissDB},
{myType, "S 4096", gsSymOff, gsMissDB, "0,-2048,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/s_512.mdl"] = {
{myType, "S 512", gsSymOff, gsMissDB, "0,256,4", "0,90,0", gsMissDB},
{myType, "S 512", gsSymOff, gsMissDB, "0,-256,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/s_64.mdl"] = {
{myType, "S 64", gsSymOff, gsMissDB, "0,32,4", "0,90,0", gsMissDB},
{myType, "S 64", gsSymOff, gsMissDB, "0,-32,4", "0,-90,0", gsMissDB}
},
["models/anytracks/straight/s_8192.mdl"] = {
{myType, "S 8192", gsSymOff, gsMissDB, "0,4096,4", "0,90,0", gsMissDB},
{myType, "S 8192", gsSymOff, gsMissDB, "0,-4096,4", "0,-90,0", gsMissDB}
}
}
--[[
* This logic statement is needed for reporting the error in the console if the
* process fails.
*
@ bSuccess = SynchronizeDSV(sTable, tData, bRepl, sPref, sDelim)
* sTable > The table you want to sync
* tData > A data table like the one described above
* bRepl > If set to /true/, makes the API replace the repeating models with
these of your addon. This is nice when you are constantly updating your track packs
If set to /false/ keeps the current model in the
database and ignores yours if they are the same file.
* sPref > An export file custom prefix. For synchronizing it must be related to your addon
* sDelim > The delimiter used by the server/client ( default is a tab symbol )
*
@ bSuccess = TranslateDSV(sTable, sPref, sDelim)
* sTable > The table you want to translate to Lua script
* sPref > An export file custom prefix. For synchronizing it must be related to your addon
* sDelim > The delimiter used by the server/client ( default is a tab symbol )
]]--
if(not asmlib.IsEmpty(myPieces)) then
asmlib.LogInstance("SynchronizeDSV start <"..myPrefix..">")
if(not asmlib.SynchronizeDSV("PIECES", myPieces, true, myPrefix)) then
myThrowError("Failed to synchronize track pieces")
else -- You are saving me from all the work for manually generating these
asmlib.LogInstance("TranslateDSV start <"..myPrefix..">")
if(not asmlib.TranslateDSV("PIECES", myPrefix)) then
myThrowError("Failed to translate DSV into Lua") end
asmlib.LogInstance("TranslateDSV done <"..myPrefix..">")
end -- Now we have Lua inserts and DSV
end
--[[
* Create a table and populate it as shown below
* In the square brackets goes your MODELBASE,
* and then for every active point, you must have one array of
* strings and numbers, where the elements match the following data settings.
* {MODELBASE, MODELADD, ENTCLASS, LINEID, POSOFF, ANGOFF, MOVETYPE, PHYSINIT, DRSHADOW, PHMOTION, PHYSLEEP, SETSOLID}
* MODELBASE > This string contains the path to your base /*.mdl/ file the additions are gonna be attached to.
* It is mandatory and taken in pairs with LINEID, it forms the unique identifier of every record.
* When used in /DSV/ mode ( like seen below ) is is used as a hash index.
* MODELADD > This is the /*.mdl/ path of the addition entity. It is mandatory and cannot be disabled.
* ENTCLASS > This is the class of the addition entity. It is mandatory and cannot be disabled.
* LINEID > This is the ID of the point that can be selected for building. They must be
* sequential and mandatory. If provided, the ID must the same as the row index under
* a given model key. Disabling this, makes it use the the index of the current line.
* Use that to swap the active points around by only moving the desired row up or down.
* For the example table definition below, the line ID in the database will be the same.
* POSOFF > This is the local position vector offset that TA uses to place the addition relative to MODELBASE.
* A NULL, empty, disabled or not available string is treated as taking {0,0,0}.
* ANGOFF > This is the local angle offset that TA uses to place the addition.
* A NULL, empty, disabled or not available string is treated as taking {0,0,0}.
* MOVETYPE > This internally calls /Entity:SetMoveType/ if the database parameter is zero or greater.
* PHYSINIT > This internally calls /Entity:PhysicsInit/ if the database parameter is zero or greater.
* DRSHADOW > This internally calls /Entity:DrawShadow/ if the database parameter is not zero.
* The call evaluates to /true/ for positive numbers and /false/ for negative.
* When the parameter is equal to zero skips the call of /Entity:DrawShadow/
* PHMOTION > This internally calls /PhysObj:EnableMotion/ if the database parameter is not zero on the validated physics object.
* The call evaluates to /true/ for positive numbers and /false/ for negative.
* When the parameter is equal to zero skips the call of /Entity:EnableMotion/
* PHYSLEEP > This internally calls /PhysObj:Sleep/ if the database parameter is grater than zero on the validated physics object.
* When the parameter is equal or less than zero skips the call of /Entity:Sleep/
* SETSOLID > This internally calls /Entity:SetSolid/ if the database parameter is zero or greater.
]]--
local myAdditions = {}
if(not asmlib.IsEmpty(myAdditions)) then
asmlib.LogInstance("SynchronizeDSV start <"..myPrefix..">")
if(not asmlib.SynchronizeDSV("ADDITIONS", myAdditions, true, myPrefix)) then
myThrowError("Failed to synchronize track additions")
else -- You are saving me from all the work for manually generating these
asmlib.LogInstance("TranslateDSV start <"..myPrefix..">")
if(not asmlib.TranslateDSV("ADDITIONS", myPrefix)) then
myThrowError("Failed to translate DSV into Lua") end
asmlib.LogInstance("TranslateDSV done <"..myPrefix..">")
end -- Now we have Lua inserts and DSV
end
--[[
* Create a table and populate it as shown below
* In the square brackets goes your TYPE,
* and then for every active point, you must have one array of
* strings and numbers, where the elements match the following data settings.
* {TYPE, LINEID, NAME}
* TYPE > This is the category under your physical properties are stored internally.
* It is mandatory and taken in pairs with LINEID, it forms the unique identifier of every record.
* When used in /DSV/ mode ( like seen below ) is is used as a hash index.
* LINEID > This is the ID of the point that can be selected for building. They must be
* sequential and mandatory. If provided, the ID must the same as the row index under
* a given model key. Disabling this, makes it use the the index of the current line.
* Use that to swap the active points around by only moving the desired row up or down.
* For the example table definition below, the line ID in the database will be the same.
* NAME > This stores the name of the physical property. It must an actual physical property.
]]--
local myPhysproperties = {}
if(not asmlib.IsEmpty(myPhysproperties)) then
asmlib.LogInstance("SynchronizeDSV start <"..myPrefix..">")
if(not asmlib.SynchronizeDSV("PHYSPROPERTIES", myPhysproperties, true, myPrefix)) then
myThrowError("Failed to synchronize track additions")
else -- You are saving me from all the work for manually generating these
asmlib.LogInstance("TranslateDSV start <"..myPrefix..">")
if(not asmlib.TranslateDSV("PHYSPROPERTIES", myPrefix)) then
myThrowError("Failed to translate DSV into Lua") end
asmlib.LogInstance("TranslateDSV done <"..myPrefix..">")
end -- Now we have Lua inserts and DSV
end
asmlib.LogInstance("<<< "..myScript)
else
myThrowError("Failed loading the required module")
end

View File

@ -57,6 +57,7 @@ local fileTime = file and file.Time
local fileSize = file and file.Size
local fileOpen = file and file.Open
local hookAdd = hook and hook.Add
local hookRemove = hook and hook.Remove
local timerSimple = timer and timer.Simple
local inputIsKeyDown = input and input.IsKeyDown
local inputIsMouseDown = input and input.IsMouseDown
@ -87,7 +88,7 @@ local gtInitLogs = {"*Init", false, 0}
------------ CONFIGURE ASMLIB ------------
asmlib.InitBase("track","assembly")
asmlib.SetOpVar("TOOL_VERSION","8.634")
asmlib.SetOpVar("TOOL_VERSION","8.637")
asmlib.SetIndexes("V" , "x", "y", "z")
asmlib.SetIndexes("A" ,"pitch","yaw","roll")
asmlib.SetIndexes("WV",1,2,3)
@ -465,26 +466,27 @@ if(CLIENT) then
asmlib.ToIcon("bnderrmod_error" , "shape_square_error")
-- Workshop matching crap
asmlib.WorkshopID("SligWolf's Rerailers" , 132843280)
asmlib.WorkshopID("SligWolf's Minitrains" , 149759773)
asmlib.WorkshopID("SProps" , 173482196)
asmlib.WorkshopID("Magnum's Rails" , 290130567)
asmlib.WorkshopID("SligWolf's Railcar" , 173717507)
asmlib.WorkshopID("Random Bridges" , 343061215)
asmlib.WorkshopID("StevenTechno's Buildings 1.0", 331192490)
asmlib.WorkshopID("Mr.Train's M-Gauge" , 517442747)
asmlib.WorkshopID("Mr.Train's G-Gauge" , 590574800)
asmlib.WorkshopID("Bobster's two feet rails" , 489114511)
asmlib.WorkshopID("G Scale Track Pack" , 718239260)
asmlib.WorkshopID("Ron's Minitrain Props" , 728833183)
asmlib.WorkshopID("SligWolf's White Rails" , 147812851)
asmlib.WorkshopID("SligWolf's Minihover" , 147812851)
asmlib.WorkshopID("Battleship's abandoned rails", 807162936)
asmlib.WorkshopID("AlexCookie's 2ft track pack" , 740453553)
asmlib.WorkshopID("Joe's track pack" , 1658816805)
asmlib.WorkshopID("StevenTechno's Buildings 2.0", 1888013789)
asmlib.WorkshopID("Modular canals" , 1336622735)
asmlib.WorkshopID("Trackmania United Props" , 1955876643)
asmlib.WorkshopID("SligWolf's Rerailers" , "132843280")
asmlib.WorkshopID("SligWolf's Minitrains" , "149759773")
asmlib.WorkshopID("SProps" , "173482196")
asmlib.WorkshopID("Magnum's Rails" , "290130567")
asmlib.WorkshopID("SligWolf's Railcar" , "173717507")
asmlib.WorkshopID("Random Bridges" , "343061215")
asmlib.WorkshopID("StevenTechno's Buildings 1.0", "331192490")
asmlib.WorkshopID("Mr.Train's M-Gauge" , "517442747")
asmlib.WorkshopID("Mr.Train's G-Gauge" , "590574800")
asmlib.WorkshopID("Bobster's two feet rails" , "489114511")
asmlib.WorkshopID("G Scale Track Pack" , "718239260")
asmlib.WorkshopID("Ron's Minitrain Props" , "728833183")
asmlib.WorkshopID("SligWolf's White Rails" , "147812851")
asmlib.WorkshopID("SligWolf's Minihover" , "147812851")
asmlib.WorkshopID("Battleship's abandoned rails", "807162936")
asmlib.WorkshopID("AlexCookie's 2ft track pack" , "740453553")
asmlib.WorkshopID("Joe's track pack" , "1658816805")
asmlib.WorkshopID("StevenTechno's Buildings 2.0", "1888013789")
asmlib.WorkshopID("Modular canals" , "1336622735")
asmlib.WorkshopID("Trackmania United Props" , "1955876643")
asmlib.WorkshopID("Anyone's Horrible Trackpack" , "2194528273")
asmlib.SetAction("CTXMENU_OPEN" , function() asmlib.IsFlag("tg_context_menu", true ) end)
asmlib.SetAction("CTXMENU_CLOSE", function() asmlib.IsFlag("tg_context_menu", false) end)
@ -1122,13 +1124,14 @@ if(CLIENT) then
asmlib.LogInstance("Folder ["..sDir.."] "..lDir, gtArgsLogs); return end
local bS, lSub = pcall(tDat.Foo, sSub); if (not bS) then
asmlib.LogInstance("Subfolder ["..sSub.."] "..lSub, gtArgsLogs); return end
local sKey = tDat.Key:format(sDir, sSub)
hookAdd("PopulateToolMenu", sKey, function()
local sKey = tDat.Key:format(sDir, sSub); hookRemove(tDat.Hoo, sKey)
hookAdd(tDat.Hoo, sKey, function()
local sNam = asmlib.GetPhrase(tDat.Nam)
spawnmenuAddToolMenuOption(lDir, lSub, sKey, sNam, "", "", tArg[3])
spawnmenuAddToolMenuOption(lDir, lSub, sKey, sNam, "", "", fFoo)
end)
end,
{
Hoo = "PopulateToolMenu",
Key = gsToolPrefL.."%s_%s",
Nam = "tool."..gsToolNameL..".name",
Foo = function(s) return s:gsub("^%l", stringUpper) end
@ -4147,6 +4150,48 @@ else
PIECES:Record({"models/nokillnando/trackmania/ground/misc/checkpointground.mdl", "#", "#", 1, "", "-180,0,0", "0,180,0"})
PIECES:Record({"models/nokillnando/trackmania/ground/jump/jumplow.mdl", "#", "#", 1, "", "-242.82343,0,5.65723", "0,-180,0", ""})
PIECES:Record({"models/nokillnando/trackmania/ground/jump/jumphigh.mdl", "#", "#", 1, "", "-242.82343,0,5.65723", "0,-180,0", ""})
--[===[
asmlib.Categorize("Anyone's Horrible Trackpack",[[function(m)
local n = m:gsub("models/anytracks/","")
local r = n:match("^%a+"); n = n:gsub("%.mdl","")
n = n:gsub(r, ""):sub(2, -1); return r, n end]])
PIECES:Record({"models/anytracks/straight/s_32.mdl", "#", "#", 1, " 30,0,4", "0, 16,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/s_32.mdl", "#", "#", 2, "-30,0,4", "0,-16,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/s_64.mdl", "#", "#", 1, "", "0, 32,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/s_64.mdl", "#", "#", 2, "", "0,-32,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/s_128.mdl", "#", "#", 1, "", "0, 64,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/s_128.mdl", "#", "#", 2, "", "0,-64,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/s_256.mdl", "#", "#", 1, "", "0, 128,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/s_256.mdl", "#", "#", 2, "", "0,-128,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/s_512.mdl", "#", "#", 1, "", "0, 256,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/s_512.mdl", "#", "#", 2, "", "0,-256,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/s_1024.mdl", "#", "#", 1, "", "0, 512,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/s_1024.mdl", "#", "#", 2, "", "0,-512,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/s_2048.mdl", "#", "#", 1, "", "0, 1024,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/s_2048.mdl", "#", "#", 2, "", "0,-1024,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/s_4096.mdl", "#", "#", 1, "", "0, 2048,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/s_4096.mdl", "#", "#", 2, "", "0,-2048,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/s_8192.mdl", "#", "#", 1, "", "0, 4096,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/s_8192.mdl", "#", "#", 2, "", "0,-4096,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_32.mdl", "#", "#", 1, " 30,0,4", "0, 16,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_32.mdl", "#", "#", 2, "-30,0,4", "0,-16,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_64.mdl", "#", "#", 1, "", "0, 32,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_64.mdl", "#", "#", 2, "", "0,-32,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_128.mdl", "#", "#", 1, "", "0, 64,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_128.mdl", "#", "#", 2, "", "0,-64,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_256.mdl", "#", "#", 1, "", "0, 128,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_256.mdl", "#", "#", 2, "", "0,-128,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_512.mdl", "#", "#", 1, "", "0, 256,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_512.mdl", "#", "#", 2, "", "0,-256,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_1024.mdl", "#", "#", 1, "", "0, 512,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_1024.mdl", "#", "#", 2, "", "0,-512,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_2048.mdl", "#", "#", 1, "", "0, 1024,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_2048.mdl", "#", "#", 2, "", "0,-1024,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_4096.mdl", "#", "#", 1, "", "0, 2048,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_4096.mdl", "#", "#", 2, "", "0,-2048,4", "0,-90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_8192.mdl", "#", "#", 1, "", "0, 4096,4", "0, 90,0", ""})
PIECES:Record({"models/anytracks/straight/hs_8192.mdl", "#", "#", 2, "", "0,-4096,4", "0,-90,0", ""})
]===]
if(gsMoDB == "SQL") then sqlCommit() end
end

View File

@ -78,7 +78,7 @@ if(asmlib) then
asmlib.LogInstance(">>> "..myScript.." ("..tostring(myFlag).."): {"..myAddon..", "..myPrefix.."}")
-- Register the addon to the workshop ID list
asmlib.WorkshopID(myAddon, 326640186)
asmlib.WorkshopID(myAddon, "326640186")
--[[
* Register the addon to the auto-load prefix list when the

View File

@ -523,15 +523,21 @@ function ToIcon(vKey, vVal)
return GetOpVar("FORM_SKILLICON"):format(tostring(sIcon))
end
function WorkshopID(sKey, nVal)
function WorkshopID(sKey, sID)
if(SERVER) then return nil end
local tID = GetOpVar("TABLE_WSIDADDON"); if(not IsString(sKey)) then
LogInstance("Invalid "..GetReport(sKey)); return nil end
if(IsHere(nVal)) then
if(IsNumber(nVal) and nVal > 0) then tID[sKey] = nVal else
LogInstance("("..sKey..") Mismatch "..GetReport(nVal)); return nil
end
end; return tID[sKey]
local sWS = tID[sKey] -- Read the value under the key
if(sID) then local sPS = tostring(sID or "") -- Convert argument
local nS, nE = sPS:find("^%d+$") -- Check ID data format
if(nS and nE) then -- The number meets the format
if(not sWS) then tID[sKey], sWS = sPS, sPS else -- Update value
LogInstance("("..sKey..") Populate "..GetReport2(sWS, sID))
end -- Report overwrite value is present in the list
else -- The number does not meet the format
LogInstance("("..sKey..") Mismatch "..GetReport2(sWS, sID))
end -- Rerurn the current value under the specified key
end; return sWS
end
function IsFlag(vKey, vVal)
@ -706,7 +712,7 @@ function InitBase(sName, sPurp)
SetOpVar("FORM_DRAWDBG", "%s{%s}: %s > %s")
SetOpVar("FORM_DRWSPKY", "%+6s")
SetOpVar("FORM_SKILLICON","icon16/%s.png")
SetOpVar("FORM_URLADDON", "https://steamcommunity.com/sharedfiles/filedetails/?id=%d")
SetOpVar("FORM_URLADDON", "https://steamcommunity.com/sharedfiles/filedetails/?id=%s")
SetOpVar("TABLE_SKILLICON",{})
SetOpVar("TABLE_WSIDADDON", {})
SetOpVar("ARRAY_GHOST",{Size=0, Slot=GetOpVar("MISS_NOMD")})

View File

@ -1682,7 +1682,7 @@ function TOOL:DrawRelateIntersection(oScreen, oPly)
local Rf = (rOrg + nLn * rDir:Forward()):ToScreen()
local Ru = (rOrg + nLn * 0.5 * rDir:Up()):ToScreen()
local nR = asmlib.GetViewRadius(oPly, rOrg)
oScreen:DrawLine(Rp, Rf, "r")
oScreen:DrawLine(Rp, Rf, "r", "SURF")
oScreen:DrawLine(Rp, Ru, "b")
oScreen:DrawCircle(Rp, nR, "y", "SEGM", {35})
return Rp, Rf, Ru
@ -1709,8 +1709,8 @@ function TOOL:DrawRelateAssist(oScreen, oPly, stTrace)
local vF, vU = aTmp:Forward(), aTmp:Up()
vF:Mul(nLn); vU:Mul(0.5 * nLn); vF:Add(vTmp); vU:Add(vTmp)
local xF, xU = vF:ToScreen(), vU:ToScreen()
oScreen:DrawCircle(Hp, nRad, "y")
oScreen:DrawLine(Hp, Op, "g")
oScreen:DrawCircle(Hp, nRad, "y", "SURF")
oScreen:DrawLine(Hp, Op, "g", "SURF")
oScreen:DrawLine(xF, Op, "r")
oScreen:DrawLine(xU, Op, "b")
end
@ -1739,8 +1739,8 @@ function TOOL:DrawModelIntersection(oScreen, oPly, stSpawn)
local xX = xx:ToScreen()
local Os, Ss = stSpawn.OPos:ToScreen(), sPos:ToScreen()
local O1, O2 = vO1:ToScreen(), vO2:ToScreen()
oScreen:DrawLine(Os,Ss,"m")
oScreen:DrawCircle(Ss, asmlib.GetViewRadius(oPly, sPos),"c")
oScreen:DrawLine(Os,Ss,"m", "SURF")
oScreen:DrawCircle(Ss, asmlib.GetViewRadius(oPly, sPos), "c", "SURF")
oScreen:DrawCircle(xX, asmlib.GetViewRadius(oPly, xx, 2), "b")
oScreen:DrawLine(xX,O1,"ry")
oScreen:DrawLine(xX,O2)
@ -1753,8 +1753,8 @@ end
function TOOL:DrawPillarIntersection(oScreen, vX, vX1, vX2)
local oPly, XX = self:GetOwner(), vX:ToScreen()
local X1, X2 = vX1:ToScreen(), vX2:ToScreen()
oScreen:DrawLine(X1,X2,"ry")
oScreen:DrawCircle(X1, asmlib.GetViewRadius(oPly, vX1),"r")
oScreen:DrawLine(X1, X2, "ry", "SURF")
oScreen:DrawCircle(X1, asmlib.GetViewRadius(oPly, vX1),"r", "SURF")
oScreen:DrawCircle(X2, asmlib.GetViewRadius(oPly, vX2),"g")
oScreen:DrawCircle(XX, asmlib.GetViewRadius(oPly, vX),"b")
return XX, X1, X2
@ -2153,9 +2153,9 @@ function TOOL.BuildCPanel(CPanel)
else pnSelf:SetExpanded(true) end
end
pRoot.DoRightClick = function()
local ID = asmlib.WorkshopID(sTyp)
if(ID and ID > 0 and inputIsKeyDown(KEY_LSHIFT)) then
guiOpenURL(asmlib.GetOpVar("FORM_URLADDON"):format(ID))
local sID = asmlib.WorkshopID(sTyp)
if(sID and sID:len() > 0 and inputIsKeyDown(KEY_LSHIFT)) then
guiOpenURL(asmlib.GetOpVar("FORM_URLADDON"):format(sID))
else SetClipboardText(pRoot:GetText()) end
end
pRoot:UpdateColours(drmSkin)