示例#1
0
        //!spawnmob [mobId] optional:[mobAmount]
        public static void SpawnMob(string[] split, MapleClient c)
        {
            int   mobId   = int.Parse(split[1]);
            WzMob mobInfo = DataBuffer.GetMobById(mobId);

            if (mobInfo == null)
            {
                return;
            }
            int amount = 1;

            if (split.Length > 2)
            {
                amount = int.Parse(split[2]);
            }
            if (amount > 1)
            {
                List <MapleMonster> mobs = new List <MapleMonster>();
                for (int i = 0; i < amount; i++)
                {
                    MapleMonster mob = new MapleMonster(mobInfo, c.Account.Character.Map);

                    mobs.Add(mob);
                }
                c.Account.Character.Map.SpawnMobsOnGroundBelow(mobs, new Point(c.Account.Character.Position.X, c.Account.Character.Position.Y - 1));
            }
            else
            {
                MapleMonster mob = new MapleMonster(mobInfo, c.Account.Character.Map);

                c.Account.Character.Map.SpawnMobOnGroundBelow(mob, new Point(c.Account.Character.Position.X, c.Account.Character.Position.Y - 1));
            }
        }
示例#2
0
        private static void HandlePickPocket(MapleCharacter player, MapleMonster monster, Tuple <int, List <int> > oned)
        {
            //金钱炸弹
            var pickpocket      = SkillFactory.GetSkill(4211003);
            var delay           = 0;
            var maxmeso         = player.GetBuffedValue(MapleBuffStat.Pickpocket);
            var reqdamage       = 20000;
            var monsterPosition = monster.Position;

            if (maxmeso == null)
            {
                return;
            }

            foreach (var eachd in oned.Item2)
            {
                if (pickpocket.GetEffect(player.GetSkillLevel(pickpocket)).MakeChanceResult())
                {
                    var perc   = eachd / (double)reqdamage;
                    var todrop = Math.Min((int)Math.Max(perc * maxmeso.Value, 1), maxmeso.Value);
                    var tdmap  = player.Map;
                    var tdpos  = new Point((int)(monsterPosition.X + Randomizer.NextDouble() * 100 - 50),
                                           monsterPosition.Y);
                    var tdmob  = monster;
                    var tdchar = player;
                    TimerManager.Instance.RunOnceTask(
                        () => { tdmap.SpawnMesoDrop(todrop, tdpos, tdmob, tdchar, false); }, delay);
                    delay += 1000;
                }
            }
        }
示例#3
0
        public MapleMonster SpawnMonster(MapleMap mapleMap)
        {
            var mob = new MapleMonster(m_monster)
            {
                Position = Pos
            };

            m_spawnedMonsters.Increment();

            mob.Listeners.Add((kak, args) =>
            {
                m_nextPossibleSpawn = DateTime.Now.GetTimeMilliseconds();
                if (m_mobTime > 0)
                {
                    m_nextPossibleSpawn += m_mobTime * 1000;
                }
                else
                {
                    m_nextPossibleSpawn += args.Monster.Stats.GetAnimationTime("die1");
                }
                m_spawnedMonsters.Decrement();
            });

            mapleMap.SpawnMonster(mob);
            if (m_mobTime == 0)
            {
                m_nextPossibleSpawn = DateTime.Now.GetTimeMilliseconds() + 5000;
            }
            return(mob);
        }
示例#4
0
 public SpawnPoint(MapleMonster monster, Point pos, int mobTime)
 {
     m_monster           = monster;
     Pos                 = pos;
     m_mobTime           = mobTime;
     m_immobile          = !monster.Stats.IsMobile;
     m_nextPossibleSpawn = DateTime.Now.GetTimeMilliseconds();
 }
示例#5
0
        public static void Handle(MapleClient c, PacketReader pr)
        {
            MapleMonster mob = c.Account.Character.Map.GetMob(pr.ReadInt());

            if (mob == null)
            {
                return;
            }
            mob.ControllerHasAggro = true;
        }
示例#6
0
        public static MobAttackInfo GetMobAttackInfo(MapleMonster mob, int attack)
        {
            MobAttackInfo ret;
            var           key = Tuple.Create(mob.Id, attack);

            if (MobAttacks.TryGetValue(key, out ret))
            {
                return(ret);
            }
            lock (MobAttacks)
            {
                if (!MobAttacks.TryGetValue(key, out ret))
                {
                    var mobData = DataSource.GetData((mob.Id + ".img").PadLeft(11, '0'));
                    if (mobData != null)
                    {
                        var linkedmob = MapleDataTool.GetString("link", mobData, "");

                        if (linkedmob != "")
                        {
                            mobData = DataSource.GetData((linkedmob + ".img").PadLeft(11, '0'));
                        }

                        var attackData = mobData.GetChildByPath($"attack{attack + 1}/info");
                        if (attackData != null)
                        {
                            var deadlyAttack = attackData.GetChildByPath("deadlyAttack");
                            var mpBurn       = MapleDataTool.GetInt("mpBurn", attackData, 0);
                            var disease      = MapleDataTool.GetInt("disease", attackData, 0);
                            var level        = MapleDataTool.GetInt("level", attackData, 0);
                            var mpCon        = MapleDataTool.GetInt("conMP", attackData, 0);
                            ret = new MobAttackInfo(mob.Id, attack)
                            {
                                IsDeadlyAttack = deadlyAttack != null,
                                MpBurn         = mpBurn,
                                DiseaseSkill   = (byte)disease,
                                DiseaseLevel   = (byte)level,
                                MpCon          = mpCon
                            };
                        }
                    }
                    if (MobAttacks.ContainsKey(key))
                    {
                        MobAttacks[key] = ret;
                    }
                    else
                    {
                        MobAttacks.Add(key, ret);
                    }
                }
                return(ret);
            }
        }
示例#7
0
        public static void updatePosition(List <MapleMovementFragment> movements, MapleMonster mob, int yOffset)
        {
            if (movements == null)
            {
                return;
            }

            for (int i = movements.Count - 1; i >= 0; i--) //loop from the back
            {
                if (movements[i] is AbsoluteLifeMovement)
                {
                    //ServerConsole.Info("Monster position updated :" + Mob.Position + " => " + Move.Position);
                    Point position = movements[i].Position;
                    position.Y  += yOffset;
                    mob.Position = position;
                    mob.Stance   = movements[i].State;
                    break;
                }
            }
        }
示例#8
0
        public void AttackMonster(int damage, byte speed, MapleMonster monster)
        {
            AttackInfo info = new AttackInfo();

            info.Attacks     = 1;
            info.Targets     = 1;
            info.AttacksByte = 0x11;
            info.Speed       = speed;
            AttackPair attackPair = new AttackPair();

            attackPair.TargetObjectId = monster.ObjectId;
            attackPair.Damage         = new List <int>()
            {
                damage
            };
            info.TargetDamageList = new List <AttackPair>()
            {
                attackPair
            };
            Owner.Map.BroadcastPacket(GetAttackPacket(info, true));
            monster.Damage(Owner, damage);
        }
示例#9
0
        public void KillTrigger(MapleMonster mob)
        {
            Boolean ForceReturn = false;

            if (FirstMobPoint == null)
            {
                FirstMobPoint = mob.Position;
                ForceReturn   = true;
            }
            if (KillTracker == 0)
            {
                KillCountTracker = 0;
                KillTracker      = DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond;
                ForceReturn      = true;
            }
            if (ForceReturn)
            {
                return;
            }

            TimeSpan Current = TimeSpan.FromMilliseconds(DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond);

            if ((Current - TimeSpan.FromMilliseconds(KillTracker)).TotalMinutes >= 1)
            {
                KillTriggerReset();
                return;
            }
            if (Functions.Distance((Point)FirstMobPoint, mob.Position) < 5)
            {
                KillCountTracker++;
            }
            //50 kills on basicly the same position (~4px)
            if (KillCountTracker > 50)
            {
                AddOffence(OffenceType.MobVac);
                KillTriggerReset();
            }
        }
示例#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;
        }
示例#11
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));
            }
        }
示例#12
0
 public void RegisterMonster(MapleMonster mob)
 {
     m_mobs.Add(mob);
     mob.EventInstanceManager = this;
 }
示例#13
0
        public static void Handle(MapleClient c, PacketReader pr)
        {
            if (c.Account.Character.Map != null)
            {
                int          objectId = pr.ReadInt();
                MapleMonster Mob      = c.Account.Character.Map.GetMob(objectId);
                if (Mob == null)
                {
                    return;
                }
                lock (Mob.MobLock)
                {
                    if (!Mob.Alive)
                    {
                        return;
                    }
                    if (Mob.GetController() != c.Account.Character)
                    {
                        c.SendPacket(MapleMonster.RemoveMobControl(objectId));
                        return;
                    }
                    pr.Skip(1);
                    short moveID     = pr.ReadShort();
                    bool  useSkill   = pr.ReadBool();
                    byte  skill      = pr.ReadByte();
                    int   unk        = pr.ReadInt();
                    Point startPos   = Mob.Position;
                    int   skillid    = 0;
                    int   skilllevel = 0;
                    if (useSkill)
                    {
                        if (Mob.WzInfo.Skills.Count > 0)
                        {
                            if (skill >= 0 && skill < Mob.WzInfo.Skills.Count)
                            {
                                MobSkill mobSkill = Mob.WzInfo.Skills[skill];
                                if ((DateTime.UtcNow - Mob.SkillTimes[mobSkill]).TotalMilliseconds > mobSkill.interval)// && mobSkill.summonOnce
                                {
                                    Mob.SkillTimes[mobSkill] = DateTime.UtcNow;
                                    if (mobSkill.hp <= Mob.HpPercent)
                                    {
                                        //supposed to apply efffect here :/
                                        //todo $$
                                        //mobSkill.applyEffect(chr, monster, true);
                                        skillid    = mobSkill.Skill;
                                        skilllevel = mobSkill.Level;
                                    }
                                }
                            }
                            else
                            {
                                return;//hacking?
                            }
                        }
                    }
                    List <int>   unkList  = new List <int>();
                    List <short> unkList2 = new List <short>();
                    byte         count    = pr.ReadByte();
                    for (int i = 0; i < count; i++)
                    {
                        unkList.Add(pr.ReadInt());
                    }
                    count = pr.ReadByte();
                    for (int i = 0; i < count; i++)
                    {
                        unkList.Add(pr.ReadShort());
                    }

                    pr.Skip(30);
                    List <MapleMovementFragment> Res = ParseMovement.Parse(pr);
                    if (Res != null && Res.Count > 0)
                    {
                        updatePosition(Res, Mob, -1);
                        if (Mob.Alive)
                        {
                            MoveResponse(c, objectId, moveID, Mob.ControllerHasAggro, (short)Mob.WzInfo.MP, 0, 0);
                            MoveMob(c, objectId, useSkill, skill, unk, startPos, Res, unkList, unkList2);
                        }
                    }
                    else
                    {
                        ServerConsole.Warning("Monster Res == null or empty!");
                    }
                }
            }
        }
示例#14
0
        public List <DropEntry> RetrieveDropChances(int monsterid)
        {
            if (m_drops.ContainsKey(monsterid))
            {
                return(m_drops[monsterid]);
            }

            var ret = new List <DropEntry>();

            if (monsterid > 9300183 && monsterid < 9300216)
            {
                for (var i = 2022359; i < 2022367; i++)
                {
                    ret.Add(new DropEntry(i, 10));
                }

                if (m_drops.ContainsKey(monsterid))
                {
                    m_drops[monsterid] = ret;
                }
                else
                {
                    m_drops.Add(monsterid, ret);
                }

                return(ret);
            }
            if (monsterid > 9300215 && monsterid < 9300269)
            {
                for (var i = 2022430; i < 2022434; i++)
                {
                    ret.Add(new DropEntry(i, 3));
                }


                if (m_drops.ContainsKey(monsterid))
                {
                    m_drops[monsterid] = ret;
                }
                else
                {
                    m_drops.Add(monsterid, ret);
                }

                return(ret);
            }


            MapleMonster theMonster = null;

            var dropItems = JsonConvert.DeserializeObject <List <DropItem> >(File.ReadAllText($"{Environment.CurrentDirectory}\\Json\\MonsterDrops.json"));
            var dropQuery = dropItems.Where(x => x.MonsterId == monsterid).Select(x => x);

            foreach (var dropInfo in dropQuery)
            {
                var rowmonsterid = dropInfo.MonsterId;
                var chance       = dropInfo.Chance;
                var questid      = dropInfo.QuestId;
                if (rowmonsterid != monsterid && rowmonsterid != 0)
                {
                    if (theMonster == null)
                    {
                        theMonster = MapleLifeFactory.GetMonster(monsterid);
                    }
                    chance += theMonster.Stats.Level * rowmonsterid;
                }
                ret.Add(new DropEntry(dropInfo.ItemId, chance, questid));
            }


            if (m_drops.ContainsKey(monsterid))
            {
                m_drops[monsterid] = ret;
            }
            else
            {
                m_drops.Add(monsterid, ret);
            }

            return(ret);
        }
示例#15
0
        private static void CheckHighDamage(MapleCharacter player, MapleMonster monster, AttackInfo attack,
                                            ISkill theSkill, MapleStatEffect attackEffect, int damageToMonster, int maximumDamageToMonster)
        {
            //检查高攻击伤害
            int elementalMaxDamagePerMonster;
            var element = Element.Neutral;

            if (theSkill != null)
            {
                element = theSkill.Element;
                var skillId = theSkill.SkillId;
                if (skillId == 3221007)
                {
                    maximumDamageToMonster = 99999;
                }
                else if (skillId == 4221001)
                {
                    maximumDamageToMonster = 400000;
                }
            }
            if (player.GetBuffedValue(MapleBuffStat.WkCharge) != null)
            {
                var chargeSkillId = player.GetBuffSource(MapleBuffStat.WkCharge);
                switch (chargeSkillId)
                {
                case 1211003:
                case 1211004:
                    element = Element.Fire;
                    break;

                case 1211005:
                case 1211006:
                    element = Element.Ice;
                    break;

                case 1211007:
                case 1211008:
                    element = Element.Lighting;
                    break;

                case 1221003:
                case 1221004:
                    element = Element.Holy;
                    break;
                }
                var chargeSkill = SkillFactory.GetSkill(chargeSkillId);
                maximumDamageToMonster *= (int)(chargeSkill.GetEffect(player.GetSkillLevel(chargeSkill)).Damage / 100.0);
            }
            if (element != Element.Neutral)
            {
                double elementalEffect;
                if (attack.Skill == 3211003 || attack.Skill == 3111003)
                {
                    //烈火箭和寒冰�?
                    elementalEffect = attackEffect.X / 200.0;
                }
                else
                {
                    elementalEffect = 0.5;
                }

                switch (monster.GetEffectiveness(element).Value)
                {
                case 1:     //immue
                    elementalMaxDamagePerMonster = 1;
                    break;

                case 0:     //normal
                    elementalMaxDamagePerMonster = maximumDamageToMonster;
                    break;

                case 3:     //weak
                    elementalMaxDamagePerMonster = (int)(maximumDamageToMonster * (1.0 + elementalEffect));
                    break;

                case 2:     //strong
                    elementalMaxDamagePerMonster = (int)(maximumDamageToMonster * (1.0 - elementalEffect));
                    break;

                default:
                    throw new Exception("Effectiveness不正确");
                }
            }
            else
            {
                elementalMaxDamagePerMonster = maximumDamageToMonster;
            }

            if (damageToMonster > elementalMaxDamagePerMonster)
            {
                player.AntiCheatTracker.RegisterOffense(CheatingOffense.HighDamage); //高伤�?
                if (attack.Skill != 1009 && attack.Skill != 10001009 && attack.Skill != 20001009)
                {
                    // * 3 until implementation of lagsafe pingchecks for buff expiration
                    if (damageToMonster <= elementalMaxDamagePerMonster * 4)
                    {
                        return;
                    }

                    if (player.IsGm || player.Job == MapleJob.Ares && player.Level <= 10)
                    {
                        //log.info("这里不进行操�?");
                    }
                    else
                    {
                        if (player.Level < 70)
                        {
                            AutobanManager.Instance.BroadcastMessage(player.Client,
                                                                     $" {player.Name} 被系统封号 封号原因:伤害异常({damageToMonster}) 当前等级:{player.Level}");
                            //player.ban(player.getName() + " 被系统封�?.(异常攻击伤害�?: " + damageToMonster + " 当前等级 " + player.getLevel() + " ElementalMaxDamage: " + elementalMaxDamagePerMonster * 4 + " (IP: " + player.getClient().getSession().getRemoteAddress().toString().split(":")[0] + ")");
                        }
                    }
                }
                else
                {
                    var maxDamage = (int)Math.Floor(monster.MaxHp * 0.3);
                    if (damageToMonster > 500000)
                    {
                        AutobanManager.Instance.Autoban(player.Client,
                                                        damageToMonster +
                                                        $"伤害异常 等级: {player.Level} 攻击力: {player.Watk} 技能ID: {attack.Skill} 攻击怪物ID: {monster.Id} 造成最大伤害: {maxDamage}");
                    }
                }
            }
        }
        public static void Handle(MapleClient c, PacketReader pr)
        {
            //6800 29939E7B 81BFD40F FD 00 60000000 00 00 037B 00
            //6800 418AE151 6BE4D40F FF 00 01000000 00 00 47357C00 FE77AD00 00 00000000 00000000 00 00 00

            //C101 CA566800 FD 60000000 00 60000000
            //C101 68EB7A00 FF 01000000 00 F6761200 00 00000000 00000000 00 00 01000000

            //effect
            //CD01 CA566800 [000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200] 0100 7B000300 00 00 00 00000000 00000000 00000000 00000000 00000000 0000
            MapleCharacter chr = c.Account.Character;

            if (chr.Hidden)
            {
                return;
            }
            pr.Skip(4); //rnd num
            pr.Skip(4); //tickcount
            byte type   = pr.ReadByte();
            int  damage = 0;

            pr.ReadByte();
            damage = pr.ReadInt();
            pr.Skip(2);
            int fake = 0;

            if (damage == -1)
            {
                fake = 4020002 + (chr.Job / 10 - 40) * 100000;
                if ((fake != NightLord.SHADOW_SHIFTER) && (fake != Shadower.SHADOW_SHIFTER))
                {
                    fake = NightLord.SHADOW_SHIFTER;
                }
            }
            switch (type)
            {
            case 0xFF:    //mob damage
            {
                int          mobid = pr.ReadInt();
                int          oid   = pr.ReadInt();
                MapleMonster mob   = chr.Map.GetMob(oid);
                if (mob == null)
                {
                    return;
                }
                byte  direction = pr.ReadByte();
                int   skillid   = pr.ReadInt();
                int   pDmg      = pr.ReadInt();
                byte  defType   = pr.ReadByte();
                bool  pPhysical = false;
                int   pId       = 0;
                byte  pType     = 0;
                Point pPos      = Point.Empty;
                pr.ReadByte();
                if (skillid != 0)
                {
                    pPhysical = pr.ReadBool();
                    pId       = pr.ReadInt();
                    pType     = pr.ReadByte();
                    pr.Skip(4);
                    pPos = pr.ReadPoint();
                }
                byte offset  = 0;
                int  offsetD = 0;
                if (pr.Available == 1L)
                {
                    offset = pr.ReadByte();
                    if ((offset == 1) && (pr.Available >= 4L))
                    {
                        offsetD = pr.ReadInt();
                    }
                    if ((offset < 0) || (offset > 2))
                    {
                        offset = 0;
                    }
                }
                BroadcastDamagePlayerPacket(chr, type, damage, mobid, direction, skillid, pDmg, pPhysical, pId, pType, pPos, offset, offsetD, fake);
                damage = DoMonsterDamageModifiers(damage, chr, mob, oid);
                if (damage > 0)
                {
                    chr.AddHP(-damage);
                }
            }
            break;

            case 0xFD:                        //no mob, such as fall damage
            {
                short skill = pr.ReadShort(); //skill
                pr.ReadByte();                //?

                byte offset  = 0;
                int  offsetD = 0;
                if (pr.Available >= 1)
                {
                    offset = pr.ReadByte();
                    if ((offset == 1) && (pr.Available >= 4))
                    {
                        offsetD = pr.ReadInt();
                    }
                    if ((sbyte)offset < 0 || offset > 2)
                    {
                        offset = 0;
                    }
                }
                BroadcastDamagePlayerPacket(chr, type, damage, 0, 0, 0, 0, false, 0, 0, System.Drawing.Point.Empty, offset, offsetD, fake);
                if (damage > 0)
                {
                    chr.AddHP(-damage);
                }
            }
            break;

            default:
                ServerConsole.Error("Invalid CharacterReceiveDamage type {0} ", type);
                break;
            }
        }
        private static int DoMonsterDamageModifiers(int damage, MapleCharacter chr, MapleMonster mobFrom, int mobFromOID)
        {
            if (damage == 0) //guard/miss etc
            {
                Buff buff = chr.GetBuff(Priest.HOLY_MAGIC_SHELL);
                if (buff != null)
                {
                    buff.Stacks -= 1;
                    if (buff.Stacks == 0)
                    {
                        chr.CancelBuff(Priest.HOLY_MAGIC_SHELL);
                    }
                }
            }
            #region Spearman
            if (chr.IsSpearman)
            {
                if (chr.Job >= JobConstants.BERSERKER)
                {
                    if (chr.Job == JobConstants.DARKKNIGHT)
                    {
                        byte evilEyeRevengeLevel = chr.GetSkillLevel(DarkKnight.REVENGE_OF_THE_EVIL_EYE);
                        if (evilEyeRevengeLevel > 0 && !chr.HasSkillOnCooldown(DarkKnight.REVENGE_OF_THE_EVIL_EYE))
                        {
                            MapleSummon evilEye     = chr.GetSummon(Spearman.EVIL_EYE);
                            Buff        evilEyebuff = chr.GetBuff(Spearman.EVIL_EYE);
                            if (evilEye != null && evilEyebuff != null && evilEyebuff.Stacks != Berserker.EVIL_EYE_OF_DOMINATION)
                            {
                                SkillEffect effect       = DataBuffer.GetCharacterSkillById(DarkKnight.REVENGE_OF_THE_EVIL_EYE).GetEffect(evilEyeRevengeLevel);
                                int         summonDamage = (int)((effect.Info[CharacterSkillStat.damage] / 100.0) * chr.Stats.GetDamage());
                                int         healHp       = (int)((effect.Info[CharacterSkillStat.x] / 100.0) * summonDamage);
                                chr.AddHP(healHp);
                                //instant KO:
                                if (!mobFrom.IsBoss && summonDamage < mobFrom.HP)
                                {
                                    if (Functions.MakeChance(effect.Info[CharacterSkillStat.z]))
                                    {
                                        summonDamage = mobFrom.HP;
                                    }
                                }
                                evilEye.AttackMonster(summonDamage, 0x84, mobFrom);
                                chr.AddCooldownSilent(DarkKnight.REVENGE_OF_THE_EVIL_EYE, (uint)effect.Info[CharacterSkillStat.cooltime] * 1000, DateTime.UtcNow, false);
                            }
                        }
                        if (chr.HasBuff(DarkKnight.FINAL_PACT2))
                        {
                            return(0); //Invincible
                        }
                    }
                    Buff crossSurgeBuff = chr.GetBuff(Berserker.CROSS_SURGE);
                    if (crossSurgeBuff != null)
                    {
                        int absorbPercent = crossSurgeBuff.Effect.Info[CharacterSkillStat.y];
                        int absorb        = (int)((chr.Stats.MaxHp - chr.Hp) * (absorbPercent / 100.0));
                        absorb  = Math.Min(absorb, crossSurgeBuff.Effect.Info[CharacterSkillStat.z]); //normally z = 4000
                        damage -= absorb;
                    }
                }
            }
            #endregion
            #region Magician
            else if (chr.IsMagician)
            {
                Buff buff = chr.GetBuff(Magician.MAGIC_GUARD);
                if (buff != null)
                {
                    if (chr.Mp > 0)
                    {
                        int absorb = (int)((buff.Effect.Info[CharacterSkillStat.x] / 100.0) * damage);
                        if (chr.Mp < absorb)
                        {
                            absorb = chr.Mp;
                        }
                        chr.AddMP(-absorb);
                        damage -= absorb;
                    }
                }
            }
            #endregion
            #region Bandit
            else if (chr.IsBandit)
            {
                Buff mesoGuard = chr.GetBuff(Bandit.MESOGUARD);
                if (mesoGuard != null)
                {
                    double absorb            = 0.5;
                    double mesoLoss          = mesoGuard.Effect.Info[CharacterSkillStat.x] / 100.0;
                    double mesoLossReduction = 0.0;
                    byte   MesoMasteryLevel  = chr.GetSkillLevel(ChiefBandit.MESO_MASTERY);
                    if (MesoMasteryLevel > 0)
                    {
                        SkillEffect effect = DataBuffer.GetCharacterSkillById(ChiefBandit.MESO_MASTERY).GetEffect(MesoMasteryLevel);
                        absorb           += effect.Info[CharacterSkillStat.v] / 100.0;
                        mesoLossReduction = effect.Info[CharacterSkillStat.v] / 100.0;
                    }
                    int damageAbsorbed = (int)(damage * absorb);
                    if (damageAbsorbed > 0)
                    {
                        int mesoUse = (int)(damageAbsorbed * mesoLoss);
                        mesoUse -= (int)(mesoUse * mesoLossReduction);
                        if (chr.Mesos >= mesoUse)
                        {
                            chr.Inventory.RemoveMesos(mesoUse, false);
                            damage -= damageAbsorbed;
                            int mesoDrops = Functions.Random(1, 4);
                            for (int i = 0; i < mesoDrops; i++)
                            {
                                chr.Map.SpawnMesoMapItem(1, chr.Position, chr.Map.GetDropPositionBelow(chr.Position, chr.Position), false, MapleDropType.Player, chr);
                            }
                        }
                    }
                }
            }
            #endregion
            #region Luminous
            else if (chr.IsLuminous)
            {
                Buff oldBuff = chr.GetBuff(Luminous2.BLACK_BLESSING);
                if (oldBuff != null)
                {
                    int remove = (int)(damage * 0.7);
                    damage -= remove;
                    if (oldBuff.Stacks < 2)
                    {
                        chr.CancelBuff(Luminous2.BLACK_BLESSING);
                    }
                    else
                    {
                        chr.CancelBuffSilent(Luminous2.BLACK_BLESSING);
                        Buff newBuff = new Buff(oldBuff.SkillId, oldBuff.Effect, oldBuff.Duration, chr);
                        newBuff.Stacks = oldBuff.Stacks - 1;
                        chr.GiveBuff(newBuff);
                    }
                }
                byte skillLevel = 0;
                if ((skillLevel = chr.GetSkillLevel(Luminous1.STANDARD_MAGIC_GUARD)) > 0)
                {
                    SkillEffect effect  = DataBuffer.GetCharacterSkillById(Luminous1.STANDARD_MAGIC_GUARD).GetEffect(skillLevel);
                    double      percent = effect.Info[CharacterSkillStat.x] / 100.0;
                    int         absorb  = (int)(percent * damage);
                    if (chr.Mp >= absorb)
                    {
                        chr.AddMP(absorb);
                        damage -= absorb;
                    }
                }
            }
            #endregion

            return(damage);
        }