示例#1
0
        public void ModifyHP(short value, bool sendPacket = true)
        {
            var startValue = PrimaryStats.HP;

            if ((PrimaryStats.HP + value) < 0)
            {
                PrimaryStats.HP = 0;
            }
            else if ((PrimaryStats.HP + value) > PrimaryStats.GetMaxHP(false))
            {
                PrimaryStats.HP = PrimaryStats.GetMaxHP(false);
            }
            else
            {
                PrimaryStats.HP = (short)(PrimaryStats.HP + value);
            }


            if (sendPacket)
            {
                CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Hp, PrimaryStats.HP);
            }

            if (startValue == PrimaryStats.HP)
            {
                // Doesn't matter
                return;
            }
            ModifiedHP();
        }
示例#2
0
        public void ModifyMP(short value, bool sendPacket = true)
        {
            if ((PrimaryStats.MP + value) < 0)
            {
                PrimaryStats.MP = 0;
            }
            else if ((PrimaryStats.MP + value) > PrimaryStats.GetMaxMP(false))
            {
                PrimaryStats.MP = PrimaryStats.GetMaxMP(false);
            }
            else
            {
                PrimaryStats.MP = (short)(PrimaryStats.MP + value);
            }
            if (sendPacket)
            {
                CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Mp, PrimaryStats.MP);

                /*if (this.PartyID != -1)
                 * {
                 *  MapPacket.UpdatePartyMemberMP(this);
                 *  MapPacket.ReceivePartyMemberMP(this);
                 * }*/
            }
        }
示例#3
0
        public int AddMesos(int value, bool isSelf = false)
        {
            var newMesos = 0;

            if (value < 0)
            {
                if ((Inventory.Mesos - value) < 0)
                {
                    newMesos = 0;
                }
                else
                {
                    newMesos = Inventory.Mesos + value;  // neg - neg = pos
                }
            }
            else
            {
                if (((long)Inventory.Mesos + value) > Int32.MaxValue)
                {
                    newMesos = Int32.MaxValue;
                }
                else
                {
                    newMesos = Inventory.Mesos + value;
                }
            }
            var mesosDiff = newMesos - Inventory.Mesos;

            Inventory.Mesos = newMesos;
            CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Mesos, Inventory.Mesos, isSelf);

            return(mesosDiff);
        }
示例#4
0
 public void SetFame(short value)
 {
     _characterLog.Info(new StatChangeLogRecord {
         value = value, type = "fame", add = false
     });
     PrimaryStats.Fame = value;
     CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Fame, value);
 }
示例#5
0
 public void ModifyMaxHP(short value)
 {
     _characterLog.Info(new StatChangeLogRecord {
         value = value, type = "maxhp", add = true
     });
     PrimaryStats.MaxHP = (short)(((PrimaryStats.MaxHP + value) > Constants.MaxMaxHp) ? Constants.MaxMaxHp : (PrimaryStats.MaxHP + value));
     CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.MaxHp, PrimaryStats.MaxHP);
 }
示例#6
0
 public void SetSP(short value)
 {
     _characterLog.Info(new StatChangeLogRecord {
         value = value, type = "sp", add = false
     });
     PrimaryStats.SP = value;
     CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Sp, PrimaryStats.SP);
 }
示例#7
0
 public void SetMesos(int value, bool isSelf = false)
 {
     if (value < 0)
     {
         value = 0;
     }
     Inventory.Mesos = value;
     CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Mesos, Inventory.Mesos, isSelf);
 }
示例#8
0
 public void SetHair(int id)
 {
     _characterLog.Info(new StatChangeLogRecord {
         value = id, type = "hair", add = false
     });
     Hair = id;
     CharacterStatsPacket.SendStatChange(this, (int)CharacterStatsPacket.StatFlags.Hair, id);
     MapPacket.SendAvatarModified(this, MapPacket.AvatarModFlag.Equips);//Because hair is a equip I guess
 }
示例#9
0
 public void SetFace(int id)
 {
     _characterLog.Info(new StatChangeLogRecord {
         value = id, type = "face", add = false
     });
     Face = id;
     CharacterStatsPacket.SendStatChange(this, (int)CharacterStatsPacket.StatFlags.Eyes, id);
     MapPacket.SendAvatarModified(this, MapPacket.AvatarModFlag.Face);
 }
示例#10
0
 public void SetSkin(byte id)
 {
     _characterLog.Info(new StatChangeLogRecord {
         value = id, type = "skin", add = false
     });
     Skin = id;
     CharacterStatsPacket.SendStatChange(this, (byte)CharacterStatsPacket.StatFlags.Skin, id);
     MapPacket.SendAvatarModified(this, MapPacket.AvatarModFlag.Skin);
 }
示例#11
0
        public void SetLuk(short value)
        {
            _characterLog.Info(new StatChangeLogRecord {
                value = value, type = "luk", add = false
            });
            PrimaryStats.Luk = value;
            CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Luk, PrimaryStats.Luk);

            this.FlushDamageLog();
        }
示例#12
0
        public void SetJob(short value)
        {
            _characterLog.Info(new StatChangeLogRecord {
                value = value, type = "job", add = false
            });
            PrimaryStats.Job = value;
            CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Job, value);

            this.FlushDamageLog();
            Server.Instance.CenterConnection.UpdatePlayerJobLevel(this);
        }
示例#13
0
        public void SetLevel(byte value)
        {
            _characterLog.Info(new StatChangeLogRecord {
                value = value, type = "level", add = false
            });
            PrimaryStats.Level = value;
            CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Level, value);
            MapPacket.SendPlayerLevelupAnim(this);

            this.FlushDamageLog();
            Server.Instance.CenterConnection.UpdatePlayerJobLevel(this);
        }
示例#14
0
 public void AddSP(short value)
 {
     _characterLog.Info(new StatChangeLogRecord {
         value = value, type = "sp", add = true
     });
     if (value + PrimaryStats.SP > Int16.MaxValue)
     {
         PrimaryStats.SP = Int16.MaxValue;
     }
     else
     {
         PrimaryStats.SP += value;
     }
     CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Sp, PrimaryStats.SP);
 }
示例#15
0
        public void SetHPAndMaxHP(short value, bool sendPacket = true)
        {
            if (value <= 0)
            {
                value = 1;
            }

            SetMaxHP(value);
            PrimaryStats.HP = value;

            if (sendPacket == true)
            {
                CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Hp, value);
            }
        }
示例#16
0
 public void AddAP(short value, bool isSelf = false)
 {
     _characterLog.Info(new StatChangeLogRecord {
         value = value, type = "ap", add = true
     });
     if (value + PrimaryStats.AP > Int16.MaxValue)
     {
         PrimaryStats.AP = Int16.MaxValue;
     }
     else
     {
         PrimaryStats.AP += value;
     }
     CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Ap, PrimaryStats.AP, isSelf);
 }
示例#17
0
        public void SetMPAndMaxMP(short value, bool isBySelf = false, bool sendPacket = true)
        {
            if (value < 0)
            {
                value = 0;
            }

            SetMaxMP(value);
            PrimaryStats.MP = value;

            if (sendPacket == true)
            {
                CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Mp, value, isBySelf);
            }
        }
示例#18
0
 public void SetMaxMP(short value)
 {
     _characterLog.Info(new StatChangeLogRecord {
         value = value, type = "maxmp", add = false
     });
     if (value > Constants.MaxMaxMp)
     {
         value = Constants.MaxMaxMp;
     }
     else if (value < Constants.MinMaxMp)
     {
         value = Constants.MinMaxMp;
     }
     PrimaryStats.MaxMP = value;
     CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.MaxMp, value);
 }
示例#19
0
        public void AddLuk(short value)
        {
            _characterLog.Info(new StatChangeLogRecord {
                value = value, type = "luk", add = true
            });
            if (value + PrimaryStats.Luk > Int16.MaxValue)
            {
                PrimaryStats.Luk = Int16.MaxValue;
            }
            else
            {
                PrimaryStats.Luk += value;
            }
            CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Luk, PrimaryStats.Luk);

            this.FlushDamageLog();
        }
示例#20
0
        public static void HandlePickupDrop(Character chr, Packet packet)
        {
            // 5F 18 FF 12 01 00 00 00 00
            packet.Skip(4); // pos?

            int dropid = packet.ReadInt();

            if (chr.AssertForHack(chr.Room != null, "Trying to loot a drop while in a 'room'") ||
                !chr.Field.DropPool.Drops.TryGetValue(dropid, out Drop drop) ||
                !drop.CanTakeDrop(chr))
            {
                InventoryPacket.NoChange(chr);
                return;
            }

            var dropLootRange = drop.Pt2 - chr.Position;

            chr.AssertForHack(dropLootRange > 200, "Possible drop VAC! Distance: " + dropLootRange, dropLootRange > 250);

            bool   SentDropNotice          = false;
            Reward reward                  = drop.Reward;
            int    dropNoticeItemIdOrMesos = reward.Drop;
            short  pickupAmount            = reward.Amount;

            if (reward.Mesos)
            {
                // Party meso distribution
                if (drop.SourceID != 0 &&
                    chr.PartyID != 0 &&
                    drop.OwnPartyID == chr.PartyID)
                {
                    var PartyData = chr.Field.GetInParty(chr.PartyID);
                    var Count     = PartyData.Count();

                    if (Count > 1)
                    {
                        SentDropNotice = true;
                        var Base = drop.Reward.Drop * 0.8 / Count + 0.5;
                        Base = Math.Floor(Base);
                        if (Base <= 0.0)
                        {
                            Base = 0.0;
                        }

                        var Bonus = Convert.ToInt32(drop.Reward.Drop - Count * Base);
                        if (Bonus < 0)
                        {
                            Bonus = 0;
                        }

                        drop.Reward.Drop = Convert.ToInt32(Base);

                        foreach (var BonusUser in PartyData)
                        {
                            int mesosGiven = reward.Drop;
                            if (chr.ID == BonusUser.ID)
                            {
                                mesosGiven += Bonus;
                            }
                            // Now figure out what we really gave the user
                            mesosGiven = BonusUser.AddMesos(mesosGiven, true);

                            Common.Tracking.MesosTransfer.PlayerLootMesos(drop.SourceID, chr.ID, mesosGiven, "Party " + chr.PartyID + ", " + chr.MapID + ", " + drop.GetHashCode());

                            CharacterStatsPacket.SendGainDrop(BonusUser, true, mesosGiven, 0);
                        }
                    }
                }

                if (!SentDropNotice)
                {
                    dropNoticeItemIdOrMesos = chr.AddMesos(reward.Drop, true);
                    Common.Tracking.MesosTransfer.PlayerLootMesos(
                        drop.SourceID,
                        chr.ID,
                        dropNoticeItemIdOrMesos,
                        chr.MapID + ", " + drop.GetHashCode()
                        );
                }
            }
            else if (Constants.isStar(reward.ItemID))
            {
                if (!chr.Inventory.HasSlotsFreeForItem(reward.ItemID, reward.Amount, Constants.isStackable(reward.ItemID)))
                {
                    CannotLoot(chr, -1);
                    InventoryPacket.NoChange(chr);
                    return;
                }
                var rewardItem = drop.Reward.GetData();
                chr.Inventory.AddItem2(rewardItem);
                ItemTransfer.ItemPickedUp(chr.ID, chr.MapID, reward.ItemID, reward.Amount, chr.MapID + ", " + drop.GetHashCode(), rewardItem);
            }
            else if (chr.Inventory.AddItem2(drop.Reward.GetData()) == drop.Reward.Amount)
            {
                CannotLoot(chr, -1);
                InventoryPacket.NoChange(chr); // ._. stupid nexon
                return;
            }
            else
            {
                if (Constants.isEquip(drop.Reward.ItemID))
                {
                    ItemTransfer.ItemPickedUp(chr.ID, chr.MapID, reward.ItemID, reward.Amount, chr.MapID + ", " + drop.GetHashCode(), drop.Reward.GetData());
                }
            }
            if (!SentDropNotice)
            {
                CharacterStatsPacket.SendGainDrop(chr, reward.Mesos, dropNoticeItemIdOrMesos, pickupAmount);
            }
            chr.Field.DropPool.RemoveDrop(drop, RewardLeaveType.FreeForAll, chr.ID);
        }
示例#21
0
        public override void AC_OnPacketInbound(Packet packet)
        {
            ClientMessages header = 0;

            try
            {
                header = (ClientMessages)packet.ReadByte();

                if (!Loaded || Player?.Character == null)
                {
                    switch (header)
                    {
                    case ClientMessages.MIGRATE_IN:
                        OnPlayerLoad(packet);
                        break;     //updated
                    }
                }
                // Block packets as we are migrating
                else if (Server.Instance.InMigration == false || Server.Instance.IsNewServerInMigration)
                {
                    var character = Player.Character;

                    if (logPackets.Contains(header))
                    {
                        PacketLog.ReceivedPacket(packet, (byte)header, Server.Instance.Name, IP);
                    }

                    switch (header)
                    {
                    case ClientMessages.ENTER_PORTAL:
                        MapPacket.OnEnterPortal(packet, character);
                        break;

                    case ClientMessages.CHANGE_CHANNEL:
                        OnChangeChannel(character, packet);
                        break;

                    case ClientMessages.ENTER_CASH_SHOP:
                        OnEnterCashShop(character);
                        break;

                    case ClientMessages.MOVE_PLAYER:
                        MapPacket.HandleMove(character, packet);
                        break;

                    case ClientMessages.SIT_REQUEST:
                        MapPacket.HandleSitChair(character, packet);
                        break;

                    case ClientMessages.ENTER_TOWN_PORTAL:
                        MapPacket.HandleDoorUse(character, packet);
                        break;

                    case ClientMessages.CLOSE_RANGE_ATTACK:
                        AttackPacket.HandleMeleeAttack(character, packet);
                        break;

                    case ClientMessages.RANGED_ATTACK:
                        AttackPacket.HandleRangedAttack(character, packet);
                        break;

                    case ClientMessages.MAGIC_ATTACK:
                        AttackPacket.HandleMagicAttack(character, packet);
                        break;

                    case ClientMessages.TAKE_DAMAGE:
                        CharacterStatsPacket.HandleCharacterDamage(character, packet);
                        break;

                    case ClientMessages.CHAT:
                        MessagePacket.HandleChat(character, packet);
                        break;

                    case ClientMessages.GROUP_MESSAGE:
                        MessagePacket.HandleSpecialChat(character, packet);
                        break;

                    case ClientMessages.WHISPER:
                        MessagePacket.HandleCommand(character, packet);
                        break;

                    case ClientMessages.EMOTE:
                        MapPacket.SendEmotion(character, packet.ReadInt());
                        break;

                    case ClientMessages.NPC_TALK:
                        MapPacket.HandleNPCChat(character, packet);
                        break;

                    case ClientMessages.NPC_TALK_MORE:
                        NpcPacket.HandleNPCChat(character, packet);
                        break;

                    case ClientMessages.SHOP_ACTION:
                        NpcPacket.HandleNPCShop(character, packet);
                        break;

                    case ClientMessages.STORAGE_ACTION:
                        StoragePacket.HandleStorage(character, packet);
                        break;

                    case ClientMessages.ITEM_MOVE:
                        InventoryPacket.HandleInventoryPacket(character, packet);
                        break;

                    case ClientMessages.ITEM_USE:
                        InventoryPacket.HandleUseItemPacket(character, packet);
                        break;

                    case ClientMessages.SUMMON_BAG_USE:
                        InventoryPacket.HandleUseSummonSack(character, packet);
                        break;

                    case ClientMessages.CASH_ITEM_USE:
                        CashPacket.HandleCashItem(character, packet);
                        break;

                    case ClientMessages.RETURN_SCROLL_USE:
                        InventoryPacket.HandleUseReturnScroll(character, packet);
                        break;

                    case ClientMessages.SCROLL_USE:
                        InventoryPacket.HandleScrollItem(character, packet);
                        break;

                    case ClientMessages.DISTRIBUTE_AP:
                        CharacterStatsPacket.HandleStats(character, packet);
                        break;

                    case ClientMessages.HEAL_OVER_TIME:
                        CharacterStatsPacket.HandleHeal(character, packet);
                        break;

                    case ClientMessages.DISTRIBUTE_SP:
                        SkillPacket.HandleAddSkillLevel(character, packet);
                        break;

                    case ClientMessages.PREPARE_SKILL:
                        SkillPacket.HandlePrepareSkill(character, packet);
                        break;

                    case ClientMessages.GIVE_BUFF:
                        SkillPacket.HandleUseSkill(character, packet);
                        break;

                    case ClientMessages.CANCEL_BUFF:
                        SkillPacket.HandleStopSkill(character, packet);
                        break;

                    case ClientMessages.DROP_MESOS:
                        DropPacket.HandleDropMesos(character, packet.ReadInt());
                        break;

                    case ClientMessages.GIVE_FAME:
                        FamePacket.HandleFame(character, packet);
                        break;

                    case ClientMessages.CHAR_INFO_REQUEST:
                        MapPacket.SendPlayerInfo(character, packet);
                        break;

                    case ClientMessages.SPAWN_PET:
                        PetsPacket.HandleSpawnPet(character, packet.ReadShort());
                        break;

                    case ClientMessages.SUMMON_MOVE:
                        MapPacket.HandleSummonMove(character, packet);
                        break;

                    case ClientMessages.SUMMON_ATTACK:
                        AttackPacket.HandleSummonAttack(character, packet);
                        break;

                    case ClientMessages.SUMMON_DAMAGED:
                        MapPacket.HandleSummonDamage(character, packet);
                        break;

                    case ClientMessages.MOB_MOVE:
                        MobPacket.HandleMobControl(character, packet);
                        break;

                    case ClientMessages.NPC_ANIMATE:
                        MapPacket.HandleNPCAnimation(character, packet);
                        break;

                    case ClientMessages.PET_MOVE: PetsPacket.HandleMovePet(character, packet); break;

                    case ClientMessages.PET_INTERACTION: PetsPacket.HandleInteraction(character, packet); break;

                    case ClientMessages.PET_ACTION: PetsPacket.HandlePetAction(character, packet); break;

                    case ClientMessages.FIELD_CONTIMOVE_STATE:
                        MapPacket.OnContiMoveState(character, packet);
                        break;

                    case ClientMessages.DROP_PICK_UP:
                        DropPacket.HandlePickupDrop(character, packet);
                        break;

                    case ClientMessages.MESSENGER:
                        MessengerHandler.HandleMessenger(character, packet);
                        break;

                    case ClientMessages.MINI_ROOM_OPERATION:
                        MiniRoomPacket.HandlePacket(character, packet);
                        break;

                    case ClientMessages.FRIEND_OPERATION:
                        BuddyHandler.HandleBuddy(character, packet);
                        break;

                    case ClientMessages.PARTY_OPERATION:
                        PartyHandler.HandleParty(character, packet);
                        break;

                    case ClientMessages.DENY_PARTY_REQUEST:
                        PartyHandler.HandleDecline(character, packet);
                        break;

                    case ClientMessages.REACTOR_HIT:
                        ReactorPacket.HandleReactorHit(character, packet);
                        break;

                    case ClientMessages.REPORT_USER:
                        MiscPacket.ReportPlayer(character, packet);
                        break;


                    //this is a garbage opcode that i use when doing janky client packet workarounds. This is where packets go to die.
                    case ClientMessages.JUNK:
                        Program.MainForm.LogDebug("received junk packet");
                        break;

                    // eh.. ignore?
                    // Happens when one of the following buffs are set:
                    // Stun, Poison, Seal, Darkness, Weakness, Curse
                    // Maybe patch out of the client
                    case ClientMessages.CHARACTER_IS_DEBUFFED: break;

                    // TODO: Implement???
                    case ClientMessages.MOB_APPLY_CONTROL: break;

                    case ClientMessages.CLIENT_HASH: break;

                    case ClientMessages.PONG:
                        // Make sure we update the player online thing
                        RedisBackend.Instance.SetPlayerOnline(
                            character.UserID,
                            Server.Instance.GetOnlineId()
                            );

                        // Cleanup expired items
                        character.Inventory.CheckExpired();
                        break;

                    default:
                        if (character.Field.HandlePacket(character, packet, header) == false)
                        {
                            Program.MainForm.LogAppend(
                                "[{0}] Unknown packet received! " + packet,
                                header
                                );
                        }

                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Program.MainForm.LogAppend($"---- ERROR ----\r\n{ex}");
                Program.MainForm.LogAppend($"Packet: {packet}");
                FileWriter.WriteLine(@"etclog\ExceptionCatcher.log", "[Game Server " + Server.Instance.ID + "][" + DateTime.Now + "] Exception caught: " + ex, true);
                //Disconnect();
            }


#if DEBUG
            if (packet.Length != packet.Position)
            {
                var packetStr = packet.ToString();
                packetStr = packetStr.Substring(0, packet.Position * 3 - 1) + "-x-" + packetStr.Substring(packet.Position * 3);

                log.Debug($"Did not read full message in packet: {header} {packetStr}");
            }
#endif
        }
示例#22
0
        public void OnVarset(Character Sent, string Var, object Value, object Value2 = null, object Value3 = null)
        {
            if (this != Sent && Sent.IsGM && !Sent.IsAdmin) //Todo Admin levels
            {
                MessagePacket.SendNotice("You don't have the premission to edit other players stats!", Sent);
                //$"{Sent.Name} tried to edit another players stats without premission"
            }
            else
            {
                try
                {
                    MapPacket.AvatarModFlag        AvatarMod = 0;
                    CharacterStatsPacket.StatFlags dwFlag    = 0;

                    switch (Var.ToLower())
                    {
                    case "hp":
                        dwFlag         |= CharacterStatsPacket.StatFlags.Hp;
                        PrimaryStats.HP = Convert.ToInt16(Value);
                        break;

                    case "mp":
                        dwFlag         |= CharacterStatsPacket.StatFlags.Mp;
                        PrimaryStats.MP = Convert.ToInt16(Value);
                        break;

                    case "exp":
                        dwFlag          |= CharacterStatsPacket.StatFlags.Exp;
                        PrimaryStats.EXP = Convert.ToInt32(Value);
                        break;

                    case "maxhp":
                        dwFlag |= CharacterStatsPacket.StatFlags.MaxHp;
                        if (Value.ToString() == "0")
                        {
                            Value = "1";
                        }
                        PrimaryStats.MaxHP = Convert.ToInt16(Value);
                        break;

                    case "maxmp":
                        dwFlag |= CharacterStatsPacket.StatFlags.MaxMp;
                        if (Value.ToString() == "0")
                        {
                            Value = "1";
                        }
                        PrimaryStats.MaxMP = Convert.ToInt16(Value);
                        break;

                    case "ap":
                        dwFlag         |= CharacterStatsPacket.StatFlags.Ap;
                        PrimaryStats.AP = Convert.ToInt16(Value);
                        break;

                    case "sp":
                        dwFlag         |= CharacterStatsPacket.StatFlags.Sp;
                        PrimaryStats.SP = Convert.ToInt16(Value);
                        break;

                    case "str":
                        dwFlag          |= CharacterStatsPacket.StatFlags.Str;
                        PrimaryStats.Str = Convert.ToInt16(Value);
                        break;

                    case "dex":
                        dwFlag          |= CharacterStatsPacket.StatFlags.Dex;
                        PrimaryStats.Dex = Convert.ToInt16(Value);
                        break;

                    case "int":
                        dwFlag          |= CharacterStatsPacket.StatFlags.Int;
                        PrimaryStats.Int = Convert.ToInt16(Value);
                        break;

                    case "luk":
                        dwFlag          |= CharacterStatsPacket.StatFlags.Luk;
                        PrimaryStats.Luk = Convert.ToInt16(Value);
                        break;

                    case "fame":
                    case "pop":
                        dwFlag           |= CharacterStatsPacket.StatFlags.Fame;
                        PrimaryStats.Fame = Convert.ToInt16(Value);
                        break;

                    case "mesos":
                        dwFlag         |= CharacterStatsPacket.StatFlags.Mesos;
                        Inventory.Mesos = Convert.ToInt32(Value);
                        break;

                    case "job":
                    {
                        var Job = Convert.ToInt16(Value);
                        if (DataProvider.HasJob(Job) || Job == 0)
                        {
                            dwFlag          |= CharacterStatsPacket.StatFlags.Job;
                            PrimaryStats.Job = Job;
                        }
                        else
                        {
                            MessagePacket.SendNotice($"Job {Job} does not exist.", Sent);
                        }
                        break;
                    }

                    case "skill":
                    {
                        var SkillID = Convert.ToInt32(Value);
                        if (DataProvider.Skills.TryGetValue(SkillID, out var Skill))
                        {
                            if (Value2 == null)
                            {
                                Value2 = Skill.MaxLevel;
                            }
                            Skills.SetSkillPoint(SkillID, Convert.ToByte(Value2), true);
                        }
                        else
                        {
                            MessagePacket.SendNotice($"Skill {SkillID} does not exist.", Sent);
                        }
                        break;
                    }

                    case "level":
                        dwFlag |= CharacterStatsPacket.StatFlags.Level;
                        Level   = Convert.ToByte(Value);
                        MapPacket.SendPlayerLevelupAnim(this);
                        break;

                    case "skin":
                    {
                        var SkinID = Convert.ToByte(Value);
                        if (SkinID >= 0 && SkinID < 6)
                        {
                            AvatarMod |= MapPacket.AvatarModFlag.Skin;
                            dwFlag    |= CharacterStatsPacket.StatFlags.Skin;
                            Skin       = SkinID;
                        }
                        else
                        {
                            MessagePacket.SendNotice($"Skin {SkinID} does not exist.", Sent);
                        }
                        break;
                    }

                    case "face":
                    {
                        var FaceID = Convert.ToInt32(Value);
                        if (DataProvider.Equips.ContainsKey(FaceID))
                        {
                            AvatarMod |= MapPacket.AvatarModFlag.Face;
                            dwFlag    |= CharacterStatsPacket.StatFlags.Eyes;
                            Face       = FaceID;
                        }
                        else
                        {
                            MessagePacket.SendNotice($"Face {FaceID} does not exist.", Sent);
                        }
                        break;
                    }

                    case "hair":
                    {
                        var HairID = Convert.ToInt32(Value);
                        if (DataProvider.Equips.ContainsKey(HairID))
                        {
                            AvatarMod |= MapPacket.AvatarModFlag.Equips;
                            dwFlag    |= CharacterStatsPacket.StatFlags.Hair;
                            Hair       = HairID;
                        }
                        else
                        {
                            MessagePacket.SendNotice($"Hair {HairID} does not exist.", Sent);
                        }
                        break;
                    }

                    case "gender":
                    {
                        Gender = ParseGenderString(Value.ToString());
                        Server.Instance.CharacterDatabase.RunQuery(
                            "UPDATE characters SET gender = @gender WHERE id = @id",
                            "@gender", Gender,
                            "@id", ID
                            );

                        MessagePacket.SendNotice($"Gender set to {(Gender == 0 ? "male" : (Gender == 2 ? "Unisex" : "female"))}. Please relog.", this);
                        break;
                    }

                    case "accgender":
                    {
                        var gender = ParseGenderString(Value.ToString());
                        Server.Instance.CharacterDatabase.RunQuery(
                            "UPDATE users SET gender = @gender WHERE ID = @id",
                            "@gender", gender,
                            "@id", UserID
                            );

                        MessagePacket.SendNotice($"Account gender set to {(gender == 0 ? "male" : (gender == 2 ? "Unisex" : "female"))}", this);
                        break;
                    }

                    case "map":
                    case "field":
                    {
                        var FieldID = Convert.ToInt32(Value);
                        if (DataProvider.Maps.ContainsKey(FieldID))
                        {
                            ChangeMap(FieldID);
                        }
                        else
                        {
                            MessagePacket.SendText(MessagePacket.MessageTypes.RedText, "Map not found.", this, MessagePacket.MessageMode.ToPlayer);
                        }
                        break;
                    }

                    default:
                        MessagePacket.SendNotice($"{Var} is not a valid Variable!", Sent);
                        return;
                    }

                    if (dwFlag != 0)
                    {
                        CharacterStatsPacket.SendUpdateStat(this, true, dwFlag);
                    }

                    if (AvatarMod != 0)
                    {
                        MapPacket.SendAvatarModified(this, AvatarMod);
                    }
                }
                catch (Exception ex)
                {
                    MessagePacket.SendNotice(ex.Message, Sent);
                }
            }
        }
示例#23
0
 public void SetEXP(int value)
 {
     PrimaryStats.EXP = value;
     CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Exp, value);
 }
示例#24
0
        public void AddEXP(uint value, bool IsLastHit = false, bool Quest = false)
        {
            if (value == 0 || PrimaryStats.Level >= 200 || PrimaryStats.HP <= 0)
            {
                return;
            }

            var amount = (int)(value > Int32.MaxValue ? Int32.MaxValue : value);
            var amnt   = (uint)(PrimaryStats.EXP + amount);

            CharacterStatsPacket.SendGainEXP(this, amount, IsLastHit, Quest);
            var level = PrimaryStats.Level;

            var save        = false;
            var expRequired = Constants.GetLevelEXP(PrimaryStats.Level);

            if (amnt >= expRequired)
            {
                short apgain = 0;
                short spgain = 0;
                short mpgain = 0;
                short hpgain = 0;
                var   job    = (short)(PrimaryStats.Job / 100);

                var intt = PrimaryStats.GetIntAddition(true);

                amnt -= (uint)expRequired;

                level++;

                // Update EXP required...
                expRequired = Constants.GetLevelEXP(level);

                apgain += Constants.ApPerLevel;
                hpgain += RNG.Range.generate(
                    Constants.HpMpFormulaArguments[job, 0, (int)Constants.HpMpFormulaFields.HPMin],
                    Constants.HpMpFormulaArguments[job, 0, (int)Constants.HpMpFormulaFields.HPMax],
                    true
                    );

                mpgain += RNG.Range.generate(
                    Constants.HpMpFormulaArguments[job, 0, (int)Constants.HpMpFormulaFields.MPMin],
                    Constants.HpMpFormulaArguments[job, 0, (int)Constants.HpMpFormulaFields.MPMax],
                    true
                    );

                // Additional buffing through INT stats
                mpgain += (short)(
                    intt *
                    Constants.HpMpFormulaArguments[job, 0, (int)Constants.HpMpFormulaFields.MPIntStatMultiplier] /
                    200
                    );

                var improvedMaxHpIncreaseLvl = Skills.GetSkillLevel(Constants.Swordsman.Skills.ImprovedMaxHpIncrease);
                if (improvedMaxHpIncreaseLvl > 0)
                {
                    hpgain += CharacterSkills.GetSkillLevelData(Constants.Swordsman.Skills.ImprovedMaxHpIncrease, improvedMaxHpIncreaseLvl).XValue;
                }

                var improvedMaxMpIncreaseLvl = Skills.GetSkillLevel(Constants.Magician.Skills.ImprovedMaxMpIncrease);
                if (improvedMaxMpIncreaseLvl > 0)
                {
                    mpgain += CharacterSkills.GetSkillLevelData(Constants.Magician.Skills.ImprovedMaxMpIncrease, improvedMaxMpIncreaseLvl).XValue;
                }

                if (PrimaryStats.Job != 0)
                {
                    spgain = Constants.SpPerLevel;
                }

                if (level >= 200)
                {
                    amnt = 0;
                    // TODO: Announce max level!
                }

                // Overflow? lets reduce it
                if (amnt >= expRequired)
                {
                    amnt = (uint)(expRequired - 1);
                }

                _levelLog.Info(new LevelLogRecord
                {
                    level = level,
                    posX  = Position.X,
                    posY  = Position.Y,
                });

                ModifyMaxHP(hpgain);
                ModifyMaxMP(mpgain);
                SetLevel(level);
                AddAP(apgain);
                AddSP(spgain);
                ModifyHP(PrimaryStats.GetMaxHP(false));
                ModifyMP(PrimaryStats.GetMaxMP(false));
                save = true;
            }

            PrimaryStats.EXP = (int)amnt;

            // Calculate savepoints

            var stepOfSave  = CalculateSaveStep();
            var curDateTime = MasterThread.CurrentDate;

            if (!save)
            {
                if (lastSaveStep != stepOfSave)
                {
                    var levelTimeSpan = curDateTime - LastSavepoint;

                    if (levelTimeSpan.TotalSeconds >= 30)
                    {
                        _characterLog.Debug(
                            $"Saving because user reached save threshold. Current {stepOfSave} last {lastSaveStep}");
                        save          = true;
                        LastSavepoint = curDateTime;
                    }
                    else
                    {
                        AssertForHack(
                            levelTimeSpan.TotalSeconds < 20,
                            $"Getting fast EXP ({levelTimeSpan.TotalSeconds} seconds since last savepoint)",
                            levelTimeSpan.TotalSeconds < 15
                            );
                    }
                    _characterLog.Debug(
                        new SavepointLogRecord
                    {
                        level = PrimaryStats.Level,
                        posX  = Position.X,
                        posY  = Position.Y,
                        totalMillisBetween = (int)levelTimeSpan.TotalMilliseconds,
                        blocked            = save == false
                    }
                        );

                    lastSaveStep = stepOfSave;
                }
            }
            else
            {
                lastSaveStep = stepOfSave;
            }


            if (save)
            {
                LastSavepoint = curDateTime;
                Save();
            }

            CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Exp, PrimaryStats.EXP);
        }
示例#25
0
 public void DamageMP(short amount)
 {
     PrimaryStats.MP = (short)(amount > PrimaryStats.MP ? 0 : PrimaryStats.MP - amount);
     CharacterStatsPacket.SendStatChange(this, (uint)CharacterStatsPacket.StatFlags.Mp, PrimaryStats.MP, false);
 }