Exemplo n.º 1
0
        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} ");
        }
Exemplo n.º 2
0
        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);
            }
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        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());
            }
        }
Exemplo n.º 5
0
        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} ");
        }
Exemplo n.º 6
0
        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);
                    }
                }
            }
                );
        }
Exemplo n.º 7
0
        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);
        }