Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spawns Enhancement #1349

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ This page lists all the individual contributions to the project by their author.
- `TurretOffset` support for SHP vehicles
- Customizable rocker amplitude
- Customizable wake anim
- Customizable spawns queue
- Initial spawns number
- **Fryone**
- Customizable ElectricBolt Arcs
- Sound entry on unit's creation
Expand Down
21 changes: 21 additions & 0 deletions docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,18 @@ OpenTopped.AllowFiringIfDeactivated=true ; boolean
OpenTopped.ShareTransportTarget=true ; boolean
```

### Customizable spawns queue
- It is now possible to spawn multiple types of spawnees from a spawner with `Spawns.Queue`. The order of spawnees in this queue is the order of their respawn.
- `Spawns` still needs to be set to enable the spawner logic and act as a default spawnee.
- `SpawnsNumber` still needs to be set to determine the amount of spawnee slots.
- If the length of the queue is longer than the spawner's `SpawnsNumber`, spawnee after this length will be omitted. If the length is shorter however, the rest of the positions will be filled by the spawnee defined by `Spawns`. Hence, it's recommended to make them the same.

In `rulesmd.ini`:
```ini
[SOMETECHNO] ; TechnoType
Spawns.Queue= ; list of aircrafts in order
```

### Disabling fallback to (Elite)Secondary weapon

- It is now possible to disable the fallback to `(Elite)Secondary` weapon from `(Elite)Primary` weapon if it cannot fire at the chosen target by setting `NoSecondaryWeaponFallback` to true (defaults to false). `NoSecondaryWeaponFallback.AllowAA` controls whether or not fallback because of projectile `AA` setting and target being in air is still allowed. This does not apply to special cases where `(Elite)Secondary` weapon is always chosen, including but not necessarily limited to the following:
Expand Down Expand Up @@ -1086,6 +1098,15 @@ OmniFire=yes
OmniFire.TurnToTarget=no ; boolean
```

### Initial spawns number
- It is now possible to set the initial amount of spawnees for a spawner, instead of always being filled. Won't work if it's larger than `SpawnsNumber`.

In `rulesmd.ini`:
```ini
[SOMETECHNO] ; TechnoType
InitialSpawnsNumber= ; integer
```

### Initial strength for TechnoTypes and cloned infantry

![image](_static/images/initialstrength.cloning-01.png)
Expand Down
2 changes: 2 additions & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ New:
- Option to restore `PowerSurplus` setting for AI (by Starkku)
- `FireOnce` infantry sequence reset toggle (by Starkku)
- Assign Super Weapon cameo to any sidebar tab (by NetsuNegi)
- Customizable spawns queue (by TwinkleStar)
- Initial spawns number (by TwinkleStar)

Vanilla fixes:
- Allow AI to repair structures built from base nodes/trigger action 125/SW delivery in single player missions (by Trsdy)
Expand Down
53 changes: 53 additions & 0 deletions src/Ext/Techno/Hooks.Misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,56 @@ DEFINE_HOOK(0x6B7600, SpawnManagerClass_AI_InitDestination, 0x6)

return R->Origin() == 0x6B7600 ? SkipGameCode1 : SkipGameCode2;
}

DEFINE_HOOK(0x6B6D44, SpawnManagerClass_Init_Spawns, 0x5)
{
enum { Jump = 0x6B6DF0, Change = 0x6B6D53, Continue = 0 };
GET(SpawnManagerClass*, pThis, ESI);
GET_STACK(size_t, i, STACK_OFFSET(0x1C, 0x4));

auto const pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->Owner->GetTechnoType());

if ((int) i >= pTypeExt->InitialSpawnsNumber.Get(pThis->SpawnCount))
{
GET(SpawnControl*, pControl, EBP);
pControl->Unit = nullptr;
pControl->SpawnTimer.Start(pThis->RegenRate);
pControl->Status = SpawnNodeStatus::Dead;
pThis->SpawnedNodes.AddItem(pControl);
return Jump;
}

if (pTypeExt->Spawns_Queue.size() <= i || !pTypeExt->Spawns_Queue[i])
return Continue;

R->EAX(pTypeExt->Spawns_Queue[i]->CreateObject(pThis->Owner->GetOwningHouse()));
return Change;
}

DEFINE_HOOK(0x6B78D3, SpawnManagerClass_Update_Spawns, 0x6)
{
GET(SpawnManagerClass*, pThis, ESI);

auto const pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->Owner->GetTechnoType());

if (pTypeExt->Spawns_Queue.empty())
return 0;

std::vector<AircraftTypeClass*> vec = pTypeExt->Spawns_Queue;

for (auto pNode : pThis->SpawnedNodes)
{
if (pNode->Unit)
{
auto it = std::find_if(vec.begin(), vec.end(), [=](auto pType) { return pType == pNode->Unit->GetTechnoType(); });
if (it != vec.end())
vec.erase(it);
}
}

if (vec.empty() || !vec[0])
return 0;

R->EAX(vec[0]->CreateObject(pThis->Owner->GetOwningHouse()));
return 0x6B78EA;
}
5 changes: 5 additions & 0 deletions src/Ext/TechnoType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->Wake.Read(exINI, pSection, "Wake");
this->Wake_Grapple.Read(exINI, pSection, "Wake.Grapple");
this->Wake_Sinking.Read(exINI, pSection, "Wake.Sinking");
this->InitialSpawnsNumber.Read(exINI, pSection, "InitialSpawnsNumber");
this->Spawns_Queue.Read(exINI, pSection, "Spawns.Queue");

// Ares 0.2
this->RadarJamRadius.Read(exINI, pSection, "RadarJamRadius");
Expand Down Expand Up @@ -688,6 +690,9 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm)
.Process(this->Wake)
.Process(this->Wake_Grapple)
.Process(this->Wake_Sinking)

.Process(this->InitialSpawnsNumber)
.Process(this->Spawns_Queue)
;
}
void TechnoTypeExt::ExtData::LoadFromStream(PhobosStreamReader& Stm)
Expand Down
6 changes: 6 additions & 0 deletions src/Ext/TechnoType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ class TechnoTypeExt
Nullable<AnimTypeClass*> Wake_Grapple;
Nullable<AnimTypeClass*> Wake_Sinking;

Nullable<int> InitialSpawnsNumber;
ValueableVector<AircraftTypeClass*> Spawns_Queue;

struct LaserTrailDataEntry
{
ValueableIdx<LaserTrailTypeClass> idxType;
Expand Down Expand Up @@ -461,6 +464,9 @@ class TechnoTypeExt
, Wake { }
, Wake_Grapple { }
, Wake_Sinking { }

, InitialSpawnsNumber { }
, Spawns_Queue { }
{ }

virtual ~ExtData() = default;
Expand Down
Loading