public void AddTargetAction(MabiCreature target, CombatActionType targetType, MabiCreature attacker = null, SkillConst skillId = SkillConst.None) { var tAction = new TargetAction(targetType, target, attacker == null ? this.AttackerAction.Creature : attacker, skillId == SkillConst.None ? this.AttackerAction.SkillId : skillId); this.TargetActions.Add(tAction); this.CurrentTargetAction = tAction; }
public void FireballProcessing(MabiCreature attacker, MabiSkill skill, MabiProp bomb, ulong targetId) { Thread.Sleep(4000); var victims = WorldManager.Instance.GetCreaturesInRange(bomb, 800).Where(c => !c.IsDead && c.IsAttackableBy(attacker)).ToList(); ulong areaTarget = SkillHelper.GetAreaTargetID(bomb.Region, (uint)bomb.Info.X, (uint)bomb.Info.Y); var sAction = new AttackerAction(CombatActionType.SpecialHit, attacker, skill.Id, areaTarget); sAction.PropId = bomb.Id; sAction.Options = AttackerOptions.KnockBackHit1 | AttackerOptions.UseEffect; var cap = new CombatActionPack(attacker, skill.Id); cap.Add(sAction); var rnd = RandomProvider.Get(); foreach (var target in victims) { target.StopMove(); var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Id); tAction.Options |= TargetOptions.Result; tAction.StunTime = target.Stun = 3000; tAction.Delay = 200; 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); // Knock down if dead tAction.OldPosition = CombatHelper.KnockBack(target, bomb); if (target.IsDead) { tAction.Options |= TargetOptions.FinishingKnockDown; } else { tAction.Options |= TargetOptions.KnockDown; CombatHelper.SetAggro(attacker, target); } WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, target.Id).PutInt(Effect.Thunderbolt).PutByte(0), SendTargets.Range, target); cap.Add(tAction); } WorldManager.Instance.HandleCombatActionPack(cap); WorldManager.Instance.RemoveProp(bomb); }
public override SkillResults UseCombat(MabiCreature attacker, ulong targetId, MabiSkill skill) { var target = WorldManager.Instance.GetCreatureById(targetId); if (target == null) return SkillResults.InvalidTarget; var sAction = new AttackerAction(CombatActionType.HardHit, attacker, skill.Id, targetId); sAction.Options |= AttackerOptions.Result; var tAction = new TargetAction(CombatActionType.CounteredHit, target, attacker, skill.Id); tAction.Options |= TargetOptions.Result | TargetOptions.KnockDown; var cap = new CombatActionPack(attacker, skill.Id); cap.Add(sAction, tAction); var damage = (attacker.GetRndTotalDamage() * (skill.RankInfo.Var2 / 100f)) + (target.GetRndTotalDamage() * (skill.RankInfo.Var1 / 100f)); if (CombatHelper.TryAddCritical(attacker, ref damage, (target.CriticalChanceAgainst(attacker) + skill.RankInfo.Var3))) tAction.Options |= TargetOptions.Critical; CombatHelper.ReduceDamage(ref damage, target.DefenseTotal, target.Protection); target.TakeDamage(tAction.Damage = damage); if (target.IsDead) tAction.Options |= TargetOptions.FinishingKnockDown; attacker.Stun = sAction.StunTime = StunTime; target.Stun = tAction.StunTime = StunTime; tAction.OldPosition = CombatHelper.KnockBack(target, attacker); WorldManager.Instance.HandleCombatActionPack(cap); Send.SkillUse(attacker.Client, attacker, skill.Id, StunTime, 1); SkillHelper.GiveSkillExp(attacker, skill, 20); return SkillResults.Okay; }
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; }
public override SkillResults Use(MabiCreature attacker, MabiSkill skill, MabiPacket packet) { var targetId = packet.GetLong(); var unk1 = packet.GetInt(); var unk2 = packet.GetInt(); var target = WorldManager.Instance.GetCreatureById(targetId); if (target == null) return SkillResults.InvalidTarget; //if (!WorldManager.InRange(creature, target, Range)) // return SkillResults.OutOfRange; // X% of Stamina var staminaCost = attacker.Stamina * (skill.RankInfo.Var2 / 100f); if (attacker is MabiPC) attacker.Stamina -= staminaCost; target.StopMove(); var clones = (uint)skill.RankInfo.Var1; attacker.SoulCount = 0; // Spawn clones var pos = target.GetPosition(); WorldManager.Instance.Broadcast( new MabiPacket(Op.Effect, attacker.Id) .PutInt(Effect.ShadowBunshin) .PutByte(3) .PutString("appear") .PutLong(target.Id) .PutInt(clones) .PutInt(Radius) .PutInt(450) // no changes? .PutFloat(pos.X) .PutFloat(pos.Y) , SendTargets.Range, target); // Change char look direction. WorldManager.Instance.Broadcast(PacketCreator.TurnTo(attacker, target), SendTargets.Range, attacker); // Jump to clone circle var toPos = WorldManager.CalculatePosOnLine(attacker, target, -(int)Radius); attacker.SetPosition(toPos.X, toPos.Y); WorldManager.Instance.Broadcast( new MabiPacket(Op.SetLocation, attacker.Id) .PutByte(0) .PutInt(toPos.X) .PutInt(toPos.Y) , SendTargets.Range, attacker); bool alreadyDead = false; uint i = 0; Timer timer = null; timer = new Timer(_ => { if (timer == null || i > clones) return; // Move WorldManager.Instance.Broadcast( new MabiPacket(Op.Effect, attacker.Id) .PutInt(Effect.ShadowBunshin) .PutByte(3) .PutString("move") .PutLong(target.Id) .PutInt(i) // clone nr .PutInt(i) // clone nr .PutInt(450) .PutInt(clones) // ? (4) .PutInt(120) // disappear time? , SendTargets.Range, attacker); // Attack WorldManager.Instance.Broadcast( new MabiPacket(Op.EffectDelayed, attacker.Id) .PutInt(120) // delay? .PutInt(Effect.ShadowBunshin) .PutByte(3) .PutString("attack") .PutInt(i) // clone nr , SendTargets.Range, attacker); var sAction = new AttackerAction(CombatActionType.SpecialHit, attacker, skill.Id, targetId); sAction.Options |= AttackerOptions.Result; var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Id); tAction.Delay = 100; var cap = new CombatActionPack(attacker, skill.Id); cap.Add(sAction); target.Stun = tAction.StunTime = 2000; CombatHelper.SetAggro(attacker, target); var rnd = RandomProvider.Get(); float damage = rnd.Next((int)skill.RankInfo.Var5, (int)skill.RankInfo.Var6 + 1); damage += skill.RankInfo.Var7 * staminaCost; // Crit if (CombatHelper.TryAddCritical(attacker, ref damage, attacker.CriticalChanceAgainst(target))) tAction.Options |= TargetOptions.Critical; // Def/Prot CombatHelper.ReduceDamage(ref damage, target.DefenseTotal, target.Protection); // Mana Shield tAction.ManaDamage = CombatHelper.DealManaDamage(target, ref damage); // Deal Life Damage if (damage > 0) target.TakeDamage(tAction.Damage = damage); // Save if target was already dead, to not send // finish action twice. if (!alreadyDead) { target.TakeDamage(tAction.Damage); // Only send damage taking part if target isn't dead yet. cap.Add(tAction); } alreadyDead = target.IsDead; if (target.IsDead) { tAction.OldPosition = pos; if (!alreadyDead) tAction.Options |= TargetOptions.FinishingKnockDown; else tAction.Options |= TargetOptions.KnockDown; } else if (i == clones) { // Knock back if not dead after last attack. tAction.Options |= TargetOptions.KnockDown; tAction.OldPosition = CombatHelper.KnockBack(target, attacker, 400); } WorldManager.Instance.HandleCombatActionPack(cap); if (i >= clones) { // Cancel timer after last attack. timer.Dispose(); timer = null; } i++; GC.KeepAlive(timer); }, null, 900, 450); // Something's messed up here, if the skill isn't explicitly // canceled the client gets confused. //WorldManager.Instance.CreatureSkillCancel(attacker); SkillHelper.GiveSkillExp(attacker, skill, 20); Send.SkillUse(attacker.Client, attacker, skill.Id, targetId, unk1, unk2); return SkillResults.Okay; }
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; }
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; }
private static void HitWithThunderbolt(MabiCreature attacker, MabiSkill skill, List<MabiCreature> targets, MabiProp cloud, float dmgModifier = 1) { var undead = targets.FirstOrDefault(c => !c.IsDead); if (undead == null) return; var sAction = new AttackerAction(CombatActionType.RangeHit, attacker, skill.Id, undead.Id); sAction.PropId = cloud.Id; sAction.Options = AttackerOptions.KnockBackHit1 | AttackerOptions.UseEffect; var cap = new CombatActionPack(attacker, skill.Id); cap.Add(sAction); var rnd = RandomProvider.Get(); foreach (var target in targets) { if (target.IsDead) continue; var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Id); tAction.Options |= TargetOptions.Result; var damage = attacker.GetMagicDamage(attacker.RightHand, rnd.Next((int)skill.RankInfo.Var1, (int)skill.RankInfo.Var2 + 1)) * dmgModifier; 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 = 2000; CombatHelper.SetAggro(attacker, target); } WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, target.Id).PutInt(Effect.Thunderbolt).PutByte(0), SendTargets.Range, target); cap.Add(tAction); } WorldManager.Instance.HandleCombatActionPack(cap); }
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; }
protected void Explode(MabiCreature attacker, MabiCreature target, MabiSkill skill, MabiProp casterProp, float dmgModifier = 1f) { WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, target.Id).PutInt(Effect.IcespearFreeze).PutByte(1).PutInt(0), SendTargets.Range, target); // Cancel freeze var tPos = target.GetPosition(); var bombProp = new MabiProp(280, target.Region, tPos.X, tPos.Y, 0); //4 WorldManager.Instance.AddProp(bombProp); WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, bombProp.Id).PutInts(Effect.IcespearBoom, target.Region, tPos.X, tPos.Y), SendTargets.Range, bombProp); WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, target.Id).PutInt(Effect.Thunderbolt).PutByte(0), SendTargets.Range, target); var sAction = new AttackerAction(CombatActionType.SpecialHit, attacker, skill.Id, SkillHelper.GetAreaTargetID(target.Region, tPos.X, tPos.Y)); sAction.PropId = casterProp.Id; sAction.Options = AttackerOptions.KnockBackHit1 | AttackerOptions.UseEffect; var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Id); tAction.Options = TargetOptions.Result; tAction.StunTime = target.Stun = 2000; var rnd = RandomProvider.Get(); var damage = attacker.GetMagicDamage(attacker.RightHand, rnd.Next((int)skill.RankInfo.Var1, (int)skill.RankInfo.Var2 + 1)) * dmgModifier; if (CombatHelper.TryAddCritical(target, ref damage, attacker.CriticalChanceAgainst(target))) tAction.Options |= TargetOptions.Critical; target.TakeDamage(tAction.Damage = damage); // Knock down if dead tAction.OldPosition = CombatHelper.KnockBack(target, bombProp); if (target.IsDead) { tAction.Options |= TargetOptions.FinishingKnockDown; } else { tAction.Options |= TargetOptions.KnockDown; CombatHelper.SetAggro(attacker, target); } var cap = new CombatActionPack(attacker, skill.Id); cap.Add(sAction, tAction); WorldManager.Instance.HandleCombatActionPack(cap); sAction = new AttackerAction(CombatActionType.SpecialHit, attacker, skill.Id, SkillHelper.GetAreaTargetID(target.Region, tPos.X, tPos.Y)); sAction.PropId = bombProp.Id; sAction.Options = AttackerOptions.UseEffect; cap = new CombatActionPack(attacker, skill.Id); cap.Add(sAction); WorldManager.Instance.HandleCombatActionPack(cap); WorldManager.Instance.RemoveProp(bombProp); }
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; var targets = this.GetIceSpearLOSChain(attacker, itarget, (uint)skill.RankInfo.Var5); foreach (var target in targets) { target.StopMove(); WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, target.Id).PutInt(Effect.IcespearFreeze).PutByte(1).PutInt(13000), SendTargets.Range, target); } var aPos = attacker.GetPosition(); var casterProp = new MabiProp(280, attacker.Region, aPos.X, aPos.Y, 0); // 3 WorldManager.Instance.AddProp(casterProp); WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.UseMagic).PutString("icespear").PutByte(1).PutLong(targetId).PutShort((ushort)skill.Id), SendTargets.Range, attacker); var charges = attacker.ActiveSkillStacks; Send.SkillUse(attacker.Client, attacker, skill.Id, targetId); SkillHelper.ClearStack(attacker, skill); // End the spear WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.StackUpdate).PutString("icespear").PutBytes(0, 0), SendTargets.Range, attacker); var sAction = new AttackerAction(CombatActionType.SpecialHit, attacker, skill.Id, targetId); sAction.Options = AttackerOptions.Result; var cap = new CombatActionPack(attacker, skill.Id); cap.Add(sAction); foreach (var target in targets) { var tAction = new TargetAction(CombatActionType.None, target, attacker, skill.Id); cap.Add(tAction); } WorldManager.Instance.HandleCombatActionPack(cap); SkillHelper.GiveSkillExp(attacker, skill, 20); System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() => { this.IcespearProcessing(attacker, skill, targets, casterProp, 3500, charges); })); t.Start(); return SkillResults.Okay; }
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; }