Пример #1
0
        protected void EnemiesListenAction()
        {
            if (Npc.Target != null || Npc.LifeStats.IsDead())
            {
                PlayerInFocus = null;
                return;
            }

            const int agroDistance = 300;

            if (PlayerInFocus != null)
            {
                if (PlayerInFocus.Position.DistanceTo(Npc.Position) > agroDistance || PlayerInFocus.LifeStats.IsDead())
                {
                    PlayerInFocus = null;
                    Global.VisibleService.Send(Npc, new SpNpcStatus(Npc, 5, 0));
                }
            }

            if (PlayerInFocus != null)
            {
                long now = RandomUtilities.GetCurrentMilliseconds();

                if (NextChangeDirectionUts < now)
                {
                    short heading = Geom.GetHeading(Npc.Position, PlayerInFocus.Position);

                    short turnTime = (short)(2 * System.Math.Abs(Npc.Position.Heading - heading)
                                             / System.Math.Max(45, System.Math.Max(Npc.NpcTemplate.Shape.TurnSpeed, Npc.NpcTemplate.Shape.WalkSpeed)));

                    if (turnTime > 200 && !MoveController.IsActive)
                    {
                        Global.VisibleService.Send(Npc, new SpDirectionChange(Creature, heading, turnTime));

                        Npc.Position.Heading   = heading;
                        NextChangeDirectionUts = now + turnTime;
                    }
                    else
                    {
                        NextChangeDirectionUts = now + 500;
                    }
                }

                return;
            }

            Npc.VisiblePlayers.Each(
                player =>
            {
                if (PlayerInFocus != null ||
                    player.LifeStats.IsDead() ||
                    player.Position.DistanceTo(Npc.Position) > agroDistance)
                {
                    return;
                }

                OnCreatureApproached(player);
            });
        }
Пример #2
0
        public void Action(long elapsed)
        {
            try
            {
                if (IsMove)
                {
                    Creature.Position.X += MoveVector.X;
                    Creature.Position.Y += MoveVector.Y;

                    IsMove = false;
                }

                if (!IsActive)
                {
                    return;
                }

                if (TargetDistance != 0)
                {
                    double d = TargetPosition.DistanceTo2D(Creature.Position) - 10;
                    double a = Geom.GetHeading(Creature.Position, Creature.Target.Position) * Math.PI / 32768;

                    TargetPosition.X = Creature.Position.X + (float)(Math.Cos(a) * d);
                    TargetPosition.Y = Creature.Position.Y + (float)(Math.Sin(a) * d);

                    TargetDistance = 0;
                }

                double distance = TargetPosition.DistanceTo2D(Creature.Position);

                if (distance < 10)
                {
                    TargetPosition.CopyTo(Creature.Position);
                    IsActive = false;
                    return;
                }

                int speed = GetSpeed();

                if (IsNewDirection)
                {
                    IsNewDirection = false;
                    Global.Global.VisibleService.Send(Creature, new SpNpcMove(Creature, TargetPosition.X, TargetPosition.Y, TargetPosition.Z, (Creature.Target != null) ? 2 : 1));
                }

                double angle = Geom.GetHeading(Creature.Position) * Math.PI / 32768;

                MoveVector.X = (float)(Math.Cos(angle));
                MoveVector.Y = (float)(Math.Sin(angle));

                IsMove = true;
            }
            catch (Exception e)
            {
                Log.ErrorException("NpcMoveController.Action():", e);
            }
        }
Пример #3
0
        public static float CheckIntersections(Creature creature, short heading, Point3D moveVector, float distance)
        {
            if (distance <= 0f)
            {
                return(0f);
            }

            WorldPosition targetPosition = moveVector.Clone().Add(creature.Position).ToWorldPosition();

            double minDistance = distance;

            List <Creature> around = Global.VisibleService.FindTargets(creature, creature.Position, distance + 40, TargetingAreaType.All);

            for (int x = 0; x < around.Count; x++)
            {
                if (around[x] == creature)
                {
                    continue;
                }

                short diff = Geom.GetAngleDiff(heading, Geom.GetHeading(creature.Position, around[x].Position));
                if (diff > 90)
                {
                    continue;
                }

                double d = Geom.DistanceToLine(around[x].Position, creature.Position, targetPosition);

                if (d > 40)
                {
                    continue;
                }

                d = creature.Position.DistanceTo(around[x].Position) - 40;

                if (d <= 0)
                {
                    return(0f);
                }

                if (d < minDistance)
                {
                    minDistance = d;
                }
            }

            return((float)(minDistance / distance));
        }
Пример #4
0
        public void UseSkill(Npc npc, Skill skill)
        {
            if (npc.Target == null)
            {
                return;
            }

            npc.Position.Heading = Geom.GetHeading(npc.Position, npc.Target.Position);

            ProcessSkill(npc, new UseSkillArgs
            {
                IsTargetAttack = false,
                SkillId        = skill.Id + 0x40000000 + (npc.NpcTemplate.HuntingZoneId << 16),
                StartPosition  = npc.Position.Clone(),
            }, skill);
        }
Пример #5
0
        public static void DebugLine(Creature creature, Point3D start, Point3D end)
        {
            const int iterations = 3;

            Point3D vector = Geom.GetNormal(Geom.GetHeading(start, end))
                             .Multiple((float)(start.DistanceTo(end) / (iterations - 1)));

            for (int i = 0; i < iterations; i++)
            {
                DropItem(creature, 20000001, 0, start.ToWorldPosition(), true);
                start.Add(vector);
            }

            Player player = creature as Player;

            if (player != null)
            {
                player.Visible.Update();
            }
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        public void Action(long elapsed)
        {
            if (IsMove)
            {
                MoveVector.Multiple(elapsed / 1000f);
                Creature.Position.X += MoveVector.X;
                Creature.Position.Y += MoveVector.Y;

                if (Projectile != null)
                {
                    Creature.Position.Z += MoveVector.Z;
                }

                //Global.GeoService.FixZ(Npc.Position);

                IsMove = false;
            }

            if (!IsActive)
            {
                return;
            }

            Creature.Position.Heading = Geom.GetHeading(Creature.Position, TargetPosition);

            if (TargetDistance != 0)
            {
                double d = TargetPosition.DistanceTo2D(Creature.Position);
                double a = Creature.Position.Heading * Math.PI / 32768;

                TargetPosition.X = Creature.Position.X + (float)(d * Math.Cos(a));
                TargetPosition.Y = Creature.Position.Y + (float)(d * Math.Sin(a));

                TargetDistance = 0;
            }

            double distance = TargetPosition.DistanceTo2D(Creature.Position);

            if (distance < 10)
            {
                TargetPosition.CopyTo(Creature.Position);
                IsActive = false;
                return;
            }

            int speed = GetSpeed();

            if (Projectile == null && IsNewDirection)
            {
                IsNewDirection = false;
                Global.VisibleService.Send(Creature, new SpNpcMove(Creature, (short)speed, TargetPosition.X, TargetPosition.Y, TargetPosition.Z));
            }

            double angle = Creature.Position.Heading * Math.PI / 32768;

            MoveVector.X = speed * (float)Math.Cos(angle);
            MoveVector.Y = speed * (float)Math.Sin(angle);

            if (Projectile != null)
            {
                MoveVector.Z = speed * (TargetPosition.Z - Creature.Position.Z) / (float)distance;
            }

            IsMove = true;
        }
Пример #8
0
 public short GetHeadingToTarget(WorldPosition worldPosition)
 {
     return(Geom.GetHeading(((float)((worldPosition.X - X) / DistanceTo(worldPosition)) * 45),
                            ((float)((worldPosition.Y - Y) / DistanceTo(worldPosition)) * 45)));
 }