From 9411ced6f19e802aa58a8a5db60a20799ab67572 Mon Sep 17 00:00:00 2001 From: Malivil Date: Wed, 29 Jul 2026 11:45:41 -0400 Subject: [PATCH 01/26] Added ability to adjust the Cannibal's eat and digestion poop sound volumes --- CONVARS.md | 2 ++ RELEASE.md | 6 ++++++ docs/teams/jester.html | 12 ++++++++++++ .../entities/weapons/weapon_can_eater.lua | 14 ++++++++++---- .../terrortown/gamemode/roles/cannibal/shared.lua | 10 ++++++++++ gamemodes/terrortown/gamemode/shared.lua | 2 +- 6 files changed, 41 insertions(+), 5 deletions(-) diff --git a/CONVARS.md b/CONVARS.md index f6cb8f00d..2f1022309 100644 --- a/CONVARS.md +++ b/CONVARS.md @@ -775,6 +775,7 @@ ttt_cannibal_notify_killer 1 // Whether to notify a Ca ttt_cannibal_notify_sound 0 // Whether to play a cheering sound when a Cannibal is killed ttt_cannibal_notify_confetti 0 // Whether to throw confetti when a Cannibal is a killed ttt_cannibal_eat_cooldown 10 // The amount of time (in seconds) between uses of the Cannibal's Cannibalizer +ttt_cannibal_eat_sound_level 100 // The sound level (volume) to play the Cannibal's eat sound (set to 0 to disable) ttt_cannibal_damage_penalty 0 // The fraction a Cannibal's damage will be scaled by when they are attacking (Only applies if ttt_cannibal_is_independent is enabled) ttt_cannibal_can_see_jesters 0 // Whether jesters are revealed (via head icons, color/icon on the scoreboard, etc.) to the Cannibal (Only applies if ttt_cannibal_is_independent is enabled) ttt_cannibal_update_scoreboard 0 // Whether the Cannibal shows dead players as missing in action (Only applies if ttt_cannibal_is_independent is enabled) @@ -784,6 +785,7 @@ ttt_cannibal_digestion 0 // Whether the Cannibal d ttt_cannibal_digestion_time 30 // How long in seconds a victim takes to be digested when eaten. Set to 0 for immediate digestion (Only applies if ttt_cannibal_digestion is enabled) ttt_cannibal_digestion_poop 1 // Whether the Cannibal drops poop when a victim is digested (Only applies if ttt_cannibal_digestion is enabled) ttt_cannibal_digestion_poop_sound 1 // Whether the Cannibal causes a sound when poop is dropped from a digested victim (Only applies if ttt_cannibal_digestion is enabled) +ttt_cannibal_digestion_poop_sound_level 100 // The sound level (volume) to play the Cannibal's digestion poop sound (set to 0 to disable). (Only applies if ttt_cannibal_digestion is enabled) // ---------------------------------------- diff --git a/RELEASE.md b/RELEASE.md index e2f6a7337..eee86a64b 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,5 +1,11 @@ # Release Notes +## 2.5.2 (Beta) +**Released:** + +### Additions +- Added ability to adjust the Cannibal's eat and digestion poop sound volumes + ## 2.5.1 **Released: July 25th, 2026** diff --git a/docs/teams/jester.html b/docs/teams/jester.html index 8b9977253..de92e41d8 100644 --- a/docs/teams/jester.html +++ b/docs/teams/jester.html @@ -600,12 +600,24 @@

Role Configuration:

Boolean Whether the Cannibal causes a sound when poop is dropped from a digested victim. (Requires ttt_cannibal_digestion to be enabled.) + + ttt_cannibal_digestion_poop_sound_level   + 100 + Integer + The sound level (volume) to play the Cannibal's digestion poop sound (set to 0 to disable). (Requires ttt_cannibal_digestion to be enabled.) + ttt_cannibal_eat_cooldown 10 Integer The amount of time in seconds between uses of the Cannibal's Cannibalizer. + + ttt_cannibal_eat_sound_level   + 100 + Integer + The sound level (volume) to play the Cannibal's eat sound (set to 0 to disable). + ttt_cannibal_gains_health 0 diff --git a/gamemodes/terrortown/entities/weapons/weapon_can_eater.lua b/gamemodes/terrortown/entities/weapons/weapon_can_eater.lua index 148934175..e7af2f61a 100644 --- a/gamemodes/terrortown/entities/weapons/weapon_can_eater.lua +++ b/gamemodes/terrortown/entities/weapons/weapon_can_eater.lua @@ -43,8 +43,10 @@ SWEP.DigestionConVar = CreateConVar("ttt_cannibal_digestion", "0", FCVAR_REPLICA SWEP.DigestionTimeConVar = CreateConVar("ttt_cannibal_digestion_time", "30", FCVAR_REPLICATED, "How long in seconds a victim takes to be digested when eaten (set to 0 for immediate digestion)", 0, 300) if SERVER then + SWEP.EatSoundLevelConVar = CreateConVar("ttt_cannibal_eat_sound_level", "100", FCVAR_NONE, "The sound level (volume) to play the Cannibal's eat sound (set to 0 to disable)", 0, 511) SWEP.DigestionPoopConVar = CreateConVar("ttt_cannibal_digestion_poop", "1", FCVAR_NONE, "Whether the Cannibal drops poop when a victim is digested", 0, 1) - SWEP.DigestionPoopSoundConVar = CreateConVar("ttt_cannibal_digestion_poop_sound", "1", FCVAR_NONE, "Whether the Cannibal causes a sound when poop is dropped from a digested victim.", 0, 1) + SWEP.DigestionPoopSoundConVar = CreateConVar("ttt_cannibal_digestion_poop_sound", "1", FCVAR_NONE, "Whether the Cannibal causes a sound when poop is dropped from a digested victim", 0, 1) + SWEP.DigestionPoopSoundLevelConVar = CreateConVar("ttt_cannibal_digestion_poop_sound_level", "100", FCVAR_NONE, "The sound level (volume) to play the Cannibal's digestion poop sound (set to 0 to disable)", 0, 511) end local eatSounds = { @@ -148,7 +150,10 @@ function SWEP:PrimaryAttack() hitEnt:SetProperty("TTTCannibalEaten", owner:SteamID64()) hitEnt:QueueMessage(MSG_PRINTBOTH, "You have been eaten by " .. owner:Nick() .. "!") - owner:EmitSound(eatSounds[math.random(1, #eatSounds)], 100) + local soundLevel = self.EatSoundLevelConVar:GetInt() + if soundLevel > 0 then + owner:EmitSound(eatSounds[math.random(1, #eatSounds)], soundLevel) + end local cooldown = self.DeviceCooldownConVar:GetInt() if cooldown > 0 then @@ -214,8 +219,9 @@ function SWEP:PrimaryAttack() poop:SetCollisionGroup(COLLISION_GROUP_WEAPON) poop.fingerprints = fingerprints - if self.DigestionPoopSoundConVar:GetBool()then - owner:EmitSound(poopSounds[math.random(#poopSounds)], 100) + soundLevel = self.DigestionPoopSoundLevelConVar:GetInt() + if self.DigestionPoopSoundConVar:GetBool() and soundLevel > 0 then + owner:EmitSound(poopSounds[math.random(#poopSounds)], soundLevel) end end end diff --git a/gamemodes/terrortown/gamemode/roles/cannibal/shared.lua b/gamemodes/terrortown/gamemode/roles/cannibal/shared.lua index e1c6ec45f..224ea75cc 100644 --- a/gamemodes/terrortown/gamemode/roles/cannibal/shared.lua +++ b/gamemodes/terrortown/gamemode/roles/cannibal/shared.lua @@ -40,6 +40,11 @@ ROLE_CONVARS[ROLE_CANNIBAL] = { type = ROLE_CONVAR_TYPE_NUM, decimal = 0 }, + { + cvar = "ttt_cannibal_eat_sound_level", + type = ROLE_CONVAR_TYPE_NUM, + decimal = 0 + }, { cvar = "ttt_cannibal_damage_penalty", type = ROLE_CONVAR_TYPE_NUM, @@ -76,6 +81,11 @@ ROLE_CONVARS[ROLE_CANNIBAL] = { { cvar = "ttt_cannibal_digestion_poop_sound", type = ROLE_CONVAR_TYPE_BOOL + }, + { + cvar = "ttt_cannibal_digestion_poop_sound_level", + type = ROLE_CONVAR_TYPE_NUM, + decimal = 0 } } diff --git a/gamemodes/terrortown/gamemode/shared.lua b/gamemodes/terrortown/gamemode/shared.lua index c385533d5..bf332badc 100644 --- a/gamemodes/terrortown/gamemode/shared.lua +++ b/gamemodes/terrortown/gamemode/shared.lua @@ -32,7 +32,7 @@ local TableInsert = table.insert include("player_class/player_ttt.lua") -- Version string for display and function for version checks -CR_VERSION = "2.5.1" +CR_VERSION = "2.5.2" CR_BETA = true CR_WORKSHOP_ID = CR_BETA and "2404251054" or "2421039084" From b31b4d36b8959506658ad5d880c34a2dea7fe6ab Mon Sep 17 00:00:00 2001 From: Malivil Date: Wed, 29 Jul 2026 11:47:11 -0400 Subject: [PATCH 02/26] Added website changes to another section of the PR tempalte --- .github/pull_request_template.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index f40449606..4b5ef26d5 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -17,5 +17,7 @@ - [ ] ConVars added to ULX list - [ ] `plymeta:IsRoleAbilityDisabled` used - Otherwise: - - [ ] CONVARS.md updated, if applicable + - [ ] Documentation + - [ ] CONVARS.md + - [ ] Website (changes marked with "beta only" notation if applicable) - [ ] ULX updated (either added to list of convars for a role, or PR created in [ULX](https://github.com/Custom-Roles-for-TTT/TTT-Custom-Roles-ULX) repo \[Add link below\]) From 4664c6c29c06114d42232002e53e78d5abad54e2 Mon Sep 17 00:00:00 2001 From: Joel Taylor Date: Fri, 31 Jul 2026 00:25:04 +0100 Subject: [PATCH 03/26] Added `TTTHUDInfoPositionOverride` hook --- API/HOOKS.md | 13 +++++++++++++ RELEASE.md | 5 +++++ gamemodes/terrortown/gamemode/cl_hud.lua | 15 +++++++++++---- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/API/HOOKS.md b/API/HOOKS.md index 704990c6e..9f1500387 100644 --- a/API/HOOKS.md +++ b/API/HOOKS.md @@ -329,6 +329,19 @@ Called after player information such as role, health, and ammo and equipment inf - *labelY* - The Y value representing the first clear space to add information - *activeLabels* - The list of current active additional labels. Used to determine the labelY offset to use via: `labelY = labelY + (20 * #activeLabels)`. Be sure to insert an entry when you add your own label so other addons can space appropriately. *(Added in 1.6.11)* +### TTTHUDInfoPositionOverride(client, x, y, width, height) +Allows overriding the position of the player information HUD element (role, health, ammo etc.). +*Realm:* Client\ +*Added in:* 2.5.2\ +*Parameters:* +- *client* - The local player +- *x* - The current x position of the element's top left corner +- *y* - The current y position of the element's top left corner +- *width* - The element's width +- *height* - The element's height + +*Return:* The new x and y positions for the element (e.g. `return newX, newY`) + ### TTTHUDRoleColorOverride(client, colorType) Allows overriding the color to use in place of the given player's normal role color.\ *Realm:* Client\ diff --git a/RELEASE.md b/RELEASE.md index e2f6a7337..5a73acacb 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,5 +1,10 @@ # Release Notes +## 2.5.2 + +### Developer +- Added `TTTHUDInfoPositionOverride` hook to override the position of the player information HUD element (role, health, ammo etc.) + ## 2.5.1 **Released: July 25th, 2026** diff --git a/gamemodes/terrortown/gamemode/cl_hud.lua b/gamemodes/terrortown/gamemode/cl_hud.lua index dee35373b..30bab206d 100644 --- a/gamemodes/terrortown/gamemode/cl_hud.lua +++ b/gamemodes/terrortown/gamemode/cl_hud.lua @@ -490,8 +490,15 @@ local function InfoPaint(client) local width = 250 local height = 94 - local x = margin - local y = ScrH() - margin - height + local defaultX = margin + local defaultY = ScrH() - margin - height + + local x = defaultX + local y = defaultY + + local overrideX, overrideY = CallHook("TTTHUDInfoPositionOverride", nil, client, x, y, width, height) + if overrideX then x = overrideX end + if overrideY then y = overrideY end DrawBg(x, y, width, height, client) @@ -508,7 +515,7 @@ local function InfoPaint(client) CRHUD:PaintBar(8, x + margin, health_y, bar_width, bar_height, overhealth_colors, MathMax(0, health - maxHealth) / maxHealth) CRHUD:PaintBar(8, x + margin, health_y, bar_width, bar_height, extraoverhealth_colors, MathMax(0, health - (2 * maxHealth)) / maxHealth) - CRHUD:ShadowedText(tostring(health), "HealthAmmo", bar_width, health_y, COLOR_WHITE, TEXT_ALIGN_RIGHT, TEXT_ALIGN_RIGHT) + CRHUD:ShadowedText(tostring(health), "HealthAmmo", x + bar_width - margin, health_y, COLOR_WHITE, TEXT_ALIGN_RIGHT, TEXT_ALIGN_RIGHT) local health_offset = 0 if client:HasEquipmentItem(EQUIP_ARMOR) then @@ -533,7 +540,7 @@ local function InfoPaint(client) CRHUD:PaintBar(8, x + margin, ammo_y, bar_width, bar_height, ammo_colors, ammo_clip / ammo_max) local text = format("%i + %02i", ammo_clip, ammo_inv) - CRHUD:ShadowedText(text, "HealthAmmo", bar_width, ammo_y, COLOR_WHITE, TEXT_ALIGN_RIGHT, TEXT_ALIGN_RIGHT) + CRHUD:ShadowedText(text, "HealthAmmo", x + bar_width - margin, ammo_y, COLOR_WHITE, TEXT_ALIGN_RIGHT, TEXT_ALIGN_RIGHT) end end From db15281268d6522023705fca727d9c9ff48b024e Mon Sep 17 00:00:00 2001 From: Joel Taylor Date: Fri, 31 Jul 2026 02:07:34 +0100 Subject: [PATCH 04/26] Added convars for player info HUD offset and updated docs accordingly --- API/HOOKS.md | 12 ++++++----- CONVARS.md | 2 ++ RELEASE.md | 5 ++++- docs/api/hooks.html | 21 +++++++++++++++++++ gamemodes/terrortown/gamemode/cl_help.lua | 8 +++++++ gamemodes/terrortown/gamemode/cl_hud.lua | 9 ++++++-- .../terrortown/gamemode/lang/english.lua | 4 ++++ 7 files changed, 53 insertions(+), 8 deletions(-) diff --git a/API/HOOKS.md b/API/HOOKS.md index 9f1500387..7f40c6724 100644 --- a/API/HOOKS.md +++ b/API/HOOKS.md @@ -330,18 +330,20 @@ Called after player information such as role, health, and ammo and equipment inf - *activeLabels* - The list of current active additional labels. Used to determine the labelY offset to use via: `labelY = labelY + (20 * #activeLabels)`. Be sure to insert an entry when you add your own label so other addons can space appropriately. *(Added in 1.6.11)* ### TTTHUDInfoPositionOverride(client, x, y, width, height) -Allows overriding the position of the player information HUD element (role, health, ammo etc.). +Allows overriding the position of the player information HUD (role, health, ammo etc.).\ *Realm:* Client\ *Added in:* 2.5.2\ *Parameters:* - *client* - The local player -- *x* - The current x position of the element's top left corner -- *y* - The current y position of the element's top left corner -- *width* - The element's width -- *height* - The element's height +- *x* - The player information HUD's current x position +- *y* - The player information HUD's current y position +- *width* - The player information HUD's width +- *height* - The player information HUD's height *Return:* The new x and y positions for the element (e.g. `return newX, newY`) +*Note:* Because of how TTT draws the player information HUD, the height of the element is actually 30 pixels taller than exposed by this hook, and the top left corner of the element is similarly 30 pixels above the `y` position value exposed. + ### TTTHUDRoleColorOverride(client, colorType) Allows overriding the color to use in place of the given player's normal role color.\ *Realm:* Client\ diff --git a/CONVARS.md b/CONVARS.md index f6cb8f00d..cfe3bea19 100644 --- a/CONVARS.md +++ b/CONVARS.md @@ -1419,6 +1419,8 @@ ttt_tracker_minimap_offset_y 14 // The screen offset from // Misc. // ---------------------------------------- ttt_distance_unit 1 // What unit to use when displaying distance. 0 - None (Source). 1 - Meters. 2 - Feet +ttt_infohud_offset_x 0 // The X (horizontal) offset of the player information HUD element +ttt_infohud_offset_y 0 // The Y (vertical) offset of the player information HUD element ``` ## Role Weapon Shop diff --git a/RELEASE.md b/RELEASE.md index 5a73acacb..6461fcad7 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -2,8 +2,11 @@ ## 2.5.2 +### Additions +- Added `ttt_infohud_offset_x` and `ttt_infohud_offset_y` client convars to allow players to reposition the player information HUD (role, health, ammo etc.) + ### Developer -- Added `TTTHUDInfoPositionOverride` hook to override the position of the player information HUD element (role, health, ammo etc.) +- Added `TTTHUDInfoPositionOverride` hook to override the position of the player information HUD (role, health, ammo etc.) ## 2.5.1 **Released: July 25th, 2026** diff --git a/docs/api/hooks.html b/docs/api/hooks.html index 7416b5749..6a4f4945d 100644 --- a/docs/api/hooks.html +++ b/docs/api/hooks.html @@ -509,6 +509,27 @@

TTTHUDInfoPositionOverride(client, x, y, width, height)

+

+ Allows overriding the position of the player information HUD (role, health, ammo etc.).
+ Realm: Client
+ Added in: 2.5.2
+ Parameters: +

+
    +
  • client - The local player
  • +
  • x - The player information HUD's current x position
  • +
  • y - The player information HUD's current y position
  • +
  • width - The player information HUD's width
  • +
  • height - The player information HUD's height
  • +
+

+ Return: The new x and y positions for the element (e.g. return newX, newY) +

+

+ Note: Because of how TTT draws the player information HUD, the height of the element is actually 30 pixels taller than exposed by this hook, and the top left corner of the element is similarly 30 pixels above the y position value exposed. +

+

TTTHUDRoleColorOverride(client, colorType)

Allows overriding the color to use in place of the given player's normal role color.
diff --git a/gamemodes/terrortown/gamemode/cl_help.lua b/gamemodes/terrortown/gamemode/cl_help.lua index 16d2cde87..67bb80e44 100644 --- a/gamemodes/terrortown/gamemode/cl_help.lua +++ b/gamemodes/terrortown/gamemode/cl_help.lua @@ -757,6 +757,14 @@ function HELPSCRN:CreateConfig(dsettings) cb = dgui:CheckBox(GetTranslation("set_hide_ammo"), "ttt_hide_ammo") cb:SetTooltip(GetTranslation("set_hide_ammo_tip")) + local infohud_offset_max_x = ScrW() - 270 + cb = dgui:NumSlider(GetTranslation("set_infohud_offset_x"), "ttt_infohud_offset_x", 0, infohud_offset_max_x, 0) + cb:SetTooltip(GetTranslation("set_infohud_offset_x_tip")) + + local infohud_offset_max_y = ScrH() - 144 + cb = dgui:NumSlider(GetTranslation("set_infohud_offset_y"), "ttt_infohud_offset_y", 0, infohud_offset_max_y, 0) + cb:SetTooltip(GetTranslation("set_infohud_offset_y_tip")) + cb = dgui:TextEntry(GetTranslation("set_radio_button"), "ttt_radio_button") cb:SetTooltip(GetTranslation("set_radio_button_tip")) diff --git a/gamemodes/terrortown/gamemode/cl_hud.lua b/gamemodes/terrortown/gamemode/cl_hud.lua index 30bab206d..1ee8d91fc 100644 --- a/gamemodes/terrortown/gamemode/cl_hud.lua +++ b/gamemodes/terrortown/gamemode/cl_hud.lua @@ -480,6 +480,11 @@ end local ttt_health_label = CreateClientConVar("ttt_health_label", "0", true) +local infohud_offset_max_x = ScrW() - 250 - (margin * 2) +local infohud_offset_max_y = ScrH() - 94 - (margin * 2) - 30 -- `traitor_y` is 30 +local ttt_infohud_offset_x = CreateClientConVar("ttt_infohud_offset_x", "0", true, false, "The X (horizontal) offset of the player information HUD element", 0, infohud_offset_max_x) +local ttt_infohud_offset_y = CreateClientConVar("ttt_infohud_offset_y", "0", true, false, "The Y (vertical) offset of the player information HUD element", 0, infohud_offset_max_y) + local armor_tex = surface.GetTextureID("vgui/ttt/equip/armor") local drown_start = nil -- Found in the "Drowning Indicator for TTT" addon which in turn found it "in Sourceā„¢ Code" @@ -493,8 +498,8 @@ local function InfoPaint(client) local defaultX = margin local defaultY = ScrH() - margin - height - local x = defaultX - local y = defaultY + local x = defaultX + ttt_infohud_offset_x:GetInt() + local y = defaultY - ttt_infohud_offset_y:GetInt() local overrideX, overrideY = CallHook("TTTHUDInfoPositionOverride", nil, client, x, y, width, height) if overrideX then x = overrideX end diff --git a/gamemodes/terrortown/gamemode/lang/english.lua b/gamemodes/terrortown/gamemode/lang/english.lua index 362160b2d..c1097b90b 100644 --- a/gamemodes/terrortown/gamemode/lang/english.lua +++ b/gamemodes/terrortown/gamemode/lang/english.lua @@ -292,6 +292,10 @@ L.set_hide_role = "Hide your role in the HUD" L.set_hide_role_tip = "By default your role will appear in the bottom left of the HUD. Turn this on to prevent screen cheating." L.set_hide_ammo = "Hide your weapon ammo in the HUD" L.set_hide_ammo_tip = "By default your weapon ammo will appear in the bottom left of the HUD. Turn this on if you have another addon that does that for you." +L.set_infohud_offset_x = "Info HUD X (horizontal) offset" +L.set_infohud_offset_x_tip = "The horizontal offset (in pixels) of the player info HUD (role, health, ammo etc.)" +L.set_infohud_offset_y = "Info HUD Y (vertical) offset" +L.set_infohud_offset_y_tip = "The vertical offset (in pixels) of the player info HUD (role, health, ammo etc.)" L.set_radio_button = "Radio menu button" L.set_radio_button_tip = "What button to press to open/close the radio menu" L.set_bypass_culling = "Bypass map culling" From c2f715ed976c6e7a132fa735fdcec478a6aad1ea Mon Sep 17 00:00:00 2001 From: Joel Taylor Date: Fri, 31 Jul 2026 02:14:38 +0100 Subject: [PATCH 05/26] Added 'Beta Only' tag in hooks.html --- docs/api/hooks.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/hooks.html b/docs/api/hooks.html index 6a4f4945d..8620878fc 100644 --- a/docs/api/hooks.html +++ b/docs/api/hooks.html @@ -509,7 +509,7 @@

TTTHUDInfoPositionOverride(client, x, y, width, height)

+

TTTHUDInfoPositionOverride(client, x, y, width, height)  

Allows overriding the position of the player information HUD (role, health, ammo etc.).
Realm: Client
From 201a540ed1125995d592a257fcd4779967c0194a Mon Sep 17 00:00:00 2001 From: Malivil Date: Fri, 31 Jul 2026 14:16:07 -0400 Subject: [PATCH 06/26] Ported "Optimize player spawn queue randomization in TTT" from base TTT --- RELEASE.md | 3 +++ gamemodes/terrortown/gamemode/init.lua | 11 +++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index eee86a64b..6819581cb 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -6,6 +6,9 @@ ### Additions - Added ability to adjust the Cannibal's eat and digestion poop sound volumes +### Changes +- Ported "Optimize player spawn queue randomization in TTT" from base TTT + ## 2.5.1 **Released: July 25th, 2026** diff --git a/gamemodes/terrortown/gamemode/init.lua b/gamemodes/terrortown/gamemode/init.lua index b99323d76..a6aa80f94 100644 --- a/gamemodes/terrortown/gamemode/init.lua +++ b/gamemodes/terrortown/gamemode/init.lua @@ -100,12 +100,12 @@ local util = util local CallHook = hook.Call local RunHook = hook.Run -local GetAllPlayers = player.GetAll local PlayerIterator = player.Iterator local MathRand = math.Rand local StringFormat = string.format local StringLower = string.lower local StringUpper = string.upper +local TableShuffle = table.Shuffle -- Round times CreateConVar("ttt_roundtime_minutes", "10", FCVAR_NOTIFY) @@ -743,13 +743,16 @@ function SpawnWillingPlayers(dead_only) local num_spawns = #GetSpawnEnts() local to_spawn = {} - for _, ply in RandomPairs(GetAllPlayers()) do + for _, ply in PlayerIterator() do if IsValid(ply) and ply:ShouldSpawn() then table.insert(to_spawn, ply) GAMEMODE:PlayerSpawnAsSpectator(ply) end end + -- Shuffle the table of queued players to randomize the spawn order + TableShuffle(to_spawn) + local sfn = function() local c = 0 -- fill the available spawnpoints with players that need @@ -1222,7 +1225,7 @@ function SelectRoles() end end - table.Shuffle(choices) + TableShuffle(choices) local choice_count = #choices -- special spawning cvars @@ -1349,7 +1352,7 @@ function SelectRoles() end end end - table.Shuffle(groupRoles) + TableShuffle(groupRoles) local chosenRole = groupRoles[1] for _, role in ipairs(groupRoles) do if role ~= chosenRole then From 7528b9c6e6440bd71287e1a371ea556db10162d2 Mon Sep 17 00:00:00 2001 From: Joel Taylor Date: Fri, 31 Jul 2026 20:13:48 +0100 Subject: [PATCH 07/26] Removed magic numbers from `cl_help.lua` --- gamemodes/terrortown/gamemode/cl_help.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gamemodes/terrortown/gamemode/cl_help.lua b/gamemodes/terrortown/gamemode/cl_help.lua index 67bb80e44..fe76f575c 100644 --- a/gamemodes/terrortown/gamemode/cl_help.lua +++ b/gamemodes/terrortown/gamemode/cl_help.lua @@ -757,12 +757,10 @@ function HELPSCRN:CreateConfig(dsettings) cb = dgui:CheckBox(GetTranslation("set_hide_ammo"), "ttt_hide_ammo") cb:SetTooltip(GetTranslation("set_hide_ammo_tip")) - local infohud_offset_max_x = ScrW() - 270 - cb = dgui:NumSlider(GetTranslation("set_infohud_offset_x"), "ttt_infohud_offset_x", 0, infohud_offset_max_x, 0) + cb = dgui:NumSlider(GetTranslation("set_infohud_offset_x"), "ttt_infohud_offset_x", 0, GetConVar("ttt_infohud_offset_x"):GetMax(), 0) cb:SetTooltip(GetTranslation("set_infohud_offset_x_tip")) - local infohud_offset_max_y = ScrH() - 144 - cb = dgui:NumSlider(GetTranslation("set_infohud_offset_y"), "ttt_infohud_offset_y", 0, infohud_offset_max_y, 0) + cb = dgui:NumSlider(GetTranslation("set_infohud_offset_y"), "ttt_infohud_offset_y", 0, GetConVar("ttt_infohud_offset_y"):GetMax(), 0) cb:SetTooltip(GetTranslation("set_infohud_offset_y_tip")) cb = dgui:TextEntry(GetTranslation("set_radio_button"), "ttt_radio_button") From a3f920b89f9414f1ffb0a1ab589d10d28d25be0a Mon Sep 17 00:00:00 2001 From: Joel Taylor Date: Fri, 31 Jul 2026 20:27:28 +0100 Subject: [PATCH 08/26] Renamed 'traitor' variables to 'role' for clarity, and removed magic number --- gamemodes/terrortown/gamemode/cl_hud.lua | 44 +++++++++++-------- .../roles/taskmaster/cl_taskmaster.lua | 4 +- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/gamemodes/terrortown/gamemode/cl_hud.lua b/gamemodes/terrortown/gamemode/cl_hud.lua index 1ee8d91fc..774fcffdf 100644 --- a/gamemodes/terrortown/gamemode/cl_hud.lua +++ b/gamemodes/terrortown/gamemode/cl_hud.lua @@ -25,12 +25,12 @@ local format = string.format local hide_role = GetConVar("ttt_hide_role") -- Fonts -surface.CreateFont("TraitorState", { +surface.CreateFont("RoleState", { font = GAMEMODE_DEFAULT_UI_FONT, size = 28, weight = 1000 }) -surface.CreateFont("TraitorStateSmall", { +surface.CreateFont("RoleStateSmall", { font = GAMEMODE_DEFAULT_UI_FONT, size = 24, weight = 1000 @@ -372,24 +372,27 @@ local function GetAmmo(ply) return ammo_clip, ammo_max, ammo_inv end +local roleAreaHeight = 30 +local roleAreaWidth = 170 + local function DrawBg(x, y, width, height, client) if not hide_role then hide_role = GetConVar("ttt_hide_role") end - -- Traitor area sizes - local th = 30 - local tw = 170 + -- Role area sizes + local rh = roleAreaHeight + local rw = roleAreaWidth -- Adjust for these - y = y - th - height = height + th + y = y - rh + height = height + rh -- main bg area, invariant -- encompasses entire area draw.RoundedBox(8, x, y, width, height, bg_colors.background_main) - -- main border, traitor based + -- main border, role based local col = ROLE_COLORS[client:GetDisplayedRole()] if GAMEMODE.round_state ~= ROUND_ACTIVE then col = bg_colors.noround @@ -400,7 +403,7 @@ local function DrawBg(x, y, width, height, client) if new_col then col = new_col end end - draw.RoundedBoxEx(8, x, y, tw, th, col, true, false, false, true) + draw.RoundedBoxEx(8, x, y, rw, rh, col, true, false, false, true) end function CRHUD:ShadowedText(text, font, x, y, color, xalign, yalign) @@ -460,7 +463,7 @@ local function SpecHUDPaint(client) draw.RoundedBox(8, x, round_y, time_x - x, height, bg_colors.noround) local text = L[roundstate_string[GAMEMODE.round_state]] - CRHUD:ShadowedText(text, "TraitorState", x + margin, round_y, COLOR_WHITE) + CRHUD:ShadowedText(text, "RoleState", x + margin, round_y, COLOR_WHITE) -- Draw round/prep/post time remaining text = util.SimpleTime(MathMax(0, GetGlobalFloat("ttt_round_end", 0) - CurTime()), "%02i:%02i") @@ -480,8 +483,11 @@ end local ttt_health_label = CreateClientConVar("ttt_health_label", "0", true) -local infohud_offset_max_x = ScrW() - 250 - (margin * 2) -local infohud_offset_max_y = ScrH() - 94 - (margin * 2) - 30 -- `traitor_y` is 30 +infoWidth = 250 +infoHeight = 94 + +local infohud_offset_max_x = ScrW() - infoWidth - (margin * 2) +local infohud_offset_max_y = ScrH() - infoHeight - (margin * 2) - roleAreaHeight local ttt_infohud_offset_x = CreateClientConVar("ttt_infohud_offset_x", "0", true, false, "The X (horizontal) offset of the player information HUD element", 0, infohud_offset_max_x) local ttt_infohud_offset_y = CreateClientConVar("ttt_infohud_offset_y", "0", true, false, "The Y (vertical) offset of the player information HUD element", 0, infohud_offset_max_y) @@ -492,8 +498,8 @@ local MAX_AIR_TIME_SECONDS = 8 local function InfoPaint(client) local L = GetLang() - local width = 250 - local height = 94 + local width = infoWidth + local height = infoHeight local defaultX = margin local defaultY = ScrH() - margin - height @@ -570,10 +576,10 @@ local function InfoPaint(client) drown_start = nil end - -- Draw traitor state + -- Draw role state local round_state = GAMEMODE.round_state - local traitor_y = y - 30 + local role_y = y - roleAreaHeight local text if round_state == ROUND_ACTIVE then if hide_role:GetBool() then @@ -595,9 +601,9 @@ local function InfoPaint(client) if text then if #text > 10 then - CRHUD:ShadowedText(text, "TraitorStateSmall", x + margin + 74, traitor_y + 2, COLOR_WHITE, TEXT_ALIGN_CENTER) + CRHUD:ShadowedText(text, "RoleStateSmall", x + margin + 74, role_y + 2, COLOR_WHITE, TEXT_ALIGN_CENTER) else - CRHUD:ShadowedText(text, "TraitorState", x + margin + 74, traitor_y, COLOR_WHITE, TEXT_ALIGN_CENTER) + CRHUD:ShadowedText(text, "RoleState", x + margin + 74, role_y, COLOR_WHITE, TEXT_ALIGN_CENTER) end end @@ -610,7 +616,7 @@ local function InfoPaint(client) local font = "TimeLeft" local color = COLOR_WHITE local rx = x + margin + 170 - local ry = traitor_y + 3 + local ry = role_y + 3 -- Time displays differently depending on whether haste mode is on, -- whether the player is traitor or not, and whether it is overtime. diff --git a/gamemodes/terrortown/gamemode/roles/taskmaster/cl_taskmaster.lua b/gamemodes/terrortown/gamemode/roles/taskmaster/cl_taskmaster.lua index ab4f6d54f..31d182e7c 100644 --- a/gamemodes/terrortown/gamemode/roles/taskmaster/cl_taskmaster.lua +++ b/gamemodes/terrortown/gamemode/roles/taskmaster/cl_taskmaster.lua @@ -172,7 +172,7 @@ local function DrawTask(task, height, isShadow) surface.DrawRect(xPos + margin + 2 + offset, height + checkboxSize + offset, checkboxSize, 2) surface.DrawRect(xPos + margin + checkboxSize + offset, height + 2 + offset, 2, checkboxSize) - surface.SetFont("TraitorStateSmall") + surface.SetFont("RoleStateSmall") surface.SetTextPos(xPos + (margin * 2) + checkboxSize + offset, height + offset) surface.DrawText(name) @@ -320,7 +320,7 @@ local function CreateTaskReroll(task, dscrollpanel) local buttonWidth, buttonHeight = 80, 45 local dname = vgui.Create("DLabel", dpanel) - dname:SetFont("TraitorStateSmall") + dname:SetFont("RoleStateSmall") dname:SetText(name) dname:SetPos(margin, margin) dname:SetWidth(width - (margin * 2) - buttonWidth - scrollBarWidth) From be2512580db23c55ee2e590f4340ba7945428bf5 Mon Sep 17 00:00:00 2001 From: Joel Taylor Date: Sat, 1 Aug 2026 00:01:11 +0100 Subject: [PATCH 09/26] `TTTHUDInfoPositionOverride` now exposes the actual x/y pos and size of the player information HUD --- gamemodes/terrortown/gamemode/cl_hud.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gamemodes/terrortown/gamemode/cl_hud.lua b/gamemodes/terrortown/gamemode/cl_hud.lua index 774fcffdf..fc4b6f62f 100644 --- a/gamemodes/terrortown/gamemode/cl_hud.lua +++ b/gamemodes/terrortown/gamemode/cl_hud.lua @@ -507,9 +507,9 @@ local function InfoPaint(client) local x = defaultX + ttt_infohud_offset_x:GetInt() local y = defaultY - ttt_infohud_offset_y:GetInt() - local overrideX, overrideY = CallHook("TTTHUDInfoPositionOverride", nil, client, x, y, width, height) + local overrideX, overrideY = CallHook("TTTHUDInfoPositionOverride", nil, client, x, y - roleAreaHeight, width, height + roleAreaHeight) if overrideX then x = overrideX end - if overrideY then y = overrideY end + if overrideY then y = overrideY + roleAreaHeight end DrawBg(x, y, width, height, client) From aecfc798f2b8394ae205400c91c440854b35c542 Mon Sep 17 00:00:00 2001 From: Joel Taylor Date: Sat, 1 Aug 2026 00:01:57 +0100 Subject: [PATCH 10/26] Updated docs to reflect change to `TTTHUDInfoPositionOverride`; made information more concise/match style --- API/HOOKS.md | 10 ++++------ docs/api/hooks.html | 11 ++++------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/API/HOOKS.md b/API/HOOKS.md index 7f40c6724..785e31763 100644 --- a/API/HOOKS.md +++ b/API/HOOKS.md @@ -335,15 +335,13 @@ Allows overriding the position of the player information HUD (role, health, ammo *Added in:* 2.5.2\ *Parameters:* - *client* - The local player -- *x* - The player information HUD's current x position -- *y* - The player information HUD's current y position -- *width* - The player information HUD's width -- *height* - The player information HUD's height +- *x* - The X position value of the top left corner of the element +- *y* - The Y position value of the top left corner of the element +- *width* - The element's width +- *height* - The element's height *Return:* The new x and y positions for the element (e.g. `return newX, newY`) -*Note:* Because of how TTT draws the player information HUD, the height of the element is actually 30 pixels taller than exposed by this hook, and the top left corner of the element is similarly 30 pixels above the `y` position value exposed. - ### TTTHUDRoleColorOverride(client, colorType) Allows overriding the color to use in place of the given player's normal role color.\ *Realm:* Client\ diff --git a/docs/api/hooks.html b/docs/api/hooks.html index 8620878fc..fcf388169 100644 --- a/docs/api/hooks.html +++ b/docs/api/hooks.html @@ -518,17 +518,14 @@

TTTHUDRoleColorOverride(client, colorType)

From a500960a689b31fec8e2d5197660fd280774d871 Mon Sep 17 00:00:00 2001 From: Joel Taylor Date: Sat, 1 Aug 2026 10:52:09 +0100 Subject: [PATCH 11/26] `TTTHUDInfoPaint` now exposes `label_top` and `label_left` based on info HUD position --- gamemodes/terrortown/gamemode/cl_hud.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gamemodes/terrortown/gamemode/cl_hud.lua b/gamemodes/terrortown/gamemode/cl_hud.lua index fc4b6f62f..a791d0daf 100644 --- a/gamemodes/terrortown/gamemode/cl_hud.lua +++ b/gamemodes/terrortown/gamemode/cl_hud.lua @@ -652,8 +652,9 @@ local function InfoPaint(client) CRHUD:ShadowedText(text, font, rx, ry, color) - local label_top = 140 - local label_left = 36 + local label_top = ScrH() - y + roleAreaHeight + 6 + local label_left = x + if client:HasEquipmentItem(EQUIP_RADAR) and RADAR.enable then label_top = label_top + 20 end From 70e13b26ea858cab0e87bfb35bda4bda09dd7c48 Mon Sep 17 00:00:00 2001 From: Joel Taylor Date: Sat, 1 Aug 2026 10:52:26 +0100 Subject: [PATCH 12/26] Radar and Disguiser now reposition based on info HUD position --- gamemodes/terrortown/gamemode/cl_disguise.lua | 31 +++++++++++++------ gamemodes/terrortown/gamemode/cl_radar.lua | 19 +++++++++++- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/gamemodes/terrortown/gamemode/cl_disguise.lua b/gamemodes/terrortown/gamemode/cl_disguise.lua index 5697df393..6c595a885 100644 --- a/gamemodes/terrortown/gamemode/cl_disguise.lua +++ b/gamemodes/terrortown/gamemode/cl_disguise.lua @@ -15,8 +15,8 @@ function DISGUISE.CreateMenu(parent) local owned = LocalPlayer():HasEquipmentItem(EQUIP_DISGUISE) if not owned then - dform:Help(T("disg_not_owned")) - return dform + dform:Help(T("disg_not_owned")) + return dform end local dcheck = vgui.Create("DCheckBoxLabel", dform) @@ -24,8 +24,8 @@ function DISGUISE.CreateMenu(parent) dcheck:SetIndent(5) dcheck:SetValue(LocalPlayer():GetNWBool("disguised", false)) dcheck.OnChange = function(s, val) - RunConsoleCommand("ttt_set_disguise", val and "1" or "0") - end + RunConsoleCommand("ttt_set_disguise", val and "1" or "0") + end dform:AddItem(dcheck) dform:Help(T("disg_help1")) @@ -37,6 +37,23 @@ function DISGUISE.CreateMenu(parent) return dform end +local labelX = 0 +local labelY = 0 + +function DISGUISE.Bought(is_item, id) + if is_item and id == EQUIP_DISGUISE then + hook.Add("TTTHUDInfoPaint", "DisguiseLabelPos", function(client, label_left, label_top, _) + labelX = label_left + labelY = ScrH() - label_top + 20 + + if not client:HasEquipmentItem(EQUIP_DISGUISE) then + hook.Remove("TTTHUDInfoPaint", "DisguiseLabelPos") + end + end) + end +end +hook.Add("TTTBoughtItem", "DisguiseBoughtItem", DISGUISE.Bought) + function DISGUISE.Draw(client) if (not client) or not client:HasEquipmentItem(EQUIP_DISGUISE) then return end if not client:GetNWBool("disguised", false) then return end @@ -47,11 +64,7 @@ function DISGUISE.Draw(client) local text = T("disg_hud") local _, h = surface.GetTextSize(text) - local label_top = 140 - if client:HasEquipmentItem(EQUIP_RADAR) then - label_top = label_top + 20 - end - surface.SetTextPos(36, ScrH() - label_top - h) + surface.SetTextPos(labelX, labelY - h) surface.DrawText(text) end diff --git a/gamemodes/terrortown/gamemode/cl_radar.lua b/gamemodes/terrortown/gamemode/cl_radar.lua index cd283512d..397fe555c 100644 --- a/gamemodes/terrortown/gamemode/cl_radar.lua +++ b/gamemodes/terrortown/gamemode/cl_radar.lua @@ -28,6 +28,11 @@ RADAR.teleport_marks = {} local detectives_corpse_call_expiration = GetConVar("ttt_detectives_corpse_call_expiration") +local labelX = 0 +local labelY = 0 + +hook.Remove("TTTHUDInfoPaint", "RadarTimeRemainingPos") + function RADAR:EndScan() self.enable = false self.endtime = CurTime() @@ -76,6 +81,15 @@ end function RADAR.Bought(is_item, id) if is_item and id == EQUIP_RADAR then RunConsoleCommand("ttt_radar_scan") + + hook.Add("TTTHUDInfoPaint", "RadarTimeRemainingPos", function(client, label_left, label_top, _) + labelX = label_left + labelY = ScrH() - label_top + 20 + + if not client:HasEquipmentItem(EQUIP_RADAR) then + hook.Remove("TTTHUDInfoPaint", "RadarTimeRemainingPos") + end + end) end end hook.Add("TTTBoughtItem", "RadarBoughtItem", RADAR.Bought) @@ -294,7 +308,10 @@ function RADAR:Draw(client) local text = GetPTranslation("radar_hud", { time = FormatTime(remaining, "%02i:%02i") }) local _, h = surface.GetTextSize(text) - surface.SetTextPos(36, ScrH() - 140 - h) + if client:HasEquipmentItem(EQUIP_DISGUISE) and client:GetNWBool("disguised", false) then + labelY = labelY + 20 + end + surface.SetTextPos(labelX, labelY - h) surface.DrawText(text) end From 143977390afc5119be8e11aad28f313ae741c8b9 Mon Sep 17 00:00:00 2001 From: joel4848 <51252788+joel4848@users.noreply.github.com> Date: Sat, 1 Aug 2026 14:24:59 +0100 Subject: [PATCH 13/26] Update gamemodes/terrortown/gamemode/cl_hud.lua Co-authored-by: Malivil --- gamemodes/terrortown/gamemode/cl_hud.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gamemodes/terrortown/gamemode/cl_hud.lua b/gamemodes/terrortown/gamemode/cl_hud.lua index a791d0daf..bf5b2d484 100644 --- a/gamemodes/terrortown/gamemode/cl_hud.lua +++ b/gamemodes/terrortown/gamemode/cl_hud.lua @@ -483,8 +483,8 @@ end local ttt_health_label = CreateClientConVar("ttt_health_label", "0", true) -infoWidth = 250 -infoHeight = 94 +local infoWidth = 250 +local infoHeight = 94 local infohud_offset_max_x = ScrW() - infoWidth - (margin * 2) local infohud_offset_max_y = ScrH() - infoHeight - (margin * 2) - roleAreaHeight From 95672ec13344d83e34c25e868eb52d148fb3bf15 Mon Sep 17 00:00:00 2001 From: Joel Taylor Date: Sat, 1 Aug 2026 14:29:20 +0100 Subject: [PATCH 14/26] Added parameters to `TTTHUDInfoPaint`; made requested changes --- API/HOOKS.md | 4 +++- RELEASE.md | 1 + docs/api/hooks.html | 2 ++ gamemodes/terrortown/gamemode/cl_hud.lua | 16 ++++++++-------- .../gamemode/roles/taskmaster/cl_taskmaster.lua | 4 ++-- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/API/HOOKS.md b/API/HOOKS.md index 785e31763..f0b56c274 100644 --- a/API/HOOKS.md +++ b/API/HOOKS.md @@ -319,7 +319,7 @@ Called when someone uses a fake cure on a player.\ *Parameters:* - *ply* - The target player who is being "cured" -### TTTHUDInfoPaint(client, labelX, labelY, activeLabels) +### TTTHUDInfoPaint(client, labelX, labelY, activeLabels, x, y) Called after player information such as role, health, and ammo and equipment information such as radar cooldown and disguiser activation are drawn on the screen. Used to write additional persistent text on the screen for player reference.\ *Realm:* Client\ *Added in:* 1.3.1\ @@ -328,6 +328,8 @@ Called after player information such as role, health, and ammo and equipment inf - *labelX* - The X value representing the correct indentation from the left side of the screen to add information - *labelY* - The Y value representing the first clear space to add information - *activeLabels* - The list of current active additional labels. Used to determine the labelY offset to use via: `labelY = labelY + (20 * #activeLabels)`. Be sure to insert an entry when you add your own label so other addons can space appropriately. *(Added in 1.6.11)* +- *x* - The X value representing the left edge of the player information HUD *(Added in 2.5.2)* +- *y* - The Y value representing the top edge of the player information HUD *(Added in 2.5.2)* ### TTTHUDInfoPositionOverride(client, x, y, width, height) Allows overriding the position of the player information HUD (role, health, ammo etc.).\ diff --git a/RELEASE.md b/RELEASE.md index 6461fcad7..bc60b943e 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -7,6 +7,7 @@ ### Developer - Added `TTTHUDInfoPositionOverride` hook to override the position of the player information HUD (role, health, ammo etc.) +- Added new `x` and `y` parameters to `TTTHUDInfoPaint` hook which provide the raw position of the player information HUD (i.e. agnostic of any existing labels) ## 2.5.1 **Released: July 25th, 2026** diff --git a/docs/api/hooks.html b/docs/api/hooks.html index fcf388169..0ea040041 100644 --- a/docs/api/hooks.html +++ b/docs/api/hooks.html @@ -507,6 +507,8 @@

 

(Added in 2.5.2) +
  • y - The Y value representing the top edge of the player information HUD   (Added in 2.5.2)
  • TTTHUDInfoPositionOverride(client, x, y, width, height)  

    diff --git a/gamemodes/terrortown/gamemode/cl_hud.lua b/gamemodes/terrortown/gamemode/cl_hud.lua index a791d0daf..0a1a0a137 100644 --- a/gamemodes/terrortown/gamemode/cl_hud.lua +++ b/gamemodes/terrortown/gamemode/cl_hud.lua @@ -25,12 +25,12 @@ local format = string.format local hide_role = GetConVar("ttt_hide_role") -- Fonts -surface.CreateFont("RoleState", { +surface.CreateFont("TraitorState", { font = GAMEMODE_DEFAULT_UI_FONT, size = 28, weight = 1000 }) -surface.CreateFont("RoleStateSmall", { +surface.CreateFont("TraitorStateSmall", { font = GAMEMODE_DEFAULT_UI_FONT, size = 24, weight = 1000 @@ -463,7 +463,7 @@ local function SpecHUDPaint(client) draw.RoundedBox(8, x, round_y, time_x - x, height, bg_colors.noround) local text = L[roundstate_string[GAMEMODE.round_state]] - CRHUD:ShadowedText(text, "RoleState", x + margin, round_y, COLOR_WHITE) + CRHUD:ShadowedText(text, "TraitorState", x + margin, round_y, COLOR_WHITE) -- Draw round/prep/post time remaining text = util.SimpleTime(MathMax(0, GetGlobalFloat("ttt_round_end", 0) - CurTime()), "%02i:%02i") @@ -483,8 +483,8 @@ end local ttt_health_label = CreateClientConVar("ttt_health_label", "0", true) -infoWidth = 250 -infoHeight = 94 +local infoWidth = 250 +local infoHeight = 94 local infohud_offset_max_x = ScrW() - infoWidth - (margin * 2) local infohud_offset_max_y = ScrH() - infoHeight - (margin * 2) - roleAreaHeight @@ -601,9 +601,9 @@ local function InfoPaint(client) if text then if #text > 10 then - CRHUD:ShadowedText(text, "RoleStateSmall", x + margin + 74, role_y + 2, COLOR_WHITE, TEXT_ALIGN_CENTER) + CRHUD:ShadowedText(text, "TraitorStateSmall", x + margin + 74, role_y + 2, COLOR_WHITE, TEXT_ALIGN_CENTER) else - CRHUD:ShadowedText(text, "RoleState", x + margin + 74, role_y, COLOR_WHITE, TEXT_ALIGN_CENTER) + CRHUD:ShadowedText(text, "TraitorState", x + margin + 74, role_y, COLOR_WHITE, TEXT_ALIGN_CENTER) end end @@ -664,7 +664,7 @@ local function InfoPaint(client) -- Allow other addons to add stuff to the player info HUD local active_labels = {} - CallHook("TTTHUDInfoPaint", nil, client, label_left, label_top, active_labels) + CallHook("TTTHUDInfoPaint", nil, client, label_left, label_top, active_labels, x, y - roleAreaHeight) end -- Paints player status HUD element in the bottom left diff --git a/gamemodes/terrortown/gamemode/roles/taskmaster/cl_taskmaster.lua b/gamemodes/terrortown/gamemode/roles/taskmaster/cl_taskmaster.lua index 31d182e7c..ab4f6d54f 100644 --- a/gamemodes/terrortown/gamemode/roles/taskmaster/cl_taskmaster.lua +++ b/gamemodes/terrortown/gamemode/roles/taskmaster/cl_taskmaster.lua @@ -172,7 +172,7 @@ local function DrawTask(task, height, isShadow) surface.DrawRect(xPos + margin + 2 + offset, height + checkboxSize + offset, checkboxSize, 2) surface.DrawRect(xPos + margin + checkboxSize + offset, height + 2 + offset, 2, checkboxSize) - surface.SetFont("RoleStateSmall") + surface.SetFont("TraitorStateSmall") surface.SetTextPos(xPos + (margin * 2) + checkboxSize + offset, height + offset) surface.DrawText(name) @@ -320,7 +320,7 @@ local function CreateTaskReroll(task, dscrollpanel) local buttonWidth, buttonHeight = 80, 45 local dname = vgui.Create("DLabel", dpanel) - dname:SetFont("RoleStateSmall") + dname:SetFont("TraitorStateSmall") dname:SetText(name) dname:SetPos(margin, margin) dname:SetWidth(width - (margin * 2) - buttonWidth - scrollBarWidth) From 37dd0b52f1f5e43ef830f77b548fdd0ecd6aa880 Mon Sep 17 00:00:00 2001 From: Malivil Date: Tue, 4 Aug 2026 14:00:23 -0400 Subject: [PATCH 15/26] Fixed players swallowed by the Cannibal still being able to trigger traitor traps --- RELEASE.md | 3 +++ gamemodes/terrortown/gamemode/roles/cannibal/cannibal.lua | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/RELEASE.md b/RELEASE.md index 6819581cb..2cf02dd81 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -3,6 +3,9 @@ ## 2.5.2 (Beta) **Released:** +### Fixes +- Fixed players swallowed by the Cannibal still being able to trigger traitor traps + ### Additions - Added ability to adjust the Cannibal's eat and digestion poop sound volumes diff --git a/gamemodes/terrortown/gamemode/roles/cannibal/cannibal.lua b/gamemodes/terrortown/gamemode/roles/cannibal/cannibal.lua index c7e4be3ab..e0220e6f3 100644 --- a/gamemodes/terrortown/gamemode/roles/cannibal/cannibal.lua +++ b/gamemodes/terrortown/gamemode/roles/cannibal/cannibal.lua @@ -114,6 +114,7 @@ local function Cannibal_TTTOnRoleAbilityDisabled(ply) ReleaseEatenPlayers(ply, ply:Nick() .. " felt unwell and spat you out!") end + ------------------------- -- EATEN PLAYER BLOCKS -- ------------------------- @@ -124,6 +125,12 @@ local function Cannibal_PlayerCanPickupWeapon(ply, wep) if ply.TTTCannibalEaten then return false end end +local function Cannibal_TTTCanUseTraitorButton(ent, ply) + if not IsValid(ply) then return end + + if ply.TTTCannibalEaten then return false end +end + local function ShouldBlockCommunications(listener, speaker) if not speaker.TTTCannibalEaten then return false end if listener.TTTCannibalEaten and listener.TTTCannibalEaten == speaker.TTTCannibalEaten then return false end @@ -235,6 +242,7 @@ ROLE_REGISTERED_HOOKS[ROLE_CANNIBAL] = { ["PlayerDeath"] = Cannibal_PlayerDeath, ["PlayerDisconnected"] = Cannibal_PlayerDisconnected, ["ScalePlayerDamage"] = Cannibal_ScalePlayerDamage, + ["TTTCanUseTraitorButton"] = Cannibal_TTTCanUseTraitorButton, ["TTTCheckForWin"] = Cannibal_TTTCheckForWin, ["TTTEndRound"] = Cannibal_TTTEndRound, ["TTTOnRoleAbilityDisabled"] = Cannibal_TTTOnRoleAbilityDisabled, From 2a8797625e2607f4e1c08de126ce0f7832b1d912 Mon Sep 17 00:00:00 2001 From: Malivil Date: Wed, 5 Aug 2026 07:41:44 -0400 Subject: [PATCH 16/26] Fixed various roles erroring about unsupported hook 'TTTUpdateRoleState' --- RELEASE.md | 1 + .../terrortown/gamemode/roles/assassin/cl_assassin.lua | 7 +++---- gamemodes/terrortown/gamemode/roles/cupid/cl_cupid.lua | 7 +++---- gamemodes/terrortown/gamemode/roles/guesser/cl_guesser.lua | 7 +++---- .../terrortown/gamemode/roles/hivemind/cl_hivemind.lua | 7 +++---- gamemodes/terrortown/gamemode/roles/killer/cl_killer.lua | 7 +++---- gamemodes/terrortown/gamemode/roles/medium/cl_medium.lua | 7 +++---- gamemodes/terrortown/gamemode/roles/shadow/cl_shadow.lua | 7 +++---- gamemodes/terrortown/gamemode/roles/vampire/cl_vampire.lua | 7 +++---- .../terrortown/gamemode/roles/vindicator/cl_vindicator.lua | 7 +++---- gamemodes/terrortown/gamemode/roles/zombie/cl_zombie.lua | 7 +++---- 11 files changed, 31 insertions(+), 40 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 2cf02dd81..b4df8ffe7 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -5,6 +5,7 @@ ### Fixes - Fixed players swallowed by the Cannibal still being able to trigger traitor traps +- Fixed various roles erroring about unsupported hook 'TTTUpdateRoleState' ### Additions - Added ability to adjust the Cannibal's eat and digestion poop sound volumes diff --git a/gamemodes/terrortown/gamemode/roles/assassin/cl_assassin.lua b/gamemodes/terrortown/gamemode/roles/assassin/cl_assassin.lua index b07edd302..f898048b0 100644 --- a/gamemodes/terrortown/gamemode/roles/assassin/cl_assassin.lua +++ b/gamemodes/terrortown/gamemode/roles/assassin/cl_assassin.lua @@ -175,7 +175,7 @@ local function EnableAssassinTargetHighlights() end) end -local function Assassin_Highlight_TTTUpdateRoleState() +AddHook("TTTUpdateRoleState", "Assassin_Highlight_TTTUpdateRoleState", function() client = LocalPlayer() assassin_target_vision = assassin_target_vision_enabled:GetBool() @@ -184,7 +184,7 @@ local function Assassin_Highlight_TTTUpdateRoleState() RemoveHook("PreDrawHalos", "Assassin_Highlight_PreDrawHalos") vision_enabled = false end -end +end) -- Handle enabling and disabling of highlighting local function Assassin_Highlight_Think() @@ -379,8 +379,7 @@ ROLE_REGISTERED_HOOKS[ROLE_ASSASSIN] = { ["TTTScoreboardPlayerRole"] = Assassin_TTTScoreboardPlayerRole, ["TTTScoringWinTitle"] = Assassin_TTTScoringWinTitle, ["TTTTargetIDPlayerTargetIcon"] = Assassin_TTTTargetIDPlayerTargetIcon, - ["TTTTargetIDPlayerText"] = Assassin_TTTTargetIDPlayerText, - ["TTTUpdateRoleState"] = Assassin_Highlight_TTTUpdateRoleState + ["TTTTargetIDPlayerText"] = Assassin_TTTTargetIDPlayerText } AddHook("TTTPrepareRound", "Assassin_TTTPrepareRound", function() diff --git a/gamemodes/terrortown/gamemode/roles/cupid/cl_cupid.lua b/gamemodes/terrortown/gamemode/roles/cupid/cl_cupid.lua index a4464df2a..ec371d5f1 100644 --- a/gamemodes/terrortown/gamemode/roles/cupid/cl_cupid.lua +++ b/gamemodes/terrortown/gamemode/roles/cupid/cl_cupid.lua @@ -302,7 +302,7 @@ local function EnableLoverHighlights() end) end -local function Cupid_Highlight_TTTUpdateRoleState() +AddHook("TTTUpdateRoleState", "Cupid_Highlight_TTTUpdateRoleState", function() client = LocalPlayer() lover_vision = cupid_lover_vision_enabled:GetBool() @@ -311,7 +311,7 @@ local function Cupid_Highlight_TTTUpdateRoleState() RemoveHook("PreDrawHalos", "Cupid_Highlight_PreDrawHalos") vision_enabled = false end -end +end) local function Cupid_Highlight_Think() if not IsPlayer(client) or not client:Alive() or client:IsSpec() then return end @@ -447,8 +447,7 @@ ROLE_REGISTERED_HOOKS[ROLE_CUPID] = { ["TTTTargetIDPlayerRing"] = Cupid_TTTTargetIDPlayerRing, ["TTTTargetIDPlayerRoleIcon"] = Cupid_TTTTargetIDPlayerRoleIcon, ["TTTTargetIDPlayerTargetIcon"] = Cupid_TTTTargetIDPlayerTargetIcon, - ["TTTTargetIDPlayerText"] = Cupid_TTTTargetIDPlayerText, - ["TTTUpdateRoleState"] = Cupid_Highlight_TTTUpdateRoleState + ["TTTTargetIDPlayerText"] = Cupid_TTTTargetIDPlayerText } AddHook("TTTPrepareRound", "Cupid_TTTPrepareRound", function() diff --git a/gamemodes/terrortown/gamemode/roles/guesser/cl_guesser.lua b/gamemodes/terrortown/gamemode/roles/guesser/cl_guesser.lua index a963f3210..9eb92513d 100644 --- a/gamemodes/terrortown/gamemode/roles/guesser/cl_guesser.lua +++ b/gamemodes/terrortown/gamemode/roles/guesser/cl_guesser.lua @@ -358,7 +358,7 @@ local function EnableGuesserTargetHighlights() end) end -local function Guesser_Highlight_TTTUpdateRoleState() +AddHook("TTTUpdateRoleState", "Guesser_Highlight_TTTUpdateRoleState", function() client = LocalPlayer() -- Disable highlights on role change @@ -366,7 +366,7 @@ local function Guesser_Highlight_TTTUpdateRoleState() RemoveHook("PreDrawHalos", "Guesser_Highlight_PreDrawHalos") vision_enabled = false end -end +end) local function Guesser_Highlight_Think() if not IsPlayer(client) or not client:Alive() or client:IsSpec() then return end @@ -451,8 +451,7 @@ ROLE_REGISTERED_HOOKS[ROLE_GUESSER] = { ["TTTScoringSummaryRender"] = Guesser_TTTScoringSummaryRender, ["TTTTargetIDPlayerRing"] = Guesser_TTTTargetIDPlayerRing, ["TTTTargetIDPlayerRoleIcon"] = Guesser_TTTTargetIDPlayerRoleIcon, - ["TTTTargetIDPlayerText"] = Guesser_TTTTargetIDPlayerText, - ["TTTUpdateRoleState"] = Guesser_Highlight_TTTUpdateRoleState + ["TTTTargetIDPlayerText"] = Guesser_TTTTargetIDPlayerText } AddHook("TTTPrepareRound", "Guesser_TTTPrepareRound", function() diff --git a/gamemodes/terrortown/gamemode/roles/hivemind/cl_hivemind.lua b/gamemodes/terrortown/gamemode/roles/hivemind/cl_hivemind.lua index 5c958826e..883ac15db 100644 --- a/gamemodes/terrortown/gamemode/roles/hivemind/cl_hivemind.lua +++ b/gamemodes/terrortown/gamemode/roles/hivemind/cl_hivemind.lua @@ -131,7 +131,7 @@ local function EnableHiveMindHighlights() end) end -local function HiveMind_Highlight_TTTUpdateRoleState() +AddHook("TTTUpdateRoleState", "HiveMind_Highlight_TTTUpdateRoleState", function() client = LocalPlayer() hivemind_vision = hivemind_vision_enabled:GetBool() @@ -140,7 +140,7 @@ local function HiveMind_Highlight_TTTUpdateRoleState() RemoveHook("PreDrawHalos", "HiveMind_Highlight_PreDrawHalos") vision_enabled = false end -end +end) -- Handle enabling and disabling of highlighting local function HiveMind_Highlight_Think() @@ -249,8 +249,7 @@ ROLE_REGISTERED_HOOKS[ROLE_HIVEMIND] = { ["TTTScoringWinTitle"] = HiveMind_TTTScoringWinTitle, ["TTTTargetIDPlayerRing"] = HiveMind_TTTTargetIDPlayerRing, ["TTTTargetIDPlayerRoleIcon"] = HiveMind_TTTTargetIDPlayerRoleIcon, - ["TTTTargetIDPlayerText"] = HiveMind_TTTTargetIDPlayerText, - ["TTTUpdateRoleState"] = HiveMind_Highlight_TTTUpdateRoleState + ["TTTTargetIDPlayerText"] = HiveMind_TTTTargetIDPlayerText } AddHook("TTTPrepareRound", "HiveMind_TTTPrepareRound", function() diff --git a/gamemodes/terrortown/gamemode/roles/killer/cl_killer.lua b/gamemodes/terrortown/gamemode/roles/killer/cl_killer.lua index 02888d4e1..f17a05296 100644 --- a/gamemodes/terrortown/gamemode/roles/killer/cl_killer.lua +++ b/gamemodes/terrortown/gamemode/roles/killer/cl_killer.lua @@ -76,7 +76,7 @@ local function EnableKillerHighlights() end) end -local function Killer_Highlight_TTTUpdateRoleState() +AddHook("TTTUpdateRoleState", "Killer_Highlight_TTTUpdateRoleState", function() client = LocalPlayer() killer_vision = killer_vision_enabled:GetBool() can_see_jesters = killer_can_see_jesters:GetBool() @@ -86,7 +86,7 @@ local function Killer_Highlight_TTTUpdateRoleState() RemoveHook("PreDrawHalos", "Killer_Highlight_PreDrawHalos") vision_enabled = false end -end +end) -- Handle enabling and disabling of highlighting local function Killer_Highlight_Think() @@ -214,8 +214,7 @@ ROLE_REGISTERED_HOOKS[ROLE_KILLER] = { ["TTTEventFinishText"] = Killer_TTTEventFinishText, ["TTTScoringWinTitle"] = Killer_TTTScoringWinTitle, ["TTTShouldPlayerSmoke"] = Killer_TTTShouldPlayerSmoke, - ["TTTTargetIDPlayerTargetIcon"] = Killer_TTTTargetIDPlayerTargetIcon, - ["TTTUpdateRoleState"] = Killer_Highlight_TTTUpdateRoleState + ["TTTTargetIDPlayerTargetIcon"] = Killer_TTTTargetIDPlayerTargetIcon } AddHook("TTTPrepareRound", "Killer_TTTPrepareRound", function() diff --git a/gamemodes/terrortown/gamemode/roles/medium/cl_medium.lua b/gamemodes/terrortown/gamemode/roles/medium/cl_medium.lua index 0e3b16298..fb62e1eb6 100644 --- a/gamemodes/terrortown/gamemode/roles/medium/cl_medium.lua +++ b/gamemodes/terrortown/gamemode/roles/medium/cl_medium.lua @@ -54,9 +54,9 @@ end) ------------------ local spirit_vision = true -local function Medium_RoleFeature_TTTUpdateRoleState() +AddHook("TTTUpdateRoleState", "Medium_RoleFeature_TTTUpdateRoleState", function() spirit_vision = medium_spirit_vision:GetBool() -end +end) local cacheTime = CurTime() local cacheLength = 5 @@ -380,6 +380,5 @@ ROLE_REGISTERED_HOOKS[ROLE_MEDIUM] = { ["PostDrawTranslucentRenderables"] = Medium_PostDrawTranslucentRenderables, ["Think"] = Medium_RoleFeature_Think, ["TTTScoreboardPlayerRole"] = Medium_TTTScoreboardPlayerRole, - ["TTTScoreGroup"] = Medium_TTTScoreGroup, - ["TTTUpdateRoleState"] = Medium_RoleFeature_TTTUpdateRoleState + ["TTTScoreGroup"] = Medium_TTTScoreGroup } \ No newline at end of file diff --git a/gamemodes/terrortown/gamemode/roles/shadow/cl_shadow.lua b/gamemodes/terrortown/gamemode/roles/shadow/cl_shadow.lua index fa7923e88..4081701c3 100644 --- a/gamemodes/terrortown/gamemode/roles/shadow/cl_shadow.lua +++ b/gamemodes/terrortown/gamemode/roles/shadow/cl_shadow.lua @@ -256,7 +256,7 @@ local function EnableShadowTargetHighlights() end) end -local function Shadow_Highlight_TTTUpdateRoleState() +AddHook("TTTUpdateRoleState", "Shadow_Highlight_TTTUpdateRoleState", function() client = client or LocalPlayer() -- Disable highlights on role change @@ -264,7 +264,7 @@ local function Shadow_Highlight_TTTUpdateRoleState() RemoveHook("PreDrawHalos", "Shadow_Highlight_PreDrawHalos") vision_enabled = false end -end +end) -- Handle enabling and disabling of highlighting local function Shadow_Highlight_Think() @@ -675,8 +675,7 @@ ROLE_REGISTERED_HOOKS[ROLE_SHADOW] = { ["TTTTargetIDPlayerRing"] = Shadow_TTTTargetIDPlayerRing, ["TTTTargetIDPlayerRoleIcon"] = Shadow_TTTTargetIDPlayerRoleIcon, ["TTTTargetIDPlayerTargetIcon"] = Shadow_TTTTargetIDPlayerTargetIcon, - ["TTTTargetIDPlayerText"] = Shadow_TTTTargetIDPlayerText, - ["TTTUpdateRoleState"] = Shadow_Highlight_TTTUpdateRoleState + ["TTTTargetIDPlayerText"] = Shadow_TTTTargetIDPlayerText } AddHook("TTTPrepareRound", "Shadow_TTTPrepareRound", function() diff --git a/gamemodes/terrortown/gamemode/roles/vampire/cl_vampire.lua b/gamemodes/terrortown/gamemode/roles/vampire/cl_vampire.lua index b7afa9c8d..99a6a95d3 100644 --- a/gamemodes/terrortown/gamemode/roles/vampire/cl_vampire.lua +++ b/gamemodes/terrortown/gamemode/roles/vampire/cl_vampire.lua @@ -207,7 +207,7 @@ local function EnableVampireHighlights() end) end -local function Vampire_Highlight_TTTUpdateRoleState() +AddHook("TTTUpdateRoleState", "Vampire_Highlight_TTTUpdateRoleState", function() client = LocalPlayer() vampire_vision = vampire_vision_enabled:GetBool() jesters_visible_to_traitors = GetConVar("ttt_jesters_visible_to_traitors"):GetBool() @@ -219,7 +219,7 @@ local function Vampire_Highlight_TTTUpdateRoleState() RemoveHook("PreDrawHalos", "Vampire_Highlight_PreDrawHalos") vision_enabled = false end -end +end) -- Handle enabling and disabling of highlighting local function Vampire_Highlight_Think() @@ -329,8 +329,7 @@ ROLE_REGISTERED_HOOKS[ROLE_VAMPIRE] = { ["TTTRolePopupParams"] = Vampire_TTTRolePopupParams, ["TTTScoringSummaryRender"] = Vampire_TTTScoringSummaryRender, ["TTTScoringWinTitle"] = Vampire_TTTScoringWinTitle, - ["TTTTargetIDPlayerTargetIcon"] = Vampire_TTTTargetIDPlayerTargetIcon, - ["TTTUpdateRoleState"] = Vampire_Highlight_TTTUpdateRoleState + ["TTTTargetIDPlayerTargetIcon"] = Vampire_TTTTargetIDPlayerTargetIcon } AddHook("TTTPrepareRound", "Vampire_TTTPrepareRound", function() diff --git a/gamemodes/terrortown/gamemode/roles/vindicator/cl_vindicator.lua b/gamemodes/terrortown/gamemode/roles/vindicator/cl_vindicator.lua index 9166de105..c720a4445 100644 --- a/gamemodes/terrortown/gamemode/roles/vindicator/cl_vindicator.lua +++ b/gamemodes/terrortown/gamemode/roles/vindicator/cl_vindicator.lua @@ -126,7 +126,7 @@ local function EnableVindicatorTargetHighlights() end) end -local function Vindicator_Highlight_TTTUpdateRoleState() +AddHook("TTTUpdateRoleState", "Vindicator_Highlight_TTTUpdateRoleState", function() client = LocalPlayer() -- Disable highlights on role change @@ -134,7 +134,7 @@ local function Vindicator_Highlight_TTTUpdateRoleState() RemoveHook("PreDrawHalos", "Vindicator_Highlight_PreDrawHalos") vision_enabled = false end -end +end) -- Handle enabling and disabling of highlighting local function Vindicator_Highlight_Think() @@ -350,8 +350,7 @@ ROLE_REGISTERED_HOOKS[ROLE_VINDICATOR] = { ["TTTScoringSummaryRender"] = Vindicator_TTTScoringSummaryRender, ["TTTScoringWinTitle"] = Vindicator_TTTScoringWinTitle, ["TTTTargetIDPlayerTargetIcon"] = Vindicator_TTTTargetIDPlayerTargetIcon, - ["TTTTargetIDPlayerText"] = Vindicator_TTTTargetIDPlayerText, - ["TTTUpdateRoleState"] = Vindicator_Highlight_TTTUpdateRoleState + ["TTTTargetIDPlayerText"] = Vindicator_TTTTargetIDPlayerText } AddHook("TTTPrepareRound", "Vindicator_TTTPrepareRound", function() diff --git a/gamemodes/terrortown/gamemode/roles/zombie/cl_zombie.lua b/gamemodes/terrortown/gamemode/roles/zombie/cl_zombie.lua index 2a1b230a8..f1ebe12c2 100644 --- a/gamemodes/terrortown/gamemode/roles/zombie/cl_zombie.lua +++ b/gamemodes/terrortown/gamemode/roles/zombie/cl_zombie.lua @@ -257,7 +257,7 @@ local function EnableZombieHighlights() end) end -local function Zombie_Highlight_TTTUpdateRoleState() +AddHook("TTTUpdateRoleState", "Zombie_Highlight_TTTUpdateRoleState", function() client = LocalPlayer() zombie_vision = zombie_vision_enabled:GetBool() jesters_visible_to_traitors = GetConVar("ttt_jesters_visible_to_traitors"):GetBool() @@ -269,7 +269,7 @@ local function Zombie_Highlight_TTTUpdateRoleState() RemoveHook("PreDrawHalos", "Zombie_Highlight_PreDrawHalos") vision_enabled = false end -end +end) -- Handle enabling and disabling of highlighting local function Zombie_Highlight_Think() @@ -381,8 +381,7 @@ ROLE_REGISTERED_HOOKS[ROLE_ZOMBIE] = { ["TTTTargetIDPlayerRing"] = Zombie_TTTTargetIDPlayerRing, ["TTTTargetIDPlayerRoleIcon"] = Zombie_TTTTargetIDPlayerRoleIcon, ["TTTTargetIDPlayerTargetIcon"] = Zombie_TTTTargetIDPlayerTargetIcon, - ["TTTTargetIDPlayerText"] = Zombie_TTTTargetIDPlayerText, - ["TTTUpdateRoleState"] = Zombie_Highlight_TTTUpdateRoleState + ["TTTTargetIDPlayerText"] = Zombie_TTTTargetIDPlayerText } AddHook("TTTPrepareRound", "Zombie_TTTPrepareRound", function() From 78218d0c6a9becd06793015a7c6a21dae0145067 Mon Sep 17 00:00:00 2001 From: Malivil Date: Wed, 5 Aug 2026 07:42:48 -0400 Subject: [PATCH 17/26] Removed beta marking from release notes --- RELEASE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index b4df8ffe7..940033ad0 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,6 +1,6 @@ # Release Notes -## 2.5.2 (Beta) +## 2.5.2 **Released:** ### Fixes From 37eee102cc9c60037f4effbee52213637008f003 Mon Sep 17 00:00:00 2001 From: Malivil Date: Wed, 5 Aug 2026 21:13:28 -0400 Subject: [PATCH 18/26] Added the new role that a player gets by being deputized by a Marshal to the event log message --- RELEASE.md | 3 +++ .../terrortown/gamemode/roles/marshal/cl_marshal.lua | 12 ++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 940033ad0..aef556378 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -3,6 +3,9 @@ ## 2.5.2 **Released:** +### Additions +- Added the new role that a player gets by being deputized by a Marshal to the event log message + ### Fixes - Fixed players swallowed by the Cannibal still being able to trigger traitor traps - Fixed various roles erroring about unsupported hook 'TTTUpdateRoleState' diff --git a/gamemodes/terrortown/gamemode/roles/marshal/cl_marshal.lua b/gamemodes/terrortown/gamemode/roles/marshal/cl_marshal.lua index c5e25d25b..ea2ad56a2 100644 --- a/gamemodes/terrortown/gamemode/roles/marshal/cl_marshal.lua +++ b/gamemodes/terrortown/gamemode/roles/marshal/cl_marshal.lua @@ -22,7 +22,7 @@ AddHook("Initialize", "Marshal_Translations_Initialize", function() LANG.AddToLanguage("english", "marshalbadge_help_sec", "The target player will become " .. ROLE_STRINGS_EXT[ROLE_DEPUTY] .. " or " .. ROLE_STRINGS[ROLE_IMPERSONATOR]) -- Event - LANG.AddToLanguage("english", "ev_marshal_deputize", "{target} was deputized by {marshal}") + LANG.AddToLanguage("english", "ev_marshal_deputize", "{target} was deputized by {marshal}, converting them into {role}") -- Announcement LANG.AddToLanguage("english", "marshal_deputize_announce", "{amarshal} has promoted {target} to be {adeputy}") @@ -55,7 +55,7 @@ AddHook("Initialize", "Marshal_Scoring_Initialize", function() local PT = LANG.GetParamTranslation Event(EVENT_DEPUTIZED, { text = function(e) - return PT("ev_marshal_deputize", {target = e.tar, marshal = e.ply}) + return PT("ev_marshal_deputize", {target = e.tar, marshal = e.ply, role = e.rol}) end, icon = function(e) return traitor_icon, "Deputized" @@ -66,9 +66,17 @@ net.Receive("TTT_Deputized", function(len) local marshalname = net.ReadString() local targetname = net.ReadString() local targetsid = net.ReadString() + + local targetply = player.GetBySteamID64(targetsid) + local targetrole = "" + if IsValid(targetply) then + targetrole = ROLE_STRINGS_EXT[targetply:GetRole()] + end + CLSCORE:AddEvent({ id = EVENT_DEPUTIZED, tar = targetname, + rol = targetrole, ply = marshalname, sid64 = targetsid, bonus = 1 From f4fed1df2c6129e633e96a7f415de00eeb2645fd Mon Sep 17 00:00:00 2001 From: Malivil Date: Wed, 5 Aug 2026 21:46:46 -0400 Subject: [PATCH 19/26] Added ability to control whether killing the Sponge ends the round (enabled by default) --- CONVARS.md | 3 +++ RELEASE.md | 1 + docs/teams/jester.html | 6 ++++++ .../gamemode/roles/sponge/cl_sponge.lua | 20 ++++++++++++++++++- .../gamemode/roles/sponge/shared.lua | 4 ++++ .../gamemode/roles/sponge/sponge.lua | 9 +++++++++ 6 files changed, 42 insertions(+), 1 deletion(-) diff --git a/CONVARS.md b/CONVARS.md index 2f1022309..aa354207d 100644 --- a/CONVARS.md +++ b/CONVARS.md @@ -740,6 +740,8 @@ ttt_sponge_device_for_beggar 0 // Whether the Beggar sho ttt_sponge_device_for_beggar_heal 0 // Whether the Beggar should be fully healed when using the spongifier ttt_sponge_device_for_bodysnatcher 0 // Whether the Bodysnatcher should get the spongifier ttt_sponge_device_for_bodysnatcher_heal 0 // Whether the Bodysnatcher be fully healed when using the spongifier +ttt_sponge_device_for_cannibal 0 // Whether the Cannibal should get the spongifier +ttt_sponge_device_for_cannibal_heal 0 // Whether the Cannibal should be fully healed when using the spongifier ttt_sponge_device_for_clown 0 // Whether the Clown should get the spongifier ttt_sponge_device_for_clown_heal 0 // Whether the Clown should be fully healed when using the spongifier ttt_sponge_device_for_cupid 0 // Whether the Cupid should get the spongifier @@ -754,6 +756,7 @@ ttt_sponge_device_for_shadow 0 // Whether the Shadow sho ttt_sponge_device_for_shadow_heal 0 // Whether the Shadow should be fully healed when using the spongifier (only created and used when "ttt_shadow_is_jester" is enabled) ttt_sponge_device_for_swapper 0 // Whether the Swapper should get the spongifier ttt_sponge_device_for_swapper_heal 0 // Whether the Swapper should be fully healed when using the spongifier +ttt_sponge_win_ends_round 1 // Whether the round should end when the Sponge wins // Guesser ttt_guesser_can_guess_detectives 0 // Whether the Guesser is allowed to guess detectives diff --git a/RELEASE.md b/RELEASE.md index aef556378..4f40c2485 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -5,6 +5,7 @@ ### Additions - Added the new role that a player gets by being deputized by a Marshal to the event log message +- Added ability to control whether killing the Sponge ends the round (enabled by default) ### Fixes - Fixed players swallowed by the Cannibal still being able to trigger traitor traps diff --git a/docs/teams/jester.html b/docs/teams/jester.html index de92e41d8..b0db195d6 100644 --- a/docs/teams/jester.html +++ b/docs/teams/jester.html @@ -1217,6 +1217,12 @@

    Role Configuration:

    Boolean Whether a specific jester role should be fully healed when using the spongifier. Replace * with the name of the jester role you want to configure without spaces or capital letters. + + ttt_sponge_win_ends_round   + 1 + Boolean + Whether the round should end when the Sponge wins. +

    A list of ConVars shared by every role and instructions for using ConVars can be found on the Configuring ConVars tutorial page.

    diff --git a/gamemodes/terrortown/gamemode/roles/sponge/cl_sponge.lua b/gamemodes/terrortown/gamemode/roles/sponge/cl_sponge.lua index ece808b25..2c4bc6ead 100644 --- a/gamemodes/terrortown/gamemode/roles/sponge/cl_sponge.lua +++ b/gamemodes/terrortown/gamemode/roles/sponge/cl_sponge.lua @@ -1,12 +1,14 @@ local hook = hook local math = math local player = player +local table = table local AddHook = hook.Add local MathCos = math.cos local MathSin = math.sin -local StringUpper = string.upper local PlayerIterator = player.Iterator +local StringUpper = string.upper +local TableInsert = table.insert ------------- -- CONVARS -- @@ -217,6 +219,21 @@ local function Sponge_TTTScoringWinTitle(wintype, wintitles, title, secondary_wi end end +local sponge_wins = false +local function Sponge_TTTScoringSecondaryWins(wintype, secondary_wins) + if sponge_wins then + TableInsert(secondary_wins, ROLE_SPONGE) + end +end + +net.Receive("TTT_SpongeWin", function() + sponge_wins = true +end) + +AddHook("TTTPrepareRound", "Sponge_TTTPrepareRound", function() + sponge_wins = false +end) + ------------ -- EVENTS -- ------------ @@ -291,6 +308,7 @@ ROLE_REGISTERED_HOOKS[ROLE_SPONGE] = { ["TTTEventFinishText"] = Sponge_TTTEventFinishText, ["TTTPlayerAliveClientThink"] = Sponge_RoleFeatures_TTTPlayerAliveClientThink, ["TTTScoreboardPlayerRole"] = Sponge_TTTScoreboardPlayerRole, + ["TTTScoringSecondaryWins"] = Sponge_TTTScoringSecondaryWins, ["TTTScoringSummaryRender"] = Sponge_TTTScoringSummaryRender, ["TTTScoringWinTitle"] = Sponge_TTTScoringWinTitle, ["TTTTargetIDPlayerRing"] = Sponge_TTTTargetIDPlayerRing, diff --git a/gamemodes/terrortown/gamemode/roles/sponge/shared.lua b/gamemodes/terrortown/gamemode/roles/sponge/shared.lua index dfc41c919..3b3da7d82 100644 --- a/gamemodes/terrortown/gamemode/roles/sponge/shared.lua +++ b/gamemodes/terrortown/gamemode/roles/sponge/shared.lua @@ -33,6 +33,10 @@ TableInsert(ROLE_CONVARS[ROLE_SPONGE], { type = ROLE_CONVAR_TYPE_NUM, decimal = 0 }) +TableInsert(ROLE_CONVARS[ROLE_SPONGE], { + cvar = "ttt_sponge_win_ends_round", + type = ROLE_CONVAR_TYPE_BOOL +}) TableInsert(ROLE_CONVARS[ROLE_SPONGE], { cvar = "ttt_sponge_notify_mode", type = ROLE_CONVAR_TYPE_DROPDOWN, diff --git a/gamemodes/terrortown/gamemode/roles/sponge/sponge.lua b/gamemodes/terrortown/gamemode/roles/sponge/sponge.lua index c78aab07a..a018ac002 100644 --- a/gamemodes/terrortown/gamemode/roles/sponge/sponge.lua +++ b/gamemodes/terrortown/gamemode/roles/sponge/sponge.lua @@ -8,6 +8,8 @@ local timer = timer local AddHook = hook.Add local PlayerIterator = player.Iterator +util.AddNetworkString("TTT_SpongeWin") + ------------- -- CONVARS -- ------------- @@ -16,6 +18,7 @@ CreateConVar("ttt_sponge_notify_mode", "0", FCVAR_NONE, "The logic to use when n CreateConVar("ttt_sponge_notify_killer", "1", FCVAR_NONE, "Whether to notify a sponge's killer", 0, 1) CreateConVar("ttt_sponge_notify_sound", "0", FCVAR_NONE, "Whether to play a cheering sound when a sponge is killed", 0, 1) CreateConVar("ttt_sponge_notify_confetti", "0", FCVAR_NONE, "Whether to throw confetti when a sponge is a killed", 0, 1) +local sponge_win_ends_round = CreateConVar("ttt_sponge_win_ends_round", "1", FCVAR_NONE, "Whether the round should end when the sponge wins", 0, 1) local sponge_aura_float_time = CreateConVar("ttt_sponge_aura_float_time", "0", FCVAR_NONE, "The amount of time (in seconds) a player can spend outside the Sponge's aura before they are no longer considered inside", 0, 10) local sponge_aura_radius = GetConVar("ttt_sponge_aura_radius") @@ -201,6 +204,12 @@ local function Sponge_WinCheck_PlayerDeath(victim, infl, attacker) SpongeKilledNotification(attacker, victim) victim:SetNWString("SpongeKiller", attacker:Nick()) + if not sponge_win_ends_round:GetBool() then + net.Start("TTT_SpongeWin") + net.Broadcast() + return + end + -- If we're debugging, don't end the round if GetConVar("ttt_debug_preventwin"):GetBool() then return From db49897687028ada628e7729d0442b723a046062 Mon Sep 17 00:00:00 2001 From: Malivil Date: Thu, 6 Aug 2026 07:40:34 -0400 Subject: [PATCH 20/26] Cleanup --- gamemodes/terrortown/entities/weapons/weapon_kil_crowbar.lua | 1 - gamemodes/terrortown/entities/weapons/weapon_kil_knife.lua | 1 - .../terrortown/entities/weapons/weapon_qua_bomb_station.lua | 1 - .../terrortown/entities/weapons/weapon_qua_station_bomb.lua | 1 - gamemodes/terrortown/entities/weapons/weapon_spy_flaregun.lua | 1 - 5 files changed, 5 deletions(-) diff --git a/gamemodes/terrortown/entities/weapons/weapon_kil_crowbar.lua b/gamemodes/terrortown/entities/weapons/weapon_kil_crowbar.lua index 7892509d1..174775fc9 100644 --- a/gamemodes/terrortown/entities/weapons/weapon_kil_crowbar.lua +++ b/gamemodes/terrortown/entities/weapons/weapon_kil_crowbar.lua @@ -41,7 +41,6 @@ SWEP.Secondary.Delay = 1 SWEP.IsGrenade = false SWEP.Kind = WEAPON_MELEE -SWEP.WeaponID = AMMO_CROWBAR SWEP.NoSights = true SWEP.IsSilent = true diff --git a/gamemodes/terrortown/entities/weapons/weapon_kil_knife.lua b/gamemodes/terrortown/entities/weapons/weapon_kil_knife.lua index a5327d997..2a29d15aa 100644 --- a/gamemodes/terrortown/entities/weapons/weapon_kil_knife.lua +++ b/gamemodes/terrortown/entities/weapons/weapon_kil_knife.lua @@ -44,7 +44,6 @@ SWEP.Secondary.Ammo = "none" SWEP.Secondary.Delay = 12 SWEP.Kind = WEAPON_NONE -SWEP.WeaponID = AMMO_CROWBAR SWEP.IsSilent = true diff --git a/gamemodes/terrortown/entities/weapons/weapon_qua_bomb_station.lua b/gamemodes/terrortown/entities/weapons/weapon_qua_bomb_station.lua index 03bc44d1d..2fcc18eed 100644 --- a/gamemodes/terrortown/entities/weapons/weapon_qua_bomb_station.lua +++ b/gamemodes/terrortown/entities/weapons/weapon_qua_bomb_station.lua @@ -46,7 +46,6 @@ SWEP.Secondary.Delay = 1.0 SWEP.Kind = WEAPON_EQUIP SWEP.CanBuy = { ROLE_QUACK } SWEP.LimitedStock = true -SWEP.WeaponID = AMMO_HEALTHSTATION SWEP.AllowDrop = false SWEP.NoSights = true diff --git a/gamemodes/terrortown/entities/weapons/weapon_qua_station_bomb.lua b/gamemodes/terrortown/entities/weapons/weapon_qua_station_bomb.lua index f2a7604c2..65bcf0fdf 100644 --- a/gamemodes/terrortown/entities/weapons/weapon_qua_station_bomb.lua +++ b/gamemodes/terrortown/entities/weapons/weapon_qua_station_bomb.lua @@ -27,7 +27,6 @@ SWEP.Category = WEAPON_CATEGORY_ROLE SWEP.CanBuy = { ROLE_QUACK } -- This is special equipment SWEP.Kind = WEAPON_EQUIP2 -SWEP.WeaponID = AMMO_STATIONBOMB SWEP.BlockShopRandomization = true diff --git a/gamemodes/terrortown/entities/weapons/weapon_spy_flaregun.lua b/gamemodes/terrortown/entities/weapons/weapon_spy_flaregun.lua index 241e297a6..791808d61 100644 --- a/gamemodes/terrortown/entities/weapons/weapon_spy_flaregun.lua +++ b/gamemodes/terrortown/entities/weapons/weapon_spy_flaregun.lua @@ -41,7 +41,6 @@ SWEP.Kind = WEAPON_ROLE SWEP.CanBuy = {} -- only traitors can buy SWEP.LimitedStock = true -- only buyable once SWEP.AllowDrop = false -SWEP.WeaponID = AMMO_FLARE SWEP.Tracer = "AR2Tracer" From 9eea72b4b3af1cf6f2ea763abfd744afd8e7362b Mon Sep 17 00:00:00 2001 From: Malivil Date: Fri, 7 Aug 2026 08:44:33 -0400 Subject: [PATCH 21/26] Added SpecSpirits script for people who want to see spectator spirit wisps even if there isn't a medium in the round --- scripts/specspirits.lua | 113 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 scripts/specspirits.lua diff --git a/scripts/specspirits.lua b/scripts/specspirits.lua new file mode 100644 index 000000000..fd9248815 --- /dev/null +++ b/scripts/specspirits.lua @@ -0,0 +1,113 @@ +AddCSLuaFile() + +local ents = ents +local hook = hook + +if SERVER then + local player = player + local timer = timer + + local CreateEntity = ents.Create + local PlayerIterator = player.Iterator + + local function CreateSpectatorSpirit(ply) + if IsValid(ply.SpiritEnt) then return end + if IsValid(ply.SpecSpiritEnt) then return end + if ply:Alive() or not ply:IsSpec() then return end + if ply:GetRole() == ROLE_NONE then return end + + local spirit = CreateEntity("npc_kleiner") + spirit:SetPos(ply:GetPos()) + spirit:SetRenderMode(RENDERMODE_NONE) + spirit:SetNotSolid(true) + spirit:DrawShadow(false) + spirit:AddFlags(FL_NOTARGET) + spirit:SetNWString("SpecSpiritOwner", ply:SteamID64()) + spirit:SetNWVector("SpecSpiritColor", ply:GetNWVector("PlayerColor", col)) + spirit:Spawn() + + ply.SpecSpiritEnt = spirit + end + + hook.Add("PlayerDeath", "SpecSpirits_PlayerDeath", function(victim, infl, attacker) + -- Wait so the Medium logic has a chance to run first + timer.Simple(0, function() + if not IsPlayer(victim) then return end + print("[SpecSpirits] Creating spirit for " .. victim:Nick()) + CreateSpectatorSpirit(victim) + end) + end) + + hook.Add("FinishMove", "SpecSpirits_FinishMove", function(ply, mv) + if not IsValid(ply) or not ply:IsSpec() then return end + if not IsValid(ply.SpecSpiritEnt) then return end + + ply.SpecSpiritEnt:SetPos(ply:GetPos()) + + local show = ply:GetObserverMode() == OBS_MODE_ROAMING + ply.SpecSpiritEnt:SetProperty("SpecSpiritVisible", show) + end) + + hook.Add("TTTPrepareRound", "SpecSpirits_TTTPrepareRound", function() + for _, p in PlayerIterator() do + SafeRemoveEntity(p.SpecSpiritEnt) + p.SpecSpiritEnt = nil + end + end) +end + +if CLIENT then + local math = math + + local EntsFindByClass = ents.FindByClass + local MathRand = math.Rand + local MathRandom = math.random + + local client + local wispOffset = Vector(0, 0, 64) + local wispVelocity = Vector(0, 0, 30) + local wispColor = Vector(1, 1, 1) + hook.Add("Think", "SpecSpirits_Think", function() + if GetRoundState() ~= ROUND_ACTIVE then return end + + if not client then + client = LocalPlayer() + end + if client:Alive() or not client:IsSpec() then return end + + for _, ent in ipairs(EntsFindByClass("npc_kleiner")) do + if ent.SpecSpiritVisible then + local curTime = CurTime() + + ent:SetNoDraw(true) + ent:SetRenderMode(RENDERMODE_NONE) + ent:SetNotSolid(true) + ent:DrawShadow(false) + if not ent.SpecSpiritEmitter then ent.SpecSpiritEmitter = ParticleEmitter(ent:GetPos()) end + if not ent.SpecSpiritNextPart then ent.SpecSpiritNextPart = curTime end + local pos = ent:GetPos() + wispOffset + -- Use DistToSqr as it's more efficient and this is called very frequently + -- 9000000 = 3000^2 + if ent.SpecSpiritNextPart < curTime and client:GetPos():DistToSqr(pos) <= 9000000 then + ent.SpecSpiritEmitter:SetPos(pos) + ent.SpecSpiritNextPart = curTime + MathRand(0.003, 0.01) + local particle = ent.SpecSpiritEmitter:Add("particle/wisp.vmt", pos) + particle:SetVelocity(wispVelocity) + particle:SetDieTime(1) + particle:SetStartAlpha(MathRandom(150, 220)) + particle:SetEndAlpha(0) + local size = MathRandom(4, 7) + particle:SetStartSize(size) + particle:SetEndSize(1) + particle:SetRoll(MathRand(0, math.pi)) + particle:SetRollDelta(0) + local col = ent:GetNWVector("SpecSpiritColor", wispColor) + particle:SetColor(col.x * 255, col.y * 255, col.z * 255) + end + elseif ent.SpecSpiritEmitter then + ent.SpecSpiritEmitter:Finish() + ent.SpecSpiritEmitter = nil + end + end + end) +end \ No newline at end of file From 210fe8910f3c2a6130091994452dfe24acc27b18 Mon Sep 17 00:00:00 2001 From: Malivil Date: Fri, 7 Aug 2026 08:46:26 -0400 Subject: [PATCH 22/26] Fixed default color --- scripts/specspirits.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/specspirits.lua b/scripts/specspirits.lua index fd9248815..3cf6e2abc 100644 --- a/scripts/specspirits.lua +++ b/scripts/specspirits.lua @@ -10,6 +10,7 @@ if SERVER then local CreateEntity = ents.Create local PlayerIterator = player.Iterator + local defaultColor = Vector(1, 1, 1) local function CreateSpectatorSpirit(ply) if IsValid(ply.SpiritEnt) then return end if IsValid(ply.SpecSpiritEnt) then return end @@ -23,7 +24,7 @@ if SERVER then spirit:DrawShadow(false) spirit:AddFlags(FL_NOTARGET) spirit:SetNWString("SpecSpiritOwner", ply:SteamID64()) - spirit:SetNWVector("SpecSpiritColor", ply:GetNWVector("PlayerColor", col)) + spirit:SetNWVector("SpecSpiritColor", ply:GetNWVector("PlayerColor", defaultColor)) spirit:Spawn() ply.SpecSpiritEnt = spirit From 6ad1e371c68c7c45024747e587beb817f61e8e94 Mon Sep 17 00:00:00 2001 From: Malivil Date: Sat, 8 Aug 2026 12:04:59 -0400 Subject: [PATCH 23/26] Updated release date --- RELEASE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index ae510dd82..ef7b4236e 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,7 +1,7 @@ # Release Notes ## 2.5.2 (Beta) -**Released:** +**Released: August 8th, 2026** ### Additions - Added the new role that a player gets by being deputized by a Marshal to the event log message From 6a5dd26184c8a49a9c4d47594d90a7996ea2a7a2 Mon Sep 17 00:00:00 2001 From: Malivil Date: Sat, 8 Aug 2026 18:13:53 -0400 Subject: [PATCH 24/26] Fixed Cannibal's "Swallowed" label not staying with the info panel when it is moved --- .../terrortown/gamemode/roles/cannibal/cl_cannibal.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua b/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua index 1f0a019e2..137e38f58 100644 --- a/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua +++ b/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua @@ -164,7 +164,7 @@ end -- HUD -- --------- -local function Cannibal_HUDDrawScoreBoard() +local function Cannibal_TTTHUDInfoPaint(cli, label_left, label_top, active_labels, x, y) if not IsPlayer(client) then client = LocalPlayer() end @@ -177,8 +177,10 @@ local function Cannibal_HUDDrawScoreBoard() fill = ROLE_COLORS[ROLE_CANNIBAL] } - CRHUD:PaintBar(8, 20, ScrH() - 59, 230, 25, bar_colors, 1) - draw.SimpleText(LANG.GetTranslation("cannibal_swallowed"), "HealthAmmo", 135, ScrH() - 59, Color(255, 255, 255, 200), TEXT_ALIGN_CENTER) + local barX = x + 10 + local barY = y + 75 + CRHUD:PaintBar(8, barX, barY, 230, 25, bar_colors, 1) + draw.SimpleText(LANG.GetTranslation("cannibal_swallowed"), "HealthAmmo", x + 125, barY, Color(255, 255, 255, 200), TEXT_ALIGN_CENTER) end -------------- @@ -228,9 +230,9 @@ end) ------------------ ROLE_REGISTERED_HOOKS[ROLE_CANNIBAL] = { - ["HUDDrawScoreBoard"] = Cannibal_HUDDrawScoreBoard, ["TTTEventFinishIconText"] = Cannibal_TTTEventFinishIconText, ["TTTEventFinishText"] = Cannibal_TTTEventFinishText, + ["TTTHUDInfoPaint"] = Cannibal_TTTHUDInfoPaint, ["TTTScoreGroup"] = Cannibal_TTTScoreGroup, ["TTTScoreboardPlayerName"] = Cannibal_TTTScoreboardPlayerName, ["TTTScoreboardPlayerRole"] = Cannibal_TTTScoreboardPlayerRole, From 63cfda120543860a063eb9289d547a07db881904 Mon Sep 17 00:00:00 2001 From: Malivil Date: Sat, 8 Aug 2026 18:20:01 -0400 Subject: [PATCH 25/26] Cleanup --- .../terrortown/gamemode/roles/cannibal/cl_cannibal.lua | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua b/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua index 137e38f58..6893a8291 100644 --- a/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua +++ b/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua @@ -165,11 +165,7 @@ end --------- local function Cannibal_TTTHUDInfoPaint(cli, label_left, label_top, active_labels, x, y) - if not IsPlayer(client) then - client = LocalPlayer() - end - - if not client.TTTCannibalEaten then return end + if not cli.TTTCannibalEaten then return end local bar_colors = { border = COLOR_WHITE, From 7d4b73bfb1d4fa2157af7395b591602b605aacd0 Mon Sep 17 00:00:00 2001 From: Malivil Date: Sat, 8 Aug 2026 21:03:11 -0400 Subject: [PATCH 26/26] Removed beta-only markings --- RELEASE.md | 2 +- docs/api/hooks.html | 6 +++--- docs/teams/jester.html | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index ef7b4236e..4d938ae40 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,6 +1,6 @@ # Release Notes -## 2.5.2 (Beta) +## 2.5.2 **Released: August 8th, 2026** ### Additions diff --git a/docs/api/hooks.html b/docs/api/hooks.html index 0ea040041..02ac5ce9a 100644 --- a/docs/api/hooks.html +++ b/docs/api/hooks.html @@ -507,11 +507,11 @@

     

    (Added in 2.5.2) -
  • y - The Y value representing the top edge of the player information HUD   (Added in 2.5.2)
  • +
  • x - The X value representing the left edge of the player information HUD (Added in 2.5.2)
  • +
  • y - The Y value representing the top edge of the player information HUD (Added in 2.5.2)
  • -

    TTTHUDInfoPositionOverride(client, x, y, width, height)  

    +

    TTTHUDInfoPositionOverride(client, x, y, width, height)

    Allows overriding the position of the player information HUD (role, health, ammo etc.).
    Realm: Client
    diff --git a/docs/teams/jester.html b/docs/teams/jester.html index b0db195d6..3f1833116 100644 --- a/docs/teams/jester.html +++ b/docs/teams/jester.html @@ -601,7 +601,7 @@

    Role Configuration:

    Whether the Cannibal causes a sound when poop is dropped from a digested victim. (Requires ttt_cannibal_digestion to be enabled.) - ttt_cannibal_digestion_poop_sound_level   + ttt_cannibal_digestion_poop_sound_level 100 Integer The sound level (volume) to play the Cannibal's digestion poop sound (set to 0 to disable). (Requires ttt_cannibal_digestion to be enabled.) @@ -613,7 +613,7 @@

    Role Configuration:

    The amount of time in seconds between uses of the Cannibal's Cannibalizer. - ttt_cannibal_eat_sound_level   + ttt_cannibal_eat_sound_level 100 Integer The sound level (volume) to play the Cannibal's eat sound (set to 0 to disable). @@ -1218,7 +1218,7 @@

    Role Configuration:

    Whether a specific jester role should be fully healed when using the spongifier. Replace * with the name of the jester role you want to configure without spaces or capital letters. - ttt_sponge_win_ends_round   + ttt_sponge_win_ends_round 1 Boolean Whether the round should end when the Sponge wins.