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
1 change: 1 addition & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -921,3 +921,4 @@ This page lists all the individual contributions to the project by their author.
- **Chang_zhi**:
- Interop export interface for accessing scenario local/global variables
- Add `ClampToScreen` tag for `BannerType` to control whether banner position is clamped to the visible area
- **obsidianus** - Automatic conversion based on health
24 changes: 24 additions & 0 deletions docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -1545,6 +1545,30 @@ This feature has the same limitations as [Ares' Type Conversion](https://ares-de
This feature requires Ares 3.0 or higher to function! When Ares 3.0+ is not detected, not all properties of a unit may be updated.
```

### Automatic conversion based on health

- Units can now be converted into another unit by health percentage.
- `Convert.Health.AbovePercent` determines the minimal health percentage at which a unit converts automatically.
- `Convert.Health.BelowPercent` determines the maximum health percentage at which a unit converts automatically.
- `Convert.Health` specify the new techno after the conversion. This unit must be of the same type of the original (infantry -> infantry, vehicle -> vehicle or aircraft -> aircraft).
- Setting a negative number will disable the HP check, and when both checks are disabled, conversion will not occur.

In `rulesmd.ini`:
```ini
[SOMETECHNO] ; TechnoType, before conversion
Convert.Health.AbovePercent=-1.0 ; floating point value, percents or absolute
Convert.Health.BelowPercent=-1.0 ; floating point value, percents or absolute
Convert.Health= ; TechnoType, after conversion
```

```{warning}
This feature has the same limitations as [Ares' Type Conversion](https://ares-developers.github.io/Ares-docs/new/typeconversion.html). This feature does not support BuildingTypes.
```

```{warning}
This feature requires Ares 3.0 or higher to function! When Ares 3.0+ is not detected, not all properties of a unit may be updated.
```

### Automatic passenger deletion

- Transports can erase passengers over time. Passengers are deleted in order of entering the transport, from first to last.
Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,7 @@ HideShakeEffects=false ; boolean
- [`600` Configure Drop Crate](AI-Scripting-and-Mapping.md#configure-drop-crate) (by FS-21)
- [DeployFire supports buildings](New-or-Enhanced-Logics.md#deployfire-supports) (By FlyStar)
- `OmniFire` supports buildings with `Turret=yes` (by FlyStar)
- [Automatic conversion based on heallth](New-or-Enhanced-Logics.md#automatic-conversion-based-on-heallth) (by obsidianus)
#### Vanilla fixes:
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)
Expand Down
18 changes: 18 additions & 0 deletions docs/locale/zh_CN/LC_MESSAGES/New-or-Enhanced-Logics.po
Original file line number Diff line number Diff line change
Expand Up @@ -3626,6 +3626,24 @@ msgid ""
"both checks are disabled, conversion will not occur."
msgstr "设为负数将会禁用弹药数量检查,当两个检查都被禁用时将不会触发变形。"

msgid "Automatic conversion based on health"
msgstr "自动根据血量变形"

msgid "Units can now be converted into another unit by health percentage."
msgstr "单位可以现在可以基于HP变为其他单位"

msgid "`Convert.Health.AbovePercent` determines the minimal health percentage at which a unit converts automatically."
msgstr "`Convert.Health.AbovePercent`决定了触发单位自动变身的最小HP值"

msgid "`Convert.Health.BelowPercent` determines the maximum health percentage at which a unit converts automatically."
msgstr "`Convert.Health.BelowPercent`决定了触发单位自动变身的最大HP值"

msgid "`Convert.Health` specify the new techno after the conversion. This unit must be of the same type of the original (infantry -> infantry, vehicle -> vehicle or aircraft -> aircraft)."
msgstr "`Convert.Health` 指定变身后的单位. 类型需要和原单位相同 (步兵 → 步兵, 载具 → 载具 或 飞机 → 飞机)"

msgid "Setting a negative number will disable the HP check, and when both checks are disabled, conversion will not occur."
msgstr "设置为负值会关闭对应的HP检查,当两项检查都被关闭则不会触发变身."

msgid "Automatic passenger deletion"
msgstr "自动删除乘客"

Expand Down
42 changes: 42 additions & 0 deletions src/Ext/Foot/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,48 @@ void FootExt::UpdateTypeData(TechnoTypeClass* pCurrentType)
}
}

void FootExt::AmmoAutoConvertActions()
{
const auto pTypeExt = this->TypeExtData;

if (!pTypeExt->Ammo_AutoConvertType.isset())
return;

const int min = pTypeExt->Ammo_AutoConvertMinimumAmount;
const int max = pTypeExt->Ammo_AutoConvertMaximumAmount;

if (min < 0 && max < 0)
return;

if (pTypeExt->OwnerObject()->Ammo <= 0)
return;

const auto pThis = this->OwnerObject();
const int ammo = pThis->Ammo;

if ((min < 0 || ammo >= min) && (max < 0 || ammo <= max))
TechnoExt::ConvertToType(pThis, pTypeExt->Ammo_AutoConvertType);
}

void FootExt::HealthAutoConvertActions()
{
const auto pTypeExt = this->TypeExtData;

if (!pTypeExt->Convert_Health.isset())
return;

const double min = pTypeExt->Convert_Health_AbovePercent;
const double max = pTypeExt->Convert_Health_BelowPercent;

if (min < 0 && max < 0)
return;

const auto pThis = this->OwnerObject();

if (TechnoExt::IsHealthInThreshold(pThis, min, max))
TechnoExt::ConvertToType(pThis, pTypeExt->Convert_Health);
}

// =============================
// load / save

Expand Down
2 changes: 2 additions & 0 deletions src/Ext/Foot/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class FootExt : public TechnoExt
void UpdateOnTunnelEnter();
void UpdateOnTunnelExit();
void UpdateTypeData(TechnoTypeClass* pCurrentType);
void HealthAutoConvertActions();
void AmmoAutoConvertActions();

virtual void LoadFromStream(PhobosStreamReader& Stm) override;
virtual void SaveToStream(PhobosStreamWriter& Stm) override;
Expand Down
26 changes: 0 additions & 26 deletions src/Ext/Techno/Body.Update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,32 +134,6 @@ void TechnoExt::ApplyInterceptor()
}
}

void TechnoExt::AmmoAutoConvertActions()
{
const auto pTypeExt = this->TypeExtData;

if (!pTypeExt->Ammo_AutoConvertType.isset())
return;

const int min = pTypeExt->Ammo_AutoConvertMinimumAmount;
const int max = pTypeExt->Ammo_AutoConvertMaximumAmount;

if (min < 0 && max < 0)
return;

if (pTypeExt->OwnerObject()->Ammo <= 0)
return;

const auto pThis = this->OwnerObject();
const int ammo = pThis->Ammo;

if ((min < 0 || ammo >= min) && (max < 0 || ammo <= max))
{
const auto pFoot = abstract_cast<FootClass*, true>(pThis);
TechnoExt::ConvertToType(pFoot, pTypeExt->Ammo_AutoConvertType);
}
}

// TODO : Merge into new AttachEffects
bool TechnoExt::CheckDeathConditions(bool isInLimbo)
{
Expand Down
2 changes: 0 additions & 2 deletions src/Ext/Techno/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,6 @@ class TechnoExt : public RadioExt, public Detach::Listener<AirstrikeClass>
int ApplyForceWeaponInRange(AbstractClass* pTarget);
void ResetDelayedFireTimer();
void UpdateTintValues();

void AmmoAutoConvertActions();
void UpdateLastTargetCrd();
int GetSight();

Expand Down
1 change: 1 addition & 0 deletions src/Ext/Techno/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ DEFINE_HOOK(0x4DA54E, FootClass_AI, 0x6)
pExt->UpdateWarpInDelay();
pExt->UpdateTiberiumEater();
pExt->AmmoAutoConvertActions();
pExt->HealthAutoConvertActions();

if (pExt->AttackMoveFollowerTempCount)
pExt->AttackMoveFollowerTempCount--;
Expand Down
11 changes: 11 additions & 0 deletions src/Ext/TechnoType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,13 @@ void TechnoTypeExt::LoadFromINIFile(CCINIClass* const pINI)
|| ExtraThreatCoefficient_Facing.Get(RulesExt::Global()->ExtraThreatCoefficient_Facing) != 0.0
|| ExtraThreatCoefficient_DistanceToLastTarget.Get(RulesExt::Global()->ExtraThreatCoefficient_DistanceToLastTarget) != 0.0;

this->Convert_Health_AbovePercent.Read(exINI, pSection, "Convert.Health.AbovePercent");
this->Convert_Health_BelowPercent.Read(exINI, pSection, "Convert.Health.BelowPercent");
this->Convert_Health.Read(exINI, pSection, "Convert.Health");

if (this->Convert_Health_AbovePercent > this->Convert_Health_BelowPercent)
Debug::Log("[Developer warning][%s] Convert.Health.AbovePercent is greater than Convert.Health.BelowPercent, resulting in no conversion.\n", pSection);

// Ares 0.2
this->RadarJamRadius.Read(exINI, pSection, "RadarJamRadius");

Expand Down Expand Up @@ -1746,6 +1753,10 @@ void TechnoTypeExt::Serialize(T& Stm)
.Process(this->ExtraThreatCoefficient_InRangeDistance)
.Process(this->ExtraThreatCoefficient_Facing)
.Process(this->ExtraThreatCoefficient_DistanceToLastTarget)

.Process(this->Convert_Health_AbovePercent)
.Process(this->Convert_Health_BelowPercent)
.Process(this->Convert_Health)
;
}
void TechnoTypeExt::LoadFromStream(PhobosStreamReader& Stm)
Expand Down
8 changes: 8 additions & 0 deletions src/Ext/TechnoType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,10 @@ class TechnoTypeExt : public ObjectTypeExt

Nullable<Powerup> DropCrate;

Valueable<double> Convert_Health_AbovePercent;
Valueable<double> Convert_Health_BelowPercent;
Nullable<TechnoTypeClass*> Convert_Health;

Nullable<bool> Unsellable; // Ares 3.0

TechnoTypeExt(TechnoTypeClass* OwnerObject) : ObjectTypeExt(OwnerObject)
Expand Down Expand Up @@ -808,6 +812,10 @@ class TechnoTypeExt : public ObjectTypeExt
, ExtraThreatCoefficient_DistanceToLastTarget {}

, DropCrate {}

, Convert_Health_AbovePercent { -1.0 }
, Convert_Health_BelowPercent { -1.0 }
, Convert_Health {}
{ }

virtual ~TechnoTypeExt() = default;
Expand Down
Loading