Inheritance: MonoBehaviour
 public static void SetSp(PlayerMgr sys, int sp)
 {
     try
     {
         sys.Character.Information.SkillPoint += ((sp + sys.Character.Information.SpBar) / 400);
         sys.Character.Information.SpBar = ((sp + sys.Character.Information.SpBar) % 400);
         sys.client.Send(Client.Packet.InfoUpdate(2, sys.Character.Information.SkillPoint, 0));
     }
     catch (Exception ex)
     {
         Log.Exception(ex);
     }
 }
        public void CalcSharedPartyExpSp(int paramexp, party pt, PlayerMgr targetplayer, ref long outexp)
        {
            try
            {
                byte mlv = ObjData.Manager.ObjectBase[ID].Level;
                // party average
                int k = 0;
                List<int> NearbyMembers = new List<int>(9);
                if (pt.Members.Count != 0)
                {
                    double playerDist;
                    foreach (int memb in pt.Members)
                    {
                        PlayerMgr i = Helpers.GetInformation.GetPlayer(memb);
                        //playerDist = Formule.gamedistance(targetplayer.Character.Position.x, targetplayer.Character.Position.y, i.Character.Position.x, i.Character.Position.y);
                        playerDist = Formule.gamedistance(targetplayer.Character.Position, i.Character.Position);
                        if (playerDist >= 50)
                        {
                            NearbyMembers.Add(i.Character.Information.UniqueID);
                        }
                    }
                    foreach (int l in NearbyMembers)
                    {
                        k += Helpers.GetInformation.GetPlayer(l).Character.Information.Level;
                    }
                    k = (int)(k / pt.Members.Count);
                    //k = átlag.
                    foreach (int mem in NearbyMembers)
                    {

                        PlayerMgr ch = Helpers.GetInformation.GetPlayer(mem);
                        int ptsp = 97;
                        //This isn't the right formula. TODO: We must find the right one!
                        int ptexp = (int)((((paramexp / mlv) + (mlv - k)) * mlv) / k) * ch.Character.Information.Level;
                        ptexp *= Helpers.Settings.Rate.Experience;
                        byte kat = Kat;
                        if (kat == 20) kat = 25;
                        ptexp *= kat; //we multiply the exp according to type of the mob.
                        //TODO: premium ticket
                        //gap:
                        ptexp -= (ptexp * (ch.Character.Information.Level) - Math.Abs(ch.Character.Information.Level - ch.MasteryGetBigLevel)) * 10 / 100;
                        if (ch.Character.Information.Level == 110 && ch.Character.Information.XP >= 4000000000) ptexp = 0;
                        //we calculate the amount of sp:
                        if (Math.Abs(ObjData.Manager.ObjectBase[ID].Level - k) < 10)
                        {
                            int gap = Math.Abs(ch.Character.Information.Level - ch.MasteryGetBigLevel) * 10;
                            if (gap >= 90) gap = 90;
                            ptsp = (ptsp * (100 + gap)) / k; //Instead of 100 I share with the avareage of the party, so we get a proportionate number.
                            ptsp *= kat;
                            ptsp *= Helpers.Settings.Rate.SkillPoint;
                        }
                        //Send total to all in party (Set exp from formula)
                        SetPartyMemberExp(ch, (long)ptexp, ch.Character.Information.Attributes, (long)ptsp);
                        SetSp(ch, ptsp);
                        if (ch.Character.Network.Guild.Guildid != 0)
                        {
                            if (Math.Abs(ch.Character.Network.Guild.LastDonate - ch.Character.Network.Guild.DonateGP) >= 10)
                            {
                                DB.query("UPDATE guild_members SET guild_points='" + ch.Character.Network.Guild.DonateGP + "' WHERE guild_member_id='" + ch.Character.Information.CharacterID + "'");
                                ch.Character.Network.Guild.LastDonate = ch.Character.Network.Guild.DonateGP;

                                // set new amount to every guild members guild class
                                foreach (int m in ch.Character.Network.Guild.Members)
                                {
                                    int targetindex = ch.Character.Network.Guild.MembersInfo.FindIndex(i => i.MemberID == m);
                                    if (ch.Character.Network.Guild.MembersInfo[targetindex].Online)
                                    {
                                        PlayerMgr sys = Helpers.GetInformation.GetPlayer(m);

                                        // here comes the messy way
                                        ObjData.guild_player mygp = new ObjData.guild_player();
                                        int myindex = 0;
                                        foreach (ObjData.guild_player gp in sys.Character.Network.Guild.MembersInfo)
                                        {
                                            if (gp.MemberID == ch.Character.Information.CharacterID)
                                            {
                                                mygp = gp;
                                                mygp.DonateGP = ch.Character.Network.Guild.DonateGP;
                                                break;
                                            }
                                            myindex++;
                                        }
                                        sys.Character.Network.Guild.MembersInfo[myindex] = mygp;
                                    }
                                }

                                ch.Character.Network.Guild.Send(Client.Packet.GuildUpdate(ch.Character, 9, 0, 0, 0));
                            }
                        }
                        outexp = ptexp;
                    }
                }
                else return;
            }
            catch (Exception ex)
            {
                Log.Exception(ex);
            }
        }
        public static void SetPartyMemberExp(PlayerMgr ch, long expamount, short stat, long sp)
        {
            try
            {
                ch.Character.Information.XP += expamount;
                bool level = false;
                while (ch.Character.Information.XP >= ObjData.Manager.LevelData[ch.Character.Information.Level])
                {
                    ch.Character.Information.XP -= ObjData.Manager.LevelData[ch.Character.Information.Level];
                    if (ch.Character.Information.XP < 1) ch.Character.Information.XP = 0;
                    stat += 3;
                    ch.Character.Information.Attributes += 3;
                    ch.Character.Information.Level++;
                    ch.Character.Stat.Intelligence++;
                    ch.Character.Stat.Strength++;
                    ch.UpdateIntelligenceInfo(1);
                    ch.UpdateStrengthInfo(1);
                    ch.SetStat();
                    level = true;
                }
                if (level)
                {
                    if (ch.Character.Network.Guild.Guildid != 0)
                    {
                        // 1 question again where we  set info to databse at lvlup? ah got it :)
                        ch.Character.Network.Guild.Send(Client.Packet.GuildUpdate(ch.Character, 8, 0, 0, 0));

                        // set new amount to every guild members guild class
                        foreach (int m in ch.Character.Network.Guild.Members)
                        {
                            int targetindex = ch.Character.Network.Guild.MembersInfo.FindIndex(i => i.MemberID == m);
                            if (ch.Character.Network.Guild.MembersInfo[targetindex].Online)
                            {
                                PlayerMgr sys = Helpers.GetInformation.GetPlayer(m);

                                // here comes the messy way
                                ObjData.guild_player mygp = new ObjData.guild_player();
                                int myindex = 0;
                                foreach (ObjData.guild_player gp in sys.Character.Network.Guild.MembersInfo)
                                {
                                    if (gp.MemberID == ch.Character.Information.CharacterID)
                                    {
                                        mygp = gp;
                                        mygp.Level = ch.Character.Information.Level;
                                        break;
                                    }
                                    myindex++;
                                }
                                sys.Character.Network.Guild.MembersInfo[myindex] = mygp;
                            }
                        }
                    }
                    ch.Send(Client.Packet.Player_LevelUpEffect(ch.Character.Information.UniqueID));
                    ch.client.Send(Client.Packet.Player_getExp(ch.Character.Information.UniqueID, expamount, sp, stat));
                    ch.SavePlayerInfo();
                }
                else
                {
                    ch.client.Send(Client.Packet.Player_getExp(ch.Character.Information.UniqueID, expamount, sp, 0));
                    ch.SavePlayerExperince();
                }
            }
            catch (Exception ex)
            {
                Log.Exception(ex);
            }
        }
        public static byte[] UnionInfo(PlayerMgr c)
        {
            PacketWriter Writer = new PacketWriter();
            Writer.Create(OperationCode.SERVER_GUILD_UNIONS);
            Writer.DWord(c.Character.Information.CharacterID);                // Union owner id
            Writer.DWord(7);                                                  // ??Need to check
            Writer.DWord(c.Character.Network.Guild.Guildid);                  // Union leader guild id
            Writer.Byte(c.Character.Network.Guild.Unions.Count);              // Count guilds in union
            //Get all guilds details
            foreach (int guild in c.Character.Network.Guild.Unions)
            {
                //Load other guild data
                DB guild_data = new DB("SELECT * FROM guild WHERE id='" + guild + "'");

                using (System.Data.SqlClient.SqlDataReader reader = guild_data.Read())
                {
                    while (reader.Read())
                    {
                        string Guildname = reader.GetString(1);
                        byte Guildlevel = reader.GetByte(2);
                        byte Guildmembercount = reader.GetByte(6);
                        int Ownerid = reader.GetInt32(9);

                        string Charname = DB.GetData("SELECT name FROM character WHERE id='" + Ownerid + "'", "name").ToString();
                        int Charmodel = Convert.ToInt32(DB.GetData("SELECT chartype FROM character WHERE id='" + Ownerid + "'", "chartype"));

                        Writer.DWord(guild);                        //Guild ID
                        Writer.Text(reader.GetString(1));           //Guildname
                        Writer.Byte(reader.GetByte(2));             //Guildlevel
                        Writer.Text(Charname);                      //Ownername
                        Writer.DWord(Charmodel);                    //Owner model
                        Writer.Byte(reader.GetByte(6));             //Guild member count

                        //Get guild details
                        PlayerMgr Guildmembers =Helpers.GetInformation.GetGuildPlayer(guild);
                        //Add clients that are online to union list
                        //Null check
                        if (Guildmembers != null)
                        {
                            foreach (int member in Guildmembers.Character.Network.Guild.Members)
                            {
                                //make sure member isnt 0
                                if (member != 0)
                                {
                                    //Get player details
                                    PlayerMgr getmember = Helpers.GetInformation.GetPlayerMainid(member);
                                    //Make sure that the player is there
                                    if (getmember != null)
                                    {
                                        //Add client to union list
                                        c.Character.Network.Guild.UnionMembers.Add(getmember.Character.Information.CharacterID);
                                        //Add to member
                                        if (c.Character.Information.CharacterID != getmember.Character.Information.CharacterID)
                                        {
                                            getmember.Character.Network.Guild.UnionMembers.Add(c.Character.Information.CharacterID);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return Writer.GetBytes();
        }
 public void Send(PlayerMgr sys, byte[] buff)
 {
     try
     {
         if (Spawned(sys.Character.Information.UniqueID))
         {
             sys.client.Send(buff);
         }
     }
     catch (Exception ex)
     {
         Log.Exception("Send error: ", ex);
     }
 }
        public targetObject(object o, PlayerMgr player)
        {
            try
            {
                os = null;
                o_x = 0;
                o_y = 0;
                o_z = 0;
                magdef = 0;
                phydef = 0;
                type = false;

                if (o == null) return;
                main = player;
                if (main == null) return;
                if (o.GetType().ToString() == "CLGameServer.WorldMgr.Monsters")
                {
                    os = o as Monsters;
                    if (os.Die) { player.StopAttackTimer(); return; }
                    o_x = (float)os.x;
                    o_y = (float)os.y;
                    o_z = (float)os.z;
                    xsec = os.xSec;
                    ysec = os.ySec;
                    magdef = ObjData.Manager.ObjectBase[os.ID].MagDef;
                    phydef = ObjData.Manager.ObjectBase[os.ID].PhyDef;
                    id = os.UniqueID;
                    type = false;
                    hps = os.HP;
                    state = os.State;
                    main.Character.Action.MonsterID.Add(os.UniqueID);
                    mabsrob = 0;
                    os.Target = player;
                }
                if (o.GetType().ToString() == "CLGameServer.PlayerMgr")
                {
                    sys = o as PlayerMgr;
                    o_x = sys.Character.Position.x;
                    o_y = sys.Character.Position.y;
                    o_z = sys.Character.Position.z;
                    xsec = sys.Character.Position.xSec;
                    ysec = sys.Character.Position.ySec;
                    magdef = sys.Character.Stat.MagDef;
                    phydef = sys.Character.Stat.PhyDef;
                    id = sys.Character.Information.UniqueID;
                    absorbphy = sys.Character.Stat.phy_Absorb;
                    absorbmag = sys.Character.Stat.mag_Absorb;
                    state = sys.Character.State.LastState;
                    hps = sys.Character.Stat.SecondHp;
                    type = true;
                    mabsrob = sys.Character.Stat.Absorb_mp;
                }
            }
            catch (Exception ex)
            {
                Log.Exception(ex);
            }
        }
        public void FollowHim(PlayerMgr sys)
        {
            try
            {
                if (sys != null && LocalType == 1 && !sys.Character.State.Die/* && !sys.Character.Action.Check() */&& !sys.Character.Transport.Right)
                {
                    if (!Busy && Agresif == 1 && Attacking == false)
                    {
                        if (x >= (sys.Character.Position.x - 10) && x <= ((sys.Character.Position.x - 10) + 20) && y >= (sys.Character.Position.y - 10) && y <= ((sys.Character.Position.y - 10) + 20))
                        {
                            if (Runing)
                            {       //Notes / bugs :
                                    //- Monster skill attacks does not count amount of attacks for example if an attack strikes 2 times, onlye does 1 time damage. since its static. AttackHim()
                                    //- Player attack distance is really bad, needs timer to check monster location so attacking distance is more accurate. rly complex so navmesh here myb .. coz mob coordinate not apropriate need to check it
                                    //- Monsters agro needs max agro count, because having 100 on top of you is rediculous
                                    //- when player has to die (when mob attacks him) dont die at 0hp player needs to get one more hit to die :P

                                Runing = false;
                                StopMovement();

                                Target = sys;

                                if (AttackHandle != null)
                                    if (AttackHandle.IsAlive)
                                        return;

                                AttackHandle = new Thread(new ThreadStart(AttackMain));
                                AttackHandle.Start();

                                return;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Exception(ex);
            }
        }