Skip to content

Commit

Permalink
Implement blocking death nukes using shields
Browse files Browse the repository at this point in the history
  • Loading branch information
lL1l1 committed Apr 7, 2024
1 parent 4779121 commit 4110861
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 2 deletions.
33 changes: 33 additions & 0 deletions lua/ShieldAbsorptionValues.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
--**********************************************************************************
--** Copyright (c) 2024 FAForever
--**
--** Permission is hereby granted, free of charge, to any person obtaining a copy
--** of this software and associated documentation files (the "Software"), to deal
--** in the Software without restriction, including without limitation the rights
--** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--** copies of the Software, and to permit persons to whom the Software is
--** furnished to do so, subject to the following conditions:
--**
--** The above copyright notice and this permission notice shall be included in all
--** copies or substantial portions of the Software.
--**
--** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--** SOFTWARE.
--**********************************************************************************

---@alias AbsorptionType
---| "Default"

--- Defines what proportion of damage a shield of `AbsorptionType` absorbs from a specific `DamageType`
--- Overrides the behavior of shields absorbing damage depending on their owner's armor type
---@type table<AbsorptionType, table<DamageType, number>>
shieldAbsorptionValues = {
["Default"] = {
["Deathnuke"] = 1.0
},
}
26 changes: 24 additions & 2 deletions lua/shield.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ local Entity = import("/lua/sim/entity.lua").Entity
local EffectTemplate = import("/lua/effecttemplates.lua")
local Util = import("/lua/utilities.lua")

local shieldAbsorptionValues = import("/lua/ShieldAbsorptionValues.lua").shieldAbsorptionValues

local DeprecatedWarnings = {}

local VectorCached = Vector(0, 0, 0)
Expand Down Expand Up @@ -147,6 +149,7 @@ end
---@field PassOverkillDamage boolean
---@field ImpactMeshBp string
---@field SkipAttachmentCheck boolean
---@field AbsorptionType AbsorptionType
Shield = ClassShield(moho.shield_methods, Entity) {

RemainEnabledWhenAttached = false,
Expand Down Expand Up @@ -212,13 +215,17 @@ Shield = ClassShield(moho.shield_methods, Entity) {
EntityAttachBoneTo(self, -1, spec.Owner, -1)

-- lookup as to whether we're static or a commander shield
local ownerCategories = self.Owner.Blueprint.CategoriesHash
local ownerBp = self.Owner.Blueprint
local ownerCategories = ownerBp.CategoriesHash
if ownerCategories.STRUCTURE then
self.StaticShield = true
elseif ownerCategories.COMMAND then
self.CommandShield = true
end

-- lookup our damage absorption type
self.AbsorptionType = ownerBp.Defense.Shield.AbsorptionType or "Default"

-- use trashbag of the unit that owns us
self.Trash = self.Owner.Trash

Expand Down Expand Up @@ -440,10 +447,19 @@ Shield = ClassShield(moho.shield_methods, Entity) {
-- under the shield. The default is to always absorb as much as possible
-- but the reason this function exists is to allow flexible implementations
-- like shields that only absorb partial damage (like armor).
--- How much of incoming damage is absorbed by the shield. Used by the engine to calculate remainder spillover damage
---@param self Shield
---@param instigator Unit
---@param amount number
---@param type DamageType
---@return number damageAbsorbed If not all damage is absorbed, the remainder passes to targets under the shield.
OnGetDamageAbsorption = function(self, instigator, amount, type)
-- Allow decoupling the shield from the owner's armor multiplier
local absorptionMulti = shieldAbsorptionValues[self.AbsorptionType][type] or self.Owner:GetArmorMult(type)

-- Like armor damage, first multiply by armor reduction, then apply handicap
-- See SimDamage.cpp (DealDamage function) for how this should work
amount = amount * (self.Owner:GetArmorMult(type))
amount = amount * absorptionMulti
amount = amount * (1.0 - ArmyGetHandicap(self.Army))

local health = EntityGetHealth(self)
Expand All @@ -454,6 +470,12 @@ Shield = ClassShield(moho.shield_methods, Entity) {
end
end,

-- Used by PersonalShield and PersonalBubble to pass damage to the Owner Unit
---@param self Shield
---@param instigator Unit
---@param amount number
---@param type DamageType
---@return number overkillDamage
GetOverkill = function(self, instigator, amount, type)
-- Like armor damage, first multiply by armor reduction, then apply handicap
-- See SimDamage.cpp (DealDamage function) for how this should work
Expand Down

0 comments on commit 4110861

Please sign in to comment.