diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj
index 4cd3042b9a..dd0b829c82 100755
--- a/OpenRA.Game/OpenRA.Game.csproj
+++ b/OpenRA.Game/OpenRA.Game.csproj
@@ -241,6 +241,7 @@
+
diff --git a/OpenRA.Game/PathFinder.cs b/OpenRA.Game/PathFinder.cs
index 0f8c0a2b53..1384aaa0dc 100644
--- a/OpenRA.Game/PathFinder.cs
+++ b/OpenRA.Game/PathFinder.cs
@@ -31,18 +31,18 @@ namespace OpenRA
public class PathFinder
{
readonly World world;
- float[][,] passableCost = new float[4][,];
+ float[][,] passableCost = new float[5][,];
public PathFinder( World world )
{
this.world = world;
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];
for( int x = 0 ; x < map.MapSize.X ; x++ )
for( int y = 0 ; y < map.MapSize.Y ; y++ )
- for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Float; umt++ )
- passableCost[(int)umt][ x, y ] = ( world.Map.IsInMap( x, y ) )
+ for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Fly; umt++ )
+ 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])]
.GetCost(umt)
: float.PositiveInfinity;
diff --git a/OpenRA.Game/PathSearch.cs b/OpenRA.Game/PathSearch.cs
index 595d1c047c..9c56a9d061 100755
--- a/OpenRA.Game/PathSearch.cs
+++ b/OpenRA.Game/PathSearch.cs
@@ -41,7 +41,6 @@ namespace OpenRA
public bool inReverse;
BuildingInfluence buildingInfluence;
- UnitInfluence unitInfluence;
public PathSearch(Actor self)
{
@@ -53,7 +52,6 @@ namespace OpenRA
umt = self.traits.Get().GetMovementType();
buildingInfluence = world.WorldActor.traits.Get();
- unitInfluence = world.WorldActor.traits.Get();
}
public PathSearch InReverse()
@@ -114,11 +112,8 @@ namespace OpenRA
if (costHere == float.PositiveInfinity)
continue;
- if (!buildingInfluence.CanMoveHere(newHere, ignoreBuilding))
- continue;
-
var mobile = self.traits.Get();
- if (checkForBlocked && !mobile.CanEnterCell(newHere, ignoreBuilding))
+ if (checkForBlocked && !mobile.CanEnterCell(newHere, ignoreBuilding, checkForBlocked))
continue;
if (customBlock != null && customBlock(newHere))
diff --git a/OpenRA.Game/Traits/Activities/Move.cs b/OpenRA.Game/Traits/Activities/Move.cs
index 4edbee0671..f1ab35d87c 100755
--- a/OpenRA.Game/Traits/Activities/Move.cs
+++ b/OpenRA.Game/Traits/Activities/Move.cs
@@ -167,7 +167,7 @@ namespace OpenRA.Traits.Activities
{
if( path.Count == 0 ) return null;
var nextCell = path[ path.Count - 1 ];
- if( !mobile.CanEnterCell( nextCell, ignoreBuilding ) )
+ if( !mobile.CanEnterCell( nextCell, ignoreBuilding, true ) )
{
if( ( mobile.toCell - destination.Value ).LengthSquared <= nearEnough )
{
@@ -185,10 +185,13 @@ namespace OpenRA.Traits.Activities
if (--waitTicksRemaining >= 0)
return null;
- self.World.WorldActor.traits.Get().Remove( self, mobile );
+
+ //self.World.WorldActor.traits.Get().Remove( self, mobile );
+ mobile.RemoveInfluence();
var newPath = getPath(self).TakeWhile(a => a != self.Location).ToList();
- self.World.WorldActor.traits.Get().Add( self, mobile );
+ //self.World.WorldActor.traits.Get().Add( self, mobile );
+ mobile.AddInfluence();
if (newPath.Count != 0)
path = newPath;
diff --git a/OpenRA.Game/Traits/Mobile.cs b/OpenRA.Game/Traits/Mobile.cs
index 1ee6a2efb2..017e142afd 100644
--- a/OpenRA.Game/Traits/Mobile.cs
+++ b/OpenRA.Game/Traits/Mobile.cs
@@ -30,12 +30,12 @@ namespace OpenRA.Traits
public readonly int WaitAverage = 60;
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
{
- readonly Actor self;
+ public readonly Actor self;
[Sync]
int2 __fromCell, __toCell;
@@ -53,17 +53,17 @@ namespace OpenRA.Traits
void SetLocation( int2 from, int2 to )
{
if( fromCell == from && toCell == to ) return;
- self.World.WorldActor.traits.Get().Remove(self, this);
+ RemoveInfluence();
__fromCell = from;
__toCell = to;
- self.World.WorldActor.traits.Get().Add(self, this);
+ AddInfluence();
}
public Mobile(ActorInitializer init)
{
this.self = init.self;
this.__fromCell = this.__toCell = init.location;
- self.World.WorldActor.traits.Get().Add(self, this);
+ AddInfluence();
}
public void SetPosition(Actor self, int2 cell)
@@ -83,7 +83,7 @@ namespace OpenRA.Traits
{
// force-move
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().MovementType;
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 IEnumerable OccupiedCells()
+ public virtual IEnumerable OccupiedCells()
{
return (fromCell == toCell)
? new[] { fromCell }
@@ -121,27 +121,30 @@ namespace OpenRA.Traits
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().CanMoveHere(p, ignoreBuilding)) return false;
-
- var canShare = self.traits.Contains();
- var actors = self.World.WorldActor.traits.Get().GetUnitsAt(p);
- var nonshareable = actors.Where(a => a != self && !(canShare && a.traits.Contains()));
- var shareable = actors.Where(a => a != self && canShare && a.traits.Contains());
-
- // 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)))
+ if (!self.World.WorldActor.traits.Get().CanMoveHere(p, ignoreActor))
return false;
+ if (checkTransientActors)
+ {
+ var canShare = self.traits.Contains();
+ var actors = self.World.WorldActor.traits.Get().GetUnitsAt(p).Where(a => a != self && a != ignoreActor);
+ var nonshareable = actors.Where(a => !(canShare && a.traits.Contains()));
+ var shareable = actors.Where(a => canShare && a.traits.Contains());
+
+ // 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) &&
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) );
}
+
+ public virtual void AddInfluence()
+ {
+ self.World.WorldActor.traits.Get().Add( self, this );
+ }
+
+ public virtual void RemoveInfluence()
+ {
+ self.World.WorldActor.traits.Get().Remove( self, this );
+ }
}
}
diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs
index bcacb5aed3..b694e60eca 100644
--- a/OpenRA.Game/Traits/TraitsInterfaces.cs
+++ b/OpenRA.Game/Traits/TraitsInterfaces.cs
@@ -67,6 +67,12 @@ namespace OpenRA.Traits
int2 TopLeft { get; }
IEnumerable OccupiedCells();
}
+
+ public interface IOccupyAir
+ {
+ int2 TopLeft { get; }
+ IEnumerable OccupiedAirCells();
+ }
public static class IOccupySpaceExts
{
diff --git a/OpenRA.Game/Traits/World/ResourceType.cs b/OpenRA.Game/Traits/World/ResourceType.cs
index 9922334491..6cdc568f57 100644
--- a/OpenRA.Game/Traits/World/ResourceType.cs
+++ b/OpenRA.Game/Traits/World/ResourceType.cs
@@ -44,8 +44,8 @@ namespace OpenRA.Traits
public class ResourceType
{
public ResourceTypeInfo info;
- float[] movementSpeed = new float[4];
- float[] pathCost = new float[4];
+ float[] movementSpeed = new float[5];
+ float[] pathCost = new float[5];
public ResourceType(ResourceTypeInfo info)
{
@@ -56,6 +56,8 @@ namespace OpenRA.Traits
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;
}
+ movementSpeed[(int)UnitMovementType.Fly] = 1.0f;
+ pathCost[(int)UnitMovementType.Fly] = 1.0f;
this.info = info;
}
diff --git a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj
index 7d11866b4b..941fac750f 100644
--- a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj
+++ b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj
@@ -52,6 +52,7 @@
+
diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
index da3c62eace..8535ad5591 100644
--- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
+++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
@@ -1,4 +1,4 @@
-
+
Debug
diff --git a/mods/cnc/structures.yaml b/mods/cnc/structures.yaml
index bec2827142..95388f8e8c 100644
--- a/mods/cnc/structures.yaml
+++ b/mods/cnc/structures.yaml
@@ -315,7 +315,7 @@ HPAD:
Crewed: yes
Sight: 5
Bib:
- ProducesHelicopters:
+ Production:
SpawnOffset: 0,-4
Produces: Plane
BelowUnits:
diff --git a/mods/cnc/system.yaml b/mods/cnc/system.yaml
index 57c232d67c..68c9473bcd 100644
--- a/mods/cnc/system.yaml
+++ b/mods/cnc/system.yaml
@@ -1,6 +1,6 @@
Player:
ProductionQueue:
- BuildSpeed: .4
+ BuildSpeed: .004
LowPowerSlowdown: 3
PlaceBuilding:
TechTreeCache:
@@ -38,7 +38,7 @@ Player:
UnitType: a10
ConquestVictoryConditions:
PlayerResources:
- InitialCash: 5000
+ InitialCash: 500000
ActorGroupProxy:
World:
@@ -47,6 +47,7 @@ World:
# WaterPaletteRotation:
BuildingInfluence:
UnitInfluence:
+ AircraftInfluence:
# BridgeLoadHook:
Theater@DESERT:
Name:Desert
diff --git a/mods/cnc/vehicles.yaml b/mods/cnc/vehicles.yaml
index e80c0a7871..931e42fa05 100644
--- a/mods/cnc/vehicles.yaml
+++ b/mods/cnc/vehicles.yaml
@@ -406,7 +406,9 @@ TRAN:
ROT: 5
Sight: 8
Speed: 15
- Helicopter:
+# Helicopter:
+ MobileAir:
+ MovementType: Fly
RenderUnitRotor:
PrimaryOffset: 0,14,0,-4
SecondaryOffset: 0,-14,0,-2
@@ -434,15 +436,14 @@ HELI:
ROT: 4
Sight: 8
Speed: 20
- AttackHeli:
+ AttackBase:
PrimaryWeapon: HighV
SecondaryWeapon: HighV
PrimaryOffset: -5,0,0,2
SecondaryOffset: 5,0,0,2
- Helicopter:
- RearmBuildings:
- RepairBuildings: hpad
- LandWhenIdle: no
+# Helicopter:
+ MobileAir:
+ MovementType: Fly
RenderUnitRotor:
PrimaryOffset: 0,0,0,-2
WithShadow:
@@ -466,15 +467,14 @@ ORCA:
ROT: 4
Sight: 8
Speed: 20
- AttackHeli:
+ AttackBase:
PrimaryWeapon: Rockets.Orca
SecondaryWeapon: Rockets.Orca
PrimaryOffset: -5,0,0,2
SecondaryOffset: 5,0,0,2
- Helicopter:
- RearmBuildings:
- RepairBuildings: hpad
- LandWhenIdle: no
+# Helicopter:
+ MobileAir:
+ MovementType: Fly
RenderUnit:
WithShadow: