diff --git a/CONVARS.md b/CONVARS.md
index 4fdc60803..24d58d587 100644
--- a/CONVARS.md
+++ b/CONVARS.md
@@ -765,7 +765,7 @@ ttt_cannibal_damage_penalty 0 // The fraction a Canniba
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)
ttt_cannibal_gains_health 0 // Whether the Cannibal gains their victim's health when eating them
-ttt_cannibal_gained_health_percentage 100 // What percentage of their victim's health the Cannibal gains. Set to 0 to always gain a flat 100HP (Only applies if ttt_cannibal_gains_health is enabled)
+ttt_cannibal_gained_health_percentage 15 // What percentage of their victim's health the Cannibal gains. Set to 0 to always gain a flat 100HP (Only applies if ttt_cannibal_gains_health is enabled)
ttt_cannibal_digestion 0 // Whether the Cannibal digests and permanently kills their victims over time
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)
diff --git a/RELEASE.md b/RELEASE.md
index 940dd62bc..4a19fbbcc 100644
--- a/RELEASE.md
+++ b/RELEASE.md
@@ -1,12 +1,12 @@
# Release Notes
## 2.4.4 (Beta)
-**Released:**
+**Released: March 21st, 2026**
### Additions
- Added messages to existing twins when a player becomes a twin during an active round
- Added option to allow Cannibal to gain a configurable percentage of their victims' health (disabled by default) (Thanks Joel!)
-- Added option to allow Cannibal to "digest" (permamnently kill) their victims a configurable amount of time after eating them (disabled by default) (Thanks Joel!)
+- Added option to allow Cannibal to "digest" (permanently kill) their victims a configurable amount of time after eating them (disabled by default) (Thanks Joel!)
- Added option to allow Cannibal to drop a poop when a victim is fully digested, with or without an audible cue (enabled by default, but depends on digestion being enabled) (Thanks Joel!)
### Changes
@@ -20,6 +20,8 @@
- Fixed cheat sheet getting cut off when it exceeded the height of the screen and a role pack was enabled
- Fixed jester, detective, innocent, and traitor role rename ConVars not working
- Fixed error in Cannibal's role weapon HUD when weapon was selected from last round (Thanks Stig!)
+- Fixed detective hats not hiding when the owning player was eaten by the Cannibal
+- Ported "Add check for checking weapon GetHeadshotMultiplier"
### Developer
- Added `ROLE_STRINGS_DEFAULT` as a copy of `ROLE_STRINGS` from before role strings are changed by ConVars
diff --git a/docs/teams/jester.html b/docs/teams/jester.html
index 4ffd23c2c..a8123bb40 100644
--- a/docs/teams/jester.html
+++ b/docs/teams/jester.html
@@ -580,7 +580,25 @@
Role Configuration:
ttt_cannibal_damage_penalty |
0 |
Float |
- The fraction a Cannibal's damage will be scaled by when they are attacking. (Requires ttt_bodysnatcher_is_independent to be enabled.) |
+ The fraction a Cannibal's damage will be scaled by when they are attacking. (Requires ttt_cannibal_is_independent to be enabled.) |
+
+
+ | ttt_cannibal_digestion |
+ 0 |
+ Boolean |
+ Whether the Cannibal digests and permanently kills their victims over time. |
+
+
+ | ttt_cannibal_digestion_poop |
+ 1 |
+ Boolean |
+ Whether the Cannibal drops poop when a victim is digested. (Requires ttt_cannibal_digestion to be enabled.) |
+
+
+ | ttt_cannibal_digestion_poop_sound |
+ 1 |
+ Boolean |
+ Whether the Cannibal causes a sound when poop is dropped from a digested victim. (Requires ttt_cannibal_digestion to be enabled.) |
| ttt_cannibal_eat_cooldown |
@@ -588,6 +606,18 @@ Role Configuration:
Integer |
The amount of time in seconds between uses of the Cannibal's Cannibalizer. |
+
+ | ttt_cannibal_gains_health |
+ 0 |
+ Boolean |
+ Whether the Cannibal gains their victim's health when eating them. |
+
+
+ | ttt_cannibal_gained_health_percentage |
+ 15 |
+ Integer |
+ What percentage of their victim's health the Cannibal gains. Set to 0 to always gain a flat 100HP (Requires ttt_cannibal_gains_health to be enabled.) |
+
| ttt_cannibal_is_independent |
0 |
@@ -598,7 +628,7 @@ Role Configuration:
ttt_cannibal_update_scoreboard |
0 |
Boolean |
- Whether the Cannibal shows dead players as missing in action. (Requires ttt_bodysnatcher_is_independent to be enabled.) |
+ Whether the Cannibal shows dead players as missing in action. (Requires ttt_cannibal_is_independent to be enabled.) |
diff --git a/gamemodes/terrortown/entities/weapons/weapon_can_eater.lua b/gamemodes/terrortown/entities/weapons/weapon_can_eater.lua
index 4b4d5e770..b9705de13 100644
--- a/gamemodes/terrortown/entities/weapons/weapon_can_eater.lua
+++ b/gamemodes/terrortown/entities/weapons/weapon_can_eater.lua
@@ -38,7 +38,7 @@ SWEP.InLoadoutForDefault = {ROLE_CANNIBAL}
SWEP.DeviceCooldownConVar = CreateConVar("ttt_cannibal_eat_cooldown", "10", FCVAR_REPLICATED, "The amount of time (in seconds) between uses of the Cannibal's Cannibalizer", 0, 60)
SWEP.GainsHealthConVar = CreateConVar("ttt_cannibal_gains_health", "0", FCVAR_REPLICATED, "Whether the Cannibal gains their victim's health when eating them", 0, 1)
-SWEP.GainedHealthPercentageConVar = CreateConVar("ttt_cannibal_gained_health_percentage", "100", FCVAR_REPLICATED, "What percentage of their victim's health the Cannibal gains (set to 0 to always gain a flat 100HP)", 0, 500)
+SWEP.GainedHealthPercentageConVar = CreateConVar("ttt_cannibal_gained_health_percentage", "15", FCVAR_REPLICATED, "What percentage of their victim's health the Cannibal gains (set to 0 to always gain a flat 100HP)", 0, 500)
SWEP.DigestionConVar = CreateConVar("ttt_cannibal_digestion", "0", FCVAR_REPLICATED, "Whether the Cannibal digests and permanently kills their victims over time", 0, 1)
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)
@@ -124,6 +124,9 @@ function SWEP:PrimaryAttack()
hitEnt:SpectateEntity(owner)
hitEnt:DrawViewModel(false)
hitEnt:DrawWorldModel(false)
+ if IsValid(hitEnt.hat) then
+ hitEnt.hat:SetNoDraw(true)
+ end
local sID64 = hitEnt:SteamID64()
@@ -154,33 +157,31 @@ function SWEP:PrimaryAttack()
-- Cannibal health gain
if self.GainsHealthConVar:GetBool() then
- local gainedhealthpercentage = self.GainedHealthPercentageConVar:GetInt()
- local victimhealth = hitEnt:Health()
- local cannibalhealth = owner:Health()
+ local gained_health_percentage = self.GainedHealthPercentageConVar:GetInt()
+ local victimHealth = hitEnt:Health()
+ local cannibalHealth = owner:Health()
- local gainedhealth
- if gainedhealthpercentage == 0 then
- gainedhealth = 100
+ local gainedHealth
+ if gained_health_percentage == 0 then
+ gainedHealth = 100
else
- local gainedhealthunrounded = (gainedhealthpercentage / 100) * victimhealth
- gainedhealth = math.floor(gainedhealthunrounded)
+ gainedHealth = math.floor((gained_health_percentage / 100) * victimHealth)
end
- local newcannibalhealth = cannibalhealth + gainedhealth
- if newcannibalhealth > cannibalhealth then
- owner:SetHealth(newcannibalhealth)
+ if gainedHealth > 0 then
+ owner:SetHealth(cannibalHealth + gainedHealth)
end
end
-- Victim digestion
if self.DigestionConVar:GetBool() then
- local digestiontime = self.DigestionTimeConVar:GetInt()
+ local digestion_time = self.DigestionTimeConVar:GetInt()
-- Ensure there's a short delay to allow time for the vars to be set first
- if digestiontime == 0 then
- digestiontime = 0.1
+ if digestion_time == 0 then
+ digestion_time = 0.1
end
- timer.Create("TTTCannibalDigestion_" .. sID64, digestiontime, 1, function()
+ timer.Create("TTTCannibalDigestion_" .. sID64, digestion_time, 1, function()
if not IsPlayer(hitEnt) then return end
if not IsPlayer(owner) then return end
diff --git a/gamemodes/terrortown/gamemode/player.lua b/gamemodes/terrortown/gamemode/player.lua
index 688b90354..0a00416e1 100644
--- a/gamemodes/terrortown/gamemode/player.lua
+++ b/gamemodes/terrortown/gamemode/player.lua
@@ -978,7 +978,7 @@ function GM:ScalePlayerDamage(ply, hitgroup, dmginfo)
local wep = util.WeaponFromDamage(dmginfo)
- if IsValid(wep) and not GetConVar("ttt_disable_headshots"):GetBool() then
+ if IsValid(wep) and wep.GetHeadshotMultiplier and not GetConVar("ttt_disable_headshots"):GetBool() then
local s = wep:GetHeadshotMultiplier(ply, dmginfo) or 2
dmginfo:ScaleDamage(s)
end
diff --git a/gamemodes/terrortown/gamemode/roles/cannibal/cannibal.lua b/gamemodes/terrortown/gamemode/roles/cannibal/cannibal.lua
index 1b3a1b115..a3fe91b12 100644
--- a/gamemodes/terrortown/gamemode/roles/cannibal/cannibal.lua
+++ b/gamemodes/terrortown/gamemode/roles/cannibal/cannibal.lua
@@ -39,6 +39,9 @@ local function ReleaseEatenPlayers(ply, message)
v:DrawViewModel(true)
v:DrawWorldModel(true)
v:SetNoDraw(false)
+ if IsValid(v.hat) then
+ v.hat:SetNoDraw(false)
+ end
v:Spawn()
local pos = ply:GetPos()
v:SetPos(FindRespawnLocation(pos) or pos)
diff --git a/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua b/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua
index 68b15588b..583adb885 100644
--- a/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua
+++ b/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua
@@ -189,17 +189,34 @@ AddHook("TTTTutorialRoleText", "Cannibal_TTTTutorialRoleText", function(role, ti
local roleTeamName, roleColor = GetRoleTeamInfo(roleTeam)
local html = "The " .. ROLE_STRINGS[ROLE_CANNIBAL] .. " is a " .. roleTeamName .. " role whose goal is to eat all other players."
- if GetConVar("ttt_cannibal_digestion"):GetBool() then
- html = html .. "Eaten players are not immediately dead, but they are unable to do anything except talk with other eaten players and spectate the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. "."
+ if GetConVar("ttt_cannibal_gains_health"):GetBool() then
+ local gained_health_percentage = GetConVar("ttt_cannibal_gained_health_percentage"):GetInt()
+ local gained
+ if gained_health_percentage > 0 then
+ gained = gained_health_percentage .. "% of the victim's health"
+ else
+ gained = "100HP"
+ end
+
+ html = html .. "When the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. " eats a player, they gain " .. gained .. " immediately."
+ end
- html = html .. "Eaten players are digested and killed " .. GetConVar("ttt_cannibal_digestion_time"):GetInt() .. " seconds after being eaten."
+ local eatenDetail = ""
+ local deathDetail = ""
+
+ if GetConVar("ttt_cannibal_digestion"):GetBool() then
+ eatenDetail = " immediately"
+ deathDetail = " undigested"
+ end
- html = html .. "If the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. " dies, all undigested eaten players are freed at the position where the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. " died."
- else
- html = html .. "Eaten players are not dead, but they are unable to do anything except talk with other eaten players and spectate the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. "."
+ html = html .. "Eaten players are not" .. eatenDetail .. " dead, but they are unable to do anything except talk with other eaten players and spectate the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. "."
- html = html .. "If the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. " dies, all eaten players are freed at the position where the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. " died."
+ if GetConVar("ttt_cannibal_digestion"):GetBool() then
+ html = html .. "Eaten players are digested and killed " .. GetConVar("ttt_cannibal_digestion_time"):GetInt() .. " seconds after being eaten."
end
+
+ html = html .. "If the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. " dies, all" .. deathDetail .. " eaten players are freed at the position where the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. " died."
+
return html
end
end)
\ No newline at end of file
diff --git a/gamemodes/terrortown/gamemode/shared.lua b/gamemodes/terrortown/gamemode/shared.lua
index 109126c82..e610042b3 100644
--- a/gamemodes/terrortown/gamemode/shared.lua
+++ b/gamemodes/terrortown/gamemode/shared.lua
@@ -27,7 +27,7 @@ local Utf8Sub = utf8.sub
include("player_class/player_ttt.lua")
-- Version string for display and function for version checks
-CR_VERSION = "2.4.3"
+CR_VERSION = "2.4.4"
CR_BETA = true
CR_WORKSHOP_ID = CR_BETA and "2404251054" or "2421039084"