public void MonsterSpawn() { _Logger.Debug($"Monster {monster.name} instanceId [{monster.instanceId}]"); monster.SetAgro(false); monsterMoving = false; _casting = false; _monsterWaiting = false; monster.SetGotoDistance(10); //monsterVelocity = 200; MonsterCoord spawnCoords = monster.monsterCoords.Find(x => x.coordIdx == 0); monster.x = spawnCoords.destination.X; monster.y = spawnCoords.destination.Y; monster.z = spawnCoords.destination.Z; monster.heading = (byte)GetHeading(monster.monsterCoords.Find(x => x.coordIdx == 1).destination); monster.hp.ToMax(); _respawnTime = monster.respawnTime; RecvDataNotifyMonsterData monsterData = new RecvDataNotifyMonsterData(monster); foreach (NecClient client in _map.clientLookup.GetAll()) { if (client.character.hasDied == false) { server.router.Send(client, monsterData.ToPacket()); } } _spawnMonster = false; monster.monsterVisible = true; monster.ClearAgroList(); //MonsterBattlePose(false); }
public void MonsterSpawn() { Logger.Debug($"Monster {_monster.Name} instanceId [{_monster.InstanceId}]"); _monster.SetAgro(false); monsterMoving = false; casting = false; monsterWaiting = false; _monster.SetGotoDistance(10); //monsterVelocity = 200; MonsterCoord spawnCoords = _monster.monsterCoords.Find(x => x.CoordIdx == 0); _monster.X = spawnCoords.destination.X; _monster.Y = spawnCoords.destination.Y; _monster.Z = spawnCoords.destination.Z; _monster.Heading = (byte)GetHeading(_monster.monsterCoords.Find(x => x.CoordIdx == 1).destination); _monster.Hp.toMax(); respawnTime = _monster.RespawnTime; RecvDataNotifyMonsterData monsterData = new RecvDataNotifyMonsterData(_monster); _server.Router.Send(Map, monsterData); spawnMonster = false; _monster.MonsterVisible = true; _monster.ClearAgroList(); //MonsterBattlePose(false); }
public override void Execute(string[] command, NecClient client, ChatMessage message, List <ChatResponse> responses) { MonsterSpawn monsterSpawn = Server.Instances.CreateInstance <MonsterSpawn>(); if (!int.TryParse(command[0], out int monsterId)) { responses.Add(ChatResponse.CommandError(client, $"Invalid Number: {command[0]}")); return; } if (!Server.SettingRepository.Monster.TryGetValue(monsterId, out MonsterSetting monsterSetting)) { responses.Add(ChatResponse.CommandError(client, $"Invalid MonsterId: {monsterId}")); return; } if (!int.TryParse(command[1], out int modelId)) { responses.Add(ChatResponse.CommandError(client, $"Invalid Number: {command[1]}")); return; } if (!Server.SettingRepository.ModelCommon.TryGetValue(modelId, out ModelCommonSetting modelSetting)) { responses.Add(ChatResponse.CommandError(client, $"Invalid ModelId: {modelId}")); return; } Logger.Debug($"modelSetting.Radius [{modelSetting.Radius}]"); monsterSpawn.MonsterId = monsterSetting.Id; monsterSpawn.Name = monsterSetting.Name; monsterSpawn.Title = monsterSetting.Title; monsterSpawn.Level = (byte)monsterSetting.Level; monsterSpawn.ModelId = modelSetting.Id; monsterSpawn.Size = (short)(modelSetting.Height / 2); monsterSpawn.Radius = (short)modelSetting.Radius; monsterSpawn.MapId = client.Character.MapId; monsterSpawn.X = client.Character.X; monsterSpawn.Y = client.Character.Y; monsterSpawn.Z = client.Character.Z; monsterSpawn.Heading = client.Character.Heading; monsterSpawn.Hp.setMax(100); monsterSpawn.Hp.setCurrent(100); if (!Server.Database.InsertMonsterSpawn(monsterSpawn)) { responses.Add(ChatResponse.CommandError(client, "MonsterSpawn could not be saved to database")); return; } RecvDataNotifyMonsterData monsterData = new RecvDataNotifyMonsterData(monsterSpawn); Router.Send(client.Map, monsterData); }
public override void Handle(NecClient client, NecPacket packet) { //you are dead here. only getting soul form characters and NPCs. sorry bro. if (client.character.state.HasFlag(CharacterState.SoulForm)) { _Logger.Debug("Rendering Dead stuff"); foreach (NecClient otherClient in client.map.clientLookup.GetAll()) { if (otherClient == client) { // skip myself continue; } //Render all the souls if you are in soul form yourself if (otherClient.character.state.HasFlag(CharacterState.SoulForm)) { RecvDataNotifyCharaData otherCharacterData = new RecvDataNotifyCharaData(otherClient.character, otherClient.soul.name); router.Send(otherCharacterData, client); } if (otherClient.union != null) { RecvDataNotifyUnionData otherUnionData = new RecvDataNotifyUnionData(otherClient.character, otherClient.union.name); router.Send(otherUnionData, client); } } foreach (NpcSpawn npcSpawn in client.map.npcSpawns.Values) { if (npcSpawn.visibility == 2 | npcSpawn.visibility == 3) //2 is the magic number for soul state only. make it an Enum some day { RecvDataNotifyNpcData npcData = new RecvDataNotifyNpcData(npcSpawn); router.Send(npcData, client); } } } else //if you are not dead, do normal stuff. else... do dead person stuff { _Logger.Debug($"Not dead. rendering living stuff. CharacterState:{client.character.state}"); foreach (NecClient otherClient in client.map.clientLookup.GetAll()) { if (otherClient == client) { continue; } if (!otherClient.character.state.HasFlag(CharacterState.SoulForm)) { RecvDataNotifyCharaData otherCharacterData = new RecvDataNotifyCharaData(otherClient.character, otherClient.soul.name); router.Send(otherCharacterData, client); } if (otherClient.union != null) { RecvDataNotifyUnionData otherUnionData = new RecvDataNotifyUnionData(otherClient.character, otherClient.union.name); router.Send(otherUnionData, client); } } foreach (MonsterSpawn monsterSpawn in client.map.monsterSpawns.Values) { RecvDataNotifyMonsterData monsterData = new RecvDataNotifyMonsterData(monsterSpawn); _Logger.Debug($"Monster Id {monsterSpawn.id} with model {monsterSpawn.modelId} is loading"); router.Send(monsterData, client); } foreach (NpcSpawn npcSpawn in client.map.npcSpawns.Values) { if (npcSpawn.visibility == 1 | npcSpawn.visibility == 3) //2 is the magic number for soul state only. make it an Enum some day { RecvDataNotifyNpcData npcData = new RecvDataNotifyNpcData(npcSpawn); router.Send(npcData, client); } } } //Allways render the stuff below this line. if (client.map.id.ToString()[0] != "1"[0]) //Don't Render dead bodies in town. Town map ids all start with 1 { foreach (DeadBody deadBody in client.map.deadBodies.Values) { RecvDataNotifyCharaBodyData deadBodyData = new RecvDataNotifyCharaBodyData(deadBody); router.Send(deadBodyData, client); } } foreach (Gimmick gimmickSpawn in client.map.gimmickSpawns.Values) { RecvDataNotifyGimmickData gimmickData = new RecvDataNotifyGimmickData(gimmickSpawn); router.Send(gimmickData, client); } foreach (GGateSpawn gGateSpawn in client.map.gGateSpawns.Values) { RecvDataNotifyGGateStoneData gGateSpawnData = new RecvDataNotifyGGateStoneData(gGateSpawn); router.Send(gGateSpawnData, client); } foreach (MapTransition mapTran in client.map.mapTransitions.Values) { RecvDataNotifyMapLink mapLink = new RecvDataNotifyMapLink(mapTran.instanceId, mapTran.referencePos, mapTran.maplinkOffset, mapTran.maplinkWidth, mapTran.maplinkColor, mapTran.maplinkHeading); router.Send(mapLink, client); //un-comment for debugging maplinks to visualize the left and right Reference Positions /* * GGateSpawn gGateSpawn = new GGateSpawn(); * Server.Instances.AssignInstance(gGateSpawn); * gGateSpawn.X = mapTran.LeftPos.X; * gGateSpawn.Y = mapTran.LeftPos.Y; * gGateSpawn.Z = mapTran.LeftPos.Z; * gGateSpawn.Heading = mapTran.MaplinkHeading; * gGateSpawn.Name = $"This is the Left Side of the transition"; * gGateSpawn.Title = $"X: {mapTran.LeftPos.X} Y:{mapTran.LeftPos.Y} "; * gGateSpawn.MapId = mapTran.MapId; * gGateSpawn.ModelId = 1805000; * gGateSpawn.Active = 0; * gGateSpawn.SerialId = 1900001; * * RecvDataNotifyGGateData gGateData = new RecvDataNotifyGGateData(gGateSpawn); * Router.Send(gGateData, client); * * gGateSpawn = new GGateSpawn(); * Server.Instances.AssignInstance(gGateSpawn); * gGateSpawn.X = mapTran.RightPos.X; * gGateSpawn.Y = mapTran.RightPos.Y; * gGateSpawn.Z = mapTran.RightPos.Z; * gGateSpawn.Heading = mapTran.MaplinkHeading; * gGateSpawn.Name = $"This is the Right Side of the transition"; * gGateSpawn.Title = $"X: {mapTran.RightPos.X} Y:{mapTran.RightPos.Y} "; * gGateSpawn.MapId = mapTran.MapId; * gGateSpawn.ModelId = 1805000; * gGateSpawn.Active = 0; * gGateSpawn.SerialId = 1900002; * * gGateData = new RecvDataNotifyGGateData(gGateSpawn); * Router.Send(gGateData, client); */ } // ToDo this should be a database lookup RecvMapFragmentFlag mapFragments = new RecvMapFragmentFlag(client.map.id, 0xff); router.Send(mapFragments, client); IBuffer res = BufferProvider.Provide(); res.WriteInt32(0); router.Send(client, (ushort)AreaPacketId.recv_map_get_info_r, res, ServerType.Area); }
public override void Execute(string[] command, NecClient client, ChatMessage message, List <ChatResponse> responses) { MonsterSpawn monsterSpawn = new MonsterSpawn(); if (!int.TryParse(command[0], out int monsterId)) { responses.Add(ChatResponse.CommandError(client, $"Invalid Number: {command[0]}")); return; } if (!server.settingRepository.monster.TryGetValue(monsterId, out MonsterSetting monsterSetting)) { responses.Add(ChatResponse.CommandError(client, $"Invalid MonsterId: {monsterId}")); return; } if (!int.TryParse(command[1], out int modelId)) { responses.Add(ChatResponse.CommandError(client, $"Invalid Number: {command[1]}")); return; } if (!server.settingRepository.modelCommon.TryGetValue(modelId, out ModelCommonSetting modelSetting)) { responses.Add(ChatResponse.CommandError(client, $"Invalid ModelId: {modelId}")); return; } _Logger.Debug($"modelSetting.Radius [{modelSetting.radius}]"); monsterSpawn.monsterId = monsterSetting.id; monsterSpawn.name = monsterSetting.name; monsterSpawn.title = monsterSetting.title; monsterSpawn.level = (byte)monsterSetting.level; monsterSpawn.modelId = modelSetting.id; monsterSpawn.size = (short)(modelSetting.height / 2); monsterSpawn.radius = (short)modelSetting.radius; monsterSpawn.mapId = client.character.mapId; monsterSpawn.x = client.character.x; monsterSpawn.y = client.character.y; monsterSpawn.z = client.character.z; monsterSpawn.heading = client.character.heading; monsterSpawn.hp.SetMax(100); monsterSpawn.hp.SetCurrent(100); if (!server.database.InsertMonsterSpawn(monsterSpawn)) { responses.Add(ChatResponse.CommandError(client, "MonsterSpawn could not be saved to database")); return; } server.instances.AssignInstance(monsterSpawn); RecvDataNotifyMonsterData monsterData = new RecvDataNotifyMonsterData(monsterSpawn); router.Send(client.map, monsterData); //IBuffer res = BufferProvider.Provide(); //res.WriteUInt32((uint)monsterSetting.id); ////Toggles state between Alive(attackable), Dead(lootable), or Inactive(nothing). //res.WriteInt32(_i); //_i++; //router.Send(client, (ushort)AreaPacketId.recv_monster_state_update_notify, res, ServerType.Area); }
public override void Handle(NecClient client, NecPacket packet) { _necClients = client.map.clientLookup.GetAll(); //if (client.Character.soulFormState == 1) { client.character.state = CharacterState.InvulnerableForm; client.character.hasDied = false; client.character.hp.depleted = false; client.character.deadType = 0; client.character.hp.ToMax(); IBuffer res1 = BufferProvider.Provide(); res1.WriteInt32(0); //Has to be 0 or else you DC res1.WriteUInt32(client.character.deadBodyInstanceId); res1.WriteUInt32(client.character.instanceId); router.Send(client, (ushort)AreaPacketId.recv_revive_init_r, res1, ServerType.Area); IBuffer res3 = BufferProvider.Provide(); res3.WriteUInt32(client.character.deadBodyInstanceId); router.Send(client.map, (ushort)AreaPacketId.recv_object_disappear_notify, res3, ServerType.Area); res3 = BufferProvider.Provide(); res3.WriteUInt32(client.character.instanceId); router.Send(client.map, (ushort)AreaPacketId.recv_object_disappear_notify, res3, ServerType.Area, client); RecvDataNotifyCharaData cData = new RecvDataNotifyCharaData(client.character, client.soul.name); router.Send(client.map, cData.ToPacket()); //Disappear .. all the monsters, NPCs, and characters. welcome to Life! it's less lonely foreach (NpcSpawn npcSpawn in client.map.npcSpawns.Values) { RecvObjectDisappearNotify recvObjectDisappearNotify = new RecvObjectDisappearNotify(npcSpawn.instanceId); router.Send(client, recvObjectDisappearNotify.ToPacket()); } foreach (MonsterSpawn monsterSpawn in client.map.monsterSpawns.Values) { RecvObjectDisappearNotify recvObjectDisappearNotify = new RecvObjectDisappearNotify(monsterSpawn.instanceId); router.Send(client, recvObjectDisappearNotify.ToPacket()); } foreach (NecClient client2 in _necClients) { if (client2 == client) { continue; //Don't dissapear yourself ! that'd be bad news bears. } RecvObjectDisappearNotify recvObjectDisappearNotify = new RecvObjectDisappearNotify(client2.character.instanceId); router.Send(client, recvObjectDisappearNotify.ToPacket()); } List <PacketResponse> brList = new List <PacketResponse>(); RecvBattleReportStartNotify brStart = new RecvBattleReportStartNotify(client.character.instanceId); RecvBattleReportNotifyRaise recvBattleReportNotifyRaise = new RecvBattleReportNotifyRaise(client.character.instanceId); RecvBattleReportEndNotify brEnd = new RecvBattleReportEndNotify(); brList.Add(brStart); brList.Add(recvBattleReportNotifyRaise); brList.Add(brEnd); router.Send(client.map, brList); RecvCharaUpdateMaxHp recvCharaUpdateMaxHp1 = new RecvCharaUpdateMaxHp(client.character.hp.max); router.Send(client, recvCharaUpdateMaxHp1.ToPacket()); Task.Delay(TimeSpan.FromSeconds(3)).ContinueWith (t1 => { RecvCharaUpdateHp cHpUpdate = new RecvCharaUpdateHp(client.character.hp.max); router.Send(client, cHpUpdate.ToPacket()); //if you are not dead, do normal stuff. else... do dead person stuff if (client.character.state != CharacterState.SoulForm) { foreach (NecClient otherClient in _necClients) { if (otherClient == client) { // skip myself continue; } if (otherClient.character.state != CharacterState.SoulForm) { RecvDataNotifyCharaData otherCharacterData = new RecvDataNotifyCharaData(otherClient.character, otherClient.soul.name); router.Send(otherCharacterData, client); } if (otherClient.union != null) { RecvDataNotifyUnionData otherUnionData = new RecvDataNotifyUnionData(otherClient.character, otherClient.union.name); router.Send(otherUnionData, client); } } foreach (MonsterSpawn monsterSpawn in client.map.monsterSpawns.Values) { RecvDataNotifyMonsterData monsterData = new RecvDataNotifyMonsterData(monsterSpawn); router.Send(monsterData, client); } foreach (NpcSpawn npcSpawn in client.map.npcSpawns.Values) { if (npcSpawn.visibility != 2) //2 is the magic number for soul state only. make it an Enum some day { RecvDataNotifyNpcData npcData = new RecvDataNotifyNpcData(npcSpawn); router.Send(npcData, client); } } foreach (DeadBody deadBody in client.map.deadBodies.Values) { if (client.map.id.ToString()[0] != "1"[0]) //Don't Render dead bodies in town. Town map ids all start with 1 { RecvDataNotifyCharaBodyData deadBodyData = new RecvDataNotifyCharaBodyData(deadBody); router.Send(deadBodyData, client); } } } } ); Task.Delay(TimeSpan.FromSeconds(10)).ContinueWith (t1 => { client.character.ClearStateBit(CharacterState.InvulnerableForm); RecvCharaNotifyStateflag recvCharaNotifyStateflag = new RecvCharaNotifyStateflag(client.character.instanceId, (ulong)client.character.state); router.Send(client.map, recvCharaNotifyStateflag.ToPacket()); } ); } /*else if (client.Character.soulFormState == 0) * { * IBuffer res1 = BufferProvider.Provide(); * res1.WriteInt32(client.Character.InstanceId); // ID * res1.WriteInt32(100101); //100101, its the id to get the tombstone * Router.Send(client, (ushort) AreaPacketId.recv_chara_notify_stateflag, res1, ServerType.Area); * * IBuffer res = BufferProvider.Provide(); * res.WriteInt32(1); // 0 = sucess to revive, 1 = failed to revive * Router.Send(client, (ushort) AreaPacketId.recv_raisescale_request_revive_r, res, ServerType.Area); * * IBuffer res5 = BufferProvider.Provide(); * Router.Send(client, (ushort) AreaPacketId.recv_self_lost_notify, res5, ServerType.Area); * }*/ if (client.map.deadBodies.ContainsKey(client.character.deadBodyInstanceId)) { client.map.deadBodies.Remove(client.character.deadBodyInstanceId); } IBuffer res = BufferProvider.Provide(); res.WriteInt32(0); // 0 = sucess to revive, 1 = failed to revive router.Send(client, (ushort)AreaPacketId.recv_raisescale_request_revive_r, res, ServerType.Area); //responsible for camera movement IBuffer res7 = BufferProvider.Provide(); res7.WriteByte(0); //router.Send(client, (ushort)AreaPacketId.recv_event_end, res7, ServerType.Area); //why is this needed? the script play ends the event }
public void Enter(NecClient client, MapPosition mapPosition = null) { if (client.map != null) { client.map.Leave(client); } client.map = this; _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; } //set character coords to default map entry coords If arriving form another map. else if (client.character.mapId != id) { client.character.x = x; client.character.y = y; client.character.z = z; client.character.heading = orientation; } client.character.mapId = id; client.character.mapChange = false; clientLookup.Add(client); _Logger.Debug($"Client Lookup count is now : {clientLookup.GetAll().Count} for map {id} "); _Logger.Debug($"Character State for character {client.character.name} is {client.character.state}"); //Send your character data to the other living or dead players on the map. //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"); } if (!_server.database.UpdateSoul(client.soul)) { _Logger.Error("Could not update the database with soul details "); } //ToDo move all this rendering logic to Send_Map_Entry. We dont need a copy of this logic on every map instance. RecvDataNotifyCharaData myCharacterData = new RecvDataNotifyCharaData(client.character, client.soul.name); //dead //you are dead here. only getting soul form characters. sorry bro. if (client.character.state.HasFlag(CharacterState.SoulForm)) { foreach (NecClient otherClient in clientLookup.GetAll()) { if (otherClient == client) { continue; } if (otherClient.character.state.HasFlag(CharacterState.SoulForm)) { _server.router.Send(myCharacterData, otherClient); } } } else //Bro, you alive! You gon see living characters! { foreach (NecClient otherClient in clientLookup.GetAll()) { if (otherClient == client) { continue; } if (otherClient.character.state.HasFlag(CharacterState.SoulForm)) { continue; } _server.router.Send(myCharacterData, otherClient); } } if (client.union != null) { RecvDataNotifyUnionData myUnionData = new RecvDataNotifyUnionData(client.character, client.union.name); _server.router.Send(this, myUnionData, client); } Task.Delay(TimeSpan.FromSeconds(10)).ContinueWith (t1 => { foreach (MonsterSpawn monsterSpawn in monsterSpawns.Values) { if (monsterSpawn.active) { 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, 2, 0); } } } } } } ); }
public override void Handle(NecClient client, NecPacket packet) { foreach (NecClient otherClient in client.Map.ClientLookup.GetAll()) { if (otherClient == client) { // skip myself continue; } RecvDataNotifyCharaData otherCharacterData = new RecvDataNotifyCharaData(otherClient.Character, otherClient.Soul.Name); Router.Send(otherCharacterData, client); if (otherClient.Union != null) { RecvDataNotifyUnionData otherUnionData = new RecvDataNotifyUnionData(otherClient.Character, otherClient.Union.Name); Router.Send(otherUnionData, client); } } foreach (MonsterSpawn monsterSpawn in client.Map.MonsterSpawns.Values) { if (monsterSpawn.Active == false) { RecvDataNotifyMonsterData monsterData = new RecvDataNotifyMonsterData(monsterSpawn); Logger.Debug($"Monster Id {monsterSpawn.Id} with model {monsterSpawn.ModelId} is loading"); Router.Send(monsterData, client); } } foreach (NpcSpawn npcSpawn in client.Map.NpcSpawns.Values) { // This requires database changes to add the GGates to the Npc database!!!!! if (npcSpawn.Name == "GGate") { GGateSpawn gGate = new GGateSpawn(); gGate.X = npcSpawn.X; gGate.Y = npcSpawn.Y; gGate.Z = npcSpawn.Z; gGate.Heading = npcSpawn.Heading; gGate.MapId = npcSpawn.MapId; gGate.Name = npcSpawn.Name; gGate.Title = npcSpawn.Title; RecvDataNotifyGGateData gGateData = new RecvDataNotifyGGateData(gGate); Router.Send(gGateData, client); } else { RecvDataNotifyNpcData npcData = new RecvDataNotifyNpcData(npcSpawn); Router.Send(npcData, client); } } foreach (Gimmick gimmickSpawn in client.Map.GimmickSpawns.Values) { RecvDataNotifyGimmickData gimmickData = new RecvDataNotifyGimmickData(gimmickSpawn); Router.Send(gimmickData, client); GGateSpawn gGateSpawn = new GGateSpawn(); Server.Instances.AssignInstance(gGateSpawn); gGateSpawn.X = gimmickSpawn.X; gGateSpawn.Y = gimmickSpawn.Y; gGateSpawn.Z = gimmickSpawn.Z + 300; gGateSpawn.Heading = gimmickSpawn.Heading; gGateSpawn.Name = $"gGateSpawn to your current position. ID {gimmickSpawn.ModelId}"; gGateSpawn.Title = $"type '/gimmick move {gimmickSpawn.InstanceId} to move this "; gGateSpawn.MapId = gimmickSpawn.MapId; gGateSpawn.ModelId = 1900001; gGateSpawn.Active = 0; gGateSpawn.SerialId = 1900001; RecvDataNotifyGGateData gGateData = new RecvDataNotifyGGateData(gGateSpawn); Router.Send(gGateData, client); } foreach (GGateSpawn gGateSpawn in client.Map.GGateSpawns.Values) { RecvDataNotifyGGateData gGateSpawnData = new RecvDataNotifyGGateData(gGateSpawn); Router.Send(gGateSpawnData, client); } foreach (DeadBody deadBody in client.Map.DeadBodies.Values) { RecvDataNotifyCharaBodyData deadBodyData = new RecvDataNotifyCharaBodyData(deadBody, client); Router.Send(deadBodyData, client); } foreach (MapTransition mapTran in client.Map.MapTransitions.Values) { MapPosition mapPos = new MapPosition(mapTran.ReferencePos.X, mapTran.ReferencePos.Y, mapTran.ReferencePos.Z, mapTran.MaplinkHeading); RecvDataNotifyMapLink mapLink = new RecvDataNotifyMapLink(client, this.Id, mapPos, mapTran.MaplinkOffset, mapTran.MaplinkWidth, mapTran.MaplinkColor); Router.Send(mapLink, client); } // ToDo this should be a database lookup RecvMapFragmentFlag mapFragments = new RecvMapFragmentFlag(client.Map.Id, 0xff); Router.Send(mapFragments, client); IBuffer res = BufferProvider.Provide(); res.WriteInt32(client.Map.Id); Router.Send(client, (ushort)AreaPacketId.recv_map_get_info_r, res, ServerType.Area); }
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"); } }