Merge pull request #4437 from pchote/moveadjacent

Fix EnterTransport pathing.
This commit is contained in:
Matthias Mailänder
2014-01-12 01:53:53 -08:00
11 changed files with 128 additions and 46 deletions

View File

@@ -25,6 +25,8 @@ NEW:
Added a new Launch.Replay=$FILEPATH parameter for OpenRA.Game.exe to instantly start watching a *.rep file.
Added HackyAI settings: ExcessPowerFactor, MinimumExcessPower, IdleBaseUnitsMaximum, RushAttackScanRadius, ProtectUnitScanRadius, RallyPointScanRadius. See the traits documentation for more information.
Added HitAnimPalette trait for LaserZap projectiles. Laser hit animations can now specify individual palettes. Defaults to effect palette.
Fixed performance issues with units pathing to naval transports.
Fixed unit moving to transports that have moved.
Server:
Message of the day is now shared between all mods and a default motd.txt gets created in the user directory.
Asset Browser:

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA.Activities
return NextActivity;
if (!Util.AdjacentCells(target).Any(c => c == self.Location))
return Util.SequenceActivities(new MoveAdjacentTo(target), this);
return Util.SequenceActivities(new MoveAdjacentTo(self, target), this);
// Move to the middle of the target, ignoring impassable tiles
var mobile = self.Trait<Mobile>();

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
@@ -8,31 +8,37 @@
*/
#endregion
using System.Linq;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
class EnterTransport : Activity
{
public Actor transport;
readonly Actor transport;
readonly Cargo cargo;
public EnterTransport(Actor self, Actor transport)
{
this.transport = transport;
cargo = transport.Trait<Cargo>();
}
public override Activity Tick(Actor self)
{
if (IsCanceled) return NextActivity;
if (transport == null || !transport.IsInWorld) return NextActivity;
if (IsCanceled)
return NextActivity;
if (transport == null || !transport.IsInWorld)
return NextActivity;
var cargo = transport.Trait<Cargo>();
if (!cargo.CanLoad(transport, self))
return NextActivity;
// TODO: Queue a move order to the transport? need to be
// careful about units that can't path to the transport
if ((transport.Location - self.Location).LengthSquared > 2)
var cells = Util.AdjacentCells(Target.FromActor(transport));
if (!cells.Contains(self.Location))
return NextActivity;
cargo.Load(transport, self);

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Mods.RA.Activities
var nearest = target.Actor.OccupiesSpace.NearestCellTo(mobile.toCell);
if ((nearest - mobile.toCell).LengthSquared > 2)
return Util.SequenceActivities(new MoveAdjacentTo(target), this);
return Util.SequenceActivities(new MoveAdjacentTo(self, target), this);
if (!capturable.CaptureInProgress)
capturable.BeginCapture(self);

View File

@@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA.Activities
return new Wait(20);
return Util.SequenceActivities(
new MoveAdjacentTo(Target.FromActor(rearmTarget)),
new MoveAdjacentTo(self, Target.FromActor(rearmTarget)),
mobile.MoveTo(rearmTarget.CenterPosition.ToCPos(), rearmTarget),
new Rearm(self),
new Repair(rearmTarget),

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
@@ -8,6 +8,8 @@
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
@@ -16,35 +18,97 @@ namespace OpenRA.Mods.RA.Activities
public class MoveAdjacentTo : Activity
{
readonly Target target;
readonly Mobile mobile;
readonly PathFinder pathFinder;
readonly DomainIndex domainIndex;
readonly int movementClass;
public MoveAdjacentTo(Target target) { this.target = target; }
Activity inner;
CPos cachedTargetPosition;
CPos[] adjacentCells;
bool repath;
public MoveAdjacentTo(Actor self, Target target)
{
this.target = target;
mobile = self.Trait<Mobile>();
pathFinder = self.World.WorldActor.Trait<PathFinder>();
domainIndex = self.World.WorldActor.TraitOrDefault<DomainIndex>();
movementClass = mobile.Info.GetMovementClass(self.World.TileSet);
repath = true;
}
public override Activity Tick(Actor self)
{
if (IsCanceled || !target.IsValidFor(self))
return NextActivity;
var mobile = self.Trait<Mobile>();
var ps1 = new PathSearch(self.World, mobile.Info, self)
{
checkForBlocked = true,
heuristic = location => 0,
inReverse = true
};
var targetPosition = target.CenterPosition.ToCPos();
foreach (var cell in Util.AdjacentCells(target))
// Calculate path to target
if (inner == null && repath)
{
if (cell == self.Location)
return NextActivity;
else
ps1.AddInitialCell(cell);
cachedTargetPosition = targetPosition;
adjacentCells = Util.AdjacentCells(target).ToArray();
repath = false;
var loc = self.Location;
var searchCells = new List<CPos>();
foreach (var cell in adjacentCells)
{
if (cell == loc)
return NextActivity;
else if (domainIndex == null || domainIndex.IsPassable(loc, cell, (uint)movementClass))
searchCells.Add(cell);
}
if (searchCells.Any())
{
var ps1 = new PathSearch(self.World, mobile.Info, self)
{
checkForBlocked = true,
heuristic = location => 0,
inReverse = true
};
foreach (var cell in searchCells)
ps1.AddInitialCell(cell);
ps1.heuristic = PathSearch.DefaultEstimator(mobile.toCell);
var ps2 = PathSearch.FromPoint(self.World, mobile.Info, self, mobile.toCell, target.CenterPosition.ToCPos(), true);
var ret = pathFinder.FindBidiPath(ps1, ps2);
inner = mobile.MoveTo(() => ret);
}
}
ps1.heuristic = PathSearch.DefaultEstimator(mobile.toCell);
var ps2 = PathSearch.FromPoint(self.World, mobile.Info, self, mobile.toCell, target.CenterPosition.ToCPos(), true);
var ret = self.World.WorldActor.Trait<PathFinder>().FindBidiPath(ps1, ps2);
// Force a repath once the actor reaches the next cell
if (!repath && cachedTargetPosition != targetPosition)
{
if (inner != null)
inner.Cancel(self);
return Util.SequenceActivities(mobile.MoveTo(() => ret), this);
repath = true;
}
inner = Util.RunActivity(self, inner);
// Move completed
if (inner == null && adjacentCells.Contains(self.Location))
return NextActivity;
return this;
}
public override IEnumerable<Target> GetTargets(Actor self)
{
if (inner != null)
return inner.GetTargets(self);
return Target.None;
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
@@ -8,6 +8,7 @@
*/
#endregion
using System.Collections.Generic;
using System.Drawing;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
@@ -27,11 +28,11 @@ namespace OpenRA.Mods.RA
public CPos? TargetLocation = null;
readonly Mobile mobile;
readonly AttackMoveInfo Info;
readonly AttackMoveInfo info;
public AttackMove(Actor self, AttackMoveInfo info)
{
Info = info;
this.info = info;
mobile = self.Trait<Mobile>();
}
@@ -39,6 +40,7 @@ namespace OpenRA.Mods.RA
{
if (order.OrderString == "AttackMove")
return "AttackMove";
return null;
}
@@ -61,7 +63,7 @@ namespace OpenRA.Mods.RA
if (order.OrderString == "AttackMove")
{
if (Info.JustMove)
if (info.JustMove)
mobile.ResolveOrder(self, new Order("Move", order));
else
{
@@ -73,19 +75,19 @@ namespace OpenRA.Mods.RA
public class AttackMoveActivity : Activity
{
const int ScanInterval = 7;
Activity inner;
int scanTicks;
AutoTarget autoTarget;
const int ScanInterval = 7;
public AttackMoveActivity( Actor self, Activity inner )
public AttackMoveActivity(Actor self, Activity inner)
{
this.inner = inner;
this.autoTarget = self.TraitOrDefault<AutoTarget>();
autoTarget = self.TraitOrDefault<AutoTarget>();
}
public override Activity Tick( Actor self )
public override Activity Tick(Actor self)
{
if (autoTarget != null && --scanTicks <= 0)
{
@@ -93,20 +95,28 @@ namespace OpenRA.Mods.RA
scanTicks = ScanInterval;
}
if( inner == null )
if (inner == null)
return NextActivity;
inner = Util.RunActivity( self, inner );
inner = Util.RunActivity(self, inner);
return this;
}
public override void Cancel( Actor self )
public override void Cancel(Actor self)
{
if( inner != null )
inner.Cancel( self );
if (inner != null)
inner.Cancel(self);
base.Cancel( self );
base.Cancel(self);
}
public override IEnumerable<Target> GetTargets(Actor self)
{
if (inner != null)
return inner.GetTargets(self);
return Target.None;
}
}
}

View File

@@ -65,7 +65,7 @@ namespace OpenRA.Mods.RA
self.CancelActivity();
self.SetTargetLine(target, Color.Red);
self.QueueActivity(new MoveAdjacentTo(target));
self.QueueActivity(new MoveAdjacentTo(self, target));
self.QueueActivity(new CallFunc(() => Explode(self)));
}

View File

@@ -146,7 +146,7 @@ namespace OpenRA.Mods.RA
self.CancelActivity();
self.SetTargetLine(target, Color.Red);
self.QueueActivity(new MoveAdjacentTo(target));
self.QueueActivity(new MoveAdjacentTo(self, target));
self.QueueActivity(new CallFunc(StartDetonationSequence));
}

View File

@@ -79,7 +79,7 @@ namespace OpenRA.Mods.RA
self.SetTargetLine(target, Color.Green);
self.CancelActivity();
self.QueueActivity(new MoveAdjacentTo(target));
self.QueueActivity(new MoveAdjacentTo(self, target));
self.QueueActivity(new EnterTransport(self, order.TargetActor));
}
}

View File

@@ -78,7 +78,7 @@ namespace OpenRA.Mods.RA
self.SetTargetLine(target, Color.Green);
self.CancelActivity();
self.QueueActivity(new MoveAdjacentTo(target));
self.QueueActivity(new MoveAdjacentTo(self, target));
self.QueueActivity(mobile.MoveTo(order.TargetActor.CenterPosition.ToCPos(), order.TargetActor));
self.QueueActivity(new Rearm(self));
self.QueueActivity(new Repair(order.TargetActor));