merged
This commit is contained in:
@@ -25,14 +25,14 @@ namespace OpenRa.Game
|
|||||||
influence[i, j] = NoClaim;
|
influence[i, j] = NoClaim;
|
||||||
|
|
||||||
Game.world.ActorAdded +=
|
Game.world.ActorAdded +=
|
||||||
a => { if (a.traits.Contains<Traits.Building>()) AddInfluence(a); };
|
a => { if (a.traits.Contains<Traits.Building>()) AddInfluence(a, a.traits.Get<Traits.Building>()); };
|
||||||
Game.world.ActorRemoved +=
|
Game.world.ActorRemoved +=
|
||||||
a => { if (a.traits.Contains<Traits.Building>()) RemoveInfluence(a); };
|
a => { if (a.traits.Contains<Traits.Building>()) RemoveInfluence(a, a.traits.Get<Traits.Building>()); };
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddInfluence(Actor a)
|
void AddInfluence(Actor a, Traits.Building building)
|
||||||
{
|
{
|
||||||
var tiles = Footprint.Tiles(a).ToArray();
|
var tiles = Footprint.Tiles(a, building).ToArray();
|
||||||
var min = int2.Max(new int2(0, 0),
|
var min = int2.Max(new int2(0, 0),
|
||||||
tiles.Aggregate(int2.Min) - new int2(maxDistance, maxDistance));
|
tiles.Aggregate(int2.Min) - new int2(maxDistance, maxDistance));
|
||||||
var max = int2.Min(new int2(128, 128),
|
var max = int2.Min(new int2(128, 128),
|
||||||
@@ -42,7 +42,7 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
var initialTileCount = 0;
|
var initialTileCount = 0;
|
||||||
|
|
||||||
foreach (var u in Footprint.UnpathableTiles(a.unitInfo, a.Location))
|
foreach (var u in Footprint.UnpathableTiles(building.unitInfo, a.Location))
|
||||||
if (IsValid(u))
|
if (IsValid(u))
|
||||||
blocked[u.X, u.Y] = true;
|
blocked[u.X, u.Y] = true;
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ namespace OpenRa.Game
|
|||||||
++initialTileCount;
|
++initialTileCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!((UnitInfo.BuildingInfo)a.unitInfo).BaseNormal)
|
if (!building.unitInfo.BaseNormal)
|
||||||
{
|
{
|
||||||
while (!pq.Empty)
|
while (!pq.Empty)
|
||||||
{
|
{
|
||||||
@@ -101,15 +101,15 @@ namespace OpenRa.Game
|
|||||||
Log.Write("Finished recalculating region. {0} cells updated.", updatedCells);
|
Log.Write("Finished recalculating region. {0} cells updated.", updatedCells);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveInfluence(Actor a)
|
void RemoveInfluence(Actor a, Traits.Building building)
|
||||||
{
|
{
|
||||||
var tiles = Footprint.Tiles(a).ToArray();
|
var tiles = Footprint.Tiles(a, building).ToArray();
|
||||||
var min = int2.Max(new int2(0, 0),
|
var min = int2.Max(new int2(0, 0),
|
||||||
tiles.Aggregate(int2.Min) - new int2(maxDistance, maxDistance));
|
tiles.Aggregate(int2.Min) - new int2(maxDistance, maxDistance));
|
||||||
var max = int2.Min(new int2(128, 128),
|
var max = int2.Min(new int2(128, 128),
|
||||||
tiles.Aggregate(int2.Max) + new int2(maxDistance, maxDistance));
|
tiles.Aggregate(int2.Max) + new int2(maxDistance, maxDistance));
|
||||||
|
|
||||||
foreach (var u in Footprint.UnpathableTiles(a.unitInfo, a.Location))
|
foreach (var u in Footprint.UnpathableTiles(building.unitInfo, a.Location))
|
||||||
if (IsValid(u))
|
if (IsValid(u))
|
||||||
blocked[u.X, u.Y] = false;
|
blocked[u.X, u.Y] = false;
|
||||||
|
|
||||||
@@ -131,7 +131,11 @@ namespace OpenRa.Game
|
|||||||
Log.Write("Finished collecting candidates for evacuated region = {0}", actors.Count);
|
Log.Write("Finished collecting candidates for evacuated region = {0}", actors.Count);
|
||||||
|
|
||||||
foreach( var b in actors )
|
foreach( var b in actors )
|
||||||
AddInfluence(b); /* we can actually safely constrain this a bit more... */
|
{
|
||||||
|
var bb = a.traits.GetOrDefault<Traits.Building>();
|
||||||
|
if( bb != null )
|
||||||
|
AddInfluence( b, bb );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValid(int2 t)
|
bool IsValid(int2 t)
|
||||||
|
|||||||
@@ -163,8 +163,12 @@ namespace OpenRa.Game
|
|||||||
controller.orderGenerator.Tick();
|
controller.orderGenerator.Tick();
|
||||||
|
|
||||||
if (--oreTicks == 0)
|
if (--oreTicks == 0)
|
||||||
|
{
|
||||||
using (new PerfSample("ore"))
|
using (new PerfSample("ore"))
|
||||||
map.GrowOre(SharedRandom);
|
map.GrowOre(SharedRandom);
|
||||||
|
oreTicks = oreFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
world.Tick();
|
world.Tick();
|
||||||
UnitInfluence.Tick();
|
UnitInfluence.Tick();
|
||||||
foreach (var player in players.Values)
|
foreach (var player in players.Values)
|
||||||
@@ -269,7 +273,7 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
static int2? FindAdjacentTile(Actor a, UnitMovementType umt)
|
static int2? FindAdjacentTile(Actor a, UnitMovementType umt)
|
||||||
{
|
{
|
||||||
var tiles = Footprint.Tiles(a);
|
var tiles = Footprint.Tiles(a, a.traits.Get<Traits.Building>());
|
||||||
var min = tiles.Aggregate(int2.Min) - new int2(1, 1);
|
var min = tiles.Aggregate(int2.Min) - new int2(1, 1);
|
||||||
var max = tiles.Aggregate(int2.Max) + new int2(1, 1);
|
var max = tiles.Aggregate(int2.Max) + new int2(1, 1);
|
||||||
|
|
||||||
@@ -281,18 +285,17 @@ namespace OpenRa.Game
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CanPlaceBuilding(string name, int2 xy, Actor toIgnore, bool adjust)
|
public static bool CanPlaceBuilding(UnitInfo.BuildingInfo building, int2 xy, Actor toIgnore, bool adjust)
|
||||||
{
|
{
|
||||||
var bi = (UnitInfo.BuildingInfo)Rules.UnitInfo[name];
|
return !Footprint.Tiles(building, xy, adjust).Any(
|
||||||
return !Footprint.Tiles(bi, xy, adjust).Any(
|
|
||||||
t => Game.map.ContainsResource(t) || !Game.IsCellBuildable(t,
|
t => Game.map.ContainsResource(t) || !Game.IsCellBuildable(t,
|
||||||
bi.WaterBound ? UnitMovementType.Float : UnitMovementType.Wheel,
|
building.WaterBound ? UnitMovementType.Float : UnitMovementType.Wheel,
|
||||||
toIgnore));
|
toIgnore));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CanPlaceBuilding(string name, int2 xy, bool adjust)
|
public static bool CanPlaceBuilding( UnitInfo.BuildingInfo building, int2 xy, bool adjust )
|
||||||
{
|
{
|
||||||
return CanPlaceBuilding(name, xy, null, adjust);
|
return CanPlaceBuilding(building, xy, null, adjust);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void BuildUnit(Player player, string name)
|
public static void BuildUnit(Player player, string name)
|
||||||
|
|||||||
@@ -9,14 +9,13 @@ namespace OpenRa.Game.GameRules
|
|||||||
{
|
{
|
||||||
static class Footprint
|
static class Footprint
|
||||||
{
|
{
|
||||||
public static IEnumerable<int2> Tiles( UnitInfo unitInfo, int2 position )
|
public static IEnumerable<int2> Tiles( UnitInfo.BuildingInfo buildingInfo, int2 position )
|
||||||
{
|
{
|
||||||
return Tiles(unitInfo, position, true);
|
return Tiles(buildingInfo, position, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<int2> Tiles(UnitInfo unitInfo, int2 position, bool adjustForPlacement)
|
public static IEnumerable<int2> Tiles( UnitInfo.BuildingInfo buildingInfo, int2 position, bool adjustForPlacement )
|
||||||
{
|
{
|
||||||
var buildingInfo = unitInfo as UnitInfo.BuildingInfo;
|
|
||||||
var dim = buildingInfo.Dimensions;
|
var dim = buildingInfo.Dimensions;
|
||||||
|
|
||||||
var footprint = buildingInfo.Footprint.Where(x => !char.IsWhiteSpace(x));
|
var footprint = buildingInfo.Footprint.Where(x => !char.IsWhiteSpace(x));
|
||||||
@@ -28,21 +27,19 @@ namespace OpenRa.Game.GameRules
|
|||||||
|
|
||||||
var adjustment = adjustForPlacement ? AdjustForBuildingSize(buildingInfo) : int2.Zero;
|
var adjustment = adjustForPlacement ? AdjustForBuildingSize(buildingInfo) : int2.Zero;
|
||||||
|
|
||||||
var tiles = TilesWhere(unitInfo.Name, dim, footprint.ToArray(), a => a != '_');
|
var tiles = TilesWhere(buildingInfo.Name, dim, footprint.ToArray(), a => a != '_');
|
||||||
return tiles.Select(t => t + position - adjustment);
|
return tiles.Select(t => t + position - adjustment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<int2> Tiles(Actor a)
|
public static IEnumerable<int2> Tiles(Actor a, Traits.Building building)
|
||||||
{
|
{
|
||||||
return Tiles(a.unitInfo, a.Location, false);
|
return Tiles( building.unitInfo, a.Location, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<int2> UnpathableTiles( UnitInfo unitInfo, int2 position )
|
public static IEnumerable<int2> UnpathableTiles( UnitInfo.BuildingInfo buildingInfo, int2 position )
|
||||||
{
|
{
|
||||||
var buildingInfo = unitInfo as UnitInfo.BuildingInfo;
|
|
||||||
|
|
||||||
var footprint = buildingInfo.Footprint.Where( x => !char.IsWhiteSpace( x ) ).ToArray();
|
var footprint = buildingInfo.Footprint.Where( x => !char.IsWhiteSpace( x ) ).ToArray();
|
||||||
foreach( var tile in TilesWhere( unitInfo.Name, buildingInfo.Dimensions, footprint, a => a == 'x' ) )
|
foreach( var tile in TilesWhere( buildingInfo.Name, buildingInfo.Dimensions, footprint, a => a == 'x' ) )
|
||||||
yield return tile + position;
|
yield return tile + position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,11 +55,6 @@ namespace OpenRa.Game.GameRules
|
|||||||
yield return new int2( x, y );
|
yield return new int2( x, y );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int2 AdjustForBuildingSize( string name )
|
|
||||||
{
|
|
||||||
return AdjustForBuildingSize( Rules.UnitInfo[ name ] as UnitInfo.BuildingInfo );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int2 AdjustForBuildingSize( UnitInfo.BuildingInfo unitInfo )
|
public static int2 AdjustForBuildingSize( UnitInfo.BuildingInfo unitInfo )
|
||||||
{
|
{
|
||||||
var dim = unitInfo.Dimensions;
|
var dim = unitInfo.Dimensions;
|
||||||
|
|||||||
@@ -58,8 +58,8 @@ namespace OpenRa.Game.Graphics
|
|||||||
var sprites = overlaySprites[o];
|
var sprites = overlaySprites[o];
|
||||||
var spriteIndex = 0;
|
var spriteIndex = 0;
|
||||||
if (Ore.overlayIsFence[o]) spriteIndex = NearbyFences(x, y);
|
if (Ore.overlayIsFence[o]) spriteIndex = NearbyFences(x, y);
|
||||||
else if (Ore.overlayIsOre[o]) spriteIndex = map.MapTiles[x,y].density;
|
else if (Ore.overlayIsOre[o]) spriteIndex = map.MapTiles[x,y].density - 1;
|
||||||
else if (Ore.overlayIsGems[o]) spriteIndex = map.MapTiles[x,y].density;
|
else if (Ore.overlayIsGems[o]) spriteIndex = map.MapTiles[x,y].density - 1;
|
||||||
spriteRenderer.DrawSprite(sprites[spriteIndex],
|
spriteRenderer.DrawSprite(sprites[spriteIndex],
|
||||||
Game.CellSize * (float2)location, 0);
|
Game.CellSize * (float2)location, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using IjwFramework.Types;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using OpenRa.Game.Traits;
|
using OpenRa.Game.Traits;
|
||||||
using OpenRa.Game.Support;
|
using OpenRa.Game.Support;
|
||||||
using Ijw.DirectX;
|
|
||||||
|
|
||||||
namespace OpenRa.Game.Graphics
|
namespace OpenRa.Game.Graphics
|
||||||
{
|
{
|
||||||
@@ -17,7 +16,6 @@ namespace OpenRa.Game.Graphics
|
|||||||
public readonly Region region;
|
public readonly Region region;
|
||||||
public readonly UiOverlay uiOverlay;
|
public readonly UiOverlay uiOverlay;
|
||||||
readonly Renderer renderer;
|
readonly Renderer renderer;
|
||||||
readonly Texture specialbin;
|
|
||||||
|
|
||||||
public static bool ShowUnitPaths = false;
|
public static bool ShowUnitPaths = false;
|
||||||
|
|
||||||
@@ -27,17 +25,13 @@ namespace OpenRa.Game.Graphics
|
|||||||
|
|
||||||
// TODO: this is layout policy. it belongs at a higher level than this.
|
// TODO: this is layout policy. it belongs at a higher level than this.
|
||||||
region = Region.Create(Game.viewport, DockStyle.Left,
|
region = Region.Create(Game.viewport, DockStyle.Left,
|
||||||
Game.viewport.Width - /*128*/ 0, Draw,
|
Game.viewport.Width, Draw, Game.controller.HandleMouseInput);
|
||||||
Game.controller.HandleMouseInput);
|
|
||||||
|
|
||||||
Game.viewport.AddRegion(region);
|
Game.viewport.AddRegion(region);
|
||||||
|
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
spriteRenderer = new SpriteRenderer(renderer, true);
|
spriteRenderer = new SpriteRenderer(renderer, true);
|
||||||
lineRenderer = new LineRenderer(renderer);
|
lineRenderer = new LineRenderer(renderer);
|
||||||
uiOverlay = new UiOverlay(spriteRenderer);
|
uiOverlay = new UiOverlay(spriteRenderer);
|
||||||
|
|
||||||
specialbin = renderer.LoadTexture("specialbin.png");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawSpriteList(RectangleF rect,
|
void DrawSpriteList(RectangleF rect,
|
||||||
@@ -47,11 +41,9 @@ namespace OpenRa.Game.Graphics
|
|||||||
{
|
{
|
||||||
var loc = image.b;
|
var loc = image.b;
|
||||||
|
|
||||||
if (loc.X > rect.Right || loc.X < rect.Left
|
if (loc.X > rect.Right || loc.X < rect.Left - image.a.bounds.Width)
|
||||||
- image.a.bounds.Width)
|
|
||||||
continue;
|
continue;
|
||||||
if (loc.Y > rect.Bottom || loc.Y < rect.Top
|
if (loc.Y > rect.Bottom || loc.Y < rect.Top - image.a.bounds.Height)
|
||||||
- image.a.bounds.Height)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
spriteRenderer.DrawSprite(image.a, loc, image.c);
|
spriteRenderer.DrawSprite(image.a, loc, image.c);
|
||||||
@@ -96,15 +88,13 @@ namespace OpenRa.Game.Graphics
|
|||||||
DrawSelectionBox(u, Color.Yellow, false);
|
DrawSelectionBox(u, Color.Yellow, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var uog = Game.controller.orderGenerator as UnitOrderGenerator;
|
if (Game.controller.orderGenerator != null)
|
||||||
if (uog != null)
|
Game.controller.orderGenerator.Render();
|
||||||
foreach (var a in uog.selection)
|
|
||||||
DrawSelectionBox(a, Color.White, true);
|
|
||||||
|
|
||||||
lineRenderer.Flush();
|
lineRenderer.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawSelectionBox(Actor selectedUnit, Color c, bool drawHealthBar)
|
public void DrawSelectionBox(Actor selectedUnit, Color c, bool drawHealthBar)
|
||||||
{
|
{
|
||||||
var center = selectedUnit.CenterLocation;
|
var center = selectedUnit.CenterLocation;
|
||||||
var size = selectedUnit.SelectedSize;
|
var size = selectedUnit.SelectedSize;
|
||||||
|
|||||||
@@ -8,5 +8,6 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
IEnumerable<Order> Order( int2 xy, bool lmb );
|
IEnumerable<Order> Order( int2 xy, bool lmb );
|
||||||
void Tick();
|
void Tick();
|
||||||
|
void Render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,22 +81,24 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
static byte GetOreDensity(this Map map, int i, int j)
|
static byte GetOreDensity(this Map map, int i, int j)
|
||||||
{
|
{
|
||||||
// perf fix. it's ugly, i know :(
|
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for (var u = -1; u < 2; u++)
|
for (var u = -1; u < 2; u++)
|
||||||
for (var v = -1; v < 2; v++)
|
for (var v = -1; v < 2; v++)
|
||||||
if (map.ContainsOre(i + u, j + v))
|
if (map.ContainsOre(i + u, j + v))
|
||||||
++sum;
|
++sum;
|
||||||
sum = sum * 3 / 2;
|
sum = (sum * 4 + 2) / 3;
|
||||||
if (sum > 11)
|
|
||||||
return 11;
|
|
||||||
return (byte)sum;
|
return (byte)sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte GetGemDensity(this Map map, int i, int j)
|
static byte GetGemDensity(this Map map, int i, int j)
|
||||||
{
|
{
|
||||||
return (byte)Math.Min(2, (AdjacentTiles(new int2(i, j)).Sum(
|
int sum = 0;
|
||||||
p => map.ContainsGem(p.X, p.Y) ? 1 : 0) / 3));
|
for (var u = -1; u < 2; u++)
|
||||||
|
for (var v = -1; v < 2; v++)
|
||||||
|
if (map.ContainsGem(i + u, j + v))
|
||||||
|
++sum;
|
||||||
|
sum = (sum+2) / 3; /* 3 gem units/tile is full. */
|
||||||
|
return (byte)sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool HasOverlay(this Map map, int i, int j)
|
public static bool HasOverlay(this Map map, int i, int j)
|
||||||
|
|||||||
@@ -130,7 +130,10 @@ namespace OpenRa.Game
|
|||||||
return MakeBidiPath(fromSrc, fromDest, p);
|
return MakeBidiPath(fromSrc, fromDest, p);
|
||||||
|
|
||||||
/* make some progress on the second search */
|
/* make some progress on the second search */
|
||||||
fromDest.Expand( passableCost );
|
var q = fromDest.Expand( passableCost );
|
||||||
|
|
||||||
|
if (fromSrc.cellInfo[q.X, q.Y].Seen && fromSrc.cellInfo[q.X, q.Y].MinCost < float.PositiveInfinity)
|
||||||
|
return MakeBidiPath(fromSrc, fromDest, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new List<int2>();
|
return new List<int2>();
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ namespace OpenRa.Game
|
|||||||
return cellInfo;
|
return cellInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Func<int2, float> DefaultEstimator( int2 destination )
|
public static Func<int2, float> DefaultEstimator( int2 destination )
|
||||||
{
|
{
|
||||||
return here =>
|
return here =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,28 +9,27 @@ namespace OpenRa.Game
|
|||||||
class PlaceBuilding : IOrderGenerator
|
class PlaceBuilding : IOrderGenerator
|
||||||
{
|
{
|
||||||
public readonly Player Owner;
|
public readonly Player Owner;
|
||||||
public readonly string Name;
|
public readonly UnitInfo.BuildingInfo Building;
|
||||||
|
|
||||||
public PlaceBuilding(Player owner, string name)
|
public PlaceBuilding(Player owner, string name)
|
||||||
{
|
{
|
||||||
Owner = owner;
|
Owner = owner;
|
||||||
Name = name;
|
Building = (UnitInfo.BuildingInfo)Rules.UnitInfo[ name ];
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Order> Order(int2 xy, bool lmb)
|
public IEnumerable<Order> Order(int2 xy, bool lmb)
|
||||||
{
|
{
|
||||||
if( lmb )
|
if( lmb )
|
||||||
{
|
{
|
||||||
if (!Game.CanPlaceBuilding(Name, xy, true))
|
if( !Game.CanPlaceBuilding( Building, xy, true ) )
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
var bi = (UnitInfo.BuildingInfo)Rules.UnitInfo[Name];
|
var maxDistance = Building.Adjacent + 2; /* real-ra is weird. this is 1 GAP. */
|
||||||
var maxDistance = bi.Adjacent + 2; /* real-ra is weird. this is 1 GAP. */
|
if( !Footprint.Tiles( Building, xy ).Any(
|
||||||
if( !Footprint.Tiles( bi, xy ).Any(
|
|
||||||
t => Game.GetDistanceToBase( t, Owner ) < maxDistance ) )
|
t => Game.GetDistanceToBase( t, Owner ) < maxDistance ) )
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
yield return OpenRa.Game.Order.PlaceBuilding( Owner, xy, Name );
|
yield return OpenRa.Game.Order.PlaceBuilding( Owner, xy, Building.Name );
|
||||||
}
|
}
|
||||||
else // rmb
|
else // rmb
|
||||||
{
|
{
|
||||||
@@ -41,8 +40,13 @@ namespace OpenRa.Game
|
|||||||
public void Tick()
|
public void Tick()
|
||||||
{
|
{
|
||||||
var producing = Owner.Producing( "Building" );
|
var producing = Owner.Producing( "Building" );
|
||||||
if( producing == null || producing.Item != Name || producing.RemainingTime != 0 )
|
if( producing == null || producing.Item != Building.Name || producing.RemainingTime != 0 )
|
||||||
Game.world.AddFrameEndTask( _ => { Game.controller.orderGenerator = null; } );
|
Game.world.AddFrameEndTask( _ => { Game.controller.orderGenerator = null; } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Render()
|
||||||
|
{
|
||||||
|
Game.worldRenderer.uiOverlay.DrawBuildingGrid( Building );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace OpenRa.Game.Traits
|
|||||||
var harvester = new Actor("harv", self.Location + new int2(1, 2), self.Owner);
|
var harvester = new Actor("harv", self.Location + new int2(1, 2), self.Owner);
|
||||||
var mobile = harvester.traits.Get<Mobile>();
|
var mobile = harvester.traits.Get<Mobile>();
|
||||||
mobile.facing = 64;
|
mobile.facing = 64;
|
||||||
mobile.InternalSetActivity(new Harvest());
|
mobile.QueueActivity(new Harvest());
|
||||||
w.Add(harvester);
|
w.Add(harvester);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,20 +19,13 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
|
|
||||||
public IActivity NextActivity { get; set; }
|
public IActivity NextActivity { get; set; }
|
||||||
|
|
||||||
public void Tick(Actor self, Mobile mobile)
|
public IActivity Tick( Actor self, Mobile mobile )
|
||||||
{
|
{
|
||||||
if (Target.IsDead)
|
if (Target == null || Target.IsDead)
|
||||||
{
|
return NextActivity;
|
||||||
mobile.InternalSetActivity(NextActivity);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((Target.Location - self.Location).LengthSquared >= Range * Range)
|
if ((Target.Location - self.Location).LengthSquared >= Range * Range)
|
||||||
{
|
return new Move( Target, Range ) { NextActivity = this };
|
||||||
mobile.InternalSetActivity(new Move(Target, Range));
|
|
||||||
mobile.QueueActivity(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var desiredFacing = Util.GetFacing((Target.Location - self.Location).ToFloat2(), 0);
|
var desiredFacing = Util.GetFacing((Target.Location - self.Location).ToFloat2(), 0);
|
||||||
var renderUnit = self.traits.WithInterface<RenderUnit>().First();
|
var renderUnit = self.traits.WithInterface<RenderUnit>().First();
|
||||||
@@ -40,19 +33,18 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
if (Util.QuantizeFacing(mobile.facing, renderUnit.anim.CurrentSequence.Length)
|
if (Util.QuantizeFacing(mobile.facing, renderUnit.anim.CurrentSequence.Length)
|
||||||
!= Util.QuantizeFacing(desiredFacing, renderUnit.anim.CurrentSequence.Length))
|
!= Util.QuantizeFacing(desiredFacing, renderUnit.anim.CurrentSequence.Length))
|
||||||
{
|
{
|
||||||
mobile.InternalSetActivity(new Turn(desiredFacing));
|
return new Turn( desiredFacing ) { NextActivity = this };
|
||||||
mobile.QueueActivity(this);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var attack = self.traits.WithInterface<AttackBase>().First();
|
var attack = self.traits.WithInterface<AttackBase>().First();
|
||||||
attack.target = Target;
|
attack.target = Target;
|
||||||
attack.DoAttack(self);
|
attack.DoAttack(self);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cancel(Actor self, Mobile mobile)
|
public void Cancel(Actor self, Mobile mobile)
|
||||||
{
|
{
|
||||||
mobile.InternalSetActivity(null);
|
Target = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
bool isDone;
|
bool isDone;
|
||||||
Actor refinery;
|
Actor refinery;
|
||||||
|
|
||||||
|
public DeliverOre() { }
|
||||||
|
|
||||||
public DeliverOre( Actor refinery )
|
public DeliverOre( Actor refinery )
|
||||||
{
|
{
|
||||||
this.refinery = refinery;
|
this.refinery = refinery;
|
||||||
@@ -19,45 +21,59 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
|
|
||||||
static readonly int2 refineryDeliverOffset = new int2( 1, 2 );
|
static readonly int2 refineryDeliverOffset = new int2( 1, 2 );
|
||||||
|
|
||||||
public void Tick(Actor self, Mobile mobile)
|
public IActivity Tick( Actor self, Mobile mobile )
|
||||||
{
|
{
|
||||||
if( self.Location != refinery.Location + refineryDeliverOffset )
|
if( isDone )
|
||||||
{
|
{
|
||||||
var move = new Move( refinery.Location + refineryDeliverOffset, 0 );
|
self.traits.Get<Harvester>().Deliver( self );
|
||||||
mobile.InternalSetActivity( move );
|
return NextActivity ?? new Harvest();
|
||||||
mobile.QueueActivity( this );
|
}
|
||||||
move.Tick( self, mobile );
|
else if( NextActivity != null )
|
||||||
return;
|
return NextActivity;
|
||||||
|
|
||||||
|
if( refinery != null && refinery.IsDead )
|
||||||
|
refinery = null;
|
||||||
|
|
||||||
|
if( refinery == null || self.Location != refinery.Location + refineryDeliverOffset )
|
||||||
|
{
|
||||||
|
var search = new PathSearch
|
||||||
|
{
|
||||||
|
heuristic = PathSearch.DefaultEstimator( self.Location ),
|
||||||
|
umt = mobile.GetMovementType(),
|
||||||
|
checkForBlocked = false,
|
||||||
|
};
|
||||||
|
var refineries = Game.world.Actors.Where( x => x.unitInfo != null && x.unitInfo.Name == "proc" ).ToList();
|
||||||
|
if( refinery != null )
|
||||||
|
search.AddInitialCell( refinery.Location + refineryDeliverOffset );
|
||||||
|
else
|
||||||
|
foreach( var r in refineries )
|
||||||
|
search.AddInitialCell( r.Location + refineryDeliverOffset );
|
||||||
|
|
||||||
|
var path = Game.PathFinder.FindPath( search );
|
||||||
|
path.Reverse();
|
||||||
|
if( path.Count != 0 )
|
||||||
|
{
|
||||||
|
refinery = refineries.FirstOrDefault( x => x.Location + refineryDeliverOffset == path[ 0 ] );
|
||||||
|
return new Move( () => path ) { NextActivity = this };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// no refineries reachable?
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
else if( mobile.facing != 64 )
|
else if( mobile.facing != 64 )
|
||||||
{
|
return new Turn( 64 ) { NextActivity = this };
|
||||||
var turn = new Turn( 64 );
|
|
||||||
mobile.InternalSetActivity( turn );
|
|
||||||
mobile.QueueActivity( this );
|
|
||||||
turn.Tick( self, mobile );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (isDone)
|
|
||||||
{
|
|
||||||
var harv = self.traits.Get<Harvester>();
|
|
||||||
|
|
||||||
harv.Deliver(self);
|
|
||||||
|
|
||||||
if( NextActivity == null )
|
|
||||||
NextActivity = new Harvest();
|
|
||||||
mobile.InternalSetActivity(NextActivity);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var renderUnit = self.traits.WithInterface<RenderUnit>().First();
|
var renderUnit = self.traits.WithInterface<RenderUnit>().First();
|
||||||
if( renderUnit.anim.CurrentSequence.Name != "empty" )
|
if( renderUnit.anim.CurrentSequence.Name != "empty" )
|
||||||
renderUnit.PlayCustomAnimation( self, "empty",
|
renderUnit.PlayCustomAnimation( self, "empty",
|
||||||
() => isDone = true );
|
() => isDone = true );
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cancel(Actor self, Mobile mobile)
|
public void Cancel(Actor self, Mobile mobile)
|
||||||
{
|
{
|
||||||
mobile.InternalSetActivity(null);
|
// TODO: allow canceling of deliver orders?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,14 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
{
|
{
|
||||||
public IActivity NextActivity { get; set; }
|
public IActivity NextActivity { get; set; }
|
||||||
|
|
||||||
public void Tick( Actor self, Mobile mobile )
|
public IActivity Tick( Actor self, Mobile mobile )
|
||||||
{
|
{
|
||||||
Game.world.AddFrameEndTask( _ =>
|
Game.world.AddFrameEndTask( _ =>
|
||||||
{
|
{
|
||||||
Game.world.Remove( self );
|
Game.world.Remove( self );
|
||||||
Game.world.Add( new Actor( "fact", self.Location - new int2( 1, 1 ), self.Owner ) );
|
Game.world.Add( new Actor( "fact", self.Location - new int2( 1, 1 ), self.Owner ) );
|
||||||
} );
|
} );
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cancel( Actor self, Mobile mobile )
|
public void Cancel( Actor self, Mobile mobile )
|
||||||
|
|||||||
@@ -18,24 +18,20 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
|
|
||||||
public IActivity NextActivity { get; set; }
|
public IActivity NextActivity { get; set; }
|
||||||
|
|
||||||
public void Tick(Actor self, Mobile mobile)
|
public IActivity Tick( Actor self, Mobile mobile )
|
||||||
{
|
{
|
||||||
if (Target.IsDead)
|
if (Target == null || Target.IsDead)
|
||||||
{
|
return NextActivity;
|
||||||
mobile.InternalSetActivity(NextActivity);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ( Target.Location - self.Location ).LengthSquared >= Range * Range )
|
if( ( Target.Location - self.Location ).LengthSquared >= Range * Range )
|
||||||
{
|
return new Move( Target, Range ) { NextActivity = this };
|
||||||
mobile.InternalSetActivity(new Move(Target, Range));
|
|
||||||
mobile.QueueActivity(this);
|
return null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cancel(Actor self, Mobile mobile)
|
public void Cancel(Actor self, Mobile mobile)
|
||||||
{
|
{
|
||||||
mobile.InternalSetActivity(null);
|
Target = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,20 +10,20 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
public IActivity NextActivity { get; set; }
|
public IActivity NextActivity { get; set; }
|
||||||
bool isHarvesting = false;
|
bool isHarvesting = false;
|
||||||
|
|
||||||
public void Tick(Actor self, Mobile mobile)
|
public IActivity Tick( Actor self, Mobile mobile )
|
||||||
{
|
{
|
||||||
|
if( isHarvesting ) return null;
|
||||||
|
|
||||||
if( NextActivity != null )
|
if( NextActivity != null )
|
||||||
{
|
return NextActivity;
|
||||||
mobile.InternalSetActivity( NextActivity );
|
|
||||||
NextActivity.Tick( self, mobile );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var harv = self.traits.Get<Harvester>();
|
var harv = self.traits.Get<Harvester>();
|
||||||
var isGem = false;
|
|
||||||
|
|
||||||
if (!harv.IsFull &&
|
if( harv.IsFull )
|
||||||
Game.map.ContainsResource(self.Location) &&
|
return new DeliverOre { NextActivity = NextActivity };
|
||||||
|
|
||||||
|
var isGem = false;
|
||||||
|
if( Game.map.ContainsResource( self.Location ) &&
|
||||||
Game.map.Harvest( self.Location, out isGem ) )
|
Game.map.Harvest( self.Location, out isGem ) )
|
||||||
{
|
{
|
||||||
var harvestAnim = "harvest" + Util.QuantizeFacing( mobile.facing, 8 );
|
var harvestAnim = "harvest" + Util.QuantizeFacing( mobile.facing, 8 );
|
||||||
@@ -34,43 +34,9 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
renderUnit.PlayCustomAnimation( self, harvestAnim, () => isHarvesting = false );
|
renderUnit.PlayCustomAnimation( self, harvestAnim, () => isHarvesting = false );
|
||||||
}
|
}
|
||||||
harv.AcceptResource( isGem );
|
harv.AcceptResource( isGem );
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHarvesting) return;
|
|
||||||
|
|
||||||
if (harv.IsFull)
|
|
||||||
PlanReturnToBase(self, mobile);
|
|
||||||
else
|
else
|
||||||
PlanMoreHarvesting(self, mobile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* maybe this doesnt really belong here, since it's the
|
|
||||||
* same as what UnitOrders has to do for an explicit return */
|
|
||||||
|
|
||||||
void PlanReturnToBase(Actor self, Mobile mobile)
|
|
||||||
{
|
|
||||||
/* find a proc */
|
|
||||||
var proc = ChooseReturnLocation(self);
|
|
||||||
if( proc != null )
|
|
||||||
mobile.QueueActivity( new DeliverOre( proc ) );
|
|
||||||
|
|
||||||
mobile.InternalSetActivity(NextActivity);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Actor ChooseReturnLocation(Actor self)
|
|
||||||
{
|
|
||||||
/* todo: compute paths to possible procs, taking into account enemy presence */
|
|
||||||
/* currently, we're good at choosing close, inaccessible procs */
|
|
||||||
|
|
||||||
return Game.world.Actors.Where(
|
|
||||||
a => a.Owner == self.Owner &&
|
|
||||||
a.traits.Contains<AcceptsOre>())
|
|
||||||
.OrderBy(p => (p.Location - self.Location).LengthSquared)
|
|
||||||
.FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlanMoreHarvesting(Actor self, Mobile mobile)
|
|
||||||
{
|
{
|
||||||
mobile.QueueActivity( new Move(
|
mobile.QueueActivity( new Move(
|
||||||
() =>
|
() =>
|
||||||
@@ -85,7 +51,8 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
return Game.PathFinder.FindPath( search );
|
return Game.PathFinder.FindPath( search );
|
||||||
} ) );
|
} ) );
|
||||||
mobile.QueueActivity( new Harvest() );
|
mobile.QueueActivity( new Harvest() );
|
||||||
mobile.InternalSetActivity( NextActivity );
|
return NextActivity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cancel(Actor self, Mobile mobile) { }
|
public void Cancel(Actor self, Mobile mobile) { }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
interface IActivity
|
interface IActivity
|
||||||
{
|
{
|
||||||
IActivity NextActivity { get; set; }
|
IActivity NextActivity { get; set; }
|
||||||
void Tick( Actor self, Mobile mobile );
|
IActivity Tick( Actor self, Mobile mobile );
|
||||||
void Cancel( Actor self, Mobile mobile );
|
void Cancel( Actor self, Mobile mobile );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRa.Game.GameRules;
|
using OpenRa.Game.GameRules;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace OpenRa.Game.Traits.Activities
|
namespace OpenRa.Game.Traits.Activities
|
||||||
{
|
{
|
||||||
@@ -48,43 +49,42 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
return (u == null || u == self);
|
return (u == null || u == self);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Tick( Actor self, Mobile mobile )
|
public IActivity Tick( Actor self, Mobile mobile )
|
||||||
{
|
{
|
||||||
if( move != null )
|
if( move != null )
|
||||||
{
|
{
|
||||||
move.TickMove( self, mobile, this );
|
move.TickMove( self, mobile, this );
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( destination == self.Location )
|
if( destination == self.Location )
|
||||||
{
|
return NextActivity;
|
||||||
mobile.InternalSetActivity( NextActivity );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( path == null ) path = getPath( self, mobile ).TakeWhile( a => a != self.Location ).ToList();
|
if( path == null )
|
||||||
|
{
|
||||||
|
path = getPath( self, mobile ).TakeWhile( a => a != self.Location ).ToList();
|
||||||
|
SanityCheckPath( mobile );
|
||||||
|
}
|
||||||
|
|
||||||
if( path.Count == 0 )
|
if( path.Count == 0 )
|
||||||
{
|
{
|
||||||
destination = mobile.toCell;
|
destination = mobile.toCell;
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
destination = path[ 0 ];
|
destination = path[ 0 ];
|
||||||
|
|
||||||
var nextCell = PopPath( self, mobile );
|
var nextCell = PopPath( self, mobile );
|
||||||
if( nextCell == null )
|
if( nextCell == null )
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
int2 dir = nextCell.Value - mobile.fromCell;
|
int2 dir = nextCell.Value - mobile.fromCell;
|
||||||
var firstFacing = Util.GetFacing( dir, mobile.facing );
|
var firstFacing = Util.GetFacing( dir, mobile.facing );
|
||||||
if( firstFacing != mobile.facing )
|
if( firstFacing != mobile.facing )
|
||||||
{
|
{
|
||||||
var t = new Turn( firstFacing ) { NextActivity = this };
|
|
||||||
mobile.InternalSetActivity( t );
|
|
||||||
path.Add( nextCell.Value );
|
path.Add( nextCell.Value );
|
||||||
|
|
||||||
t.Tick( self, mobile );
|
return new Turn( firstFacing ) { NextActivity = this };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -99,9 +99,21 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
Game.UnitInfluence.Update( mobile );
|
Game.UnitInfluence.Update( mobile );
|
||||||
|
|
||||||
move.TickMove( self, mobile, this );
|
move.TickMove( self, mobile, this );
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Conditional( "SANITY_CHECKS")]
|
||||||
|
void SanityCheckPath( Mobile mobile )
|
||||||
|
{
|
||||||
|
if( path.Count == 0 )
|
||||||
|
return;
|
||||||
|
var d = path[path.Count-1] - mobile.toCell;
|
||||||
|
if( d.LengthSquared > 2 )
|
||||||
|
throw new InvalidOperationException( "(Move) Sanity check failed" );
|
||||||
|
}
|
||||||
|
|
||||||
int2? PopPath( Actor self, Mobile mobile )
|
int2? PopPath( Actor self, Mobile mobile )
|
||||||
{
|
{
|
||||||
if( path.Count == 0 ) return null;
|
if( path.Count == 0 ) return null;
|
||||||
|
|||||||
@@ -16,16 +16,13 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
this.desiredFacing = desiredFacing;
|
this.desiredFacing = desiredFacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Tick( Actor self, Mobile mobile )
|
public IActivity Tick( Actor self, Mobile mobile )
|
||||||
{
|
{
|
||||||
if( desiredFacing == mobile.facing )
|
if( desiredFacing == mobile.facing )
|
||||||
{
|
return NextActivity;
|
||||||
mobile.InternalSetActivity( NextActivity );
|
|
||||||
if( NextActivity != null )
|
|
||||||
NextActivity.Tick( self, mobile );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Util.TickFacing( ref mobile.facing, desiredFacing, self.unitInfo.ROT );
|
Util.TickFacing( ref mobile.facing, desiredFacing, self.unitInfo.ROT );
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cancel( Actor self, Mobile mobile )
|
public void Cancel( Actor self, Mobile mobile )
|
||||||
|
|||||||
@@ -8,8 +8,11 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
class Building : ITick, INotifyBuildComplete
|
class Building : ITick, INotifyBuildComplete
|
||||||
{
|
{
|
||||||
|
public readonly UnitInfo.BuildingInfo unitInfo;
|
||||||
|
|
||||||
public Building(Actor self)
|
public Building(Actor self)
|
||||||
{
|
{
|
||||||
|
unitInfo = (UnitInfo.BuildingInfo)self.unitInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
@@ -23,10 +26,7 @@ namespace OpenRa.Game.Traits
|
|||||||
|
|
||||||
public void BuildingComplete(Actor self)
|
public void BuildingComplete(Actor self)
|
||||||
{
|
{
|
||||||
UnitInfo.BuildingInfo bi = self.unitInfo as UnitInfo.BuildingInfo;
|
self.Owner.ChangePower(unitInfo.Power);
|
||||||
if (bi == null) return;
|
|
||||||
|
|
||||||
self.Owner.ChangePower(bi.Power);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
if (lmb) return null;
|
if (lmb) return null;
|
||||||
|
|
||||||
if (xy == self.Location)
|
if( xy != self.Location ) return null;
|
||||||
return OpenRa.Game.Order.DeployMcv(self, !Game.CanPlaceBuilding("fact", xy - new int2(1,1), self, false));
|
|
||||||
|
|
||||||
return null;
|
var factBuildingInfo = (UnitInfo.BuildingInfo)Rules.UnitInfo[ "fact" ];
|
||||||
|
return OpenRa.Game.Order.DeployMcv(self, !Game.CanPlaceBuilding(factBuildingInfo, xy - new int2(1,1), self, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,17 +42,20 @@ namespace OpenRa.Game.Traits
|
|||||||
act.NextActivity = nextActivity;
|
act.NextActivity = nextActivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InternalSetActivity( IActivity activity )
|
|
||||||
{
|
|
||||||
currentActivity = activity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Tick(Actor self)
|
public void Tick(Actor self)
|
||||||
{
|
{
|
||||||
if( currentActivity != null )
|
if( currentActivity == null )
|
||||||
currentActivity.Tick( self, this );
|
{
|
||||||
else
|
|
||||||
fromCell = toCell;
|
fromCell = toCell;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nextActivity = currentActivity;
|
||||||
|
while( nextActivity != null )
|
||||||
|
{
|
||||||
|
currentActivity = nextActivity;
|
||||||
|
nextActivity = nextActivity.Tick( self, this );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Order Order(Actor self, int2 xy, bool lmb, Actor underCursor)
|
public Order Order(Actor self, int2 xy, bool lmb, Actor underCursor)
|
||||||
@@ -81,10 +84,19 @@ namespace OpenRa.Game.Traits
|
|||||||
|
|
||||||
public UnitMovementType GetMovementType()
|
public UnitMovementType GetMovementType()
|
||||||
{
|
{
|
||||||
var vi = self.unitInfo as UnitInfo.VehicleInfo;
|
switch( Rules.UnitCategory[ self.unitInfo.Name ] )
|
||||||
if (vi == null) return UnitMovementType.Foot;
|
{
|
||||||
if (vi.WaterBound) return UnitMovementType.Float;
|
case "Infantry":
|
||||||
return vi.Tracked ? UnitMovementType.Track : UnitMovementType.Wheel;
|
return UnitMovementType.Foot;
|
||||||
|
case "Vehicle":
|
||||||
|
return ( self.unitInfo as UnitInfo.VehicleInfo ).Tracked ? UnitMovementType.Track : UnitMovementType.Wheel;
|
||||||
|
case "Ship":
|
||||||
|
return UnitMovementType.Float;
|
||||||
|
case "Plane":
|
||||||
|
return UnitMovementType.Track; // FIXME: remove this when planes actually fly.
|
||||||
|
default:
|
||||||
|
throw new InvalidOperationException( "GetMovementType on unit that shouldn't be aable to move." );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<int2> GetCurrentPath()
|
public IEnumerable<int2> GetCurrentPath()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace OpenRa.Game.Traits
|
|||||||
|
|
||||||
public RallyPoint(Actor self)
|
public RallyPoint(Actor self)
|
||||||
{
|
{
|
||||||
var bi = (UnitInfo.BuildingInfo)self.unitInfo;
|
var bi = self.traits.Get<Building>().unitInfo;
|
||||||
rallyPoint = self.Location + new int2(bi.RallyPoint[0], bi.RallyPoint[1]);
|
rallyPoint = self.Location + new int2(bi.RallyPoint[0], bi.RallyPoint[1]);
|
||||||
anim = new Animation("flagfly");
|
anim = new Animation("flagfly");
|
||||||
anim.PlayRepeating("idle");
|
anim.PlayRepeating("idle");
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ namespace OpenRa.Game.Traits
|
|||||||
|
|
||||||
void DoBib(Actor self, bool isRemove)
|
void DoBib(Actor self, bool isRemove)
|
||||||
{
|
{
|
||||||
var buildingInfo = (UnitInfo.BuildingInfo)self.unitInfo;
|
var buildingInfo = self.traits.Get<Building>().unitInfo;
|
||||||
if (buildingInfo.Bib)
|
if (buildingInfo.Bib)
|
||||||
{
|
{
|
||||||
var size = buildingInfo.Dimensions.X;
|
var size = buildingInfo.Dimensions.X;
|
||||||
|
|||||||
@@ -41,14 +41,12 @@ namespace OpenRa.Game
|
|||||||
for (var i = 0; i < 128; i++)
|
for (var i = 0; i < 128; i++)
|
||||||
if (Game.UnitInfluence.GetUnitAt(new int2(i, j)) != null)
|
if (Game.UnitInfluence.GetUnitAt(new int2(i, j)) != null)
|
||||||
spriteRenderer.DrawSprite(unitDebug, Game.CellSize * new float2(i, j), 0);
|
spriteRenderer.DrawSprite(unitDebug, Game.CellSize * new float2(i, j), 0);
|
||||||
|
}
|
||||||
|
|
||||||
var placeBuilding = Game.controller.orderGenerator as PlaceBuilding;
|
public void DrawBuildingGrid( UnitInfo.BuildingInfo bi )
|
||||||
if (placeBuilding == null) return;
|
{
|
||||||
|
|
||||||
var position = Game.controller.MousePosition.ToInt2();
|
var position = Game.controller.MousePosition.ToInt2();
|
||||||
|
|
||||||
var bi = (UnitInfo.BuildingInfo)Rules.UnitInfo[placeBuilding.Name];
|
|
||||||
|
|
||||||
var maxDistance = bi.Adjacent + 2; /* real-ra is weird. this is 1 GAP. */
|
var maxDistance = bi.Adjacent + 2; /* real-ra is weird. this is 1 GAP. */
|
||||||
|
|
||||||
if( ShowBuildDebug )
|
if( ShowBuildDebug )
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
public void Tick()
|
public void Tick()
|
||||||
{
|
{
|
||||||
SanityCheck();
|
//SanityCheck();
|
||||||
|
|
||||||
var units = Game.world.Actors
|
//var units = Game.world.Actors
|
||||||
.Select( a => a.traits.GetOrDefault<Traits.Mobile>() ).Where( m => m != null );
|
// .Select( a => a.traits.GetOrDefault<Traits.Mobile>() ).Where( m => m != null );
|
||||||
|
|
||||||
foreach (var u in units)
|
//foreach (var u in units)
|
||||||
Update(u);
|
// Update(u);
|
||||||
|
|
||||||
SanityCheck();
|
SanityCheck();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
@@ -28,5 +28,11 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
selection.RemoveAll(a => a.IsDead);
|
selection.RemoveAll(a => a.IsDead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Render()
|
||||||
|
{
|
||||||
|
foreach( var a in selection )
|
||||||
|
Game.worldRenderer.DrawSelectionBox( a, Color.White, true );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ namespace OpenRa.Game
|
|||||||
}
|
}
|
||||||
case "DeployMcv":
|
case "DeployMcv":
|
||||||
{
|
{
|
||||||
if (!Game.CanPlaceBuilding("fact", order.Subject.Location - new int2(1,1), order.Subject, false))
|
var factBuildingInfo = (UnitInfo.BuildingInfo)Rules.UnitInfo[ "fact" ];
|
||||||
|
if( !Game.CanPlaceBuilding( factBuildingInfo, order.Subject.Location - new int2( 1, 1 ), order.Subject, false ) )
|
||||||
break; /* throw the order on the floor */
|
break; /* throw the order on the floor */
|
||||||
|
|
||||||
var mobile = order.Subject.traits.Get<Mobile>();
|
var mobile = order.Subject.traits.Get<Mobile>();
|
||||||
@@ -77,14 +78,14 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
Game.world.AddFrameEndTask( _ =>
|
Game.world.AddFrameEndTask( _ =>
|
||||||
{
|
{
|
||||||
var building = Rules.UnitInfo[ order.TargetString ];
|
var building = (UnitInfo.BuildingInfo)Rules.UnitInfo[ order.TargetString ];
|
||||||
var producing = order.Player.Producing( "Building" );
|
var producing = order.Player.Producing( "Building" );
|
||||||
if( producing == null || producing.Item != order.TargetString || producing.RemainingTime != 0 )
|
if( producing == null || producing.Item != order.TargetString || producing.RemainingTime != 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Log.Write( "Player \"{0}\" builds {1}", order.Player.PlayerName, building.Name );
|
Log.Write( "Player \"{0}\" builds {1}", order.Player.PlayerName, building.Name );
|
||||||
|
|
||||||
Game.world.Add( new Actor( building.Name, order.TargetLocation - GameRules.Footprint.AdjustForBuildingSize( building.Name ), order.Player ) );
|
Game.world.Add( new Actor( building.Name, order.TargetLocation - GameRules.Footprint.AdjustForBuildingSize( building ), order.Player ) );
|
||||||
|
|
||||||
order.Player.FinishProduction(Rules.UnitCategory[building.Name]);
|
order.Player.FinishProduction(Rules.UnitCategory[building.Name]);
|
||||||
} );
|
} );
|
||||||
@@ -99,7 +100,7 @@ namespace OpenRa.Game
|
|||||||
* ( 25 * 60 ) /* frames per min */ /* todo: build acceleration, if we do that */
|
* ( 25 * 60 ) /* frames per min */ /* todo: build acceleration, if we do that */
|
||||||
/ 1000;
|
/ 1000;
|
||||||
|
|
||||||
time = .05f * time; /* temporary hax so we can build stuff fast for test */
|
time = .01f * time; /* temporary hax so we can build stuff fast for test */
|
||||||
|
|
||||||
order.Player.BeginProduction(group,
|
order.Player.BeginProduction(group,
|
||||||
new ProductionItem(order.TargetString, (int)time, ui.Cost,
|
new ProductionItem(order.TargetString, (int)time, ui.Cost,
|
||||||
|
|||||||
@@ -259,8 +259,9 @@
|
|||||||
<!-- v2 rocket launcher -->
|
<!-- v2 rocket launcher -->
|
||||||
<unit name="v2rl">
|
<unit name="v2rl">
|
||||||
<sequence name="idle" start="0" length="32" />
|
<sequence name="idle" start="0" length="32" />
|
||||||
<sequence name="reloading" start="32" length="32" />
|
<sequence name="empty-idle" start="32" length="32" />
|
||||||
<sequence name="aiming" start="64" length="16" />
|
<sequence name="aim" start="64" length="8" />
|
||||||
|
<sequence name="empty-aim" start="72" length="8" />
|
||||||
</unit>
|
</unit>
|
||||||
<!-- artillery -->
|
<!-- artillery -->
|
||||||
<unit name="arty">
|
<unit name="arty">
|
||||||
|
|||||||
Reference in New Issue
Block a user