mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
213 lines
5.6 KiB
Lua
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
|