// © 2025 Naked People Team. All Rights Reserved. #include "LocationSubsystem.h" #include "LocationData.h" void ULocationSubsystem::EnterLocation(ULocationData* Location) { if (!Location) return; int32& Count = ActiveCounts.FindOrAdd(Location); ++Count; if (Count == 1) { RebuildActiveTags(); OnLocationEntered.Broadcast(Location); } } void ULocationSubsystem::ExitLocation(ULocationData* Location) { if (!Location) return; int32* Count = ActiveCounts.Find(Location); if (!Count) return; if (--(*Count) <= 0) { ActiveCounts.Remove(Location); RebuildActiveTags(); OnLocationExited.Broadcast(Location); } } bool ULocationSubsystem::IsPlayerInLocation(FGameplayTag Query) const { return Query.IsValid() && ActiveTags.HasTag(Query); } ULocationData* ULocationSubsystem::GetCurrentLocation() const { ULocationData* Best = nullptr; int32 BestDepth = -1; for (const TPair, int32>& Pair : ActiveCounts) { ULocationData* Location = Pair.Key; if (!Location || !Location->Tag.IsValid()) continue; // More tag segments = more specific (Location.City.Beach beats Location.City). const int32 Depth = Location->Tag.GetGameplayTagParents().Num(); if (Depth > BestDepth) { BestDepth = Depth; Best = Location; } } return Best; } void ULocationSubsystem::RebuildActiveTags() { ActiveTags.Reset(); for (const TPair, int32>& Pair : ActiveCounts) { if (Pair.Key && Pair.Key->Tag.IsValid()) ActiveTags.AddTag(Pair.Key->Tag); } }