forked from FAForever/fa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
EffectUtilitiesSeraphim.lua
215 lines (179 loc) · 8.67 KB
/
EffectUtilitiesSeraphim.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
-- imports for functionality
local EffectTemplate = import("/lua/effecttemplates.lua")
-- globals as upvalues for performance
local AttachBeamEntityToEntity = AttachBeamEntityToEntity
local CreateSlider = CreateSlider
local WaitTicks = WaitTicks
local MathMax = math.max
local MathMin = math.min
local TableGetn = table.getn
local IEffectScaleEmitter = moho.IEffect.ScaleEmitter
local IEffectSetEmitterParam = moho.IEffect.SetEmitterParam
local SliderSetGoal = moho.SlideManipulator.SetGoal
local SliderSetSpeed = moho.SlideManipulator.SetSpeed
local SliderSetWorldUnits = moho.SlideManipulator.SetWorldUnits
local TrashBagAdd = TrashBag.Add
local UnitGetFractionComplete = moho.unit_methods.GetFractionComplete
-- cached effects
local SeraphimBuildBeams01 = EffectTemplate.SeraphimBuildBeams01
local BuildEffectBaseEmitters = {
'/effects/emitters/seraphim_being_built_ambient_01_emit.bp',
}
local BuildEffectsEmitters = {
'/effects/emitters/seraphim_being_built_ambient_02_emit.bp',
'/effects/emitters/seraphim_being_built_ambient_03_emit.bp',
'/effects/emitters/seraphim_being_built_ambient_04_emit.bp',
'/effects/emitters/seraphim_being_built_ambient_05_emit.bp',
}
--- Creates the seraphim factory building beam effects.
---@param builder Unit The factory that is building the unit
---@param unitBeingBuilt Unit The unit that is being built by the factory
---@param effectBones string[] The bones of the factory to spawn effects for
---@param effectsBag TrashBag The trashbag for effects
function CreateSeraphimUnitEngineerBuildingEffects(builder, unitBeingBuilt, effectBones, effectsBag)
-- do not create beams if things turn out to be destroyed
if builder.Dead or unitBeingBuilt.Dead then
return
end
local army = builder.Army
for _, bone in effectBones do
TrashBagAdd(effectsBag, CreateAttachedEmitter(builder, bone, army, '/effects/emitters/seraphim_build_01_emit.bp'))
for _, effect in SeraphimBuildBeams01 do
TrashBagAdd(effectsBag, AttachBeamEntityToEntity(builder, bone, unitBeingBuilt, -1, army, effect))
end
end
end
--- Creates the seraphim factory building effects.
---@param builder Unit The factory that is building the unit
---@param unitBeingBuilt Unit The unit that is being built by the factory
---@param effectBones string[] The bones of the factory to spawn effects for
---@param locationBone string The main build bone where the unit spawns on top of (unused)
---@param effectsBag TrashBag The trashbag for effects
function CreateSeraphimFactoryBuildingEffects(builder, unitBeingBuilt, effectBones, locationBone, effectsBag)
-- -- initialize various info used throughout the function
local army = builder.Army
local bp = unitBeingBuilt.Blueprint
local Physics = bp.Physics
local Footprint = bp.Footprint
local sx = Physics.MeshExtentsX or Footprint.SizeX
local sz = Physics.MeshExtentsZ or Footprint.SizeZ
local sy = Physics.MeshExtentsY or Footprint.SizeYX or MathMin(sx, sz)
-- do not apply offsets for subs and air units
local offset = 0
if unitBeingBuilt.Blueprint.CategoriesHash["HOVER"] then
offset = bp.Elevation or 0
end
-- -- Create effects for each build bone
local CreateAttachedEmitter = CreateAttachedEmitter
for _, bone in effectBones do
TrashBagAdd(effectsBag, CreateAttachedEmitter(builder, bone, army, '/effects/emitters/seraphim_build_01_emit.bp'))
for _, effect in SeraphimBuildBeams01 do
TrashBagAdd(effectsBag, AttachBeamEntityToEntity(builder, bone, unitBeingBuilt, -1, army, effect))
end
end
-- -- Check if unit has been initialised
local slider = unitBeingBuilt.ConstructionSlider
if not unitBeingBuilt.ConstructionInitialised then
unitBeingBuilt.ConstructionInitialised = true
-- -- Add seraphim pool effect
local unitBeingBuiltTrash = unitBeingBuilt.Trash
local unitOnStopBeingBuiltTrash = unitBeingBuilt.OnBeingBuiltEffectsBag
for _, effect in BuildEffectsEmitters do
local emitter = CreateAttachedEmitter(unitBeingBuilt, -1, army, effect)
TrashBagAdd(unitBeingBuiltTrash, emitter)
TrashBagAdd(unitOnStopBeingBuiltTrash, emitter)
end
-- -- Create slider to move unit
slider = CreateSlider(unitBeingBuilt, 0)
unitBeingBuilt.ConstructionSlider = slider
SliderSetWorldUnits(slider,true)
SliderSetGoal(slider, 0, sy + offset, 0)
SliderSetSpeed(slider, 100)
TrashBagAdd(unitBeingBuiltTrash, slider)
TrashBagAdd(unitOnStopBeingBuiltTrash, slider)
WaitFor(slider)
end
-- localize for optimal access
local UnitGetFractionComplete = UnitGetFractionComplete
local completed = UnitGetFractionComplete(unitBeingBuilt)
-- -- Gradually move the unit to the plateau
while not unitBeingBuilt.Dead and completed < 1.0 do
SliderSetGoal(slider, 0, (1 - completed) * sy + offset, 0)
SliderSetSpeed(slider, completed * completed * completed)
completed = UnitGetFractionComplete(unitBeingBuilt)
WaitTicks(2)
end
-- -- Nillify temporary tables
unitBeingBuilt.ConstructionSlider = nil
unitBeingBuilt.ConstructionInitialised = nil
end
--- Creates the seraphim build cube effect.
---@param unitBeingBuilt Unit The unit that is being built by the factory
---@param builder Unit The factory that is building the unit
---@param effectsBag TrashBag The trashbag for effects
---@param scaleFactor number A scale factor for the effects
function CreateSeraphimBuildThread(unitBeingBuilt, builder, effectsBag, scaleFactor)
-- -- initialize various info used throughout the function
local army = builder.Army
-- optimize local access
local IEffectScaleEmitter = IEffectScaleEmitter
local UnitGetFractionComplete = UnitGetFractionComplete
-- matches with number of effects being made, pre-allocates the table
local emitters = { false, false, false, false, false }
local emittersHead = 1
-- determine a sane LOD cutoff for the size of the unit
local bp = unitBeingBuilt.Blueprint
local lods = bp.Display.Mesh.LODs
local count = TableGetn(lods)
local sx = bp.Physics.MeshExtentsX or bp.Footprint.SizeX
local sz = bp.Physics.MeshExtentsZ or bp.Footprint.SizeZ
local LODCutoff = 0.9 * lods[count].LODCutoff or (90 * MathMax(sx, sz))
-- smaller inner, dark-purple effect
for _, effect in BuildEffectsEmitters do
local emitter = CreateAttachedEmitter(unitBeingBuilt, -1, army, effect)
IEffectScaleEmitter(emitter, scaleFactor)
IEffectSetEmitterParam(emitter, "LODCUTOFF", lods[1].LODCutoff)
TrashBagAdd(effectsBag, emitter)
emitters[emittersHead] = emitter
emittersHead = emittersHead + 1
end
-- large outer radius effect
for _, effect in BuildEffectBaseEmitters do
local emitter = CreateAttachedEmitter(unitBeingBuilt, -1, army, effect)
IEffectScaleEmitter(emitter,scaleFactor)
IEffectSetEmitterParam(emitter, "LODCUTOFF", LODCutoff)
TrashBagAdd(effectsBag, emitter)
emitters[emittersHead] = emitter
emittersHead = emittersHead + 1
end
-- -- Scale effects until the unit is finished
-- only naval factories are not square, use the Z axis to get largest axis
local unitScaleMetric = 0.75 * sz
local scaledUnitMetric = unitScaleMetric * scaleFactor
local complete = UnitGetFractionComplete(unitBeingBuilt)
while not unitBeingBuilt.Dead and complete < 1.0 do
local emitterScale = 1 + scaledUnitMetric * complete
for k = 1, emittersHead - 1 do
IEffectScaleEmitter(emitters[k], emitterScale)
end
complete = UnitGetFractionComplete(unitBeingBuilt)
WaitTicks(4)
end
-- -- Poof - we're finished and clean up
CreateLightParticleIntel(unitBeingBuilt, -1, army, unitScaleMetric * 3.5, 8, 'glow_02', 'ramp_blue_22')
end
--- Creates the seraphim build cube effect.
---@param unitBeingBuilt Unit the unit that is being built by the factory
---@param builder Unit The factory that is building the unit
---@param effectsBag TrashBag The trashbag for effects
function CreateSeraphimBuildBaseThread(unitBeingBuilt, builder, effectsBag)
CreateSeraphimBuildThread(unitBeingBuilt, builder, effectsBag, 1)
end
--- Creates the seraphim build cube effect.
---@param unitBeingBuilt Unit the unit that is being built by the factory
---@param builder Unit The factory that is building the unit
---@param effectsBag TrashBag The trashbag for effects
---@param scale? number
function CreateSeraphimExperimentalBuildBaseThread(unitBeingBuilt, builder, effectsBag, scale)
CreateSeraphimBuildThread(unitBeingBuilt, builder, effectsBag, scale or 1)
end