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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Credits
- **ChrisLv_CN** - interceptor logic, LaserTrails, laser fixes, general assistance (work relicensed under [following permission](images/ChrisLv-relicense.png))
- **Xkein** - general assistance, YRpp edits
- **thomassneddon** - general assistance
- **Starkku** - Warhead shield penetration & breaking, strafing aircraft weapon customization, vehicle DeployFire fixes/improvements, stationary VehicleTypes, Burst logic improvements, TechnoType auto-firing weapons, Secondary weapon fallback customization, weapon target type filtering, AreaFire targeting customization, CreateUnit improvements, Attached animation & jumpjet unit layer customization, IsSimpleDeployer improvements, Shield modification warheads, Warhead decloaking toggle, Warp(In/Out)Weapon, Grinder improvements / additions, Attached animation position customization, Critical hit logic additions, Aircraft & jumpjet speed modifiers fix, Local warhead screen shaking, Vehicle custom palette fix
- **Starkku** - Warhead shield penetration & breaking, strafing aircraft weapon customization, vehicle DeployFire fixes/improvements, stationary VehicleTypes, Burst logic improvements, TechnoType auto-firing weapons, Secondary weapon fallback customization, weapon target type filtering, AreaFire targeting customization, CreateUnit improvements, Attached animation & jumpjet unit layer customization, IsSimpleDeployer improvements, Shield modification warheads, Warhead decloaking toggle, Warp(In/Out)Weapon, Grinder improvements / additions, Attached animation position customization, Critical hit logic additions, Aircraft & jumpjet speed modifiers fix, Local warhead screen shaking, Vehicle custom palette fix, Weapon owner detachment, Feedback weapon
- **SukaHati (Erzoid)** - Minimum interceptor guard range
- **Morton (MortonPL)** - XDrawOffset, Shield passthrough & absorption, building LimboDelivery, fix for Image in art rules, power delta counter
- **mevitar** - honorary shield tester *triple* award
Expand Down
13 changes: 13 additions & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Fixed Engineers being able to enter `Grinding` buildings even when they shouldn't (such as ally building at full HP).
- Aircraft & jumpjet units are now affected by speed modifiers such as `SpeedAircraft/Infantry/UnitsMult` on `Countries`, `VeteranSpeed` and Crates / AttachEffect (Ares feature).
- Both voxel and SHP vehicle units should now correctly respect custom palette set through `Palette`.
- Weapons fired by EMPulse superweapons without `EMPulse.TargetSelf=true` *(Ares feature)* can now create radiation.

## Animations

Expand Down Expand Up @@ -285,6 +286,18 @@ Bolt.Disable2=false ; boolean
Bolt.Disable3=false ; boolean
```

### Detaching weapon from owner TechnoType

- You can now control if weapon is detached from the TechnoType that fired it. This results in the weapon / warhead being able to damage the TechnoType itself even if it does not have `DamageSelf=true` set, but also treats it as if owned by no house or object, meaning any ownership-based checks like `AffectsAllies` do not function as expected and no experience is awarded.
- The effect of this is inherited through `AirburstWeapon` and `ShrapnelWeapon`.
- This does not affect projectile image or functionality or `FirersPalette` on initially fired weapon, but `FirersPalette` will not function for any weapons inheriting the effect.

In `rulesmd.ini`:
```ini
[SOMEWEAPONTYPE] ; WeaponType
DetachedFromOwner=false ; boolean
```

## Projectiles

### Customizable projectile gravity
Expand Down
40 changes: 24 additions & 16 deletions docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -453,35 +453,32 @@ In `rulesmd.ini`:
ForceWeapon.Naval.Decloaked=-1 ; Integer. 0 for primary weapon, 1 for secondary weapon
```

## Terrains

### Destroy animation & sound

- You can now specify a destroy animation and sound for a TerrainType that are played when it is destroyed.

In `rulesmd.ini`:
```ini
[SOMETERRAINTYPE] ; TerrainType
DestroyAnim= ; Animation
DestroySound= ; Sound
```

### Weapons fired on warping in / out

- It is now possible to add weapons that are fired on a teleporting TechnoType when it warps in or out. They are at the same time as the appropriate animations (`WarpIn` / `WarpOut`) are displayed.
- `WarpInMinRangeWeapon` is used instead of `WarpInWeapon` if the distance traveled (in leptons) was less than `ChronoRangeMinimum`. This works regardless of if `ChronoTrigger` is set or not. If `WarpInMinRangeWeapon` is not set, it defaults to `WarpInWeapon`.
- If `WarpInWeapon.UseDistanceAsDamage` is set, `Damage` of `WarpIn(MinRange)Weapon` is overriden by the number of whole cells teleported across.
- `WarpInWeapon.FireAsSelf` & `WarpOutWeapon.FireAsSelf` can be used to disable firing the weapon with the teleporting TechnoType as an owner. This allows damaging itself, but also makes certain Weapon or Warhead features reliant on owner not available.

In `rulesmd.ini`:
```ini
[SOMETECHNO] ; TechnoType
WarpInWeapon= ; WeaponType
WarpInMinRangeWeapon= ; WeaponType
WarpInWeapon.UseDistanceAsDamage=false ; boolean
WarpInWeapon.FireAsSelf=true ; boolean
WarpOutWeapon= ; WeaponType
WarpOutWeapon.FireAsSelf=true ; boolean
```

## Terrains

### Destroy animation & sound

- You can now specify a destroy animation and sound for a TerrainType that are played when it is destroyed.

In `rulesmd.ini`:
```ini
[SOMETERRAINTYPE] ; TerrainType
DestroyAnim= ; Animation
DestroySound= ; Sound
```

## Weapons
Expand Down Expand Up @@ -551,6 +548,17 @@ In `rulesmd.ini`:
AreaFire.Target=base ; AreaFire Target Enumeration (base|self|random)
```

### Feedback weapon

- You can now specify an auxiliary weapon to be fired on the firer itself when a weapon is fired.
- `FireInTransport` setting of the feedback weapon is respected to determine if it can be fired when the original weapon is fired from inside `OpenTopped=true` transport. If feedback weapon is fired, it is fired on the transport. `OpenToppedDamageMultiplier` is not applied on feedback weapons.

In `rulesmd.ini`:
```ini
[SOMEWEAPON] ; WeaponType
FeedbackWeapon= ; WeaponType
```

## Warheads

```{hint}
Expand Down
2 changes: 2 additions & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ New:
- Additional critical hit logic customizations (by Starkku)
- Laser trails for VoxelAnims (by Otamaa)
- Local warhead screen shaking (by Starkku)
- Weapon owner detachment (by Starkku)
- Feedback weapon (by Starkku)

Vanilla fixes:
- Fixed laser drawing code to allow for thicker lasers in house color draw mode (by Kerbiter, ChrisLv_CN)
Expand Down
12 changes: 12 additions & 0 deletions src/Ext/Building/Hooks.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Body.h"

#include <BulletClass.h>
#include <UnitClass.h>

DEFINE_HOOK(0x7396D2, UnitClass_TryToDeploy_Transfer, 0x5)
Expand Down Expand Up @@ -69,3 +70,14 @@ DEFINE_HOOK(0x4401BB, Factory_AI_PickWithFreeDocks, 0x6)

return 0;
}


DEFINE_HOOK(0x44D455, BuildingClass_Mission_Missile_EMPPulseBulletWeapon, 0x8)
{
GET(WeaponTypeClass*, pWeapon, EBP);
GET_STACK(BulletClass*, pBullet, STACK_OFFS(0xF0, 0xA4));

pBullet->SetWeaponType(pWeapon);

return 0;
}
25 changes: 21 additions & 4 deletions src/Ext/Bullet/Hooks.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "Body.h"
#include <Ext/WeaponType/Body.h>
#include <Ext/WarheadType/Body.h>
#include <Ext/BulletType/Body.h>
#include <Misc/CaptureManager.h>
Expand Down Expand Up @@ -38,7 +39,8 @@ DEFINE_HOOK(0x4666F7, BulletClass_AI, 0x6)
pThis->WeaponType &&
pThis->WeaponType->LimboLaunch;

if (isLimbo) {
if (isLimbo)
{
pThis->SetTarget(nullptr);
auto damage = pTechno->Health * 2;
pTechno->SetLocation(pThis->GetCoords());
Expand All @@ -65,7 +67,7 @@ DEFINE_HOOK(0x4666F7, BulletClass_AI, 0x6)
(int)(location.Z + velocity.Z)
};

for (auto const& trail: pBulletExt->LaserTrails)
for (auto const& trail : pBulletExt->LaserTrails)
{
// We insert initial position so the first frame of trail doesn't get skipped - Kerbiter
// TODO move hack to BulletClass creation
Expand Down Expand Up @@ -183,9 +185,9 @@ DEFINE_HOOK(0x46A3D6, BulletClass_Shrapnel_Forced, 0xA)
enum { Shrapnel = 0x46A40C, Skip = 0x46ADCD };

GET(BulletClass*, pBullet, EDI);

auto const pData = BulletTypeExt::ExtMap.Find(pBullet->Type);

if (auto const pObject = pBullet->GetCell()->FirstObject)
{
if (pObject->WhatAmI() != AbstractType::Building || pData->Shrapnel_AffectsBuildings)
Expand All @@ -212,5 +214,20 @@ DEFINE_HOOK(0x4690D4, BulletClass_Logics_ScreenShake, 0x6)
return SkipShaking;
}

return 0;
}

DEFINE_HOOK(0x4690C1, BulletClass_Logics_DetachFromOwner, 0x8)
{
GET(BulletClass*, pThis, ESI);

if (pThis->Owner && pThis->WeaponType)
{
auto pWeaponExt = WeaponTypeExt::ExtMap.Find(pThis->WeaponType);

if (pWeaponExt->DetachedFromOwner)
pThis->Owner = nullptr;
}

return 0;
}
37 changes: 29 additions & 8 deletions src/Ext/Techno/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,12 @@ DEFINE_HOOK(0x518505, InfantryClass_TakeDamage_NotHuman, 0x4)

DEFINE_HOOK(0x5218F3, InfantryClass_WhatWeaponShouldIUse_DeployFireWeapon, 0x6)
{
GET(TechnoTypeClass*, pType, ECX);
GET(TechnoTypeClass*, pType, ECX);

if (pType->DeployFireWeapon == -1)
return 0x52194E;
if (pType->DeployFireWeapon == -1)
return 0x52194E;

return 0;
return 0;
}

// Customizable OpenTopped Properties
Expand Down Expand Up @@ -355,7 +355,7 @@ DEFINE_HOOK(0x71067B, TechnoClass_EnterTransport_LaserTrails, 0x7)

if (pTechnoExt && pTechnoTypeExt)
{
for (auto &pLaserTrail : pTechnoExt->LaserTrails)
for (auto& pLaserTrail : pTechnoExt->LaserTrails)
{
pLaserTrail->Visible = false;
pLaserTrail->LastLocation = { };
Expand All @@ -372,7 +372,7 @@ DEFINE_HOOK(0x5F4F4E, ObjectClass_Unlimbo_LaserTrails, 0x7)
auto pTechnoExt = TechnoExt::ExtMap.Find(pTechno);
if (pTechnoExt)
{
for (auto &pLaserTrail : pTechnoExt->LaserTrails)
for (auto& pLaserTrail : pTechnoExt->LaserTrails)
{
pLaserTrail->LastLocation = { };
pLaserTrail->Visible = true;
Expand Down Expand Up @@ -402,8 +402,8 @@ DEFINE_HOOK(0x6F3428, TechnoClass_GetWeapon_ForceWeapon, 0x6)

if (auto pTechnoTypeExt = TechnoTypeExt::ExtMap.Find(pTechnoType))
{
if (pTechnoTypeExt->ForceWeapon_Naval_Decloaked >= 0
&& pTargetType->Cloakable && pTargetType->Naval
if (pTechnoTypeExt->ForceWeapon_Naval_Decloaked >= 0
&& pTargetType->Cloakable && pTargetType->Naval
&& pTarget->CloakState == CloakState::Uncloaked)
{
R->EAX(pTechnoTypeExt->ForceWeapon_Naval_Decloaked);
Expand All @@ -424,3 +424,24 @@ DEFINE_HOOK(0x6FB086, TechnoClass_Reload_ReloadAmount, 0x8)

return 0;
}

DEFINE_HOOK(0x6FF43F, TechnoClass_FireAt_FeedbackWeapon, 0x6)
{
GET(TechnoClass*, pThis, ESI);
GET(WeaponTypeClass*, pWeapon, EBX);

if (auto pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeapon))
{
if (pWeaponExt->FeedbackWeapon.isset())
{
auto fbWeapon = pWeaponExt->FeedbackWeapon.Get();

if (pThis->InOpenToppedTransport && !fbWeapon->FireInTransport)
return 0;

WeaponTypeExt::DetonateAt(fbWeapon, pThis, pThis);
}
}

return 0;
}
4 changes: 0 additions & 4 deletions src/Ext/TechnoType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->WarpInMinRangeWeapon.Read(exINI, pSection, "WarpInMinRangeWeapon", true);
this->WarpOutWeapon.Read(exINI, pSection, "WarpOutWeapon", true);
this->WarpInWeapon_UseDistanceAsDamage.Read(exINI, pSection, "WarpInWeapon.UseDistanceAsDamage");
this->WarpInWeapon_FireAsSelf.Read(exINI, pSection, "WarpInWeapon.FireAsSelf");
this->WarpOutWeapon_FireAsSelf.Read(exINI, pSection, "WarpOutWeapon.FireAsSelf");

this->OreGathering_Anims.Read(exINI, pSection, "OreGathering.Anims");
this->OreGathering_Tiberiums.Read(exINI, pSection, "OreGathering.Tiberiums");
Expand Down Expand Up @@ -271,8 +269,6 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm)
.Process(this->WarpInMinRangeWeapon)
.Process(this->WarpOutWeapon)
.Process(this->WarpInWeapon_UseDistanceAsDamage)
.Process(this->WarpInWeapon_FireAsSelf)
.Process(this->WarpOutWeapon_FireAsSelf)
.Process(this->OreGathering_Anims)
.Process(this->OreGathering_Tiberiums)
.Process(this->OreGathering_FramesPerDir)
Expand Down
4 changes: 0 additions & 4 deletions src/Ext/TechnoType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ class TechnoTypeExt
Nullable<WeaponTypeClass*> WarpInMinRangeWeapon;
Nullable<WeaponTypeClass*> WarpOutWeapon;
Valueable<bool> WarpInWeapon_UseDistanceAsDamage;
Valueable<bool> WarpInWeapon_FireAsSelf;
Valueable<bool> WarpOutWeapon_FireAsSelf;

ValueableVector<AnimTypeClass*> OreGathering_Anims;
ValueableVector<int> OreGathering_Tiberiums;
Expand Down Expand Up @@ -158,8 +156,6 @@ class TechnoTypeExt
, WarpInMinRangeWeapon {}
, WarpOutWeapon {}
, WarpInWeapon_UseDistanceAsDamage { false }
, WarpInWeapon_FireAsSelf { true }
, WarpOutWeapon_FireAsSelf { true }
, OreGathering_Anims {}
, OreGathering_Tiberiums {}
, OreGathering_FramesPerDir {}
Expand Down
4 changes: 2 additions & 2 deletions src/Ext/TechnoType/Hooks.Teleport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ DEFINE_HOOK(0x719439, TeleportLocomotionClass_ILocomotion_Process_WarpoutAnim, 0
R->EDX<AnimTypeClass*>(pExt->WarpOut.Get(RulesClass::Instance->WarpOut));

if (pExt->WarpOutWeapon.isset())
WeaponTypeExt::DetonateAt(pExt->WarpOutWeapon.Get(), pLocomotor->LinkedTo, pExt->WarpOutWeapon_FireAsSelf ? pLocomotor->LinkedTo : nullptr);
WeaponTypeExt::DetonateAt(pExt->WarpOutWeapon.Get(), pLocomotor->LinkedTo, pLocomotor->LinkedTo);

return 0x71943F;
}
Expand All @@ -39,7 +39,7 @@ DEFINE_HOOK(0x719788, TeleportLocomotionClass_ILocomotion_Process_WarpInAnim, 0x
if (weaponType)
{
int damage = pExt->WarpInWeapon_UseDistanceAsDamage ? pTechnoExt->LastWarpDistance / 256 : weaponType->Damage;
WeaponTypeExt::DetonateAt(weaponType, pLocomotor->LinkedTo, pExt->WarpInWeapon_FireAsSelf ? pLocomotor->LinkedTo : nullptr, damage);
WeaponTypeExt::DetonateAt(weaponType, pLocomotor->LinkedTo, pLocomotor->LinkedTo, damage);
}

return 0x71978E;
Expand Down
4 changes: 4 additions & 0 deletions src/Ext/WeaponType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ void WeaponTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->CanTargetHouses.Read(exINI, pSection, "CanTargetHouses");
this->Burst_Delays.Read(exINI, pSection, "Burst.Delays");
this->AreaFire_Target.Read(exINI, pSection, "AreaFire.Target");
this->DetachedFromOwner.Read(exINI, pSection, "DetachedFromOwner");
this->FeedbackWeapon.Read(exINI, pSection, "FeedbackWeapon", true);
}

template <typename T>
Expand All @@ -63,6 +65,8 @@ void WeaponTypeExt::ExtData::Serialize(T& Stm)
.Process(this->RadType)
.Process(this->Burst_Delays)
.Process(this->AreaFire_Target)
.Process(this->DetachedFromOwner)
.Process(this->FeedbackWeapon)
;
};

Expand Down
4 changes: 4 additions & 0 deletions src/Ext/WeaponType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class WeaponTypeExt
Valueable<AffectedHouse> CanTargetHouses;
ValueableVector<int> Burst_Delays;
Valueable<AreaFireTarget> AreaFire_Target;
Valueable<bool> DetachedFromOwner;
Nullable<WeaponTypeClass*> FeedbackWeapon;

ExtData(WeaponTypeClass* OwnerObject) : Extension<WeaponTypeClass>(OwnerObject)
, DiskLaser_Radius { 38.2 }
Expand All @@ -45,6 +47,8 @@ class WeaponTypeExt
, CanTargetHouses { AffectedHouse::All }
, Burst_Delays {}
, AreaFire_Target { AreaFireTarget::Base }
, DetachedFromOwner { false }
, FeedbackWeapon {}
{ }

virtual ~ExtData() = default;
Expand Down