Ejemplo n.º 1
0
        //*********************************************************************************************
        // playerAttackNpc / Revisto pela última vez em 01/08/2016, criado por Allyson S. Bacon
        // Determinado jogador efetua um ataque em determinado NPC
        //*********************************************************************************************
        public static void playerAttackNpc(int Attacker, int Victim, int isSpell = 0, int Map = 0, bool isPassive = false, int skill_level = 0, bool is_pet = false)
        {
            //EXTEND
            if (Extensions.ExtensionApp.extendMyApp
                    (MethodBase.GetCurrentMethod().Name, Attacker, Victim, isSpell, Map, isPassive, skill_level, is_pet) != null)
            {
                return;
            }

            //CÓDIGO
            if (Map == 0)
            {
                Map = Convert.ToInt32(character[Attacker, player[Attacker].SelectedChar].Map);
            }
            int  Dir         = character[Attacker, player[Attacker].SelectedChar].Dir;
            int  NpcX        = NpcStruct.tempnpc[Map, Victim].X;
            int  NpcY        = NpcStruct.tempnpc[Map, Victim].Y;
            int  PlayerX     = Convert.ToInt32(character[Attacker, player[Attacker].SelectedChar].X);
            int  PlayerY     = Convert.ToInt32(character[Attacker, player[Attacker].SelectedChar].Y);
            int  Damage      = 0;
            int  chance      = 0;
            bool is_critical = false;

            if ((!isPassive) && (isSpell == 0))
            {
                SkillRelations.skillPassive(Attacker, Globals.Target_Npc, Victim);
            }
            if ((NpcStruct.tempnpc[Map, Victim].Vitality <= 0) || (NpcStruct.tempnpc[Map, Victim].Dead))
            {
                return;
            }

            //Cálculo do dano

            //Magias
            if (isSpell > 0)
            {
                int skill_slot = 0;

                if (!isPassive)
                {
                    skill_slot = SkillRelations.getPlayerSkillSlot(Attacker, isSpell);
                }
                else
                {
                    skill_slot = SkillRelations.getPlayerSkillSlot(Attacker, isSpell, true);
                }

                if (skill_slot == 0)
                {
                    return;
                }

                int extra_spellbuff = 0;

                for (int i = 1; i < Globals.MaxSpellBuffs; i++)
                {
                    if (pspellbuff[Attacker, i].active)
                    {
                        if (pspellbuff[Attacker, i].timer > Loops.TickCount.ElapsedMilliseconds)
                        {
                            extra_spellbuff += pspellbuff[Attacker, i].value;
                        }
                        else
                        {
                            pspellbuff[Attacker, i].value  = 0;
                            pspellbuff[Attacker, i].type   = 0;
                            pspellbuff[Attacker, i].timer  = 0;
                            pspellbuff[Attacker, i].active = false;
                        }
                    }
                }

                //Multiplicador de dano
                double multiplier = Convert.ToDouble(SkillStruct.skill[isSpell].scope) / 7.2;

                //Elemento mágico multiplicado
                double min_damage = PlayerRelations.getPlayerMinMagic(Attacker);
                double max_damage = PlayerRelations.getPlayerMaxMagic(Attacker);

                if (hotkey[Attacker, skill_slot].num > Globals.MaxPlayer_Skills)
                {
                    hotkey[Attacker, skill_slot].num = 0;
                    return;
                }

                //Multiplicador de nível
                double levelmultiplier = (1.0 + multiplier) * skill[Attacker, hotkey[Attacker, skill_slot].num].level; //Except

                //Verificando se a skill teve algum problema e corrigindo
                if (levelmultiplier < 1.0)
                {
                    levelmultiplier = 1.0;
                }

                //Dano total que pode ser causado
                double totaldamage    = max_damage + (Convert.ToDouble(SkillStruct.skill[isSpell].damage_formula) * levelmultiplier);
                double totalmindamage = min_damage + (Convert.ToDouble(SkillStruct.skill[isSpell].damage_formula) * levelmultiplier);

                //Passamos para int para tornar o dano exato
                int MinDamage = Convert.ToInt32(totalmindamage);
                int MaxDamage = Convert.ToInt32(totaldamage) + 1;

                if (MinDamage >= MaxDamage)
                {
                    MaxDamage = MinDamage;
                }

                //Definição geral do dano
                Damage  = Globals.Rand(MinDamage, MaxDamage);
                Damage -= (Damage / 100) * tempplayer[Attacker].ReduceDamage;
                Damage  = Damage - ((Damage / 100) * NpcStruct.npc[Map, Victim].MagicDefense);

                if (tempplayer[Attacker].ReduceDamage > 0)
                {
                    SendData.sendActionMsg(Victim, lang.damage_reduced, Globals.ColorWhite, NpcX, NpcY, 1, 0, Map);
                    tempplayer[Attacker].ReduceDamage = 0;
                }

                if (isSpell == 36)
                {
                    Damage += ((Damage / 100) * PlayerRelations.getPlayerDefense(Attacker));
                }

                if (character[Attacker, player[Attacker].SelectedChar].ClassId == 6)
                {
                    for (int i = 1; i < Globals.MaxPlayer_Skills; i++)
                    {
                        if ((skill[Attacker, i].num == 42) && (skill[Attacker, i].level > 0))
                        {
                            //Dano crítico?
                            int critical_t = Globals.Rand(0, 100);

                            if (critical_t <= PlayerRelations.getPlayerCritical(Attacker))
                            {
                                Damage = Convert.ToInt32((Convert.ToDouble(Damage) * 1.5));
                                SendData.sendAnimation(Map, Globals.Target_Npc, Victim, 152);
                            }
                            //break;
                        }
                        if ((skill[Attacker, i].num == 41) && (skill[Attacker, i].level > 0))
                        {
                            if (isSpell == 40)
                            {
                                int open_passive = SkillRelations.getOpenPassiveEffect(Attacker);

                                if (open_passive == 0)
                                {
                                    return;
                                }

                                ppassiveffect[Attacker, open_passive].spellnum   = skill[Attacker, i].num;
                                ppassiveffect[Attacker, open_passive].timer      = Loops.TickCount.ElapsedMilliseconds + SkillStruct.skill[skill[Attacker, i].num].passive_interval;
                                ppassiveffect[Attacker, open_passive].target     = Victim;
                                ppassiveffect[Attacker, open_passive].targettype = Globals.Target_Npc;
                                ppassiveffect[Attacker, open_passive].type       = 1;
                                ppassiveffect[Attacker, open_passive].active     = true;
                            }
                            //break;
                        }
                    }
                }

                if (Damage < 1)
                {
                    SendData.sendActionMsg(Attacker, lang.resisted, Globals.ColorPink, NpcX, NpcY, Globals.Action_Msg_Scroll, 0, Map);
                    return;
                }

                if (extra_spellbuff > 0)
                {
                    //BUFFF :DDDD
                    Damage += (Damage / 100) * extra_spellbuff;
                }

                int drain = SkillStruct.skill[isSpell].drain;

                //Drenagem de vida?
                if (drain > 0)
                {
                    double real_drain = (Convert.ToDouble(Damage) / 100) * drain;
                    PlayerLogic.HealPlayer(Attacker, Convert.ToInt32(real_drain));
                    //SendData.sendActionMsg(Attacker, Convert.ToInt32(real_drain).ToString(), Globals.ColorGreen, PlayerX, PlayerY, 1, 1);
                    //SendData.sendPlayerVitalityToMap(Map, Attacker, tempplayer[Attacker].Vitality);
                }

                NpcStruct.tempnpc[Map, Victim].Target = Attacker;
            }
            //Ataques básicos
            else
            {
                if (tempplayer[Attacker].Blind)
                {
                    SendData.sendActionMsg(Attacker, lang.attack_missed, Globals.ColorWhite, NpcX, NpcY, 1, 0, Map);
                    return;
                }

                //Desviar do golpe?
                int parry_test = Globals.Rand(0, 100);

                if (parry_test <= (NpcStruct.getNpcParry(Map, Victim) - PlayerRelations.getPlayerCritical(Attacker)))
                {
                    SendData.sendActionMsg(Attacker, lang.attack_missed, Globals.ColorWhite, NpcX, NpcY, 1, 0, Map);
                    return;
                }

                //Dano comum
                int MinDamage = PlayerRelations.getPlayerMinAttack(Attacker);
                int MaxDamage = PlayerRelations.getPlayerMaxAttack(Attacker);

                if (is_pet)
                {
                    string   equipment = character[Attacker, player[Attacker].SelectedChar].Equipment;
                    string[] equipdata = equipment.Split(',');
                    string[] petdata   = equipdata[4].Split(';');

                    int petnum = Convert.ToInt32(petdata[0]);
                    int petlvl = Convert.ToInt32(petdata[1]);

                    MinDamage = (Convert.ToInt32(ItemStruct.item[petnum].damage_variance)) + ((petlvl / 2) * Convert.ToInt32(ItemStruct.item[petnum].damage_formula));
                    MaxDamage = (Convert.ToInt32(ItemStruct.item[petnum].damage_variance)) + ((petlvl) * Convert.ToInt32(ItemStruct.item[petnum].damage_formula));

                    if (MinDamage >= MaxDamage)
                    {
                        Damage  = MinDamage;
                        Damage -= (Damage / 100) * tempplayer[Attacker].ReduceDamage;
                        Damage  = Damage - ((Damage / 100) * NpcStruct.npc[Map, Victim].Defense);
                    }
                    else
                    {
                        Damage  = Globals.Rand(MinDamage, MaxDamage);
                        Damage -= (Damage / 100) * tempplayer[Attacker].ReduceDamage;
                        Damage  = Damage - ((Damage / 100) * NpcStruct.npc[Map, Victim].Defense);
                    }

                    SendData.sendAnimation(Map, Globals.Target_Npc, Victim, ItemStruct.item[petnum].animation_id);
                    SendData.sendActionMsg(Attacker, "-" + Damage.ToString(), Globals.ColorPurple, NpcX, NpcY, 1, character[Attacker, player[Attacker].SelectedChar].Dir, Map);
                    goto important;
                }

                if (MinDamage >= MaxDamage)
                {
                    Damage  = MinDamage;
                    Damage -= (Damage / 100) * tempplayer[Attacker].ReduceDamage;
                    Damage  = Damage - ((Damage / 100) * NpcStruct.npc[Map, Victim].Defense);
                }
                else
                {
                    Damage  = Globals.Rand(MinDamage, MaxDamage);
                    Damage -= (Damage / 100) * tempplayer[Attacker].ReduceDamage;
                    Damage  = Damage - ((Damage / 100) * NpcStruct.npc[Map, Victim].Defense);
                }

                if (character[Attacker, player[Attacker].SelectedChar].ClassId == 2)
                {
                    for (int i = 1; i < Globals.MaxPlayer_Skills; i++)
                    {
                        if ((skill[Attacker, i].num == 52) && (skill[Attacker, i].level > 0))
                        {
                            Damage += ((NpcStruct.npc[Map, Victim].Vitality / 100) * (2 + skill[Attacker, i].level));
                        }
                    }
                }

                if (tempplayer[Attacker].ReduceDamage > 0)
                {
                    SendData.sendActionMsg(Victim, lang.damage_reduced, Globals.ColorWhite, NpcX, NpcY, 1, 0, Map);
                    tempplayer[Attacker].ReduceDamage = 0;
                }

                if (Damage <= 0)
                {
                    Damage = 1;
                }

                //Dano crítico?
                int critical_test = Globals.Rand(0, 100);

                if (critical_test <= PlayerRelations.getPlayerCritical(Attacker))
                {
                    Damage      = Convert.ToInt32((Convert.ToDouble(Damage) * 1.5));
                    is_critical = true;
                    NpcStruct.tempnpc[Map, Victim].Target = Attacker;
                }

                //Dano e animação
                SendData.sendAnimation(Map, 2, Victim, 7);
            }

            if (is_critical)
            {
                SendData.sendActionMsg(Attacker, "-" + Damage.ToString(), 1, NpcX, NpcY, 1, character[Attacker, player[Attacker].SelectedChar].Dir, Map);
                int true_range = 0;
                for (int i = 1; i <= 2; i++)
                {
                    if (MovementRelations.canThrowNpc(Map, Victim, character[Attacker, player[Attacker].SelectedChar].Dir, i))
                    {
                        true_range += 1;
                    }
                    else
                    {
                        break;
                    }
                }

                if (true_range < 2)
                {
                    Damage += 2 - true_range;
                }

                if (true_range > 0)
                {
                    MovementRelations.throwNpc(Map, Victim, character[Attacker, player[Attacker].SelectedChar].Dir, true_range);
                }
            }
            else
            {
                if (isSpell > 0)
                {
                    SendData.sendActionMsg(Attacker, "-" + Damage.ToString(), Globals.ColorPink, NpcX, NpcY, Globals.Action_Msg_Scroll, character[Attacker, player[Attacker].SelectedChar].Dir, Map);
                }
                else
                {
                    SendData.sendActionMsg(Attacker, "-" + Damage.ToString(), 4, NpcX, NpcY, Globals.Action_Msg_Scroll, character[Attacker, player[Attacker].SelectedChar].Dir, Map);
                }
            }

important:
            //Nova vida do npc
            NpcStruct.tempnpc[Map, Victim].Vitality -= Damage;

            //O NPC é um coletor?
            if (NpcStruct.tempnpc[Map, Victim].guildnum > 0)
            {
                if (!MapStruct.tempmap[Map].WarActive)
                {
                    MapStruct.tempmap[Map].WarActive = true;
                    SendData.sendMsgToGuild(NpcStruct.tempnpc[Map, Victim].guildnum, lang.the_colector_of + " " + MapStruct.map[Map].name + " " + lang.is_being_attacked, Globals.ColorYellow, Globals.Msg_Type_Server);
                }
                MapStruct.tempmap[Map].WarTimer = Loops.TickCount.ElapsedMilliseconds + 20000;
                //Avisar a guilda sobre seu ataque
            }

            //Sleep?
            if (NpcStruct.tempnpc[Map, Victim].Sleeping)
            {
                NpcStruct.tempnpc[Map, Victim].Sleeping   = false;
                NpcStruct.tempnpc[Map, Victim].SleepTimer = 0;
                SendData.sendSleep(Map, 2, Victim, 0);
            }

            //Enviamos a nova vida do npc
            SendData.sendNpcVitality(Map, Victim, NpcStruct.tempnpc[Map, Victim].Vitality);

            if ((NpcStruct.npc[Map, Victim].Type == 1) && (NpcStruct.tempnpc[Map, Victim].Target == 0))
            {
                NpcStruct.tempnpc[Map, Victim].Target = Attacker;
            }

            if (NpcStruct.tempnpc[Map, Victim].Vitality <= 0)
            {
                //Npc era um coletor?
                if (NpcStruct.tempnpc[Map, Victim].guildnum > 0)
                {
                    SendData.sendMsgToAll(lang.the_area + " " + MapStruct.map[Map].name + " " + lang.is_free_now, Globals.ColorYellow, Globals.Msg_Type_Server);
                    SendData.sendMsgToGuild(NpcStruct.tempnpc[Map, Victim].guildnum, lang.the_colector_of + " " + MapStruct.map[Map].name + " " + lang.has_been_defeated, Globals.ColorYellow, Globals.Msg_Type_Server);
                    SendData.sendMsgToPlayer(Attacker, lang.colector_defeated_success, Globals.ColorYellow, Globals.Msg_Type_Server);
                    PlayerRelations.givePlayerGold(Attacker, MapStruct.map[Map].guildgold);
                    MapStruct.map[Map].guildnum  = 0;
                    MapStruct.map[Map].guildgold = 0;
                    NpcStruct.clearTempNpc(Map, Victim);
                    SendData.sendMapGuildToMap(Map);
                    MapStruct.tempmap[Map].NpcCount = MapStruct.getMapNpcCount(Map);
                    //Avisamos que o npc tem que sumir
                    SendData.sendNpcLeft(Map, Victim);
                    return;
                }

                //O mapa possúi um coletor?
                int guildnum = MapStruct.map[Map].guildnum;
                if (guildnum > 0)
                {
                    int total_exp = (NpcStruct.npc[Map, Victim].Exp / 100) * 10; //10%
                    if (total_exp <= 0)
                    {
                        total_exp = 1;
                    }
                    int total_gold = (NpcStruct.npc[Map, Victim].Gold / 100) * 10; //10%
                    if (total_gold <= 0)
                    {
                        total_gold = 1;
                    }
                    GuildStruct.guild[guildnum].exp += total_exp;
                    MapStruct.map[Map].guildgold    += total_gold;
                }

                //Entrega a exp para o grupo
                PartyRelations.partyShareExp(Attacker, Victim, Map);

                //Avisamos que o npc tem que sumir
                SendData.sendNpcLeft(Map, Victim);

                //Morto
                NpcStruct.tempnpc[Map, Victim].Dead = true;

                //Drop
                for (int i = 0; i <= NpcStruct.getNpcDropCount(Map, Victim); i++)
                {
                    chance = Globals.Rand(1, NpcStruct.npcdrop[Map, Victim, i].Chance);
                    if (chance == NpcStruct.npcdrop[Map, Victim, i].Chance)
                    {
                        if (MapStruct.getNullMapItem(Map) == 0)
                        {
                            break;
                        }
                        int NullMapItem = MapStruct.getNullMapItem(Map);
                        if (NpcStruct.npcdrop[Map, Victim, i].ItemType > 1)
                        {
                            DropRelations.dropItem(Map, NullMapItem, NpcX, NpcY, NpcStruct.npcdrop[Map, Victim, i].Value, NpcStruct.npcdrop[Map, Victim, i].ItemNum, NpcStruct.npcdrop[Map, Victim, i].ItemType, DropRelations.getRefinDrop());
                        }
                        else
                        {
                            DropRelations.dropItem(Map, NullMapItem, NpcX, NpcY, NpcStruct.npcdrop[Map, Victim, i].Value, NpcStruct.npcdrop[Map, Victim, i].ItemNum, NpcStruct.npcdrop[Map, Victim, i].ItemType, 0);
                        }
                        SendData.sendMapItem(Map, NullMapItem);
                    }
                    else
                    {
                        //Tentar de novo
                        if (PlayerRelations.isPlayerPremmy(Attacker))
                        {
                            chance = Globals.Rand(1, NpcStruct.npcdrop[Map, Victim, i].Chance * 2);
                            if (chance == NpcStruct.npcdrop[Map, Victim, i].Chance * 2)
                            {
                                if (MapStruct.getNullMapItem(Map) == 0)
                                {
                                    break;
                                }
                                int NullMapItem = MapStruct.getNullMapItem(Map);
                                if (NpcStruct.npcdrop[Map, Victim, i].ItemType > 1)
                                {
                                    DropRelations.dropItem(Map, NullMapItem, NpcX, NpcY, NpcStruct.npcdrop[Map, Victim, i].Value, NpcStruct.npcdrop[Map, Victim, i].ItemNum, NpcStruct.npcdrop[Map, Victim, i].ItemType, DropRelations.getRefinDrop());
                                }
                                else
                                {
                                    DropRelations.dropItem(Map, NullMapItem, NpcX, NpcY, NpcStruct.npcdrop[Map, Victim, i].Value, NpcStruct.npcdrop[Map, Victim, i].ItemNum, NpcStruct.npcdrop[Map, Victim, i].ItemType, 0);
                                }
                                SendData.sendMapItem(Map, NullMapItem);
                            }
                        }
                    }
                }


                //GOLD
                PlayerRelations.givePlayerGold(Attacker, NpcStruct.npc[Map, Victim].Gold);

                //Limpar dados de estudo de movimento
                NpcIA.clearPrevMove(Map, Victim);

                ///Temporizador para voltar
                NpcStruct.tempnpc[Map, Victim].RespawnTimer = Loops.TickCount.ElapsedMilliseconds + NpcStruct.npc[Map, Victim].Respawn;
            }
        }
Ejemplo n.º 2
0
        //*********************************************************************************************
        // DisconnectUser / Revisto pela última vez em 01/08/2016, criado por Allyson S. Bacon
        // Desconectar o jogador.
        //*********************************************************************************************
        public static void disconnectUser(int clientid)
        {
            //EXTEND
            if (Extensions.ExtensionApp.extendMyApp
                    (MethodBase.GetCurrentMethod().Name, clientid) != null)
            {
                return;
            }

            //CÓDIGO
            //LOL
            if ((Clients.Count <= 0) || (clientid > Clients.Count - 1))
            {
                return;
            }
            //Se estiver morto, resetar posição
            //PlayerStruct.tempplayer[Clients[clientid].s].isDead = false;

            //Sai da troca
            if (PlayerStruct.tempplayer[Clients[clientid].s].InTrade > 0)
            {
                TradeRelations.giveTrade(Clients[clientid].s);
                TradeRelations.giveTrade(PlayerStruct.tempplayer[Clients[clientid].s].InTrade);

                //Verificar se o jogador não se desconectou no processo
                if (Clients[(UserConnection.getS(PlayerStruct.tempplayer[Clients[clientid].s].InTrade))].IsConnected)
                {
                    SendData.sendPlayerG(PlayerStruct.tempplayer[Clients[clientid].s].InTrade);
                    SendData.sendTradeClose(PlayerStruct.tempplayer[Clients[clientid].s].InTrade);
                    SendData.sendInvSlots(PlayerStruct.tempplayer[Clients[clientid].s].InTrade, PlayerStruct.player[PlayerStruct.tempplayer[Clients[clientid].s].InTrade].SelectedChar);
                }

                TradeRelations.clearTempTrade(PlayerStruct.tempplayer[Clients[clientid].s].InTrade);
                TradeRelations.clearTempTrade(Clients[clientid].s);
            }

            //Sai do Craft
            if (PlayerStruct.tempplayer[Clients[clientid].s].InCraft)
            {
                for (int i = 1; i < Globals.Max_Craft; i++)
                {
                    if (PlayerStruct.craft[Clients[clientid].s, i].num > 0)
                    {
                        InventoryRelations.giveItem(Clients[clientid].s, PlayerStruct.craft[Clients[clientid].s, i].type, PlayerStruct.craft[Clients[clientid].s, i].num, PlayerStruct.craft[Clients[clientid].s, i].value, PlayerStruct.craft[Clients[clientid].s, i].refin, PlayerStruct.craft[Clients[clientid].s, i].exp);
                    }
                }
            }

            //Salva o jogador SE PRECISAR
            if (PlayerStruct.tempplayer[Clients[clientid].s].ingame)
            {
                Database.Characters.saveCharacter(Clients[clientid].s, PlayerStruct.player[Clients[clientid].s].Email, PlayerStruct.player[Clients[clientid].s].SelectedChar);
                Database.Banks.saveBank(Clients[clientid].s);
                Database.FriendLists.saveFriendList(Clients[clientid].s);
            }

            //Sai do grupo
            if (PlayerStruct.tempplayer[Clients[clientid].s].Party > 0)
            {
                PartyRelations.kickParty(Clients[clientid].s, Clients[clientid].s, true);
            }

            //Vamos avisar ao mapa que o jogador saiu
            SendData.sendPlayerLeft(PlayerStruct.character[Clients[clientid].s, PlayerStruct.player[Clients[clientid].s].SelectedChar].Map, Clients[clientid].s);

            //Apagamos o banco
            Database.Banks.clearBank(Clients[clientid].s);

            Console.WriteLine(lang.player_cleared + " " + clientid + Clients[clientid].s);

            //Fecha a conexão
            Clients[clientid].Async.Close();

            //Limpa dados sobre o jogador
            Clients[clientid].Async = null;

            //Limpa dados temporários sobre o jogador
            PlayerStruct.clearPlayer(Clients[clientid].s, true);
            PlayerStruct.clearTempPlayer(Clients[clientid].s);

            //Limpa informações gerais da conexão
            Clients[clientid].s = -1;

            //Remova da lista de clientes do servidor
            Clients.RemoveAt(clientid);

            //Zerar o Player_Highs pra evitar problemas
            Globals.Player_Highs = 0;

            //Vamos atualizar o Player_Highs sem frescura
            for (int i = 0; i < WinsockAsync.Clients.Count(); i++)
            {
                if (Clients[i].s > Globals.Player_Highs)
                {
                    Globals.Player_Highs = Clients[i].s;
                }
            }

            //Vamos atualizar o Player_Highs para todos os jogadores
            SendData.sendUpdatePlayerHighs();

            Log(lang.player_disconnected + " " + clientid);
        }
Ejemplo n.º 3
0
        //*********************************************************************************************
        // partyShareExp / Revisto pela última vez em 01/08/2016, criado por Allyson S. Bacon
        // Divide a Exp para determinado grupo baseado no atacante
        //*********************************************************************************************
        public static void partyShareExp(int Attacker, int Victim, int Map)
        {
            //EXTEND
            if (Extensions.ExtensionApp.extendMyApp
                    (MethodBase.GetCurrentMethod().Name, Attacker, Victim, Map) != null)
            {
                return;
            }

            //CÓDIGO
            int NpcX    = NpcStruct.tempnpc[Map, Victim].X;
            int NpcY    = NpcStruct.tempnpc[Map, Victim].Y;
            int PlayerX = Convert.ToInt32(PlayerStruct.character[Attacker, PlayerStruct.player[Attacker].SelectedChar].X);
            int PlayerY = Convert.ToInt32(PlayerStruct.character[Attacker, PlayerStruct.player[Attacker].SelectedChar].Y);

            //PARTY EXP
            int partynum = PlayerStruct.tempplayer[Attacker].Party;

            //Damos xp ao jogador e mostramos a xp ganha
            if (partynum > 0)
            {
                int memberscount = PartyRelations.getPartyMembersCount(partynum);
                for (int i = 1; i <= memberscount; i++)
                {
                    int members = PlayerStruct.partymembers[partynum, i].s;
                    if (PlayerStruct.character[members, PlayerStruct.player[members].SelectedChar].Map == PlayerStruct.character[Attacker, PlayerStruct.player[Attacker].SelectedChar].Map)
                    {
                        //Tem grupo para dividir a exp
                        //Adiciona uma kill se houver uma quest para esse npc
                        for (int g = 1; g < Globals.MaxQuestGivers; g++)
                        {
                            for (int q = 1; q < Globals.MaxQuestPerGiver; q++)
                            {
                                //Prevent
                                if ((String.IsNullOrEmpty(MapStruct.quest[g, q].type)) && (PlayerStruct.queststatus[members, g, q].status > 0))
                                {
                                    PlayerStruct.queststatus[members, g, q].status = 0; return;
                                }

                                //Execute
                                if ((PlayerStruct.queststatus[members, g, q].status == 1) && (Convert.ToInt32(MapStruct.quest[g, q].type.Split('|')[0]) > 0))
                                {
                                    for (int k = 1; k < Globals.MaxQuestKills; k++)
                                    {
                                        if (MapStruct.questkills[g, q, k].monstername == NpcStruct.npc[Map, Victim].Name)
                                        {
                                            if (PlayerStruct.questkills[members, g, q, k].kills < MapStruct.questkills[g, q, k].value)
                                            {
                                                PlayerStruct.questkills[members, g, q, k].kills += 1;
                                                SendData.sendActionMsg(members, lang.quest_defeat + " " + MapStruct.questkills[g, q, k].monstername + " " + PlayerStruct.questkills[members, g, q, k].kills + "/" + MapStruct.questkills[g, q, k].value, Globals.ColorGreen, NpcX, NpcY, 0, PlayerStruct.character[Attacker, PlayerStruct.player[Attacker].SelectedChar].Dir);
                                                SendData.sendQuestKill(members, g, q, k);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        int exp = NpcStruct.npc[Map, Victim].Exp;
                        if (PlayerRelations.isPlayerPremmy(members))
                        {
                            exp = Convert.ToInt32(exp * 1.5);
                        }
                        PlayerRelations.givePlayerExp(members, exp);
                    }
                }
            }
            //Não tem grupo para dividir a exp
            else
            {
                //Adiciona uma kill se houver uma quest para esse npc
                for (int g = 1; g < Globals.MaxQuestGivers; g++)
                {
                    for (int q = 1; q < Globals.MaxQuestPerGiver; q++)
                    {
                        //Prevent
                        if ((String.IsNullOrEmpty(MapStruct.quest[g, q].type)) && (PlayerStruct.queststatus[Attacker, g, q].status > 0))
                        {
                            PlayerStruct.queststatus[Attacker, g, q].status = 0; return;
                        }

                        //Execute
                        if ((PlayerStruct.queststatus[Attacker, g, q].status == 1) && (Convert.ToInt32(MapStruct.quest[g, q].type.Split('|')[0]) > 0))
                        {
                            for (int k = 1; k < Globals.MaxQuestKills; k++)
                            {
                                if (MapStruct.questkills[g, q, k].monstername == NpcStruct.npc[Map, Victim].Name)
                                {
                                    if (PlayerStruct.questkills[Attacker, g, q, k].kills < MapStruct.questkills[g, q, k].value)
                                    {
                                        PlayerStruct.questkills[Attacker, g, q, k].kills += 1;
                                        SendData.sendActionMsg(Attacker, lang.quest_defeat + " " + MapStruct.questkills[g, q, k].monstername + " " + PlayerStruct.questkills[Attacker, g, q, k].kills + "/" + MapStruct.questkills[g, q, k].value, Globals.ColorGreen, NpcX, NpcY, 0, PlayerStruct.character[Attacker, PlayerStruct.player[Attacker].SelectedChar].Dir);
                                        SendData.sendQuestKill(Attacker, g, q, k);
                                    }
                                }
                            }
                        }
                    }
                }
                int exp = NpcStruct.npc[Map, Victim].Exp;
                if (PlayerRelations.isPlayerPremmy(Attacker))
                {
                    exp = Convert.ToInt32(exp * 1.5);
                }
                PlayerRelations.givePlayerExp(Attacker, exp);
            }
        }