예제 #1
0
        public override SkillResults UseCombat(MabiCreature attacker, ulong targetId, MabiSkill skill)
        {
            var target = WorldManager.Instance.GetCreatureById(targetId);
            if (target == null)
                return SkillResults.InvalidTarget;

            if (attacker.Magazine == null || attacker.Magazine.Count < 1)
                return SkillResults.Failure;

            var rnd = RandomProvider.Get();

            attacker.StopMove();

            var factory = new CombatFactory();
            factory.SetAttackerAction(attacker, CombatActionType.RangeHit, skill.Id, targetId);
            factory.SetAttackerOptions(AttackerOptions.Result);
            factory.SetAttackerStun(AfterUseStun);

            bool hit = false;

            if (attacker.GetAimPercent(1) > rnd.NextDouble())
            {
                target.StopMove();

                factory.AddTargetAction(target, CombatActionType.TakeHit);
                factory.SetTargetOptions(TargetOptions.Result);
                factory.SetTargetStun(StunTime);

                hit = true;
            }
            else
            {
                factory.AddTargetAction(target, CombatActionType.None);
            }

            Send.SkillUse(attacker.Client, attacker, skill.Id, AfterUseStun, 1);

            SkillHelper.ClearStack(attacker, skill);

            attacker.Client.Send(new MabiPacket(Op.CombatTargetSet, attacker.Id).PutLong(0));

            factory.ExecuteDamage(new System.Func<MabiCreature, MabiCreature, float>((a, t) =>
                {
                    var damage = attacker.GetRndRangeDamage();
                    damage *= skill.RankInfo.Var1 / 100f;
                    return damage;
                }));
            factory.ExecuteStun();
            factory.ExecuteKnockback(CombatHelper.MaxKnockBack);

            WorldManager.Instance.HandleCombatActionPack(factory.GetCap());

            if (hit)
                CombatHelper.SetAggro(attacker, target);

            SkillHelper.GiveSkillExp(attacker, skill, 20);

            return SkillResults.Okay;
        }
예제 #2
0
        public override SkillResults Prepare(MabiCreature creature, MabiSkill skill, MabiPacket packet, uint castTime)
        {
            creature.StopMove();

            WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, creature.Id).PutInt(Effect.SkillInit).PutString("thunder").PutShort((ushort)skill.Id), SendTargets.Range, creature);

            Send.SkillPrepare(creature.Client, creature, skill.Id, castTime);

            return SkillResults.Okay;
        }
예제 #3
0
        public override SkillResults Prepare(MabiCreature creature, MabiSkill skill, MabiPacket packet, uint castTime)
        {
            Send.SkillInitEffect(creature);

            creature.StopMove();

            Send.SkillPrepare(creature.Client, creature, skill.Id, castTime);

            return SkillResults.Okay;
        }
예제 #4
0
        public override SkillResults Prepare(MabiCreature creature, MabiSkill skill, MabiPacket packet, uint castTime)
        {
            creature.StopMove();

            // Casting motion?
            WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, creature.Id).PutInt(Effect.Casting).PutShort(skill.Info.Id).PutBytes(0, 1).PutShort(0), SendTargets.Range, creature);

            Send.SkillPrepare(creature.Client, creature, skill.Id, castTime);

            return SkillResults.Okay;
        }
예제 #5
0
        public override SkillResults Start(MabiCreature creature, MabiSkill skill)
        {
            creature.Activate(CreatureConditionB.Demigod);

            creature.StopMove();

            // Spawn eruption
            {
                var pos = creature.GetPosition();
                var targets = WorldManager.Instance.GetAttackableCreaturesInRange(creature, EruptionRadius);

                var cap = new CombatActionPack(creature, skill.Id);
                var aAction = new AttackerAction(CombatActionType.SpecialHit, creature, skill.Id, SkillHelper.GetAreaTargetID(creature.Region, pos.X, pos.Y));
                aAction.Options |= AttackerOptions.KnockBackHit1 | AttackerOptions.UseEffect;

                cap.Add(aAction);

                foreach (var target in targets)
                {
                    target.StopMove();

                    // Officials use CM skill id.
                    var tAction = new TargetAction(CombatActionType.TakeHit, target, creature, skill.Id);
                    tAction.StunTime = EruptionStun;
                    tAction.Delay = 1000;

                    // Supposedly it's magic damage
                    tAction.Damage = creature.GetMagicDamage(null, EruptionDamage);

                    target.TakeDamage(tAction.Damage);
                    tAction.OldPosition = CombatHelper.KnockBack(target, creature, EruptionKnockBack);
                    if (target.IsDead)
                        tAction.Options |= TargetOptions.FinishingKnockDown;

                    cap.Add(tAction);
                }

                WorldManager.Instance.HandleCombatActionPack(cap);
            }

            Send.EffectDelayed(Effect.AwakeningOfLight1, 800, creature);
            Send.EffectDelayed(Effect.AwakeningOfLight2, 800, creature);
            Send.UseMotion(creature, 67, 3, false, false);

            creature.StatRegens.Add(creature.Temp.DemiHpRegen = new MabiStatRegen(Stat.Life, skill.RankInfo.Var3, creature.LifeMax));
            creature.StatRegens.Add(creature.Temp.DemiMpRegen = new MabiStatRegen(Stat.Mana, skill.RankInfo.Var4, creature.ManaMax));
            creature.StatRegens.Add(creature.Temp.DemiStmRegen = new MabiStatRegen(Stat.Stamina, skill.RankInfo.Var5, creature.StaminaMax));
            WorldManager.Instance.CreatureStatsUpdate(creature);

            return SkillResults.Okay;
        }
예제 #6
0
        public override SkillResults UseCombat(MabiCreature attacker, ulong targetId, MabiSkill skill)
        {
            // if rank > x then
            //     for splash targets

            var target = WorldManager.Instance.GetCreatureById(targetId);
            if (target == null)
                return SkillResults.InvalidTarget;

            if (!WorldManager.InRange(attacker, target, (uint)(attacker.RaceInfo.AttackRange + 50)))
                return SkillResults.OutOfRange;

            attacker.StopMove();
            target.StopMove();

            var factory = new CombatFactory();

            factory.SetAttackerAction(attacker, CombatActionType.HardHit, skill.Id, targetId);
            factory.SetAttackerOptions(AttackerOptions.Result | AttackerOptions.KnockBackHit2);
            factory.SetAttackerStun(AfterUseStun);

            factory.AddTargetAction(target, CombatActionType.TakeHit, skillId: SkillConst.MeleeCombatMastery);
            factory.SetTargetOptions(TargetOptions.Result | TargetOptions.Smash);
            factory.SetTargetStun(StunTime);

            var critChance = attacker.CriticalChanceAgainst(target);
            var critOpts = CombatFactory.CriticalOptions.NoCritical;

            // +5% crit for 2H
            if (attacker.RightHand != null && attacker.RightHand.IsTwoHandWeapon)
                critChance *= 1.05f;

            // Crit
            if (CombatHelper.TryCritical(critChance))
                critOpts = CombatFactory.CriticalOptions.Critical;

            factory.ExecuteDamage(calculateSmashDamage, critOpts);
            factory.ExecuteStun();
            factory.ExecuteKnockback(CombatHelper.MaxKnockBack);

            WorldManager.Instance.HandleCombatActionPack(factory.GetCap());

            Send.SkillUse(attacker.Client, attacker, skill.Id, AfterUseStun, 1);

            CombatHelper.SetAggro(attacker, target);

            SkillHelper.GiveSkillExp(attacker, skill, 20);

            return SkillResults.Okay;
        }
예제 #7
0
        public override SkillResults Prepare(MabiCreature creature, MabiSkill skill, MabiPacket packet, uint castTime)
        {
            // Is this check done client sided in every client by now?
            if (WorldConf.BunshinSouls && creature is MabiPC && creature.SoulCount < skill.RankInfo.Var1)
            {
                Send.Notice(creature.Client, "You need {0} more souls\nto be able to use Shadow Bunshin.", (skill.RankInfo.Var1 - creature.SoulCount));
                return SkillResults.Failure;
            }

            creature.StopMove();

            WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, creature.Id).PutInt(Effect.ShadowBunshin).PutByte(1), SendTargets.Range, creature);
            Send.SkillPrepare(creature.Client, creature, skill.Id, castTime);

            return SkillResults.Okay;
        }
예제 #8
0
        public override SkillResults Use(MabiCreature attacker, MabiSkill skill, MabiPacket packet)
        {
            //Logger.Debug(packet);

            var targetId = packet.GetLong();
            var unk1 = packet.GetInt();
            var unk2 = packet.GetInt();

            // Determine range, doesn't seem to be included in rank info.
            var range = this.GetRange(skill);

            // Add attack range from race, range must increase depending on "size".
            range += (uint)attacker.RaceInfo.AttackRange;

            var enemies = WorldManager.Instance.GetAttackableCreaturesInRange(attacker, range);
            if (enemies.Count < 1)
            {
                Send.Notice(attacker.Client, Localization.Get("skills.wm_no_target")); // Unable to use when there is no target.
                Send.SkillSilentCancel(attacker.Client, attacker);

                return SkillResults.OutOfRange | SkillResults.Failure;
            }

            var rnd = RandomProvider.Get();

            attacker.StopMove();

            // Spin motion
            Send.UseMotion(attacker, 8, 4);

            var cap = new CombatActionPack(attacker, skill.Id);

            // One source action, target actions are added for every target
            // and then we send the pack on its way.
            var sAction = new AttackerAction(CombatActionType.Hit, attacker, skill.Id, targetId);
            sAction.Options |= AttackerOptions.Result | AttackerOptions.KnockBackHit1;

            cap.Add(sAction);

            attacker.Stun = sAction.StunTime = 2500;

            // For aggro selection, only one enemy gets it.
            MabiCreature aggroTarget = null;
            var survived = new List<MabiCreature>();

            foreach (var target in enemies)
            {
                target.StopMove();

                var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Id);
                cap.Add(tAction);

                var damage = attacker.GetRndTotalDamage();
                damage *= skill.RankInfo.Var1 / 100;

                if (CombatHelper.TryAddCritical(attacker, ref damage, attacker.CriticalChance))
                    tAction.Options |= TargetOptions.Critical;

                target.TakeDamage(tAction.Damage = damage);
                if (target.IsDead)
                    tAction.Options |= TargetOptions.FinishingKnockDown;

                tAction.Options |= TargetOptions.KnockDown;
                target.Stun = tAction.StunTime = CombatHelper.GetStunTarget(CombatHelper.GetAverageAttackSpeed(attacker), true);

                tAction.OldPosition = CombatHelper.KnockBack(target, attacker, 375);

                tAction.Delay = (uint)rnd.Next(300, 351);

                if (target.Target == attacker)
                    aggroTarget = target;

                if (!target.IsDead)
                    survived.Add(target);
            }

            // No aggro yet, random target.
            if (aggroTarget == null && survived.Count > 0)
                aggroTarget = survived[rnd.Next(0, survived.Count)];

            if (aggroTarget != null)
                CombatHelper.SetAggro(attacker, aggroTarget);

            WorldManager.Instance.HandleCombatActionPack(cap);

            Send.SkillUse(attacker.Client, attacker, skill.Id, targetId, unk1, unk2);
            //attacker.Client.SendSkillStackUpdate(attacker, skill.Id, 0);

            SkillHelper.DecStack(attacker, skill);
            SkillHelper.GiveSkillExp(attacker, skill, 20);

            return SkillResults.Okay;
        }
예제 #9
0
        public override SkillResults UseCombat(MabiCreature attacker, ulong targetId, MabiSkill skill)
        {
            var target = WorldManager.Instance.GetCreatureById(targetId);
            if (target == null)
                return SkillResults.InvalidTarget;

            if (attacker.Inventory.Magazine == null || attacker.Inventory.Magazine.Count < 1)
                return SkillResults.Failure;

            var rnd = RandomProvider.Get();

            attacker.StopMove();

            var factory = new CombatFactory();
            factory.SetAttackerAction(attacker, CombatActionType.RangeHit, skill.Id, targetId);
            factory.SetAttackerOptions(AttackerOptions.Result);
            factory.SetAttackerStun(AfterUseStun);

            bool hit = false;

            if (attacker.GetAimPercent(attacker.Skills.Get(SkillConst.RangedCombatMastery).RankInfo.Var3, attacker.ActiveSkillStacks == 5 ? skill.RankInfo.Var3 : 0) > rnd.NextDouble())
            {
                target.StopMove();

                factory.AddTargetAction(target, CombatActionType.TakeHit);
                factory.SetTargetOptions(TargetOptions.Result);
                factory.SetTargetStun(StunTime);

                hit = true;
            }
            else
            {
                factory.AddTargetAction(target, CombatActionType.None);
            }

            Send.SkillUse(attacker.Client, attacker, skill.Id, AfterUseStun, 1);

            SkillHelper.DecStack(attacker, skill);

            attacker.Client.Send(new MabiPacket(Op.CombatTargetSet, attacker.Id).PutLong(0));

            factory.ExecuteDamage(new System.Func<MabiCreature, MabiCreature, float>((a, t) =>
                {
                    var dmg = attacker.GetRndRangeDamage();

                    switch (5 - a.ActiveSkillStacks)
                    {
                        case 1:
                            dmg *= (95 + skill.RankInfo.Var1) / 100f;
                            break;
                        case 2:
                            dmg *= (105 + skill.RankInfo.Var1) / 100f;
                            break;
                        case 3:
                            dmg *= (110 + skill.RankInfo.Var1) / 100f;
                            break;
                        case 4:
                            dmg *= (130 + skill.RankInfo.Var1) / 100f;
                            break;
                        default:
                            dmg *= (160 + skill.RankInfo.Var2) / 100f;
                            break;
                    }

                    return dmg;
                }));
            factory.ExecuteStun();
            factory.ExecuteKnockback(40f);

            WorldManager.Instance.HandleCombatActionPack(factory.GetCap());

            if (hit)
                CombatHelper.SetAggro(attacker, target);

            SkillHelper.GiveSkillExp(attacker, skill, 20);

            return SkillResults.Okay;
        }
예제 #10
0
        public override SkillResults UseCombat(MabiCreature attacker, ulong targetId, MabiSkill skill)
        {
            var target = WorldManager.Instance.GetCreatureById(targetId);
            if (target == null)
                return SkillResults.InvalidTarget;

            if (!WorldManager.InRange(attacker, target, 1200))
                return SkillResults.OutOfRange;

            attacker.StopMove();

            WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.UseMagic).PutString(this.Name), SendTargets.Range, attacker);

            Send.SkillUse(attacker.Client, attacker, skill.Id, UseStun, 1);

            var sAction = new AttackerAction(CombatActionType.RangeHit, attacker, skill.Id, targetId);
            sAction.Options |= AttackerOptions.Result;

            var cap = new CombatActionPack(attacker, skill.Id);
            cap.Add(sAction);

            var rnd = RandomProvider.Get();

            var damage = attacker.GetMagicDamage(attacker.RightHand, rnd.Next((int)skill.RankInfo.Var1, (int)skill.RankInfo.Var2 + 1));

            attacker.Stun = sAction.StunTime = UseStun;

            var targets = WorldManager.Instance.GetCreaturesInRange(target, 500).Where(c => !c.IsDead && c.IsAttackableBy(attacker)).ToList();
            targets.Insert(0, target);
            for (byte i = 0; i < attacker.ActiveSkillStacks && i < targets.Count; i++)
            {
                targets[i].StopMove();

                var splashAction = new TargetAction(CombatActionType.TakeHit, targets[i], attacker, skill.Id);
                splashAction.Options |= TargetOptions.Result;

                cap.Add(splashAction);

                splashAction.Damage = damage * ((100 - (i * 10)) / 100f);

                if (CombatHelper.TryAddCritical(targets[i], ref damage, attacker.CriticalChanceAgainst(targets[i])))
                    splashAction.Options |= TargetOptions.Critical;

                targets[i].TakeDamage(splashAction.Damage);

                targets[i].Stun = splashAction.StunTime = TargetStun;

                // Knock down if dead
                if (targets[i].IsDead)
                {
                    splashAction.OldPosition = CombatHelper.KnockBack(targets[i], (i == 0 ? attacker : targets[i - 1]));
                    splashAction.Options |= TargetOptions.FinishingKnockDown;
                }
                else
                {
                    if (targets[i].KnockBack >= CombatHelper.LimitKnockBack)
                    {
                        splashAction.Options |= TargetOptions.KnockDown;
                    }
                    else
                    {
                        targets[i].KnockBack += KnockBack;
                        if (targets[i].KnockBack >= CombatHelper.LimitKnockBack)
                        {
                            splashAction.OldPosition = CombatHelper.KnockBack(targets[i], (i == 0 ? attacker : targets[i - 1]));
                            splashAction.Options |= TargetOptions.KnockBack;
                        }
                    }

                    targets[i].Stun = splashAction.StunTime = TargetStun;

                    CombatHelper.SetAggro(attacker, targets[i]);
                }
            }

            SkillHelper.ClearStack(attacker, skill);

            WorldManager.Instance.HandleCombatActionPack(cap);

            SkillHelper.GiveSkillExp(attacker, skill, 20);

            return SkillResults.Okay;
        }
예제 #11
0
        public override SkillResults UseCombat(MabiCreature attacker, ulong targetId, MabiSkill skill)
        {
            var target = WorldManager.Instance.GetCreatureById(targetId);
            if (target == null)
                return SkillResults.InvalidTarget;

            if (!WorldManager.InRange(attacker, target, 1200))
                return SkillResults.OutOfRange;

            attacker.StopMove();
            target.StopMove();

            WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.UseMagic).PutString(this.Name), SendTargets.Range, attacker);

            Send.SkillUse(attacker.Client, attacker, skill.Id, UseStun, 1);

            SkillHelper.DecStack(attacker, skill);

            var sAction = new AttackerAction(CombatActionType.RangeHit, attacker, skill.Id, targetId);
            sAction.Options |= AttackerOptions.Result;

            var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Id);
            tAction.Options |= TargetOptions.Result;

            var cap = new CombatActionPack(attacker, skill.Id);
            cap.Add(sAction, tAction);

            var rnd = RandomProvider.Get();

            var damage = attacker.GetMagicDamage(attacker.RightHand, rnd.Next((int)skill.RankInfo.Var1, (int)skill.RankInfo.Var2 + 1));

            if (CombatHelper.TryAddCritical(target, ref damage, attacker.CriticalChanceAgainst(target)))
                tAction.Options |= TargetOptions.Critical;

            target.TakeDamage(tAction.Damage = damage);

            attacker.Stun = sAction.StunTime = UseStun;

            // Knock down if dead
            if (target.IsDead)
            {
                tAction.OldPosition = CombatHelper.KnockBack(target, attacker);
                tAction.Options |= TargetOptions.FinishingKnockDown;
            }
            else
            {
                if (target.KnockBack >= CombatHelper.LimitKnockBack)
                {
                    tAction.Options |= TargetOptions.KnockDown;
                }
                else
                {
                    target.KnockBack += KnockBack;
                    if (target.KnockBack >= CombatHelper.LimitKnockBack)
                    {
                        tAction.OldPosition = CombatHelper.KnockBack(target, attacker);
                        tAction.Options |= TargetOptions.KnockBack;
                    }
                }

                target.Stun = tAction.StunTime = TargetStun;

                CombatHelper.SetAggro(attacker, target);
            }

            WorldManager.Instance.HandleCombatActionPack(cap);

            SkillHelper.GiveSkillExp(attacker, skill, 20);

            return SkillResults.Okay;
        }
예제 #12
0
        public override SkillResults UseCombat(MabiCreature attacker, ulong targetId, MabiSkill skill)
        {
            var target = WorldManager.Instance.GetCreatureById(targetId);
            if (target == null)
                return SkillResults.InvalidTarget;

            if (attacker.Magazine == null || attacker.Magazine.Count < 1)
                return SkillResults.Failure;

            var rnd = RandomProvider.Get();

            attacker.StopMove();

            var factory = new CombatFactory();
            factory.SetAttackerAction(attacker, CombatActionType.RangeHit, skill.Id, targetId);
            factory.SetAttackerOptions(AttackerOptions.Result);
            factory.SetAttackerStun(AfterUseStun);

            bool hit = false;

            if (attacker.GetAimPercent(attacker.Skills.Get(SkillConst.RangedCombatMastery).RankInfo.Var3) > rnd.NextDouble())
            {
                target.StopMove();

                factory.AddTargetAction(target, CombatActionType.TakeHit);
                factory.SetTargetOptions(TargetOptions.Result);
                factory.SetTargetStun(StunTime);

                hit = true;
            }
            else
            {
                factory.AddTargetAction(target, CombatActionType.None);
            }

            Send.SkillUse(attacker.Client, attacker, skill.Id, AfterUseStun, 1);

            SkillHelper.ClearStack(attacker, skill);

            attacker.Client.Send(new MabiPacket(Op.CombatTargetSet, attacker.Id).PutLong(0));

            factory.ExecuteDamage(new System.Func<MabiCreature, MabiCreature, float>((a, t) =>
                {
                    var damage = attacker.GetRndRangeDamage();
                    return damage * .8f;
                }));
            factory.ExecuteStun();
            factory.ExecuteKnockback(0f);

            WorldManager.Instance.HandleCombatActionPack(factory.GetCap());

            if (!target.IsDead && hit)
            {
                // TODO: debuff

                WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, target.Id).PutInt(Effect.SupportShot).PutByte(1), SendTargets.Range, target);

                System.Threading.Thread t = new System.Threading.Thread(() =>
                {
                    System.Threading.Thread.Sleep(3000);
                    WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, target.Id).PutInt(Effect.SupportShot).PutByte(0), SendTargets.Range, target);
                });

                t.Start();

                CombatHelper.SetAggro(attacker, target);
            }

            SkillHelper.GiveSkillExp(attacker, skill, 20);

            return SkillResults.Okay;
        }
예제 #13
0
        public override SkillResults UseCombat(MabiCreature attacker, ulong targetId, MabiSkill skill)
        {
            var itarget = WorldManager.Instance.GetCreatureById(targetId);
            if (itarget == null)
                return SkillResults.InvalidTarget;

            if (!WorldManager.InRange(attacker, itarget, 2000))
                return SkillResults.OutOfRange;

            attacker.StopMove();

            WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.UseMagic).PutString("thunder").PutByte(0).PutLong(targetId).PutShort((ushort)skill.Id), SendTargets.Range, attacker);

            var charges = attacker.ActiveSkillStacks;

            List<MabiCreature> targets = new List<MabiCreature>() { itarget };
            this.GetThunderChain(attacker, itarget, targets, ((byte)skill.Rank >= (byte)SkillRank.R1 ? 4 : 1) + (charges - 1) * 2);

            var pos = itarget.GetPosition();
            var cloud = new MabiProp(280, itarget.Region, pos.X, pos.Y, 0);
            WorldManager.Instance.AddProp(cloud);

            var lbPacket = new MabiPacket(Op.Effect, Id.Broadcast).PutInt(Effect.Lightningbolt).PutLong(attacker.Id).PutInt((uint)targets.Count);

            foreach (var target in targets)
            {
                lbPacket.PutLong(target.Id);
            }

            WorldManager.Instance.Broadcast(lbPacket, SendTargets.Range, attacker);

            Send.SkillUse(attacker.Client, attacker, skill.Id, UseStun, 1);

            SkillHelper.ClearStack(attacker, skill);

            // End the lightning balls
            WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.StackUpdate).PutString("lightningbolt").PutBytes(0, 0), SendTargets.Range, attacker);

            var sAction = new AttackerAction(CombatActionType.RangeHit, attacker, skill.Id, targetId);
            sAction.Options |= AttackerOptions.Result;

            attacker.Stun = sAction.StunTime = UseStun;

            var cap = new CombatActionPack(attacker, skill.Id);
            cap.Add(sAction);

            var rnd = RandomProvider.Get();

            foreach (var target in targets)
            {
                var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Id);
                tAction.Options |= TargetOptions.Result;

                cap.Add(tAction);

                var damage = attacker.GetMagicDamage(attacker.RightHand, rnd.Next((int)skill.RankInfo.Var4, (int)skill.RankInfo.Var5 + 1));

                if (CombatHelper.TryAddCritical(target, ref damage, attacker.CriticalChanceAgainst(target)))
                    tAction.Options |= TargetOptions.Critical;

                target.TakeDamage(tAction.Damage = damage);

                // Knock down if dead
                if (target.IsDead)
                {
                    tAction.OldPosition = CombatHelper.KnockBack(target, attacker);
                    tAction.Options |= TargetOptions.FinishingKnockDown;
                }
                else
                {
                    if (target.KnockBack >= CombatHelper.LimitKnockBack)
                    {
                        tAction.Options |= TargetOptions.KnockDown;
                    }
                    else
                    {
                        target.KnockBack += KnockBack;
                        if (target.KnockBack >= CombatHelper.LimitKnockBack)
                        {
                            tAction.OldPosition = CombatHelper.KnockBack(target, attacker);
                            tAction.Options |= TargetOptions.KnockBack;
                        }
                    }

                    target.Stun = tAction.StunTime = (ushort)skill.RankInfo.Var3;

                    CombatHelper.SetAggro(attacker, target);
                }
            }

            WorldManager.Instance.HandleCombatActionPack(cap);

            SkillHelper.GiveSkillExp(attacker, skill, 20);

            System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() =>
                {
                    this.ThunderProcessing(attacker, skill, targets, cloud, DateTime.Now.AddMilliseconds(skill.RankInfo.Var3), charges);
                }));
            t.Start();

            return SkillResults.Okay;
        }
예제 #14
0
        public override SkillResults UseCombat(MabiCreature attacker, ulong targetId, MabiSkill skill)
        {
            var target = WorldManager.Instance.GetCreatureById(targetId);
            if (target == null)
                return SkillResults.InvalidTarget;

            if (!WorldManager.InRange(attacker, target, (uint)(attacker.RaceInfo.AttackRange + 50)))
                return SkillResults.OutOfRange;

            if (attacker.IsStunned)
                return SkillResults.AttackStunned;

            attacker.StopMove();
            target.StopMove();

            // Check counter
            var counter = CombatHelper.TryCounter(target, attacker);
            if (counter != SkillResults.None)
                return SkillResults.Okay;

            uint prevCombatActionId = 0;
            var rnd = RandomProvider.Get();

            var rightHand = attacker.RightHand;
            var leftHand = attacker.LeftHand;
            if (leftHand != null && !leftHand.IsOneHandWeapon)
                leftHand = null;

            var sAction = new AttackerAction(CombatActionType.Hit, attacker, skill.Id, targetId);
            sAction.Options |= AttackerOptions.Result;
            if (rightHand != null && leftHand != null)
                sAction.Options |= AttackerOptions.DualWield;

            // Do this for two weapons, break if there is no second hit.
            for (byte i = 1; i <= 2; ++i)
            {
                var weapon = (i == 1 ? rightHand : leftHand);
                var atkSpeed = CombatHelper.GetAverageAttackSpeed(attacker);

                var cap = new CombatActionPack(attacker, skill.Id);
                cap.PrevCombatActionId = prevCombatActionId;
                cap.Hit = i;
                cap.HitsMax = (byte)(sAction.Has(AttackerOptions.DualWield) ? 2 : 1);

                var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Id);

                cap.Add(sAction, tAction);

                // Damage
                {
                    var damage = attacker.GetRndDamage(weapon);
                    var protection = target.Protection;

                    // Crit
                    if (CombatHelper.TryAddCritical(attacker, ref damage, attacker.CriticalChanceAgainst(target)))
                        tAction.Options |= TargetOptions.Critical;

                    // Def/Prot
                    CombatHelper.ReduceDamage(ref damage, target.DefenseTotal, protection);

                    // Mana Shield
                    tAction.ManaDamage = CombatHelper.DealManaDamage(target, ref damage);

                    // Deal Life Damage
                    if (damage > 0)
                        target.TakeDamage(tAction.Damage = damage);
                }

                // Killed?
                if (target.IsDead)
                {
                    tAction.Options |= TargetOptions.FinishingKnockDown;
                    attacker.Stun = sAction.StunTime = CombatHelper.GetStunSource(atkSpeed, tAction.IsKnock);
                }
                else
                {
                    // Defense
                    if (target.HasSkillLoaded(SkillConst.Defense))
                    {
                        tAction.Type = CombatActionType.Defended;
                        tAction.SkillId = SkillConst.Defense;
                        target.Stun = tAction.StunTime = 1000;
                        attacker.Stun = sAction.StunTime = 2500;
                    }
                    // Normal hit
                    else
                    {
                        // Knock back
                        if (target.RaceInfo.Is(RaceStands.KnockBackable))
                        {
                            target.KnockBack += CombatHelper.GetKnockDown(weapon) / cap.HitsMax;
                            if (target.KnockBack >= CombatHelper.LimitKnockBack)
                            {
                                // Knock down if critical
                                tAction.Options |= (tAction.Has(TargetOptions.Critical) ? TargetOptions.KnockDown : TargetOptions.KnockBack);
                            }
                        }

                        attacker.Stun = sAction.StunTime = CombatHelper.GetStunSource(atkSpeed, tAction.IsKnock);
                        target.Stun = tAction.StunTime = CombatHelper.GetStunTarget(atkSpeed, tAction.IsKnock);
                    }
                }

                // Stop on knock back
                if (tAction.IsKnock && target.RaceInfo.Is(RaceStands.KnockBackable))
                {
                    tAction.OldPosition = CombatHelper.KnockBack(target, attacker);
                    sAction.Options |= AttackerOptions.KnockBackHit2;
                    cap.HitsMax = cap.Hit;
                }

                // Weapon Exp
                if (weapon != null)
                    SkillHelper.GiveItemExp(attacker, weapon);

                // Aggro
                CombatHelper.SetAggro(attacker, target);

                // Submit
                WorldManager.Instance.HandleCombatActionPack(cap);

                // Stop when all hits are done
                if (cap.Hit >= cap.HitsMax)
                    break;

                prevCombatActionId = cap.CombatActionId;
            }

            SkillHelper.GiveSkillExp(attacker, skill, 20);

            return SkillResults.Okay;
        }
예제 #15
0
        public override SkillResults UseCombat(MabiCreature attacker, ulong targetId, MabiSkill skill)
        {
            var target = WorldManager.Instance.GetCreatureById(targetId);
            if (target == null)
                return SkillResults.InvalidTarget;

            if (!WorldManager.InRange(attacker, target, 2000))
                return SkillResults.OutOfRange;

            if (attacker.ActiveSkillStacks != 5)
                return SkillResults.Failure;

            attacker.StopMove();

            WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.UseMagic).PutString("fireball").PutByte(1).PutLong(targetId).PutShort((ushort)skill.Id), SendTargets.Range, attacker);

            WorldManager.Instance.Broadcast(PacketCreator.TurnTo(attacker, target).PutByte(1), SendTargets.Range, attacker);

            var pos = target.GetPosition();
            var bomb = new MabiProp(280, target.Region, pos.X, pos.Y, 1f);
            WorldManager.Instance.AddProp(bomb);

            var frompos = attacker.GetPosition();

            WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, bomb.Id).PutInts(Effect.FireballFly, bomb.Region).PutFloats(frompos.X, frompos.Y, pos.X, pos.Y).PutInt(4000).PutByte(0).PutInt((uint)skill.Id), SendTargets.Range, attacker);

            Send.SkillUse(attacker.Client, attacker, skill.Id, UseStun, 1);

            SkillHelper.ClearStack(attacker, skill);

            // End the fire bolts
            WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.StackUpdate).PutString("firebolt").PutBytes(0, 0), SendTargets.Range, attacker);

            SkillHelper.GiveSkillExp(attacker, skill, 20);

            var t = new Thread(new System.Threading.ThreadStart(() =>
            {
                this.FireballProcessing(attacker, skill, bomb, targetId);
            }));
            t.Start();

            return SkillResults.Okay;
        }