diff --git a/CONVARS.md b/CONVARS.md index b8d887dda..a5b3f0260 100644 --- a/CONVARS.md +++ b/CONVARS.md @@ -765,6 +765,14 @@ 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 1 // 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) +ttt_cannibal_digests_victims 1 // 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) +ttt_cannibal_does_poopy 1 // Whether the Cannibal poops themselves when a victim is digested +ttt_cannibal_does_poopy_noise 1 // Whether the Cannibal's poops produce an audible cue + // ---------------------------------------- // INDEPENDENT TEAM SETTINGS diff --git a/gamemodes/terrortown/content/materials/models/poo/poo.vmt b/gamemodes/terrortown/content/materials/models/poo/poo.vmt new file mode 100644 index 000000000..91d40117a --- /dev/null +++ b/gamemodes/terrortown/content/materials/models/poo/poo.vmt @@ -0,0 +1,10 @@ +"VertexLitGeneric" +{ + "$baseTexture" "Models/poo/poo" + "$bumpmap" "Models/poo/poo_n" + // -- From here down is new stuff which will only be applied if $phong is set to 1 -- + "$phong" "1" + "$phongboost" "4" + "$phongexponent" "30" + "$phongfresnelranges" "[.2 .5 1]" +} diff --git a/gamemodes/terrortown/content/materials/models/poo/poo.vtf b/gamemodes/terrortown/content/materials/models/poo/poo.vtf new file mode 100644 index 000000000..f32c30dc3 Binary files /dev/null and b/gamemodes/terrortown/content/materials/models/poo/poo.vtf differ diff --git a/gamemodes/terrortown/content/materials/models/poo/poo_n.vtf b/gamemodes/terrortown/content/materials/models/poo/poo_n.vtf new file mode 100644 index 000000000..3a9d0b58f Binary files /dev/null and b/gamemodes/terrortown/content/materials/models/poo/poo_n.vtf differ diff --git a/gamemodes/terrortown/content/models/poo/poo.dx80.vtx b/gamemodes/terrortown/content/models/poo/poo.dx80.vtx new file mode 100644 index 000000000..3182d23c3 Binary files /dev/null and b/gamemodes/terrortown/content/models/poo/poo.dx80.vtx differ diff --git a/gamemodes/terrortown/content/models/poo/poo.dx90.vtx b/gamemodes/terrortown/content/models/poo/poo.dx90.vtx new file mode 100644 index 000000000..8c3f0539e Binary files /dev/null and b/gamemodes/terrortown/content/models/poo/poo.dx90.vtx differ diff --git a/gamemodes/terrortown/content/models/poo/poo.mdl b/gamemodes/terrortown/content/models/poo/poo.mdl new file mode 100644 index 000000000..6cb10c73c Binary files /dev/null and b/gamemodes/terrortown/content/models/poo/poo.mdl differ diff --git a/gamemodes/terrortown/content/models/poo/poo.phy b/gamemodes/terrortown/content/models/poo/poo.phy new file mode 100644 index 000000000..f2b486025 Binary files /dev/null and b/gamemodes/terrortown/content/models/poo/poo.phy differ diff --git a/gamemodes/terrortown/content/models/poo/poo.sw.vtx b/gamemodes/terrortown/content/models/poo/poo.sw.vtx new file mode 100644 index 000000000..df55c7972 Binary files /dev/null and b/gamemodes/terrortown/content/models/poo/poo.sw.vtx differ diff --git a/gamemodes/terrortown/content/models/poo/poo.vvd b/gamemodes/terrortown/content/models/poo/poo.vvd new file mode 100644 index 000000000..902257872 Binary files /dev/null and b/gamemodes/terrortown/content/models/poo/poo.vvd differ diff --git a/gamemodes/terrortown/content/sound/cannibal/poop1.wav b/gamemodes/terrortown/content/sound/cannibal/poop1.wav new file mode 100644 index 000000000..770aee196 Binary files /dev/null and b/gamemodes/terrortown/content/sound/cannibal/poop1.wav differ diff --git a/gamemodes/terrortown/content/sound/cannibal/poop2.wav b/gamemodes/terrortown/content/sound/cannibal/poop2.wav new file mode 100644 index 000000000..3adc03fee Binary files /dev/null and b/gamemodes/terrortown/content/sound/cannibal/poop2.wav differ diff --git a/gamemodes/terrortown/content/sound/cannibal/poop3.wav b/gamemodes/terrortown/content/sound/cannibal/poop3.wav new file mode 100644 index 000000000..fde256fa8 Binary files /dev/null and b/gamemodes/terrortown/content/sound/cannibal/poop3.wav differ diff --git a/gamemodes/terrortown/content/sound/cannibal/poop4.wav b/gamemodes/terrortown/content/sound/cannibal/poop4.wav new file mode 100644 index 000000000..de94b9400 Binary files /dev/null and b/gamemodes/terrortown/content/sound/cannibal/poop4.wav differ diff --git a/gamemodes/terrortown/content/sound/cannibal/poop5.wav b/gamemodes/terrortown/content/sound/cannibal/poop5.wav new file mode 100644 index 000000000..683fac570 Binary files /dev/null and b/gamemodes/terrortown/content/sound/cannibal/poop5.wav differ diff --git a/gamemodes/terrortown/content/sound/cannibal/poop6.wav b/gamemodes/terrortown/content/sound/cannibal/poop6.wav new file mode 100644 index 000000000..ca0d00158 Binary files /dev/null and b/gamemodes/terrortown/content/sound/cannibal/poop6.wav differ diff --git a/gamemodes/terrortown/entities/weapons/weapon_can_eater.lua b/gamemodes/terrortown/entities/weapons/weapon_can_eater.lua index c4272d36e..9c0d386c5 100644 --- a/gamemodes/terrortown/entities/weapons/weapon_can_eater.lua +++ b/gamemodes/terrortown/entities/weapons/weapon_can_eater.lua @@ -37,6 +37,12 @@ SWEP.InLoadoutFor = {ROLE_CANNIBAL} 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", "1", 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.DigestsVictimsConVar = CreateConVar("ttt_cannibal_digests_victims", "1", 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) +SWEP.RectallyIncontinentConVar = CreateConVar("ttt_cannibal_does_poopy", "1", FCVAR_REPLICATED, "Whether the Cannibal poops themselves when a victim is digested", 0, 1) +SWEP.AudibleIncontinenceConVar = CreateConVar("ttt_cannibal_does_poopy_noise", "1", FCVAR_REPLICATED, "Whether the Cannibal's poops produce an audible cue", 0, 1) local eatSounds = { "cannibal/eat1.wav", @@ -44,6 +50,15 @@ local eatSounds = { "cannibal/eat3.wav" } +local poopSounds = { + "cannibal/poop1.wav", + "cannibal/poop2.wav", + "cannibal/poop3.wav", + "cannibal/poop4.wav", + "cannibal/poop5.wav", + "cannibal/poop6.wav" +} + function SWEP:Initialize() if CLIENT then self:AddHUDHelp("can_eater_help_pri", nil, true) @@ -125,6 +140,84 @@ function SWEP:PrimaryAttack() if cooldown > 0 then self:SetDeviceCooldownEnd(CurTime() + cooldown) end + + -- Cannibal health gain + if self.GainsHealthConVar:GetBool() then + + local gainedhealthpercentage = self.GainedHealthPercentageConVar:GetInt() + local victimhealth = hitEnt:Health() + local cannibalhealth = owner:Health() + + if gainedhealthpercentage == 0 then + gainedhealth = 100 + else + gainedhealthunrounded = (gainedhealthpercentage / 100) * victimhealth + gainedhealth = math.floor(gainedhealthunrounded) + end + + local newcannibalhealth = cannibalhealth + gainedhealth + if newcannibalhealth > cannibalhealth then + owner:SetHealth(newcannibalhealth) + end + + end + + -- Victim digestion + if self.DigestsVictimsConVar:GetBool() then + + local digestiontime = self.DigestionTimeConVar:GetInt() + + if digestiontime == 0 then + digestiontime = 0.1 -- short delay to avoid fuckyness? + end + + local disgestiontimername = "TTTCannibalDigestion_" .. sID64 + + -- Remove existing digestion timer for victim if one somehow exists + if timer.Exists(disgestiontimername) then + timer.Remove(disgestiontimername) + end + + timer.Create(disgestiontimername, digestiontime, 1, function() + + -- Safety checks + if not IsValid(hitEnt) or not hitEnt:IsPlayer() then return end + if not IsValid(owner) or not owner:IsPlayer() then return end + + -- Only digest if they are still in THIS cannibal's tummy + if hitEnt.TTTCannibalEaten == owner:SteamID64() then + hitEnt:KillSilent() + hitEnt:ClearProperty("TTTCannibalEaten") + + hitEnt:SetParent(nil) + hitEnt:SpectateEntity(nil) + + hitEnt:QueueMessage(MSG_PRINTBOTH, "You have been fully digested!", 3) + owner:QueueMessage(MSG_PRINTBOTH, "You have fully digested " .. hitEnt:Nick() .. "!", 3) + + -- Spawn poop at cannibal's position + if self.RectallyIncontinentConVar:GetBool() then + local poop = ents.Create("prop_physics") + if IsValid(poop) then + poop:SetModel("models/poo/poo.mdl") + + local forward = owner:GetForward() + local dropPos = owner:GetPos() + forward * -30 + Vector(0, 0, 10) + poop:SetPos(dropPos) + + poop:SetAngles(Angle(0, math.random(0, 360), 0)) + poop:Spawn() + poop:Activate() + + if self.AudibleIncontinenceConVar:GetBool()then + owner:EmitSound(poopSounds[math.random(1, #poopSounds)], 100) + end + end + end + end + + end) + end end end diff --git a/gamemodes/terrortown/gamemode/roles/cannibal/cannibal.lua b/gamemodes/terrortown/gamemode/roles/cannibal/cannibal.lua index e029f6505..1b3a1b115 100644 --- a/gamemodes/terrortown/gamemode/roles/cannibal/cannibal.lua +++ b/gamemodes/terrortown/gamemode/roles/cannibal/cannibal.lua @@ -46,6 +46,8 @@ local function ReleaseEatenPlayers(ply, message) local sID64 = v:SteamID64() + timer.Remove("TTTCannibalDigestion_" .. sID64) + for _, data in ipairs(CANNIBAL.playerWeapons[sID64]) do local wep = v:Give(data.class) if not IsValid(wep) then continue end diff --git a/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua b/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua index a57af1f9d..b00e80bd1 100644 --- a/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua +++ b/gamemodes/terrortown/gamemode/roles/cannibal/cl_cannibal.lua @@ -189,10 +189,21 @@ 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." - 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] .. "." + if GetConVar("ttt_cannibal_digests_victims"):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] .. "." - html = html .. "If the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. " dies, all eaten players are freed at the position where the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. " died." + html = html .. "Eaten players are digested and killed " .. GetConVar("ttt_cannibal_digestion_time"):GetInt() .. " seconds after being eaten." + 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 .. "If the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. " dies, all eaten players are freed at the position where the " .. ROLE_STRINGS[ROLE_CANNIBAL] .. " died." + + end return html end end) \ No newline at end of file diff --git a/gamemodes/terrortown/gamemode/roles/cannibal/shared.lua b/gamemodes/terrortown/gamemode/roles/cannibal/shared.lua index 75e2f9c46..cdd21ce4e 100644 --- a/gamemodes/terrortown/gamemode/roles/cannibal/shared.lua +++ b/gamemodes/terrortown/gamemode/roles/cannibal/shared.lua @@ -49,6 +49,30 @@ table.insert(ROLE_CONVARS[ROLE_CANNIBAL], { cvar = "ttt_cannibal_update_scoreboard", type = ROLE_CONVAR_TYPE_BOOL }) +table.insert(ROLE_CONVARS[ROLE_CANNIBAL], { + cvar = "ttt_cannibal_gains_health", + type = ROLE_CONVAR_TYPE_BOOL +}) +table.insert(ROLE_CONVARS[ROLE_CANNIBAL], { + cvar = "ttt_cannibal_gained_health_percentage", + type = ROLE_CONVAR_TYPE_NUM +}) +table.insert(ROLE_CONVARS[ROLE_CANNIBAL], { + cvar = "ttt_cannibal_digests_victims", + type = ROLE_CONVAR_TYPE_BOOL +}) +table.insert(ROLE_CONVARS[ROLE_CANNIBAL], { + cvar = "ttt_cannibal_digestion_time", + type = ROLE_CONVAR_TYPE_NUM +}) +table.insert(ROLE_CONVARS[ROLE_CANNIBAL], { + cvar = "ttt_cannibal_does_poopy", + type = ROLE_CONVAR_TYPE_BOOL +}) +table.insert(ROLE_CONVARS[ROLE_CANNIBAL], { + cvar = "ttt_cannibal_does_poopy_noise", + type = ROLE_CONVAR_TYPE_BOOL +}) ------------------- -- ROLE FEATURES --