Beispiel #1
0
        private static bool CheckChargeAndDamage(int skillId, byte skillLevel, PacketReader pr, out int charge, out int fixedDamage, out SkillEffect effect, out double skillDamage)
        {
            WzCharacterSkill wzSkill = DataBuffer.GetCharacterSkillById(skillId);

            if (wzSkill != null)
            {
                charge = wzSkill.IsKeyDownSkill ? pr.ReadInt() : 0;
                effect = wzSkill.GetEffect(skillLevel);
                if (!effect.Info.TryGetValue(CharacterSkillStat.fixdamage, out fixedDamage))
                {
                    fixedDamage = -1;
                    int temp;
                    if (!effect.Info.TryGetValue(CharacterSkillStat.damage, out temp))
                    {
                        temp = effect.Info[CharacterSkillStat.x];
                    }
                    skillDamage = temp / 100.0;
                }
                else
                {
                    skillDamage = 1;
                }
                return(true);
            }
            effect      = null;
            charge      = 0;
            skillDamage = 1;
            fixedDamage = -1;
            return(false);
        }
Beispiel #2
0
        public static void MaxSkill(string[] split, MapleClient c)
        {
            int skill = int.Parse(split[1]);
            WzCharacterSkill wzSkill = DataBuffer.GetCharacterSkillById(skill);

            if (wzSkill != null)
            {
                c.Account.Character.SetSkillLevel(skill, wzSkill.MaxLevel, wzSkill.MaxLevel, true);
            }
        }
        public static void SkillInfo(string[] split, MapleClient c)
        {
            int              skill   = int.Parse(split[1]);
            byte             level   = byte.Parse(split[2]);
            WzCharacterSkill wzSkill = DataBuffer.GetCharacterSkillById(skill);
            SkillEffect      effect  = wzSkill.GetEffect(level);

            c.Account.Character.SendBlueMessage(string.Format("Skill {0} level {1} info:", skill, level));
            foreach (var kvp in effect.Info)
            {
                c.Account.Character.SendBlueMessage(string.Format("{0} - {1}", Enum.GetName(typeof(CharacterSkillStat), kvp.Key), kvp.Value));
            }
        }
Beispiel #4
0
        public static void HandleSkill(MapleClient c, PacketReader pr)
        {
            int         objectId = pr.ReadInt();
            MapleSummon summon   = c.Account.Character.Map.GetSummon(objectId);

            if (summon != null && summon.Owner.Id == c.Account.Character.Id && summon.MovementType != SummonMovementType.Stationary)
            {
                int skillId = pr.ReadInt();
                WzCharacterSkill skillInfo = DataBuffer.GetCharacterSkillById(skillId);
                if (skillInfo == null)
                {
                    return;
                }
                SkillEffect effect = skillInfo.GetEffect(summon.SkillLevel);
                switch (skillId)
                {
                case Spearman.EVIL_EYE:
                    if (summon.SourceSkillId != Spearman.EVIL_EYE)
                    {
                        return;
                    }
                    if (DateTime.UtcNow.Subtract(summon.LastAbilityTime).TotalMilliseconds < effect.Info[CharacterSkillStat.x] * 1000)
                    {
                        c.CheatTracker.AddOffence(AntiCheat.OffenceType.NoDelaySummon);
                        return;
                    }
                    c.Account.Character.AddHP(effect.Info[CharacterSkillStat.hp]);
                    summon.LastAbilityTime = DateTime.UtcNow;
                    break;

                case Berserker.HEX_OF_THE_EVIL_EYE:
                    if (summon.SourceSkillId != Spearman.EVIL_EYE)
                    {
                        return;
                    }
                    effect.ApplyBuffEffect(summon.Owner);
                    break;

                default:
                    string txt = "Unhandled summon skill: " + skillId + " from summon skill: " + summon.SourceSkillId;
                    ServerConsole.Warning(txt);
                    Helpers.FileLogging.Log("Unhandled Summon Skills", txt);
                    break;
                }
                //c.SendPacket(Skill.ShowOwnSkillEffect(skillId, summon.SkillLevel));
                c.Account.Character.Map.BroadcastPacket(summon.GetUseSkillPacket(skillId, (byte)7), c.Account.Character); //stance ?
            }
        }
 public void IncreaseLightGauge(int amount, MapleCharacter chr)
 {
     if (State == LuminousState.None)
     {
         WzCharacterSkill skill = DataBuffer.GetCharacterSkillById(LuminousBasics.SUNFIRE);
         skill.GetEffect(1).ApplyBuffEffect(chr);
         chr.AddCooldown(LuminousBasics.SUNFIRE, 180000);
         State = LuminousState.Light;
     }
     if (LightLevel < 5)
     {
         LightGauge += amount;
         if (LightGauge > 10000)
         {
             LightGauge = 0;
             LightLevel++;
         }
     }
 }
Beispiel #6
0
        public static void HandleKeyMapChange(MapleClient c, PacketReader pr)
        {
            //ServerConsole.Info("Key packet:" + pr.ToString());
            pr.Skip(4);
            int count = pr.ReadInt();

            //StringBuilder sb = new StringBuilder("Default keys = ");
            for (int i = 0; i < count; i++)
            {
                uint key    = (uint)pr.ReadInt();
                byte type   = pr.ReadByte();
                int  action = pr.ReadInt();

                if (type == 1 && (action >= 1000))
                {
                    if (!c.Account.Character.HasSkill(action))
                    {
                        WzCharacterSkill skillInfo = DataBuffer.GetCharacterSkillById(action);
                        if (skillInfo == null || !skillInfo.HasFixedLevel)
                        {
                            continue;
                        }
                    }
                }
                c.Account.Character.ChangeKeybind(key, type, action);

                /*sb.Append("\n{{");
                *  sb.Append(key);
                *  sb.Append(", ");
                *  sb.Append("new Pair<byte, int>(");
                *  sb.Append(type);
                *  sb.Append(", ");
                *  sb.Append(action);
                *  sb.Append(")}},");*/
            }
            //ServerConsole.Info(sb.ToString());
        }
Beispiel #7
0
        public void Recalculate(MapleCharacter chr)
        {
            int mhpX = 0, mmpX = 0;
            int mhpR = 0, mmpR = 0;
            int lv2mhp = 0, lv2mmp = 0;
            int strR = 0, dexR = 0, intR = 0, lukR = 0;
            int watk = 0, matk = 9;
            int damR = 100, pdR = 0;

            Str               = chr.Str + 5;
            Dex               = chr.Dex + 5;
            Int               = chr.Int + 5;
            Luk               = chr.Luk + 5;
            MinDamage         = 0; MaxDamage = 0;
            AsrR              = 0;
            RecoveryHp        = 0; RecoveryMp = 0;
            RecoveryHpR       = 0; RecoveryMpR = 0;
            RecoveryTime      = 0;
            watk              = 3; matk = 3;
            LifeStealR        = 0; LifeStealProp = 0;
            MpEaterR          = 0; MpEaterProp = 0;
            DoTTimeInc        = 0;
            CostMpR           = 0;
            ExpR              = 100; MesoR = 100; DropR = 100;
            PickPocketR       = 0;
            StunR             = 0;
            AmmoInc           = 0;
            MasteryR          = 0;
            BuffTimeR         = 100;
            PotionEffectR     = 100;
            ElixirEffectR     = 100;
            CritRate          = 5;
            ExpLossReductionR = 0;

            #region PassiveSkills
            IEnumerable <Skill> passiveSkills = chr.GetSkillList().Where(x => x.SkillId % 10000 < 1000);
            foreach (Skill skill in passiveSkills)
            {
                if (skill.Level < 1)
                {
                    continue;
                }
                WzCharacterSkill skillInfo = DataBuffer.GetCharacterSkillById(skill.SkillId);
                if (skillInfo == null)
                {
                    continue;
                }
                SkillEffect effect = skillInfo.GetEffect(skill.Level);
                if (effect == null)
                {
                    continue;
                }
                foreach (var kvp in effect.Info)
                {
                    switch (kvp.Key)
                    {
                    case CharacterSkillStat.mhpX:
                        mhpX += kvp.Value; break;

                    case CharacterSkillStat.mmpX:
                        mmpX += kvp.Value; break;

                    case CharacterSkillStat.mhpR:
                        mhpR += kvp.Value; break;

                    case CharacterSkillStat.mmpR:
                        mmpR += kvp.Value; break;

                    case CharacterSkillStat.lv2mhp:
                        lv2mhp += kvp.Value; break;

                    case CharacterSkillStat.lv2mmp:
                        lv2mmp += kvp.Value; break;

                    case CharacterSkillStat.strX:
                        Str += kvp.Value; break;

                    case CharacterSkillStat.dexX:
                        Dex += kvp.Value; break;

                    case CharacterSkillStat.intX:
                        Int += kvp.Value; break;

                    case CharacterSkillStat.lukX:
                        Luk += kvp.Value; break;

                    case CharacterSkillStat.asrR:
                        AsrR += kvp.Value; break;

                    case CharacterSkillStat.mastery:
                        MasteryR = Math.Max(MasteryR, kvp.Value);
                        break;

                    case CharacterSkillStat.costmpR:
                        CostMpR += kvp.Value; break;

                    case CharacterSkillStat.bufftimeR:
                        BuffTimeR += kvp.Value; break;

                    case CharacterSkillStat.padX:
                        watk += kvp.Value; break;

                    case CharacterSkillStat.madX:
                        matk += kvp.Value; break;

                    case CharacterSkillStat.pdR:
                        pdR += kvp.Value; break;

                    case CharacterSkillStat.damR:
                        damR += kvp.Value; break;

                    case CharacterSkillStat.cr:
                        CritRate += kvp.Value; break;
                    }
                }
            }
            #region Specific passive skill handling
            byte skillLevel;
            if (chr.IsWarrior)
            {
                if ((skillLevel = chr.GetSkillLevel(Swordman.IRON_BODY)) > 0)
                {
                    mhpR += DataBuffer.CharacterSkillBuffer[Swordman.IRON_BODY].GetEffect(skillLevel).Info[CharacterSkillStat.mhpR];
                }

                if (chr.IsFighter)
                {
                    if ((skillLevel = chr.GetSkillLevel(Crusader.SELF_RECOVERY)) > 0)
                    {
                        var info = DataBuffer.CharacterSkillBuffer[Crusader.SELF_RECOVERY].GetEffect(skillLevel).Info;
                        RecoveryHp += info[CharacterSkillStat.hp];
                        RecoveryMp += info[CharacterSkillStat.mp];
                    }
                }
                else if (chr.IsSpearman)
                {
                    if ((skillLevel = chr.GetSkillLevel(Berserker.LORD_OF_DARKNESS)) > 0)
                    {
                        var info = DataBuffer.CharacterSkillBuffer[Berserker.LORD_OF_DARKNESS].GetEffect(skillLevel).Info;
                        LifeStealProp += info[CharacterSkillStat.prop];
                        LifeStealR    += info[CharacterSkillStat.x];
                    }
                }
            }
            else if (chr.IsMagician)
            {
                if (chr.IsFirePoisonMage)
                {
                    if ((skillLevel = chr.GetSkillLevel(FirePoison2.SPELL_MASTERY)) > 0)
                    {
                        matk += DataBuffer.CharacterSkillBuffer[FirePoison2.SPELL_MASTERY].GetEffect(skillLevel).Info[CharacterSkillStat.x];
                    }
                    if ((skillLevel = chr.GetSkillLevel(FirePoison2.MP_EATER)) > 0)
                    {
                        var info = DataBuffer.CharacterSkillBuffer[FirePoison2.MP_EATER].GetEffect(skillLevel).Info;
                        MpEaterProp += info[CharacterSkillStat.prop];
                        MpEaterR    += info[CharacterSkillStat.x];
                    }
                }
                if (chr.IsIceLightningMage)
                {
                    if ((skillLevel = chr.GetSkillLevel(IceLightning2.MP_EATER)) > 0)
                    {
                        var info = DataBuffer.CharacterSkillBuffer[IceLightning2.MP_EATER].GetEffect(skillLevel).Info;
                        MpEaterProp += info[CharacterSkillStat.prop];
                        MpEaterR    += info[CharacterSkillStat.x];
                    }
                    if ((skillLevel = chr.GetSkillLevel(IceLightning2.SPELL_MASTERY)) > 0)
                    {
                        matk += DataBuffer.CharacterSkillBuffer[IceLightning2.SPELL_MASTERY].GetEffect(skillLevel).Info[CharacterSkillStat.x];
                    }
                }
                if (chr.IsCleric)
                {
                    if ((skillLevel = chr.GetSkillLevel(Cleric.MP_EATER)) > 0)
                    {
                        var info = DataBuffer.CharacterSkillBuffer[Cleric.MP_EATER].GetEffect(skillLevel).Info;
                        MpEaterProp += info[CharacterSkillStat.prop];
                        MpEaterR    += info[CharacterSkillStat.x];
                    }
                    if ((skillLevel = chr.GetSkillLevel(Cleric.SPELL_MASTERY)) > 0)
                    {
                        matk += DataBuffer.CharacterSkillBuffer[Cleric.SPELL_MASTERY].GetEffect(skillLevel).Info[CharacterSkillStat.x];
                    }
                    if ((skillLevel = chr.GetSkillLevel(Priest.DIVINE_PROTECTION)) > 0)
                    {
                        AsrR += DataBuffer.CharacterSkillBuffer[Priest.DIVINE_PROTECTION].GetEffect(skillLevel).Info[CharacterSkillStat.asrR];
                    }
                }
            }
            else if (chr.IsArcher)
            {
                if (chr.IsHunter)
                {
                    if ((skillLevel = chr.GetSkillLevel(Bowmaster.BOW_EXPERT)) > 0)
                    {
                        watk += DataBuffer.CharacterSkillBuffer[Bowmaster.BOW_EXPERT].GetEffect(skillLevel).Info[CharacterSkillStat.x];
                    }
                }
                else if (chr.IsCrossbowman)
                {
                    if ((skillLevel = chr.GetSkillLevel(Marksman.CROSSBOW_EXPERT)) > 0)
                    {
                        watk += DataBuffer.CharacterSkillBuffer[Marksman.CROSSBOW_EXPERT].GetEffect(skillLevel).Info[CharacterSkillStat.x];
                    }
                }
            }
            else if (chr.IsThief)
            {
                if (chr.IsAssassin)
                {
                    if ((skillLevel = chr.GetSkillLevel(Assassin.CLAW_MASTERY)) > 0)
                    {
                        AmmoInc += DataBuffer.CharacterSkillBuffer[Assassin.CLAW_MASTERY].GetEffect(skillLevel).Info[CharacterSkillStat.y];
                    }
                    if ((skillLevel = chr.GetSkillLevel(Hermit.ALCHEMIC_ADRENALINE)) > 0)
                    {
                        PotionEffectR += DataBuffer.CharacterSkillBuffer[Hermit.ALCHEMIC_ADRENALINE].GetEffect(skillLevel).Info[CharacterSkillStat.x] - 100;
                    }
                    if ((skillLevel = chr.GetSkillLevel(NightLord.CLAW_EXPERT)) > 0)
                    {
                        watk += DataBuffer.CharacterSkillBuffer[NightLord.CLAW_EXPERT].GetEffect(skillLevel).Info[CharacterSkillStat.x];
                    }
                }
                else if (chr.IsBandit)
                {
                    if ((skillLevel = chr.GetSkillLevel(Bandit.SHIELD_MASTERY)) > 0)
                    {
                        watk += DataBuffer.CharacterSkillBuffer[Bandit.SHIELD_MASTERY].GetEffect(skillLevel).Info[CharacterSkillStat.y];
                    }
                    if ((skillLevel = chr.GetSkillLevel(ChiefBandit.MESO_MASTERY)) > 0)
                    {
                        var info = DataBuffer.CharacterSkillBuffer[ChiefBandit.MESO_MASTERY].GetEffect(skillLevel).Info;
                        MesoR       += info[CharacterSkillStat.mesoR];
                        PickPocketR += info[CharacterSkillStat.u];
                    }
                    if ((skillLevel = chr.GetSkillLevel(Shadower.DAGGER_EXPERT)) > 0)
                    {
                        watk += DataBuffer.CharacterSkillBuffer[Shadower.DAGGER_EXPERT].GetEffect(skillLevel).Info[CharacterSkillStat.x];
                    }
                }
            }
            else if (chr.IsDualBlade)
            {
                if ((skillLevel = chr.GetSkillLevel(DualBlade3p.LIFE_DRAIN)) > 0)
                {
                    var info = DataBuffer.CharacterSkillBuffer[DualBlade3p.LIFE_DRAIN].GetEffect(skillLevel).Info;
                    LifeStealR    += info[CharacterSkillStat.x];
                    LifeStealProp += info[CharacterSkillStat.prop];
                }
                if ((skillLevel = chr.GetSkillLevel(DualBlade4.KATARA_EXPERT)) > 0)
                {
                    watk += DataBuffer.CharacterSkillBuffer[DualBlade4.KATARA_EXPERT].GetEffect(skillLevel).Info[CharacterSkillStat.x];
                }
            }
            else if (chr.IsPirate)
            {
                if (chr.IsBrawler)
                {
                    if ((skillLevel = chr.GetSkillLevel(Brawler.PERSEVERANCE)) > 0)
                    {
                        var info = DataBuffer.CharacterSkillBuffer[Brawler.PERSEVERANCE].GetEffect(skillLevel).Info;
                        int x    = info[CharacterSkillStat.x];
                        RecoveryHpR += x;
                        RecoveryMpR += x;
                        RecoveryTime = info[CharacterSkillStat.y];
                    }
                    if ((skillLevel = chr.GetSkillLevel(Marauder.STUN_MASTERY)) > 0)
                    {
                        StunR += DataBuffer.CharacterSkillBuffer[Marauder.STUN_MASTERY].GetEffect(skillLevel).Info[CharacterSkillStat.subProp];
                    }
                }
                else if (chr.IsGunslinger)
                {
                    if ((skillLevel = skillLevel = chr.GetSkillLevel(Gunslinger.GUN_MASTERY)) > 0)
                    {
                        AmmoInc += DataBuffer.CharacterSkillBuffer[Gunslinger.GUN_MASTERY].GetEffect(skillLevel).Info[CharacterSkillStat.y];
                    }
                }
            }
            else if (chr.IsCannonneer)
            {
                if ((skillLevel = chr.GetSkillLevel(Cannoneer3.BARREL_ROULETTE)) > 0)
                {
                    damR += DataBuffer.CharacterSkillBuffer[Cannoneer3.BARREL_ROULETTE].GetEffect(skillLevel).Info[CharacterSkillStat.damR];
                }
            }
            else if (chr.IsJett)
            {
                /*if ((skillLevel = chr.GetSkillLevel(Jett2.PERSEVERANCE)) > 0)
                 * {
                 *  var info = DataBuffer.CharacterSkillBuffer[Jett2.PERSEVERANCE].GetSkillEffect(skillLevel).Info;
                 *  int x = info[CharacterSkillStat.x];
                 *  RecoveryHpR += x;
                 *  RecoveryMpR += x;
                 *  RecoveryTime = info[CharacterSkillStat.y] * 1000;
                 * } */
            }
            #endregion
            #endregion

            #region Buffs
            foreach (Buff buff in chr.GetBuffs())
            {
                var buffInfo = buff.Effect.BuffInfo;
                foreach (var pair in buffInfo)
                {
                    //if (pair.Key == MapleBuffStat.ENHANCED_MAXHP || pair.Key == MapleBuffStat.STACKING_MAXHP)
                    //mhpX += pair.Value;
                    if (pair.Key == MapleBuffStat.MAXHP_R || pair.Key == MapleBuffStat.STACKING_MAXHP_R)
                    {
                        mhpR += pair.Value;
                    }
                    //else if (pair.Key == MapleBuffStat.ENHANCED_MAXMP || pair.Key == MapleBuffStat.STACKING_MAXMP)
                    //mmpX += pair.Value;
                    else if (pair.Key == MapleBuffStat.MAXMP_R || pair.Key == MapleBuffStat.STACKING_MAXMP_R)
                    {
                        mmpR += pair.Value;
                    }
                    //else if (pair.Key == MapleBuffStat.WATK || pair.Key == MapleBuffStat.ENHANCED_WATK || pair.Key == MapleBuffStat.STACKING_WATK)
                    //watk += pair.Value;
                    //else if (pair.Key == MapleBuffStat.MATK || pair.Key == MapleBuffStat.ENHANCED_MATK || pair.Key == MapleBuffStat.STACKING_MATK)
                    //matk += pair.Value;
                    //else if (pair.Key == MapleBuffStat.CRIT || pair.Key == MapleBuffStat.STACKING_CRIT)
                    //CritRate += pair.Value;
                    else if (pair.Key == MapleBuffStat.STACKING_STATS)
                    {
                        Str += pair.Value;
                        Dex += pair.Value;
                        Int += pair.Value;
                        Luk += pair.Value;
                    }
                    else if (pair.Key == MapleBuffStat.STACKING_STATS_R)
                    {
                        Str += (int)(chr.Str * (pair.Value / 100.0)); //todo: check if this isnt math.ceil
                        Dex += (int)(chr.Dex * (pair.Value / 100.0));
                        Int += (int)(chr.Int * (pair.Value / 100.0));
                        Luk += (int)(chr.Luk * (pair.Value / 100.0));
                    }
                    //else if (pair.Key == MapleBuffStat.HOLY_SYMBOL)
                    {
                        // ExpR += pair.Value;
                    }
                }
            }
            #endregion

            #region Equips
            foreach (MapleItem item in chr.Inventory.GetItemsFromInventory(MapleInventoryType.Equipped))
            {
                MapleEquip equip = item as MapleEquip;
                if (equip == null)
                {
                    continue;
                }
                mhpX += equip.IncMhp;
                mmpX += equip.IncMmp;
                Str  += equip.Str;
                Dex  += equip.Dex;
                Int  += equip.Int;
                Luk  += equip.Luk;
                watk += equip.Pad;
                matk += equip.Mad;
                //todo: potential stuff from here
            }
            #endregion

            MaxHp  = chr.MaxHp;
            MaxHp += lv2mhp * chr.Level;
            MaxHp += (int)((MaxHp) * (mhpR / 100.0));
            MaxHp += mhpX;
            if (chr.Hp > MaxHp)
            {
                chr.AddHP(-(chr.Hp - MaxHp));
            }

            MaxMp  = chr.MaxMp;
            MaxMp += (int)(chr.MaxMp * (double)(mmpR / 100.0));
            MaxMp += lv2mmp * chr.Level;
            MaxMp += mhpX;
            if (chr.Mp > MaxMp)
            {
                chr.AddMP(-(chr.Mp - MaxMp));
            }

            Str += (short)(chr.Str * (double)(strR / 100.0));
            Dex += (short)(chr.Dex * (double)(dexR / 100.0));
            Int += (short)(chr.Int * (double)(intR / 100.0));
            Luk += (short)(chr.Luk * (double)(lukR / 100.0));

            bool      mage                    = false;
            int       primaryStat             = 0;
            int       secondaryStat           = 0;
            MapleItem weapon                  = chr.Inventory.GetEquippedItem((short)MapleEquipPosition.Weapon);
            if (weapon == null)
            {
                MinDamage = 1;
                MaxDamage = 1;
                return;
            }
            MapleItemType weaponItemType = ItemConstants.GetMapleItemType(weapon.ItemId);
            switch ((chr.Job % 1000) / 100)
            {
            case 1:     //Warrior-type
                primaryStat   = Str;
                secondaryStat = Dex;
                break;

            case 2:     //Magician-type
            case 7:     //Luminous
                primaryStat   = Int;
                secondaryStat = Luk;
                mage          = true;
                break;

            case 3:     //Archer-type
                primaryStat   = Dex;
                secondaryStat = Str;
                break;

            case 4:     //Thief-type
                primaryStat   = Luk;
                secondaryStat = Dex;
                break;

            case 5:     //Pirate-type
                if (weaponItemType == MapleItemType.Gun || weaponItemType == MapleItemType.SoulShooter)
                {
                    primaryStat   = Dex;
                    secondaryStat = Str;
                }
                else     //counts for cannons too
                {
                    primaryStat   = Str;
                    secondaryStat = Dex;
                }
                break;

            case 6:     //Xenon
                primaryStat = (Str + Dex + Luk);
                break;
            }
            if (!mage)
            {
                damR += pdR; //TODO: check, Not sure about this
            }
            CalculateDamageRange(weaponItemType, primaryStat, secondaryStat, mage ? matk : watk, damR, chr.IsFighter);
        }
Beispiel #8
0
        public static void HandleAttack(MapleClient c, PacketReader pr)
        {
            int            objectId = pr.ReadInt();
            MapleCharacter chr      = c.Account.Character;
            MapleSummon    summon   = chr.Map.GetSummon(objectId);

            if (summon != null)
            {
                if (summon.Owner.Id != chr.Id)
                {
                    return;
                }
                int tickCount = pr.ReadInt();
                WzCharacterSkill skillInfo = DataBuffer.GetCharacterSkillById(summon.SourceSkillId);
                if (skillInfo == null || skillInfo.SummonInfo == null)
                {
                    return;
                }
                WzCharacterSkill.SummonAttackInfo summonAttackInfo = skillInfo.SummonInfo;
                byte animation  = pr.ReadByte();
                byte attackByte = pr.ReadByte();
                int  attacks    = (attackByte & 0x0F);
                int  targets    = ((attackByte >> 4) & 0x0F);
                if (summonAttackInfo.MobCount < targets || summonAttackInfo.AttackCount < attacks)
                {
                    ServerConsole.Warning("Player " + chr.Name + "'s summon: " + summon.SourceSkillId + "has mismatching targets- or attackcount: " + attacks + "/" + summonAttackInfo.AttackCount + " attacks, " + targets + "/" + summonAttackInfo.MobCount + " mobs");
                    return;
                }
                pr.Skip(12);
                List <AttackPair> attackList = new List <AttackPair>();
                for (int i = 0; i < targets; i++)
                {
                    int          targetObjectId = pr.ReadInt();
                    MapleMonster target         = chr.Map.GetMob(targetObjectId);
                    if (target == null)
                    {
                        ServerConsole.Debug("Error parsing summon attack, summon skillId: " + summon.SourceSkillId + " attack byte: " + attackByte);
                        return;
                    }
                    AttackPair ap = new AttackPair();
                    ap.TargetObjectId = targetObjectId;
                    pr.Skip(24);
                    int damage = pr.ReadInt(); //only supports 1 damage count, not sure if there are summons with attackcount > 1
                    ap.Damage.Add(damage);
                    attackList.Add(ap);
                    pr.Skip(4);
                }
                AttackInfo attackInfo = new AttackInfo();
                attackInfo.Attacks          = attacks;
                attackInfo.AttacksByte      = attackByte;
                attackInfo.Speed            = animation;
                attackInfo.Targets          = targets;
                attackInfo.TargetDamageList = attackList;
                foreach (AttackPair ap in attackList)
                {
                    MapleMonster mob = chr.Map.GetMob(ap.TargetObjectId);
                    if (mob != null)
                    {
                        long totalDamage = 0;
                        foreach (int i in ap.Damage)
                        {
                            totalDamage += i;
                        }
                        if (totalDamage > int.MaxValue)
                        {
                            totalDamage = int.MaxValue;
                        }
                        mob.Damage(chr, (int)totalDamage);
                    }
                }
                bool darkFlare = summon.SourceSkillId == ChiefBandit.DARK_FLARE || summon.SourceSkillId == Hermit.DARK_FLARE || summon.SourceSkillId == NightWalker3.DARK_FLARE;
                chr.Map.BroadcastPacket(summon.GetAttackPacket(attackInfo, darkFlare));
            }
        }
Beispiel #9
0
        public static void Handle(MapleClient c, PacketReader packet)
        {
            MapleCharacter chr = c.Account.Character;

            if (!chr.DisableActions())
            {
                return;
            }
            try
            {
                int  tickCount = packet.ReadInt();
                int  skillId   = packet.ReadInt();
                byte amount    = packet.ReadByte(); //new v137, multiple sp
                if (amount <= 0)
                {
                    amount = 1;
                }

                short skillJobId = (short)(skillId / 10000);

                WzCharacterSkill wzSkill = DataBuffer.GetCharacterSkillById(skillId);
                if (wzSkill == null)
                {
                    return;
                }
                if (wzSkill.IsGmSkill && !chr.IsStaff)
                {
                    return;
                }
                if (!JobConstants.JobCanLearnSkill(skillId, chr.Job))
                {
                    return;
                }
                if (wzSkill.HasFixedLevel)
                {
                    return;
                }
                if (chr.Level < wzSkill.RequiredLevel)
                {
                    return;
                }
                if (wzSkill.RequiredSkills != null)
                {
                    foreach (var kvp in wzSkill.RequiredSkills)
                    {
                        if (!chr.HasSkill(kvp.Key, kvp.Value))
                        {
                            return;
                        }
                    }
                }
                if (wzSkill.IsHyperSkill)
                {
                    chr.SendPopUpMessage("Hyper skills aren't functional yet.");
                    chr.EnableActions();
                    return;
                }
                if (JobConstants.IsBeginnerJob(skillJobId))
                {
                    switch (skillId)
                    {
                    //Three snails:
                    case Explorer.THREE_SNAILS:
                    case Cygnus.THREE_SNAILS:
                    case AranBasics.THREE_SNAILS:
                    case EvanBasics.THREE_SNAILS:
                    case MihileBasics.THREE_SNAILS:
                    //Recovery:
                    case Explorer.RECOVERY:
                    case Cygnus.RECOVERY:
                    case AranBasics.RECOVERY:
                    case EvanBasics.RECOVER:
                    case MihileBasics.RECOVERY:
                    //Nimble Feet:
                    case Explorer.NIMBLE_FEET:
                    case Cygnus.NIMBLE_FEET:
                    case AranBasics.AGILE_BODY:
                    case EvanBasics.NIMBLE_FEET:
                    case MihileBasics.NIMBLE_FEET:
                    //Resistance:
                    case Resistance.POTION_MASTERY:
                    case Resistance.INFILTRATE:
                    case Resistance.CRYSTAL_THROW:
                        if (chr.GetSkillLevel(skillId) + amount > 3)     //already maxed
                        {
                            return;
                        }
                        int baseNum = 0;
                        switch (skillId / 100000)
                        {
                        case 300:         //resistance
                        {
                            if (!chr.IsResistance)
                            {
                                return;
                            }
                            int usedBeginnerSP = chr.GetSkillLevel(Resistance.CRYSTAL_THROW) + chr.GetSkillLevel(Resistance.INFILTRATE) + chr.GetSkillLevel(Resistance.POTION_MASTERY);
                            if (usedBeginnerSP + amount <= 9 && chr.GetSkillLevel(skillId) + amount <= 3)
                            {
                                chr.IncreaseSkillLevel(skillId, amount);
                            }
                            break;
                        }

                        case 0:
                            if (!chr.IsExplorer)
                            {
                                return;
                            }
                            goto common;

                        case 100:         //cygnus
                            if (!chr.IsCygnus)
                            {
                                return;
                            }
                            baseNum = 10000000;
                            goto common;

                        case 200:         //hero
                            if (!chr.IsAran && !chr.IsEvan)
                            {
                                return;
                            }
                            baseNum = 20000000;
                            goto common;

                        case 500:         //mihile
                            if (!chr.IsMihile)
                            {
                                return;
                            }
                            baseNum = 50000000;
common:
                            {
                                int usedBeginnerSP = chr.GetSkillLevel(baseNum + 1000) + chr.GetSkillLevel(baseNum + 1001) + chr.GetSkillLevel(baseNum + 1002);
                                if (usedBeginnerSP + amount <= 6 && chr.GetSkillLevel(skillId) + amount <= 3)
                                {
                                    chr.IncreaseSkillLevel(skillId, amount);
                                }
                                break;
                            }

                        default:
                            return;
                        }
                        break;

                    default:
                        return;
                    }
                }
                else
                {
                    int spTableIndex = JobConstants.GetSkillBookForJob(skillJobId);
                    if (chr.SpTable[spTableIndex] >= amount)
                    {
                        Skill skill = chr.GetSkill(skillId);
                        if (skill == null) //Player doesnt have the skill yet
                        {
                            int maxLevel = wzSkill.HasMastery ? wzSkill.DefaultMastery : wzSkill.MaxLevel;
                            if (amount <= maxLevel)
                            {
                                chr.LearnSkill(skillId, amount, wzSkill);
                                chr.SpTable[spTableIndex] -= amount;
                                MapleCharacter.UpdateSingleStat(c, MapleCharacterStat.Sp, chr.SpTable[0], true);
                            }
                        }
                        else
                        {
                            if (skill.Level + amount <= skill.MasterLevel)
                            {
                                chr.IncreaseSkillLevel(skillId, amount);
                                chr.SpTable[spTableIndex] -= amount;
                                MapleCharacter.UpdateSingleStat(c, MapleCharacterStat.Sp, chr.SpTable[0], true);
                            }
                        }
                    }
                }
            }
            finally
            {
                chr.EnableActions(false);
            }
        }
Beispiel #10
0
        private static void HandleAttackInfo(MapleClient c, AttackInfo attackInfo, SendHeader type, SkillEffect effect)
        {
            //Anti-cheat
            //c.CheatTracker.Trigger(AntiCheat.TriggerType.Attack);
            WzCharacterSkill wzSkill = effect != null ? effect.Parent : null;
            MapleCharacter   chr     = c.Account.Character;

            if (attackInfo.SkillId > 0)
            {
                if (!SkillEffect.CheckAndApplySkillEffect(c.Account.Character, attackInfo.SkillId, wzSkill, -1, attackInfo.Targets, attackInfo.Attacks))
                {
                    return;
                }
            }

            chr.Map.BroadcastPacket(GenerateAttackInfo(type, c.Account.Character, attackInfo), c.Account.Character, false);
            long totalDamage = 0;

            #region DoTs and Pickpocket
            int pickPocketProp = 0;
            int dotSkillId     = 0;
            int dotChance      = 0;
            int dotDamage      = 0;
            int dotTimeMS      = 0;
            int dotMaxStacks   = 1;
            #region Thief
            if (chr.IsThief)
            {
                byte venomSkillLevel = 0;
                if (chr.IsBandit)
                {
                    Buff pickPocket = chr.GetBuff(ChiefBandit.PICKPOCKET);
                    if (pickPocket != null)
                    {
                        pickPocketProp = pickPocket.Effect.Info[CharacterSkillStat.prop];
                    }
                    venomSkillLevel = chr.GetSkillLevel(ChiefBandit.VENOM);
                    if (venomSkillLevel > 0)
                    {
                        dotSkillId = ChiefBandit.VENOM;
                        byte toxicVenomSkillLevel = chr.GetSkillLevel(Shadower.TOXIC_VENOM);
                        if (toxicVenomSkillLevel > 0)
                        {
                            venomSkillLevel = toxicVenomSkillLevel;
                            dotSkillId      = Shadower.TOXIC_VENOM;
                        }
                    }
                }
                else if (chr.IsAssassin)
                {
                    #region Assassin
                    venomSkillLevel = chr.GetSkillLevel(Hermit.VENOM);
                    if (venomSkillLevel > 0)
                    {
                        dotSkillId = Hermit.VENOM;
                        byte toxicVenomSkillLevel = chr.GetSkillLevel(NightLord.TOXIC_VENOM);
                        if (toxicVenomSkillLevel > 0)
                        {
                            venomSkillLevel = toxicVenomSkillLevel;
                            dotSkillId      = NightLord.TOXIC_VENOM;
                        }
                    }
                    #endregion
                }
                else if (chr.IsDualBlade)
                {
                    #region DualBlade
                    venomSkillLevel = chr.GetSkillLevel(DualBlade3.VENOM);
                    if (venomSkillLevel > 0)
                    {
                        dotSkillId = DualBlade3.VENOM;
                        byte toxicVenomSkillLevel = chr.GetSkillLevel(DualBlade4.TOXIC_VENOM);
                        if (toxicVenomSkillLevel > 0)
                        {
                            venomSkillLevel = toxicVenomSkillLevel;
                            dotSkillId      = DualBlade4.TOXIC_VENOM;
                        }
                    }
                    #endregion
                }
                if (venomSkillLevel > 0)
                {
                    SkillEffect venomEffect = DataBuffer.GetCharacterSkillById(dotSkillId).GetEffect(venomSkillLevel);
                    dotChance = venomEffect.Info[CharacterSkillStat.prop];
                    dotDamage = (int)(chr.Stats.GetDamage() * (venomEffect.Info[CharacterSkillStat.dot] / 100.0));
                    dotTimeMS = venomEffect.Info[CharacterSkillStat.dotTime] * 1000;
                    if (!venomEffect.Info.TryGetValue(CharacterSkillStat.dotSuperpos, out dotMaxStacks))
                    {
                        dotMaxStacks = 1;
                    }
                }
            }
            #endregion
            if (attackInfo.SkillId > 0 && effect.Info.TryGetValue(CharacterSkillStat.dot, out dotDamage)) //Skill has/is dot
            {
                dotTimeMS = effect.Info[CharacterSkillStat.dotTime] * 1000;
                if (!effect.Info.TryGetValue(CharacterSkillStat.prop, out dotChance))
                {
                    dotChance = 100;
                }
                dotSkillId = attackInfo.SkillId;
                dotDamage  = (int)(chr.Stats.GetDamage() * (dotDamage / 100.0));
                if (!effect.Info.TryGetValue(CharacterSkillStat.dotSuperpos, out dotMaxStacks))
                {
                    dotMaxStacks = 1;
                }
            }
            #endregion

            foreach (AttackPair ap in attackInfo.TargetDamageList)
            {
                MapleMonster mob = chr.Map.GetMob(ap.TargetObjectId);
                if (mob != null && mob.Alive)
                {
                    long totalMobDamage = 0;
                    foreach (int damage in ap.Damage)
                    {
                        totalMobDamage += damage;
                    }
                    if (totalMobDamage > 0)
                    {
                        totalDamage += totalMobDamage;
                        if (totalDamage > int.MaxValue)
                        {
                            totalDamage = int.MaxValue;
                        }

                        #region Status effects
                        if (effect != null)
                        {
                            foreach (MonsterBuffApplication mba in effect.MonsterBuffs)
                            {
                                if (Functions.MakeChance(mba.Prop))
                                {
                                    foreach (var kvp in mba.Buffs)
                                    {
                                        mob.ApplyStatusEffect(attackInfo.SkillId, kvp.Key, kvp.Value, mba.Duration, chr);
                                    }
                                }
                            }
                        }
                        #endregion

                        #region MP Eater
                        if (chr.Stats.MpEaterProp > 0)
                        {
                            if (Functions.MakeChance(chr.Stats.MpEaterProp))
                            {
                                int mpSteal = (int)((chr.Stats.MpEaterR / 100.0) * mob.WzInfo.MP);
                                chr.AddMP(mpSteal);
                            }
                        }
                        #endregion
                        #region Bandit
                        if (chr.IsBandit)
                        {
                            if (Functions.MakeChance(pickPocketProp))
                            {
                                chr.Map.SpawnMesoMapItem(1, mob.Position, chr.Map.GetDropPositionBelow(mob.Position, mob.Position), false, MapleDropType.Player, chr);
                            }
                            if (attackInfo.SkillId == Bandit.STEAL)
                            {
                                int prop = DataBuffer.GetCharacterSkillById(Bandit.STEAL).GetEffect(chr.GetSkillLevel(Bandit.STEAL)).Info[CharacterSkillStat.prop];
                                if (Functions.MakeChance(prop))
                                {
                                    MapleItem item = mob.TryGetStealableItem(chr.Id, chr.Name);
                                    if (item != null)
                                    {
                                        chr.Map.SpawnMapItem(item, mob.Position, chr.Map.GetDropPositionBelow(chr.Position, mob.Position), false, Map.MapleDropType.Player, chr);
                                    }
                                }
                            }
                        }
                        #endregion

                        if (Functions.MakeChance(dotChance))
                        {
                            mob.ApplyPoison(dotSkillId, dotTimeMS, dotDamage, 1000, chr, dotMaxStacks);
                        }

                        mob.Damage(chr, (int)totalDamage);
                    }
                }
            }
            #region special skill handling
            if (type == SendHeader.RangedAttack)
            {
                if (attackInfo.Targets > 0 && chr.IsHunter)
                {
                    #region QuiverCartridge
                    QuiverCartridgeSystem qcs = chr.Resource as QuiverCartridgeSystem;
                    if (qcs != null && qcs.ChosenArrow > -1)
                    {
                        int usedArrow = qcs.HandleUse(c);
                        switch (usedArrow)
                        {
                        case 0:                           // Blood
                            if (Functions.MakeChance(50)) //50% chance to heal 20% of damage as hp
                            {
                                chr.AddHP((int)(totalDamage * 0.2));
                            }
                            break;

                        case 1:     // Poison
                            //TODO: poison, 90% damage, 8 seconds, stacks 3 times
                            break;

                        case 2:     // Magic, don't need handling I think
                            break;
                        }
                    }
                    #endregion
                }
            }

            if (totalDamage > 0)
            {
                BuffedCharacterStats stats = chr.Stats;
                if (stats.LifeStealProp > 0 && stats.LifeStealR > 0)
                {
                    if (Functions.MakeChance(stats.LifeStealProp))
                    {
                        int lifesteal = (int)((stats.LifeStealR / 100.0) * totalDamage);
                        chr.AddHP(lifesteal);
                    }
                }

                if (chr.IsMagician)
                {
                    #region ArcaneAim
                    int arcaneAimId = 0;
                    if (chr.Job == JobConstants.FIREPOISON4)
                    {
                        arcaneAimId = FirePoison4.ARCANE_AIM;
                    }
                    else if (chr.Job == JobConstants.ICELIGHTNING4)
                    {
                        arcaneAimId = IceLightning4.ARCANE_AIM;
                    }
                    else if (chr.Job == JobConstants.BISHOP)
                    {
                        arcaneAimId = Bishop.ARCANE_AIM;
                    }
                    if (arcaneAimId > 0)
                    {
                        byte skillLevel = chr.GetSkillLevel(arcaneAimId);
                        if (skillLevel > 0)
                        {
                            if ((DateTime.UtcNow.Subtract(chr.LastAttackTime).TotalMilliseconds) < 5000)
                            {
                                Buff oldBuff = chr.GetBuff(arcaneAimId);
                                if (oldBuff != null)
                                {
                                    int prop = oldBuff.Effect.Info[CharacterSkillStat.prop];
                                    if (Functions.MakeChance(prop))
                                    {
                                        Buff newBuff   = new Buff(arcaneAimId, oldBuff.Effect, oldBuff.Duration, chr);
                                        int  oldStacks = oldBuff.Stacks / 6;
                                        newBuff.Stacks = Math.Min(30, (oldStacks + 1) * 6);
                                        chr.GiveBuff(newBuff);
                                    }
                                }
                                else
                                {
                                    SkillEffect arcaneAimEffect = DataBuffer.GetCharacterSkillById(arcaneAimId).GetEffect(skillLevel);
                                    int         prop            = arcaneAimEffect.Info[CharacterSkillStat.prop];
                                    if (Functions.MakeChance(prop))
                                    {
                                        Buff newBuff = new Buff(arcaneAimId, arcaneAimEffect, 5000, chr);
                                        newBuff.Stacks = 6;
                                        chr.GiveBuff(newBuff);
                                    }
                                }
                            }
                        }
                    }
                    #endregion
                }
                else if (chr.IsThief)
                {
                    if (chr.IsBandit)
                    {
                        chr.IncreaseCriticalGrowth(true);
                        byte skillLevel = chr.GetSkillLevel(Shadower.SHADOWER_INSTINCT);
                        if (skillLevel > 0)
                        {
                            ((BodyCountSystem)chr.Resource).IncreaseBodyCount(c);
                        }
                    }
                }
            }
            #endregion
            chr.LastAttackTime = DateTime.UtcNow;
        }