public void Release() { Creature = null; Npc = null; Projectile = null; TargetPosition = null; }
public override void Release() { base.Release(); Projectile = null; if (MoveController != null) MoveController.Release(); MoveController = null; }
public NpcMoveController(Creature creature) { Creature = creature; Npc = creature as Npc; Projectile = creature as Projectile; TargetPosition = new Point3D(); MoveVector = new Point3D(); }
public override void Init(Creature creature) { base.Init(creature); Projectile = (Projectile) creature; if (Projectile.TargetPosition != null) { MoveController = new NpcMoveController(creature); MoveController.MoveTo(Projectile.TargetPosition); } DieUts = RandomUtilities.GetCurrentMilliseconds() + Projectile.Lifetime; }
public static void ReleaseProjectile(Projectile projectile) { MapService.DespawnTeraObject(projectile); projectile.Release(); }
public static void CreateProjectile(Creature creature, Projectile projectile) { AiLogic.InitAi(projectile); MapService.SpawnTeraObject(projectile, creature.Instance); }
private async void ProcessArea(Creature creature, Skill skill, Targeting targeting, TargetingArea area, Projectile projectile = null) { try { bool isProjectileSkill = skill.Type == SkillType.Projectile || skill.Type == SkillType.Userslug; int skillId = creature.Attack.Args.SkillId; if (isProjectileSkill) skillId += 20; if (targeting.Time > 0) await Task.Delay((int) (targeting.Time/skill.TimeRate)); int elapsed = targeting.Time; Player player = creature as Player; do { try { if (creature.LifeStats.IsDead()) return; if (area.DropItem != null) creature.Instance.AddDrop(new Item { Owner = player, ItemId = (int) area.DropItem, Count = 1, Position = Geom.ForwardPosition(creature.Position, 40), Instance = player.Instance, }); Point3D center = projectile != null ? projectile.Position.ToPoint3D() : Geom.GetNormal(creature.Position.Heading) .Multiple(area.OffsetDistance) .Add(creature.Position); int count = 0; List<Creature> targets = creature.Attack.Args.Targets.Count > 0 ? creature.Attack.Args.Targets : VisibleService.FindTargets(creature, center, projectile != null ? projectile.AttackDistance : area.MaxRadius, area.Type); foreach (Creature target in targets) { if (target != creature //Ignore checks for self-target && !isProjectileSkill && !creature.Attack.Args.IsItemSkill) { if (center.DistanceTo(target.Position) < area.MinRadius - 40) continue; if (center.DistanceTo(target.Position) > area.MaxRadius) continue; short diff = Geom.GetAngleDiff(creature.Attack.Args.StartPosition.Heading, Geom.GetHeading(center, target.Position)); //diff from 0 to 180 //area.RangeAngel from 0 to 360 if (diff * 2 > (creature.Attack.Args.IsTargetAttack ? 90 : Math.Abs(area.RangeAngle) + 10)) continue; } if (skill.TotalAtk > 0) { int damage = SeUtils.CalculateDamage(creature, target, skill.TotalAtk*area.Effect.Atk); AttackResult result = new AttackResult { AttackType = AttackType.Normal, AttackUid = creature.Attack.UID, Damage = damage, Target = target, }; result.AngleDif = Geom.GetAngleDiff(creature.Attack.Args.StartPosition.Heading, result.Target.Position.Heading); SeUtils.UpdateAttackResult(creature, result); if (result.AttackType == AttackType.Block) VisibleService.Send(target, new SpAttackShowBlock(target, skillId)); VisibleService.Send(target, new SpAttackResult(creature, skillId, result)); AiLogic.OnAttack(creature, target); AiLogic.OnAttacked(target, creature, result.Damage); if (target is Player && ((Player)target).Duel != null && player != null && ((Player)target).Duel.Equals(player.Duel) && target.LifeStats.GetHpDiffResult(damage) < 1) DuelService.FinishDuel(player); else CreatureLogic.HpChanged(target, target.LifeStats.MinusHp(result.Damage)); } if (area.Effect.HpDiff > 0) { AttackResult result = new AttackResult {HpDiff = area.Effect.HpDiff, Target = target}; PassivityProcessor.OnHeal(player, result); if(target is Player) PassivityProcessor.OnHealed((Player)target, result); CreatureLogic.HpChanged(target, target.LifeStats.PlusHp(result.HpDiff), creature); } if (area.Effect.MpDiff > 0) CreatureLogic.MpChanged(target, target.LifeStats.PlusMp(area.Effect.MpDiff), creature); if (area.Effect.AbnormalityOnCommon != null) for (int i = 0; i < area.Effect.AbnormalityOnCommon.Count; i++) AbnormalityProcessor.AddAbnormality(target, area.Effect.AbnormalityOnCommon[i], creature); if (player != null) { DuelService.ProcessDamage(player); //MP regen on combo skill if (skill.Id/10000 == 1 && player.GameStats.CombatMpRegen > 0) { CreatureLogic.MpChanged(player, player.LifeStats.PlusMp( player.MaxMp*player.GameStats.CombatMpRegen/200)); } } if (++count == area.MaxCount) break; } } catch (Exception ex) { Logger.WriteLine(LogState.Exception,"SkillEngine: ProcessAreaExc: " + ex); } if (targeting.Interval > 0) { await Task.Delay((int) (targeting.Interval/skill.TimeRate)); elapsed += targeting.Interval; } } while (targeting.Interval > 0 && elapsed < targeting.Until); } catch (Exception ex) { Logger.WriteLine(LogState.Exception,"SkillEngine: ProcessArea: " + ex); } }
private void ProcessProjectileSkillList(Creature creature, ProjectileSkill projectileSkill) { Projectile projectile = new Projectile(creature, projectileSkill); CreatureLogic.CreateProjectile(creature, projectile); }
private void ProcessProjectileTargets(Creature creature, Skill skill, Projectile projectile) { if (skill.ProjectileData.With(data => data.TargetingList) == null) return; skill.ProjectileData.TargetingList.Map(targeting => targeting.AreaList.Map(area => { if (area.Type == TargetingAreaType.PvP) return; ProcessArea(creature, skill, targeting, area, projectile); })); }
private void ProcessSkill(Creature creature, UseSkillArgs args, Skill skill, Projectile projectile = null) { bool isProjectileSkill = skill.Type == SkillType.Projectile || skill.Type == SkillType.Userslug; if (!isProjectileSkill) { if (skill.ChargingStageList == null || skill.ChargingStageList.ChargeStageList.Count == 0) { if (skill.Precondition.Cost.Hp > 0) CreatureLogic.HpChanged(creature, creature.LifeStats.MinusHp(skill.Precondition.Cost.Hp)); if (skill.Precondition.Cost.Mp > 0) CreatureLogic.MpChanged(creature, creature.LifeStats.MinusMp(skill.Precondition.Cost.Mp)); } if (!args.IsDelaySkill || args.IsDelayStart) { if (args.TargetPosition.IsNull()) { double angle = args.StartPosition.Heading*Math.PI/32768; args.StartPosition.CopyTo(args.TargetPosition); args.TargetPosition.X += 100*(float) Math.Cos(angle); args.TargetPosition.Y += 100*(float) Math.Sin(angle); } // ReSharper disable ImplicitlyCapturedClosure creature.Attack = new Attack(creature, args, () => GlobalLogic.AttackStageEnd(creature), () => GlobalLogic.AttackFinished(creature)); // ReSharper restore ImplicitlyCapturedClosure VisibleService.Send(creature, new SpAttack(creature, creature.Attack)); VisibleService.Send(creature, new SpAttackDestination(creature, creature.Attack)); if (!args.IsDelaySkill) ProcessStages(creature, skill); else { Player player = creature as Player; if (player != null && skill.BaseId == 20100 && (player.PlayerData.Class == PlayerClass.Berserker || player.PlayerData.Class == PlayerClass.Lancer)) { player.EffectsImpact.ResetChanges(player); //Set IsBlockFrontAttacks } } ProcessMove(creature, skill); } } else { creature.Attack.Args.IsTargetAttack = args.IsTargetAttack; creature.Attack.Args.Targets = args.Targets; ProcessProjectileTargets(creature, skill, projectile); } AiLogic.OnUseSkill(creature, skill); if (skill.ChargingStageList != null) { if (args.IsDelayStart) { int uid = creature.Attack.UID; ThreadPool.QueueUserWorkItem( o => { Thread.Sleep(750); for (int i = 1; i < skill.ChargingStageList.ChargeStageList.Count; i++) { if (creature.Attack.UID != uid) return; creature.Attack.NextStage(); if (i != 3) Thread.Sleep(750); } }); } } else ProcessTargets(creature, skill); }
public void UseProjectileSkill(Projectile projectile) { Creature creature = (Creature) projectile.Parent; if (projectile.Skill == null) return; ProcessSkill(creature, new UseSkillArgs { IsTargetAttack = true, SkillId = projectile.SkillId, StartPosition = projectile.Position.Clone(), }, projectile.Skill, projectile); }
public SpProjectile(Projectile projectile) { Projectile = projectile; }
private void CheckProjectile(Projectile projectile) { if (IsVisible(Player, projectile)) { if (!Player.VisibleProjectiles.Contains(projectile)) { Player.VisibleProjectiles.Add(projectile); projectile.VisiblePlayers.Add(Player); PlayerLogic.InTheVision(Player, projectile); } } else { if (Player.VisibleProjectiles.Contains(projectile)) { Player.VisibleProjectiles.Remove(projectile); projectile.VisiblePlayers.Remove(Player); PlayerLogic.OutOfVision(Player, projectile); } } }
public SpRemoveProjectile(Projectile projectile) { Projectile = projectile; }