-- EXCLUSION SYSTEM local EXCLUSIONS_FILENAME = "client/airoptions/exclusions.dat" local function ReadExclusionsFromFile() local result = {} local file = io.openlocal(EXCLUSIONS_FILENAME, "r") if file local fileContent = file:read("*all") for skinName in string.gmatch(fileContent, "[^\n]+") result[skinName] = true end file:close() end return result end local exclusions = ReadExclusionsFromFile() local function WriteExclusionsToFile() local file = io.openlocal(EXCLUSIONS_FILENAME, "w") local isFirst = true for key, _ in pairs(exclusions) if isFirst isFirst = false else file:write("\n") end file:write(key) end file:close() end local function ExcludeCharacters(player, ...) local args = {...} local noArgs = true CONS_Printf(player, "Excluded characters: ") for i, skinName in ipairs(args) exclusions[skinName] = true CONS_Printf(player, "- " .. skinName) noArgs = false end if noArgs CONS_Printf(player, "(no arguments given)") else WriteExclusionsToFile() end end local function IncludeCharacters(player, ...) local args = {...} local noArgs = true CONS_Printf(player, "Included characters: ") for _, skinName in ipairs(args) exclusions[skinName] = nil CONS_Printf(player, "- " .. skinName) noArgs = false end if noArgs CONS_Printf(player, "(no arguments given)") else WriteExclusionsToFile() end end local function ViewExclusions(player, ...) CONS_Printf(player, "Characters excluded from Air Options: ") for key, _ in pairs(exclusions) CONS_Printf(player, "- " .. key) end end COM_AddCommand("aoexclude", ExcludeCharacters) COM_AddCommand("aoinclude", IncludeCharacters) COM_AddCommand("aoviewexclusions", ViewExclusions) -- ACTUAL AIR OPTIONS SYSTEM local function RefreshAbility(player) player.pflags = $ | PF_JUMPED & ~PF_THOKKED player.secondjump = 0; end local function SpinCharThink(player) -- Ignore if character is grounded if (P_IsObjectOnGround(player.mo)) player.mo.ao_donecheck = false return end -- If spinning in the air if (player.pflags & PF_SPINNING) -- Turn off the spinning flag; this means you won't turn slowly like when rolling on ground player.pflags = $ & ~PF_SPINNING -- Use the jump state instead player.mo.state = S_PLAY_JUMP -- Enable air ability player.mo.ao_donecheck = true end if (player.mo.ao_donecheck and not player.mo.coyoteTime) player.mo.ao_donecheck = false RefreshAbility(player) end end local function NonSpinCharThink(player) -- Ignore if character is grounded if (P_IsObjectOnGround(player.mo)) player.mo.ao_donecheck = false return end if (player.mo.state == S_PLAY_SPRING) player.mo.ao_donecheck = false end if not (player.mo.ao_donecheck or player.mo.coyoteTime) player.mo.ao_donecheck = true RefreshAbility(player) end end local function AirOptionsThink(player) if exclusions[player.mo.skin] return end -- Run spin or nonspin character logic if (player.charflags & SF_NOJUMPSPIN) NonSpinCharThink(player) else SpinCharThink(player) end end addHook("PreThinkFrame", function() for player in players.iterate AirOptionsThink(player); end end);