Skip to content

Commit

Permalink
Improve memory management of treads (#4640)
Browse files Browse the repository at this point in the history
  • Loading branch information
Garanas committed Jan 29, 2023
1 parent b067d18 commit f2d8bd2
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 79 deletions.
2 changes: 1 addition & 1 deletion lua/AI/AIBuilders/AIAirAttackBuilders.lua
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,10 @@ BuilderGroup {
{ IBC, 'BrainNotLowPowerMode', {} },
{ MIBC, 'ArmyNeedsTransports', {} },
{ EBC, 'GreaterThanEconEfficiencyOverTime', { 0.8, 1.05 }}, --DUNCAN - was 0.9
{ UCBC, 'LocationFactoriesBuildingLess', { 'LocationType', 1, categories.TRANSPORTFOCUS } },
{ UCBC, 'HaveGreaterThanUnitsWithCategory', { 5, categories.AIR * categories.ANTIAIR } }, --DUNCAN - added
{ UCBC, 'HaveGreaterThanUnitsWithCategory', { 8, categories.LAND * (categories.TECH2 + categories.TECH3) } }, --DUNCAN - added
{ UCBC, 'HaveLessThanUnitsWithCategory', { 3 , categories.TRANSPORTFOCUS * categories.TECH2} },
{ UCBC, 'LocationFactoriesBuildingLess', { 'LocationType', 1, categories.TRANSPORTFOCUS } },
},
BuilderType = 'Air',
},
Expand Down
118 changes: 114 additions & 4 deletions lua/defaultcomponents.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@

---@class ShieldEffectsComponent : Unit
---@field Trash TrashBag
---@field ShieldEffectsBag TrashBag
---@field ShieldEffectsBone Bone
---@field ShieldEffectsScale number
ShieldEffectsComponent = ClassSimple {

ShieldEffects = { },
ShieldEffects = {},
ShieldEffectsBone = 0,
ShieldEffectsScale = 1,

Expand All @@ -20,12 +19,123 @@ ShieldEffectsComponent = ClassSimple {
OnShieldEnabled = function(self)
self.ShieldEffectsBag:Destroy()
for _, v in self.ShieldEffects do
self.ShieldEffectsBag:Add(CreateAttachedEmitter(self, self.ShieldEffectsBone, self.Army, v):ScaleEmitter(self.ShieldEffectsScale))
self.ShieldEffectsBag:Add(CreateAttachedEmitter(self, self.ShieldEffectsBone, self.Army, v):ScaleEmitter(self
.ShieldEffectsScale))
end
end,

---@param self ShieldEffectsComponent
OnShieldDisabled = function(self)
self.ShieldEffectsBag:Destroy()
end,
}
}


---@type table<string, number>
local TechToDuration = {
TECH1 = 1,
TECH2 = 2,
TECH3 = 4,
EXPERIMENTAL = 16,
}

---@type table<string, number>
local TechToLOD = {
TECH1 = 120,
TECH2 = 180,
TECH3 = 240,
EXPERIMENTAL = 320,
}

---@class TreadComponent
---@field TreadBlueprint UnitBlueprintTreads
---@field TreadSuspend? boolean
---@field TreadThreads? table<number, thread>
TreadComponent = ClassSimple {

---@param self Unit | TreadComponent
OnCreate = function(self)
self.TreadBlueprint = self.Blueprint.Display.MovementEffects.Land.Treads
end,

---@param self Unit | TreadComponent
CreateMovementEffects = function(self)
local treads = self.TreadBlueprint
if treads then
self:AddThreadScroller(1.0, treads.ScrollMultiplier or 0.2)

local treadMarks = treads.TreadMarks
local treadType = self.TerrainType.Treads
if treadMarks and treadType and treadType ~= 'None' then
self:CreateTreads(treadMarks)
end
end
end,

---@param self Unit | TreadComponent
DestroyMovementEffects = function(self)
local treads = self.TreadBlueprint
if treads then
self:RemoveScroller()

if self.TreadThreads then
self.TreadSuspend = true
end
end
end,

---@param self Unit | TreadComponent
---@param treadsBlueprint UnitBlueprintTreadMarks
CreateTreads = function(self, treadsBlueprint)
local treadThreads = self.TreadThreads
if not treadThreads then
treadThreads = { }

for k, treadBlueprint in treadsBlueprint do
local thread = ForkThread(self.CreateTreadsThread, self, treadBlueprint)
treadThreads[k] = thread
self.Trash:Add(thread)
end

self.TreadThreads = treadThreads
else
self.TreadSuspend = nil
for k, thread in treadThreads do
ResumeThread(thread)
end
end
end,

---@param self Unit | TreadComponent
---@param treads UnitBlueprintTreadMarks
CreateTreadsThread = function(self, treads)

-- to local scope for performance
local WaitTicks = WaitTicks
local CreateSplatOnBone = CreateSplatOnBone
local SuspendCurrentThread = SuspendCurrentThread

local tech = self.Blueprint.TechCategory
local sizeX = treads.TreadMarksSizeX
local sizeZ = treads.TreadMarksSizeZ
local interval = 10 * treads.TreadMarksInterval
local treadOffset = treads.TreadOffset
local treadBone = treads.BoneName or 0
local treadTexture = treads.TreadMarks

local duration = treads.TreadLifeTime or TechToDuration[tech] or 1
local lod = TechToLOD[tech] or 120
local army = self.Army

while true do
while not self.TreadSuspend do
CreateSplatOnBone(self, treadOffset, treadBone, treadTexture, sizeX, sizeZ, lod, duration, army)
WaitTicks(interval)
end

SuspendCurrentThread()
self.TreadSuspend = nil
WaitTicks(1)
end
end,
}
42 changes: 37 additions & 5 deletions lua/defaultunits.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ local AdjacencyBuffs = import("/lua/sim/adjacencybuffs.lua")
local FireState = import("/lua/game.lua").FireState
local ScenarioFramework = import("/lua/scenarioframework.lua")

local TreadComponent = import("/lua/defaultcomponents.lua").TreadComponent


local RolloffUnitTable = { nil }
local RolloffPositionTable = { 0, 0, 0 }

Expand Down Expand Up @@ -2213,9 +2216,23 @@ AirTransport = ClassUnit(AirUnit, BaseTransport) {
end,
}

-- LAND UNITS
---@class LandUnit : MobileUnit
LandUnit = ClassUnit(MobileUnit) {}
---@class LandUnit : MobileUnit, TreadComponent
LandUnit = ClassUnit(MobileUnit, TreadComponent) {
OnCreate = function(self)
MobileUnit.OnCreate(self)
TreadComponent.OnCreate(self)
end,

CreateMovementEffects = function(self, effectsBag, typeSuffix, terrainType)
MobileUnit.CreateMovementEffects(self, effectsBag, typeSuffix, terrainType)
TreadComponent.CreateMovementEffects(self)
end,

DestroyMovementEffects = function(self)
MobileUnit.DestroyMovementEffects(self)
TreadComponent.DestroyMovementEffects(self)
end,
}

-- CONSTRUCTION UNITS
---@class ConstructionUnit : MobileUnit
Expand Down Expand Up @@ -2424,8 +2441,23 @@ SlowHoverLandUnit = ClassUnit(HoverLandUnit) {
}

-- AMPHIBIOUS LAND UNITS
---@class AmphibiousLandUnit : MobileUnit
AmphibiousLandUnit = ClassUnit(MobileUnit) { }
---@class AmphibiousLandUnit : MobileUnit, TreadComponent
AmphibiousLandUnit = ClassUnit(MobileUnit, TreadComponent) {
OnCreate = function(self)
MobileUnit.OnCreate(self)
TreadComponent.OnCreate(self)
end,

CreateMovementEffects = function(self, effectsBag, typeSuffix, terrainType)
MobileUnit.CreateMovementEffects(self, effectsBag, typeSuffix, terrainType)
TreadComponent.CreateMovementEffects(self)
end,

DestroyMovementEffects = function(self)
MobileUnit.DestroyMovementEffects(self)
TreadComponent.DestroyMovementEffects(self)
end,
}

---@class SlowAmphibiousLandUnit : AmphibiousLandUnit
SlowAmphibiousLandUnit = ClassUnit(AmphibiousLandUnit) {
Expand Down
1 change: 0 additions & 1 deletion lua/proptree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ Tree = Class(Prop) {
---@param dz number
---@param depth number
FallThread = function(self, dx, dy, dz, depth)

-- make it fall down
local motor = self:FallDown()
motor:Whack(dx, dy, dz, depth, true)
Expand Down
76 changes: 12 additions & 64 deletions lua/sim/Unit.lua
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ local cUnit = moho.unit_methods
---@field EventCallbacks table<string, function[]>
---@field Blueprint UnitBlueprint
---@field EngineFlags any
---@field TerrainType TerrainType
---@field EngineCommandCap? table<string, boolean>
---@field UnitBeingBuilt Unit?
Unit = ClassUnit(moho.unit_methods) {
Expand Down Expand Up @@ -1692,6 +1693,8 @@ Unit = ClassUnit(moho.unit_methods) {
end
end,



--- Called when a unit collides with a projectile to check if the collision is valid
---@param self Unit The unit we're checking the collision for
---@param other Projectile The projectile we're checking the collision with
Expand Down Expand Up @@ -3693,6 +3696,7 @@ Unit = ClassUnit(moho.unit_methods) {
---@param new string
---@param old string
OnTerrainTypeChange = function(self, new, old)
self.TerrainType = new
if self.MovementEffectsExist then
self:DestroyMovementEffects()
self:CreateMovementEffects(self.MovementEffectsBag, nil, new)
Expand Down Expand Up @@ -3814,14 +3818,6 @@ Unit = ClassUnit(moho.unit_methods) {
end
end,

---@param self Unit
---@param pos Vector
---@return TerrainTreadType
GetTTTreadType = function(self, pos)
local terrainType = GetTerrainType(pos[1], pos[3])
return terrainType.Treads or 'None'
end,

---@param fxType TerrainEffectType
---@param layer Layer
---@param pos Vector
Expand Down Expand Up @@ -3940,12 +3936,6 @@ Unit = ClassUnit(moho.unit_methods) {
bpTable = bpTable[layer]
local effectTypeGroups = bpTable.Effects

if bpTable.Treads then
self:CreateTreads(bpTable.Treads)
else
self:RemoveScroller()
end

if not effectTypeGroups or (effectTypeGroups and (table.empty(effectTypeGroups))) then
if not self.Footfalls and bpTable.Footfall then
WARN('*WARNING: No movement effect groups defined for unit ', repr(self.UnitId), ', Effect groups with bone lists must be defined to play movement effects. Add these to the Display.MovementEffects', layer, '.Effects table in unit blueprint. ')
Expand Down Expand Up @@ -4001,18 +3991,6 @@ Unit = ClassUnit(moho.unit_methods) {
self:ShakeCamera(shake.Radius, shake.MaxShakeEpicenter * 0.25, shake.MinShakeAtRadius * 0.25, 1)
end
end

-- Clean up treads
if self.TreadThreads then
for k, v in self.TreadThreads do
KillThread(v)
end
self.TreadThreads = {}
end

if bpTable[layer].Treads.ScrollTreads then
self:RemoveScroller()
end
end,

---@param self Unit
Expand Down Expand Up @@ -4108,44 +4086,6 @@ Unit = ClassUnit(moho.unit_methods) {
end
end,

---@param self Unit
---@param treads UnitBlueprintTreads
CreateTreads = function(self, treads)
if treads.ScrollTreads then
self:AddThreadScroller(1.0, treads.ScrollMultiplier or 0.2)
end

self.TreadThreads = {}
if treads.TreadMarks then
local type = self:GetTTTreadType(self:GetPosition())
if type ~= 'None' then
for k, v in treads.TreadMarks do
table.insert(self.TreadThreads, self:ForkThread(self.CreateTreadsThread, v, type))
end
end
end
end,

---@param self Unit
---@param treads UnitBlueprintTreadMarks
---@param type string
CreateTreadsThread = function(self, treads, type)
local sizeX = treads.TreadMarksSizeX
local sizeZ = treads.TreadMarksSizeZ
local interval = treads.TreadMarksInterval
local treadOffset = treads.TreadOffset
local treadBone = treads.BoneName or 0
local treadTexture = treads.TreadMarks
local duration = treads.TreadLifeTime or 10

while true do
-- Syntactic reference
-- CreateSplatOnBone(entity, offset, boneName, textureName, sizeX, sizeZ, lodParam, duration, army)
CreateSplatOnBone(self, treadOffset, treadBone, treadTexture, sizeX, sizeZ, 130, duration, self.Army)
WaitSeconds(interval)
end
end,

---@param self Unit
---@param footfall boolean
---@return boolean
Expand Down Expand Up @@ -5181,6 +5121,14 @@ Unit = ClassUnit(moho.unit_methods) {

--- Deprecated functionality

---@param self Unit
---@param pos Vector
---@return TerrainTreadType
GetTTTreadType = function(self, pos)
local terrainType = GetTerrainType(pos[1], pos[3])
return terrainType.Treads or 'None'
end,

---@deprecated
---@param self Unit
---@param fn function
Expand Down
8 changes: 4 additions & 4 deletions units/UEL0401/UEL0401_unit.bp
Original file line number Diff line number Diff line change
Expand Up @@ -238,24 +238,24 @@ UnitBlueprint {
TreadMarks = {
{
TreadMarks = 'tank_treads06_albedo',
TreadMarksInterval = 0.6,
TreadMarksInterval = 0.3,
TreadMarksSizeX = 5,
TreadMarksSizeZ = 5.5,
TreadOffset = {
0,
0,
-1.5,
-0.5,
},
},
{
TreadMarks = 'tank_treads06_albedo',
TreadMarksInterval = 0.6,
TreadMarksInterval = 0.3,
TreadMarksSizeX = 5.5,
TreadMarksSizeZ = 5.5,
TreadOffset = {
0,
0,
-5.5,
-4.5,
},
},
},
Expand Down

0 comments on commit f2d8bd2

Please sign in to comment.