Compare commits

..

No commits in common. "master" and "v1.2.18" have entirely different histories.

View File

@ -12,28 +12,12 @@ local splits = {}
local PATCH = nil
local help = true
local EncoreInitial = nil
local scoreTable
-- Text flash on finish
local FlashTics = 0
local FlashRate
local FlashVFlags
local YellowFlash = {
[0] = V_YELLOWMAP,
[1] = V_ORANGEMAP,
[2] = 0
}
local RedFlash = {
[0] = V_REDMAP,
[1] = 0
}
-- Tracks if stats have been written or not
local StatTrack = false
local UNCLAIMED = "Unclaimed Record"
local HELP_MESSAGE = "\x89Leaderboard Commands:\nretry exit findmap changelevel spba_clearcheats lb_gui rival scroll encore records"
local HELP_MESSAGE = "\x89Leaderboard Commands:\nretry exit findmap changelevel spba_clearcheats lb_gui rival scroll encore"
local FILENAME = "leaderboard.txt"
-- Retry / changelevel map
@ -90,10 +74,6 @@ local ticsToTime
local allowJoin
---------------
-- cvars
local cv_teamchange
local cv_spbatk
local cv_gui = CV_RegisterVar({
name = "lb_gui",
defaultvalue = GUI_ON,
@ -101,24 +81,11 @@ local cv_gui = CV_RegisterVar({
PossibleValue = {Off = GUI_OFF, Splits = GUI_SPLITS, On = GUI_ON}
})
local AntiAFK = true
CV_RegisterVar({
local cv_afk = CV_RegisterVar({
name = "lb_afk",
defaultvalue = 1,
flags = CV_NETVAR | CV_CALL,
PossibleValue = CV_OnOff,
func = function(v)
-- Set players afkTime and toggle AntiAFK
if v.value then
for p in players.iterate do
p.afkTime = leveltime
end
AntiAFK = true
else
AntiAFK = false
end
end
flags = CV_NETVAR,
PossibleValue = CV_OnOff
})
local cv_enable = CV_RegisterVar({
@ -272,7 +239,7 @@ if f then
flags = tonumber(t[7])
end
scoreTable = getScoreTable(tonumber(t[1]), flags) or {}
local scoreTable = getScoreTable(tonumber(t[1]), flags) or {}
local spl = {}
if t[6] != nil then
@ -328,27 +295,23 @@ function allowJoin(v)
end
end
-- Returns true if there is a single player ingame
local function singleplayer()
local function ingame()
local n = 0
for p in players.iterate do
if p.valid and not p.spectator then
n = $ + 1
if n > 1 then
return false
end
end
end
return true
return n
end
local function initLeaderboard(player)
if disable and leveltime < START_TIME then
disable = not singleplayer()
disable = ingame() > 1
else
disable = disable or not singleplayer()
disable = disable or ingame() > 1
end
disable = $ or not cv_enable.value or not (maptol & (TOL_SP | TOL_RACE))
disable = $ or not cv_enable.value
-- Restore encore mode to initial value
if disable and EncoreInitial != nil then
@ -361,7 +324,7 @@ end
addHook("PlayerSpawn", initLeaderboard)
local function doyoudare(player)
if not singleplayer() or player.spectator then
if ingame() > 1 or player.spectator then
CONS_Printf(player, "How dare you")
return false
end
@ -386,58 +349,26 @@ local function exitlevel(player, ...)
end
COM_AddCommand("exit", exitlevel)
local function zoneAct(map)
local z = ""
if map.zonttl != "" then
z = " " + map.zonttl
elseif not(map.levelflags & LF_NOZONE) then
z = " Zone"
end
if map.actnum != "" then
z = $ + " " + map.actnum
end
return z
end
local function findMap(player, ...)
local search = ...
if search == nil then
local hell = "\x85HELL"
local tol = {
[TOL_SP] = "\x81Race\x80", -- Nuked race maps
[TOL_COOP] = "\x8D\Battle\x80", -- Nuked battle maps
[TOL_RACE] = "\x88Race\x80",
[TOL_MATCH] = "\x87\Battle\x80"
}
local lvltype, map, lvlttl
return
end
for i = 1, #mapheaderinfo do
map = mapheaderinfo[i]
local map = mapheaderinfo[i]
if map == nil then
continue
end
lvlttl = map.lvlttl + zoneAct(map)
if not search or lvlttl:lower():find(search:lower()) then
-- Only care for up to TOL_MATCH (0x10)
lvltype = tol[map.typeoflevel & 0x1F] or map.typeoflevel
-- If not battle print numlaps
lvltype = (map.typeoflevel & (TOL_MATCH | TOL_COOP) and lvltype)
or string.format("%s \x82%-2d\x80", lvltype, map.numlaps)
if map.lvlttl:lower():find(search:lower()) then
CONS_Printf(
player,
string.format(
"%s %-9s %-30s - %s\t%s",
"%s - %s",
G_BuildMapName(i),
lvltype,
lvlttl,
map.subttl,
(map.menuflags & LF2_HIDEINMENU and hell) or ""
map.lvlttl
)
)
end
@ -445,128 +376,11 @@ local function findMap(player, ...)
end
COM_AddCommand("findmap", findMap)
local function mapnumFromExtended(map)
local p, q = map:upper():match("MAP(%w)(%w)$", 1)
if not (p and q) then
return nil
end
local mapnum = 0
local A = string.byte("A")
if tonumber(p) != nil then
-- Non extended map numbers
if tonumber(q) == nil then
return nil
end
mapnum = tonumber(p) * 10 + tonumber(q)
else
--Extended map numbers
p = string.byte(p) - A
local qn = tonumber(q)
if qn == nil then
qn = string.byte(q) - A + 10
end
mapnum = 36 * p + qn + 100
end
return mapnum
local function mapNotExists(player, map)
CONS_Printf(player, string.format("Map doesn't exist: %s", map:upper()))
end
local SPBModeSym = {
[F_SPBEXP] = "X",
[F_SPBBIG] = "B",
[F_SPBJUS] = "J",
}
local function modeToString(mode)
local modestr = "Time Attack"
if mode & F_SPBATK then
modestr = "SPB"
for k, v in pairs(SPBModeSym) do
if mode & k then
modestr = $ + v
end
end
end
return modestr
end
local function records(player, ...)
local mapid = ...
local mapnum = gamemap
if mapid then
mapnum = mapnumFromExtended(mapid)
if not mapnum then
CONS_Printf(player, string.format("Invalid map name: %s", mapid))
return
end
end
local map = mapheaderinfo[mapnum]
if map then
CONS_Printf(player,
string.format(
"\x83%s%8s",
map.lvlttl,
(map.menuflags & LF2_HIDEINMENU and "\x85HELL") or ""
)
)
local zoneact = zoneAct(map)
-- print the zone/act on the right hand size under the title
CONS_Printf(
player,
string.format(
string.format("\x83%%%ds%%s\x80 - \x88%%s", #map.lvlttl - #zoneact / 2 - 1),
" ",
zoneAct(map),
map.subttl
)
)
else
CONS_Printf(player, "\x85UNKNOWN MAP")
end
for mode, maps in pairs(lb) do
local maptbl = maps[mapnum]
if not maptbl then continue end
CONS_Printf(player, "")
CONS_Printf(player, modeToString(mode))
-- don't print flags for time attack
if mode then
for i, tbl in ipairs(maptbl) do
CONS_Printf(
player,
string.format(
"%2d %-21s \x89%8s \x80%s",
i,
tbl["name"],
ticsToTime(tbl["time"]),
modeToString(tbl["flags"])
)
)
end
else
for i, tbl in ipairs(maptbl) do
CONS_Printf(
player,
string.format(
"%2d %-21s \x89%8s",
i,
tbl["name"],
ticsToTime(tbl["time"])
)
)
end
end
end
end
COM_AddCommand("records", records)
local ALPH = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local function changelevel(player, ...)
if not doyoudare(player) then
@ -582,19 +396,32 @@ local function changelevel(player, ...)
return
end
local mapnum = mapnumFromExtended(map)
if not mapnum then
local p, q = map:upper():match("MAP(%w)(%w)$", 1)
if not (p and q) then
CONS_Printf(player, string.format("Invalid map name: %s", map))
end
if mapheaderinfo[mapnum] == nil then
CONS_Printf(player, string.format("Map doesn't exist: %s", map:upper()))
return
end
-- Verify valid race level
if not (mapheaderinfo[mapnum].typeoflevel & (TOL_SP | TOL_RACE)) then
CONS_Printf(player, "Battle maps are not supported")
local mapnum = 0
if tonumber(p) != nil then
-- Non extended map numbers
if tonumber(q) == nil then
mapNotExists(player, map)
return
end
mapnum = tonumber(p) * 10 + tonumber(q)
else
--Extended map numbers
p = ALPH:find(p) - 1
local qn = tonumber(q)
if qn == nil then
qn = ALPH:find(q) + 9
end
mapnum = 36 * p + qn + 100
end
if mapheaderinfo[mapnum] == nil then
mapNotExists(player, map)
return
end
@ -711,6 +538,12 @@ local function findRival(player, ...)
return a["rival"]["map"] < b["rival"]["map"]
end
local modestrings = {
[F_SPBEXP] = "X",
[F_SPBBIG] = "B",
[F_SPBJUS] = "J",
}
for mode, tbl in pairs(scores) do
if i >= stop then break end
@ -724,7 +557,15 @@ local function findRival(player, ...)
if i >= stop then break end
i = i + 1
local modestr = modeToString(score["rival"]["flags"])
local modestr = "TA"
if score["rival"]["flags"] & F_SPBATK then
modestr = "SPB"
for k, v in pairs(modestrings) do
if score["rival"]["flags"] & k then
modestr = $ + v
end
end
end
if score["your"] then
local diff = score["your"]["time"] - score["rival"]["time"]
@ -806,7 +647,6 @@ addHook("MapLoad", function()
drawState = DS_DEFAULT
scrollY = 50 * FRACUNIT
scrollAcc = 0
FlashTics = 0
allowJoin(true)
--printTable(lb)
@ -820,7 +660,7 @@ function ticsToTime(tics, pure)
return string.format(
"%d:%02d:%02d",
G_TicsToMinutes(tics, true),
G_TicsToMinutes(tics),
G_TicsToSeconds(tics),
G_TicsToCentiseconds(tics)
)
@ -899,11 +739,10 @@ local FACERANK_DIM = 16
local FACERANK_SPC = FACERANK_DIM + 4
local function drawScore(v, player, pos, x, y, gui, faceRank, score, drawPos, textVFlags)
textVFlags = textVFlags or V_HUDTRANSHALF
local me = player.name == score["name"]
--draw Patch/chili
v.draw(x, y, faceRank, V_HUDTRANS | VFLAGS, v.getColormap("sonic", score["color"]))
if me then
if player.name == score["name"] then
v.draw(x, y, PATCH["CHILI"][(leveltime / 4) % 8], V_HUDTRANS | VFLAGS)
end
@ -915,7 +754,7 @@ local function drawScore(v, player, pos, x, y, gui, faceRank, score, drawPos, te
bob + (y + FACERANK_DIM / 2) * FRACUNIT,
FRACUNIT / 6,
PATCH["RUBY"],
V_HUDTRANS | VFLAGS
V_HUDTRANS
)
end
@ -999,16 +838,11 @@ local function drawScore(v, player, pos, x, y, gui, faceRank, score, drawPos, te
end
end
local flashV = 0
if me and FlashTics > leveltime then
flashV = FlashVFlags[leveltime / FlashRate % (#FlashVFlags + 1)]
end
v.drawString(
x + FACERANK_DIM + px,
y + py,
name,
textVFlags | V_ALLOWLOWERCASE | VFLAGS | flashV,
textVFlags | V_ALLOWLOWERCASE | VFLAGS,
stralign
)
@ -1026,7 +860,7 @@ local function drawScore(v, player, pos, x, y, gui, faceRank, score, drawPos, te
x + px + FACERANK_DIM,
y + 8,
ticsToTime(score["time"], true),
textVFlags | bodium[min(pos, 4)] | VFLAGS | flashV
textVFlags | bodium[min(pos, 4)] | VFLAGS
)
end
end
@ -1073,10 +907,10 @@ local function drawScroll(v, player, scoreTable, gui)
local x = 10
if #scoreTable >= 10 then
x = x + 8
end
if #scoreTable >= 100 then
x = x + 8
end
end
local y = FixedInt(scrollY)
@ -1127,6 +961,8 @@ local function drawScoreboard(v, player)
cachePatches(v)
local scoreTable = getScoreTable(gamemap, Flags)
local gui = cv_gui.value
if leveltime < START_TIME or player.exiting or player.lives == 0 then
gui = GUI_ON
@ -1173,7 +1009,7 @@ end
-- Find location of player and scroll to it
function scroll_to(player)
local m = scoreTable or {}
local m = getScoreTable(gamemap, Flags) or {}
scrollToPos = 2
for pos, score in ipairs(m) do
@ -1202,8 +1038,7 @@ local function writeStats()
end
local function saveTime(player)
scoreTable = $ or {}
local scoreTable = getScoreTable(gamemap, Flags) or {}
local pskin = skins[player.mo.skin]
local newscore = score_t(
@ -1223,16 +1058,10 @@ local function saveTime(player)
if lbComp(newscore, scoreTable[i]) then
table.remove(scoreTable, i)
S_StartSound(nil, 130)
FlashTics = leveltime + TICRATE * 3
FlashRate = 1
FlashVFlags = YellowFlash
break
else
-- You suck lol
S_StartSound(nil, 201)
FlashTics = leveltime + TICRATE * 3
FlashRate = 3
FlashVFlags = RedFlash
scroll_to(player)
return
end
@ -1309,17 +1138,14 @@ local function getGamer()
end
end
local function changeMap()
COM_BufInsertText(server, "map " + nextMap + " -force -gametype race")
nextMap = nil
end
local function think()
if nextMap then changeMap() end
if nextMap then
COM_BufInsertText(server, "map " + nextMap)
nextMap = nil
end
if disable then
if AntiAFK then
if not singleplayer() then
if cv_afk.value and ingame() > 1 then
for p in players.iterate do
if p.valid and not p.spectator and not p.exiting and p.lives > 0 then
if p.cmd.buttons then
@ -1344,7 +1170,6 @@ local function think()
end
end
end
end
help = true
return
@ -1356,7 +1181,7 @@ local function think()
if leveltime < START_TIME then
-- Help message
if leveltime == START_TIME - TICRATE * 3 then
if singleplayer() then
if ingame() == 1 then
if help then
help = false
chatprint(HELP_MESSAGE, true)
@ -1382,29 +1207,24 @@ local function think()
end
end
end
if not cv_spbatk then
cv_spbatk = CV_FindVar("spbatk")
end
-- Gamemode flags
Flags = $ & !(F_SPBATK | F_SPBEXP | F_SPBBIG | F_SPBJUS)
if server.SPBArunning
and cv_spbatk.value
and leveltime > START_TIME - (3 * TICRATE) / 2 then
if leveltime > START_TIME - (3 * TICRATE) / 2 and server.SPBArunning then
Flags = $ | F_SPBATK
if server.SPBAexpert then
Flags = $ | F_SPBEXP
end
if clearcheats then
clearcheats = false
for q in players.iterate do
q.SPBAKARTBIG = false
q.SPBAjustice = false
q.SPBAshutup = false
for p in players.iterate do
p.SPBAKARTBIG = false
p.SPBAjustice = false
p.SPBAshutup = false
end
end
if p then
for p in players.iterate do
if not p.spectator then
if p.SPBAKARTBIG then
Flags = $ | F_SPBBIG
end
@ -1412,27 +1232,14 @@ local function think()
Flags = $ | F_SPBJUS
end
end
-- make sure the spb actually spawned
if leveltime == START_TIME - 1 then
if not (server.SPBAbomb and server.SPBAbomb.valid) then
-- it didn't spawn, clear spb flags
Flags = $ & !(F_SPBATK | F_SPBEXP | F_SPBBIG | F_SPBJUS)
end
end
else
if not (Flags & F_SPBATK) then
hud.enable("freeplay")
end
end
scoreTable = getScoreTable(gamemap, Flags)
if not cv_teamchange then
cv_teamchange = CV_FindVar("allowteamchange")
end
local cv_teamchange = CV_FindVar("allowteamchange")
if p then
-- Scroll controller
-- Spectators can't input buttons so let the gamer do it
@ -1457,7 +1264,6 @@ local function think()
p.afkTime = leveltime
end
if not replayplayback then
if leveltime > PREVENT_JOIN_TIME and p.afkTime + AFK_TIMEOUT > leveltime then
if cv_teamchange.value then
allowJoin(false)
@ -1467,7 +1273,6 @@ local function think()
allowJoin(true)
end
end
end
if p.laps >= mapheaderinfo[gamemap].numlaps and timeFinished == 0 then
timeFinished = p.realtime
@ -1481,18 +1286,15 @@ end
addHook("ThinkFrame", think)
local function interThink()
if nextMap then changeMap() end
if not cv_teamchange then
cv_teamchange = CV_FindVar("allowteamchange")
if nextMap then
COM_BufInsertText(server, "map " + nextMap)
nextMap = nil
end
if not cv_teamchange.value then
if not CV_FindVar("allowteamchange").value then
allowJoin(true)
end
end
addHook("IntermissionThinker", interThink)
addHook("VoteThinker", interThink)
-- Returns the values clamed between min, max
function clamp(min_v, v, max_v)