Files
wnsrc/gamemodes/terrortown/gamemode/scoring_shd.lua
lifestorm 94063e4369 Upload
2024-08-04 22:55:00 +03:00

213 lines
5.6 KiB
Lua

--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
-- Server and client both need this for scoring event logs
-- 2^16 bytes - 4 (header) - 2 (UInt length in TTT_ReportStream) - 1 (terminanting byte)
(SERVER and SCORE or CLSCORE).MaxStreamLength = 65529
function ScoreInit()
return {
deaths=0,
suicides=0,
innos=0,
traitors=0,
was_traitor=false,
bonus=0 -- non-kill points to add
};
end
function ScoreEvent(e, scores)
if e.id == EVENT_KILL then
local aid = e.att.sid64
local vid = e.vic.sid64
-- make sure a score table exists for this person
-- he might have disconnected by now
if scores[vid] == nil then
scores[vid] = ScoreInit()
-- normally we have the ply:GetTraitor stuff to base this on, but that
-- won't do for disconnected players
scores[vid].was_traitor = e.vic.tr
end
if scores[aid] == nil then
scores[aid] = ScoreInit()
scores[aid].was_traitor = e.att.tr
end
scores[vid].deaths = scores[vid].deaths + 1
if aid == vid then
scores[vid].suicides = scores[vid].suicides + 1
elseif aid != -1 then
if e.vic.tr then
scores[aid].traitors = scores[aid].traitors + 1
elseif not e.vic.tr then
scores[aid].innos = scores[aid].innos + 1
end
end
elseif e.id == EVENT_BODYFOUND then
local sid64 = e.sid64
if scores[sid64] == nil or scores[sid64].was_traitor then return end
local find_bonus = scores[sid64].was_detective and 3 or 1
scores[sid64].bonus = scores[sid64].bonus + find_bonus
end
end
-- events should be event log as generated by scoring.lua
-- scores should be table with SteamID64s as keys
-- The method of finding these IDs differs between server and client
function ScoreEventLog(events, scores, traitors, detectives)
for k, s in pairs(scores) do
scores[k] = ScoreInit()
scores[k].was_traitor = table.HasValue(traitors, k)
scores[k].was_detective = table.HasValue(detectives, k)
end
local tmp = nil
for k, e in pairs(events) do
ScoreEvent(e, scores)
end
return scores
end
function ScoreTeamBonus(scores, wintype)
local alive = {traitors = 0, innos = 0}
local dead = {traitors = 0, innos = 0}
for k, sc in pairs(scores) do
local state = (sc.deaths == 0) and alive or dead
if sc.was_traitor then
state.traitors = state.traitors + 1
else
state.innos = state.innos + 1
end
end
local bonus = {}
bonus.traitors = (alive.traitors * 1) + math.ceil(dead.innos * 0.5)
bonus.innos = alive.innos * 1
-- running down the clock must never be beneficial for traitors
if wintype == WIN_TIMELIMIT then
bonus.traitors = math.floor(alive.innos * -0.5) + math.ceil(dead.innos * 0.5)
end
return bonus
end
-- Scores were initially calculated as points immediately, but not anymore, so
-- we can convert them using this fn
function KillsToPoints(score, was_traitor)
return ((score.suicides * -1)
+ score.bonus
+ (score.traitors * (was_traitor and -16 or 5))
+ (score.innos * (was_traitor and 1 or -8))
+ (score.deaths == 0 and 1 or 0)) --effectively 2 due to team bonus
--for your own survival
end
---- Weapon AMMO_ enum stuff, used only in score.lua/cl_score.lua these days
-- Not actually ammo identifiers anymore, but still weapon identifiers. Used
-- only in round report (score.lua) to save bandwidth because we can't use
-- pooled strings there. Custom SWEPs are sent as classname string and don't
-- need to bother with these.
AMMO_DEAGLE = 2
AMMO_PISTOL = 3
AMMO_MAC10 = 4
AMMO_RIFLE = 5
AMMO_SHOTGUN = 7
-- Following are custom, intentionally out of ammo enum range
AMMO_CROWBAR = 50
AMMO_SIPISTOL = 51
AMMO_C4 = 52
AMMO_FLARE = 53
AMMO_KNIFE = 54
AMMO_M249 = 55
AMMO_M16 = 56
AMMO_DISCOMB = 57
AMMO_POLTER = 58
AMMO_TELEPORT = 59
AMMO_RADIO = 60
AMMO_DEFUSER = 61
AMMO_WTESTER = 62
AMMO_BEACON = 63
AMMO_HEALTHSTATION = 64
AMMO_MOLOTOV = 65
AMMO_SMOKE = 66
AMMO_BINOCULARS = 67
AMMO_PUSH = 68
AMMO_STUN = 69
AMMO_CSE = 70
AMMO_DECOY = 71
AMMO_GLOCK = 72
local WeaponNames = nil
function GetWeaponClassNames()
if not WeaponNames then
local tbl = {}
for k,v in pairs(weapons.GetList()) do
if v and v.WeaponID then
tbl[v.WeaponID] = WEPS.GetClass(v)
end
end
for k,v in pairs(scripted_ents.GetList()) do
local id = v and (v.WeaponID or (v.t and v.t.WeaponID))
if id then
tbl[id] = WEPS.GetClass(v)
end
end
WeaponNames = tbl
end
return WeaponNames
end
-- reverse lookup from enum to SWEP table
function EnumToSWEP(ammo)
local e2w = GetWeaponClassNames() or {}
if e2w[ammo] then
return util.WeaponForClass(e2w[ammo])
else
return nil
end
end
function EnumToSWEPKey(ammo, key)
local swep = EnumToSWEP(ammo)
return swep and swep[key]
end
-- something the client can display
-- This used to be done with a big table of AMMO_ ids to names, now we just use
-- the weapon PrintNames. This means it is no longer usable from the server (not
-- used there anyway), and means capitalization is slightly less pretty.
function EnumToWep(ammo)
return EnumToSWEPKey(ammo, "PrintName")
end
-- something cheap to send over the network
function WepToEnum(wep)
if not IsValid(wep) then return end
return wep.WeaponID
end