Add plumbing for custom movement layers.

This commit is contained in:
Paul Chote
2017-01-04 18:10:46 +00:00
parent 695a572dc3
commit 2bd5a392d1
12 changed files with 207 additions and 56 deletions

View File

@@ -184,10 +184,15 @@ namespace OpenRA.Mods.Common.Activities
else
{
mobile.SetLocation(mobile.FromCell, mobile.FromSubCell, nextCell.Value.First, nextCell.Value.Second);
var from = self.World.Map.CenterOfSubCell(mobile.FromCell, mobile.FromSubCell);
var map = self.World.Map;
var from = (mobile.FromCell.Layer == 0 ? map.CenterOfCell(mobile.FromCell) :
self.World.GetCustomMovementLayers()[mobile.FromCell.Layer].CenterOfCell(mobile.FromCell)) +
map.Grid.OffsetOfSubCell(mobile.FromSubCell);
var to = Util.BetweenCells(self.World, mobile.FromCell, mobile.ToCell) +
(self.World.Map.Grid.OffsetOfSubCell(mobile.FromSubCell) +
self.World.Map.Grid.OffsetOfSubCell(mobile.ToSubCell)) / 2;
(map.Grid.OffsetOfSubCell(mobile.FromSubCell) + map.Grid.OffsetOfSubCell(mobile.ToSubCell)) / 2;
var move = new MoveFirstHalf(
this,
from,
@@ -415,21 +420,22 @@ namespace OpenRA.Mods.Common.Activities
protected override MovePart OnComplete(Actor self, Mobile mobile, Move parent)
{
var fromSubcellOffset = self.World.Map.Grid.OffsetOfSubCell(mobile.FromSubCell);
var toSubcellOffset = self.World.Map.Grid.OffsetOfSubCell(mobile.ToSubCell);
var map = self.World.Map;
var fromSubcellOffset = map.Grid.OffsetOfSubCell(mobile.FromSubCell);
var toSubcellOffset = map.Grid.OffsetOfSubCell(mobile.ToSubCell);
var nextCell = parent.PopPath(self);
if (nextCell != null)
{
if (IsTurn(mobile, nextCell.Value.First))
{
var nextSubcellOffset = self.World.Map.Grid.OffsetOfSubCell(nextCell.Value.Second);
var nextSubcellOffset = map.Grid.OffsetOfSubCell(nextCell.Value.Second);
var ret = new MoveFirstHalf(
Move,
Util.BetweenCells(self.World, mobile.FromCell, mobile.ToCell) + (fromSubcellOffset + toSubcellOffset) / 2,
Util.BetweenCells(self.World, mobile.ToCell, nextCell.Value.First) + (toSubcellOffset + nextSubcellOffset) / 2,
mobile.Facing,
Util.GetNearestFacing(mobile.Facing, self.World.Map.FacingBetween(mobile.ToCell, nextCell.Value.First, mobile.Facing)),
Util.GetNearestFacing(mobile.Facing, map.FacingBetween(mobile.ToCell, nextCell.Value.First, mobile.Facing)),
moveFraction - MoveFractionTotal);
mobile.FinishedMoving(self);
@@ -440,10 +446,13 @@ namespace OpenRA.Mods.Common.Activities
parent.path.Add(nextCell.Value.First);
}
var toPos = mobile.ToCell.Layer == 0 ? map.CenterOfCell(mobile.ToCell) :
self.World.GetCustomMovementLayers()[mobile.ToCell.Layer].CenterOfCell(mobile.ToCell);
var ret2 = new MoveSecondHalf(
Move,
Util.BetweenCells(self.World, mobile.FromCell, mobile.ToCell) + (fromSubcellOffset + toSubcellOffset) / 2,
self.World.Map.CenterOfCell(mobile.ToCell) + toSubcellOffset,
toPos + toSubcellOffset,
mobile.Facing,
mobile.Facing,
moveFraction - MoveFractionTotal);

View File

@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Activities
{
static readonly List<CPos> NoPath = new List<CPos>();
readonly Mobile mobile;
protected readonly Mobile Mobile;
readonly IPathFinder pathFinder;
readonly DomainIndex domainIndex;
readonly uint movementClass;
@@ -53,10 +53,10 @@ namespace OpenRA.Mods.Common.Activities
{
Target = target;
mobile = self.Trait<Mobile>();
Mobile = self.Trait<Mobile>();
pathFinder = self.World.WorldActor.Trait<IPathFinder>();
domainIndex = self.World.WorldActor.Trait<DomainIndex>();
movementClass = (uint)mobile.Info.GetMovementClass(self.World.Map.Rules.TileSet);
movementClass = (uint)Mobile.Info.GetMovementClass(self.World.Map.Rules.TileSet);
if (target.IsValidFor(self))
targetPosition = self.World.Map.CellContaining(target.CenterPosition);
@@ -91,7 +91,7 @@ namespace OpenRA.Mods.Common.Activities
inner.Cancel(self);
self.SetTargetLine(Target.FromCell(self.World, targetPosition), Color.Green);
return ActivityUtils.RunActivity(self, new AttackMoveActivity(self, mobile.MoveTo(targetPosition, 0)));
return ActivityUtils.RunActivity(self, new AttackMoveActivity(self, Mobile.MoveTo(targetPosition, 0)));
}
// Inner move order has completed.
@@ -103,7 +103,7 @@ namespace OpenRA.Mods.Common.Activities
return NextActivity;
// Target has moved, and MoveAdjacentTo is still valid.
inner = mobile.MoveTo(() => CalculatePathToTarget(self));
inner = Mobile.MoveTo(() => CalculatePathToTarget(self));
repath = false;
}
@@ -142,14 +142,14 @@ namespace OpenRA.Mods.Common.Activities
var loc = self.Location;
foreach (var cell in targetCells)
if (domainIndex.IsPassable(loc, cell, movementClass) && mobile.CanEnterCell(cell))
if (domainIndex.IsPassable(loc, cell, movementClass) && Mobile.CanEnterCell(cell))
searchCells.Add(cell);
if (!searchCells.Any())
return NoPath;
using (var fromSrc = PathSearch.FromPoints(self.World, mobile.Info, self, searchCells, loc, true))
using (var fromDest = PathSearch.FromPoint(self.World, mobile.Info, self, loc, targetPosition, true).Reverse())
using (var fromSrc = PathSearch.FromPoints(self.World, Mobile.Info, self, searchCells, loc, true))
using (var fromDest = PathSearch.FromPoint(self.World, Mobile.Info, self, loc, targetPosition, true).Reverse())
return pathFinder.FindBidiPath(fromSrc, fromDest);
}

View File

@@ -11,6 +11,7 @@
using System.Collections.Generic;
using System.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Activities
@@ -31,12 +32,13 @@ namespace OpenRA.Mods.Common.Activities
{
// We are now in range. Don't move any further!
// HACK: This works around the pathfinder not returning the shortest path
return AtCorrectRange(self.CenterPosition);
return AtCorrectRange(self.CenterPosition) && Mobile.CanInteractWithGroundLayer(self);
}
protected override bool ShouldRepath(Actor self, CPos oldTargetPosition)
{
return targetPosition != oldTargetPosition && !AtCorrectRange(self.CenterPosition);
return targetPosition != oldTargetPosition && (!AtCorrectRange(self.CenterPosition)
|| !Mobile.CanInteractWithGroundLayer(self));
}
protected override IEnumerable<CPos> CandidateMovementCells(Actor self)