Skip to content

Commit 5869392

Browse files
committed
Allow using <Player @ X> as trigger owner in skirmish/MP
1 parent 06e1076 commit 5869392

File tree

8 files changed

+101
-3
lines changed

8 files changed

+101
-3
lines changed

CREDITS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ This page lists all the individual contributions to the project by their author.
269269
- Build area customizations
270270
- `Scorch` / `Flamer` fire animation customization
271271
- EM Pulse cannon logic improvements
272-
- `<Player @ X>` as owner for pre-placed objects
272+
- `<Player @ X>` as owner for pre-placed objects and triggers
273273
- Custom exit cell for infantry factory
274274
- Vehicles keeping target on move command
275275
- `IsSonic` wave drawing crash fix

YRpp

docs/AI-Scripting-and-Mapping.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ This page describes all AI scripting and mapping related additions and changes i
44

55
## Bugfixes and Miscellanous
66

7+
- `<Player @ X>` can now be used as owner for pre-placed objects as well as owner for triggers on skirmish and multiplayer maps. Triggers with owners that are not present in the game are destroyed and never sprung.
78
- Script action `Move to cell` now obeys YR cell calculation now. Using `1000 * Y + X` as its cell value. (was `128 * Y + X` as it's a RA1 leftover)
89
- The game now can reads waypoints ranges in [0, 2147483647]. (was [0,701])
910
- Map trigger action `41 Play Animation At...` can now create 'non-inert' animations which can play sounds, deal damage and apply `TiberiumChainReaction` if a parameter is set (needs [following changes to `fadata.ini`](Whats-New.md#for-map-editor-final-alert-2)).

docs/Fixed-or-Improved-Logics.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
167167
- Certain global tileset indices (`ShorePieces`, `WaterSet`, `CliffSet`, `WaterCliffs`, `WaterBridge`, `BridgeSet` and `WoodBridgeSet`) can now be toggled to be parsed for lunar theater by setting `[General] -> ApplyLunarFixes` to true in `lunarmd.ini`. Do note that enabling this without fixing f.ex `WoodBridgeTileSet` pointing to a tileset with `TilesInSet=0` will cause issues in-game.
168168
- Fixed infantry `SecondaryFire` / `SecondaryProne` sequences being displayed in water instead of `WetAttack`.
169169
- Fixed objects with ally target and `AttackFriendlies=true` having their target reset every frame, particularly AI-owned buildings.
170-
- `<Player @ X>` can now be used as owner for pre-placed objects on skirmish and multiplayer maps.
171170
- Follower vehicle index for preplaced vehicles in maps is now explicitly constrained to `[Units]` list in map files and is no longer thrown off by vehicles that could not be created or created vehicles having other vehicles as initial passengers.
172171
- Drive/Jumpjet/Ship/Teleport locomotor did not power on when it is un-piggybacked bugfix
173172
- Stop command (`[S]` by default) behavior is now more correct:

docs/Whats-New.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ New:
458458
- Fast access structure (by FlyStar)
459459
- Toggle off laser trail and shake effects (by Ollerus)
460460
- [Dehardcode the `ZAdjust` of warhead anim](Fixed-or-Improved-Logics.md#dehardcode-the-zadjust-of-warhead-anim) (by TaranDahl)
461+
- `<Player @ X>` can now be used as owner for triggers on skirmish and multiplayer maps (by Starkku)
461462
462463
Vanilla fixes:
463464
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)

src/Ext/Scenario/Body.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ void ScenarioExt::ExtData::Serialize(T& Stm)
168168
.Process(this->DefaultLS800BkgdName)
169169
.Process(this->DefaultLS800BkgdPal)
170170
.Process(this->LimboLaunchers)
171+
.Process(this->TriggerTypePlayerAtXOwners)
171172
.Process(this->UndergroundTracker)
172173
.Process(this->SpecialTracker)
173174
.Process(this->FallingDownTracker)
@@ -198,6 +199,7 @@ DEFINE_HOOK(0x683549, ScenarioClass_CTOR, 0x9)
198199
ScenarioExt::Global()->Waypoints.clear();
199200
ScenarioExt::Global()->Variables[0].clear();
200201
ScenarioExt::Global()->Variables[1].clear();
202+
ScenarioExt::Global()->TriggerTypePlayerAtXOwners.clear();
201203

202204
return 0;
203205
}

src/Ext/Scenario/Body.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ class ScenarioExt
4848

4949
std::vector<TechnoExt::ExtData*> LimboLaunchers;
5050

51+
std::map<int, int> TriggerTypePlayerAtXOwners; // TriggerTypeClass ArrayIndex -> Player slot index
52+
5153
DynamicVectorClass<TechnoClass*> UndergroundTracker; // Technos that are underground.
5254
DynamicVectorClass<TechnoClass*> SpecialTracker; // For special purposes, like tracking technos that are forced moving. Currently unused.
5355
DynamicVectorClass<TechnoClass*> FallingDownTracker; // Technos that are falling down, parachutes and land technos falling from bridge.
@@ -66,6 +68,7 @@ class ScenarioExt
6668
, DefaultLS800BkgdName {}
6769
, DefaultLS800BkgdPal {}
6870
, LimboLaunchers {}
71+
, TriggerTypePlayerAtXOwners {}
6972
, UndergroundTracker {}
7073
, SpecialTracker {}
7174
, FallingDownTracker {}

src/Ext/Trigger/Hooks.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include <TriggerClass.h>
2+
#include <TriggerTypeClass.h>
23

34
#include <Helpers/Macro.h>
45

6+
#include <Ext/Scenario/Body.h>
57
#include <Ext/TEvent/Body.h>
68

79
DEFINE_HOOK(0x727064, TriggerTypeClass_HasLocalSetOrClearedEvent, 0x5)
@@ -27,3 +29,93 @@ DEFINE_HOOK(0x727024, TriggerTypeClass_HasGlobalSetOrClearedEvent, 0x5)
2729
? 0x72702E
2830
: 0x727029;
2931
}
32+
33+
#pragma region PlayerAtX
34+
35+
// Store player slot index for trigger type if such value is used in scenario INI.
36+
DEFINE_HOOK(0x727292, TriggerTypeClass_ReadINI_PlayerAtX, 0x5)
37+
{
38+
GET(TriggerTypeClass*, pThis, EBP);
39+
GET(const char*, pID, ESI);
40+
41+
// Bail out early in campaign mode or if the name does not start with <
42+
if (SessionClass::IsCampaign() || *pID != '<')
43+
return 0;
44+
45+
const int playerAtIndex = HouseClass::GetPlayerAtFromString(pID);
46+
47+
if (playerAtIndex != -1)
48+
{
49+
ScenarioExt::Global()->TriggerTypePlayerAtXOwners.emplace(pThis->ArrayIndex, playerAtIndex);
50+
51+
// Override the name to prevent Ares whining about non-existing HouseType names.
52+
R->ESI(NONE_STR);
53+
}
54+
55+
return 0;
56+
}
57+
58+
// Handle mapping player slot index for trigger to HouseClass pointer in logic.
59+
DEFINE_HOOK_AGAIN(0x7265F7, TriggerClass_Logic_PlayerAtX, 0x6)
60+
DEFINE_HOOK(0x72652D, TriggerClass_Logic_PlayerAtX, 0x6)
61+
{
62+
enum { SkipGameCode1 = 0x726538, SkipGameCode2 = 0x726602};
63+
64+
GET(TriggerTypeClass*, pType, EDX);
65+
66+
if (SessionClass::IsCampaign())
67+
return 0;
68+
69+
auto const& triggerOwners = ScenarioExt::Global()->TriggerTypePlayerAtXOwners;
70+
auto it = triggerOwners.find(pType->ArrayIndex);
71+
72+
if (it != triggerOwners.end())
73+
{
74+
if (auto const pHouse = HouseClass::FindByPlayerAt(it->second))
75+
{
76+
R->EAX(pHouse);
77+
return R->Origin() == 0x72652D ? SkipGameCode1 : SkipGameCode2;
78+
}
79+
}
80+
81+
return 0;
82+
}
83+
84+
// Destroy triggers with Player @ X owners if they are not present in scenario.
85+
DEFINE_HOOK(0x725FC7, TriggerClass_CTOR_PlayerAtX, 0x7)
86+
{
87+
GET(TriggerClass*, pThis, ESI);
88+
89+
if (SessionClass::IsCampaign())
90+
return 0;
91+
92+
auto& triggerOwners = ScenarioExt::Global()->TriggerTypePlayerAtXOwners;
93+
auto it = triggerOwners.find(pThis->Type->ArrayIndex);
94+
95+
if (it != triggerOwners.end())
96+
{
97+
if (!HouseClass::FindByPlayerAt(it->second))
98+
pThis->Destroy();
99+
}
100+
101+
return 0;
102+
}
103+
104+
// Remove destroyed triggers from the map.
105+
DEFINE_HOOK(0x726727, TriggerClass_Destroy_PlayerAtX, 0x5)
106+
{
107+
GET(TriggerClass*, pThis, ESI);
108+
109+
if (SessionClass::IsCampaign())
110+
return 0;
111+
112+
auto& triggerOwners = ScenarioExt::Global()->TriggerTypePlayerAtXOwners;
113+
auto it = triggerOwners.find(pThis->Type->ArrayIndex);
114+
115+
if (it != triggerOwners.end())
116+
triggerOwners.erase(it);
117+
118+
return 0;
119+
}
120+
121+
#pragma endregion

0 commit comments

Comments
 (0)