PWADCN--Object skins v1.0 --Script made by Chaobrother, special thanks to Ashnal for the initial rewrite. --Object spawn state swapping may crash with objects that have MF_RUNSPAWNFUNC. --This is a script which changes a particular property of an object. --Hopefully it will cut down on freeslot/thing starvation. --There are also server commands for global overrides. --Map Header Setup: Use Lua.ObjectSkin then a comma separated list. --Each object to change can have all of its properties modified. The order can vary, but: --Start off with your object type you want to modify starting with "MT_" --The following arguments should alternate until the end of the level header or you want to use a new object. --The first argument is the type of property to change: S_RAISESTATE, S_SPAWNSTATE, etc. --this should be written as the property appears in an object definition (e.g spawnstate) --Changing the spawn state will also alter the current state. --The second is the property's new value. Use _G[MT_Object] if the new value is an object. --Lua.spawnskin merely changes the frame and sprite of an object on spawn. --Like object skin enter your parameters as a comma separated list. --The first argument is the object to look for. --The second is the new sprite prefix with SPR_ in the front. --The third is the new frame. --If you run out of space on a line add a number starting from one to a new level header parameter. --Example: Lua.spawnskin, Lua.spawnskin1,Lua.spawnskin2,... --The script will concatenate each header. --[[Server Commands obsk_add: Defines custom state overrides for all maps. By default changes here do not take precedence over custom overrides defined by level header parameters. Argument: A comma seperated string that is formatted the same as lua.objectskin level header parameter. --Start off with your object type you want to modify starting with "MT_" --The following arguments should alternate until the end of the levelheader or you want to use a new object. --The first argument is the type of property to change: S_RAISESTATE, S_SPAWNSTATE, etc. --this should be written as the property appears in an object definition (e.g spawnstate) --Changing the spawn state will also alter the current state. --The second is the new property. obsk_remove: Removes a custom overide from all maps Argument: A comma seperated list with the object and all states that need to be cleared to follow. Every custom override for a given object is cleared if no states are given. e.g: MT_OBJECT, spawnstate obsk_clear: clears all of the server's custom overrides for all maps. No Arguments obsk_disable: Prevents (but does not remove) the server's custom overrides from loading. Arguments: on or off. obsk_serverpriority: Determines if the server's overrides or the maps should take precedence. Arguments: on or off. obsk_fastload: Makes changes to the server's overrides immediate. May cause issues if enabled. Arguments: on or off. ]] --The complete script is not to be modified as it would change the behavior of other map packs which use it. --It is free to be packaged with your file. --Any part of the script is free to reuse for external purposes, however. if (objectskin_initialized) then return end -- Check if the script has already been run local function tableparse(x) local y = {} local i = 0 if x for word in x:gmatch('[^,%s]+') do y[i+1] = word i = $+1 end end return y end local function tableconcat(param) local i = 1 local z = tableparse(mapheaderinfo[gamemap][param]) local y = {} repeat y = tableparse(mapheaderinfo[gamemap][param..i]) if not y break end for j = 1 , #y table.insert(z,y[j]) end i = $1 + 1 until not mapheaderinfo[gamemap][param..i] return z end local function stroperators(val1,token,val2) if token == "<<" then return val1 << val2 elseif token == ">>" then return val1 >> val2 elseif token == "|" then return val1 | val2 elseif token == "&" then return val1 & val2 --[[elseif token == "^^" then return val1 ^^ val2 elseif token == "~" then return val1 ! val2 elseif token == "!" then return val1 ! val2]] end if token == "-" then return val1 - val2 elseif token == "+" then return val1 + val2 elseif token == "/" then return val1 / val2 elseif token == "*" then return val1 * val2 elseif token == "%" then return val1 % val2 elseif token == "^" then return val1 ^ val2 else print("Operation error with "..(val1 or "nil")..","..(token or "nil")..", and "..(val2 or "nil")) return nil end end local function strtomath(str) local operators = {} local operands = {} for w in str:gmatch("[%+%-%*%/%|%^%%%%&(%<)(%>)]+") do table.insert(operators,w) end for w in str:gmatch("[^%+%-%*%/%|%^%%%%&(%<)(%>)]+") do table.insert(operands,w) end local num = _G[operands[1]] or tonumber(operands[1]) local num2 for k=1 , #operands do if operands[k+1] and operators[k]then num2 = _G[operands[k+1]] or tonumber(operands[k+1]) num = stroperators(num,operators[k],num2) end end return num; end local function swaptablemake(sswaptable, restable, instr) local mobjtype = 0 local propertykey local restableticker = 0 local stateswapval = 0 local alreadykey = 0 for i = 1, #instr if string.sub(instr[i],1,3) == "MT_" mobjtype = _G[instr[i]] restableticker = 0 if restable[mobjtype] == nil restable[mobjtype] = {} end if sswaptable[mobjtype] == nil sswaptable[mobjtype] = {} end continue else --If you need to use objects for other purposes. --Use _G[objectype] without quotes in the brackets. instr[i] = string.gsub(instr[i],"_G%b[]", function(w) return _G[string.sub(w,4,-2)] end) if restableticker == 1 if tonumber(instr[i]) stateswapval = instr[i] else if not _G[instr[i]] stateswapval = strtomath(instr[i]) else stateswapval = _G[instr[i]] end end sswaptable[mobjtype][propertykey] = stateswapval else propertykey = instr[i] alreadykey = 0 --Setting up restoration. for j = 1, #restable[mobjtype] if instr[i] == restable[mobjtype][j] alreadykey = 1 break end end if alreadykey == 0 table.insert(restable[mobjtype], instr[i]) table.insert(restable[mobjtype], --[[ZBno]]mobjinfo[mobjtype][instr[i]]) end end restableticker = $1 ^^ 1 end end return sswaptable,restable end local function obskinparse(sswaptable) for k,v in pairs(sswaptable) for l,w in pairs(sswaptable[k]) --[[ZBno]]mobjinfo[k][l] = w end end end local serverswaptable = {} local serverrestoretable = {} local serverrestoreclear = 0 local skinremoval addHook("NetVars",function(net) serverswaptable = net{$} serverrestoretable = net{$} serverrestoreclear = net{$} skinremoval = net{$} end) local obsk_disable = CV_RegisterVar({ name = "obsk_disable", defaultvalue = 0, flags = CV_NETVAR, possiblevalue = CV_OnOFF }) local obsk_serverpriority = CV_RegisterVar({ name = "obsk_serverpriority", defaultvalue = 0, flags = CV_NETVAR, possiblevalue = CV_OnOFF }) local obsk_fastload = CV_RegisterVar({ name = "obsk_fastload", defaultvalue = 0, flags = CV_NETVAR, possiblevalue = CV_OnOFF }) COM_AddCommand("obsk_add" ,function(p,arg) local addtable = tableparse(arg) or {} serverswaptable,serverrestoretable = swaptablemake(serverswaptable, serverrestoretable, addtable) if CV_FindVar("obsk_fastload").value == 1 obskinparse(serverswaptable) end end,COM_ADMIN) local function obskremove(removaltable) local mobjtype = 0 for i = 1,#removaltable if string.sub(removaltable[i],1,3) == "MT_" mobjtype = _G[removaltable[i]] if serverrestoretable[mobjtype] == nil continue end if (removaltable[i+1] == nil) or (string.sub(removaltable[i+1],1,3) == "MT_") serverswaptable[_G[removaltable[i]]] = nil for k, v in pairs(serverrestoretable) if k != mobjtype continue end for i = 1,#serverrestoretable[k],2 --[[ZBno]]mobjinfo[k][serverrestoretable[k][i]] = serverrestoretable[k][i+1] end end end continue else for k, v in pairs(serverrestoretable[mobjtype]) if v == removaltable[i] --[[ZBno]]mobjinfo[mobjtype][v] = serverrestoretable[mobjtype][k+1] serverswaptable[mobjtype][v] = nil end end end end end COM_AddCommand("obsk_remove" ,function(p,arg) skinremoval = table.insert(skinremoval,(tableparse(arg) or {})) if CV_FindVar("obsk_fastload").value == 1 obskremove(skinremoval) skinremoval = {} end end,COM_ADMIN) COM_AddCommand("obsk_clear" ,function(p) if CV_FindVar("obsk_fastload").value == 1 serverrestoreclear = 0 for k, v in pairs(serverrestoretable) for i = 1,#serverrestoretable[k],2 --[[ZBno]]mobjinfo[k][serverrestoretable[k][i]] = serverrestoretable[k][i+1] end end serverswaptable = {} serverrestoretable = {} else serverrestoreclear = 1 end end,COM_ADMIN) local stateswaptable = {} local skinswaptable = {} local restoretable = {} addHook("NetVars",function(net) stateswaptable = net($) skinswaptable = net($) restoretable = net($) end) local function mapobjskin() if mapheaderinfo[gamemap].objectskin stateswaptable,restoretable = swaptablemake(stateswaptable, restoretable, tableconcat("objectskin")) obskinparse(stateswaptable) end if mapheaderinfo[gamemap].spawnskin skinswaptable = tableconcat("spawnskin") end end local function serverobjskin() local mobjtype = 0 if CV_FindVar("obsk_disable").value == 0 obskinparse(serverswaptable) else for k, v in pairs(serverrestoretable) for i = 1,#serverrestoretable[k],2 --[[ZBno]]mobjinfo[k][serverrestoretable[k][i]] = serverrestoretable[k][i+1] end end end if skinremoval ~= nil and #skinremoval > 0 obskremove(skinremoval) skinremoval = {} end end addHook("MapChange",function() for k, v in pairs(restoretable) for i = 1,#restoretable[k],2 --[[ZBno]]mobjinfo[k][restoretable[k][i]] = restoretable[k][i+1] end end restoretable = {} if serverrestoreclear == 1 for k, v in pairs(serverrestoretable) for i = 1,#serverrestoretable[k],2 --[[ZBno]]mobjinfo[k][serverrestoretable[k][i]] = serverrestoretable[k][i+1] end end serverswaptable = {} serverrestoretable = {} serverrestoreclear = 0 end if CV_FindVar("obsk_serverpriority").value == 1 mapobjskin() serverobjskin() else serverobjskin() mapobjskin() end end) addHook("MobjSpawn",function(mo) if not mapheaderinfo[gamemap].spawnskin return end for i = 1,#skinswaptable,3 if mo.type == _G[skinswaptable[i]] and mo.valid mo.sprite = _G[skinswaptable[i+1]] mo.frame = _G[skinswaptable[i+2]] end end end) rawset(_G, "objectskin_initialized", true) --AlterMap v1.0 by Chaobrother. This is a script remodeled from Paradise Illusion. --Toggles the normal look of a stage to something else. -- Parameters -- 0: Normal Standard, Encore Alternate -- 1: Normal Alternate, Encore Standard -- 2: Normal and Encore Standard mode. This is the default. -- 3: Normal and Encore Alternate mode. -- Level Header parameters: --[[ lua.altermap: This level has an alternate mode where the default can be changed with a console command. Make sure to call ALTERMAPDECLARATION with your map number in an external script for proper operation. lua.altermapsky: Sets the sky to the number defined when loaded into alternate mode. lua.altermapexecute: A linedef number to execute when in alternate mode. lua.altermapbrightness: Increments all sector brightnesses by the number defined. lua.altermapflats: A comma seperated list of flats to replace. The pattern is oldflat, newflat. If there are too many caracters to fit in one argument use altermapflats1 to altermapflats[n] instead, where [n] is any number (without brackets). lua.altermaptextures: Same usage as altermapflats but for textures. lua.altermapencore: Enables an Encore mode hack which will force the map to load in its Encore style without the palette at the expense of the map not flipping. This will only occur if the unused style is shown in Encore with altermap command parameters 0 or 1. ]] --Linedef executor ALTERMAP does alternate mode operations without needing a console --variable or being an altermap. local commtable = commtable or {} -- Call this function in a different script to setup an altermap. -- i is map index, command is a custom command which can be -- used to change value and be called for other checks outside of this script. -- value is the default altermap argument for your map. -- You may need to change or add a command to your map if there is a netid conflict. rawset(_G, "ALTERMAPDECLARATION", function(i,command,value) if not commtable[i] if command ~= nil commtable[i] = CV_RegisterVar({ name = command, defaultvalue = value or "Off", flags = CV_NETVAR, possiblevalue = {Off = 0, On = 1, Never = 2, Always = 3} }) rawset(_G,command,commtable[i]) else commtable[i] = CV_RegisterVar({ name = "alter"..string.lower(G_BuildMapName(i)), defaultvalue = value or "Off", flags = CV_NETVAR, possiblevalue = {Off = 0, On = 1, Never = 2, Always = 3} }) end end end) if AlternateMapLib return end rawset(_G,"AlternateMapLib",true) rawset(_G, "ISALTERMODE", false) local function tableparse(x) if not x return {} end local y = {} local i = 0 for word in x:gmatch('[^,%s]+') do y[i+1] = word i = $+1 end return y end -- garbage string for swapping, B311RGIM --[[Converts a level header with texture swaps (A->B) (B->A) to a list which facilitates practically doing so (A->C)(B->A)(C->B) currently non-functional due to some unknowns and combos of swaps/nonswaps]] local function swapparse(x) local haveSeen = {} local swapindex = {} for i = 1, #x do local element = x[i] if not haveSeen[element] then haveSeen[element] = {i} else table.insert(haveSeen[element],i) end end for k,v in pairs(haveSeen) print(#v) end for i=1, #x do --0,1,1,0 --1,2,0,1,2,0 if #haveSeen[x[i]] == 1 --unique value table.insert(swapindex,x[i]) else for j = 1, #haveSeen[x[i]] if haveSeen[x[i]][j] % 2 ~= 0 and i > haveSeen[x[i]][j] --from value table.insert(swapindex,x[i+1]) table.insert(swapindex,"GFZROCK") table.insert(swapindex,x[i]) table.insert(swapindex,x[i+1]) table.insert(swapindex,"GFZROCK") table.insert(swapindex,x[i]) --haveSeen[x[i]][j] = i end break end end end for i = 1 , #swapindex do if swapindex[i] --print(swapindex[i].." ") end end return swapindex end local function tableconcat(param) local i = 1 local z = tableparse(mapheaderinfo[gamemap][param]) local y = {} repeat y = tableparse(mapheaderinfo[gamemap][param..i]) if not y break end for j = 1 , #y table.insert(z,y[j]) end i = $1 + 1 until not mapheaderinfo[gamemap][param..i] return z end --Function which handles all altermapalterations --[[Linedef Properties -Backside texture: Name is appended to altermapflats and altermaptextures for the potential of multiple textureswaps. -Front side X offset determines global brightnees increment. -Block Enemies will make the linedef only affect global brightness. ]] local function doaltermap(j,mo,d) local flatset = {} local textureset = {} local brightmod = 0 if not j if mapheaderinfo[gamemap].altermapsky P_SetupLevelSky(tonumber(mapheaderinfo[gamemap].altermapsky), true) end if mapheaderinfo[gamemap].altermapexecute P_LinedefExecute(tonumber(mapheaderinfo[gamemap].altermapexecute)) end end if not j or ~(j.flags & ML_BLOCKMONSTERS) if j and j.backside if mapheaderinfo[gamemap]["altermapflats"..string.lower(j.backside.text)] flatset = tableconcat("altermapflats"..string.lower(j.backside.text)) end if mapheaderinfo[gamemap]["altermaptextures"..string.lower(j.backside.text,"ALTERMAP")] textureset = tableconcat("altermaptextures"..string.lower(j.backside.text,"ALTERMAP")) end else if mapheaderinfo[gamemap].altermapflats flatset = tableconcat("altermapflats") end if mapheaderinfo[gamemap].altermaptextures textureset = tableconcat("altermaptextures") end end end if j brightmod = j.frontside.textureoffset/FRACUNIT elseif mapheaderinfo[gamemap].altermapbrightness brightmod = tonumber(mapheaderinfo[gamemap].altermapbrightness) end --Texture Replacement for s in sectors.iterate s.lightlevel = $1 + brightmod for i = 1 , #flatset, 2 if s.floorpic == flatset[i] s.floorpic = flatset[i+1] end if s.ceilingpic == flatset[i] s.ceilingpic = flatset[i+1] end end end local function textureswap(l,old,swap) if (l.special == 439) return end --Front side local this = l.frontside if (this.toptexture == old) this.toptexture = swap end if (this.midtexture == old ) this.midtexture = swap end if (this.bottomtexture == old) this.bottomtexture = swap end if l.backside == nil return --One-sided stops here. end --Back side local this = l.backside; if (this.toptexture == old) this.toptexture = swap end if (this.midtexture == old) this.midtexture = swap end if (this.bottomtexture == old ) this.bottomtexture = swap end end for l in lines.iterate for i = 1 , #textureset, 2 textureswap(l,R_TextureNumForName(textureset[i]),R_TextureNumForName(textureset[i+1])) end end end addHook("LinedefExecute", doaltermap,"ALTERMAP") addHook("MapChange",function() if not mapheaderinfo[gamemap].altermap == true return end if not commtable[gamemap] ALTERMAPDECLARATION(gamemap) end end) addHook("MapLoad", function(mapnum) if not mapheaderinfo[gamemap].altermap == true return end if (commtable[gamemap].value == 1 and encoremode == true) or (commtable[gamemap].value == 0 and encoremode == false) or (commtable[gamemap].value == 2) ISALTERMODE = false --See what you are missing in Encore mode. return end ISALTERMODE = true doaltermap() end) local oldaltvar local function altmodevars(net) oldaltvar = net($) end addHook("ThinkFrame",function() --Hacky method to supress encore when altermap is on or off. if not mapheaderinfo[gamemap].altermap or not (commtable[gamemap].value == 1 or commtable[gamemap].value == 0) or(encoremode == false) return end --Using flashpals in encore did not work as intended; the palette would always be a --default one (%75 tinted white) --[[for p in players.iterate P_FlashPal(p,7,1) end]] --Reload the map instead if mapheaderinfo[gamemap].altermapencore if leveltime == 1 oldaltvar = commtable[gamemap].value local changeval if commtable[gamemap].value == 1 changeval = 2 end if commtable[gamemap].value == 0 changeval = 3 end COM_BufInsertText(server, commtable[gamemap].name.." "..changeval) if CV_FindVar("kartencore").value == 1 COM_BufInsertText(server, "map "..gamemap.." -e") else COM_BufInsertText(server, "kartencore off") COM_BufInsertText(server, "map "..gamemap) end COM_BufInsertText(server, "wait 1") COM_BufInsertText(server, commtable[gamemap].name.." "..oldaltvar) end end end) ,LUA_OBSK,("LUA_ALTM