public List <Character> GetCharactersRange(Vector3 position, int range) { List <Character> characters = new List <Character>(); foreach (NecClient client in ClientLookup.GetAll()) { Character character = client.Character; Vector3 characterPos = new Vector3(character.X, character.Y, character.Z); if (Vector3.Distance(position, characterPos) <= range) { characters.Add(character); } } return(characters); }
public void Leave(NecClient client) { Logger.Info(client, $"Leaving Map: {Id}:{FullName}"); ClientLookup.Remove(client); if (!_server.Database.UpdateCharacter(client.Character)) { Logger.Error("Could not update the database with last known player position"); } client.Map = null; RecvObjectDisappearNotify objectDisappearData = new RecvObjectDisappearNotify(client.Character.InstanceId); _server.Router.Send(this, objectDisappearData, client); if (ClientLookup.GetAll().Count == 0) { foreach (MonsterSpawn monsterSpawn in this.MonsterSpawns.Values) { monsterSpawn.SpawnActive = false; } } Logger.Debug($"Client Lookup count is now : {ClientLookup.GetAll().Count} for map {this.Id} "); }
public Map(MapData mapData, NecServer server) { _server = server; clientLookup = new ClientLookup(); this.npcSpawns = new Dictionary <uint, NpcSpawn>(); this.monsterSpawns = new Dictionary <uint, MonsterSpawn>(); this.gimmickSpawns = new Dictionary <uint, Gimmick>(); this.mapTransitions = new Dictionary <uint, MapTransition>(); this.gGateSpawns = new Dictionary <uint, GGateSpawn>(); deadBodies = new Dictionary <uint, DeadBody>(); id = mapData.id; x = mapData.x; y = mapData.y; z = mapData.z; country = mapData.country; area = mapData.area; place = mapData.place; orientation = (byte)(mapData.orientation / 2); // Client uses 180 degree orientation traps = new Dictionary <uint, TrapStack>(); List <MapTransition> mapTransitions = server.database.SelectMapTransitionsByMapId(mapData.id); foreach (MapTransition mapTran in mapTransitions) { if (mapTran.id == 0) //Only one special transition { double angle = mapTran.maplinkHeading / 255.0; mapTran.leftPos.X = (float)((mapTran.referencePos.X + mapTran.maplinkWidth / 2) * Math.Cos(angle)); mapTran.leftPos.Y = (float)(mapTran.referencePos.Y * Math.Cos(angle)); mapTran.rightPos.X = (float)((mapTran.referencePos.X - mapTran.maplinkWidth / 2) * Math.Cos(angle)); mapTran.rightPos.Y = mapTran.referencePos.Y + mapTran.maplinkWidth / 2; } else if (mapTran.invertedTransition != true) //map is x dominant { mapTran.leftPos.X = mapTran.referencePos.X + mapTran.maplinkWidth / 2; mapTran.leftPos.Y = mapTran.referencePos.Y; mapTran.rightPos.X = mapTran.referencePos.X - mapTran.maplinkWidth / 2; mapTran.rightPos.Y = mapTran.referencePos.Y; } else if (mapTran.invertedTransition) //map is y dominant { mapTran.leftPos.X = mapTran.referencePos.X; mapTran.leftPos.Y = mapTran.referencePos.Y + mapTran.maplinkWidth / 2; mapTran.rightPos.X = mapTran.referencePos.X; mapTran.rightPos.Y = mapTran.referencePos.Y - mapTran.maplinkWidth / 2; } server.instances.AssignInstance(mapTran); this.mapTransitions.Add(mapTran.instanceId, mapTran); _Logger.Debug($"Loaded Map transition {mapTran.id} on map {fullName}"); } //Assign Unique Instance ID to each NPC per map. Add to dictionary stored with the Map object List <NpcSpawn> npcSpawns = server.database.SelectNpcSpawnsByMapId(mapData.id); foreach (NpcSpawn npcSpawn in npcSpawns) { server.instances.AssignInstance(npcSpawn); this.npcSpawns.Add(npcSpawn.instanceId, npcSpawn); } //Assign Unique Instance ID to each Gimmick per map. Add to dictionary stored with the Map object List <Gimmick> gimmickSpawns = server.database.SelectGimmicksByMapId(mapData.id); foreach (Gimmick gimmickSpawn in gimmickSpawns) { server.instances.AssignInstance(gimmickSpawn); this.gimmickSpawns.Add(gimmickSpawn.instanceId, gimmickSpawn); } List <GGateSpawn> gGateSpawns = server.database.SelectGGateSpawnsByMapId(mapData.id); foreach (GGateSpawn gGateSpawn in gGateSpawns) { server.instances.AssignInstance(gGateSpawn); this.gGateSpawns.Add(gGateSpawn.instanceId, gGateSpawn); } //To-Do | for each deadBody in Deadbodies {RecvDataNotifyCharabodyData} List <MonsterSpawn> monsterSpawns = server.database.SelectMonsterSpawnsByMapId(mapData.id); foreach (MonsterSpawn monsterSpawn in monsterSpawns) { server.instances.AssignInstance(monsterSpawn); if (!_server.settingRepository.modelCommon.TryGetValue(monsterSpawn.modelId, out ModelCommonSetting modelSetting)) { _Logger.Error($"Error getting ModelCommonSetting for ModelId {monsterSpawn.modelId}"); continue; } if (!_server.settingRepository.monster.TryGetValue(monsterSpawn.monsterId, out MonsterSetting monsterSetting)) { _Logger.Error($"Error getting MonsterSetting for MonsterId {monsterSpawn.monsterId}"); continue; } monsterSpawn.modelId = modelSetting.id; //monsterSpawn.Size = (short) (modelSetting.Height / 2); //commenting out to use size setting from database. monsterSpawn.radius = (short)modelSetting.radius; monsterSpawn.hp.SetMax(300); monsterSpawn.hp.SetCurrent(300); monsterSpawn.attackSkillId = monsterSetting.attackSkillId; //monsterSpawn.Level = (byte) monsterSetting.Level; monsterSpawn.combatMode = monsterSetting.combatMode; monsterSpawn.catalogId = monsterSetting.catalogId; monsterSpawn.textureType = monsterSetting.textureType; monsterSpawn.map = this; this.monsterSpawns.Add(monsterSpawn.instanceId, monsterSpawn); List <MonsterCoord> coords = server.database.SelectMonsterCoordsByMonsterId(monsterSpawn.id); if (coords.Count > 0) { monsterSpawn.defaultCoords = false; monsterSpawn.monsterCoords.Clear(); foreach (MonsterCoord monsterCoord in coords) { //Console.WriteLine($"added coord {monsterCoord} to monster {monsterSpawn.InstanceId}"); monsterSpawn.monsterCoords.Add(monsterCoord); } } else { //home coordinate set to monster X,Y,Z from database Vector3 homeVector3 = new Vector3(monsterSpawn.x, monsterSpawn.y, monsterSpawn.z); MonsterCoord homeCoord = new MonsterCoord(); homeCoord.id = monsterSpawn.id; homeCoord.monsterId = (uint)monsterSpawn.monsterId; homeCoord.mapId = (uint)monsterSpawn.mapId; homeCoord.coordIdx = 0; homeCoord.destination = homeVector3; monsterSpawn.monsterCoords.Add(homeCoord); //default path part 2 Vector3 defaultVector3 = new Vector3(monsterSpawn.x, monsterSpawn.y + Util.GetRandomNumber(50, 150), monsterSpawn.z); MonsterCoord defaultCoord = new MonsterCoord(); defaultCoord.id = monsterSpawn.id; defaultCoord.monsterId = (uint)monsterSpawn.monsterId; defaultCoord.mapId = (uint)monsterSpawn.mapId; defaultCoord.coordIdx = 1; defaultCoord.destination = defaultVector3; monsterSpawn.monsterCoords.Add(defaultCoord); //default path part 3 Vector3 defaultVector32 = new Vector3(monsterSpawn.x + Util.GetRandomNumber(50, 150), monsterSpawn.y + Util.GetRandomNumber(50, 150), monsterSpawn.z); MonsterCoord defaultCoord2 = new MonsterCoord(); defaultCoord2.id = monsterSpawn.id; defaultCoord2.monsterId = (uint)monsterSpawn.monsterId; defaultCoord2.mapId = (uint)monsterSpawn.mapId; defaultCoord2.coordIdx = 2; //64 is currently the Idx of monsterHome on send_map_get_info.cs defaultCoord2.destination = defaultVector32; monsterSpawn.monsterCoords.Add(defaultCoord2); } } }
public Map() { _logger = LogProvider.Logger <NecLogger>(this); ClientLookup = new ClientLookup(); }
public Map(MapSetting setting, NecServer server) { _server = server; ClientLookup = new ClientLookup(); NpcSpawns = new Dictionary <uint, NpcSpawn>(); MonsterSpawns = new Dictionary <uint, MonsterSpawn>(); GimmickSpawns = new Dictionary <uint, Gimmick>(); MapTransitions = new Dictionary <uint, MapTransition>(); GGateSpawns = new Dictionary <uint, GGateSpawn>(); DeadBodies = new Dictionary <uint, DeadBody>(); Id = setting.Id; X = setting.X; Y = setting.Y; Z = setting.Z; Country = setting.Country; Area = setting.Area; Place = setting.Place; Orientation = (byte)(setting.Orientation / 2); // Client uses 180 degree orientation Traps = new Dictionary <uint, TrapStack>(); List <MapTransition> mapTransitions = server.Database.SelectMapTransitionsByMapId(setting.Id); foreach (MapTransition mapTran in mapTransitions) { server.Instances.AssignInstance(mapTran); mapTran.Start(_server, this); MapTransitions.Add(mapTran.InstanceId, mapTran); } //Assign Unique Instance ID to each NPC per map. Add to dictionary stored with the Map object List <NpcSpawn> npcSpawns = server.Database.SelectNpcSpawnsByMapId(setting.Id); foreach (NpcSpawn npcSpawn in npcSpawns) { server.Instances.AssignInstance(npcSpawn); NpcSpawns.Add(npcSpawn.InstanceId, npcSpawn); } //Assign Unique Instance ID to each Gimmick per map. Add to dictionary stored with the Map object List <Gimmick> gimmickSpawns = server.Database.SelectGimmicksByMapId(setting.Id); foreach (Gimmick gimmickSpawn in gimmickSpawns) { server.Instances.AssignInstance(gimmickSpawn); GimmickSpawns.Add(gimmickSpawn.InstanceId, gimmickSpawn); } List <GGateSpawn> gGateSpawns = server.Database.SelectGGateSpawnsByMapId(setting.Id); foreach (GGateSpawn gGateSpawn in gGateSpawns) { server.Instances.AssignInstance(gGateSpawn); GGateSpawns.Add(gGateSpawn.InstanceId, gGateSpawn); } //To-Do | for each deadBody in Deadbodies {RecvDataNotifyCharabodyData} List <MonsterSpawn> monsterSpawns = server.Database.SelectMonsterSpawnsByMapId(setting.Id); foreach (MonsterSpawn monsterSpawn in monsterSpawns) { server.Instances.AssignInstance(monsterSpawn); if (!_server.SettingRepository.ModelCommon.TryGetValue(monsterSpawn.ModelId, out ModelCommonSetting modelSetting)) { Logger.Error($"Error getting ModelCommonSetting for ModelId {monsterSpawn.ModelId}"); continue; } if (!_server.SettingRepository.Monster.TryGetValue(monsterSpawn.MonsterId, out MonsterSetting monsterSetting)) { Logger.Error($"Error getting MonsterSetting for MonsterId {monsterSpawn.MonsterId}"); continue; } monsterSpawn.ModelId = modelSetting.Id; monsterSpawn.Size = (short)(modelSetting.Height / 2); monsterSpawn.Radius = (short)modelSetting.Radius; monsterSpawn.Hp.setMax(300); monsterSpawn.Hp.setCurrent(300); monsterSpawn.AttackSkillId = monsterSetting.AttackSkillId; monsterSpawn.Level = (byte)monsterSetting.Level; monsterSpawn.CombatMode = monsterSetting.CombatMode; monsterSpawn.CatalogId = monsterSetting.CatalogId; monsterSpawn.TextureType = monsterSetting.TextureType; monsterSpawn.Map = this; MonsterSpawns.Add(monsterSpawn.InstanceId, monsterSpawn); List <MonsterCoord> coords = server.Database.SelectMonsterCoordsByMonsterId(monsterSpawn.Id); if (coords.Count > 0) { monsterSpawn.defaultCoords = false; monsterSpawn.monsterCoords.Clear(); foreach (MonsterCoord monsterCoord in coords) { //Console.WriteLine($"added coord {monsterCoord} to monster {monsterSpawn.InstanceId}"); monsterSpawn.monsterCoords.Add(monsterCoord); } } else { //home coordinate set to monster X,Y,Z from database Vector3 homeVector3 = new Vector3(monsterSpawn.X, monsterSpawn.Y, monsterSpawn.Z); MonsterCoord homeCoord = new MonsterCoord(); homeCoord.Id = monsterSpawn.Id; homeCoord.MonsterId = (uint)monsterSpawn.MonsterId; homeCoord.MapId = (uint)monsterSpawn.MapId; homeCoord.CoordIdx = 0; homeCoord.destination = homeVector3; monsterSpawn.monsterCoords.Add(homeCoord); //default path part 2 Vector3 defaultVector3 = new Vector3(monsterSpawn.X, monsterSpawn.Y + Util.GetRandomNumber(50, 150), monsterSpawn.Z); MonsterCoord defaultCoord = new MonsterCoord(); defaultCoord.Id = monsterSpawn.Id; defaultCoord.MonsterId = (uint)monsterSpawn.MonsterId; defaultCoord.MapId = (uint)monsterSpawn.MapId; defaultCoord.CoordIdx = 1; defaultCoord.destination = defaultVector3; monsterSpawn.monsterCoords.Add(defaultCoord); //default path part 3 Vector3 defaultVector32 = new Vector3(monsterSpawn.X + Util.GetRandomNumber(50, 150), monsterSpawn.Y + Util.GetRandomNumber(50, 150), monsterSpawn.Z); MonsterCoord defaultCoord2 = new MonsterCoord(); defaultCoord2.Id = monsterSpawn.Id; defaultCoord2.MonsterId = (uint)monsterSpawn.MonsterId; defaultCoord2.MapId = (uint)monsterSpawn.MapId; defaultCoord2.CoordIdx = 2; //64 is currently the Idx of monsterHome on send_map_get_info.cs defaultCoord2.destination = defaultVector32; monsterSpawn.monsterCoords.Add(defaultCoord2); } } }
public void Enter(NecClient client, MapPosition mapPosition = null) { if (client.Map != null) { client.Map.Leave(client); } Logger.Info(client, $"Entering Map: {Id}:{FullName}"); // If position is passed in use it and set character position, if null then use map default coords // If this isn't set here, the wrong coords are in character until send_movement_info updates it. if (mapPosition != null) { client.Character.X = mapPosition.X; client.Character.Y = mapPosition.Y; client.Character.Z = mapPosition.Z; client.Character.Heading = mapPosition.Heading; } else { client.Character.X = this.X; client.Character.Y = this.Y; client.Character.Z = this.Z; client.Character.Heading = this.Orientation; } client.Map = this; client.Character.MapId = Id; client.Character.mapChange = false; ClientLookup.Add(client); Logger.Debug($"Client Lookup count is now : {ClientLookup.GetAll().Count} for map {this.Id} "); RecvDataNotifyCharaData myCharacterData = new RecvDataNotifyCharaData(client.Character, client.Soul.Name); _server.Router.Send(this, myCharacterData, client); if (client.Union != null) { RecvDataNotifyUnionData myUnionData = new RecvDataNotifyUnionData(client.Character, client.Union.Name); _server.Router.Send(this, myUnionData, client); } foreach (MonsterSpawn monsterSpawn in this.MonsterSpawns.Values) { if (monsterSpawn.Active == true) { monsterSpawn.SpawnActive = true; if (!monsterSpawn.TaskActive) { MonsterTask monsterTask = new MonsterTask(_server, monsterSpawn); if (monsterSpawn.defaultCoords) { monsterTask.monsterHome = monsterSpawn.monsterCoords[0]; } else { monsterTask.monsterHome = monsterSpawn.monsterCoords.Find(x => x.CoordIdx == 64); } monsterTask.Start(); } else { if (monsterSpawn.MonsterVisible) { Logger.Debug($"MonsterTask already running for [{monsterSpawn.Name}]"); RecvDataNotifyMonsterData monsterData = new RecvDataNotifyMonsterData(monsterSpawn); _server.Router.Send(monsterData, client); if (!monsterSpawn.GetAgro()) { monsterSpawn.MonsterMove(_server, client, monsterSpawn.MonsterWalkVelocity, (byte)2, (byte)0); } } } } } //on successful map entry, update the client database position if (!_server.Database.UpdateCharacter(client.Character)) { Logger.Error("Could not update the database with current known player position"); } }