Skip to content

Commit

Permalink
🐛 Fixed hook/tie/rope glitches.
Browse files Browse the repository at this point in the history
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, causing a crash if re-attached. 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:
* SimData.h: the ActorLinkingRequestType enum was merged with HookAction enum and got new fields: HOOK_RESET, TIE_RESET, ROPE_RESET - the `DisjoinInterActorBeams()` function now uses these.
* Actor.h: `hookToggle()/tieToggle()/ropeToggle()` funcs got new parameter `forceunlock_filter` and all now accept ActorLinkingRequestType param;
* Actor.cpp: `SyncReset()` no longer manipulates beams/hooks/ties/ropes directly - that's all done by the extended `DisjoinInterActorBeams()`.
* ScriptEvents.h - added SE_GENERIC_TRUCK_LINKING_CHANGED
* All other files are just fallout from changes above.
  • Loading branch information
ohlidalp committed Jun 27, 2024
1 parent dc7514d commit 3de983a
Show file tree
Hide file tree
Showing 14 changed files with 212 additions and 246 deletions.
4 changes: 3 additions & 1 deletion doc/angelscript/Script2Game/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ void print(const string message);

SE_GENERIC_MESSAGEBOX_CLICK //!< triggered when the user clicks on a message box button, the argument refers to the button pressed
SE_GENERIC_EXCEPTION_CAUGHT //!< Triggered when C++ exception (usually Ogre::Exception) is thrown; #1 ScriptUnitID, #5 originFuncName, #6 type, #7 message.
SE_GENERIC_MODCACHE_ACTIVITY //!< Triggered when status of modcache changes, args: #1 type, #2 entry number, for other args see `RoR::modCacheActivityType`
SE_GENERIC_MODCACHE_ACTIVITY //!< Triggered when status of modcache changes, args: #1 type, #2 entry number, for other args see `RoR::modCacheActivityType`

SE_GENERIC_TRUCK_LINKING_CHANGED //!< Triggered when 2 actors become linked or unlinked via ties/hooks/ropes/slidenodes; args: #1 state (1=linked, 0=unlinked), #2 action `ActorLinkingRequestType` #3 master ActorInstanceID_t, #4 slave ActorInstanceID_t

SE_ALL_EVENTS = 0xffffffff,
SE_NO_EVENTS = 0
Expand Down
7 changes: 3 additions & 4 deletions source/main/GameContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1367,21 +1367,20 @@ void GameContext::UpdateCommonInputEvents(float dt)
{
//m_player_actor->hookToggle(-1, HOOK_TOGGLE, -1);
ActorLinkingRequest* hook_rq = new ActorLinkingRequest();
hook_rq->alr_type = ActorLinkingRequestType::HOOK_ACTION;
hook_rq->alr_type = ActorLinkingRequestType::HOOK_TOGGLE;
hook_rq->alr_actor_instance_id = m_player_actor->ar_instance_id;
hook_rq->alr_hook_action = HOOK_TOGGLE;
App::GetGameContext()->PushMessage(Message(MSG_SIM_ACTOR_LINKING_REQUESTED, hook_rq));

//m_player_actor->toggleSlideNodeLock();
ActorLinkingRequest* slidenode_rq = new ActorLinkingRequest();
slidenode_rq->alr_type = ActorLinkingRequestType::SLIDENODE_ACTION;
slidenode_rq->alr_type = ActorLinkingRequestType::SLIDENODE_TOGGLE;
hook_rq->alr_actor_instance_id = m_player_actor->ar_instance_id;
App::GetGameContext()->PushMessage(Message(MSG_SIM_ACTOR_LINKING_REQUESTED, slidenode_rq));
}

if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_AUTOLOCK))
{
m_player_actor->hookToggle(-2, HOOK_UNLOCK, -1); //unlock all autolocks
m_player_actor->hookToggle(-2, ActorLinkingRequestType::HOOK_UNLOCK, -1); //unlock all autolocks
}

//strap
Expand Down
5 changes: 2 additions & 3 deletions source/main/gameplay/SceneMouse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,10 @@ bool SceneMouse::mouseMoved(const OIS::MouseEvent& _arg)
{
if (it->hk_hook_node->pos == minnode)
{
//grab_truck->hookToggle(it->hk_group, MOUSE_HOOK_TOGGLE, minnode);
//grab_truck->hookToggle(it->hk_group, HOOK_MOUSE_TOGGLE, minnode);
ActorLinkingRequest* rq = new ActorLinkingRequest();
rq->alr_type = ActorLinkingRequestType::HOOK_ACTION;
rq->alr_type = ActorLinkingRequestType::HOOK_MOUSE_TOGGLE;
rq->alr_actor_instance_id = grab_truck->ar_instance_id;
rq->alr_hook_action = MOUSE_HOOK_TOGGLE;
rq->alr_hook_group = it->hk_group;
rq->alr_hook_mousenode = minnode;
App::GetGameContext()->PushMessage(Message(MSG_SIM_ACTOR_LINKING_REQUESTED, rq));
Expand Down
2 changes: 2 additions & 0 deletions source/main/gameplay/ScriptEvents.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ enum scriptEvents
SE_GENERIC_EXCEPTION_CAUGHT = BITMASK(24), //!< Triggered when C++ exception (usually Ogre::Exception) is thrown; #1 ScriptUnitID, #5 originFuncName, #6 type, #7 message.
SE_GENERIC_MODCACHE_ACTIVITY = BITMASK(25), //!< Triggered when status of modcache changes, args: #1 type, #2 entry number, for other args see `RoR::modCacheActivityType`

SE_GENERIC_TRUCK_LINKING_CHANGED = BITMASK(26), //!< Triggered when 2 actors become linked or unlinked via ties/hooks/ropes/slidenodes; args: #1 state (1=linked, 0=unlinked), #2 action `ActorLinkingRequestType` #3 master ActorInstanceID_t, #4 slave ActorInstanceID_t

SE_ALL_EVENTS = 0xffffffff,
SE_NO_EVENTS = 0

Expand Down
5 changes: 2 additions & 3 deletions source/main/gui/panels/GUI_VehicleButtons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1183,14 +1183,13 @@ void VehicleButtons::DrawLockButton(RoR::GfxActor* actorx)
{
//actorx->GetActor()->hookToggle(-1, HOOK_TOGGLE, -1);
ActorLinkingRequest* hook_rq = new ActorLinkingRequest();
hook_rq->alr_type = ActorLinkingRequestType::HOOK_ACTION;
hook_rq->alr_type = ActorLinkingRequestType::HOOK_TOGGLE;
hook_rq->alr_actor_instance_id = actorx->GetActor()->ar_instance_id;
hook_rq->alr_hook_action = HOOK_TOGGLE;
App::GetGameContext()->PushMessage(Message(MSG_SIM_ACTOR_LINKING_REQUESTED, hook_rq));

//actorx->GetActor()->toggleSlideNodeLock();
ActorLinkingRequest* slidenode_rq = new ActorLinkingRequest();
slidenode_rq->alr_type = ActorLinkingRequestType::SLIDENODE_ACTION;
slidenode_rq->alr_type = ActorLinkingRequestType::SLIDENODE_TOGGLE;
hook_rq->alr_actor_instance_id = actorx->GetActor()->ar_instance_id;
App::GetGameContext()->PushMessage(Message(MSG_SIM_ACTOR_LINKING_REQUESTED, slidenode_rq));
}
Expand Down
19 changes: 11 additions & 8 deletions source/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1142,23 +1142,26 @@ int main(int argc, char *argv[])
{
switch (request->alr_type)
{
case ActorLinkingRequestType::HOOK_ACTION:
actor->hookToggle(request->alr_hook_group, request->alr_hook_action, request->alr_hook_mousenode);
if (request->alr_hook_action == MOUSE_HOOK_TOGGLE)
{
case ActorLinkingRequestType::HOOK_LOCK:
case ActorLinkingRequestType::HOOK_UNLOCK:
case ActorLinkingRequestType::HOOK_TOGGLE:
actor->hookToggle(request->alr_hook_group, request->alr_type);
break;

case ActorLinkingRequestType::HOOK_MOUSE_TOGGLE:
actor->hookToggle(request->alr_hook_group, request->alr_type, request->alr_hook_mousenode);
TRIGGER_EVENT_ASYNC(SE_TRUCK_MOUSE_GRAB, request->alr_actor_instance_id);
}
break;

case ActorLinkingRequestType::TIE_ACTION:
case ActorLinkingRequestType::TIE_TOGGLE:
actor->tieToggle(request->alr_tie_group);
break;

case ActorLinkingRequestType::ROPE_ACTION:
case ActorLinkingRequestType::ROPE_TOGGLE:
actor->ropeToggle(request->alr_rope_group);
break;

case ActorLinkingRequestType::SLIDENODE_ACTION:
case ActorLinkingRequestType::SLIDENODE_TOGGLE:
actor->toggleSlideNodeLock();
break;
}
Expand Down
Loading

0 comments on commit 3de983a

Please sign in to comment.