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)); }
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)); } }
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); }