Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ Phobos fixes:
- Fixed an issue that jumpjet infantries stop incorrectly when assigned a target out of range (by TaranDahl)
- Fixed an issue where the 77 trigger event in Ares was not functioning properly (by NetsuNegi)
- Fixed an interaction error between the engineer and the Ares rubble (by FlyStar)
- Fixed an issue where the game would only use `Weapon1` and `Weapon2` for auto-targeting even when `MultiWeapon=yes` was set (by FlyStar)
Fixes / interactions with other extensions:
- Allowed `AuxBuilding` and Ares' `SW.Aux/NegBuildings` to count building upgrades (by Ollerus)
Expand Down
5 changes: 5 additions & 0 deletions src/Ext/Rules/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,11 @@ DEFINE_HOOK(0x679CAF, RulesData_LoadAfterTypeData, 0x5)

RulesExt::LoadAfterTypeData(pItem, pINI);

for (const auto pTechnoType : TechnoTypeClass::Array)
{
TechnoTypeExt::ExtMap.Find(pTechnoType)->ParseCombatDamageAndThreatType(pINI);
}

return 0;
}

Expand Down
63 changes: 63 additions & 0 deletions src/Ext/TechnoType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,69 @@ void TechnoTypeExt::ExtData::ParseVoiceWeaponAttacks(INI_EX& exINI, const char*
}
}

void TechnoTypeExt::ExtData::ParseCombatDamageAndThreatType(CCINIClass* const pINI)
{
int Num = 0;
int EliteNum = 0;

this->ThreatTypes = { ThreatType::Normal,ThreatType::Normal };
this->CombatDamages = { 0,0 };

const auto pThis = this->OwnerObject();
int Count = 2;

if (this->MultiWeapon
&& (!pThis->IsGattling && (!pThis->HasMultipleTurrets() || !pThis->Gunner)))
{
Count = Math::min(pThis->WeaponCount, this->MultiWeapon_SelectCount);
}

for (int index = 0; index < Count; index++)
{
const auto pWeapon = pThis->GetWeapon(index)->WeaponType;
auto pEliteWeapon = pThis->GetEliteWeapon(index)->WeaponType;

if (!pEliteWeapon)
pEliteWeapon = pWeapon;

if (pWeapon)
{
if (const auto pBulletType = pWeapon->Projectile)
{
if (pBulletType->AA)
this->ThreatTypes.X |= ThreatType::Air;

if (pBulletType->AG && !BulletTypeExt::ExtMap.Find(pBulletType)->AAOnly)
this->ThreatTypes.X |= static_cast<ThreatType>(ThreatType::Infantry | ThreatType::Vehicles | ThreatType::Buildings | ThreatType::Boats);
}

this->CombatDamages.X += (pWeapon->Damage + pWeapon->AmbientDamage);
Num++;
}

if (pEliteWeapon)
{
if (const auto pBulletType = pEliteWeapon->Projectile)
{
if (pBulletType->AA)
this->ThreatTypes.X |= ThreatType::Air;

if (pBulletType->AG && !BulletTypeExt::ExtMap.Find(pBulletType)->AAOnly)
this->ThreatTypes.X |= (ThreatType::Infantry | ThreatType::Vehicles | ThreatType::Buildings | ThreatType::Boats);
}

this->CombatDamages.Y += (pEliteWeapon->Damage + pEliteWeapon->AmbientDamage);
EliteNum++;
}
}

if (Num > 0)
this->CombatDamages.X /= Num;

if (EliteNum > 0)
this->CombatDamages.Y /= EliteNum;
}

void TechnoTypeExt::ExtData::CalculateSpawnerRange()
{
const auto pThis = this->OwnerObject();
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 @@ -422,6 +422,8 @@ class TechnoTypeExt
ValueableVector<bool> MultiWeapon_IsSecondary;
Valueable<int> MultiWeapon_SelectCount;
bool ReadMultiWeapon;
Vector2D<ThreatType> ThreatTypes;
Vector2D<int> CombatDamages;

ValueableIdx<VocClass> VoiceIFVRepair;
ValueableVector<int> VoiceWeaponAttacks;
Expand Down Expand Up @@ -804,6 +806,8 @@ class TechnoTypeExt
, MultiWeapon_IsSecondary {}
, MultiWeapon_SelectCount { 2 }
, ReadMultiWeapon { false }
, ThreatTypes { ThreatType::Normal,ThreatType::Normal }
, CombatDamages { 0,0 }

, VoiceIFVRepair { -1 }
, VoiceWeaponAttacks {}
Expand Down Expand Up @@ -832,6 +836,8 @@ class TechnoTypeExt
int SelectForceWeapon(TechnoClass* pThis, AbstractClass* pTarget);
int SelectMultiWeapon(TechnoClass* const pThis, AbstractClass* const pTarget);

void ParseCombatDamageAndThreatType(CCINIClass* const pINI);

// Ares 0.A
const char* GetSelectionGroupID() const;

Expand Down
66 changes: 66 additions & 0 deletions src/Ext/TechnoType/Hooks.MultiWeapon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,69 @@ DEFINE_HOOK(0x7090A0, TechnoClass_VoiceAttack, 0x7)

return 0x7091C7;
}

ThreatType __forceinline GetThreatType(TechnoClass* pThis, TechnoTypeExt::ExtData* pTypeExt, ThreatType result)
{
ThreatType flags = pThis->Veterancy.IsElite() ? pTypeExt->ThreatTypes.Y : pTypeExt->ThreatTypes.X;
return result | flags;
}

DEFINE_HOOK_AGAIN(0x51E2CF, InfantryClass_SelectAutoTarget_MultiWeapon, 0x6) // InfantryClass_SelectAutoTarget
DEFINE_HOOK(0x743203, UnitClass_SelectAutoTarget_MultiWeapon, 0x6) // UnitClass_SelectAutoTarget
{
GET(FootClass*, pThis, ESI);
GET(ThreatType, result, EDI);
enum { InfantryReturn = 0x51E31B, UnitReturn = 0x74324F };

R->EDI(GetThreatType(pThis, TechnoTypeExt::ExtMap.Find(pThis->GetTechnoType()), result));
return R->Origin() == 0x743203 ? UnitReturn : InfantryReturn;
}

DEFINE_HOOK(0x445F04, BuildingClass_SelectAutoTarget_MultiWeapon, 0xA)
{
GET(BuildingClass*, pThis, ESI);
GET_STACK(ThreatType, result, STACK_OFFSET(0x8, 0x4));
enum { ReturnThreatType = 0x445F58 };

R->EDI(GetThreatType(pThis, TechnoTypeExt::ExtMap.Find(pThis->Type), result));
return ReturnThreatType;
}

DEFINE_HOOK(0x6F39F4, TechnoClass_CombatDamage_MultiWeapon, 0x6)
{
GET(TechnoClass*, pThis, ESI);
enum { ReturnDamage = 0x6F3ABB };

const auto pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->GetTechnoType());
R->EAX(pThis->Veterancy.IsElite() ? pTypeExt->CombatDamages.Y : pTypeExt->CombatDamages.X);
return ReturnDamage;
}

DEFINE_HOOK(0x707ED0, TechnoClass_GetGuardRange_MultiWeapon, 0x6)
{
GET(TechnoClass*, pThis, ESI);
enum { NewRange = 0x707F08 };

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

if (pTypeExt->MultiWeapon
&& (!pType->IsGattling && (!pType->HasMultipleTurrets() || !pType->Gunner)))
{
const int selectCount = Math::min(pType->WeaponCount, pTypeExt->MultiWeapon_SelectCount);
int range = 0;

for (int index = selectCount - 1; index >= 0; --index)
{
const auto weaponRange = pThis->GetWeaponRange(index);

if (weaponRange > range)
range = weaponRange;
}

R->EAX(range);
return NewRange;
}

return 0;
}
Loading