示例#1
0
        protected FDMovePath DecidePositionAndPath(FDPosition targetPos)
        {
            DistanceResolver disResolver = new DistanceResolver(this.GameAction.GetField());

            disResolver.ResolveDistanceFrom(targetPos, this.Creature.Position);

            FDPosition originalPos = this.Creature.Position;

            float bestDistance       = 999;
            int   bestDistanceInUnit = -1;
            bool  inAttackScope      = false;

            MoveRangeFinder finder    = new MoveRangeFinder(this.GameAction, this.Creature);
            FDMoveRange     moveRange = finder.CalculateMoveRange();

            FDSpan     span     = null;
            FDPosition finalPos = originalPos;

            if (this.GameAction.GetCreatureAt(targetPos) != null)
            {
                span = Creature.Data.GetAttackItem()?.AttackScope;
            }
            else
            {
                span = new FDSpan(0, 0);
            }

            foreach (FDPosition movePos in moveRange.Positions)
            {
                int distanceToTarget = GetDirectDistance(targetPos, movePos);
                if (span.ContainsValue(distanceToTarget))
                {
                    inAttackScope = true;
                    if (distanceToTarget > bestDistanceInUnit)
                    {
                        bestDistanceInUnit = distanceToTarget;
                        finalPos           = movePos;
                    }
                }

                if (!inAttackScope)
                {
                    float distance = disResolver.GetDistanceTo(movePos);
                    if (distance < bestDistance)
                    {
                        bestDistance = distance;
                        finalPos     = movePos;
                    }
                }
            }

            return(moveRange.GetPath(finalPos));
        }
示例#2
0
        private void WalkOnPosition(FDPosition position, int leftMovePoint, FDMoveRange range)
        {
            int moveCost = GetMoveCost(position, creature);

            if (moveCost == -1 || leftMovePoint < moveCost)
            {
                // Nothing to walk
                return;
            }

            // If this is ZOC, stop the move
            if (!position.AreSame(this.creature.Position) && HasAdjacentEnemy(position))
            {
                return;
            }

            int leftPoint = leftMovePoint - moveCost;

            foreach (FDPosition direction in position.GetAdjacentPositions())
            {
                if (direction.X <= 0 || direction.X > gameField.Width ||
                    direction.Y <= 0 || direction.Y > gameField.Height)
                {
                    continue;
                }

                if (range.Contains(direction))
                {
                    continue;
                }

                // If already occupied by creature
                FDCreature existing = gameAction.GetCreatureAt(direction);
                if (existing != null && existing.IsOppositeFaction(creature))
                {
                    continue;
                }

                if (GetMoveCost(direction, creature) == -1)
                {
                    // Cannot land on target direction
                    continue;
                }

                range.AddPosition(direction, position);
                positionQueue.Enqueue(new MoveRangeQueueObject(direction, leftPoint));
            }
        }
示例#3
0
        public FDMoveRange CalculateMoveRange()
        {
            FDPosition  central = this.creature.Position;
            FDMoveRange range   = new FDMoveRange(central);

            int movePoint = creature.Data.CalculatedMv;

            positionQueue = new Queue <MoveRangeQueueObject>();

            range.AddPosition(central, null);
            positionQueue.Enqueue(new MoveRangeQueueObject(central, movePoint));

            while (positionQueue.Count > 0)
            {
                MoveRangeQueueObject queueObject = positionQueue.Dequeue();
                WalkOnPosition(queueObject.Position, queueObject.LeftMovePoint, range);
            }

            // Remove the friend creatures from range
            List <FDCreature> creatureInRange = gameAction.GetCreatureInRange(range, creature.Faction);

            if (creature.Faction == CreatureFaction.Friend)
            {
                creatureInRange.AddRange(gameAction.GetCreatureInRange(range, CreatureFaction.Npc));
            }
            else if (creature.Faction == CreatureFaction.Npc)
            {
                creatureInRange.AddRange(gameAction.GetCreatureInRange(range, CreatureFaction.Friend));
            }

            foreach (FDCreature c in creatureInRange)
            {
                if (c.CreatureId == creature.CreatureId)
                {
                    continue;
                }

                range.AddSkipPosition(c.Position);
            }

            return(range);
        }
        public override void OnEnter()
        {
            base.OnEnter();

            // Calculcate the moving scopes and save it in cache
            if (moveRange == null)
            {
                MoveRangeFinder finder = new MoveRangeFinder(gameAction, this.creature);
                moveRange = finder.CalculateMoveRange();
            }

            // If the creature has moved, reset the creature position
            this.creature.ResetPosition();
            CreatureRefreshPack reset = new CreatureRefreshPack(this.creature.Clone());

            SendPack(reset);

            ShowRangePack showRange = new ShowRangePack(moveRange);

            SendPack(showRange);
        }