package zone import ( "sync" "sync/atomic" "time" "eq2emu/internal/spawn" ) // Instance types define different zone instance behaviors type InstanceType int16 const ( InstanceTypeNone InstanceType = iota InstanceTypeGroupLockout InstanceTypeGroupPersist InstanceTypeRaidLockout InstanceTypeRaidPersist InstanceTypeSoloLockout InstanceTypeSoloPersist InstanceTypeTradeskill InstanceTypePublic InstanceTypePersonalHouse InstanceTypeGuildHouse InstanceTypeQuest ) // Core zone server structure - equivalent to C++ ZoneServer class type ZoneServer struct { // Zone identity and configuration zoneID int32 instanceID int32 zoneName string zoneFile string zoneSkyFile string zoneDescription string // Zone properties cityZone bool alwaysLoaded bool duplicatedZone bool duplicatedID int32 locked bool isInstance bool instanceType InstanceType // Safe zone coordinates safeX float32 safeY float32 safeZ float32 safeHeading float32 underworld float32 // Zone modifiers and rules xpModifier float32 minimumStatus int16 minimumLevel int16 maximumLevel int16 minimumVersion int16 expansionFlag int32 holidayFlag int32 canBind bool canGate bool canEvac bool // Zone times and lockouts defaultLockoutTime int32 defaultReenterTime int32 defaultResetTime int32 groupZoneOption int8 // Player and client management clients []Client numPlayers int32 maxPlayers int32 incomingClients int32 lifetimeClientCount int32 // Weather system weatherEnabled bool weatherAllowed bool weatherType int8 weatherFrequency int32 weatherMinSeverity float32 weatherMaxSeverity float32 weatherChangeAmount float32 weatherDynamicOffset float32 weatherChangeChance int8 weatherCurrentSeverity float32 weatherPattern int8 weatherLastChangedTime int32 weatherSignaled bool rain float32 // Time system isDusk bool duskHour int duskMinute int dawnHour int dawnMinute int // Zone message zoneMOTD string // Thread and processing state spawnThreadActive bool combatThreadActive bool initialSpawnThreads int8 clientThreadActive bool loadingData bool zoneShuttingDown atomic.Bool isInitialized atomic.Bool finishedDepop bool depopZone bool repopZone bool respawnsAllowed bool // Spawn management spawnList map[int32]*spawn.Spawn spawnLocationList map[int32]*SpawnLocation changedSpawns map[int32]bool damagedSpawns []int32 pendingSpawnList []*spawn.Spawn pendingSpawnRemove map[int32]bool spawnDeleteList map[*spawn.Spawn]int32 spawnExpireTimers map[int32]int32 // Grid system for spatial optimization gridMaps map[int32]*GridMap // Movement and pathfinding pathfinder IPathfinder movementMgr *MobMovementManager // System components spellProcess SpellProcess tradeskillMgr TradeskillManager // Timers aggroTimer *time.Timer charsheetChanges *time.Timer clientSave *time.Timer locationProxTimer *time.Timer movementTimer *time.Timer regenTimer *time.Timer respawnTimer *time.Timer shutdownTimer *time.Timer spawnRangeTimer *time.Timer spawnUpdateTimer *time.Timer syncGameTimer *time.Timer trackingTimer *time.Timer weatherTimer *time.Timer widgetTimer *time.Timer // Proximity systems playerProximities map[int32]*PlayerProximity locationProximities []*LocationProximity locationGrids []*LocationGrid // Faction management enemyFactionList map[int32][]int32 npcFactionList map[int32][]int32 reverseEnemyFactionList map[int32][]int32 // Revive points revivePoints []*RevivePoint // Transport system transportSpawns []int32 transportLocations []*LocationTransportDestination transporters map[int32][]*TransportDestination locationTransporters map[int32][]*LocationTransportDestination transportMaps map[int32]string // Flight paths flightPaths map[int32]*FlightPathInfo flightPathRoutes map[int32][]*FlightPathLocation // Loot system lootTables map[int32]*LootTable lootDrops map[int32][]*LootDrop spawnLootList map[int32][]int32 levelLootList []*GlobalLoot racialLootList map[int16][]*GlobalLoot zoneLootList map[int32][]*GlobalLoot // Spawn data caches npcList map[int32]*NPC objectList map[int32]*Object signList map[int32]*Sign widgetList map[int32]*Widget groundSpawnList map[int32]*GroundSpawn // Entity commands entityCommandList map[int32][]*EntityCommand // Spawn groups and locations spawnGroupAssociations map[int32][]int32 spawnGroupChances map[int32]float32 spawnGroupLocations map[int32]map[int32]int32 spawnGroupMap map[int32][]int32 spawnLocationGroups map[int32][]int32 // Script timers spawnScriptTimers []*SpawnScriptTimer // Widget management widgetTimers map[int32]int32 ignoredWidgets map[int32]bool // House items subspawnList map[SubspawnType]map[int32]*spawn.Spawn housingSpawnMap map[int32]int32 // Respawn management respawnTimers map[int32]int32 // Zone map defaultZoneMap Map // Group/raid level tracking groupRaidMinLevel int32 groupRaidMaxLevel int32 groupRaidAvgLevel int32 groupRaidFirstLevel int32 // Watchdog watchdogTimestamp int32 // Lua command queues luaQueuedStateCommands map[int32]int32 luaSpawnUpdateCommands map[int32]map[string]float32 // Mutexes for thread safety masterZoneLock sync.RWMutex masterSpawnLock sync.RWMutex spawnListLock sync.RWMutex clientListLock sync.RWMutex changedSpawnsLock sync.RWMutex gridMapsLock sync.RWMutex spawnLocationListLock sync.RWMutex spawnDeleteListLock sync.RWMutex widgetTimersLock sync.RWMutex ignoredWidgetsLock sync.RWMutex pendingSpawnRemoveLock sync.RWMutex luaQueueStateCmdLock sync.Mutex transportLock sync.RWMutex factionLock sync.RWMutex spawnScriptTimersLock sync.RWMutex deadSpawnsLock sync.RWMutex incomingClientsLock sync.RWMutex } // PlayerProximity manages spawn proximity events for Lua scripting type PlayerProximity struct { Distance float32 InRangeLuaFunction string LeavingRangeLuaFunction string ClientsInProximity map[Client]bool mutex sync.RWMutex } // LocationProximity handles location-based proximity triggers type LocationProximity struct { X float32 Y float32 Z float32 MaxVariation float32 InRangeLuaFunction string LeavingRangeLuaFunction string ClientsInProximity map[Client]bool mutex sync.RWMutex } // LocationGrid manages discovery grids and player tracking type LocationGrid struct { ID int32 GridID int32 Name string IncludeY bool Discovery bool Locations []*Location Players map[Player]bool mutex sync.RWMutex } // GridMap provides spawn organization by grid for efficient querying type GridMap struct { GridID int32 Spawns map[int32]*spawn.Spawn mutex sync.RWMutex } // TrackedSpawn represents distance-based spawn tracking for clients type TrackedSpawn struct { Spawn *spawn.Spawn Distance float32 } // HouseItem represents player housing item management type HouseItem struct { SpawnID int32 ItemID int32 UniqueID int64 Item *Item } // RevivePoint represents death recovery locations type RevivePoint struct { ID int32 ZoneID int32 LocationName string X float32 Y float32 Z float32 Heading float32 AlwaysIncluded bool } // SpawnScriptTimer represents Lua script timer management type SpawnScriptTimer struct { Timer int32 SpawnID int32 PlayerID int32 Function string CurrentCount int32 MaxCount int32 } // FlightPathInfo contains flight path configuration type FlightPathInfo struct { Speed float32 Flying bool Dismount bool } // FlightPathLocation represents a waypoint in a flight path type FlightPathLocation struct { X float32 Y float32 Z float32 } // ZoneInfoSlideStructInfo represents zone intro slide information type ZoneInfoSlideStructInfo struct { Unknown1 [2]float32 Unknown2 [2]int32 Unknown3 int32 Unknown4 int32 Slide string Voiceover string Key1 int32 Key2 int32 } // ZoneInfoSlideStructTransitionInfo represents slide transition data type ZoneInfoSlideStructTransitionInfo struct { TransitionX int32 TransitionY int32 TransitionZoom float32 TransitionTime float32 } // ZoneInfoSlideStruct combines slide info and transitions type ZoneInfoSlideStruct struct { Info *ZoneInfoSlideStructInfo SlideTransitionInfo []*ZoneInfoSlideStructTransitionInfo } // SubspawnType enumeration for different spawn subtypes type SubspawnType int const ( SubspawnTypeCollector SubspawnType = iota SubspawnTypeHouseItem SubspawnTypeMax = 20 ) // Expansion flags for client compatibility const ( ExpansionUnknown = 1 ExpansionUnknown2 = 64 ExpansionUnknown3 = 128 ExpansionUnknown4 = 256 ExpansionUnknown5 = 512 ExpansionDOF = 1024 ExpansionKOS = 2048 ExpansionEOF = 4096 ExpansionROK = 8192 ExpansionTSO = 16384 ExpansionDOV = 65536 ) // Spawn script event types const ( SpawnScriptSpawn = iota SpawnScriptRespawn SpawnScriptAttacked SpawnScriptTargeted SpawnScriptHailed SpawnScriptDeath SpawnScriptKilled SpawnScriptAggro SpawnScriptHealthChanged SpawnScriptRandomChat SpawnScriptConversation SpawnScriptTimerEvent SpawnScriptCustom SpawnScriptHailedBusy SpawnScriptCastedOn SpawnScriptAutoAttackTick SpawnScriptCombatReset SpawnScriptGroupDead SpawnScriptHearSay SpawnScriptPrespawn SpawnScriptUseDoor SpawnScriptBoard SpawnScriptDeboard ) // Spawn conditional flags const ( SpawnConditionalNone = 0 SpawnConditionalDay = 1 SpawnConditionalNight = 2 SpawnConditionalNotRaining = 4 SpawnConditionalRaining = 8 ) // Distance constants const ( SendSpawnDistance = 250.0 // When spawns appear visually to the client HearSpawnDistance = 30.0 // Max distance a client can be from a spawn to 'hear' it MaxChaseDistance = 80.0 // Maximum chase distance for NPCs RemoveSpawnDistance = 300.0 // Distance at which spawns are removed from client MaxRevivePointDistance = 1000.0 // Maximum distance for revive point selection ) // Tracking system constants const ( TrackingStop = iota TrackingStart TrackingUpdate TrackingCloseWindow ) const ( TrackingTypeEntities = iota + 1 TrackingTypeHarvestables ) const ( TrackingSpawnTypePC = iota TrackingSpawnTypeNPC ) // Waypoint categories const ( WaypointCategoryGroup = iota WaypointCategoryQuests WaypointCategoryPeople WaypointCategoryPlaces WaypointCategoryUser WaypointCategoryDirections WaypointCategoryTracking WaypointCategoryHouses WaypointCategoryMap ) // Weather system constants const ( WeatherTypeNormal = iota WeatherTypeDynamic WeatherTypeRandom WeatherTypeChaotic ) const ( WeatherPatternDecreasing = iota WeatherPatternIncreasing WeatherPatternRandom ) // NewZoneServer creates a new zone server instance with the given zone name func NewZoneServer(zoneName string) *ZoneServer { zs := &ZoneServer{ zoneName: zoneName, respawnsAllowed: true, finishedDepop: true, canBind: true, canGate: true, canEvac: true, clients: make([]Client, 0), spawnList: make(map[int32]*spawn.Spawn), spawnLocationList: make(map[int32]*SpawnLocation), changedSpawns: make(map[int32]bool), damagedSpawns: make([]int32, 0), pendingSpawnList: make([]*spawn.Spawn, 0), pendingSpawnRemove: make(map[int32]bool), spawnDeleteList: make(map[*spawn.Spawn]int32), spawnExpireTimers: make(map[int32]int32), gridMaps: make(map[int32]*GridMap), playerProximities: make(map[int32]*PlayerProximity), locationProximities: make([]*LocationProximity, 0), locationGrids: make([]*LocationGrid, 0), enemyFactionList: make(map[int32][]int32), npcFactionList: make(map[int32][]int32), reverseEnemyFactionList: make(map[int32][]int32), revivePoints: make([]*RevivePoint, 0), transportSpawns: make([]int32, 0), transportLocations: make([]*LocationTransportDestination, 0), transporters: make(map[int32][]*TransportDestination), locationTransporters: make(map[int32][]*LocationTransportDestination), transportMaps: make(map[int32]string), flightPaths: make(map[int32]*FlightPathInfo), flightPathRoutes: make(map[int32][]*FlightPathLocation), lootTables: make(map[int32]*LootTable), lootDrops: make(map[int32][]*LootDrop), spawnLootList: make(map[int32][]int32), levelLootList: make([]*GlobalLoot, 0), racialLootList: make(map[int16][]*GlobalLoot), zoneLootList: make(map[int32][]*GlobalLoot), npcList: make(map[int32]*NPC), objectList: make(map[int32]*Object), signList: make(map[int32]*Sign), widgetList: make(map[int32]*Widget), groundSpawnList: make(map[int32]*GroundSpawn), entityCommandList: make(map[int32][]*EntityCommand), spawnGroupAssociations: make(map[int32][]int32), spawnGroupChances: make(map[int32]float32), spawnGroupLocations: make(map[int32]map[int32]int32), spawnGroupMap: make(map[int32][]int32), spawnLocationGroups: make(map[int32][]int32), spawnScriptTimers: make([]*SpawnScriptTimer, 0), widgetTimers: make(map[int32]int32), ignoredWidgets: make(map[int32]bool), subspawnList: make(map[SubspawnType]map[int32]*spawn.Spawn), housingSpawnMap: make(map[int32]int32), respawnTimers: make(map[int32]int32), luaQueuedStateCommands: make(map[int32]int32), luaSpawnUpdateCommands: make(map[int32]map[string]float32), watchdogTimestamp: int32(time.Now().Unix()), } // Initialize subspawn lists for i := SubspawnType(0); i < SubspawnTypeMax; i++ { zs.subspawnList[i] = make(map[int32]*spawn.Spawn) } zs.loadingData = true zs.zoneShuttingDown.Store(false) zs.isInitialized.Store(false) return zs } // String returns a string representation of the instance type func (it InstanceType) String() string { switch it { case InstanceTypeNone: return "None" case InstanceTypeGroupLockout: return "Group Lockout" case InstanceTypeGroupPersist: return "Group Persistent" case InstanceTypeRaidLockout: return "Raid Lockout" case InstanceTypeRaidPersist: return "Raid Persistent" case InstanceTypeSoloLockout: return "Solo Lockout" case InstanceTypeSoloPersist: return "Solo Persistent" case InstanceTypeTradeskill: return "Tradeskill" case InstanceTypePublic: return "Public" case InstanceTypePersonalHouse: return "Personal House" case InstanceTypeGuildHouse: return "Guild House" case InstanceTypeQuest: return "Quest" default: return "Unknown" } } // IsShuttingDown returns whether the zone is in the process of shutting down func (zs *ZoneServer) IsShuttingDown() bool { return zs.zoneShuttingDown.Load() } // IsInitialized returns whether the zone has completed initialization func (zs *ZoneServer) IsInitialized() bool { return zs.isInitialized.Load() } // Shutdown initiates the zone shutdown process func (zs *ZoneServer) Shutdown() { zs.zoneShuttingDown.Store(true) }