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 @@ -781,6 +781,7 @@ This page lists all the individual contributions to the project by their author.
- Customize whether or not passenger can fire out when the transport is moving
- Show game time
- Fix a game crash when parsing string list with null entry
- More veteran and elite abilities
- **NaotoYuuki** - Vertical & meteor trajectory projectile prototypes
- **handama**:
- AI script action to `16005 Jump Back To Previous Script`
Expand Down
33 changes: 32 additions & 1 deletion docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -2336,6 +2336,25 @@ CombatAlert.EVA=EVA_UnitsInCombat ; EVA entry
CombatAlert.Suppress= ; boolean
```

### Weapon range adjustment on promotion

- Now you can add `RANGE` to `VeteranAbilities` and `EliteAbilities` to adjust the weapon range of this TechnoType.
- `ProjectileRange` of the weapon's projectile will also be affected if `Projectile.ApplyModifiers` set to true.

```{hint}
- Abilities from `VeteranAbilities` keep working at elite level, and `EliteAbilities` are added on top, matching how vanilla abilities accumulate.
- `VeteranRange` will be applied to the range calculation. Values greater than `1.0` lengthen the range, values smaller than `1.0` shorten it, and `1.0` (the default) leaves it unchanged.
```

In `rulesmd.ini`:
```ini
[General]
VeteranRange=1.0 ; floating point value, multiplier

[SOMETECHNO] ; TechnoType, with VeteranAbilities and/or EliteAbilities containing RANGE.
VeteranRange= ; floating point value, multiplier, default to [General] -> VeteranRange
```

### Recount burst index

- You can now make technos recount their current burst index when they have changed the firing weapon or have maintained for a period of time without any targets (take the larger value of last firing weapon's `ROF` and 30 frames).
Expand Down Expand Up @@ -2785,10 +2804,19 @@ AffectsGround=true ; boolean
- `Crit.AnimOnAffectedTargets`, if set, makes the animation(s) from `Crit.AnimList` play on each affected target *in addition* to animation from Warhead's `AnimList` playing as normal instead of replacing `AnimList` animation. Note that because these animations are independent from `AnimList`, `Crit.AnimList.PickRandom` and `Crit.AnimList.CreateAll` will not default to their `AnimList` counterparts here and need to be explicitly set if needed.
- `Crit.ActiveChanceAnims` can be used to set animation to be always displayed at the Warhead's detonation coordinates if the current Warhead has a chance to critically hit. If more than one animation is listed, a random one is selected.
- `Crit.SuppressWhenIntercepted`, if set, prevents critical hits from occuring at all if the warhead was detonated from a [projectile that was intercepted](#projectile-interception-logic).
- `ImmuneToCrit` can be set on TechnoTypes and ShieldTypes to make them immune to critical hits.
- `ImmuneToCrit` can be set on TechnoTypes and ShieldTypes to make them immune to critical hits. You can also add `CRITIMMUNE` to the TechnoTypes' `VeteranAbilities` and `EliteAbilities` to grant them immunity when promoting.
- You can add `CRITCHANCE` to `VeteranAbilities` and `EliteAbilities` to adjust the critical hit chance of this TechnoType.

```{hint}
- Abilities from `VeteranAbilities` keep working at elite level, and `EliteAbilities` are added on top, matching how vanilla abilities accumulate.
- `VeteranCritChance` will be applied to the range calculation. Values greater than `1.0` increase the chance, values smaller than `1.0` decrease it, and `1.0` (the default) leaves it unchanged.
```

In `rulesmd.ini`:
```ini
[General]
VeteranCritChance=1.0 ; floating point value

[CombatDamage]
Crit.ApplyChancePerTarget=false ; boolean
Crit.ExtraDamage.ApplyFirepowerMult=false ; boolean
Expand All @@ -2815,6 +2843,9 @@ Crit.SuppressWhenIntercepted= ; boolean, default to [CombatDamage]

[SOMETECHNO] ; TechnoType
ImmuneToCrit=false ; boolean

[SOMETECHNO] ; TechnoType, with VeteranAbilities and/or EliteAbilities containing CRITCHANCE.
VeteranCritChance= ; floating point value, multiplier, default to [General] -> VeteranCritChance
```

```{warning}
Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ HideShakeEffects=false ; boolean
#### New:
- [Customized transport plane for teams](AI-Scripting-and-Mapping.md#customized-transport-plane-for-teams) (by FlyStar)
- [Modify ammo on impact](New-or-Enhanced-Logics.md#modify-ammo-on-impact) (by FS-21)
- More veteran and elite abilities (by Ollerus)

#### Vanilla fixes:
- Fixed the bug where a building with `Factory=BuildingType` owned by the AI did not play `ProductionAnim` when placing a produced building (by Noble_Fish)
Expand Down
4 changes: 4 additions & 0 deletions src/Ext/Rules/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)

this->VeteranReload.Read(exINI, GameStrings::General, "VeteranReload");
this->VeteranEmptyReload.Read(exINI, GameStrings::General, "VeteranEmptyReload");
this->VeteranRange.Read(exINI, GameStrings::General, "VeteranRange");
this->VeteranCritChance.Read(exINI, GameStrings::General, "VeteranCritChance");

this->NoTurret_TrackTarget.Read(exINI, GameStrings::General, "NoTurret.TrackTarget");

Expand Down Expand Up @@ -923,6 +925,8 @@ void RulesExt::ExtData::Serialize(T& Stm)
.Process(this->NoReload_Temporal)
.Process(this->VeteranReload)
.Process(this->VeteranEmptyReload)
.Process(this->VeteranRange)
.Process(this->VeteranCritChance)
.Process(this->NoTurret_TrackTarget)
.Process(this->GatherWhenMCVDeploy)
.Process(this->AIFireSale)
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 @@ -291,6 +291,8 @@ class RulesExt
Valueable<bool> NoReload_Temporal;
Valueable<double> VeteranReload;
Nullable<double> VeteranEmptyReload;
Valueable<double> VeteranRange;
Valueable<double> VeteranCritChance;
Valueable<bool> NoTurret_TrackTarget;

Valueable<bool> GatherWhenMCVDeploy;
Expand Down Expand Up @@ -788,6 +790,8 @@ class RulesExt
, NoReload_Temporal { false }
, VeteranReload { 1.0 }
, VeteranEmptyReload {}
, VeteranRange { 1.0 }
, VeteranCritChance { 1.0 }
, NoTurret_TrackTarget { false }
, GatherWhenMCVDeploy { true }
, AIFireSale { true }
Expand Down
7 changes: 3 additions & 4 deletions src/Ext/Techno/Hooks.Firing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,7 @@ DEFINE_HOOK(0x6F3AEB, TechnoClass_GetFLH, 0x6)
GET(TechnoTypeClass*, pType, EAX);
GET(const int, weaponIndex, ESI);
GET_STACK(CoordStruct*, pCoords, STACK_OFFSET(0xD8, 0x4));
REF_STACK(CoordStruct, offset, STACK_OFFSET(0xD8, 0xC));
REF_STACK(const CoordStruct, offset, STACK_OFFSET(0xD8, 0xC));

bool allowOnTurret = true;
CoordStruct flh = CoordStruct::Empty;
Expand Down Expand Up @@ -1172,11 +1172,10 @@ static inline int ScaleReloadDurationForVeterancy(TechnoClass* pThis, int durati
return duration;

const auto pTypeExt = TechnoExt::Fetch(pThis)->TypeExtData;
const auto pRulesExt = RulesExt::Global();

const double multiplier = ability == AdditionalAbility::EmptyReload
? pTypeExt->VeteranEmptyReload.Get(pRulesExt->VeteranEmptyReload.Get(RulesExt::Global()->VeteranReload))
: pTypeExt->VeteranReload.Get(pRulesExt->VeteranReload);
? pTypeExt->VeteranEmptyReload.Get(RulesExt::Global()->VeteranEmptyReload.Get(RulesExt::Global()->VeteranReload))
: pTypeExt->VeteranReload.Get(RulesExt::Global()->VeteranReload);

return Math::max(1, GeneralUtils::SafeMultiply(duration, multiplier));
}
Expand Down
7 changes: 7 additions & 0 deletions src/Ext/TechnoType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ namespace
constexpr std::pair<const char*, AdditionalAbility> AbilityTokens[] = {
{ "RELOAD", AdditionalAbility::Reload },
{ "EMPTY_RELOAD", AdditionalAbility::EmptyReload },
{ "RANGE", AdditionalAbility::Range },
{ "CRITIMMUNE", AdditionalAbility::CritImmune },
{ "CRITCHANCE", AdditionalAbility::CritChance }
};

void ReadAdditionalAbilities(
Expand Down Expand Up @@ -1050,6 +1053,8 @@ void TechnoTypeExt::LoadFromINIFile(CCINIClass* const pINI)

this->VeteranReload.Read(exINI, pSection, "VeteranReload");
this->VeteranEmptyReload.Read(exINI, pSection, "VeteranEmptyReload");
this->VeteranRange.Read(exINI, pSection, "VeteranRange");
this->VeteranCritChance.Read(exINI, pSection, "VeteranCritChance");

this->Wake.Read(exINI, pSection, "Wake");
this->Wake_Grapple.Read(exINI, pSection, "Wake.Grapple");
Expand Down Expand Up @@ -1678,6 +1683,8 @@ void TechnoTypeExt::Serialize(T& Stm)
.Process(this->AdditionalEliteAbilities)
.Process(this->VeteranReload)
.Process(this->VeteranEmptyReload)
.Process(this->VeteranRange)
.Process(this->VeteranCritChance)

.Process(this->Wake)
.Process(this->Wake_Grapple)
Expand Down
4 changes: 4 additions & 0 deletions src/Ext/TechnoType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ class TechnoTypeExt : public ObjectTypeExt
std::bitset<AdditionalAbilityCount> AdditionalEliteAbilities;
Nullable<double> VeteranReload;
Nullable<double> VeteranEmptyReload;
Nullable<double> VeteranRange;
Nullable<double> VeteranCritChance;

Nullable<AnimTypeClass*> Wake;
Nullable<AnimTypeClass*> Wake_Grapple;
Expand Down Expand Up @@ -702,6 +704,8 @@ class TechnoTypeExt : public ObjectTypeExt
, AdditionalEliteAbilities {}
, VeteranReload {}
, VeteranEmptyReload {}
, VeteranRange {}
, VeteranCritChance {}

, Wake { }
, Wake_Grapple { }
Expand Down
5 changes: 4 additions & 1 deletion src/Ext/WarheadType/Detonate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@

auto const pTargetExt = TechnoExt::Fetch(pTarget);

if (pTargetExt->TypeExtData->ImmuneToCrit)
if (pTargetExt->TypeExtData->ImmuneToCrit || TechnoExt::HasAdditionalAbility(pTarget, AdditionalAbility::CritImmune))
return;

auto const pSld = pTargetExt->Shield.get();
Expand Down Expand Up @@ -747,6 +747,9 @@

auto const pExt = TechnoExt::Fetch(pFirer);

if (TechnoExt::HasAdditionalAbility(pFirer, AdditionalAbility::CritChance))
critChance = GeneralUtils::SafeMultiply(critChance, Math::max(pExt->TypeExtData->VeteranCritChance.Get(RulesExt::Global()->VeteranCritChance), 0.0));

Check warning on line 751 in src/Ext/WarheadType/Detonate.cpp

View workflow job for this annotation

GitHub Actions / build

'argument': conversion from 'double' to 'int', possible loss of data [D:\a\Phobos\Phobos\Phobos.vcxproj]

if (!pExt->AE.HasCritModifiers)
return critChance;

Expand Down
3 changes: 3 additions & 0 deletions src/Ext/WeaponType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,9 @@ int WeaponTypeExt::GetRangeWithModifiers(WeaponTypeClass* pThis, TechnoClass* pF

auto const pTechnoExt = TechnoExt::Fetch(pTechno);

if (TechnoExt::HasAdditionalAbility(pTechno, AdditionalAbility::Range))
range = GeneralUtils::SafeMultiply(range, Math::max(pTechnoExt->TypeExtData->VeteranRange.Get(RulesExt::Global()->VeteranRange), 0.0));

if (!pTechnoExt->AE.HasRangeModifier)
return range;

Expand Down
3 changes: 3 additions & 0 deletions src/Utilities/Enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,9 @@ enum class AdditionalAbility : unsigned char
{
Reload = 0,
EmptyReload = 1,
Range = 2,
CritImmune = 3,
CritChance = 4,
Count
};

Expand Down
Loading