Skip to content
Merged
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
29 changes: 16 additions & 13 deletions src/Ext/Infantry/Hooks.Firing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ DEFINE_HOOK(0x5209AF, InfantryClass_FiringAI, 0x6)
{
enum { Continue = 0x5209CD, ReturnFromFunction = 0x520AD9 };

GET(InfantryClass*, pThis, EBP);
GET(int, firingFrame, EDX);
GET(InfantryClass* const, pThis, EBP);
GET(const int, fireUp, EDX);

int cumulativeDelay = 0;
int projectedDelay = 0;
Expand All @@ -115,17 +115,20 @@ DEFINE_HOOK(0x5209AF, InfantryClass_FiringAI, 0x6)
}
}

if (TechnoExt::HandleDelayedFireWithPauseSequence(pThis, weaponIndex, firingFrame + cumulativeDelay))
const int frame = pThis->Animation.Value;
const int firingFrame = fireUp + cumulativeDelay;

if (TechnoExt::HandleDelayedFireWithPauseSequence(pThis, FiringAITemp::WeaponType, weaponIndex, frame, firingFrame))
return ReturnFromFunction;

if (pThis->Animation.Value == firingFrame + cumulativeDelay)
if (frame == firingFrame)
{
if (allowBurst)
{
int frameCount = pThis->Type->Sequence->GetSequence(pThis->SequenceAnim).CountFrames;
const int frameCount = pThis->Type->Sequence->GetSequence(pThis->SequenceAnim).CountFrames;

// If projected frame for firing next shot goes beyond the sequence frame count, cease firing after this shot and start rearm timer.
if (firingFrame + projectedDelay > frameCount)
if (fireUp + projectedDelay > frameCount)
TechnoExt::ExtMap.Find(pThis)->ForceFullRearmDelay = true;
}

Expand Down Expand Up @@ -177,26 +180,26 @@ DEFINE_HOOK(0x5209EE, InfantryClass_UpdateFiring_BurstNoDelay, 0x5)
enum { SkipVanillaFire = 0x520A57 };

GET(InfantryClass* const, pThis, EBP);
GET(const int, wpIdx, ESI);
GET(const int, weaponIndex, ESI);
GET(AbstractClass* const, pTarget, EAX);

if (const auto pWeapon = pThis->GetWeapon(wpIdx)->WeaponType)
if (const auto pWeapon = pThis->GetWeapon(weaponIndex)->WeaponType)
{
if (pWeapon->Burst > 1)
{
const auto pExt = WeaponTypeExt::ExtMap.Find(pWeapon);
const auto pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeapon);

if (pExt->Burst_NoDelay && (!pExt->DelayedFire_Duration.isset() || pExt->DelayedFire_OnlyOnInitialBurst))
if (pWeaponExt->Burst_NoDelay && (!pWeaponExt->DelayedFire_Duration.isset() || pWeaponExt->DelayedFire_OnlyOnInitialBurst))
{
if (pThis->Fire(pTarget, wpIdx))
if (pThis->Fire(pTarget, weaponIndex))
{
if (!pThis->CurrentBurstIndex)
return SkipVanillaFire;

auto rof = pThis->RearmTimer.TimeLeft;
int rof = pThis->RearmTimer.TimeLeft;
pThis->RearmTimer.Start(0);

for (auto i = pThis->CurrentBurstIndex; i < pWeapon->Burst && pThis->GetFireError(pTarget, wpIdx, true) == FireError::OK && pThis->Fire(pTarget, wpIdx); ++i)
for (int i = pThis->CurrentBurstIndex; i < pWeapon->Burst && pThis->GetFireError(pTarget, weaponIndex, true) == FireError::OK && pThis->Fire(pTarget, weaponIndex); ++i)
{
rof = pThis->RearmTimer.TimeLeft;
pThis->RearmTimer.Start(0);
Expand Down
6 changes: 2 additions & 4 deletions src/Ext/Techno/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,11 +689,10 @@ void TechnoExt::CreateDelayedFireAnim(TechnoClass* pThis, AnimTypeClass* pAnimTy
}
}

bool TechnoExt::HandleDelayedFireWithPauseSequence(TechnoClass* pThis, int weaponIndex, int firingFrame)
bool TechnoExt::HandleDelayedFireWithPauseSequence(TechnoClass* pThis, WeaponTypeClass* pWeapon, int weaponIndex, int frame, int firingFrame)
{
auto const pExt = TechnoExt::ExtMap.Find(pThis);
auto& timer = pExt->DelayedFireTimer;
auto const pWeapon = pThis->GetWeapon(weaponIndex)->WeaponType;
auto const pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeapon);

if (pExt->DelayedFireWeaponIndex >= 0 && pExt->DelayedFireWeaponIndex != weaponIndex)
Expand All @@ -706,7 +705,7 @@ bool TechnoExt::HandleDelayedFireWithPauseSequence(TechnoClass* pThis, int weapo
{
if (pWeapon->Burst <= 1 || !pWeaponExt->DelayedFire_OnlyOnInitialBurst || pThis->CurrentBurstIndex == 0)
{
if (pThis->Animation.Value == firingFrame)
if (frame == firingFrame)
pExt->DelayedFireSequencePaused = true;

if (!timer.HasStarted())
Expand Down Expand Up @@ -925,7 +924,6 @@ void TechnoExt::ExtData::Serialize(T& Stm)
.Process(this->LastSensorsMapCoords)
.Process(this->TiberiumEater_Timer)
.Process(this->AirstrikeTargetingMe)
.Process(this->FiringAnimationTimer)
.Process(this->SimpleDeployerAnimationTimer)
.Process(this->DelayedFireSequencePaused)
.Process(this->DelayedFireTimer)
Expand Down
5 changes: 1 addition & 4 deletions src/Ext/Techno/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ class TechnoExt

AirstrikeClass* AirstrikeTargetingMe;

CDTimerClass FiringAnimationTimer;

bool IsSelected;
bool ResetLocomotor;

Expand Down Expand Up @@ -146,7 +144,6 @@ class TechnoExt
, LastSensorsMapCoords { CellStruct::Empty }
, TiberiumEater_Timer {}
, AirstrikeTargetingMe { nullptr }
, FiringAnimationTimer {}
, SimpleDeployerAnimationTimer {}
, DelayedFireSequencePaused { false }
, DelayedFireWeaponIndex { -1 }
Expand Down Expand Up @@ -280,7 +277,7 @@ class TechnoExt
static void GetValuesForDisplay(TechnoClass* pThis, DisplayInfoType infoType, int& value, int& maxValue, int infoIndex);
static void GetDigitalDisplayFakeHealth(TechnoClass* pThis, int& value, int& maxValue);
static void CreateDelayedFireAnim(TechnoClass* pThis, AnimTypeClass* pAnimType, int weaponIndex, bool attach, bool center, bool removeOnNoDelay, bool onTurret, CoordStruct firingCoords);
static bool HandleDelayedFireWithPauseSequence(TechnoClass* pThis, int weaponIndex, int firingFrame);
static bool HandleDelayedFireWithPauseSequence(TechnoClass* pThis, WeaponTypeClass* pWeapon, int weaponIndex, int frame, int firingFrame);
static bool IsHealthInThreshold(TechnoClass* pObject, double min, double max);
static UnitTypeClass* GetUnitTypeExtra(UnitClass* pUnit);
static AircraftTypeClass* GetAircraftTypeExtra(AircraftClass* pAircraft);
Expand Down
14 changes: 13 additions & 1 deletion src/Ext/Techno/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ DEFINE_JUMP(VTABLE, 0x7F5CF4, 0x741490) // UnitClass_GetTechnoType -> UnitClass_

#pragma region Update

DEFINE_HOOK(0x7363C9, UnitClass_AI_AnimationPaused, 0x6)
{
enum { SkipGameCode = 0x7363DE };

GET(UnitClass*, pThis, ESI);

if (TechnoExt::ExtMap.Find(pThis)->DelayedFireSequencePaused)
return SkipGameCode;

return 0;
}

// Early, before ObjectClass_AI
DEFINE_HOOK(0x6F9E50, TechnoClass_AI, 0x5)
{
Expand Down Expand Up @@ -983,7 +995,7 @@ DEFINE_HOOK(0x6FCF3E, TechnoClass_SetTarget_After, 0x6)
|| !pThis->IsCloseEnough(pTarget, pThis->SelectWeapon(pTarget)))
{
pUnit->CurrentFiringFrame = -1;
pExt->FiringAnimationTimer.Stop();
pExt->ResetDelayedFireTimer();
}
}
}
Expand Down
60 changes: 30 additions & 30 deletions src/Ext/Unit/Hooks.Firing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,41 @@ DEFINE_HOOK(0x736F61, UnitClass_UpdateFiring_FireUp, 0x6)
{
enum { SkipFiring = 0x737063 };

GET(UnitClass*, pThis, ESI);
GET(int, weaponIndex, EDI);
GET(UnitClass* const, pThis, ESI);
GET(const int, weaponIndex, EDI);

const auto pType = pThis->Type;

if (pType->Turret || pType->Voxel)
if (pType->Turret || pType->Voxel || pThis->InLimbo)
return 0;

const auto pExt = TechnoExt::ExtMap.Find(pThis);

// SHP vehicles have no secondary action frames, so it does not need SecondaryFire.
const auto pTypeExt = pExt->TypeExtData;
const int fireUp = pTypeExt->FireUp;
CDTimerClass& timer = pExt->FiringAnimationTimer;
const int fireUp = pExt->TypeExtData->FireUp;

if (fireUp >= 0 && !pType->OpportunityFire && pThis->Locomotor->Is_Really_Moving_Now())
{
if (timer.InProgress())
timer.Stop();
if (pThis->CurrentFiringFrame != -1)
pThis->CurrentFiringFrame = -1;

return SkipFiring;
}

const int frames = pType->FiringFrames;
const int firingFrames = pType->FiringFrames;
const int frames = 2 * firingFrames - 1;

if (!timer.InProgress() && frames >= 1)
{
pThis->CurrentFiringFrame = 2 * frames - 1;
timer.Start(pThis->CurrentFiringFrame);
}
if (frames >= 0 && pThis->CurrentFiringFrame == -1)
pThis->CurrentFiringFrame = frames;

if (fireUp >= 0 && frames >= 1)
auto const pWeapon = pThis->GetWeapon(weaponIndex)->WeaponType;

if (fireUp >= 0)
{
int cumulativeDelay = 0;
int projectedDelay = 0;
auto const pWeaponExt = WeaponTypeExt::ExtMap.TryFind(pThis->GetWeapon(weaponIndex)->WeaponType);
const bool allowBurst = pWeaponExt && pWeaponExt->Burst_FireWithinSequence;
auto const pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeapon);
const bool allowBurst = pWeaponExt->Burst_FireWithinSequence;
const int currentBurstIndex = pThis->CurrentBurstIndex;
auto& random = ScenarioClass::Instance->Random;

Expand All @@ -66,15 +64,13 @@ DEFINE_HOOK(0x736F61, UnitClass_UpdateFiring_FireUp, 0x6)
}
}

if (TechnoExt::HandleDelayedFireWithPauseSequence(pThis, weaponIndex, fireUp + cumulativeDelay))
return SkipFiring;
const int frame = (frames - pThis->CurrentFiringFrame) / 2;
const int firingFrame = fireUp + cumulativeDelay;

int frame = (timer.TimeLeft - timer.GetTimeLeft());

if (frame % 2 != 0)
if (TechnoExt::HandleDelayedFireWithPauseSequence(pThis, pWeapon, weaponIndex, frame, firingFrame))
return SkipFiring;

if (frame / 2 != fireUp + cumulativeDelay)
if (frame != firingFrame)
{
return SkipFiring;
}
Expand All @@ -85,6 +81,10 @@ DEFINE_HOOK(0x736F61, UnitClass_UpdateFiring_FireUp, 0x6)
pExt->ForceFullRearmDelay = true;
}
}
else if (TechnoExt::HandleDelayedFireWithPauseSequence(pThis, pWeapon, weaponIndex, 0, -1))
{
return SkipFiring;
}

return 0;
}
Expand All @@ -94,26 +94,26 @@ DEFINE_HOOK(0x736F67, UnitClass_UpdateFiring_BurstNoDelay, 0x6)
enum { SkipVanillaFire = 0x737063 };

GET(UnitClass* const, pThis, ESI);
GET(const int, wpIdx, EDI);
GET(const int, weaponIndex, EDI);
GET(AbstractClass* const, pTarget, EAX);

if (const auto pWeapon = pThis->GetWeapon(wpIdx)->WeaponType)
if (const auto pWeapon = pThis->GetWeapon(weaponIndex)->WeaponType)
{
if (pWeapon->Burst > 1)
{
const auto pExt = WeaponTypeExt::ExtMap.Find(pWeapon);
const auto pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeapon);

if (pExt->Burst_NoDelay && (!pExt->DelayedFire_Duration.isset() || pExt->DelayedFire_OnlyOnInitialBurst))
if (pWeaponExt->Burst_NoDelay && (!pWeaponExt->DelayedFire_Duration.isset() || pWeaponExt->DelayedFire_OnlyOnInitialBurst))
{
if (pThis->Fire(pTarget, wpIdx))
if (pThis->Fire(pTarget, weaponIndex))
{
if (!pThis->CurrentBurstIndex)
return SkipVanillaFire;

auto rof = pThis->RearmTimer.TimeLeft;
int rof = pThis->RearmTimer.TimeLeft;
pThis->RearmTimer.Start(0);

for (auto i = pThis->CurrentBurstIndex; i < pWeapon->Burst && pThis->GetFireError(pTarget, wpIdx, true) == FireError::OK && pThis->Fire(pTarget, wpIdx); ++i)
for (int i = pThis->CurrentBurstIndex; i < pWeapon->Burst && pThis->GetFireError(pTarget, weaponIndex, true) == FireError::OK && pThis->Fire(pTarget, weaponIndex); ++i)
{
rof = pThis->RearmTimer.TimeLeft;
pThis->RearmTimer.Start(0);
Expand Down
2 changes: 1 addition & 1 deletion src/Ext/WeaponType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ void WeaponTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
exINI.ParseStringList(this->AttachEffect_RequiredGroups, pSection, "AttachEffect.RequiredGroups");
exINI.ParseStringList(this->AttachEffect_DisallowedGroups, pSection, "AttachEffect.DisallowedGroups");
this->AttachEffect_RequiredMinCounts.Read(exINI, pSection, "AttachEffect.RequiredMinCounts");
this->AttachEffect_RequiredMaxCounts.Read(exINI, pSection, "AttachEffect.RequiredMaxCounts");this->DelayedFire_Duration.Read(exINI, pSection, "DelayedFire.Duration");
this->AttachEffect_RequiredMaxCounts.Read(exINI, pSection, "AttachEffect.RequiredMaxCounts");
this->AttachEffect_DisallowedMinCounts.Read(exINI, pSection, "AttachEffect.DisallowedMinCounts");
this->AttachEffect_DisallowedMaxCounts.Read(exINI, pSection, "AttachEffect.DisallowedMaxCounts");
this->AttachEffect_CheckOnFirer.Read(exINI, pSection, "AttachEffect.CheckOnFirer");
Expand Down
Loading