Skip to content

Commit c7413b5

Browse files
committed
Add improvements
- Fix issues with frame calcs by verifying frame counts - Add animation playback rate customization
1 parent cd0089c commit c7413b5

6 files changed

Lines changed: 50 additions & 14 deletions

File tree

docs/Fixed-or-Improved-Logics.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,7 @@ ConsideredVehicle= ; boolean
10071007
- By default building `TurretAnim(Damaged)` with `TurretAnimIsVoxel=false` only displays one frame per each of the 32 facings. This can now be increased and there are additional animations available for low power state and firing weapons.
10081008
- The frames in the .shp file should be in the order: `IdleFrames`, `LowPowerIdleFrames`, `FiringFrames`, `LowPowerFiringFrames`, animations with frame count set to 0 will be skipped / ignored.
10091009
- Note that `FiringFrames` starts playing when attacking and weapon can fire, it will not stop firing of weapon until it has finished playing nor will anything prevent it from looping multiple times if weapon firing is blocked by [delayed firing](New-or-Enhanced-Logics.md#delayed-firing) for longer than there are frames for. Matching delayed firing duration with firing frame count can be used to make pre-firing animation.
1010+
- `TurretAnim.IdleRate` and `TurretAnim.FiringRate` can be used to customize animation frame playback rate for idle and firing frames respectively.
10101011

10111012
In `rulesmd.ini`:
10121013
```ini
@@ -1015,6 +1016,8 @@ TurretAnim.IdleFrames=1 ; integer
10151016
TurretAnim.LowPowerIdleFrames=0 ; integer
10161017
TurretAnim.FiringFrames=0 ; integer
10171018
TurretAnim.LowPowerFiringFrames=0 ; integer
1019+
TurretAnim.IdleRate=1 ; integer, game frames
1020+
TurretAnim.FiringRate=1 ; integer, game frames
10181021
```
10191022

10201023
### Custom exit cell for infantry factory

src/Ext/Building/Body.cpp

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -475,13 +475,15 @@ int BuildingExt::GetTurretFrame(BuildingClass* pThis)
475475

476476
int framesPerFacing = pTypeExt->TurretAnim_IdleFrames;
477477
int baseOffset = offsetIdle;
478+
bool hasFiringFrames = false;
478479

479480
if (isLowPower)
480481
{
481-
if (isFiring)
482+
if (isFiring && pTypeExt->TurretAnim_LowPowerFiringFrames > 0)
482483
{
483484
framesPerFacing = pTypeExt->TurretAnim_LowPowerFiringFrames;
484485
baseOffset = offsetLowPowerFiring;
486+
hasFiringFrames = true;
485487
}
486488
else if (pTypeExt->TurretAnim_LowPowerIdleFrames > 0)
487489
{
@@ -491,32 +493,49 @@ int BuildingExt::GetTurretFrame(BuildingClass* pThis)
491493
}
492494
else
493495
{
494-
if (isFiring)
496+
if (isFiring && pTypeExt->TurretAnim_FiringFrames > 0)
495497
{
496498
framesPerFacing = pTypeExt->TurretAnim_FiringFrames;
497499
baseOffset = offsetFiring;
500+
hasFiringFrames = true;
498501
}
499502
}
500503

501504
int animFrame = 0;
502505

503-
if (framesPerFacing > 1)
506+
if (isFiring && hasFiringFrames)
504507
{
505-
if (isFiring)
508+
animFrame = pExt->TurretAnimFiringFrame;
509+
pExt->TurretAnimRateTick++;
510+
511+
if (pExt->TurretAnimRateTick >= pTypeExt->TurretAnim_FiringRate)
506512
{
507-
animFrame = pExt->TurretAnimFiringFrame;
513+
pExt->TurretAnimRateTick = 0;
508514
pExt->TurretAnimFiringFrame++;
515+
}
509516

510-
if (pExt->TurretAnimFiringFrame >= framesPerFacing)
511-
{
512-
pExt->TurretAnimFiringFrame = -1;
513-
pExt->TurretAnimIdleFrame = 0; // Reset idle anim frame.
514-
}
517+
if (pExt->TurretAnimFiringFrame >= framesPerFacing)
518+
{
519+
pExt->TurretAnimFiringFrame = -1;
520+
pExt->TurretAnimIdleFrame = 0; // Reset idle anim frame.
521+
pExt->TurretAnimRateTick = 0;
515522
}
516-
else
523+
}
524+
else if (framesPerFacing > 1)
525+
{
526+
animFrame = pExt->TurretAnimIdleFrame;
527+
pExt->TurretAnimRateTick++;
528+
529+
if (pExt->TurretAnimRateTick >= pTypeExt->TurretAnim_IdleRate)
530+
{
531+
pExt->TurretAnimRateTick = 0;
532+
pExt->TurretAnimIdleFrame++;
533+
}
534+
535+
if (pExt->TurretAnimIdleFrame >= framesPerFacing)
517536
{
518-
animFrame = pExt->TurretAnimIdleFrame;
519-
++pExt->TurretAnimIdleFrame %= framesPerFacing;
537+
pExt->TurretAnimIdleFrame = 0;
538+
pExt->TurretAnimRateTick = 0;
520539
}
521540
}
522541

@@ -544,6 +563,7 @@ void BuildingExt::ExtData::Serialize(T& Stm)
544563
.Process(this->CurrentEMPulseSW)
545564
.Process(this->TurretAnimIdleFrame)
546565
.Process(this->TurretAnimFiringFrame)
566+
.Process(this->TurretAnimRateTick)
547567
//.Process(this->IsFiringNow) It is set and reset within a same function.
548568
;
549569
}
@@ -575,7 +595,7 @@ bool BuildingExt::SaveGlobals(PhobosStreamWriter& Stm)
575595
// =============================
576596
// container
577597

578-
BuildingExt::ExtContainer::ExtContainer() : Container("BuildingClass") { }
598+
BuildingExt::ExtContainer::ExtContainer() : Container("BuildingClass") {}
579599

580600
BuildingExt::ExtContainer::~ExtContainer() = default;
581601

src/Ext/Building/Body.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class BuildingExt
2929
bool IsFiringNow;
3030
int TurretAnimIdleFrame;
3131
int TurretAnimFiringFrame;
32+
int TurretAnimRateTick;
3233

3334
ExtData(BuildingClass* OwnerObject) : Extension<BuildingClass>(OwnerObject)
3435
, TypeExtData { nullptr }
@@ -46,6 +47,7 @@ class BuildingExt
4647
, IsFiringNow { false }
4748
, TurretAnimIdleFrame { 0 }
4849
, TurretAnimFiringFrame { -1 }
50+
, TurretAnimRateTick { 0 }
4951
{ }
5052

5153
void DisplayIncomeString();

src/Ext/Building/Hooks.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,10 @@ DEFINE_HOOK(0x44B6C7, BuildingClass_Mission_Attack_TurretAnim, 0x6)
11211121
bool firingFrames = isLowPower ? pTypeExt->TurretAnim_LowPowerFiringFrames : pTypeExt->TurretAnim_FiringFrames;
11221122

11231123
if (firingFrames > 0 && pExt->TurretAnimFiringFrame == -1)
1124+
{
11241125
pExt->TurretAnimFiringFrame = 0;
1126+
pExt->TurretAnimRateTick = 0;
1127+
}
11251128
}
11261129
}
11271130

src/Ext/BuildingType/Body.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ void BuildingTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
229229
this->TurretAnim_LowPowerIdleFrames.Read(exINI, pSection, "TurretAnim.LowPowerIdleFrames");
230230
this->TurretAnim_FiringFrames.Read(exINI, pSection, "TurretAnim.FiringFrames");
231231
this->TurretAnim_LowPowerFiringFrames.Read(exINI, pSection, "TurretAnim.LowPowerFiringFrames");
232+
this->TurretAnim_IdleRate.Read(exINI, pSection, "TurretAnim.IdleRate");
233+
this->TurretAnim_FiringRate.Read(exINI, pSection, "TurretAnim.FiringRate");
232234

233235
if (pThis->NumberOfDocks > 0)
234236
{
@@ -389,6 +391,8 @@ void BuildingTypeExt::ExtData::Serialize(T& Stm)
389391
.Process(this->TurretAnim_LowPowerIdleFrames)
390392
.Process(this->TurretAnim_FiringFrames)
391393
.Process(this->TurretAnim_LowPowerFiringFrames)
394+
.Process(this->TurretAnim_IdleRate)
395+
.Process(this->TurretAnim_FiringFrames)
392396

393397
// Ares 0.2
394398
.Process(this->CloningFacility)

src/Ext/BuildingType/Body.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ class BuildingTypeExt
108108
Valueable<int> TurretAnim_LowPowerIdleFrames;
109109
Valueable<int> TurretAnim_FiringFrames;
110110
Valueable<int> TurretAnim_LowPowerFiringFrames;
111+
Valueable<int> TurretAnim_IdleRate;
112+
Valueable<int> TurretAnim_FiringRate;
111113

112114
// Ares 0.2
113115
Valueable<bool> CloningFacility;
@@ -192,6 +194,8 @@ class BuildingTypeExt
192194
, TurretAnim_LowPowerIdleFrames { 0 }
193195
, TurretAnim_FiringFrames { 0 }
194196
, TurretAnim_LowPowerFiringFrames { 0 }
197+
, TurretAnim_IdleRate { 1 }
198+
, TurretAnim_FiringRate { 1 }
195199

196200
// Ares 0.2
197201
, CloningFacility { false }

0 commit comments

Comments
 (0)