Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Armor: Armor system #370

Merged
merged 57 commits into from
Oct 2, 2019
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
7da35e9
armor draft
TimGoll Aug 11, 2019
16c6ea7
basic armor item and hud rendering
TimGoll Aug 11, 2019
e0015b8
improved pure skin integration
TimGoll Aug 11, 2019
ddad3b7
colortweaking
TimGoll Aug 11, 2019
573d345
reset armor on player spawn
TimGoll Aug 11, 2019
d143944
changed/added hud icons
TimGoll Aug 14, 2019
36f2dad
improved status system
TimGoll Aug 14, 2019
fc141b9
sidebar stuff
TimGoll Aug 14, 2019
084701c
refactored armor system to work with karma and addons that change the…
TimGoll Aug 17, 2019
1628044
allow reinforced armor
TimGoll Aug 17, 2019
47d3246
added armor to pureskin hud
TimGoll Aug 17, 2019
2c41364
old_ttt support added
TimGoll Aug 17, 2019
3d13888
Merge branch 'master' into armor-system
TimGoll Aug 17, 2019
ffe6edd
armor cleanup after merge
TimGoll Aug 17, 2019
59a0ef7
overhead icons follow head movement
TimGoll Aug 17, 2019
12301ad
fixed performance problem
TimGoll Aug 17, 2019
81bcd45
convar for a classic armor fallback
TimGoll Aug 17, 2019
ac08d39
cleanup
TimGoll Aug 21, 2019
eff5755
fixed variable bug
TimGoll Aug 28, 2019
e27f8c6
[incomplete] allow items to be bought multiple times
TimGoll Aug 28, 2019
12722a4
Merge branch 'master' into armor-system
TimGoll Aug 29, 2019
7398c74
introducing .limited to items as well
TimGoll Aug 29, 2019
9fe63d1
edited language file to fir new armor system
TimGoll Aug 29, 2019
0ca9aee
rename convar
TimGoll Aug 29, 2019
950d862
some improvements
TimGoll Aug 30, 2019
cf9c318
added validity check
TimGoll Aug 30, 2019
d2849c9
made requested change
TimGoll Aug 31, 2019
b94a5b5
make sure that the default armor is only given when a player is playing
TimGoll Aug 31, 2019
fc739c7
localization and small improvements
TimGoll Aug 31, 2019
e56bfd8
added reroll texture to the forcedownload list
TimGoll Aug 31, 2019
1f81276
cleanup for merge
TimGoll Sep 1, 2019
384d8dc
this should do the trick
TimGoll Sep 1, 2019
f4a1518
adressing many issues
TimGoll Sep 2, 2019
e9cdea0
moved into seperate files
TimGoll Sep 2, 2019
611b2ca
further improvements
TimGoll Sep 2, 2019
0491689
removed `tostring()`
TimGoll Sep 2, 2019
bf8f769
Merge branch 'master' into armor-system
TimGoll Sep 5, 2019
8a1501e
resolved problems
TimGoll Sep 5, 2019
ea46b2f
making jenkins happy
TimGoll Sep 5, 2019
3e7d426
oof
TimGoll Sep 5, 2019
fc46413
jenkins - your best friend
TimGoll Sep 5, 2019
e995688
cleanup
TimGoll Sep 5, 2019
e9f3d04
Merge branch 'master' into armor-system
TimGoll Sep 27, 2019
8223a4e
removed remaining prints
TimGoll Sep 27, 2019
da33077
renamings and removing change
TimGoll Sep 29, 2019
6a7e397
Merge branch 'master' into armor-system
TimGoll Sep 29, 2019
20b0c9d
rework naming scheme
TimGoll Sep 29, 2019
ab74f7c
Merge branch 'master' into armor-system
TimGoll Sep 29, 2019
ed8e863
readded credits (?)
TimGoll Sep 29, 2019
cbb423e
armor function naming cleanup
TimGoll Sep 30, 2019
4324def
simplified system
TimGoll Sep 30, 2019
90bb9a9
finish up
TimGoll Sep 30, 2019
89ed55e
renamings are THE HIT
TimGoll Sep 30, 2019
f8a3fd8
improved code consistency
Alf21 Oct 1, 2019
6fabb2f
reintroduced armor_offset
TimGoll Oct 2, 2019
016d83f
Update sv_armor.lua
Alf21 Oct 2, 2019
c8d9025
improved armor checks
Alf21 Oct 2, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions gamemodes/terrortown/entities/weapons/weapon_ttt_armor.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
SWEP.Base = "weapon_tttbase"
Alf21 marked this conversation as resolved.
Show resolved Hide resolved

SWEP.Spawnable = true
SWEP.AutoSpawnable = false
SWEP.AdminSpawnable = true
SWEP.AllowDrop = false

SWEP.Kind = WEAPON_EXTRA

if SERVER then
AddCSLuaFile()
else
SWEP.PrintName = "Armor"


SWEP.Icon = "vgui/ttt/icon_armor"
SWEP.EquipMenuData = {
type = "Weapon",
desc = "ttt2_weapon_armor_desc"
}
end

SWEP.CanBuy = {ROLE_TRAITOR, ROLE_DETECTIVE}

function SWEP:Equip(buyer)
if SERVER then
buyer:IncreaseArmor(30)
self:Remove()
end
end

-- REGISTER STATUS ICONS
if CLIENT then
hook.Add("Initialize", "ttt2_base_register_armor_status", function()
STATUS:RegisterStatus("ttt_weapon_armor", {
hud = {
Material("vgui/ttt/perks/hud_armor.png"),
Material("vgui/ttt/perks/hud_armor_reinforced.png")
},
type = "good"
})
end)
end
59 changes: 53 additions & 6 deletions gamemodes/terrortown/gamemode/client/cl_status.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ STATUS.active = {}

---
-- Registers a @{STATUS}
-- @param number id The index of the new status
-- @param number id the index of the new status
TimGoll marked this conversation as resolved.
Show resolved Hide resolved
-- @param table data
-- @return boolean whether the creation was successfully
-- @realm client
function STATUS:RegisterStatus(id, data)
if STATUS.registered[id] ~= nil then -- name is not unique
return false
end

-- support single and multible icons per status effect
if data.hud.GetTexture then
data.hud = {data.hud}
Alf21 marked this conversation as resolved.
Show resolved Hide resolved
end

STATUS.registered[id] = data

Expand All @@ -25,23 +30,26 @@ end
---
-- Adds a status to the currently active ones
-- @param number id The id of the registered @{STATUS}
-- @param number active_icon
TimGoll marked this conversation as resolved.
Show resolved Hide resolved
-- @realm client
function STATUS:AddStatus(id)
function STATUS:AddStatus(id, active_icon)
if STATUS.registered[id] == nil then return end

STATUS.active[id] = table.Copy(STATUS.registered[id])
self:SetActiveIcon(id, active_icon or 1)
Alf21 marked this conversation as resolved.
Show resolved Hide resolved
end

---
-- Adds a timed status to the currently active ones
-- @param number id The id of the registered @{STATUS}
-- @param number duration The duration of the @{STATUS}. If the time elapsed,
-- the @{STATUS} will be removed automatically
-- @param number active_icon
TimGoll marked this conversation as resolved.
Show resolved Hide resolved
-- @realm client
function STATUS:AddTimedStatus(id, duration, showDuration)
function STATUS:AddTimedStatus(id, duration, showDuration, active_icon)
if STATUS.registered[id] == nil or duration == 0 then return end

self:AddStatus(id)
self:AddStatus(id, active_icon)

STATUS.active[id].displaytime = CurTime() + duration

Expand All @@ -56,6 +64,41 @@ function STATUS:AddTimedStatus(id, duration, showDuration)
end
end

---
-- Changes the active icon for a specifiv active effect for a given @{Player}
-- @param number id The id of the registered @{STATUS}
-- @param number active_icon
-- @realm client
function STATUS:SetActiveIcon(id, active_icon)
if STATUS.active[id] == nil then return end

local max_amount = (self.registered[id].hud.GetTexture) and 1 or #STATUS.registered[id].hud
Alf21 marked this conversation as resolved.
Show resolved Hide resolved

if active_icon < 1 or active_icon > max_amount then
active_icon = 1
end

STATUS.active[id].active_icon = active_icon
end

---
-- Checks if a @{STATUS} is registered
-- @param number id the index of the status
-- @return boolean whether the status is registered
-- @realm client
function STATUS:Registered(id)
return (STATUS.registered[id] ~= nil) and true or false
end

---
-- Checks if a @{STATUS} is active
-- @param number id the index of the status
-- @return boolean whether the status is active
-- @realm client
function STATUS:Active(id)
return (STATUS.active[id] ~= nil) and true or false
end

---
-- Removes a currently active status
-- @param number id The id of the registered @{STATUS}
Expand All @@ -81,11 +124,15 @@ function STATUS:RemoveAll()
end

net.Receive("ttt2_status_effect_add", function()
STATUS:AddStatus(net.ReadString())
STATUS:AddStatus(net.ReadString(), net.ReadUInt(8))
end)

net.Receive("ttt2_status_effect_set_id", function()
STATUS:SetActiveIcon(net.ReadString(), net.ReadUInt(8))
end)

net.Receive("ttt2_status_effect_add_timed", function()
STATUS:AddTimedStatus(net.ReadString(), net.ReadUInt(32), net.ReadBool())
STATUS:AddTimedStatus(net.ReadString(), net.ReadUInt(32), net.ReadBool(), net.ReadUInt(8))
end)

net.Receive("ttt2_status_effect_remove", function()
Expand Down
19 changes: 12 additions & 7 deletions gamemodes/terrortown/gamemode/client/cl_targetid.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ end
indicator_col = Color(255, 255, 255, 130)

local propspec_outline = Material("models/props_combine/portalball001_sheet")
local base = Material("vgui/ttt/dynamic/sprite_base")
local base_overlay = Material("vgui/ttt/dynamic/sprite_base_overlay")

---
-- Called after all translucent entities are drawn.
Expand All @@ -78,22 +80,25 @@ function GM:PostDrawTranslucentRenderables(bDrawingDepth, bDrawingSkybox)

if client:IsSpecial() then
dir = (client:GetForward() * -1)

for i = 1, #plys do
local ply = plys[i]
local rd = ply:GetSubRoleData()

local pos = ply:GetPos()
pos.z = pos.z + 80


local pos = ply:GetBonePosition(6)
pos.z = pos.z + 20

local ea = ply:EyeAngles()
ea.pitch = 0
local shift = Vector(2,0,0)
Alf21 marked this conversation as resolved.
Show resolved Hide resolved
shift:Rotate(ea)
pos:Add(shift)
Alf21 marked this conversation as resolved.
Show resolved Hide resolved
saibotk marked this conversation as resolved.
Show resolved Hide resolved

if ply ~= client
and ply:IsActive()
and ply:IsSpecial()
and (not client:IsActive() or ply:IsInTeam(client))
and not ply:GetSubRoleData().avoidTeamIcons
then
local base = Material("vgui/ttt/dynamic/sprite_base")
local base_overlay = Material("vgui/ttt/dynamic/sprite_base_overlay.png")
local icon = Material("vgui/ttt/dynamic/roles/icon_" .. rd.abbr)
Alf21 marked this conversation as resolved.
Show resolved Hide resolved
local incol = ply:GetRoleColor()

Expand Down
1 change: 1 addition & 0 deletions gamemodes/terrortown/gamemode/server/sv_main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ function GM:SyncGlobals()
SetGlobalBool("ttt_highlight_vip", GetConVar("ttt_highlight_vip"):GetBool())
SetGlobalBool("ttt_highlight_addondev", GetConVar("ttt_highlight_addondev"):GetBool())
SetGlobalBool("ttt_highlight_supporter", GetConVar("ttt_highlight_supporter"):GetBool())
SetGlobalBool("ttt_armor_classic", GetConVar("ttt_armor_classic"):GetBool())
SetGlobalBool("ttt_locational_voice", GetConVar("ttt_locational_voice"):GetBool())
SetGlobalInt("ttt_idle_limit", idle_time:GetInt())
SetGlobalBool("ttt_idle", idle_enabled:GetBool())
Expand Down
69 changes: 67 additions & 2 deletions gamemodes/terrortown/gamemode/server/sv_player.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1430,14 +1430,21 @@ function GM:PlayerTakeDamage(ent, infl, att, amount, dmginfo)
-- start painting blood decals
util.StartBleeding(ent, dmginfo:GetDamage(), 5)

-- general actions for pvp damage
-- handle damage scaling by karma
if ent ~= att and IsValid(att) and att:IsPlayer() and GetRoundState() == ROUND_ACTIVE and math.floor(dmginfo:GetDamage()) > 0 then

-- scale everything to karma damage factor except the knife, because it
-- assumes a kill
if not dmginfo:IsDamageType(DMG_SLASH) then
dmginfo:ScaleDamage(att:GetDamageFactor())
end
end

-- before the karma is calculated, but after all other damage hooks / damage change is processed,
-- the armor system should come into place (GM functions are called last)
HandlePlayerArmorSystem(ent, infl, att, amount, dmginfo)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain, why this is excluded from the previous if statement?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I wanted to keep it a bit seperated to not clutter the code above. Additionally I like to work with if bla then return end instead of nested ifs


-- handle karma change / log etc
if ent ~= att and IsValid(att) and att:IsPlayer() and GetRoundState() == ROUND_ACTIVE and math.floor(dmginfo:GetDamage()) > 0 then

-- process the effects of the damage on karma
KARMA.Hurt(att, ent, dmginfo)
Expand All @@ -1446,6 +1453,64 @@ function GM:PlayerTakeDamage(ent, infl, att, amount, dmginfo)
end
end

function HandlePlayerArmorSystem(ent, infl, att, amount, dmginfo)
-- armor does not help when the head receives damage
--if ent:LastHitGroup() == HITGROUP_HEAD then return end
TimGoll marked this conversation as resolved.
Show resolved Hide resolved
-- DISABLED for now since the hook gets called twice, once with 0 damage, but with a hitgroup and once
-- with damage but no hitgroup. I have to dig deeper into this

-- some entities cause this hook to be triggered, ignore 0 damage events
if dmginfo:GetDamage() == 0 then return end

-- fallback for players who prefer the vanilla armor
if GetConVar("ttt_armor_classic"):GetBool() and ent:Armor() > 0 then
dmginfo:ScaleDamage(0.7)
return
Alf21 marked this conversation as resolved.
Show resolved Hide resolved
end

print("-------------------------------------------------------")
TimGoll marked this conversation as resolved.
Show resolved Hide resolved

-- handle different damage type factors
local armor_factor, body_factor
if dmginfo:IsDamageType(DMG_BULLET) or dmginfo:IsDamageType(DMG_CLUB) then -- bullet or crowbar damage
Alf21 marked this conversation as resolved.
Show resolved Hide resolved
armor_factor = 1.0
body_factor = 1.0
print("damage type : bullet or crowbar")
Alf21 marked this conversation as resolved.
Show resolved Hide resolved
elseif dmginfo:IsDamageType(DMG_BURN) or dmginfo:IsDamageType(DMG_BLAST) then -- fire or explosion damage
armor_factor = 1.5
body_factor = 0.75
print("damage type : fire or explosion")
Alf21 marked this conversation as resolved.
Show resolved Hide resolved
else
return
end

-- calculate damage
local damage = dmginfo:GetDamage()
local armor = ent:Armor()

print("current HP : " .. tostring(ent:Health()))
Alf21 marked this conversation as resolved.
Show resolved Hide resolved
print("current Armor : " .. tostring(armor))
print("damage to take : " .. tostring(damage))

-- normal damage handling when no armor is available
if armor == 0 then return end

local cv_armor_factor = ent:ArmorIsReinforced() and GetConVar("ttt_armor_rei_damage_block_pct"):GetFloat() or GetConVar("ttt_armor_damage_block_pct"):GetFloat()
local cv_body_factor = ent:ArmorIsReinforced() and GetConVar("ttt_armor_rei_damage_health_pct"):GetFloat() or GetConVar("ttt_armor_damage_health_pct"):GetFloat()

print("armor factor : " .. tostring(cv_armor_factor))
Alf21 marked this conversation as resolved.
Show resolved Hide resolved
print("body factor : " .. tostring(cv_body_factor))

armor = armor - cv_armor_factor * armor_factor * damage
print("armor internal : " .. tostring(armor))
Alf21 marked this conversation as resolved.
Show resolved Hide resolved
ent:SetArmor(math.max(armor, 0))
print("new armor : " .. tostring(ent:Armor()))
Alf21 marked this conversation as resolved.
Show resolved Hide resolved

local new_damage = cv_body_factor * body_factor * damage - math.min(armor, 0)
print("calced dmg : " .. tostring(new_damage))
Alf21 marked this conversation as resolved.
Show resolved Hide resolved
dmginfo:SetDamage(new_damage)
end

---
-- Called whenever an @{NPC} is killed
-- @param NPC npc The killed @{NPC}
Expand Down
50 changes: 34 additions & 16 deletions gamemodes/terrortown/gamemode/server/sv_status.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ STATUS = {}

-- register networkt messages
util.AddNetworkString("ttt2_status_effect_add")
util.AddNetworkString("ttt2_status_effect_set_id")
util.AddNetworkString("ttt2_status_effect_add_timed")
util.AddNetworkString("ttt2_status_effect_remove")
util.AddNetworkString("ttt2_status_effect_remove_all")
Expand All @@ -13,11 +14,26 @@ util.AddNetworkString("ttt2_status_effect_remove_all")
-- Adds a status for a given @{Player}
-- @param Player ply
-- @param string id
-- @param number active_icon
TimGoll marked this conversation as resolved.
Show resolved Hide resolved
-- @realm server
function STATUS:AddStatus(ply, id)
net.Start("ttt2_status_effect_add")
net.WriteString(id)
net.Send(ply)
function STATUS:AddStatus(ply, id, active_icon)
net.Start("ttt2_status_effect_add")
net.WriteString(id)
net.WriteUInt(active_icon or 1, 8)
net.Send(ply)
end

---
-- Changes the active icon for a specifiv active effect for a given @{Player}
-- @param Player ply
-- @param string id
-- @param number active_icon
TimGoll marked this conversation as resolved.
Show resolved Hide resolved
-- @realm server
function STATUS:SetActiveIcon(ply, id, active_icon)
net.Start("ttt2_status_effect_set_id")
net.WriteString(id)
net.WriteUInt(active_icon or 1, 8)
net.Send(ply)
end

---
Expand All @@ -26,13 +42,15 @@ end
-- @param string id
-- @param number duration the time
-- @param boolean showDuration
-- @param number active_icon
TimGoll marked this conversation as resolved.
Show resolved Hide resolved
-- @realm server
function STATUS:AddTimedStatus(ply, id, duration, showDuration)
net.Start("ttt2_status_effect_add_timed")
net.WriteString(id)
net.WriteUInt(duration, 32)
net.WriteBool(showDuration or false)
net.Send(ply)
function STATUS:AddTimedStatus(ply, id, duration, showDuration, active_icon)
net.Start("ttt2_status_effect_add_timed")
net.WriteString(id)
net.WriteUInt(duration, 32)
net.WriteBool(showDuration or false)
net.WriteUInt(active_icon or 1, 8)
net.Send(ply)
end

---
Expand All @@ -41,20 +59,20 @@ end
-- @param string id
-- @realm server
function STATUS:RemoveStatus(ply, id)
net.Start("ttt2_status_effect_remove")
net.WriteString(id)
net.Send(ply)
net.Start("ttt2_status_effect_remove")
net.WriteString(id)
net.Send(ply)
end

---
-- Removes each status for a given @{Player}
-- @param Player ply
-- @realm server
function STATUS:RemoveAll(ply)
net.Start("ttt2_status_effect_remove_all")
net.Send(ply)
net.Start("ttt2_status_effect_remove_all")
net.Send(ply)
end

hook.Add("PlayerSpawn", "status_removed", function(ply)
STATUS:RemoveAll(ply)
STATUS:RemoveAll(ply)
end)
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ if CLIENT then
surface.SetDrawColor(clr(c))
surface.DrawRect(x, y, w, h)

local w2 = math.Round(w * (p or 1))
local w_ = math.Round(w * (p or 1))
Alf21 marked this conversation as resolved.
Show resolved Hide resolved

surface.SetDrawColor(0, 0, 0, 165)
surface.DrawRect(x + w2, y, w - w2, h)
surface.DrawRect(x + w_, y, w - w_, h)

-- draw lines around this bar
self:DrawLines(x, y, w, h, c.a)
Expand Down
Loading