Skip to content

Commit 767cb32

Browse files
committed
🐛 Fixed hook/tie/rope glitches.
PROBLEMS: * when you release a load from a hook (be it by pressing L or Hard-resetting), the skeletonview and physics paused states don't get reset. In 2022.12 it's the same except physicspause does get reset when unhooking by L (not by hardreset tho.). * when you release a load from ties using O key, skeleton view gets reset, but physics-pause does not. Also when you hard reset, everything remains dirty. 2022.12 behaves the same. * When you Hard-reset or delete a vehicle with hooks/ties attached, they are not removed correctly, potentially causing a crash. The `DisjoinInterActorBeams()` helper (used by SyncReset() and Actor destructor) was leaving data in inconsistent state - specifically, it properly removed the inter-beams themselves and linkage records (both the per-actor and global lists), but it didn't update the `tie_t/hook_t/rope_t` objects itself - these kept pointing to the deleted/reset actor. SOLUTIONS: * Remake the actor-linking code to track when 2 actors become linked/unlinked - and sync the sekeletonview & physicspause there. * Instead of employing custom code to do Hard-reset, extend the existing (old!) `hookToggle()/tieToggle()/ropeToggle()` funcs (used for regular locking/unlocking of those elements) to also do forced unlocking upon removing/SyncReset-ing an actor, and then modify `DisjoinInterActorBeams()` to use them. DEV NOTE: This is quite a significant remake of actor-linking code; a direct follow-up to d36c4ec which introduced ✉️ MSG_SIM_ACTOR_LINKING_REQUESTED. A remake was needed because there was no single spot to correctly reset the skeleton/physicspause on actor unlink - there was simply no concept of "actors were just linked/unlinked". While researching how to add it, I realized scripts may want to know when that happens, so I added a script event `SE_GENERIC_TRUCK_LINKING_CHANGED` for it. Keep in mind there can be multiple interlinking beams at the same time, so not every added/removed beam means linking changes. The new event also helps navigate the codebase and documents how stuff works. CODECHANGES: * Functions `[Add/Remove]InterActorBeam()` moved from Actor.cpp to ActorManager.cpp and signifficantly rewritten, adding a lot of safety checks. * SimData.h: the ActorLinkingRequestType enum was merged with HookAction enum and got new fields: HOOK_RESET, TIE_RESET, ROPE_RESET * Actor.h: `hookToggle()/tieToggle()/ropeToggle()` funcs got new parameter `forceunlock_filter` and all now accept ActorLinkingRequestType param; deleted func DetermineLinkedActors() as no longer needed for `DisjoinInterActorBeams()` * ScriptEvents.h - added SE_GENERIC_TRUCK_LINKING_CHANGED * All other files are just fallout from changes above.
1 parent c017ad8 commit 767cb32

14 files changed

+341
-316
lines changed

doc/angelscript/Script2Game/globals.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ void print(const string message);
7575

7676
SE_GENERIC_MESSAGEBOX_CLICK //!< triggered when the user clicks on a message box button, the argument refers to the button pressed
7777
SE_GENERIC_EXCEPTION_CAUGHT //!< Triggered when C++ exception (usually Ogre::Exception) is thrown; #1 ScriptUnitID, #5 originFuncName, #6 type, #7 message.
78-
SE_GENERIC_MODCACHE_ACTIVITY //!< Triggered when status of modcache changes, args: #1 type, #2 entry number, for other args see `RoR::modCacheActivityType`
78+
SE_GENERIC_MODCACHE_ACTIVITY //!< Triggered when status of modcache changes, args: #1 type, #2 entry number, for other args see `RoR::modCacheActivityType`
79+
80+
SE_GENERIC_TRUCK_LINKING_CHANGED //!< Triggered when 2 actors become linked or unlinked via ties/hooks/ropes/slidenodes; args: #1 action (1=linked, 0=unlinked), #2 link type `ActorLinkingRequestType` (will be INVALID on savegame load or forced unlink when deleting actor) #3 master ActorInstanceID_t, #4 slave ActorInstanceID_t
7981

8082
SE_ALL_EVENTS = 0xffffffff,
8183
SE_NO_EVENTS = 0

source/main/GameContext.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -1367,21 +1367,20 @@ void GameContext::UpdateCommonInputEvents(float dt)
13671367
{
13681368
//m_player_actor->hookToggle(-1, HOOK_TOGGLE, -1);
13691369
ActorLinkingRequest* hook_rq = new ActorLinkingRequest();
1370-
hook_rq->alr_type = ActorLinkingRequestType::HOOK_ACTION;
1370+
hook_rq->alr_type = ActorLinkingRequestType::HOOK_TOGGLE;
13711371
hook_rq->alr_actor_instance_id = m_player_actor->ar_instance_id;
1372-
hook_rq->alr_hook_action = HOOK_TOGGLE;
13731372
App::GetGameContext()->PushMessage(Message(MSG_SIM_ACTOR_LINKING_REQUESTED, hook_rq));
13741373

13751374
//m_player_actor->toggleSlideNodeLock();
13761375
ActorLinkingRequest* slidenode_rq = new ActorLinkingRequest();
1377-
slidenode_rq->alr_type = ActorLinkingRequestType::SLIDENODE_ACTION;
1376+
slidenode_rq->alr_type = ActorLinkingRequestType::SLIDENODE_TOGGLE;
13781377
hook_rq->alr_actor_instance_id = m_player_actor->ar_instance_id;
13791378
App::GetGameContext()->PushMessage(Message(MSG_SIM_ACTOR_LINKING_REQUESTED, slidenode_rq));
13801379
}
13811380

13821381
if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_AUTOLOCK))
13831382
{
1384-
m_player_actor->hookToggle(-2, HOOK_UNLOCK, -1); //unlock all autolocks
1383+
m_player_actor->hookToggle(-2, ActorLinkingRequestType::HOOK_UNLOCK, -1); //unlock all autolocks
13851384
}
13861385

13871386
//strap

source/main/gameplay/SceneMouse.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,10 @@ bool SceneMouse::mouseMoved(const OIS::MouseEvent& _arg)
165165
{
166166
if (it->hk_hook_node->pos == minnode)
167167
{
168-
//grab_truck->hookToggle(it->hk_group, MOUSE_HOOK_TOGGLE, minnode);
168+
//grab_truck->hookToggle(it->hk_group, HOOK_MOUSE_TOGGLE, minnode);
169169
ActorLinkingRequest* rq = new ActorLinkingRequest();
170-
rq->alr_type = ActorLinkingRequestType::HOOK_ACTION;
170+
rq->alr_type = ActorLinkingRequestType::HOOK_MOUSE_TOGGLE;
171171
rq->alr_actor_instance_id = grab_truck->ar_instance_id;
172-
rq->alr_hook_action = MOUSE_HOOK_TOGGLE;
173172
rq->alr_hook_group = it->hk_group;
174173
rq->alr_hook_mousenode = minnode;
175174
App::GetGameContext()->PushMessage(Message(MSG_SIM_ACTOR_LINKING_REQUESTED, rq));

source/main/gameplay/ScriptEvents.h

+2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ enum scriptEvents
6161
SE_GENERIC_EXCEPTION_CAUGHT = BITMASK(24), //!< Triggered when C++ exception (usually Ogre::Exception) is thrown; #1 ScriptUnitID, #5 originFuncName, #6 type, #7 message.
6262
SE_GENERIC_MODCACHE_ACTIVITY = BITMASK(25), //!< Triggered when status of modcache changes, args: #1 type, #2 entry number, for other args see `RoR::modCacheActivityType`
6363

64+
SE_GENERIC_TRUCK_LINKING_CHANGED = BITMASK(26), //!< Triggered when 2 actors become linked or unlinked via ties/hooks/ropes/slidenodes; args: #1 action (1=linked, 0=unlinked), #2 link type `ActorLinkingRequestType` (will be INVALID on savegame load or forced unlink when deleting actor) #3 master ActorInstanceID_t, #4 slave ActorInstanceID_t
65+
6466
SE_ALL_EVENTS = 0xffffffff,
6567
SE_NO_EVENTS = 0
6668

source/main/gui/panels/GUI_VehicleButtons.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -1183,14 +1183,13 @@ void VehicleButtons::DrawLockButton(RoR::GfxActor* actorx)
11831183
{
11841184
//actorx->GetActor()->hookToggle(-1, HOOK_TOGGLE, -1);
11851185
ActorLinkingRequest* hook_rq = new ActorLinkingRequest();
1186-
hook_rq->alr_type = ActorLinkingRequestType::HOOK_ACTION;
1186+
hook_rq->alr_type = ActorLinkingRequestType::HOOK_TOGGLE;
11871187
hook_rq->alr_actor_instance_id = actorx->GetActor()->ar_instance_id;
1188-
hook_rq->alr_hook_action = HOOK_TOGGLE;
11891188
App::GetGameContext()->PushMessage(Message(MSG_SIM_ACTOR_LINKING_REQUESTED, hook_rq));
11901189

11911190
//actorx->GetActor()->toggleSlideNodeLock();
11921191
ActorLinkingRequest* slidenode_rq = new ActorLinkingRequest();
1193-
slidenode_rq->alr_type = ActorLinkingRequestType::SLIDENODE_ACTION;
1192+
slidenode_rq->alr_type = ActorLinkingRequestType::SLIDENODE_TOGGLE;
11941193
hook_rq->alr_actor_instance_id = actorx->GetActor()->ar_instance_id;
11951194
App::GetGameContext()->PushMessage(Message(MSG_SIM_ACTOR_LINKING_REQUESTED, slidenode_rq));
11961195
}

source/main/main.cpp

+11-8
Original file line numberDiff line numberDiff line change
@@ -1142,23 +1142,26 @@ int main(int argc, char *argv[])
11421142
{
11431143
switch (request->alr_type)
11441144
{
1145-
case ActorLinkingRequestType::HOOK_ACTION:
1146-
actor->hookToggle(request->alr_hook_group, request->alr_hook_action, request->alr_hook_mousenode);
1147-
if (request->alr_hook_action == MOUSE_HOOK_TOGGLE)
1148-
{
1145+
case ActorLinkingRequestType::HOOK_LOCK:
1146+
case ActorLinkingRequestType::HOOK_UNLOCK:
1147+
case ActorLinkingRequestType::HOOK_TOGGLE:
1148+
actor->hookToggle(request->alr_hook_group, request->alr_type);
1149+
break;
1150+
1151+
case ActorLinkingRequestType::HOOK_MOUSE_TOGGLE:
1152+
actor->hookToggle(request->alr_hook_group, request->alr_type, request->alr_hook_mousenode);
11491153
TRIGGER_EVENT_ASYNC(SE_TRUCK_MOUSE_GRAB, request->alr_actor_instance_id);
1150-
}
11511154
break;
11521155

1153-
case ActorLinkingRequestType::TIE_ACTION:
1156+
case ActorLinkingRequestType::TIE_TOGGLE:
11541157
actor->tieToggle(request->alr_tie_group);
11551158
break;
11561159

1157-
case ActorLinkingRequestType::ROPE_ACTION:
1160+
case ActorLinkingRequestType::ROPE_TOGGLE:
11581161
actor->ropeToggle(request->alr_rope_group);
11591162
break;
11601163

1161-
case ActorLinkingRequestType::SLIDENODE_ACTION:
1164+
case ActorLinkingRequestType::SLIDENODE_TOGGLE:
11621165
actor->toggleSlideNodeLock();
11631166
break;
11641167
}

0 commit comments

Comments
 (0)