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

257 lines
7.0 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/
--]]
-- shared extensions to player table
local plymeta = FindMetaTable( "Player" )
if not plymeta then return end
local math = math
function plymeta:IsTerror() return self:Team() == TEAM_TERROR end
function plymeta:IsSpec() return self:Team() == TEAM_SPEC end
AccessorFunc(plymeta, "role", "Role", FORCE_NUMBER)
-- Role access
function plymeta:GetTraitor() return self:GetRole() == ROLE_TRAITOR end
function plymeta:GetDetective() return self:GetRole() == ROLE_DETECTIVE end
plymeta.IsTraitor = plymeta.GetTraitor
plymeta.IsDetective = plymeta.GetDetective
function plymeta:IsSpecial() return self:GetRole() != ROLE_INNOCENT end
-- Player is alive and in an active round
function plymeta:IsActive()
return self:IsTerror() and GetRoundState() == ROUND_ACTIVE
end
-- convenience functions for common patterns
function plymeta:IsRole(role) return self:GetRole() == role end
function plymeta:IsActiveRole(role) return self:IsRole(role) and self:IsActive() end
function plymeta:IsActiveTraitor() return self:IsActiveRole(ROLE_TRAITOR) end
function plymeta:IsActiveDetective() return self:IsActiveRole(ROLE_DETECTIVE) end
function plymeta:IsActiveSpecial() return self:IsSpecial() and self:IsActive() end
local role_strings = {
[ROLE_TRAITOR] = "traitor",
[ROLE_INNOCENT] = "innocent",
[ROLE_DETECTIVE] = "detective"
};
local GetRTranslation = CLIENT and LANG.GetRawTranslation or util.passthrough
-- Returns printable role
function plymeta:GetRoleString()
return GetRTranslation(role_strings[self:GetRole()]) or "???"
end
-- Returns role language string id, caller must translate if desired
function plymeta:GetRoleStringRaw()
return role_strings[self:GetRole()]
end
function plymeta:GetBaseKarma() return self:GetNWFloat("karma", 1000) end
function plymeta:HasEquipmentWeapon()
for _, wep in ipairs(self:GetWeapons()) do
if IsValid(wep) and wep:IsEquipment() then
return true
end
end
return false
end
function plymeta:CanCarryWeapon(wep)
if (not wep) or (not wep.Kind) then return false end
return self:CanCarryType(wep.Kind)
end
function plymeta:CanCarryType(t)
if not t then return false end
for _, w in ipairs(self:GetWeapons()) do
if w.Kind and w.Kind == t then
return false
end
end
return true
end
function plymeta:IsDeadTerror()
return (self:IsSpec() and not self:Alive())
end
function plymeta:HasBought(id)
return self.bought and table.HasValue(self.bought, id)
end
function plymeta:GetCredits() return self.equipment_credits or 0 end
function plymeta:GetEquipmentItems() return self.equipment_items or EQUIP_NONE end
-- Given an equipment id, returns if player owns this. Given nil, returns if
-- player has any equipment item.
function plymeta:HasEquipmentItem(id)
if not id then
return self:GetEquipmentItems() != EQUIP_NONE
else
return util.BitSet(self:GetEquipmentItems(), id)
end
end
function plymeta:HasEquipment()
return self:HasEquipmentItem() or self:HasEquipmentWeapon()
end
-- Override GetEyeTrace for an optional trace mask param. Technically traces
-- like GetEyeTraceNoCursor but who wants to type that all the time, and we
-- never use cursor tracing anyway.
function plymeta:GetEyeTrace(mask)
mask = mask or MASK_SOLID
if CLIENT then
local framenum = FrameNumber()
if self.LastPlayerTrace == framenum and self.LastPlayerTraceMask == mask then
return self.PlayerTrace
end
self.LastPlayerTrace = framenum
self.LastPlayerTraceMask = mask
end
local tr = util.GetPlayerTrace(self)
tr.mask = mask
tr = util.TraceLine(tr)
self.PlayerTrace = tr
return tr
end
if CLIENT then
function plymeta:AnimApplyGesture(act, weight)
self:AnimRestartGesture(GESTURE_SLOT_CUSTOM, act, true) -- true = autokill
self:AnimSetGestureWeight(GESTURE_SLOT_CUSTOM, weight)
end
local simple_runners = {
ACT_GMOD_GESTURE_DISAGREE,
ACT_GMOD_GESTURE_BECON,
ACT_GMOD_GESTURE_AGREE,
ACT_GMOD_GESTURE_WAVE,
ACT_GMOD_GESTURE_BOW,
ACT_SIGNAL_FORWARD,
ACT_SIGNAL_GROUP,
ACT_SIGNAL_HALT,
ACT_GMOD_TAUNT_CHEER,
ACT_GMOD_GESTURE_ITEM_PLACE,
ACT_GMOD_GESTURE_ITEM_DROP,
ACT_GMOD_GESTURE_ITEM_GIVE
}
local function MakeSimpleRunner(act)
return function (ply, w)
-- just let this gesture play itself and get out of its way
if w == 0 then
ply:AnimApplyGesture(act, 1)
return 1
else
return 0
end
end
end
-- act -> gesture runner fn
local act_runner = {
-- ear grab needs weight control
-- sadly it's currently the only one
[ACT_GMOD_IN_CHAT] =
function (ply, w)
local dest = ply:IsSpeaking() and 1 or 0
w = math.Approach(w, dest, FrameTime() * 10)
if w > 0 then
ply:AnimApplyGesture(ACT_GMOD_IN_CHAT, w)
end
return w
end
};
-- Insert all the "simple" gestures that do not need weight control
for _, a in ipairs(simple_runners) do
act_runner[a] = MakeSimpleRunner(a)
end
local show_gestures = CreateConVar("ttt_show_gestures", "1", FCVAR_ARCHIVE)
-- Perform the gesture using the GestureRunner system. If custom_runner is
-- non-nil, it will be used instead of the default runner for the act.
function plymeta:AnimPerformGesture(act, custom_runner)
if not show_gestures:GetBool() then return end
local runner = custom_runner or act_runner[act]
if not runner then return false end
self.GestureWeight = 0
self.GestureRunner = runner
return true
end
-- Perform a gesture update
function plymeta:AnimUpdateGesture()
if self.GestureRunner then
self.GestureWeight = self:GestureRunner(self.GestureWeight)
if self.GestureWeight <= 0 then
self.GestureRunner = nil
end
end
end
function GM:UpdateAnimation(ply, vel, maxseqgroundspeed)
ply:AnimUpdateGesture()
return self.BaseClass.UpdateAnimation(self, ply, vel, maxseqgroundspeed)
end
function GM:GrabEarAnimation(ply) end
net.Receive("TTT_PerformGesture", function()
local ply = net.ReadPlayer()
local act = net.ReadUInt(16)
if IsValid(ply) and act then
ply:AnimPerformGesture(act)
end
end)
else -- SERVER
-- On the server, we just send the client a message that the player is
-- performing a gesture. This allows the client to decide whether it should
-- play, depending on eg. a cvar.
function plymeta:AnimPerformGesture(act)
if not act then return end
net.Start("TTT_PerformGesture")
net.WritePlayer(self)
net.WriteUInt(act, 16)
net.Broadcast()
end
end