Skip to content

Commit fce6411

Browse files
committed
CreateUnit refactoring / improvements
- Move parsing to separate class, pass a pointer to TechnoExt::CreateUnit function instead of large amount of parameters - Fix an issue where CreateUnit.AIMission did not get correctly used - Add CreateUnit.RequireOwner which aborts creation of unit if there is no owner set or the house has been defeated
1 parent d6307cd commit fce6411

File tree

10 files changed

+170
-100
lines changed

10 files changed

+170
-100
lines changed

Phobos.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
</ProjectConfiguration>
1919
</ItemGroup>
2020
<ItemGroup>
21+
<ClCompile Include="src\New\Type\Affiliated\CreateUnitTypeClass.cpp" />
2122
<ClCompile Include="src\Blowfish\blowfish.cpp" />
2223
<ClCompile Include="src\Blowfish\Hooks.Blowfish.cpp" />
2324
<ClCompile Include="src\Ext\Cell\Body.cpp" />
@@ -195,6 +196,7 @@
195196
<ClCompile Include="YRpp\StaticInits.cpp" />
196197
</ItemGroup>
197198
<ItemGroup>
199+
<ClInclude Include="src\New\Type\Affiliated\CreateUnitTypeClass.h" />
198200
<ClInclude Include="src\Blowfish\blowfish.h" />
199201
<ClInclude Include="src\Ext\Cell\Body.h" />
200202
<ClInclude Include="src\New\Entity\AttachEffectClass.h" />

docs/New-or-Enhanced-Logics.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ Shield.InheritStateOnReplace=false ; boolean
455455
![image](_static/images/animToUnit.gif)
456456

457457
- Animations can now create (or "convert" to) any unit (vehicles, aircraft and infantry) when they end via `CreateUnit`. This offers more settings than `MakeInfantry` does for infantry.
458-
- `CreateUnit.Owner` determines which house will own the created unit. This only works as expected if the animation has owner set.
458+
- `CreateUnit.Owner` determines which house will own the created unit. This only works as expected if the animation has owner set. If there is no owner or the owner house has been defeated, the created unit will be owned by first house from Civilian side unless `CreateUnit.RequireOwner` is set to true in which case no unit will be created.
459459
- Vehicle [destroy animations](Fixed-or-Improved-Logics.md#destroy-animations), animations from Warhead `AnimList/SplashList` and map trigger action `41 Play Anim At` will have the owner set correctly.
460460
- `CreateUnit.RemapAnim`, if set to true, will cause the animation to be drawn in unit palette and remappable to owner's team color.
461461
- `CreateUnit.Mission` determines the initial mission of the created unit. This can be overridden for AI players by setting `CreateUnit.AIMission`.
@@ -473,6 +473,7 @@ In `artmd.ini`:
473473
[SOMEANIM] ; AnimationType
474474
CreateUnit= ; TechnoType
475475
CreateUnit.Owner=Victim ; Owner house kind, Invoker/Killer/Victim/Civilian/Special/Neutral/Random
476+
CreateUnit.RequireOwner=false ; boolean
476477
CreateUnit.RemapAnim=false ; boolean
477478
CreateUnit.Mission=Guard ; MissionType
478479
CreateUnit.AIMission= ; MissionType

src/Ext/Anim/Body.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ bool AnimExt::SetAnimOwnerHouseKind(AnimClass* pAnim, HouseClass* pInvoker, Hous
7070
{
7171
auto const pTypeExt = AnimTypeExt::ExtMap.Find(pAnim->Type);
7272
bool makeInf = pAnim->Type->MakeInfantry > -1;
73-
bool createUnit = pTypeExt->CreateUnit.Get();
73+
bool createUnit = pTypeExt->CreateUnitType != nullptr;
7474
auto ownerKind = OwnerHouseKind::Default;
7575
HouseClass* pDefaultOwner = nullptr;
7676

@@ -83,7 +83,7 @@ bool AnimExt::SetAnimOwnerHouseKind(AnimClass* pAnim, HouseClass* pInvoker, Hous
8383
ownerKind = pTypeExt->MakeInfantryOwner;
8484

8585
if (createUnit)
86-
ownerKind = pTypeExt->CreateUnit_Owner;
86+
ownerKind = pTypeExt->CreateUnitType->Owner;
8787

8888
auto newOwner = HouseExt::GetHouseKind(ownerKind, true, pDefaultOwner, pInvoker, pVictim);
8989

@@ -96,7 +96,7 @@ bool AnimExt::SetAnimOwnerHouseKind(AnimClass* pAnim, HouseClass* pInvoker, Hous
9696
isRemappable = true;
9797

9898
if (createUnit)
99-
isRemappable = pTypeExt->CreateUnit_RemapAnim;
99+
isRemappable = pTypeExt->CreateUnitType->RemapAnim;
100100

101101
if (isRemappable && !newOwner->Defeated)
102102
pAnim->LightConvert = ColorScheme::Array[newOwner->ColorSchemeIndex]->LightConvert;

src/Ext/Anim/Hooks.AnimCreateUnit.cpp

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ DEFINE_HOOK(0x4226F0, AnimClass_CTOR_CreateUnit_MarkOccupationBits, 0x6)
4545

4646
auto const pTypeExt = AnimTypeExt::ExtMap.Find(pThis->Type);
4747

48-
if (pTypeExt->CreateUnit.Get())
48+
if (pTypeExt->CreateUnitType)
4949
pThis->MarkAllOccupationBits(pThis->GetCell()->GetCoordsWithBridge());
5050

5151
return 0; //return (pThis->Type->MakeInfantry != -1) ? 0x423BD6 : 0x423C03;
@@ -57,31 +57,26 @@ DEFINE_HOOK(0x424932, AnimClass_AI_CreateUnit_ActualEffects, 0x6)
5757

5858
auto const pTypeExt = AnimTypeExt::ExtMap.Find(pThis->Type);
5959

60-
if (auto const pUnitType = pTypeExt->CreateUnit.Get())
60+
if (auto const pCreateUnit = pTypeExt->CreateUnitType.get())
6161
{
62+
auto const pUnitType = pCreateUnit->Type;
6263
auto const pExt = AnimExt::ExtMap.Find(pThis);
6364
pThis->UnmarkAllOccupationBits(pThis->GetCell()->GetCoordsWithBridge());
6465

65-
auto facing = pTypeExt->CreateUnit_RandomFacing
66-
? static_cast<DirType>(ScenarioClass::Instance->Random.RandomRanged(0, 255)) : pTypeExt->CreateUnit_Facing;
66+
auto facing = pCreateUnit->RandomFacing
67+
? static_cast<DirType>(ScenarioClass::Instance->Random.RandomRanged(0, 255)) : pCreateUnit->Facing;
6768

68-
auto const primaryFacing = pTypeExt->CreateUnit_InheritDeathFacings && pExt->FromDeathUnit ? pExt->DeathUnitFacing : facing;
69+
auto const primaryFacing = pCreateUnit->InheritDeathFacings && pExt->FromDeathUnit ? pExt->DeathUnitFacing : facing;
6970
DirType* secondaryFacing = nullptr;
70-
Mission* missionAI = nullptr;
7171

72-
if (pUnitType->WhatAmI() == AbstractType::UnitType && pUnitType->Turret && pExt->FromDeathUnit && pExt->DeathUnitHasTurret && pTypeExt->CreateUnit_InheritTurretFacings)
72+
if (pUnitType->WhatAmI() == AbstractType::UnitType && pUnitType->Turret && pExt->FromDeathUnit && pExt->DeathUnitHasTurret && pCreateUnit->InheritTurretFacings)
7373
{
7474
auto dir = pExt->DeathUnitTurretFacing.GetDir();
7575
secondaryFacing = &dir;
76-
Debug::Log("CreateUnit: Using stored turret facing %d\n", pExt->DeathUnitTurretFacing.GetFacing<256>());
76+
Debug::Log("CreateUnit: Using stored turret facing %d from anim [%s]\n", pExt->DeathUnitTurretFacing.GetFacing<256>(), pThis->Type->get_ID());
7777
}
7878

79-
if (pTypeExt->CreateUnit_AIMission.isset())
80-
missionAI = &pTypeExt->CreateUnit_AIMission;
81-
82-
TechnoTypeExt::CreateUnit(pUnitType, pThis->Location, primaryFacing, secondaryFacing, pThis->Owner, pExt->Invoker, pExt->InvokerHouse,
83-
pTypeExt->CreateUnit_SpawnAnim, pTypeExt->CreateUnit_SpawnHeight, pTypeExt->CreateUnit_AlwaysSpawnOnGround, pTypeExt->CreateUnit_ConsiderPathfinding,
84-
pTypeExt->CreateUnit_SpawnParachutedInAir, pTypeExt->CreateUnit_Mission, missionAI);
79+
TechnoTypeExt::CreateUnit(pCreateUnit, primaryFacing, secondaryFacing, pThis->Location, pThis->Owner, pExt->Invoker, pExt->InvokerHouse);
8580
}
8681

8782
return (pThis->Type->MakeInfantry != -1) ? 0x42493E : 0x424B31;

src/Ext/AnimType/Body.cpp

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,18 @@ void AnimTypeExt::ProcessDestroyAnims(UnitClass* pThis, TechnoClass* pKiller)
6161
pAnimExt->SetInvoker(pThis);
6262
pAnimExt->FromDeathUnit = true;
6363

64-
if (pAnimTypeExt->CreateUnit_InheritDeathFacings.Get())
65-
pAnimExt->DeathUnitFacing = facing;
66-
67-
if (pAnimTypeExt->CreateUnit_InheritTurretFacings.Get())
64+
if (auto const pCreateUnit = pAnimTypeExt->CreateUnitType.get())
6865
{
69-
if (pThis->HasTurret())
66+
if (pCreateUnit->InheritDeathFacings)
67+
pAnimExt->DeathUnitFacing = facing;
68+
69+
if (pCreateUnit->InheritTurretFacings)
7070
{
71-
pAnimExt->DeathUnitHasTurret = true;
72-
pAnimExt->DeathUnitTurretFacing = pThis->SecondaryFacing.Current();
71+
if (pThis->HasTurret())
72+
{
73+
pAnimExt->DeathUnitHasTurret = true;
74+
pAnimExt->DeathUnitTurretFacing = pThis->SecondaryFacing.Current();
75+
}
7376
}
7477
}
7578
}
@@ -83,20 +86,6 @@ void AnimTypeExt::ExtData::LoadFromINIFile(CCINIClass* pINI)
8386
INI_EX exINI(pINI);
8487

8588
this->Palette.LoadFromINI(pINI, pID, "CustomPalette");
86-
this->CreateUnit.Read(exINI, pID, "CreateUnit");
87-
this->CreateUnit_Facing.Read(exINI, pID, "CreateUnit.Facing");
88-
this->CreateUnit_InheritDeathFacings.Read(exINI, pID, "CreateUnit.InheritFacings");
89-
this->CreateUnit_InheritTurretFacings.Read(exINI, pID, "CreateUnit.InheritTurretFacings");
90-
this->CreateUnit_RemapAnim.Read(exINI, pID, "CreateUnit.RemapAnim");
91-
this->CreateUnit_Mission.Read(exINI, pID, "CreateUnit.Mission");
92-
this->CreateUnit_AIMission.Read(exINI, pID, "CreateUnit.AIMission");
93-
this->CreateUnit_Owner.Read(exINI, pID, "CreateUnit.Owner");
94-
this->CreateUnit_RandomFacing.Read(exINI, pID, "CreateUnit.RandomFacing");
95-
this->CreateUnit_AlwaysSpawnOnGround.Read(exINI, pID, "CreateUnit.AlwaysSpawnOnGround");
96-
this->CreateUnit_SpawnParachutedInAir.Read(exINI, pID, "CreateUnit.SpawnParachutedInAir");
97-
this->CreateUnit_ConsiderPathfinding.Read(exINI, pID, "CreateUnit.ConsiderPathfinding");
98-
this->CreateUnit_SpawnAnim.Read(exINI, pID, "CreateUnit.SpawnAnim");
99-
this->CreateUnit_SpawnHeight.Read(exINI, pID, "CreateUnit.SpawnHeight");
10089
this->XDrawOffset.Read(exINI, pID, "XDrawOffset");
10190
this->HideIfNoOre_Threshold.Read(exINI, pID, "HideIfNoOre.Threshold");
10291
this->Layer_UseObjectLayer.Read(exINI, pID, "Layer.UseObjectLayer");
@@ -130,27 +119,30 @@ void AnimTypeExt::ExtData::LoadFromINIFile(CCINIClass* pINI)
130119
this->LargeFireAnims.Read(exINI, pID, "LargeFireAnims");
131120
this->LargeFireChances.Read(exINI, pID, "LargeFireChances");
132121
this->LargeFireDistances.Read(exINI, pID, "LargeFireDistances");
122+
123+
// Parasitic types
124+
Nullable<TechnoTypeClass*> createUnit;
125+
createUnit.Read(exINI, pID, "CreateUnit");
126+
127+
if (createUnit)
128+
{
129+
if (this->CreateUnitType == nullptr)
130+
this->CreateUnitType = std::make_unique<CreateUnitTypeClass>();
131+
132+
this->CreateUnitType->LoadFromINI(pINI, pID);
133+
}
134+
else if (createUnit.isset())
135+
{
136+
this->CreateUnitType.reset();
137+
}
133138
}
134139

135140
template <typename T>
136141
void AnimTypeExt::ExtData::Serialize(T& Stm)
137142
{
138143
Stm
139144
.Process(this->Palette)
140-
.Process(this->CreateUnit)
141-
.Process(this->CreateUnit_Facing)
142-
.Process(this->CreateUnit_InheritDeathFacings)
143-
.Process(this->CreateUnit_RemapAnim)
144-
.Process(this->CreateUnit_Mission)
145-
.Process(this->CreateUnit_AIMission)
146-
.Process(this->CreateUnit_InheritTurretFacings)
147-
.Process(this->CreateUnit_Owner)
148-
.Process(this->CreateUnit_RandomFacing)
149-
.Process(this->CreateUnit_AlwaysSpawnOnGround)
150-
.Process(this->CreateUnit_SpawnParachutedInAir)
151-
.Process(this->CreateUnit_ConsiderPathfinding)
152-
.Process(this->CreateUnit_SpawnAnim)
153-
.Process(this->CreateUnit_SpawnHeight)
145+
.Process(this->CreateUnitType)
154146
.Process(this->XDrawOffset)
155147
.Process(this->HideIfNoOre_Threshold)
156148
.Process(this->Layer_UseObjectLayer)

src/Ext/AnimType/Body.h

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
#include <AnimTypeClass.h>
44

5+
#include <New/Type/Affiliated//CreateUnitTypeClass.h>
56
#include <Utilities/Container.h>
67
#include <Utilities/Enum.h>
78
#include <Utilities/Constructs.h>
89
#include <Utilities/Template.h>
10+
911
class AnimTypeExt
1012
{
1113
public:
@@ -18,20 +20,7 @@ class AnimTypeExt
1820
{
1921
public:
2022
CustomPalette Palette;
21-
Valueable<TechnoTypeClass*> CreateUnit;
22-
Valueable<DirType> CreateUnit_Facing;
23-
Valueable<bool> CreateUnit_InheritDeathFacings;
24-
Valueable<bool> CreateUnit_InheritTurretFacings;
25-
Valueable<bool> CreateUnit_RemapAnim;
26-
Valueable<bool> CreateUnit_RandomFacing;
27-
Valueable<Mission> CreateUnit_Mission;
28-
Nullable<Mission> CreateUnit_AIMission;
29-
Valueable<OwnerHouseKind> CreateUnit_Owner;
30-
Valueable<bool> CreateUnit_AlwaysSpawnOnGround;
31-
Valueable<bool> CreateUnit_SpawnParachutedInAir;
32-
Valueable<bool> CreateUnit_ConsiderPathfinding;
33-
Valueable<AnimTypeClass*> CreateUnit_SpawnAnim;
34-
Valueable<int> CreateUnit_SpawnHeight;
23+
std::unique_ptr<CreateUnitTypeClass> CreateUnitType;
3524
Valueable<int> XDrawOffset;
3625
Valueable<int> HideIfNoOre_Threshold;
3726
Nullable<bool> Layer_UseObjectLayer;
@@ -68,19 +57,7 @@ class AnimTypeExt
6857

6958
ExtData(AnimTypeClass* OwnerObject) : Extension<AnimTypeClass>(OwnerObject)
7059
, Palette { CustomPalette::PaletteMode::Temperate }
71-
, CreateUnit_Facing { DirType::North }
72-
, CreateUnit_RandomFacing { true }
73-
, CreateUnit_InheritDeathFacings { false }
74-
, CreateUnit_InheritTurretFacings { false }
75-
, CreateUnit_RemapAnim { false }
76-
, CreateUnit_Mission { Mission::Guard }
77-
, CreateUnit_AIMission {}
78-
, CreateUnit_Owner { OwnerHouseKind::Victim }
79-
, CreateUnit_AlwaysSpawnOnGround { false }
80-
, CreateUnit_SpawnParachutedInAir { false }
81-
, CreateUnit_ConsiderPathfinding { false }
82-
, CreateUnit_SpawnAnim {}
83-
, CreateUnit_SpawnHeight { -1 }
60+
, CreateUnitType { nullptr }
8461
, XDrawOffset { 0 }
8562
, HideIfNoOre_Threshold { 0 }
8663
, Layer_UseObjectLayer {}

src/Ext/TechnoType/Body.cpp

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,24 @@ TechnoTypeClass* TechnoTypeExt::GetTechnoType(ObjectTypeClass* pType)
114114
return nullptr;
115115
}
116116

117-
TechnoClass* TechnoTypeExt::CreateUnit(TechnoTypeClass* pType, CoordStruct location, DirType facing, DirType* secondaryFacing, HouseClass* pOwner, TechnoClass* pInvoker, HouseClass* pInvokerHouse,
118-
AnimTypeClass* pSpawnAnimType, int spawnHeight, bool alwaysOnGround, bool checkPathfinding, bool parachuteIfInAir, Mission mission, Mission* missionAI)
117+
TechnoClass* TechnoTypeExt::CreateUnit(CreateUnitTypeClass* pCreateUnit, DirType facing, DirType* secondaryFacing,
118+
CoordStruct location, HouseClass* pOwner, TechnoClass* pInvoker, HouseClass* pInvokerHouse)
119119
{
120+
auto const pType = pCreateUnit->Type;
120121
auto const rtti = pType->WhatAmI();
121122

122123
if (rtti == AbstractType::BuildingType)
123124
return nullptr;
124125

125-
HouseClass* decidedOwner = pOwner && !pOwner->Defeated
126-
? pOwner : HouseClass::FindCivilianSide();
126+
HouseClass* decidedOwner = pOwner;
127+
128+
if (!pOwner || pOwner->Defeated)
129+
{
130+
if (pCreateUnit->RequireOwner)
131+
return nullptr;
132+
133+
decidedOwner = HouseClass::FindCivilianSide();
134+
}
127135

128136
auto pCell = MapClass::Instance.TryGetCellAt(location);
129137
auto const speedType = rtti != AbstractType::AircraftType ? pType->SpeedType : SpeedType::Wheel;
@@ -133,7 +141,7 @@ TechnoClass* TechnoTypeExt::CreateUnit(TechnoTypeClass* pType, CoordStruct locat
133141
int baseHeight = location.Z;
134142
bool inAir = location.Z >= Unsorted::CellHeight * 2;
135143

136-
if (checkPathfinding && (!pCell || !pCell->IsClearToMove(speedType, false, false, -1, mZone, -1, isBridge)))
144+
if (pCreateUnit->ConsiderPathfinding && (!pCell || !pCell->IsClearToMove(speedType, false, false, -1, mZone, -1, isBridge)))
137145
{
138146
auto nCell = MapClass::Instance.NearByLocation(CellClass::Coord2Cell(location), speedType, -1, mZone,
139147
isBridge, 1, 1, true, false, false, isBridge, CellStruct::Empty, false, false);
@@ -151,11 +159,11 @@ TechnoClass* TechnoTypeExt::CreateUnit(TechnoTypeClass* pType, CoordStruct locat
151159
{
152160
isBridge = allowBridges && pCell->ContainsBridge();
153161
int bridgeZ = isBridge ? CellClass::BridgeHeight : 0;
154-
int zCoord = alwaysOnGround ? INT32_MIN : baseHeight;
162+
int zCoord = pCreateUnit->AlwaysSpawnOnGround ? INT32_MIN : baseHeight;
155163
int cellFloorHeight = MapClass::Instance.GetCellFloorHeight(location) + bridgeZ;
156164

157-
if (!alwaysOnGround && spawnHeight >= 0)
158-
location.Z = cellFloorHeight + spawnHeight;
165+
if (!pCreateUnit->AlwaysSpawnOnGround && pCreateUnit->SpawnHeight >= 0)
166+
location.Z = cellFloorHeight + pCreateUnit->SpawnHeight;
159167
else
160168
location.Z = Math::max(cellFloorHeight, zCoord);
161169

@@ -165,12 +173,12 @@ TechnoClass* TechnoTypeExt::CreateUnit(TechnoTypeClass* pType, CoordStruct locat
165173
bool parachuted = false;
166174
pTechno->OnBridge = isBridge;
167175

168-
if (rtti != AbstractType::AircraftType && parachuteIfInAir && !alwaysOnGround && inAir)
176+
if (rtti != AbstractType::AircraftType && pCreateUnit->SpawnParachutedInAir && !pCreateUnit->AlwaysSpawnOnGround && inAir)
169177
{
170178
parachuted = true;
171179
success = pTechno->SpawnParachuted(location);
172180
}
173-
else if (!pCell->GetBuilding() || !checkPathfinding)
181+
else if (!pCell->GetBuilding() || !pCreateUnit->ConsiderPathfinding)
174182
{
175183
++Unsorted::ScenarioInit;
176184
success = pTechno->Unlimbo(location, facing);
@@ -186,16 +194,16 @@ TechnoClass* TechnoTypeExt::CreateUnit(TechnoTypeClass* pType, CoordStruct locat
186194
if (secondaryFacing)
187195
pTechno->SecondaryFacing.SetCurrent(DirStruct(*secondaryFacing));
188196

189-
if (pSpawnAnimType)
197+
if (pCreateUnit->SpawnAnim)
190198
{
191-
auto const pAnim = GameCreate<AnimClass>(pSpawnAnimType, location);
199+
auto const pAnim = GameCreate<AnimClass>(pCreateUnit->SpawnAnim, location);
192200
AnimExt::SetAnimOwnerHouseKind(pAnim, pInvokerHouse, nullptr, false, true);
193201
AnimExt::ExtMap.Find(pAnim)->SetInvoker(pInvoker, pInvokerHouse);
194202
}
195203

196204
if (!pTechno->InLimbo)
197205
{
198-
if (!alwaysOnGround)
206+
if (!pCreateUnit->AlwaysSpawnOnGround)
199207
{
200208
inAir = pTechno->IsInAir();
201209
if (auto const pFlyLoco = locomotion_cast<FlyLocomotionClass*>(pTechno->Locomotor))
@@ -235,12 +243,12 @@ TechnoClass* TechnoTypeExt::CreateUnit(TechnoTypeClass* pType, CoordStruct locat
235243
}
236244
}
237245

238-
auto newMission = mission;
246+
auto newMission = pCreateUnit->UnitMission;
239247

240-
if (!decidedOwner->IsControlledByHuman() && missionAI)
241-
newMission = *missionAI;
248+
if (!decidedOwner->IsControlledByHuman() && pCreateUnit->AIUnitMission.isset())
249+
newMission = pCreateUnit->AIUnitMission;
242250

243-
pTechno->QueueMission(mission, false);
251+
pTechno->QueueMission(newMission, false);
244252
}
245253

246254
if (!decidedOwner->Type->MultiplayPassive)

src/Ext/TechnoType/Body.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <New/Type/SelectBoxTypeClass.h>
1515
#include <New/Type/Affiliated/DroppodTypeClass.h>
1616
#include <New/Type/Affiliated/TiberiumEaterTypeClass.h>
17+
#include <New/Type/Affiliated/CreateUnitTypeClass.h>
1718

1819
class Matrix3D;
1920
class ParticleSystemTypeClass;
@@ -698,9 +699,8 @@ class TechnoTypeExt
698699
static void ApplyTurretOffset(TechnoTypeClass* pType, Matrix3D* mtx, double factor = 1.0);
699700
static TechnoTypeClass* GetTechnoType(ObjectTypeClass* pType);
700701

701-
static TechnoClass* CreateUnit(TechnoTypeClass* pType, CoordStruct location, DirType facing, DirType* secondaryFacing, HouseClass* pOwner,
702-
TechnoClass* pInvoker = nullptr, HouseClass* pInvokerHouse = nullptr, AnimTypeClass* pSpawnAnimType = nullptr, int spawnHeight = -1,
703-
bool alwaysOnGround = false, bool checkPathfinding = false, bool parachuteIfInAir = false, Mission mission = Mission::Guard, Mission* missionAI = nullptr);
702+
static TechnoClass* CreateUnit(CreateUnitTypeClass* pCreateUnit, DirType facing, DirType* secondaryFacing,
703+
CoordStruct location, HouseClass* pOwner, TechnoClass* pInvoker, HouseClass* pInvokerHouse);
704704

705705
// Ares 0.A
706706
static const char* GetSelectionGroupID(ObjectTypeClass* pType);

0 commit comments

Comments
 (0)