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"); } if (!_server.database.UpdateSoul(client.soul)) { _Logger.Error("Could not update the database with soul details "); } 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 monsterSpawns.Values) { monsterSpawn.spawnActive = false; } } _Logger.Debug($"Client Lookup count is now : {clientLookup.GetAll().Count} for map {id} "); }
public override void Handle(NecClient client, NecPacket packet) { int response = packet.data.ReadInt32(); //0 for yes, -1 for no; NecClient necClient = server.clients.GetByCharacterInstanceId((uint)client.character.eventSelectExecCode); //Salvager //Notify the dead client that it has accepted body collection and it's soul now posseses the salvager. RecvCharaBodySelfSalvageResult recvCharaBodySelfSalvageResult = new RecvCharaBodySelfSalvageResult(response); router.Send(client, recvCharaBodySelfSalvageResult.ToPacket()); //tell the salvager about your choice. RecvCharaBodySalvageRequest recvCharaBodySalvageRequest = new RecvCharaBodySalvageRequest(response); router.Send(necClient, recvCharaBodySalvageRequest.ToPacket()); if (response == (int)MyResponse.AcceptCollection) { //tell the dead client who collected the body RecvCharaBodySalvageNotifySalvager recvCharaBodySalvageNotifySalvager = new RecvCharaBodySalvageNotifySalvager(necClient.character.instanceId, necClient.character.name, necClient.soul.name); router.Send(client, recvCharaBodySalvageNotifySalvager.ToPacket()); //tell the salvager who they collected. RecvCharaBodySalvageNotifyBody recvCharaBodySalvageNotifyBody = new RecvCharaBodySalvageNotifyBody(client.character.deadBodyInstanceId, client.character.name, client.soul.name); router.Send(necClient, recvCharaBodySalvageNotifyBody.ToPacket()); //tell the salvager to close the charabody access window. RecvCharaBodyAccessEnd recvCharaBodyAccessEnd = new RecvCharaBodyAccessEnd(0); router.Send(necClient, recvCharaBodyAccessEnd.ToPacket()); //Tell the deadBody to disappear from the map, as it's being carried. RecvObjectDisappearNotify recvObjectDisappearNotify = new RecvObjectDisappearNotify(client.character.deadBodyInstanceId); router.Send(client.map, recvObjectDisappearNotify); //Tell the deadClient it can see the salvager even in soul form now. RecvDataNotifyCharaData cData = new RecvDataNotifyCharaData(necClient.character, necClient.soul.name); router.Send(client, cData.ToPacket()); //remove the deadBody from the map so newly entering players can't see it. client.map.deadBodies.Remove(client.character.deadBodyInstanceId); //Add the deadBody to the client that's carrying it for Movement Sends necClient.bodyCollection.Add(client.character.deadBodyInstanceId, client); //move the soulState client to the salvagers position IBuffer res5 = BufferProvider.Provide(); res5.WriteUInt32(client.character.instanceId); res5.WriteFloat(necClient.character.x); res5.WriteFloat(necClient.character.y); res5.WriteFloat(necClient.character.z); res5.WriteByte(necClient.character.heading); //Heading res5.WriteByte(necClient.character.movementAnim); //state router.Send(client, (ushort)AreaPacketId.recv_object_point_move_notify, res5, ServerType.Area); } }
public bool MonsterCheck() { // Logger.Debug($"Monster HP [{_monster.GetHP()}]"); if (_monster.Hp.current <= 0) { foreach (uint instanceId in _monster.GetAgroInstanceList()) { _monster.MonsterHate(_server, false, instanceId); } Logger.Debug($"Monster is dead InstanceId [{_monster.InstanceId}]"); //Death Animation List <PacketResponse> brList = new List <PacketResponse>(); RecvBattleReportStartNotify brStart = new RecvBattleReportStartNotify(_monster.InstanceId); RecvBattleReportEndNotify brEnd = new RecvBattleReportEndNotify(); RecvBattleReportNoactDead brDead = new RecvBattleReportNoactDead(_monster.InstanceId, 1); brList.Add(brStart); brList.Add(brDead); brList.Add(brEnd); _server.Router.Send(Map, brList); //Make the monster a lootable state IBuffer res10 = BufferProvider.Provide(); res10.WriteUInt32(_monster.InstanceId); res10.WriteInt32(2); //Toggles state between Alive(attackable), Dead(lootable), or Inactive(nothing). _server.Router.Send(Map, (ushort)AreaPacketId.recv_monster_state_update_notify, res10, ServerType.Area); Thread.Sleep(_monster.RespawnTime); //decompose the body IBuffer res7 = BufferProvider.Provide(); res7.WriteUInt32(_monster.InstanceId); res7.WriteInt32( 5); //4 here causes a cloud and the model to disappear, 5 causes a mist to happen and disappear res7.WriteInt32(1); _server.Router.Send(Map, (ushort)AreaPacketId.recv_charabody_notify_deadstate, res7, ServerType.Area); Thread.Sleep(2000); RecvObjectDisappearNotify objectDisappearData = new RecvObjectDisappearNotify(_monster.InstanceId); _server.Router.Send(Map, objectDisappearData); _monster.MonsterVisible = false; spawnMonster = true; return(true); } return(false); }
public override void Handle(NecClient client, NecPacket packet) { client.map.deadBodies.TryGetValue(client.character.eventSelectReadyCode, out DeadBody deadBody); Character deadCharacter = _server.instances.GetInstance(deadBody.characterInstanceId) as Character; ItemLocation itemLocation = deadCharacter.lootNotify; NecClient necClient = client.map.clientLookup.GetByCharacterInstanceId(deadBody.characterInstanceId); RecvCharaBodyNotifyLootStartCancel recvCharaBodyNotifyLootStartCancel = new RecvCharaBodyNotifyLootStartCancel((byte)itemLocation.zoneType, itemLocation.container, itemLocation.slot, client.soul.name, client.character.name); if (necClient != null) { router.Send(necClient, recvCharaBodyNotifyLootStartCancel.ToPacket()); } RecvObjectDisappearNotify recvObjectDisappearNotify = new RecvObjectDisappearNotify(client.character.instanceId); if (necClient != null) { router.Send(necClient, recvObjectDisappearNotify.ToPacket()); } }
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} "); }
private void PlayerDead() { _playerDied = true; _client.character.hasDied = true; _client.character.state = CharacterState.SoulForm; _client.character.deadType = (short)Util.GetRandomNumber(1, 4); _Logger.Debug($"Death Animation Number : {_client.character.deadType}"); List <PacketResponse> brList = new List <PacketResponse>(); RecvBattleReportStartNotify brStart = new RecvBattleReportStartNotify(_client.character.instanceId); RecvBattleReportNoactDead cDead1 = new RecvBattleReportNoactDead(_client.character.instanceId, _client.character.deadType); RecvBattleReportEndNotify brEnd = new RecvBattleReportEndNotify(); brList.Add(brStart); brList.Add(cDead1); //animate the death of your living body brList.Add(brEnd); _server.router.Send(_client.map, brList); // send death animation to all players DeadBody deadBody = _server.instances.GetInstance(_client.character.deadBodyInstanceId) as DeadBody; deadBody.x = _client.character.x; deadBody.y = _client.character.y; deadBody.z = _client.character.z; deadBody.heading = _client.character.heading; deadBody.beginnerProtection = (byte)_client.character.beginnerProtection; deadBody.charaName = _client.character.name; deadBody.soulName = _client.soul.name; deadBody.equippedItems = _client.character.equippedItems; deadBody.raceId = _client.character.raceId; deadBody.sexId = _client.character.sexId; deadBody.hairId = _client.character.hairId; deadBody.hairColorId = _client.character.hairColorId; deadBody.faceId = _client.character.faceId; deadBody.faceArrangeId = _client.character.faceArrangeId; deadBody.voiceId = _client.character.voiceId; deadBody.level = _client.character.level; deadBody.classId = _client.character.classId; deadBody.equippedItems = _client.character.equippedItems; deadBody.criminalStatus = _client.character.criminalState; deadBody.connectionState = 1; _clients = _client.map.clientLookup.GetAll(); _client.map.deadBodies.Add(deadBody.instanceId, deadBody); List <NecClient> soulStateClients = new List <NecClient>(); //Disappear .. all the monsters, NPCs, and characters. welcome to death! it's lonely foreach (NpcSpawn npcSpawn in _client.map.npcSpawns.Values) { RecvObjectDisappearNotify recvObjectDisappearNotify = new RecvObjectDisappearNotify(npcSpawn.instanceId); _server.router.Send(_client, recvObjectDisappearNotify.ToPacket()); } foreach (MonsterSpawn monsterSpawn in _client.map.monsterSpawns.Values) { RecvObjectDisappearNotify recvObjectDisappearNotify = new RecvObjectDisappearNotify(monsterSpawn.instanceId); _server.router.Send(_client, recvObjectDisappearNotify.ToPacket()); } foreach (NecClient client in _clients) { if (client == _client) { continue; //Don't dissapear yourself ! that'd be bad news bears. } RecvObjectDisappearNotify recvObjectDisappearNotify = new RecvObjectDisappearNotify(client.character.instanceId); _server.router.Send(_client, recvObjectDisappearNotify.ToPacket()); } //load your dead body on the map for looting. disappear your character model for everyone else besides you Task.Delay(TimeSpan.FromSeconds(5)).ContinueWith (t1 => { RecvDataNotifyCharaBodyData cBodyData = new RecvDataNotifyCharaBodyData(deadBody); if (_client.map.id.ToString()[0] != "1"[0]) //Don't Render dead bodies in town. Town map ids all start with 1 { _server.router.Send(_client.map, cBodyData.ToPacket(), _client); } _server.router.Send(_client, cBodyData.ToPacket()); RecvObjectDisappearNotify recvObjectDisappearNotify = new RecvObjectDisappearNotify(_client.character.instanceId); _server.router.Send(_client.map, recvObjectDisappearNotify.ToPacket(), _client); //send your soul to all the other souls runnin around foreach (NecClient client in _clients) { if (client.character.state == CharacterState.SoulForm) { soulStateClients.Add(client); } } //re-render your soulstate character to your client with out gear on it, and any other soul state clients on map. RecvDataNotifyCharaData cData = new RecvDataNotifyCharaData(_client.character, _client.soul.name); _server.router.Send(soulStateClients, cData.ToPacket()); } ); //Re-render all the NPCs and Monsters, and character objects Task.Delay(TimeSpan.FromSeconds(6)).ContinueWith (t1 => { foreach (NecClient otherClient in _clients) { if (otherClient == _client) { // skip myself continue; } //Render all the souls if you are in soul form yourself if (otherClient.character.state == CharacterState.SoulForm) { RecvDataNotifyCharaData otherCharacterData = new RecvDataNotifyCharaData(otherClient.character, otherClient.soul.name); _server.router.Send(otherCharacterData, _client); } if (otherClient.union != null) { RecvDataNotifyUnionData otherUnionData = new RecvDataNotifyUnionData(otherClient.character, otherClient.union.name); _server.router.Send(otherUnionData, _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); _server.router.Send(npcData, _client); } } } ); }
private void AreaClientDisconnected(NecConnection connection) { NecClient client = connection.client; if (client == null) { return; } //Try to update the character stats. if (!database.UpdateCharacter(client.character)) { _Logger.Error("Could not update the database with character details before disconnect"); } if (!database.UpdateSoul(client.soul)) { _Logger.Error("Could not update the database with soul details before disconnect"); } clients.Remove(client); //I disconnected while my dead body was being carried around by another player if (client.character.hasDied) { DeadBody deadBody = instances.GetInstance(client.character.deadBodyInstanceId) as DeadBody; if (deadBody.salvagerId != 0) { NecClient mySalvager = clients.GetByCharacterInstanceId(deadBody.salvagerId); if (mySalvager != null) { deadBody.x = mySalvager.character.x; deadBody.y = mySalvager.character.y; deadBody.z = mySalvager.character.z; deadBody.mapId = mySalvager.character.mapId; deadBody.connectionState = 0; mySalvager.bodyCollection.Remove(deadBody.instanceId); mySalvager.map.deadBodies.Add(deadBody.instanceId, deadBody); RecvDataNotifyCharaBodyData cBodyData = new RecvDataNotifyCharaBodyData(deadBody); if (client.map.id.ToString()[0] != "1"[0]) //Don't Render dead bodies in town. Town map ids all start with 1 { router.Send(mySalvager.map, cBodyData.ToPacket(), client); } //must occur after the charaBody notify. RecvCharaBodySalvageEnd recvCharaBodySalvageEnd = new RecvCharaBodySalvageEnd(deadBody.instanceId, 5); router.Send(mySalvager, recvCharaBodySalvageEnd.ToPacket()); } } } //while i was dead and being carried around, the player carrying me disconnected foreach (NecClient collectedBody in client.bodyCollection.Values) { DeadBody deadBody = instances.GetInstance(collectedBody.character.deadBodyInstanceId) as DeadBody; RecvCharaBodySelfSalvageEnd recvCharaBodySelfSalvageEnd = new RecvCharaBodySelfSalvageEnd(3); router.Send(collectedBody, recvCharaBodySelfSalvageEnd.ToPacket()); deadBody.x = client.character.x; deadBody.y = client.character.y; deadBody.z = client.character.z; collectedBody.character.x = client.character.x; collectedBody.character.y = client.character.y; collectedBody.character.z = client.character.z; //ToDo add Town checking. if map.ID.toString()[0]==1 skip deadbody rendering deadBody.mapId = client.character.mapId; client.map.deadBodies.Add(deadBody.instanceId, deadBody); RecvDataNotifyCharaBodyData cBodyData = new RecvDataNotifyCharaBodyData(deadBody); if (client.map.id.ToString()[0] != "1"[0]) //Don't Render dead bodies in town. Town map ids all start with 1 { router.Send(client.map, cBodyData.ToPacket()); } //send your soul to all the other souls runnin around RecvDataNotifyCharaData cData = new RecvDataNotifyCharaData(collectedBody.character, collectedBody.soul.name); foreach (NecClient soulStateClient in client.map.clientLookup.GetAll()) { if (soulStateClient.character.state == CharacterState.SoulForm) { router.Send(soulStateClient, cData.ToPacket()); } } } Map map = client.map; //If i was dead, toggle my deadBody to a Rucksack if (map != null) { if (map.deadBodies.ContainsKey(client.character.deadBodyInstanceId)) { map.deadBodies.TryGetValue(client.character.deadBodyInstanceId, out DeadBody deadBody); deadBody.connectionState = 0; RecvCharaBodyNotifySpirit recvCharaBodyNotifySpirit = new RecvCharaBodyNotifySpirit(client.character.deadBodyInstanceId, (byte)RecvCharaBodyNotifySpirit.ValidSpirit.DisconnectedClient); router.Send(map, recvCharaBodyNotifySpirit.ToPacket()); Task.Delay(TimeSpan.FromSeconds(600)).ContinueWith (t1 => { if (map.deadBodies.ContainsKey(client.character.deadBodyInstanceId)) { RecvObjectDisappearNotify recvObjectDisappearNotify = new RecvObjectDisappearNotify(client.character.deadBodyInstanceId); router.Send(client.map, recvObjectDisappearNotify.ToPacket(), client); map.deadBodies.Remove(client.character.deadBodyInstanceId); } } ); } } if (map != null) { map.Leave(client); } Union union = client.union; if (union != null) { union.Leave(client); } Character character = client.character; if (character != null) { instances.FreeInstance(character); character.characterActive = false; } }
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 bool MonsterCheck() { // Logger.Debug($"Monster HP [{_monster.GetHP()}]"); if (monster.hp.current <= 0) { foreach (uint instanceId in monster.GetAgroInstanceList()) { monster.MonsterHate(server, false, instanceId); NecClient client = server.clients.GetByCharacterInstanceId(instanceId); client.character.experienceCurrent += monster.loot.experience; IBuffer res = BufferProvider.Provide(); res.WriteUInt64(client.character.experienceCurrent); res.WriteByte(0); //bool server.router.Send(client, (ushort)AreaPacketId.recv_self_exp_notify, res, ServerType.Area); //This should go to the party of whomever did the most damage. TODO //To-Do, make a variable to track union gold client.character.adventureBagGold += monster.loot.gold; //Updates your Character.AdventureBagGold server.database.UpdateCharacter(client.character); res = BufferProvider.Provide(); res.WriteUInt64(client.character.adventureBagGold); // Sets your Adventure Bag Gold server.router.Send(client, (ushort)AreaPacketId.recv_self_money_notify, res, ServerType.Area); } _Logger.Debug($"Monster is dead InstanceId [{monster.instanceId}]"); //Death Animation List <PacketResponse> brList = new List <PacketResponse>(); RecvBattleReportStartNotify brStart = new RecvBattleReportStartNotify(monster.instanceId); RecvBattleReportEndNotify brEnd = new RecvBattleReportEndNotify(); RecvBattleReportNoactDead brDead = new RecvBattleReportNoactDead(monster.instanceId, 1); brList.Add(brStart); brList.Add(brDead); brList.Add(brEnd); server.router.Send(_map, brList); //Make the monster a lootable state IBuffer res10 = BufferProvider.Provide(); res10.WriteUInt32(monster.instanceId); res10.WriteInt32(2); //Toggles state between Alive(attackable), Dead(lootable), or Inactive(nothing). server.router.Send(_map, (ushort)AreaPacketId.recv_monster_state_update_notify, res10, ServerType.Area); Thread.Sleep(monster.respawnTime); //decompose the body IBuffer res7 = BufferProvider.Provide(); res7.WriteUInt32(monster.instanceId); res7.WriteInt32(Util.GetRandomNumber(1, 5)); //4 here causes a cloud and the model to disappear, 5 causes a mist to happen and disappear res7.WriteInt32(1); server.router.Send(_map, (ushort)AreaPacketId.recv_charabody_notify_deadstate, res7, ServerType.Area); Thread.Sleep(2000); RecvObjectDisappearNotify objectDisappearData = new RecvObjectDisappearNotify(monster.instanceId); server.router.Send(_map, objectDisappearData); monster.monsterVisible = false; _spawnMonster = true; return(true); } return(false); }
private bool MonsterAgro() { Vector3 monster = new Vector3(this.monster.x, this.monster.y, this.monster.z); Character currentTarget = this.monster.GetCurrentTarget(); if (currentTarget == null) { _Logger.Error("No character target set for agroed monster"); return(true); } if (MonsterCheck()) { _Logger.Debug("MonsterCheck returned true"); return(true); } float homeDistance = GetDistance(monsterHome.destination, monster); if (homeDistance >= agroRange * 4) { foreach (uint instanceId in this.monster.GetAgroInstanceList()) { this.monster.MonsterHate(server, false, instanceId); } RecvObjectDisappearNotify objectDisappearData = new RecvObjectDisappearNotify(this.monster.instanceId); server.router.Send(_map, objectDisappearData); _spawnMonster = true; _Logger.Debug("Too far from home"); return(true); } MonsterAgroAdjust(); Vector3 character = new Vector3(currentTarget.x, currentTarget.y, currentTarget.z); float distanceChar = GetDistance(character, monster); if (distanceChar <= this.monster.GetGotoDistance() + 50) { if (monsterMoving) { Thread.Sleep(_updateTime / 2); monsterMoving = false; this.monster.MonsterStop(server, 1, 0, 0.1F); Thread.Sleep(100); } if (!_monsterWaiting) { switch (_castState) { case 0: OrientMonster(); //Casters if (this.monster.monsterId == 100201) { // skillInstanceId = _server.Instances.CreateInstance<Skill>().InstanceId; // Logger.Debug($"attackId [200301411]"); // //_monster.MonsterStop(Server,8, 231, 2.0F); // StartMonsterCastQueue(200301411, skillInstanceId); // PlayerDamage(); // waitTime = 2000; // CastState = 1; } //Melee Attackers else { int attackId = this.monster.attackSkillId * 100 + Util.GetRandomNumber(1, 4); //Logger.Debug($"_monster.AttackSkillId [{_monster.AttackSkillId}] attackId[{attackId}]"); MonsterAttackQueue(attackId); PlayerDamage(); _waitTime = 5000; _castState = 0; } _monsterWaiting = true; _currentWait = 0; break; case 1: //int skillInstanceID = (int)Server.Instances.CreateInstance<Skill>().InstanceId; MonsterCastQueue(200301411); _monsterWaiting = true; _waitTime = 1000; _currentWait = 0; _castState = 3; break; case 2: _monsterWaiting = true; _waitTime = 1000; _currentWait = 0; _castState = 3; break; case 3: //int effectObjectInstanceId = (int)Server.Instances.CreateInstance<Skill>().InstanceId; SendDataNotifyEoData(_skillInstanceId, 301411); SendEoNotifyDisappearSchedule(_skillInstanceId); MonsterCastMove(_skillInstanceId, 3000, 2, 2); _monsterWaiting = true; _waitTime = 5000; _currentWait = 0; _castState = 0; if (_currentSkill < _SkillList.Length - 1) { _currentSkill++; } else { _currentSkill = 0; } break; case 4: _monsterWaiting = true; _waitTime = 5000; _currentWait = 0; _castState = 0; break; } } } else { MonsterAgroMove(); } return(false); }