Esempio n. 1
0
        public static void Proc(ref Actor sActor, ref Actor dActor, ref Map.SkillArgs args)
        {
            ActorPC pc = (ActorPC)sActor;

            ActorEventHandlers.PC_EventHandler eh = (SagaMap.ActorEventHandlers.PC_EventHandler)pc.e;
            if (sActor.type == ActorType.PC)
            {
                if (!SkillHandler.CheckSkillSP(pc, args.skillID))
                {
                    SkillHandler.SetSkillFailed(ref args);
                    return;
                }
                args.damage     = 0;
                args.isCritical = Map.SkillArgs.AttackResult.Heal;
                ActorPC targetPC;
                args.damage = CalcDamage(sActor, dActor, args);
                if (dActor.type == ActorType.PC)
                {
                    targetPC     = (ActorPC)dActor;
                    eh           = (SagaMap.ActorEventHandlers.PC_EventHandler)targetPC.e;
                    targetPC.HP += (ushort)args.damage;
                    eh.C.SendSkillEffect(SkillFactory.GetSkill((uint)args.skillID).addition, SkillEffects.HP, args.damage);
                    if (targetPC.HP > targetPC.maxHP)
                    {
                        targetPC.HP = targetPC.maxHP;
                    }
                    eh.C.SendCharStatus(0);
                }
            }
        }
Esempio n. 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;
                }
            }
        }
Esempio n. 3
0
    public IEnumerator Start()
    {
        Responsible.JobFinished   = false;
        Responsible.TargetInRange = false;

        if (Target)
        {
            Responsible.Target = Target.gameObject;
        }

        Responsible.StartCoroutine(Coroutine);

        if (!Responsible.Inventory.InInventory(Target.gameObject))
        {
            yield return(new WaitUntil(() => Responsible.TargetInRange));
        }

        if (Target == null || Target.InUse <= 0 || !Target.Methods.Contains(Method))
        {
            Debug.Log("Target is already in use!");
            Stop(true);
            yield break;
        }

        _started = true;
        Debug.Log("Reached to the target now I'm gonna start doing my job!");
        Target.InUse--;
        SkillManager.AddSkill(Responsible, SkillFactory.GetSkill(SkillType));
        EffectManager.Apply(Responsible, Effects);
    }
Esempio n. 4
0
        public static void Proc(ref Actor sActor, ref Actor dActor, ref Map.SkillArgs args)
        {
            if (sActor.type == ActorType.PC)
            {
                ActorPC pc = (ActorPC)sActor;
                if (pc.SP < SkillFactory.GetSkill((uint)args.skillID).sp)
                {
                    args.damage     = 0;
                    args.isCritical = Map.SkillArgs.AttackResult.Miss;
                    args.failed     = true;
                    return;
                }
                else
                {
                    ActorEventHandlers.PC_EventHandler eh = (ActorEventHandlers.PC_EventHandler)pc.e;
                    pc.SP -= (ushort)SkillFactory.GetSkill((uint)args.skillID).sp;
                    pc.LP += 1;
                    if (pc.LP > 5)
                    {
                        pc.LP = 5;
                    }
                    eh.C.SendCharStatus(0);
                }
            }
            args.damage     = 0;
            args.isCritical = Map.SkillArgs.AttackResult.Nodamage;
            byte    level    = (byte)(args.skillID - baseID + 1);
            ActorPC targetpc = (ActorPC)dActor;

            Tasks.PassiveSkillStatus ss;

            if (targetpc.Tasks.ContainsKey("VenomCoat"))
            {
                ss       = (PassiveSkillStatus)targetpc.Tasks["VenomCoat"];
                ss.level = level;
                SkillHandler.RemoveStatusIcon(dActor, (uint)1457400 + ss.level);
                targetpc.BattleStatus.atkskill -= CalcDamage(ss.level);
                ss.Deactivate();
                ss.dueTime = 1;
                ss.period  = 600000;
                targetpc.BattleStatus.atkskill += CalcDamage(level);
                SkillHandler.AddStatusIcon(dActor, (uint)args.skillID, 600000);
                ss.Activate();
            }
            else
            {
                ss         = new PassiveSkillStatus(level);
                ss.dueTime = 1;
                ss.period  = 600000;

                ss.client = dActor;
                ss.Func   = new PassiveSkillStatus.CallBackFunc(Callback);
                targetpc.Tasks.Add("VenomCoat", ss);
                targetpc.BattleStatus.atkskill += CalcDamage(level);
                SkillHandler.AddStatusIcon(dActor, (uint)args.skillID, 600000);
                ss.Activate();
            }
        }
Esempio n. 5
0
        public IActionResult GetSkill(int skillId)
        {
            Skill desc = SkillFactory.GetSkill(skillId);

            if (desc == null)
            {
                return(NotFound());
            }
            return(Json(desc));
        }
Esempio n. 6
0
            public MapleStatEffect GetAttackEffect(MapleCharacter chr, ISkill theSkill)
            {
                var mySkill    = theSkill ?? SkillFactory.GetSkill(Skill);
                var skillLevel = chr.GetSkillLevel(mySkill);

                if (mySkill.SkillId == 1009 || mySkill.SkillId == 10001009)
                {
                    skillLevel = 1;
                }
                return(skillLevel == 0 ? null : mySkill.GetEffect(skillLevel));
            }
Esempio n. 7
0
 public MapleSummon(MapleCharacter owner, int skill, Point pos, SummonMovementType movementType)
 {
     Owner      = owner;
     SkillId    = skill;
     SkillLevel = owner.GetSkillLevel(SkillFactory.GetSkill(skill));
     if (SkillLevel == 0)
     {
         Console.WriteLine("Trying to create a summon for a char without the skill");
     }
     MovementType = movementType;
     Position     = pos;
 }
Esempio n. 8
0
 public void AddSkill(SkillName name)
 {
     if (!HasSkill(name))
     {
         Skill s = SkillFactory.GetSkill(name);
         Skills.Add(s);
     }
     else
     {
         Console.WriteLine($"{Name} already knows {name}");
     }
 }
Esempio n. 9
0
        public void OnChangeStatus(Actor sActor, MapEventArgs args)
        {
            Map.StatusArgs arg = (Map.StatusArgs)args;
            switch (arg.type)
            {
            case Map.StatusArgs.EventType.Add:
                foreach (Map.StatusArgs.StatusInfo i in arg.StatusList)
                {
                    Packets.Server.ExchangeAddition p1 = new SagaMap.Packets.Server.ExchangeAddition();
                    p1.SetID(sActor.id);
                    Skill info = SkillFactory.GetSkill(i.SkillID);
                    if (info != null)
                    {
                        p1.SetStatusID(info.addition);
                    }
                    else
                    {
                        p1.SetStatusID(i.SkillID);
                    }
                    p1.SetTime(i.time);
                    this.C.netIO.SendPacket(p1, C.SessionID);
                }
                break;

            case Map.StatusArgs.EventType.Remove:
                foreach (Map.StatusArgs.StatusInfo i in arg.StatusList)
                {
                    Packets.Server.DeleteExchangeAddition p1 = new SagaMap.Packets.Server.DeleteExchangeAddition();
                    p1.SetID(sActor.id);
                    Skill info = SkillFactory.GetSkill(i.SkillID);
                    if (info != null)
                    {
                        p1.SetStatusID(info.addition);
                    }
                    else
                    {
                        p1.SetStatusID(i.SkillID);
                    }
                    this.C.netIO.SendPacket(p1, C.SessionID);
                }
                break;
            }
        }
Esempio n. 10
0
        public void TestSkillFacotry(SkillName s)
        {
            Skill expected = null;

            switch (s)
            {
            case SkillName.Learning:
                expected = new Learning();
                break;

            case SkillName.Logistics:
                expected = new Logistics();
                break;

            case SkillName.Offense:
                expected = new Offense();
                break;
            }
            Skill actual = SkillFactory.GetSkill(s);

            Assert.Equal(expected.Name, actual.Name);
        }
Esempio n. 11
0
 public static void Proc(ref Actor sActor, ref Actor dActor, ref Map.SkillArgs args)
 {
     if (sActor.type == ActorType.PC)
     {
         ActorPC pc = (ActorPC)sActor;
         if (pc.SP < SkillFactory.GetSkill((uint)args.skillID).sp)
         {
             args.damage     = 0;
             args.isCritical = Map.SkillArgs.AttackResult.Miss;
             args.failed     = true;
             return;
         }
         else
         {
             ActorEventHandlers.PC_EventHandler eh = (ActorEventHandlers.PC_EventHandler)pc.e;
             pc.SP -= (ushort)SkillFactory.GetSkill((uint)args.skillID).sp;
             pc.LP += 1;
             if (pc.LP > 5)
             {
                 pc.LP = 5;
             }
             eh.C.SendCharStatus(0);
         }
     }
     args.damage     = 0;
     args.isCritical = SkillHandler.CalcCrit(sActor, dActor, args, SkillHandler.AttackType.Physical);
     if (args.isCritical != Map.SkillArgs.AttackResult.Miss && args.isCritical != Map.SkillArgs.AttackResult.Block)
     {
         ActorPC targetPC = (ActorPC)sActor;
         args.damage = CalcDamage(sActor, dActor, args);
     }
     if (args.damage <= 0)
     {
         args.damage = 1;
     }
     SkillHandler.PhysicalAttack(ref sActor, ref dActor, args.damage, SkillHandler.AttackElements.HOLY, ref args);
 }
Esempio n. 12
0
        public bool ApplyStatus(MapleCharacter from, MonsterStatusEffect status, bool poison, long duration, bool venom)
        {
            switch (Stats.GetEffectiveness(status.GetSkill().Element).Value)
            {
            case 1:     //IMMUNE:
            case 2:     //STRONG:
                return(false);

            case 0:     //NORMAL:
            case 3:     //WEAK:
                break;

            default:
                throw new Exception(
                          $"Unknown elemental effectiveness:{Stats.GetEffectiveness(status.GetSkill().Element)}");
            }

            // compos don't have an elemental (they have 2 - so we have to hack here...)
            ElementalEffectiveness effectiveness = null;

            switch (status.GetSkill().SkillId)
            {
            case 2111006:
                effectiveness = Stats.GetEffectiveness(Element.Poison);
                if (effectiveness == ElementalEffectiveness.Immune || effectiveness == ElementalEffectiveness.Strong)
                {
                    return(false);
                }
                break;

            case 2211006:
                effectiveness = Stats.GetEffectiveness(Element.Ice);
                if (effectiveness == ElementalEffectiveness.Strong || effectiveness == ElementalEffectiveness.Strong)
                {
                    return(false);
                }
                break;

            case 4120005:
            case 4220005:
                effectiveness = Stats.GetEffectiveness(Element.Poison);
                if (effectiveness == ElementalEffectiveness.Weak)
                {
                    return(false);
                }
                break;
            }

            if (poison && Hp <= 1)
            {
                return(false);
            }

            if (IsBoss && !status.Stati.ContainsKey(MonsterStatus.Speed))
            {
                return(false);
            }

            status.Stati.Keys.ToList().ForEach(stat =>
            {
                MonsterStatusEffect oldEffect;
                if (m_stati.TryGetValue(stat, out oldEffect))
                {
                    oldEffect.RemoveActiveStatus(stat);
                    if (!oldEffect.Stati.Any())
                    {
                        //oldEffect.getCancelTask().cancel(false);
                        //oldEffect.cancelPoisonSchedule();
                        m_activeEffects.Remove(oldEffect);
                    }
                }
            });

            var    timerManager = TimerManager.Instance;
            Action cancelTask   = () =>
            {
                if (IsAlive)
                {
                    var packet = PacketCreator.CancelMonsterStatus(ObjectId, status.Stati);
                    Map.BroadcastMessage(packet, Position);
                    if (GetController() != null && !GetController().VisibleMapObjects.Contains(this))
                    {
                        GetController().Client.Send(packet);
                    }
                }
                try
                {
                    m_activeEffects.Remove(status);
                    status.Stati.Keys.ToList().ForEach(stat => { m_stati.Remove(stat); });
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
                VenomMultiplier = 0;
                //status.cancelPoisonSchedule();
            };

            if (!Map.HasEvent)
            {
                if (poison)
                {
                    var poisonLevel  = from.GetSkillLevel(status.GetSkill());
                    var poisonDamage = Math.Min(short.MaxValue, (int)(MaxHp / (70.0 - poisonLevel) + 0.999));
                    status.SetValue(MonsterStatus.Poison, poisonDamage);
                    //status.setPoisonSchedule(timerManager.register(new PoisonTask(poisonDamage, from, status, cancelTask, false), 1000, 1000));
                }
                else if (venom)
                {
                    if (from.Job == MapleJob.Nightlord || from.Job == MapleJob.Shadower)
                    {
                        var poisonLevel = 0;
                        var matk        = 0;
                        if (from.Job == MapleJob.Nightlord)
                        {
                            poisonLevel = from.GetSkillLevel(SkillFactory.GetSkill(4120005));
                            if (poisonLevel <= 0)
                            {
                                return(false);
                            }
                            matk = SkillFactory.GetSkill(4120005).GetEffect(poisonLevel).Matk;
                        }
                        else if (from.Job == MapleJob.Shadower)
                        {
                            poisonLevel = from.GetSkillLevel(SkillFactory.GetSkill(4220005));
                            if (poisonLevel <= 0)
                            {
                                return(false);
                            }
                            matk = SkillFactory.GetSkill(4220005).GetEffect(poisonLevel).Matk;
                        }
                        else
                        {
                            return(false);
                        }

                        int luk    = from.Luk;
                        var maxDmg = (int)Math.Ceiling(Math.Min(short.MaxValue, 0.2 * luk * matk));
                        var minDmg = (int)Math.Ceiling(Math.Min(short.MaxValue, 0.1 * luk * matk));
                        var gap    = maxDmg - minDmg;
                        if (gap == 0)
                        {
                            gap = 1;
                        }
                        var poisonDamage = 0;
                        for (var i = 0; i < VenomMultiplier; i++)
                        {
                            poisonDamage = poisonDamage + Randomizer.Next(gap) + minDmg;
                        }
                        poisonDamage = Math.Min(short.MaxValue, poisonDamage);
                        status.SetValue(MonsterStatus.Poison, poisonDamage);
                        //status.setPoisonSchedule(timerManager.register(new PoisonTask(poisonDamage, from, status, cancelTask, false), 1000, 1000));
                    }
                    else
                    {
                        return(false);
                    }
                }
                else if (status.GetSkill().SkillId == 4111003)
                {
                    // shadow web
                    var webDamage = (int)(MaxHp / 50.0 + 0.999);
                    // actually shadow web works different but similar...
                    //status.setPoisonSchedule(timerManager.schedule(new PoisonTask(webDamage, from, status, cancelTask, true), 3500));
                }

                foreach (var stat in status.Stati.Keys)
                {
                    if (m_stati.ContainsKey(stat))
                    {
                        m_stati[stat] = status;
                    }
                    else
                    {
                        m_stati.Add(stat, status);
                    }
                }

                m_activeEffects.Add(status);

                var animationTime = status.GetSkill().AnimationTime;
                var packet        = PacketCreator.ApplyMonsterStatus(ObjectId, status.Stati, status.GetSkill().SkillId, false,
                                                                     0);
                Map.BroadcastMessage(packet, Position);
                if (GetController() != null && !GetController().VisibleMapObjects.Contains(this))
                {
                    GetController().Client.Send(packet);
                }
                //ScheduledFuture <?> schedule = timerManager.schedule(cancelTask, duration + animationTime);
                //status.setCancelTask(schedule);
            }
            return(true);
        }
Esempio n. 13
0
        public void Run(MapleCharacter c, int?extSelection)
        {
            MapleQuestStatus status;

            switch (Type)
            {
            case MapleQuestActionType.Exp:
                status = c.GetQuest(m_quest);
                if (status.Status == MapleQuestStatusType.NotStarted && status.Forfeited > 0)
                {
                    break;
                }
                c.GainExp(MapleDataTool.GetInt(Data) * c.Client.ChannelServer.ExpRate, true, true);
                break;

            case MapleQuestActionType.Item:
                var ii    = MapleItemInformationProvider.Instance;
                var props = new Dictionary <int, int>();
                foreach (var iEntry in Data.Children)
                {
                    if (iEntry.GetChildByPath("prop") != null &&
                        MapleDataTool.GetInt(iEntry.GetChildByPath("prop")) != -1 && CanGetItem(iEntry, c))
                    {
                        for (var i = 0; i < MapleDataTool.GetInt(iEntry.GetChildByPath("prop")); i++)
                        {
                            props.Add(props.Count, MapleDataTool.GetInt(iEntry.GetChildByPath("id")));
                        }
                    }
                }
                var selection = 0;
                var extNum    = 0;
                if (props.Any())
                {
                    props.TryGetValue((int)(Randomizer.NextDouble() * props.Count), out selection);
                }
                foreach (var iEntry in Data.Children)
                {
                    if (!CanGetItem(iEntry, c))
                    {
                        continue;
                    }
                    if (iEntry.GetChildByPath("prop") != null)
                    {
                        if (MapleDataTool.GetInt(iEntry.GetChildByPath("prop")) == -1)
                        {
                            if (extSelection.HasValue && extSelection.Value != extNum++)
                            {
                                continue;
                            }
                        }
                        else if (MapleDataTool.GetInt(iEntry.GetChildByPath("id")) != selection)
                        {
                            continue;
                        }
                    }
                    if (MapleDataTool.GetInt(iEntry.GetChildByPath("count"), 0) < 0)
                    {
                        // remove items

                        var itemId   = MapleDataTool.GetInt(iEntry.GetChildByPath("id"));
                        var iType    = ii.GetInventoryType(itemId);
                        var quantity = (short)(MapleDataTool.GetInt(iEntry.GetChildByPath("count"), 0) * -1);
                        try
                        {
                            //MapleInventoryManipulator.removeById(c.Client, iType, itemId, quantity, true, false);
                        }
                        catch
                        {
                            Console.WriteLine("Completing a quest without meeting the requirements");
                        }
                        c.Client.Send(PacketCreator.GetShowItemGain(itemId,
                                                                    (short)MapleDataTool.GetInt(iEntry.GetChildByPath("count"), 0), true));
                    }
                    else
                    {
                        // add items

                        var itemId   = MapleDataTool.GetInt(iEntry.GetChildByPath("id"));
                        var quantity = (short)MapleDataTool.GetInt(iEntry.GetChildByPath("count"), 0);
                        var logInfo  = new StringBuilder(c.Name);
                        logInfo.Append(" received ");
                        logInfo.Append(quantity);
                        logInfo.Append(" as reward from a quest");
                        // MapleInventoryManipulator.addById(c.Client, itemId, quantity, logInfo.ToString(), null, -1);
                        c.Client.Send(PacketCreator.GetShowItemGain(itemId, quantity, true));
                    }
                }
                break;

            case MapleQuestActionType.Nextquest:
                status = c.GetQuest(m_quest);
                var nextQuest = MapleDataTool.GetInt(Data);
                if (status.Status == MapleQuestStatusType.NotStarted && status.Forfeited > 0)
                {
                    break;
                }
                c.Client.Send(PacketCreator.UpdateQuestFinish((short)m_quest.GetQuestId(), status.Npcid,
                                                              (short)nextQuest));
                MapleQuest.GetInstance(nextQuest).Start(c, status.Npcid);
                break;

            case MapleQuestActionType.Meso:
                status = c.GetQuest(m_quest);
                if (status.Status == MapleQuestStatusType.NotStarted && status.Forfeited > 0)
                {
                    break;
                }
                c.GainMeso(MapleDataTool.GetInt(Data), true, false, true);
                break;

            case MapleQuestActionType.Quest:
                foreach (var qEntry in Data)
                {
                    var questid = MapleDataTool.GetInt(qEntry.GetChildByPath("id"));
                    var stat    = MapleDataTool.GetInt(qEntry.GetChildByPath("state"), 0);
                    c.UpdateQuest(new MapleQuestStatus(MapleQuest.GetInstance(questid), (MapleQuestStatusType)stat));
                }
                break;

            case MapleQuestActionType.Skill:
                foreach (var sEntry in Data)
                {
                    var skillid        = MapleDataTool.GetInt(sEntry.GetChildByPath("id"));
                    var skillLevel     = (byte)MapleDataTool.GetInt(sEntry.GetChildByPath("skillLevel"));
                    var masterLevel    = (byte)MapleDataTool.GetInt(sEntry.GetChildByPath("masterLevel"));
                    var skillObject    = SkillFactory.GetSkill(skillid);
                    var shouldLearn    = false;
                    var applicableJobs = sEntry.GetChildByPath("job");
                    foreach (var applicableJob in applicableJobs)
                    {
                        var job = MapleJob.GetByJobId(MapleDataTool.GetShort(applicableJob));
                        if (c.Job == job)
                        {
                            shouldLearn = true;
                            break;
                        }
                    }
                    if (skillObject.IsBeginnerSkill)
                    {
                        shouldLearn = true;
                    }
                    skillLevel  = Math.Max(skillLevel, c.GetSkillLevel(skillObject));
                    masterLevel = Math.Max(masterLevel, skillObject.MaxLevel);
                    if (shouldLearn)
                    {
                        c.ChangeSkillLevel(skillObject, skillLevel, masterLevel);
                        c.DropMessage(
                            $"你已获得 {SkillFactory.GetSkillName(skillid)} 当前等级 {skillLevel} 最高等级 {masterLevel}");
                    }
                }
                break;

            case MapleQuestActionType.Fame:
                status = c.GetQuest(m_quest);
                if (status.Status == MapleQuestStatusType.NotStarted && status.Forfeited > 0)
                {
                    break;
                }
                c.Fame += MapleDataTool.GetShort(Data);
                c.UpdateSingleStat(MapleStat.Fame, c.Fame);
                var fameGain = MapleDataTool.GetInt(Data);
                c.Client.Send(PacketCreator.GetShowFameGain(fameGain));
                break;

            case MapleQuestActionType.Buff:
                status = c.GetQuest(m_quest);
                if (status.Status == MapleQuestStatusType.NotStarted && status.Forfeited > 0)
                {
                    break;
                }
                var mii = MapleItemInformationProvider.Instance;
                //mii.GetItemEffect(MapleDataTool.GetInt(data)).applyTo(c);
                break;

            case MapleQuestActionType.Petskill:
                status = c.GetQuest(m_quest);
                if (status.Status == MapleQuestStatusType.NotStarted && status.Forfeited > 0)
                {
                    break;
                }
                var flag = MapleDataTool.GetInt("petskill", Data);
                //c.getPet(0).setFlag((byte)(c.getPet(0).getFlag() | InventoryConstants.Items.Flags.getFlagByInt(flag)));
                break;

            default:
                break;
            }
        }
Esempio n. 14
0
        public static AttackInfo ParseDamage(MapleCharacter c, InPacket p, bool ranged)
        {
            var ret = new AttackInfo();

            p.ReadByte();
            p.Skip(8);
            ret.NumAttackedAndDamage = p.ReadByte();
            p.Skip(8);
            ret.NumAttacked = RightMove(ret.NumAttackedAndDamage, 4) & 0xF;
            ret.NumDamage   = ret.NumAttackedAndDamage & 0xF;
            ret.AllDamage   = new List <Tuple <int, List <int> > >();
            ret.Skill       = p.ReadInt();
            p.Skip(8);

            if ((ret.Skill == 2121001) || (ret.Skill == 2221001) || (ret.Skill == 2321001) || (ret.Skill == 5201002) ||
                (ret.Skill == 14111006) || (ret.Skill == 5101004) || (ret.Skill == 15101003))
            {
                ret.Charge = p.ReadInt();
            }
            else
            {
                ret.Charge = 0;
            }

            if (ret.Skill == 1221011)
            {
                ret.IsHh = true;
            }

            p.ReadInt();
            ret.AresCombo = p.ReadByte(); //记录目前的Combo点数
            var sourceid = ret.Skill;     //以下�?能为Combo专用�?�?

            if ((sourceid == 21100004) || (sourceid == 21100005) || (sourceid == 21110003) || (sourceid == 21110004) ||
                (sourceid == 21120006) || (sourceid == 21120007))
            {
                //c.setCombo(1);
            }
            ret.Pos    = p.ReadByte(); //动作
            ret.Stance = p.ReadByte(); //姿势

            if (ret.Skill == 4211006)
            {
                //return parseMesoExplosion(lea, ret);
            }

            if (ranged)
            {
                p.ReadByte();
                ret.Speed = p.ReadByte();
                p.ReadByte();
                ret.Direction = p.ReadByte();
                p.Skip(7);
                if ((ret.Skill == 3121004) || (ret.Skill == 3221001) || (ret.Skill == 5221004) ||
                    (ret.Skill == 13111002))
                {
                    p.Skip(4);
                }
            }
            else
            {
                p.ReadByte();
                ret.Speed = p.ReadByte();
                p.Skip(4);
            }

            for (var i = 0; i < ret.NumAttacked; ++i)
            {
                var oid = p.ReadInt();

                p.Skip(14);

                var allDamageNumbers = new List <int>();
                for (var j = 0; j < ret.NumDamage; ++j)
                {
                    var damage = p.ReadInt();

                    MapleStatEffect effect = null;
                    if (ret.Skill != 0)
                    {
                        effect =
                            SkillFactory.GetSkill(ret.Skill)
                            .GetEffect(c.GetSkillLevel(SkillFactory.GetSkill(ret.Skill)));
                    }

                    if ((damage != 0) && (effect != null) && (effect.GetFixedDamage() != 0))
                    {
                        damage = effect.GetFixedDamage();
                    }

                    allDamageNumbers.Add(damage);
                }
                if (ret.Skill != 5221004)
                {
                    p.Skip(4);
                }

                ret.AllDamage.Add(Tuple.Create(oid, allDamageNumbers));
            }

            return(ret);
        }
Esempio n. 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}");
                    }
                }
            }
        }
Esempio n. 16
0
 public static void SetSkill(SkillEnum s, Level l)
 {
     skill = SkillFactory.GetSkill(s, l);
 }
Esempio n. 17
0
        public static void ApplyAttack(AttackInfo attack, MapleCharacter player, int maxDamagePerMonster,
                                       int attackCount)
        {
            //应用攻击
            player.AntiCheatTracker.ResetHpRegen();
            //player.resetAfkTimer();
            player.AntiCheatTracker.CheckAttack(attack.Skill);

            ISkill          theSkill     = null;
            MapleStatEffect attackEffect = null;

            if (attack.Skill != 0)
            {
                theSkill     = SkillFactory.GetSkill(attack.Skill);
                attackEffect = attack.GetAttackEffect(player, theSkill);
                if (attackEffect == null)
                {
                    AutobanManager.Instance.Autoban(player.Client, $"使用了没有的技能ID:{attack.Skill}");
                }
                else if (attack.Skill != 2301002)
                {
                    if (player.IsAlive)
                    {
                        attackEffect.ApplyTo(player);
                    }
                    else
                    {
                        player.Client.Send(PacketCreator.EnableActions());
                    }
                }
            }

            if (!player.IsAlive)
            {
                player.AntiCheatTracker.RegisterOffense(CheatingOffense.AttackingWhileDead);
                return;
            }

            if (attackCount != attack.NumDamage && attack.Skill != 4211006 && attack.NumDamage != attackCount * 2)
            {
                player.AntiCheatTracker.RegisterOffense(CheatingOffense.MismatchingBulletcount,
                                                        attack.NumDamage + "/" + attackCount);
                return;
            }

            var totDamage = 0;
            var map       = player.Map;

            if (attack.Skill == 4211006)
            {
                // meso explosion
                long delay = 0;
                foreach (var oned in attack.AllDamage)
                {
                    var mapobject = map.Mapobjects[oned.Item1];
                    if (mapobject != null && mapobject.GetType() == MapleMapObjectType.Item)
                    {
                        var mapitem = (MapleMapItem)mapobject;
                        if (mapitem.Meso > 0)
                        {
                            lock (mapitem)
                            {
                                if (mapitem.IsPickedUp)
                                {
                                    return;
                                }
                                TimerManager.Instance.RunOnceTask(() =>
                                {
                                    map.RemoveMapObject(mapitem);
                                    map.BroadcastMessage(PacketCreator.RemoveItemFromMap(mapitem.ObjectId, 4, 0),
                                                         mapitem.Position);
                                    mapitem.IsPickedUp = true;
                                }, delay);
                                delay += 100;
                            }
                        }
                        else if (mapitem.Meso == 0)
                        {
                            player.AntiCheatTracker.RegisterOffense(CheatingOffense.EtcExplosion);
                            return;
                        }
                    }
                    else if (mapobject != null && mapobject.GetType() != MapleMapObjectType.Monster)
                    {
                        player.AntiCheatTracker.RegisterOffense(CheatingOffense.ExplodingNonexistant);
                        return; // etc explosion, exploding nonexistant things, etc.
                    }
                }
            }

            foreach (var oned in attack.AllDamage)
            {
                var monster = map.GetMonsterByOid(oned.Item1);

                if (monster != null)
                {
                    var totDamageToOneMonster = 0;
                    foreach (var eachd in oned.Item2)
                    {
                        totDamageToOneMonster += eachd;
                    }
                    totDamage += totDamageToOneMonster;


                    player.CheckMonsterAggro(monster);
                    if (totDamageToOneMonster > attack.NumDamage + 1)
                    {
                        var dmgCheck = player.AntiCheatTracker.CheckDamage(totDamageToOneMonster);
                        if (dmgCheck > 5 && totDamageToOneMonster < 99999 && monster.Id < 9500317 &&
                            monster.Id > 9500319)
                        {
                            player.AntiCheatTracker
                            .RegisterOffense(CheatingOffense.SameDamage,
                                             dmgCheck + " times: " + totDamageToOneMonster);
                        }
                    }
                    // �?测单次攻击�?�,这里不会�?!
                    if (player.IsGm || player.Job == MapleJob.Ares && player.Level <= 10)
                    {
                        //log.info("这里不进行操�?");
                    }
                    else
                    {
                        if (player.Level < 10)
                        {
                            if (totDamageToOneMonster > 10000)
                            {
                                AutobanManager.Instance.BroadcastMessage(player.Client,
                                                                         player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " +
                                                                         player.Level + ")");
                                //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")");
                                return;
                            }
                        }
                        if (player.Level < 20)
                        {
                            if (totDamageToOneMonster > 20000)
                            {
                                AutobanManager.Instance.BroadcastMessage(player.Client,
                                                                         player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " +
                                                                         player.Level + ")");
                                //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")");
                                return;
                            }
                        }
                        if (player.Level < 30)
                        {
                            if (totDamageToOneMonster > 30000)
                            {
                                AutobanManager.Instance.BroadcastMessage(player.Client,
                                                                         player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " +
                                                                         player.Level + ")");
                                //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")");
                                return;
                            }
                        }
                        if (player.Level < 50)
                        {
                            if (totDamageToOneMonster > 50000)
                            {
                                AutobanManager.Instance.BroadcastMessage(player.Client,
                                                                         player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " +
                                                                         player.Level + ")");
                                //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")");
                                return;
                            }
                        }
                        if (player.Level < 70)
                        {
                            if (totDamageToOneMonster > 150000)
                            {
                                AutobanManager.Instance.BroadcastMessage(player.Client,
                                                                         player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " +
                                                                         player.Level + ")");
                                //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")");
                                return;
                            }
                        }
                        if (player.Level < 150)
                        {
                            if (totDamageToOneMonster > 350000)
                            {
                                AutobanManager.Instance.BroadcastMessage(player.Client,
                                                                         player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " +
                                                                         player.Level + ")");
                                //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")");
                                return;
                            }
                        }
                    }

                    CheckHighDamage(player, monster, attack, theSkill, attackEffect, totDamageToOneMonster,
                                    maxDamagePerMonster);
                    var distance = player.Position.DistanceSquare(monster.Position);
                    if (distance > 400000.0)
                    {
                        // 600^2, 550 is approximatly the range of ultis
                        player.AntiCheatTracker.RegisterOffense(CheatingOffense.AttackFarawayMonster,
                                                                Math.Sqrt(distance).ToString(CultureInfo.InvariantCulture));
                    } //遥远的�?�物袭击

                    if (attack.Skill == 5111004)
                    {
                        // 能量转换
                        var edrain = SkillFactory.GetSkill(5111004);
                        var gainhp = (int)
                                     (totDamage * (double)edrain.GetEffect(player.GetSkillLevel(edrain)).X / 100.0);
                        gainhp     = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2));
                        player.Hp += (short)gainhp;
                    }
                    else if (attack.Skill == 15100004)
                    {
                        //光�?�拳
                        var edrain = SkillFactory.GetSkill(15100004);
                        var gainhp = (int)
                                     (totDamage * (double)edrain.GetEffect(player.GetSkillLevel(edrain)).X / 100.0);
                        gainhp     = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2));
                        player.Hp += (short)gainhp;
                    }

                    if (!monster.ControllerHasAggro)
                    {
                        if (monster.GetController() == player)
                        {
                            monster.ControllerHasAggro = true;
                        }
                        else
                        {
                            monster.SwitchController(player, true);
                        }
                    }
                    if (attack.Skill == 2301002 && !monster.Stats.IsUndead)
                    {
                        player.AntiCheatTracker.RegisterOffense(CheatingOffense.HealAttackingUndead); //医治攻击亡灵
                        return;
                    }
                    // Pickpocket
                    if ((attack.Skill == 4001334 || attack.Skill == 4201005 || attack.Skill == 0 ||
                         attack.Skill == 4211002 || attack.Skill == 4211004) &&
                        player.GetBuffedValue(MapleBuffStat.Pickpocket) != null)
                    {
                        HandlePickPocket(player, monster, oned);
                    }
                    if (attack.Skill == 21100005)
                    {
                        // 生命吸收21100005
                        var drain  = SkillFactory.GetSkill(21100005);
                        var gainhp =
                            (int)
                            (totDamageToOneMonster *
                             (double)drain.GetEffect(player.GetSkillLevel(drain)).X / 100.0);
                        gainhp     = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2));
                        player.Hp += (short)gainhp;
                    }
                    if (attack.Skill == 4101005)
                    {
                        // 生命吸收21100005
                        var drain  = SkillFactory.GetSkill(4101005);
                        var gainhp =
                            (int)
                            (totDamageToOneMonster *
                             (double)drain.GetEffect(player.GetSkillLevel(drain)).X / 100.0);
                        gainhp     = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2));
                        player.Hp += (short)gainhp;
                    }
                    if (attack.Skill == 14101006)
                    {
                        // 吸血
                        var drain  = SkillFactory.GetSkill(14101006);
                        var gainhp =
                            (int)
                            (totDamageToOneMonster *
                             (double)drain.GetEffect(player.GetSkillLevel(drain)).X / 100.0);
                        gainhp     = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2));
                        player.Hp += (short)gainhp;
                    }
                    if (player.GetBuffedValue(MapleBuffStat.Hamstring) != null)
                    {
                        var hamstring = SkillFactory.GetSkill(3121007); //降低速度的击�?�?
                        if (hamstring.GetEffect(player.GetSkillLevel(hamstring)).MakeChanceResult())
                        {
                            var monsterStatusEffect =
                                new MonsterStatusEffect(
                                    new Dictionary <MonsterStatus, int>
                            {
                                {
                                    MonsterStatus.Speed,
                                    hamstring.GetEffect(player.GetSkillLevel(hamstring)).X
                                }
                            }, hamstring, false);
                            monster.ApplyStatus(player, monsterStatusEffect, false,
                                                hamstring.GetEffect(player.GetSkillLevel(hamstring)).Y *1000);
                        }
                    }

                    if (player.GetBuffedValue(MapleBuffStat.Blind) != null)
                    {
                        //刺眼�?
                        var blind = SkillFactory.GetSkill(3221006);
                        if (blind.GetEffect(player.GetSkillLevel(blind)).MakeChanceResult())
                        {
                            var monsterStatusEffect =
                                new MonsterStatusEffect(
                                    new Dictionary <MonsterStatus, int>
                            {
                                {
                                    MonsterStatus.Acc,
                                    blind.GetEffect(player.GetSkillLevel(blind)).X
                                }
                            }
                                    , blind, false);
                            monster.ApplyStatus(player, monsterStatusEffect, false,
                                                blind.GetEffect(player.GetSkillLevel(blind)).Y *1000);
                        }
                    }

                    if (player.Job == MapleJob.Whiteknight)
                    {
                        int[] charges = { 1211005, 1211006 }; //寒冰钝器
                        foreach (var charge in charges)
                        {
                            var chargeSkill = SkillFactory.GetSkill(charge);

                            if (player.IsBuffFrom(MapleBuffStat.WkCharge, chargeSkill))
                            {
                                var iceEffectiveness = monster.GetEffectiveness(Element.Ice);
                                if (totDamageToOneMonster > 0 && iceEffectiveness == ElementalEffectiveness.Normal ||
                                    iceEffectiveness == ElementalEffectiveness.Weak)
                                {
                                    var chargeEffect =
                                        chargeSkill.GetEffect(player.GetSkillLevel(chargeSkill));
                                    var monsterStatusEffect =
                                        new MonsterStatusEffect(
                                            new Dictionary <MonsterStatus, int> {
                                        { MonsterStatus.Freeze, 1 }
                                    },
                                            chargeSkill, false);
                                    monster.ApplyStatus(player, monsterStatusEffect, false, chargeEffect.Y * 2000);
                                }
                                break;
                            }
                        }
                    }
                    var venomNl = SkillFactory.GetSkill(4120005); //武器用毒�?
                    if (player.GetSkillLevel(venomNl) <= 0)
                    {
                        venomNl = SkillFactory.GetSkill(14110004); //武器用毒�?
                    }
                    var venomShadower = SkillFactory.GetSkill(4220005);
                    if (player.GetSkillLevel(venomNl) > 0)
                    {
                        var venomEffect = venomNl.GetEffect(player.GetSkillLevel(venomNl));
                        for (var i = 0; i < attackCount; i++)
                        {
                            if (venomEffect.MakeChanceResult())
                            {
                                if (monster.VenomMultiplier < 3)
                                {
                                    monster.VenomMultiplier += 1;
                                    var monsterStatusEffect =
                                        new MonsterStatusEffect(
                                            new Dictionary <MonsterStatus, int> {
                                        { MonsterStatus.Poison, 1 }
                                    },
                                            venomNl, false);
                                    monster.ApplyStatus(player, monsterStatusEffect, false, venomEffect.Duration,
                                                        true);
                                }
                            }
                        }
                    }
                    else if (player.GetSkillLevel(venomShadower) > 0)
                    {
                        var venomEffect = venomShadower.GetEffect(player.GetSkillLevel(venomShadower));
                        for (var i = 0; i < attackCount; i++)
                        {
                            if (venomEffect.MakeChanceResult())
                            {
                                if (monster.VenomMultiplier < 3)
                                {
                                    monster.VenomMultiplier += 1;
                                    var monsterStatusEffect =
                                        new MonsterStatusEffect(
                                            new Dictionary <MonsterStatus, int> {
                                        { MonsterStatus.Poison, 1 }
                                    },
                                            venomShadower, false);
                                    monster.ApplyStatus(player, monsterStatusEffect, false, venomEffect.Duration,
                                                        true);
                                }
                            }
                        }
                    }
                    if (totDamageToOneMonster > 0 && attackEffect != null && attackEffect.MonsterStatus.Any())
                    {
                        if (attackEffect.MakeChanceResult())
                        {
                            var monsterStatusEffect =
                                new MonsterStatusEffect(attackEffect.MonsterStatus, theSkill, false);
                            monster.ApplyStatus(player, monsterStatusEffect, attackEffect.IsPoison(),
                                                attackEffect.Duration);
                        }
                    }
                    if (attack.IsHh && !monster.IsBoss)
                    {
                        map.DamageMonster(player, monster, monster.Hp - 1);
                    }
                    else if (attack.IsHh && monster.IsBoss)
                    {
                        var weaponItem = player.Inventorys[MapleInventoryType.Equipped.Value].Inventory[0xF5]; //装备
                        MapleItemInformationProvider.Instance.GetWeaponType(weaponItem.ItemId);
                    }
                    else
                    {
                        map.DamageMonster(player, monster, totDamageToOneMonster);
                    }
                }
            }
            if (totDamage > 1)
            {
                player.AntiCheatTracker.SetAttacksWithoutHit(player.AntiCheatTracker.GetAttacksWithoutHit() + 1);
                int offenseLimit;
                if (attack.Skill != 3121004)
                {
                    //暴风箭雨
                    offenseLimit = 100;
                }
                else
                {
                    offenseLimit = 300;
                }
                if (player.AntiCheatTracker.GetAttacksWithoutHit() > offenseLimit)
                {
                    player.AntiCheatTracker
                    .RegisterOffense(CheatingOffense.AttackWithoutGettingHit,
                                     player.AntiCheatTracker.GetAttacksWithoutHit().ToString());
                }
                //没有受到撞击攻击
                //if (player.hasEnergyCharge())
                //{
                //    player.increaseEnergyCharge(attack.numAttacked);
                //}
            }
        }