Skip to content

Commit

Permalink
Separate subterranean movement speed from regular speed
Browse files Browse the repository at this point in the history
  • Loading branch information
Starkku committed Oct 14, 2024
1 parent 07ef945 commit b493c41
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 37 deletions.
15 changes: 8 additions & 7 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Fixed damaged aircraft not repairing on `UnitReload=true` docks unless they land on the dock first.
- Certain global tileset indices (`ShorePieces`, `WaterSet`, `CliffSet`, `WaterCliffs`, `WaterBridge`, `BridgeSet` and `WoodBridgeSet`) are now correctly parsed for Lunar theater.
- Unit `Speed` setting now accepts floating-point values. Internally parsed values are clamped down to maximum of 100, multiplied by 256 and divided by 100, the result (which at this point is converted to an integer) then clamped down to maximum of 255 giving effective internal speed value range of 0 to 255, e.g leptons traveled per game frame.
- Subterranean movement now benefits from speed multipliers from all sources such as veterancy, AttachEffect etc.

## Fixes / interactions with other extensions

Expand Down Expand Up @@ -921,17 +922,17 @@ GatherWhenMCVDeploy=true ; boolean
### Subterranean unit travel height and speed

- It is now possible to control the height at which units with subterranean (Tunnel) `Locomotor` travel, globally or per TechnoType.
- It is also possible to change subterranean units to use their `Speed` and any speed modifiers when traveling underground, instead of hardcoded speed setting that would be roughly between `Speed=7` and `Speed=8`.
- Subterranean movement speed is now also customizable, both globally and per TechnoType. If per-TechnoType value is negative, global value is used. This does not affect the speed at which the unit moves vertically when burrowing which is determined by `Speed` multiplied by `[General]`->`TunnelSpeed`.

In `rulesmd.ini`:
```ini
[General]
SubterraneanHeight=-256 ; integer, height in leptons (1/256th of a cell)
SubterraneanUseSpeed=false ; boolean

[SOMETECHNO] ; TechnoType
SubterraneanHeight= ; integer, height in leptons (1/256th of a cell)
SubterraneanUseSpeed= ; boolean
SubterraneanHeight=-256 ; integer, height in leptons (1/256th of a cell)
SubterraneanSpeed=7.5 ; floating point value
[SOMETECHNO] ; TechnoType
SubterraneanHeight= ; integer, height in leptons (1/256th of a cell)
SubterraneanSpeed=-1 ; floating point value
```

```{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 @@ -542,6 +542,7 @@ Vanilla fixes:
- Projectiles created from `AirburstWeapon` now remember their WeaponType and can apply radiation etc. (by Starkku)
- Fixed damaged aircraft not repairing on `UnitReload=true` docks unless they land on the dock first (by Starkku)
- Certain global tileset indices (`ShorePieces`, `WaterSet`, `CliffSet`, `WaterCliffs`, `WaterBridge`, `BridgeSet` and `WoodBridgeSet`) are now correctly parsed for Lunar theater (by Starkku)
- Subterranean movement now benefits from speed multipliers from all sources such as veterancy, AttachEffect etc. (by Starkku)
Phobos fixes:
- Fixed a few errors of calling for superweapon launch by `LaunchSW` or building infiltration (by Trsdy)
Expand Down
5 changes: 3 additions & 2 deletions src/Ext/Rules/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
this->ChronoSphereDelay.Read(exINI, GameStrings::General, "ChronoSphereDelay");
this->AIChronoSphereSW.Read(exINI, GameStrings::General, "AIChronoSphereSW");
this->AIChronoWarpSW.Read(exINI, GameStrings::General, "AIChronoWarpSW");
this->SubterraneanUseSpeed.Read(exINI, GameStrings::General, "SubterraneanUseSpeed");

exINI.ReadSpeed(GameStrings::General, "SubterraneanSpeed", &this->SubterraneanSpeed);
this->SubterraneanHeight.Read(exINI, GameStrings::General, "SubterraneanHeight");
this->AISuperWeaponDelay.Read(exINI, GameStrings::General, "AISuperWeaponDelay");
this->UseGlobalRadApplicationDelay.Read(exINI, GameStrings::Radiation, "UseGlobalRadApplicationDelay");
Expand Down Expand Up @@ -286,7 +287,7 @@ void RulesExt::ExtData::Serialize(T& Stm)
.Process(this->ChronoSphereDelay)
.Process(this->AIChronoSphereSW)
.Process(this->AIChronoWarpSW)
.Process(this->SubterraneanUseSpeed)
.Process(this->SubterraneanSpeed)
.Process(this->SubterraneanHeight)
.Process(this->AISuperWeaponDelay)
.Process(this->UseGlobalRadApplicationDelay)
Expand Down
4 changes: 2 additions & 2 deletions src/Ext/Rules/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class RulesExt
Valueable<int> ChronoSphereDelay;
ValueableIdx<SuperWeaponTypeClass> AIChronoSphereSW;
ValueableIdx<SuperWeaponTypeClass> AIChronoWarpSW;
Valueable<bool> SubterraneanUseSpeed;
int SubterraneanSpeed;
Valueable<int> SubterraneanHeight;
Nullable<int> AISuperWeaponDelay;
Valueable<bool> UseGlobalRadApplicationDelay;
Expand Down Expand Up @@ -178,7 +178,7 @@ class RulesExt
, ChronoSphereDelay { 0 }
, AIChronoSphereSW {}
, AIChronoWarpSW {}
, SubterraneanUseSpeed { false }
, SubterraneanSpeed { 19 }
, SubterraneanHeight { -256 }
, AISuperWeaponDelay {}
, UseGlobalRadApplicationDelay { true }
Expand Down
4 changes: 2 additions & 2 deletions src/Ext/TechnoType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->WarpOutWeapon.Read<true>(exINI, pSection, "WarpOutWeapon");
this->WarpInWeapon_UseDistanceAsDamage.Read(exINI, pSection, "WarpInWeapon.UseDistanceAsDamage");

this->SubterraneanUseSpeed.Read(exINI, pSection, "SubterraneanUseSpeed");
exINI.ReadSpeed(pSection, "SubterraneanSpeed", &this->SubterraneanSpeed);
this->SubterraneanHeight.Read(exINI, pSection, "SubterraneanHeight");

this->OreGathering_Anims.Read(exINI, pSection, "OreGathering.Anims");
Expand Down Expand Up @@ -701,7 +701,7 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm)
.Process(this->WarpOutWeapon)
.Process(this->WarpInWeapon_UseDistanceAsDamage)

.Process(this->SubterraneanUseSpeed)
.Process(this->SubterraneanSpeed)
.Process(this->SubterraneanHeight)

.Process(this->OreGathering_Anims)
Expand Down
4 changes: 2 additions & 2 deletions src/Ext/TechnoType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class TechnoTypeExt
Valueable<WeaponTypeClass*> WarpOutWeapon;
Valueable<bool> WarpInWeapon_UseDistanceAsDamage;

Nullable<bool> SubterraneanUseSpeed;
int SubterraneanSpeed;
Nullable<int> SubterraneanHeight;

ValueableVector<AnimTypeClass*> OreGathering_Anims;
Expand Down Expand Up @@ -303,7 +303,7 @@ class TechnoTypeExt
, WarpOutWeapon {}
, WarpInWeapon_UseDistanceAsDamage { false }

, SubterraneanUseSpeed {}
, SubterraneanSpeed { -1 }
, SubterraneanHeight {}

, OreGathering_Anims {}
Expand Down
14 changes: 4 additions & 10 deletions src/Ext/TechnoType/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,7 @@ DEFINE_HOOK(0x711FDF, TechnoTypeClass_RefundAmount_FactoryPlant, 0x8)
return 0;
}


DEFINE_HOOK(0x71464A, TechnoTypeClass_ReadINI_Speed, 0x7)
{
enum { SkipGameCode = 0x71469F };
Expand All @@ -855,16 +856,9 @@ DEFINE_HOOK(0x71464A, TechnoTypeClass_ReadINI_Speed, 0x7)
GET(char*, pSection, EBX);
GET(int, eliteAirstrikeRechargeTime, EAX);

// Restore overridden instructions.
pThis->EliteAirstrikeRechargeTime = eliteAirstrikeRechargeTime;

double parsedSpeed = pINI->ReadDouble(pSection, "Speed", -1.0);

if (parsedSpeed >= 0.0)
{
int speed = Game::F2I((Math::min(parsedSpeed, 100.0) * 256.0) / 100.0);
pThis->Speed = Math::min(speed, 255);
}
pThis->EliteAirstrikeRechargeTime = eliteAirstrikeRechargeTime; // Restore overridden instructions.
INI_EX exINI(pINI);
exINI.ReadSpeed(pSection, "Speed", &pThis->Speed);

return SkipGameCode;
}
25 changes: 13 additions & 12 deletions src/Misc/Hooks.BugFixes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -944,21 +944,22 @@ DEFINE_HOOK(0x7295C5, TunnelLocomotionClass_ProcessDigging_SlowdownDistance, 0x9
GET(TunnelLocomotionClass* const, pLoco, ESI);
GET(int const, distance, EAX);

auto const pTypeExt = TechnoTypeExt::ExtMap.Find(pLoco->LinkedTo->GetTechnoType());
int currentSpeed = 19;

// The movement speed was actually also hardcoded here to 19, so the distance check made sense
// It can now be lifted by setting this key on TechnoType or globally - Starkku
if (pTypeExt->SubterraneanUseSpeed.Get(RulesExt::Global()->SubterraneanUseSpeed))
{
// Subterranean locomotor doesn't normally use this so it would be 0.0 here and cause issues.
pLoco->LinkedTo->SpeedPercentage = 1.0;
currentSpeed = pLoco->LinkedTo->GetCurrentSpeed();
}
// It can now be customized globally or per TechnoType however - Starkku
auto const pType = pLoco->LinkedTo->GetTechnoType();
auto const pTypeExt = TechnoTypeExt::ExtMap.Find(pType);
int speed = pTypeExt->SubterraneanSpeed >= 0 ? pTypeExt->SubterraneanSpeed : RulesExt::Global()->SubterraneanSpeed;

// Calculate speed multipliers.
pLoco->LinkedTo->SpeedPercentage = 1.0; // Subterranean locomotor doesn't normally use this so it would be 0.0 here and cause issues.
int maxSpeed = pType->Speed;
pType->Speed = speed;
speed = pLoco->LinkedTo->GetCurrentSpeed();
pType->Speed = maxSpeed;

TunnelLocomotionClass::TunnelMovementSpeed = currentSpeed;
TunnelLocomotionClass::TunnelMovementSpeed = speed;

return distance >= currentSpeed + 1 ? KeepMoving : CloseEnough;
return distance >= speed + 1 ? KeepMoving : CloseEnough;
}

DEFINE_HOOK(0x75BD70, WalkLocomotionClass_ProcessMoving_SlowdownDistance, 0x9)
Expand Down
14 changes: 14 additions & 0 deletions src/Utilities/INIParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

#include <Phobos.h>
#include <CCINIClass.h>
#include <Unsorted.h>

class INI_EX
{
Expand Down Expand Up @@ -151,6 +152,19 @@ class INI_EX
return (*nBuffer != -1);
}

bool ReadSpeed(const char* pSection, const char* pKey, int* nBuffer)
{
double parsedSpeed = IniFile->ReadDouble(pSection, pKey, -1.0);

if (parsedSpeed >= 0.0)
{
int speed = Game::F2I((Math::min(parsedSpeed, 100.0) * 256.0) / 100.0);
*nBuffer = Math::min(speed, 255);
}

return (*nBuffer != -1);
}

bool ParseStringList(std::vector<std::string>& values, const char* pSection, const char* pKey)
{
if (this->ReadString(pSection, pKey))
Expand Down

0 comments on commit b493c41

Please sign in to comment.