Skip to content
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
1 change: 1 addition & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ This page lists all the individual contributions to the project by their author.
- Toggle per-target warhead effects apply timing
- Extra range for chasing and pre-firing
- Fix an issue that rockets do not consider the destination altitude during climbing
- Updateable firing anim
- **solar-III (凤九歌)**
- Target scanning delay customization (documentation)
- Skip target scanning function calling for unarmed technos (documentation)
Expand Down
14 changes: 14 additions & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -2540,3 +2540,17 @@ In `rulesmd.ini`:
[SOMEWEAPON] ; WeaponType
IsSingleColor=false ; boolean
```

### Updateable firing anim

- In vanilla, firing anims is attached to the firer, but it won't update its type and location to fit the firer's facing. This is now customizable by the following flags.

In `rulesmd.ini`:
```ini
[AudioVisual]
FiringAnim.Update=false ; boolean

[SOMEWEAPON] ; WeaponType
Anim.Update= ; boolean, default to [AudioVisual] -> FiringAnim.Update
```

1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,7 @@ New:
- Allow techno type considered as other type when recruiting techno for teams (by NetsuNegi)
- Map Action [`511` Undeploy Building to Waypoint](AI-Scripting-and-Mapping.md#undeploy-building-to-waypoint), [`609` Set Radar Mode](AI-Scripting-and-Mapping.md#set-radar-mode), [`610` Set house's `TeamDelays` value](AI-Scripting-and-Mapping.md#set-house-s-teamdelays-value) (by FlyStar)
- Fixed an issue that rockets do not consider the destination altitude during climbing (by TaranDahl)
- [Updateable firing anim](Fixed-or-Improved-Logics.md#updateable-firing-anim) (by TaranDahl)

Vanilla fixes:
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)
Expand Down
61 changes: 61 additions & 0 deletions src/Ext/Anim/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,64 @@ void AnimExt::ExtData::DeleteAttachedSystem()
}
}

inline unsigned int TranslateFixedPoint(size_t bitsFrom, size_t bitsTo, unsigned int value, unsigned int offset = 0)
{
const size_t MaskIn = ((1u << bitsFrom) - 1);
const size_t MaskOut = ((1u << bitsTo) - 1);

if (bitsFrom > bitsTo)
{
// converting down
return (((((value & MaskIn) >> (bitsFrom - bitsTo - 1)) + 1) >> 1) + offset) & MaskOut;

}
else if (bitsFrom < bitsTo)
{
// converting up
return (((value - offset) & MaskIn) << (bitsTo - bitsFrom)) & MaskOut;

}
else
{
return value & MaskOut;
}
}

void AnimExt::ExtData::UpdateAsFiringAnim()
{
auto pThis = this->OwnerObject();
auto pOwner = abstract_cast<TechnoClass*>(pThis->OwnerObject);

if (this->FromWeapon && pOwner)
{
AnimTypeClass* pNewType = nullptr;
auto pWeapon = this->FromWeapon;

auto highest = Conversions::Int2Highest(pWeapon->Anim.Count);

// 2^highest is the frame count, 3 means 8 frames
if (highest >= 3)
{
auto offset = 1u << (highest - 3);
auto index = TranslateFixedPoint(16, highest, static_cast<WORD>((pOwner)->GetRealFacing().GetValue<16>()), offset);
pNewType = pWeapon->Anim.GetItemOrDefault(index);
}
else
{
pNewType = pWeapon->Anim.GetItemOrDefault(0);
}

if (pNewType)
pThis->Type = pNewType;

auto burstIdx = pOwner->CurrentBurstIndex;
pOwner->CurrentBurstIndex = this->FromBurstIdx;
auto flh = pOwner->GetFLH(this->FromWeaponIdx, CoordStruct::Empty);
pOwner->CurrentBurstIndex = burstIdx;
pThis->SetLocation(flh - pOwner->GetCoords());
}
}

//Modified from Ares
bool AnimExt::SetAnimOwnerHouseKind(AnimClass* pAnim, HouseClass* pInvoker, HouseClass* pVictim, bool defaultToVictimOwner, bool defaultToInvokerOwner)
{
Expand Down Expand Up @@ -411,6 +469,9 @@ void AnimExt::ExtData::Serialize(T& Stm)
.Process(this->DelayedFireRemoveOnNoDelay)
.Process(this->IsAttachedEffectAnim)
.Process(this->IsShieldIdleAnim)
.Process(this->FromWeapon)
.Process(this->FromWeaponIdx)
.Process(this->FromBurstIdx)
;
}

Expand Down
8 changes: 8 additions & 0 deletions src/Ext/Anim/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class AnimExt
bool DelayedFireRemoveOnNoDelay;
bool IsAttachedEffectAnim;
bool IsShieldIdleAnim;
WeaponTypeClass* FromWeapon;
int FromWeaponIdx;
int FromBurstIdx;

ExtData(AnimClass* OwnerObject) : Extension<AnimClass>(OwnerObject)
, DeathUnitFacing { 0 }
Expand All @@ -45,13 +48,18 @@ class AnimExt
, DelayedFireRemoveOnNoDelay { false }
, IsAttachedEffectAnim { false }
, IsShieldIdleAnim { false }
, FromWeapon {}
, FromWeaponIdx {}
, FromBurstIdx {}
{ }

void SetInvoker(TechnoClass* pInvoker);
void SetInvoker(TechnoClass* pInvoker, HouseClass* pInvokerHouse);
void CreateAttachedSystem();
void DeleteAttachedSystem();

void UpdateAsFiringAnim();

virtual ~ExtData() override;

virtual void InvalidatePointer(void* ptr, bool bRemoved) override { }
Expand Down
26 changes: 26 additions & 0 deletions src/Ext/Anim/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ DEFINE_HOOK(0x423B95, AnimClass_AI_HideIfNoOre_Threshold, 0x8)
pThis->Invisible = pThis->GetCell()->GetContainedTiberiumValue() <= nThreshold;
}

AnimExt::ExtMap.Find(pThis)->UpdateAsFiringAnim();

return 0x423BBF;
}

Expand Down Expand Up @@ -549,3 +551,27 @@ DEFINE_HOOK(0x4250E1, AnimClass_Middle_CraterDestroyTiberium, 0x6)
return AnimTypeExt::ExtMap.Find(pType)->Crater_DestroyTiberium.Get(RulesExt::Global()->AnimCraterDestroyTiberium) ? 0 : SkipDestroyTiberium;
}

#pragma region FiringAnimUpdate

DEFINE_HOOK(0x6FF42B, TechnoClass_Fire_Anim, 0x7)
{
enum { SkipBuildingCheck = 0x6FF437 };

GET(TechnoClass*, pThis, ESI);
GET(AnimClass*, pAnim, EDI);
GET(WeaponTypeClass*, pWeapon, EBX);
GET_BASE(int, wpIdx, 0xC);

auto pAnimExt = AnimExt::ExtMap.Find(pAnim);

if (WeaponTypeExt::ExtMap.Find(pWeapon)->Anim_Update.Get(RulesExt::Global()->FiringAnim_Update))
{
pAnimExt->FromWeapon = pWeapon;
pAnimExt->FromWeaponIdx = wpIdx;
pAnimExt->FromBurstIdx = pThis->CurrentBurstIndex;
}

return SkipBuildingCheck;
}

#pragma endregion
3 changes: 3 additions & 0 deletions src/Ext/Rules/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,8 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
this->ExtraRange_Prefiring.Read(exINI, GameStrings::General, "ExtraRange.Prefiring");
this->ExtraRange_Prefiring_IncludeBurst.Read(exINI, GameStrings::General, "ExtraRange.Prefiring.IncludeBurst");

this->FiringAnim_Update.Read(exINI, GameStrings::AudioVisual, "FiringAnim.Update");

// Section AITargetTypes
int itemsCount = pINI->GetKeyCount("AITargetTypes");
for (int i = 0; i < itemsCount; ++i)
Expand Down Expand Up @@ -632,6 +634,7 @@ void RulesExt::ExtData::Serialize(T& Stm)
.Process(this->ExtraRange_TargetMoving_CloseRangeOnly)
.Process(this->ExtraRange_Prefiring)
.Process(this->ExtraRange_Prefiring_IncludeBurst)
.Process(this->FiringAnim_Update)
;
}

Expand Down
4 changes: 4 additions & 0 deletions src/Ext/Rules/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ class RulesExt
Valueable<bool> ExtraRange_Prefiring_IncludeBurst;

Valueable<bool> ApplyPerTargetEffectsOnDetonate;

Valueable<bool> FiringAnim_Update;

ExtData(RulesClass* OwnerObject) : Extension<RulesClass>(OwnerObject)
, Storage_TiberiumIndex { -1 }
Expand Down Expand Up @@ -534,6 +536,8 @@ class RulesExt
, ExtraRange_TargetMoving_CloseRangeOnly { false }
, ExtraRange_Prefiring { Leptons(0) }
, ExtraRange_Prefiring_IncludeBurst { true }

, FiringAnim_Update { false }
{ }

virtual ~ExtData() = default;
Expand Down
4 changes: 3 additions & 1 deletion src/Ext/WeaponType/Body.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "Body.h"
#include "Body.h"
#include <Ext/Bullet/Body.h>
#include <Ext/Techno/Body.h>
#include <SpawnManagerClass.h>
Expand Down Expand Up @@ -156,6 +156,7 @@ void WeaponTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->ExtraRange_TargetMoving.Read(exINI, GameStrings::General, "ExtraRange.TargetMoving");
this->ExtraRange_Prefiring.Read(exINI, GameStrings::General, "ExtraRange.Prefiring");
this->ExtraRange_Prefiring_IncludeBurst.Read(exINI, GameStrings::General, "ExtraRange.Prefiring.IncludeBurst");
this->Anim_Update.Read(exINI, pSection, "Anim.Update");

// handle SkipWeaponPicking
if (this->CanTarget != AffectedTarget::All || this->CanTargetHouses != AffectedHouse::All
Expand Down Expand Up @@ -243,6 +244,7 @@ void WeaponTypeExt::ExtData::Serialize(T& Stm)
.Process(this->ExtraRange_TargetMoving)
.Process(this->ExtraRange_Prefiring)
.Process(this->ExtraRange_Prefiring_IncludeBurst)
.Process(this->Anim_Update)
;
};

Expand Down
4 changes: 2 additions & 2 deletions src/Ext/WeaponType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ class WeaponTypeExt
Valueable<bool> DelayedFire_OnlyOnInitialBurst;
Nullable<CoordStruct> DelayedFire_AnimOffset;
Valueable<bool> DelayedFire_AnimOnTurret;

Nullable<Leptons> ExtraRange_TargetMoving;
Nullable<Leptons> ExtraRange_Prefiring;
Nullable<bool> ExtraRange_Prefiring_IncludeBurst;
Nullable<bool> Anim_Update;

bool SkipWeaponPicking;

Expand Down Expand Up @@ -168,10 +168,10 @@ class WeaponTypeExt
, DelayedFire_OnlyOnInitialBurst { false }
, DelayedFire_AnimOffset {}
, DelayedFire_AnimOnTurret { true }

, ExtraRange_TargetMoving {}
, ExtraRange_Prefiring {}
, ExtraRange_Prefiring_IncludeBurst {}
, Anim_Update {}
{ }

int GetBurstDelay(int burstIndex) const;
Expand Down