Skip to content

Commit 88b250f

Browse files
committed
fix: gate static actor interaction range by map
1 parent 8599f0f commit 88b250f

3 files changed

Lines changed: 23 additions & 1 deletion

File tree

internal/worldruntime/scopes.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ func (s Scopes) VisibleStaticActorByVIDWithinInteractionRange(subject loginticke
299299
}
300300

301301
func StaticActorWithinInteractionRange(subject loginticket.Character, actor StaticEntity, maxDistance int32) bool {
302-
if maxDistance <= 0 {
302+
if maxDistance <= 0 || effectiveMapIndex(subject.MapIndex) != effectiveMapIndex(actor.Position.MapIndex) {
303303
return false
304304
}
305305
dx := int64(subject.X) - int64(actor.Position.X)
@@ -309,6 +309,13 @@ func StaticActorWithinInteractionRange(subject loginticket.Character, actor Stat
309309
return distanceSquared <= maxDistanceSquared
310310
}
311311

312+
func effectiveMapIndex(mapIndex uint32) uint32 {
313+
if mapIndex == 0 {
314+
return bootstrapMapIndex
315+
}
316+
return mapIndex
317+
}
318+
312319
func (s Scopes) VisibleTargetsForStaticActor(actor StaticEntity) []PlayerEntity {
313320
return s.filterTargets(0, staticActorVisibilityCharacter(actor), s.Topology.SharesVisibleWorld)
314321
}

internal/worldruntime/scopes_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,15 @@ func TestScopesVisibleStaticActorByVIDWithinInteractionRangeRequiresCurrentRange
253253
}
254254
}
255255

256+
func TestStaticActorWithinInteractionRangeRequiresSameEffectiveMap(t *testing.T) {
257+
subject := entityRegistryCharacter("Subject", 0x02040101, 42, 1700, 2800)
258+
actor := StaticEntity{Entity: Entity{ID: 10, Name: "NearbyOtherMap"}, Position: NewPosition(43, 1701, 2801), RaceNum: 20300}
259+
260+
if StaticActorWithinInteractionRange(subject, actor, 300) {
261+
t.Fatal("expected nearby static actor on another map to stay outside interaction range")
262+
}
263+
}
264+
256265
func TestScopesCharacterVisibilitySnapshotsIncludeVisibleStaticActors(t *testing.T) {
257266
topology := NewBootstrapTopology(1).WithRadiusVisibilityPolicy(400, 200)
258267
registry := NewEntityRegistryWithTopology(topology)

spec/protocol/visibility-rebuild.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ This is the query now reused by:
6969
- self-facing AOI rebuild on `MOVE`
7070
- self-facing AOI rebuild on `SYNC_POSITION`
7171

72+
Interaction-range helpers are deliberately stricter than plain distance math:
73+
- the actor must still share the subject's effective bootstrap map
74+
- then the helper applies the configured maximum squared-distance check
75+
76+
This prevents a nearby coordinate on another effective map from passing a later interaction or combat range gate solely because its `x/y` values are close.
77+
7278
### Ground-item relocation visibility
7379

7480
`internal/worldruntime/scopes.go` now owns relocation-preview math for runtime-owned ground-item occupancy supplied by the bootstrap shared-world runtime.

0 commit comments

Comments
 (0)