Skip to content

Fix onMarkerHit not firing in interiors (#5018)#5020

Open
QueryOfficial wants to merge 5 commits into
multitheftauto:masterfrom
QueryOfficial:fix/onmarkerhit-interiors
Open

Fix onMarkerHit not firing in interiors (#5018)#5020
QueryOfficial wants to merge 5 commits into
multitheftauto:masterfrom
QueryOfficial:fix/onmarkerhit-interiors

Conversation

@QueryOfficial

Copy link
Copy Markdown
Contributor

Summary

Fixed onMarkerHit not firing in interiors when a geometric collision was recorded but the event was silently cancelled due to an interior mismatch. Interior (and dimension for pickups) checks were moved from callbacks into collision state management; hit detection is now refreshed after setElementInterior and createMarker.

Affected events:

  • Server: onMarkerHit, onMarkerLeave, onPickupHit, onPickupLeave
  • Client: onClientMarkerHit, onClientMarkerLeave, onClientPickupHit, onClientPickupLeave

Motivation

Fixes #5018

CColManager::HandleHitDetectionResult recorded collisions based on geometry only, while CMarker::Callback_OnCollision blocked the event entirely when interiors did not match. This mismatch created a stale collision state: even after the player later entered the correct interior, CollisionExists was already true, so onMarkerHit never fired again.

The same root cause also affected pickup and client-side marker/pickup events.

Test plan

Original repro (server console):

srun m = createMarker(me.position + Vector3(0,0,0.5), 'cylinder', 1.1, 255, 255, 255)
addEventHandler('onMarkerHit', m, function(he,md) outputChatBox('HIT '..tostring(he)..' md='..tostring(md)) end)
setElementInterior(m, 14)
setElementInterior(me, 14)
  • onMarkerHit should fire.

Additional scenarios:

  • Player passes through the marker area in interior 0 → event does not fire; then setElementInterior(me, 14)onMarkerHit fires.
  • Player is inside the marker and setElementInterior(me, 0) is called → onMarkerLeave fires.
  • With a dimension mismatch, onMarkerHit still fires with matchingDimension = false.
  • Same interior stale-state scenario verified for pickups via onPickupHit.
  • Client-side onClientMarkerHit tested with the local player using the same scenarios.
  • When interiors match, isElementWithinMarker returns true and onMarkerHit fires consistently.

Checklist

  • Your code should follow the coding guidelines.
  • Smaller pull requests are easier to review. If your pull request is beefy, your pull request should be reviewable commit-by-commit.

…d classes

- Introduced ShouldTrackCollision method in CClientColCallback, CClientMarker, and CClientPickup to determine if collisions should be tracked based on entity conditions.
- Updated CClientColManager to utilize the new tracking logic during hit detection.
- Refactored collision handling in CClientMarker and CClientPickup to streamline event calls and ensure proper interior and dimension checks.
- Enhanced CStaticFunctionDefinitions to refresh collision states after interior changes for markers and pickups.

This update improves collision management and event handling across various entity types in the deathmatch logic.
No code changes; previous checks were cancelled with hosted runner not acquired.
Clarifies why collision state is gated separately from geometry hits (fixes stale interior collisions, multitheftauto#5018).
@Lpsd

Lpsd commented Jul 10, 2026

Copy link
Copy Markdown
Member

Do you know what caused this (a specific commit/PR)? Or has it always been broken?

@HeresHavi

Copy link
Copy Markdown

Do you know what caused this (a specific commit/PR)? Or has it always been broken?

November 23, 2008

  • Commit: de636610
  • SetInterior only changed the interior value and did not refresh collision detection.

August 4, 2009

  • Commit: f2a99c7c
  • Added interior checks to server-side marker and pickup callbacks.
  • Collisions were still recorded before these checks, creating the stale collision state.

March 18, 2021

July 31, 2025

Conclusion

The missing collision refresh is longstanding, but the stale server-side collision behavior appears to originate from f2a99c7c in 2009. The client-side equivalent was introduced separately in 2025.

@QueryOfficial

Copy link
Copy Markdown
Contributor Author

Do you know what caused this (a specific commit/PR)? Or has it always been broken?

Agreed with this timeline. The stale collision state was introduced when interior checks were added to callbacks (f2a99c7, 2009) without updating CColManager to skip recording collisions when interiors don't match. The missing refresh on SetElementInterior (de63661, 2008) made it easier to trigger. This PR addresses both: interior filtering is now part of collision state management, and hit detection is refreshed on interior changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

onMarkerHit is broken in interiors

3 participants