Helicopters use pathfinder
This commit is contained in:
@@ -241,6 +241,7 @@
|
|||||||
<Compile Include="Widgets\PowerBinWidget.cs" />
|
<Compile Include="Widgets\PowerBinWidget.cs" />
|
||||||
<Compile Include="Widgets\ImageWidget.cs" />
|
<Compile Include="Widgets\ImageWidget.cs" />
|
||||||
<Compile Include="Traits\SharesCell.cs" />
|
<Compile Include="Traits\SharesCell.cs" />
|
||||||
|
<Compile Include="Traits\World\AircraftInfluence.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
||||||
|
|||||||
@@ -31,18 +31,18 @@ namespace OpenRA
|
|||||||
public class PathFinder
|
public class PathFinder
|
||||||
{
|
{
|
||||||
readonly World world;
|
readonly World world;
|
||||||
float[][,] passableCost = new float[4][,];
|
float[][,] passableCost = new float[5][,];
|
||||||
|
|
||||||
public PathFinder( World world )
|
public PathFinder( World world )
|
||||||
{
|
{
|
||||||
this.world = world;
|
this.world = world;
|
||||||
var map = world.Map;
|
var map = world.Map;
|
||||||
for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Float; umt++)
|
for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Fly; umt++)
|
||||||
passableCost[(int)umt] = new float[map.MapSize.X, map.MapSize.Y];
|
passableCost[(int)umt] = new float[map.MapSize.X, map.MapSize.Y];
|
||||||
for( int x = 0 ; x < map.MapSize.X ; x++ )
|
for( int x = 0 ; x < map.MapSize.X ; x++ )
|
||||||
for( int y = 0 ; y < map.MapSize.Y ; y++ )
|
for( int y = 0 ; y < map.MapSize.Y ; y++ )
|
||||||
for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Float; umt++ )
|
for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Fly; umt++ )
|
||||||
passableCost[(int)umt][ x, y ] = ( world.Map.IsInMap( x, y ) )
|
passableCost[(int)umt][ x, y ] = (umt == UnitMovementType.Fly) ? 0f : ( world.Map.IsInMap( x, y ) )
|
||||||
? (float)Rules.TerrainTypes[world.TileSet.GetTerrainType(world.Map.MapTiles[x, y])]
|
? (float)Rules.TerrainTypes[world.TileSet.GetTerrainType(world.Map.MapTiles[x, y])]
|
||||||
.GetCost(umt)
|
.GetCost(umt)
|
||||||
: float.PositiveInfinity;
|
: float.PositiveInfinity;
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ namespace OpenRA
|
|||||||
public bool inReverse;
|
public bool inReverse;
|
||||||
|
|
||||||
BuildingInfluence buildingInfluence;
|
BuildingInfluence buildingInfluence;
|
||||||
UnitInfluence unitInfluence;
|
|
||||||
|
|
||||||
public PathSearch(Actor self)
|
public PathSearch(Actor self)
|
||||||
{
|
{
|
||||||
@@ -53,7 +52,6 @@ namespace OpenRA
|
|||||||
umt = self.traits.Get<Mobile>().GetMovementType();
|
umt = self.traits.Get<Mobile>().GetMovementType();
|
||||||
|
|
||||||
buildingInfluence = world.WorldActor.traits.Get<BuildingInfluence>();
|
buildingInfluence = world.WorldActor.traits.Get<BuildingInfluence>();
|
||||||
unitInfluence = world.WorldActor.traits.Get<UnitInfluence>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PathSearch InReverse()
|
public PathSearch InReverse()
|
||||||
@@ -114,11 +112,8 @@ namespace OpenRA
|
|||||||
if (costHere == float.PositiveInfinity)
|
if (costHere == float.PositiveInfinity)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!buildingInfluence.CanMoveHere(newHere, ignoreBuilding))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var mobile = self.traits.Get<Mobile>();
|
var mobile = self.traits.Get<Mobile>();
|
||||||
if (checkForBlocked && !mobile.CanEnterCell(newHere, ignoreBuilding))
|
if (checkForBlocked && !mobile.CanEnterCell(newHere, ignoreBuilding, checkForBlocked))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (customBlock != null && customBlock(newHere))
|
if (customBlock != null && customBlock(newHere))
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ namespace OpenRA.Traits.Activities
|
|||||||
{
|
{
|
||||||
if( path.Count == 0 ) return null;
|
if( path.Count == 0 ) return null;
|
||||||
var nextCell = path[ path.Count - 1 ];
|
var nextCell = path[ path.Count - 1 ];
|
||||||
if( !mobile.CanEnterCell( nextCell, ignoreBuilding ) )
|
if( !mobile.CanEnterCell( nextCell, ignoreBuilding, true ) )
|
||||||
{
|
{
|
||||||
if( ( mobile.toCell - destination.Value ).LengthSquared <= nearEnough )
|
if( ( mobile.toCell - destination.Value ).LengthSquared <= nearEnough )
|
||||||
{
|
{
|
||||||
@@ -185,10 +185,13 @@ namespace OpenRA.Traits.Activities
|
|||||||
if (--waitTicksRemaining >= 0)
|
if (--waitTicksRemaining >= 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
self.World.WorldActor.traits.Get<UnitInfluence>().Remove( self, mobile );
|
|
||||||
|
//self.World.WorldActor.traits.Get<UnitInfluence>().Remove( self, mobile );
|
||||||
|
mobile.RemoveInfluence();
|
||||||
var newPath = getPath(self).TakeWhile(a => a != self.Location).ToList();
|
var newPath = getPath(self).TakeWhile(a => a != self.Location).ToList();
|
||||||
|
|
||||||
self.World.WorldActor.traits.Get<UnitInfluence>().Add( self, mobile );
|
//self.World.WorldActor.traits.Get<UnitInfluence>().Add( self, mobile );
|
||||||
|
mobile.AddInfluence();
|
||||||
if (newPath.Count != 0)
|
if (newPath.Count != 0)
|
||||||
path = newPath;
|
path = newPath;
|
||||||
|
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ namespace OpenRA.Traits
|
|||||||
public readonly int WaitAverage = 60;
|
public readonly int WaitAverage = 60;
|
||||||
public readonly int WaitSpread = 20;
|
public readonly int WaitSpread = 20;
|
||||||
|
|
||||||
public object Create(ActorInitializer init) { return new Mobile(init); }
|
public virtual object Create(ActorInitializer init) { return new Mobile(init); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Mobile : IIssueOrder, IResolveOrder, IOccupySpace, IMove
|
public class Mobile : IIssueOrder, IResolveOrder, IOccupySpace, IMove
|
||||||
{
|
{
|
||||||
readonly Actor self;
|
public readonly Actor self;
|
||||||
|
|
||||||
[Sync]
|
[Sync]
|
||||||
int2 __fromCell, __toCell;
|
int2 __fromCell, __toCell;
|
||||||
@@ -53,17 +53,17 @@ namespace OpenRA.Traits
|
|||||||
void SetLocation( int2 from, int2 to )
|
void SetLocation( int2 from, int2 to )
|
||||||
{
|
{
|
||||||
if( fromCell == from && toCell == to ) return;
|
if( fromCell == from && toCell == to ) return;
|
||||||
self.World.WorldActor.traits.Get<UnitInfluence>().Remove(self, this);
|
RemoveInfluence();
|
||||||
__fromCell = from;
|
__fromCell = from;
|
||||||
__toCell = to;
|
__toCell = to;
|
||||||
self.World.WorldActor.traits.Get<UnitInfluence>().Add(self, this);
|
AddInfluence();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mobile(ActorInitializer init)
|
public Mobile(ActorInitializer init)
|
||||||
{
|
{
|
||||||
this.self = init.self;
|
this.self = init.self;
|
||||||
this.__fromCell = this.__toCell = init.location;
|
this.__fromCell = this.__toCell = init.location;
|
||||||
self.World.WorldActor.traits.Get<UnitInfluence>().Add(self, this);
|
AddInfluence();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPosition(Actor self, int2 cell)
|
public void SetPosition(Actor self, int2 cell)
|
||||||
@@ -83,7 +83,7 @@ namespace OpenRA.Traits
|
|||||||
{
|
{
|
||||||
// force-move
|
// force-move
|
||||||
if (!mi.Modifiers.HasModifier(Modifiers.Alt)) return null;
|
if (!mi.Modifiers.HasModifier(Modifiers.Alt)) return null;
|
||||||
if (!self.World.IsActorCrushableByActor(underCursor, self)) return null;
|
if (!CanEnterCell(underCursor.Location, null, true)) return null;
|
||||||
}
|
}
|
||||||
var umt = self.Info.Traits.Get<MobileInfo>().MovementType;
|
var umt = self.Info.Traits.Get<MobileInfo>().MovementType;
|
||||||
if (Util.GetEffectiveSpeed(self,umt) == 0) return null; /* allow disabling move orders from modifiers */
|
if (Util.GetEffectiveSpeed(self,umt) == 0) return null; /* allow disabling move orders from modifiers */
|
||||||
@@ -105,7 +105,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public int2 TopLeft { get { return toCell; } }
|
public int2 TopLeft { get { return toCell; } }
|
||||||
|
|
||||||
public IEnumerable<int2> OccupiedCells()
|
public virtual IEnumerable<int2> OccupiedCells()
|
||||||
{
|
{
|
||||||
return (fromCell == toCell)
|
return (fromCell == toCell)
|
||||||
? new[] { fromCell }
|
? new[] { fromCell }
|
||||||
@@ -121,27 +121,30 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public bool CanEnterCell(int2 p)
|
public bool CanEnterCell(int2 p)
|
||||||
{
|
{
|
||||||
return CanEnterCell(p, null);
|
return CanEnterCell(p, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanEnterCell(int2 p, Actor ignoreBuilding)
|
public virtual bool CanEnterCell(int2 p, Actor ignoreActor, bool checkTransientActors)
|
||||||
{
|
{
|
||||||
if (!self.World.WorldActor.traits.Get<BuildingInfluence>().CanMoveHere(p, ignoreBuilding)) return false;
|
if (!self.World.WorldActor.traits.Get<BuildingInfluence>().CanMoveHere(p, ignoreActor))
|
||||||
|
|
||||||
var canShare = self.traits.Contains<SharesCell>();
|
|
||||||
var actors = self.World.WorldActor.traits.Get<UnitInfluence>().GetUnitsAt(p);
|
|
||||||
var nonshareable = actors.Where(a => a != self && !(canShare && a.traits.Contains<SharesCell>()));
|
|
||||||
var shareable = actors.Where(a => a != self && canShare && a.traits.Contains<SharesCell>());
|
|
||||||
|
|
||||||
// only allow 5 in a cell
|
|
||||||
if (shareable.Count() >= 5)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// We can enter a cell with nonshareable units if we can crush all of them
|
|
||||||
if (nonshareable.Any(
|
|
||||||
a => !self.World.IsActorCrushableByActor(a, self)))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (checkTransientActors)
|
||||||
|
{
|
||||||
|
var canShare = self.traits.Contains<SharesCell>();
|
||||||
|
var actors = self.World.WorldActor.traits.Get<UnitInfluence>().GetUnitsAt(p).Where(a => a != self && a != ignoreActor);
|
||||||
|
var nonshareable = actors.Where(a => !(canShare && a.traits.Contains<SharesCell>()));
|
||||||
|
var shareable = actors.Where(a => canShare && a.traits.Contains<SharesCell>());
|
||||||
|
|
||||||
|
// only allow 5 in a cell
|
||||||
|
if (shareable.Count() >= 5)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// We can enter a cell with nonshareable units if we can crush all of them
|
||||||
|
if (nonshareable.Any(
|
||||||
|
a => !self.World.IsActorCrushableByActor(a, self)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return self.World.Map.IsInMap(p.X, p.Y) &&
|
return self.World.Map.IsInMap(p.X, p.Y) &&
|
||||||
Rules.TerrainTypes[self.World.TileSet.GetTerrainType(self.World.Map.MapTiles[p.X, p.Y])]
|
Rules.TerrainTypes[self.World.TileSet.GetTerrainType(self.World.Map.MapTiles[p.X, p.Y])]
|
||||||
@@ -155,5 +158,15 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
return Enumerable.Reverse(move.path).Select( c => Util.CenterOfCell(c) );
|
return Enumerable.Reverse(move.path).Select( c => Util.CenterOfCell(c) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void AddInfluence()
|
||||||
|
{
|
||||||
|
self.World.WorldActor.traits.Get<UnitInfluence>().Add( self, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void RemoveInfluence()
|
||||||
|
{
|
||||||
|
self.World.WorldActor.traits.Get<UnitInfluence>().Remove( self, this );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,12 @@ namespace OpenRA.Traits
|
|||||||
int2 TopLeft { get; }
|
int2 TopLeft { get; }
|
||||||
IEnumerable<int2> OccupiedCells();
|
IEnumerable<int2> OccupiedCells();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface IOccupyAir
|
||||||
|
{
|
||||||
|
int2 TopLeft { get; }
|
||||||
|
IEnumerable<int2> OccupiedAirCells();
|
||||||
|
}
|
||||||
|
|
||||||
public static class IOccupySpaceExts
|
public static class IOccupySpaceExts
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ namespace OpenRA.Traits
|
|||||||
public class ResourceType
|
public class ResourceType
|
||||||
{
|
{
|
||||||
public ResourceTypeInfo info;
|
public ResourceTypeInfo info;
|
||||||
float[] movementSpeed = new float[4];
|
float[] movementSpeed = new float[5];
|
||||||
float[] pathCost = new float[4];
|
float[] pathCost = new float[5];
|
||||||
|
|
||||||
public ResourceType(ResourceTypeInfo info)
|
public ResourceType(ResourceTypeInfo info)
|
||||||
{
|
{
|
||||||
@@ -56,6 +56,8 @@ namespace OpenRA.Traits
|
|||||||
pathCost[(int)umt] = (info.PathingTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetCost(umt)
|
pathCost[(int)umt] = (info.PathingTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetCost(umt)
|
||||||
: (info.MovementTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetCost(umt) : 1.0f;
|
: (info.MovementTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetCost(umt) : 1.0f;
|
||||||
}
|
}
|
||||||
|
movementSpeed[(int)UnitMovementType.Fly] = 1.0f;
|
||||||
|
pathCost[(int)UnitMovementType.Fly] = 1.0f;
|
||||||
|
|
||||||
this.info = info;
|
this.info = info;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
<Compile Include="ProductionAirdrop.cs" />
|
<Compile Include="ProductionAirdrop.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="TiberiumRefineryDockAction.cs" />
|
<Compile Include="TiberiumRefineryDockAction.cs" />
|
||||||
|
<Compile Include="MobileAir.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ HPAD:
|
|||||||
Crewed: yes
|
Crewed: yes
|
||||||
Sight: 5
|
Sight: 5
|
||||||
Bib:
|
Bib:
|
||||||
ProducesHelicopters:
|
Production:
|
||||||
SpawnOffset: 0,-4
|
SpawnOffset: 0,-4
|
||||||
Produces: Plane
|
Produces: Plane
|
||||||
BelowUnits:
|
BelowUnits:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Player:
|
Player:
|
||||||
ProductionQueue:
|
ProductionQueue:
|
||||||
BuildSpeed: .4
|
BuildSpeed: .004
|
||||||
LowPowerSlowdown: 3
|
LowPowerSlowdown: 3
|
||||||
PlaceBuilding:
|
PlaceBuilding:
|
||||||
TechTreeCache:
|
TechTreeCache:
|
||||||
@@ -38,7 +38,7 @@ Player:
|
|||||||
UnitType: a10
|
UnitType: a10
|
||||||
ConquestVictoryConditions:
|
ConquestVictoryConditions:
|
||||||
PlayerResources:
|
PlayerResources:
|
||||||
InitialCash: 5000
|
InitialCash: 500000
|
||||||
ActorGroupProxy:
|
ActorGroupProxy:
|
||||||
|
|
||||||
World:
|
World:
|
||||||
@@ -47,6 +47,7 @@ World:
|
|||||||
# WaterPaletteRotation:
|
# WaterPaletteRotation:
|
||||||
BuildingInfluence:
|
BuildingInfluence:
|
||||||
UnitInfluence:
|
UnitInfluence:
|
||||||
|
AircraftInfluence:
|
||||||
# BridgeLoadHook:
|
# BridgeLoadHook:
|
||||||
Theater@DESERT:
|
Theater@DESERT:
|
||||||
Name:Desert
|
Name:Desert
|
||||||
|
|||||||
@@ -406,7 +406,9 @@ TRAN:
|
|||||||
ROT: 5
|
ROT: 5
|
||||||
Sight: 8
|
Sight: 8
|
||||||
Speed: 15
|
Speed: 15
|
||||||
Helicopter:
|
# Helicopter:
|
||||||
|
MobileAir:
|
||||||
|
MovementType: Fly
|
||||||
RenderUnitRotor:
|
RenderUnitRotor:
|
||||||
PrimaryOffset: 0,14,0,-4
|
PrimaryOffset: 0,14,0,-4
|
||||||
SecondaryOffset: 0,-14,0,-2
|
SecondaryOffset: 0,-14,0,-2
|
||||||
@@ -434,15 +436,14 @@ HELI:
|
|||||||
ROT: 4
|
ROT: 4
|
||||||
Sight: 8
|
Sight: 8
|
||||||
Speed: 20
|
Speed: 20
|
||||||
AttackHeli:
|
AttackBase:
|
||||||
PrimaryWeapon: HighV
|
PrimaryWeapon: HighV
|
||||||
SecondaryWeapon: HighV
|
SecondaryWeapon: HighV
|
||||||
PrimaryOffset: -5,0,0,2
|
PrimaryOffset: -5,0,0,2
|
||||||
SecondaryOffset: 5,0,0,2
|
SecondaryOffset: 5,0,0,2
|
||||||
Helicopter:
|
# Helicopter:
|
||||||
RearmBuildings:
|
MobileAir:
|
||||||
RepairBuildings: hpad
|
MovementType: Fly
|
||||||
LandWhenIdle: no
|
|
||||||
RenderUnitRotor:
|
RenderUnitRotor:
|
||||||
PrimaryOffset: 0,0,0,-2
|
PrimaryOffset: 0,0,0,-2
|
||||||
WithShadow:
|
WithShadow:
|
||||||
@@ -466,15 +467,14 @@ ORCA:
|
|||||||
ROT: 4
|
ROT: 4
|
||||||
Sight: 8
|
Sight: 8
|
||||||
Speed: 20
|
Speed: 20
|
||||||
AttackHeli:
|
AttackBase:
|
||||||
PrimaryWeapon: Rockets.Orca
|
PrimaryWeapon: Rockets.Orca
|
||||||
SecondaryWeapon: Rockets.Orca
|
SecondaryWeapon: Rockets.Orca
|
||||||
PrimaryOffset: -5,0,0,2
|
PrimaryOffset: -5,0,0,2
|
||||||
SecondaryOffset: 5,0,0,2
|
SecondaryOffset: 5,0,0,2
|
||||||
Helicopter:
|
# Helicopter:
|
||||||
RearmBuildings:
|
MobileAir:
|
||||||
RepairBuildings: hpad
|
MovementType: Fly
|
||||||
LandWhenIdle: no
|
|
||||||
RenderUnit:
|
RenderUnit:
|
||||||
WithShadow:
|
WithShadow:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user