Skip to content

Commit

Permalink
OC AoE fix (FAForever#2392)
Browse files Browse the repository at this point in the history
* OC AoE fix

* OC Decal

* OC decal

* OC Decal

* OC Decal

* Update worldview.lua

* symbol

* OverchargeCanKill()

* Texture info

* textures

* OverchargeCanKill() -- a little mistake again=)

* OverchargeCanKill() +ACU +Structures

* OC vs buidling fix

* OverchargeCanKill() changes according to OC fix

* Damage vs ACU shield, structures + aoe bug fixes

* Static damage vs structures/ACU shield

* OverchargeCanKill()

* Blueprint: structureDamage

* Blueprint: structureDamage

* Blueprint: structureDamage

* Blueprint: structureDamage

* Blueprint: structureDamage

* ...

* Bp: maxDamage = 15000

* Bp: maxDamage = 15000

* Bp: maxDamage = 15000

* Bp: maxDamage = 15000

* Bp: maxDamage = 15000

* Formatting + shield changes

Bug fixed:
- static shields taking full damage
- Uef ACU buble shield taking full damage

* Formatting. Second try

* One more try and coding is not my hobby anymore

I'm serious

* New detection system

shell.pos instead of target.pos in calculations

+ additional getUnitsInSphere for t4 units

* Formatting, code optimization etc.

* mistake

* Blueprints. Forgot autoOC

* Code optimization

- CategoriesHash. in shield.lua
- OverchargeCanKill() now uses selecteUnit blueprint instead of hardcoded Aeon ACU bp. + CategoriesHash instead of string.find.
- unitsHP = {} -> maxHP = 0  -> no table.sort (all comparisons are in loops).

* oc "idle" symbol

can kill - green
can't kill - orange
idle - grey

* Few fixes in OverchargeCanKill()

* More fixes + commented LOG() in defproj.lua
  • Loading branch information
Strogoo authored and JaggedAppliance committed Mar 26, 2018
1 parent 4d3fda5 commit 3bff897
Show file tree
Hide file tree
Showing 27 changed files with 196 additions and 31 deletions.
11 changes: 10 additions & 1 deletion lua/defaultunits.lua
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,15 @@ StructureUnit = Class(Unit) {
end
end
end,

DoTakeDamage = function(self, instigator, amount, vector, damageType)
-- Handle incoming OC damage
if damageType == 'Overcharge' then
local wep = instigator:GetWeaponByLabel('OverCharge')
amount = wep:GetBlueprint().Overcharge.structureDamage
end
Unit.DoTakeDamage(self, instigator, amount, vector, damageType)
end,
}

-- FACTORY UNITS
Expand Down Expand Up @@ -2283,7 +2292,7 @@ ACUUnit = Class(CommandUnit) {
ArmyBrains[self:GetArmy()]:SetUnitStat(self:GetUnitId(), "lowest_health", self:GetHealth())
self.WeaponEnabled = {}
end,

DoTakeDamage = function(self, instigator, amount, vector, damageType)
-- Handle incoming OC damage
if damageType == 'Overcharge' then
Expand Down
9 changes: 9 additions & 0 deletions lua/shield.lua
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ Shield = Class(moho.shield_methods, Entity) {
end,

ApplyDamage = function(self, instigator, amount, vector, dmgType, doOverspill)
if dmgType == 'Overcharge' and instigator.EntityId then
local wep = instigator:GetWeaponByLabel('OverCharge')
if self.Owner:GetBlueprint().CategoriesHash.COMMAND then --fixed damage for all ACU shields
amount = wep:GetBlueprint().Overcharge.commandDamage
elseif self.Owner:GetBlueprint().CategoriesHash.STRUCTURE then -- fixed damage for static shields
amount = wep:GetBlueprint().Overcharge.structureDamage * 2
-- Static shields absorbing 50% OC damage somehow, I don't want to change anything anywhere so just *2.
end
end
if self.Owner ~= instigator then
local absorbed = self:OnGetDamageAbsorption(instigator, amount, dmgType)

Expand Down
83 changes: 65 additions & 18 deletions lua/sim/DefaultProjectiles.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
-- File : /lua/defaultprojectiles.lua
-- Author(s): John Comes, Gordon Duclos
-- Summary : Script for default projectiles
-- Copyright © 2005 Gas Powered Games, Inc. All rights reserved.
-- Copyright © 2005 Gas Powered Games, Inc. All rights reserved.
-----------------------------------------------------------------
local Projectile = import('/lua/sim/Projectile.lua').Projectile

local UnitsInSphere = import('/lua/utilities.lua').GetTrueEnemyUnitsInSphere
local GetDistanceBetweenTwoEntities = import('/lua/utilities.lua').GetDistanceBetweenTwoEntities
-----------------------------------------------------------------
-- Null Shell
-----------------------------------------------------------------
Expand Down Expand Up @@ -314,12 +315,12 @@ BaseGenericDebris = Class(EmitterProjectile){
-----------------------------------------------------------
OverchargeProjectile = Class() {
OnImpact = function(self, targetType, targetEntity)
WARN('Inside OCPROJ OnImpact')
--[[WARN('Inside OCPROJ OnImpact')
LOG(targetType)
LOG(targetEntity)
if targetEntity and IsUnit(targetEntity) then
LOG(targetEntity:GetUnitId())
end
end]]

-- Stop us doing blueprint damage in the other OnImpact call if we ditch this one without resetting self.DamageData
self.DamageData.DamageAmount = 0
Expand All @@ -334,6 +335,7 @@ OverchargeProjectile = Class() {
-- Overcharge = {
-- energyMult = _, -- What proportion of current storage are we allowed to spend?
-- commandDamage = _, -- Takes effect in ACUUnit DoTakeDamage()
-- structureDamage = _, -- Takes effect in StructureUnit DoTakeDamage() & Shield ApplyDamage()
-- maxDamage = _,
-- minDamage = _,
-- },
Expand All @@ -357,7 +359,7 @@ OverchargeProjectile = Class() {
targetEntity = targetEntity.Owner
end

if not EntityCategoryContains(categories.COMMAND, targetEntity) then -- Static damage for against ACUs

-- Get max energy available to drain according to how much we have
local energyLimit = launcher:GetAIBrain():GetEconomyStored('ENERGY') * data.energyMult
local energyLimitDamage = self:EnergyAsDamage(energyLimit)
Expand All @@ -367,29 +369,36 @@ OverchargeProjectile = Class() {

-- How much damage do we actually need to kill the unit?
local idealDamage = targetEntity:GetHealth()
local shield = targetEntity.MyShield

local shieldHealth = 0
if shield then -- No need to check if shield is up. If it is, we hit it. If not, no need to damage it, so add 0.
shieldHealth = shield:GetHealth()
local maxHP = self:UnitsDetection(targetType, targetEntity)

idealDamage = maxHP or data.minDamage

-----SHIELDS------
if targetEntity.MyShield and targetEntity.MyShield.ShieldType == 'Bubble' then
if EntityCategoryContains(categories.STRUCTURE, targetEntity) then
idealDamage = data.minDamage
else
idealDamage = targetEntity.MyShield:GetMaxHealth()
end
--MaxHealth instead of GetHealth because with getHealth OC won't kill bubble shield which is in AoE range but has more hp than targetEntity.MyShield.
--good against group of mobile shields
end

if shield.ShieldType ~= 'Bubble' then -- Personal shields. Damage to overwhelm.
idealDamage = idealDamage + shieldHealth
else -- Mobile shield generators. Hit the shield, not the HP.
idealDamage = shieldHealth

------ ACU -------
if EntityCategoryContains(categories.COMMAND, targetEntity) and not maxHP then -- no units around ACU - min.damage
idealDamage = data.minDamage
end

damage = math.min(damage, idealDamage)
damage = math.max(data.minDamage, damage)
end

end

-- Turn the final damage into energy
local drain = self:DamageAsEnergy(damage)

LOG('Drain is ' .. drain)
LOG('Damage is ' .. damage)
--LOG('Drain is ' .. drain)
--LOG('Damage is ' .. damage)
self.DamageData.DamageAmount = damage

if drain > 0 then
Expand All @@ -411,4 +420,42 @@ OverchargeProjectile = Class() {
EnergyAsDamage = function(self, energy)
return (math.log((energy + 9700) / 3000) / 0.000095) - 15500
end,

UnitsDetection = function(self, targetType, targetEntity)
-- looking for units around target which are in splash range
local launcher = self:GetLauncher()
local maxHP = 0

for _, unit in UnitsInSphere(launcher, self:GetPosition(), 2.7, categories.MOBILE -categories.COMMAND) do
if unit.MyShield and unit:GetHealth() + unit.MyShield:GetHealth() > maxHP then
maxHP = unit:GetHealth() + unit.MyShield:GetHealth()
elseif unit:GetHealth() > maxHP then
maxHP = unit:GetHealth()
end
end

for _, unit in UnitsInSphere(launcher, self:GetPosition(), 13.2, categories.EXPERIMENTAL*categories.LAND*categories.MOBILE) do
-- Special for fatty's shield
if EntityCategoryContains(categories.UEF, unit) and unit.MyShield._IsUp and unit.MyShield:GetMaxHealth() > maxHP then
maxHP = unit.MyShield:GetMaxHealth()
elseif unit:GetHealth() > maxHP then
local distance = math.min(unit:GetBlueprint().SizeX, unit:GetBlueprint().SizeZ)
if GetDistanceBetweenTwoEntities(unit, self) < distance + self.DamageData.DamageRadius then
maxHP = unit:GetHealth()
end
end
end

if EntityCategoryContains(categories.EXPERIMENTAL, targetEntity) and targetEntity:GetHealth() > maxHP then
maxHP = targetEntity:GetHealth()
--[[ we need this because if OC shell hitted top part of GC model its health won't be in our table
Bug appeared since we use shell.pos in getUnitsInSphere instead of target.pos.
Shell is too far from actual target.pos(target pos is somewhere near land and shell is near GC's head)
and getUnits returns nothing. Same to GetDistance. Distance between shell and GC pos > than math.min (x,z) size]]
end

if maxHP ~= 0 then
return maxHP
end
end,
}
2 changes: 2 additions & 0 deletions lua/skins/skins.lua
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ skins = {
W_E = {'/textures/ui/common/game/cursors/w_e.dds', 15, 15},
MOVE_WINDOW = {'/textures/ui/common/game/cursors/move_window.dds', 15, 15},
ATTACK_MOVE = {'/textures/ui/common/game/cursors/attack_move-.dds', 15, 15, 12, 12},
OVERCHARGE_ORANGE = {'/textures/ui/common/game/cursors/overcharge_orange-.dds', 15, 15, 8, 12},
OVERCHARGE_GREY = {'/textures/ui/common/game/cursors/overcharge_grey-.dds', 15, 15, 8, 12},
},
},
}
Expand Down
21 changes: 20 additions & 1 deletion lua/ui/controls/worldview.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ local Ping = import('/lua/ui/game/ping.lua')
local UserDecal = import('/lua/user/UserDecal.lua').UserDecal
local WorldViewMgr = import('/lua/ui/game/worldview.lua')
local Prefs = import('/lua/user/prefs.lua')
local OverchargeCanKill = import('/lua/ui/game/unitview.lua').OverchargeCanKill

WorldViewParams = {
ui_SelectTolerance = 7.0,
Expand Down Expand Up @@ -128,10 +129,19 @@ local function AttackDecalFunc(mode)
)
end

local function OverchargeDecalFunc()
return RadiusDecalFunction(
function(w)
return w.DamageType == 'Overcharge'
end
)
end

DecalFunctions = {
RULEUCC_Attack = AttackDecalFunc,
RULEUCC_Nuke = NukeDecalFunc,
RULEUCC_Tactical = TacticalDecalFunc
RULEUCC_Tactical = TacticalDecalFunc,
RULEUCC_Overcharge = OverchargeDecalFunc
}

WorldView = Class(moho.UIWorldView, Control) {
Expand Down Expand Up @@ -215,6 +225,15 @@ WorldView = Class(moho.UIWorldView, Control) {
elseif command_mode == "order" then
if self:ShowConvertToPatrolCursor() then
self.Cursor = {UIUtil.GetCursor("MOVE2PATROLCOMMAND")}
elseif command_data.name == "RULEUCC_Overcharge" then
local canKill = OverchargeCanKill()
if canKill == true then
self.Cursor = {UIUtil.GetCursor(command_data.name)}
elseif canKill == false then
self.Cursor = {UIUtil.GetCursor("OVERCHARGE_ORANGE")}
else
self.Cursor = {UIUtil.GetCursor("OVERCHARGE_GREY")}
end
else
if command_data.cursor then
self.Cursor = {UIUtil.GetCursor(command_data.cursor)}
Expand Down
68 changes: 67 additions & 1 deletion lua/ui/game/unitview.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,70 @@ local GetUnitRolloverInfo = import("/lua/keymap/selectedinfo.lua").GetUnitRollov

local selectedUnit = nil
local updateThread = nil

local unitHP = {}
controls = import('/lua/ui/controls.lua').Get()

function OverchargeCanKill()
if unitHP[1] and unitHP.blueprintId then
local selected = GetSelectedUnits()
local ACU
local ACUBp
local bp

for _, unit in selected do
if unit:GetBlueprint().CategoriesHash.COMMAND or EntityCategoryContains(categories.SUBCOMMANDER * categories.SERAPHIM, unit) then
ACU = unit
break
end
end

if ACU then
ACUBp = ACU:GetBlueprint()

if ACUBp.Weapon[2].Overcharge then
bp = ACUBp.Weapon[2].Overcharge
elseif ACUBp.Weapon[3].Overcharge then -- cyb ACU
bp = ACUBp.Weapon[3].Overcharge
-- First weapon in cyb bp is "torpedo fix". Weapon[1] - torp, [2] - normal gun, [3] - OC. Other ACUs: [1] - normal, [2] - OC.
end

if bp then
local targetCategories = __blueprints[unitHP.blueprintId].CategoriesHash
-- this one is from DefaultProjectiles.lua OverchargeProjectile EnergyAsDamage()
local damage = (math.log((GetEconomyTotals().stored.ENERGY * bp.energyMult + 9700) / 3000) / 0.000095) - 15500

if damage > bp.maxDamage then
damage = bp.maxDamage
end

if targetCategories.COMMAND then
if unitHP[1] < bp.commandDamage then
unitHP[1] = nil
return true
else
unitHP[1] = nil
return false
end
elseif targetCategories.STRUCTURE then
if unitHP[1] < bp.structureDamage then
unitHP[1] = nil
return true
else
unitHP[1] = nil
return false
end
elseif unitHP[1] < damage then
unitHP[1] = nil
return true
else
unitHP[1] = nil
return false
end
end
end
end
end

function Contract()
controls.bg:SetNeedsFrameUpdate(false)
controls.bg:Hide()
Expand Down Expand Up @@ -301,6 +362,11 @@ function UpdateWindow(info)

-- Removing a MaxHealth buff causes health > maxhealth until a damage event for some reason
info.health = math.min(info.health, info.maxHealth)

if not info.userUnit then
unitHP[1] = info.health
unitHP.blueprintId = info.blueprintId
end

controls.healthBar:SetValue(info.health/info.maxHealth)
if info.health/info.maxHealth > .75 then
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
7 changes: 5 additions & 2 deletions units/UAL0001/UAL0001_unit.bp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ UnitBlueprint {
'SHOWQUEUE',
'OVERLAYDIRECTFIRE',
'OVERLAYOMNI',
'SHOWATTACKRETICLE',
},
Defense = {
AirThreatLevel = 0,
Expand Down Expand Up @@ -974,7 +975,8 @@ UnitBlueprint {
Overcharge = {
energyMult = 0.9,
commandDamage = 400,
maxDamage = 40000,
structureDamage = 800,
maxDamage = 15000,
minDamage = 1500,
},
OverChargeWeapon = true,
Expand Down Expand Up @@ -1061,7 +1063,8 @@ UnitBlueprint {
Overcharge = {
energyMult = 0.9,
commandDamage = 400,
maxDamage = 40000,
structureDamage = 800,
maxDamage = 15000,
minDamage = 1500,
},
ProjectileId = '/projectiles/ADFOverCharge01/ADFOverCharge01_proj.bp',
Expand Down
6 changes: 4 additions & 2 deletions units/UEL0001/UEL0001_unit.bp
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,8 @@ UnitBlueprint {
Overcharge = {
energyMult = 0.9,
commandDamage = 400,
maxDamage = 40000,
structureDamage = 800,
maxDamage = 15000,
minDamage = 1500,
},
OverChargeWeapon = true,
Expand Down Expand Up @@ -1126,7 +1127,8 @@ UnitBlueprint {
Overcharge = {
energyMult = 0.9,
commandDamage = 400,
maxDamage = 40000,
structureDamage = 800,
maxDamage = 15000,
minDamage = 1500,
},
ProjectileId = '/projectiles/TDFOverCharge01/TDFOverCharge01_proj.bp',
Expand Down
7 changes: 5 additions & 2 deletions units/URL0001/URL0001_unit.bp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ UnitBlueprint {
'SHOWQUEUE',
'OVERLAYDIRECTFIRE',
'OVERLAYOMNI',
'SHOWATTACKRETICLE',
},
Defense = {
AirThreatLevel = 0,
Expand Down Expand Up @@ -923,7 +924,8 @@ UnitBlueprint {
Overcharge = {
energyMult = 0.9,
commandDamage = 400,
maxDamage = 40000,
structureDamage = 800,
maxDamage = 15000,
minDamage = 1500,
},
OverChargeWeapon = true,
Expand Down Expand Up @@ -1011,7 +1013,8 @@ UnitBlueprint {
Overcharge = {
energyMult = 0.9,
commandDamage = 400,
maxDamage = 40000,
structureDamage = 800,
maxDamage = 15000,
minDamage = 1500,
},
ProjectileId = '/projectiles/CDFCannonMolecularOvercharge01/CDFCannonMolecularOvercharge01_proj.bp',
Expand Down
Loading

0 comments on commit 3bff897

Please sign in to comment.