using MMOserver.Game.Channel.Maps.ZoneData; using MMOserver.Game.Engine; namespace MMOserver.Game.Channel.Maps; /* * 게임 맵 * - 각 존 관리 * - 맵의 유저 관리 */ public abstract class AMap : UserContainer { public abstract EnumMap GetMapType(); public abstract int GetMapId(); // 존 그리드 설정 (MapLoader에서 주입) public int Rows { get; private set; } public int Cols { get; private set; } public int ZoneSize { get; private set; } // 존 관리 private readonly Dictionary zones = new(); public void SetZoneConfig(int rows, int cols, int zoneSize) { Rows = rows; Cols = cols; ZoneSize = zoneSize; } // 존 생성 public void CreateZones(List zoneConfigs) { foreach (ZoneConfigData config in zoneConfigs) { Vector3 position = new Vector3(config.CenterX, 0, config.CenterZ); Vector3 size = new Vector3(ZoneSize, 0, ZoneSize); Zone zone = new Zone(this, config.ZoneId, config.Row, config.Col, position, size); AddZone(zone); } } public void AddZone(Zone zone) { zones[zone.ZoneId] = zone; } public Zone? GetZone(int zoneId) { zones.TryGetValue(zoneId, out Zone? zone); return zone; } // 현재 맵의 근처 존 가져오기 public virtual (int, int, int, int) GetNearZone(int zoneId, Vector3? position) { return (zoneId, -1, -1, -1); } // 좌상단/우상단/우하단/좌하단 판정 public int ZoneAt(int row, int col) { return (row >= 0 && row < Rows && col >= 0 && col < Cols) ? row * Cols + col : -1; } // 이동시 zone업데이트 public bool UpdatePlayerZone(int userId, Player player) { // 플레이어의 위치는 이동한 상태 int col = (int)(player.Position.X / ZoneSize); int row = (int)(player.Position.Z / ZoneSize); int newZoneId = ZoneAt(row, col); if (newZoneId == player.CurrentZoneId) { return true; } // 범위 밖으로 이동한 상태 일단 존은 그대로 둔다. if (newZoneId < 0) { return false; } GetZone(player.CurrentZoneId)?.RemoveUser(userId); GetZone(newZoneId)!.AddUser(userId, player); player.CurrentZoneId = newZoneId; return true; } }