merged
This commit is contained in:
@@ -8,8 +8,9 @@ namespace OpenRa.FileFormats
|
|||||||
{
|
{
|
||||||
public readonly Dictionary<ushort, Terrain> tiles = new Dictionary<ushort, Terrain>();
|
public readonly Dictionary<ushort, Terrain> tiles = new Dictionary<ushort, Terrain>();
|
||||||
|
|
||||||
readonly Dictionary<ushort, Dictionary<int, int>> walk =
|
public readonly Walkability Walkability = new Walkability();
|
||||||
new Dictionary<ushort, Dictionary<int, int>>(); // cjf will fix
|
public readonly Dictionary<ushort, TileTemplate> walk
|
||||||
|
= new Dictionary<ushort, TileTemplate>();
|
||||||
|
|
||||||
string NextLine( StreamReader reader )
|
string NextLine( StreamReader reader )
|
||||||
{
|
{
|
||||||
@@ -27,7 +28,7 @@ namespace OpenRa.FileFormats
|
|||||||
|
|
||||||
public TileSet( string suffix )
|
public TileSet( string suffix )
|
||||||
{
|
{
|
||||||
Walkability walkability = new Walkability();
|
Walkability = new Walkability();
|
||||||
|
|
||||||
char tileSetChar = char.ToUpperInvariant( suffix[ 1 ] );
|
char tileSetChar = char.ToUpperInvariant( suffix[ 1 ] );
|
||||||
StreamReader tileIdFile = new StreamReader( FileSystem.Open( "tileSet.til" ) );
|
StreamReader tileIdFile = new StreamReader( FileSystem.Open( "tileSet.til" ) );
|
||||||
@@ -51,7 +52,7 @@ namespace OpenRa.FileFormats
|
|||||||
string tilename = string.Format(pattern, i + 1);
|
string tilename = string.Format(pattern, i + 1);
|
||||||
|
|
||||||
if (!walk.ContainsKey((ushort)(start + i)))
|
if (!walk.ContainsKey((ushort)(start + i)))
|
||||||
walk.Add((ushort)(start + i), walkability.GetWalkability(tilename));
|
walk.Add((ushort)(start + i), Walkability.GetWalkability(tilename));
|
||||||
|
|
||||||
using( Stream s = FileSystem.Open( tilename + suffix ) )
|
using( Stream s = FileSystem.Open( tilename + suffix ) )
|
||||||
{
|
{
|
||||||
@@ -82,7 +83,7 @@ namespace OpenRa.FileFormats
|
|||||||
if (r.tile == 0xff || r.tile == 0xffff)
|
if (r.tile == 0xff || r.tile == 0xffff)
|
||||||
r.image = 0;
|
r.image = 0;
|
||||||
|
|
||||||
return walk[r.tile][r.image];
|
return walk[r.tile].TerrainType[r.image];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,51 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace OpenRa.FileFormats
|
namespace OpenRa.FileFormats
|
||||||
{
|
{
|
||||||
|
public class TileTemplate
|
||||||
|
{
|
||||||
|
public int Index;
|
||||||
|
public string Name;
|
||||||
|
public int2 Size;
|
||||||
|
public string Bridge;
|
||||||
|
public float HP;
|
||||||
|
public Dictionary<int, int> TerrainType = new Dictionary<int, int>();
|
||||||
|
}
|
||||||
|
|
||||||
public class Walkability
|
public class Walkability
|
||||||
{
|
{
|
||||||
Dictionary<string, Dictionary<int, int>> walkability =
|
Dictionary<string, TileTemplate> walkability
|
||||||
new Dictionary<string, Dictionary<int, int>>();
|
= new Dictionary<string,TileTemplate>();
|
||||||
|
|
||||||
public Walkability()
|
public Walkability()
|
||||||
{
|
{
|
||||||
IniFile file = new IniFile( FileSystem.Open( "templates.ini" ) );
|
var file = new IniFile( FileSystem.Open( "templates.ini" ) );
|
||||||
Regex pattern = new Regex(@"tiletype(\d+)");
|
|
||||||
|
|
||||||
foreach (IniSection section in file.Sections)
|
foreach (var section in file.Sections)
|
||||||
{
|
{
|
||||||
string name = section.GetValue("Name", null).ToLowerInvariant();
|
var tile = new TileTemplate
|
||||||
|
|
||||||
Dictionary<int, int> tileWalkability = new Dictionary<int, int>();
|
|
||||||
foreach (KeyValuePair<string, string> p in section)
|
|
||||||
{
|
{
|
||||||
Match m = pattern.Match(p.Key);
|
Size = new int2(
|
||||||
if (m != null && m.Success)
|
int.Parse(section.GetValue("width", "0")),
|
||||||
tileWalkability.Add(int.Parse(m.Groups[1].Value), int.Parse(p.Value));
|
int.Parse(section.GetValue("height", "0"))),
|
||||||
}
|
TerrainType = section
|
||||||
|
.Where(p => p.Key.StartsWith("tiletype"))
|
||||||
|
.ToDictionary(
|
||||||
|
p => int.Parse(p.Key.Substring(8)),
|
||||||
|
p => int.Parse(p.Value)),
|
||||||
|
Name = section.GetValue("Name", null).ToLowerInvariant(),
|
||||||
|
Index = int.Parse(section.Name.Substring(3)),
|
||||||
|
Bridge = section.GetValue("bridge", null),
|
||||||
|
HP = float.Parse(section.GetValue("hp", "0"))
|
||||||
|
};
|
||||||
|
|
||||||
walkability[name] = tileWalkability;
|
walkability[tile.Name] = tile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<int, int> GetWalkability(string terrainName)
|
public TileTemplate GetWalkability(string terrainName)
|
||||||
{
|
{
|
||||||
return walkability[terrainName];
|
return walkability[terrainName];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ namespace OpenRa
|
|||||||
|
|
||||||
public bool IsDead { get { return Health <= 0; } }
|
public bool IsDead { get { return Health <= 0; } }
|
||||||
public bool IsInWorld { get; set; }
|
public bool IsInWorld { get; set; }
|
||||||
|
public bool RemoveOnDeath = true;
|
||||||
|
|
||||||
public DamageState GetDamageState()
|
public DamageState GetDamageState()
|
||||||
{
|
{
|
||||||
@@ -145,6 +146,7 @@ namespace OpenRa
|
|||||||
if (attacker.Owner != null)
|
if (attacker.Owner != null)
|
||||||
attacker.Owner.Kills++;
|
attacker.Owner.Kills++;
|
||||||
|
|
||||||
|
if (RemoveOnDeath)
|
||||||
Game.world.AddFrameEndTask(w => w.Remove(this));
|
Game.world.AddFrameEndTask(w => w.Remove(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
67
OpenRa.Game/Bridges.cs
Normal file
67
OpenRa.Game/Bridges.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using OpenRa.Traits;
|
||||||
|
|
||||||
|
namespace OpenRa
|
||||||
|
{
|
||||||
|
static class Bridges
|
||||||
|
{
|
||||||
|
public static void MakeBridges(World w)
|
||||||
|
{
|
||||||
|
var mini = w.Map.XOffset; var maxi = w.Map.XOffset + w.Map.Width;
|
||||||
|
var minj = w.Map.YOffset; var maxj = w.Map.YOffset + w.Map.Height;
|
||||||
|
|
||||||
|
for (var j = minj; j < maxj; j++)
|
||||||
|
for (var i = mini; i < maxi; i++)
|
||||||
|
if (IsBridge(w, w.Map.MapTiles[i, j].tile))
|
||||||
|
ConvertBridgeToActor(w, i, j);
|
||||||
|
|
||||||
|
foreach (var br in w.Actors.SelectMany(a => a.traits.WithInterface<Bridge>()))
|
||||||
|
br.FinalizeBridges(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ConvertBridgeToActor(World w, int i, int j)
|
||||||
|
{
|
||||||
|
var tile = w.Map.MapTiles[i, j].tile;
|
||||||
|
var image = w.Map.MapTiles[i, j].image;
|
||||||
|
var template = w.TileSet.walk[tile];
|
||||||
|
|
||||||
|
// base position of the tile
|
||||||
|
var ni = i - image % template.Size.X;
|
||||||
|
var nj = j - image / template.Size.X;
|
||||||
|
|
||||||
|
var replacedTiles = new Dictionary<int2, int>();
|
||||||
|
for (var y = nj; y < nj + template.Size.Y; y++)
|
||||||
|
for (var x = ni; x < ni + template.Size.X; x++)
|
||||||
|
{
|
||||||
|
var n = (x - ni) + template.Size.X * (y - nj);
|
||||||
|
if (!template.TerrainType.ContainsKey(n)) continue;
|
||||||
|
|
||||||
|
if (w.Map.IsInMap(x, y))
|
||||||
|
if (w.Map.MapTiles[x, y].tile == tile
|
||||||
|
&& w.Map.MapTiles[x,y].image == n)
|
||||||
|
{
|
||||||
|
// stash it
|
||||||
|
replacedTiles[new int2(x, y)] = w.Map.MapTiles[x, y].image;
|
||||||
|
// remove the tile from the actual map
|
||||||
|
w.Map.MapTiles[x, y].tile = 0xfffe;
|
||||||
|
w.Map.MapTiles[x, y].image = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replacedTiles.Any())
|
||||||
|
{
|
||||||
|
var a = w.CreateActor(template.Bridge, new int2(ni, nj), null);
|
||||||
|
var br = a.traits.Get<Bridge>();
|
||||||
|
br.SetTiles(w, template, replacedTiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsBridge(World w, ushort t)
|
||||||
|
{
|
||||||
|
return w.TileSet.walk[t].Bridge != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -58,6 +58,7 @@ namespace OpenRa
|
|||||||
FileSystem.UnmountTemporaryPackages();
|
FileSystem.UnmountTemporaryPackages();
|
||||||
Rules.LoadRules(mapName, usingAftermath);
|
Rules.LoadRules(mapName, usingAftermath);
|
||||||
|
|
||||||
|
world = null; // trying to access the old world will NRE, rather than silently doing it wrong.
|
||||||
world = new World();
|
world = new World();
|
||||||
Game.world.ActorAdded += a =>
|
Game.world.ActorAdded += a =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ namespace OpenRa.Graphics
|
|||||||
if (terrainTypeColors == null)
|
if (terrainTypeColors == null)
|
||||||
{
|
{
|
||||||
var pal = new Palette(FileSystem.Open(world.Map.Theater + ".pal"));
|
var pal = new Palette(FileSystem.Open(world.Map.Theater + ".pal"));
|
||||||
terrainTypeColors = new[] {theater.ToLowerInvariant() == "snow" ? 0xe3 :0x1a, 0x63, 0x2f, 0x1f, 0x14, 0x64, 0x1f, 0x68, 0x6b, 0x6d }
|
terrainTypeColors = new[] {
|
||||||
|
theater.ToLowerInvariant() == "snow" ? 0xe3 :0x1a,
|
||||||
|
0x63, 0x2f, 0x1f, 0x14, 0x64, 0x1f, 0x68, 0x6b, 0x6d, 0x88 }
|
||||||
.Select( a => Color.FromArgb(alpha, pal.GetColor(a) )).ToArray();
|
.Select( a => Color.FromArgb(alpha, pal.GetColor(a) )).ToArray();
|
||||||
|
|
||||||
playerColors = Util.MakeArray<Color>( 8, b => Color.FromArgb(alpha, Chat.paletteColors[b]) );
|
playerColors = Util.MakeArray<Color>( 8, b => Color.FromArgb(alpha, Chat.paletteColors[b]) );
|
||||||
|
|||||||
@@ -107,8 +107,6 @@ namespace OpenRa.Graphics
|
|||||||
|
|
||||||
public static Sprite GetImageFromCollection(Renderer renderer,string collection, string image)
|
public static Sprite GetImageFromCollection(Renderer renderer,string collection, string image)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
// Cached sprite
|
// Cached sprite
|
||||||
if (cachedSprites.ContainsKey(collection) && cachedSprites[collection].ContainsKey(image))
|
if (cachedSprites.ContainsKey(collection) && cachedSprites[collection].ContainsKey(image))
|
||||||
return cachedSprites[collection][image];
|
return cachedSprites[collection][image];
|
||||||
|
|||||||
@@ -77,6 +77,7 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Bridges.cs" />
|
||||||
<Compile Include="Chat.cs" />
|
<Compile Include="Chat.cs" />
|
||||||
<Compile Include="Chrome.cs" />
|
<Compile Include="Chrome.cs" />
|
||||||
<Compile Include="Combat.cs" />
|
<Compile Include="Combat.cs" />
|
||||||
@@ -210,6 +211,7 @@
|
|||||||
<Compile Include="Traits\AutoHeal.cs" />
|
<Compile Include="Traits\AutoHeal.cs" />
|
||||||
<Compile Include="Traits\AutoTarget.cs" />
|
<Compile Include="Traits\AutoTarget.cs" />
|
||||||
<Compile Include="Traits\BelowUnits.cs" />
|
<Compile Include="Traits\BelowUnits.cs" />
|
||||||
|
<Compile Include="Traits\Bridge.cs" />
|
||||||
<Compile Include="Traits\Buildable.cs" />
|
<Compile Include="Traits\Buildable.cs" />
|
||||||
<Compile Include="Traits\Building.cs" />
|
<Compile Include="Traits\Building.cs" />
|
||||||
<Compile Include="Traits\Cargo.cs" />
|
<Compile Include="Traits\Cargo.cs" />
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ namespace OpenRa.Orders
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
State = ConnectionState.NotConnected;
|
State = ConnectionState.NotConnected;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using OpenRa.FileFormats;
|
using OpenRa.FileFormats;
|
||||||
using OpenRa.Support;
|
using OpenRa.Support;
|
||||||
using OpenRa.Traits;
|
using OpenRa.Traits;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace OpenRa
|
namespace OpenRa
|
||||||
{
|
{
|
||||||
@@ -143,9 +144,7 @@ namespace OpenRa
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Conditional( "SANITY_CHECKS" )]
|
||||||
|
|
||||||
[System.Diagnostics.Conditional( "SANITY_CHECKS" )]
|
|
||||||
static void CheckSanePath( List<int2> path )
|
static void CheckSanePath( List<int2> path )
|
||||||
{
|
{
|
||||||
if( path.Count == 0 )
|
if( path.Count == 0 )
|
||||||
@@ -160,7 +159,7 @@ namespace OpenRa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[System.Diagnostics.Conditional("SANITY_CHECKS")]
|
[Conditional("SANITY_CHECKS")]
|
||||||
static void CheckSanePath2(List<int2> path, int2 src, int2 dest)
|
static void CheckSanePath2(List<int2> path, int2 src, int2 dest)
|
||||||
{
|
{
|
||||||
if (path.Count == 0)
|
if (path.Count == 0)
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ namespace OpenRa
|
|||||||
public UnitMovementType umt;
|
public UnitMovementType umt;
|
||||||
Func<int2, bool> customBlock;
|
Func<int2, bool> customBlock;
|
||||||
public bool checkForBlocked;
|
public bool checkForBlocked;
|
||||||
public bool ignoreTerrain;
|
|
||||||
public Actor ignoreBuilding;
|
public Actor ignoreBuilding;
|
||||||
|
|
||||||
public PathSearch()
|
public PathSearch()
|
||||||
@@ -40,8 +39,12 @@ namespace OpenRa
|
|||||||
var p = queue.Pop();
|
var p = queue.Pop();
|
||||||
cellInfo[ p.Location.X, p.Location.Y ].Seen = true;
|
cellInfo[ p.Location.X, p.Location.Y ].Seen = true;
|
||||||
|
|
||||||
if (!ignoreTerrain)
|
var custom2 = Game.world.customTerrain[p.Location.X, p.Location.Y];
|
||||||
if (passableCost[(int)umt][p.Location.X, p.Location.Y] == float.PositiveInfinity)
|
var thisCost = (custom2 != null)
|
||||||
|
? custom2.GetCost(p.Location, umt)
|
||||||
|
: passableCost[(int)umt][p.Location.X, p.Location.Y];
|
||||||
|
|
||||||
|
if (thisCost == float.PositiveInfinity)
|
||||||
return p.Location;
|
return p.Location;
|
||||||
|
|
||||||
foreach( int2 d in Util.directions )
|
foreach( int2 d in Util.directions )
|
||||||
@@ -52,16 +55,17 @@ namespace OpenRa
|
|||||||
if( cellInfo[ newHere.X, newHere.Y ].Seen )
|
if( cellInfo[ newHere.X, newHere.Y ].Seen )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!ignoreTerrain)
|
var custom = Game.world.customTerrain[newHere.X, newHere.Y];
|
||||||
{
|
var costHere = (custom != null) ? custom.GetCost(newHere, umt) : passableCost[(int)umt][newHere.X, newHere.Y];
|
||||||
if (passableCost[(int)umt][newHere.X, newHere.Y] == float.PositiveInfinity)
|
|
||||||
|
if (costHere == float.PositiveInfinity)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!Game.world.BuildingInfluence.CanMoveHere(newHere) &&
|
if (!Game.world.BuildingInfluence.CanMoveHere(newHere) &&
|
||||||
Game.world.BuildingInfluence.GetBuildingAt(newHere) != ignoreBuilding)
|
Game.world.BuildingInfluence.GetBuildingAt(newHere) != ignoreBuilding)
|
||||||
continue;
|
continue;
|
||||||
if (Game.world.Map.IsOverlaySolid(newHere))
|
if (Game.world.Map.IsOverlaySolid(newHere))
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// Replicate real-ra behavior of not being able to enter a cell if there is a mixture of crushable and uncrushable units
|
// Replicate real-ra behavior of not being able to enter a cell if there is a mixture of crushable and uncrushable units
|
||||||
if (checkForBlocked && (Game.world.UnitInfluence.GetUnitsAt(newHere).Any(a => !Game.world.IsActorPathableToCrush(a, umt))))
|
if (checkForBlocked && (Game.world.UnitInfluence.GetUnitsAt(newHere).Any(a => !Game.world.IsActorPathableToCrush(a, umt))))
|
||||||
@@ -70,13 +74,11 @@ namespace OpenRa
|
|||||||
if (customBlock != null && customBlock(newHere))
|
if (customBlock != null && customBlock(newHere))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
var est = heuristic( newHere );
|
var est = heuristic( newHere );
|
||||||
if( est == float.PositiveInfinity )
|
if( est == float.PositiveInfinity )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float cellCost = ( ( d.X * d.Y != 0 ) ? 1.414213563f : 1.0f ) *
|
float cellCost = ((d.X * d.Y != 0) ? 1.414213563f : 1.0f) * costHere;
|
||||||
(ignoreTerrain ? 1 : passableCost[ (int)umt ][ newHere.X, newHere.Y ]);
|
|
||||||
float newCost = cellInfo[ p.Location.X, p.Location.Y ].MinCost + cellCost;
|
float newCost = cellInfo[ p.Location.X, p.Location.Y ].MinCost + cellCost;
|
||||||
|
|
||||||
if( newCost >= cellInfo[ newHere.X, newHere.Y ].MinCost )
|
if( newCost >= cellInfo[ newHere.X, newHere.Y ].MinCost )
|
||||||
|
|||||||
@@ -23,28 +23,29 @@ namespace OpenRa
|
|||||||
Wall = 7,
|
Wall = 7,
|
||||||
Beach = 8,
|
Beach = 8,
|
||||||
Ore = 9,
|
Ore = 9,
|
||||||
|
Special = 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
static class TerrainCosts
|
static class TerrainCosts
|
||||||
{
|
{
|
||||||
static double[][] costs = Util.MakeArray<double[]>( 4,
|
static float[][] costs = Util.MakeArray<float[]>(4,
|
||||||
a => Util.MakeArray<double>( 10, b => double.PositiveInfinity ));
|
a => Util.MakeArray<float>(11, b => float.PositiveInfinity));
|
||||||
|
|
||||||
static TerrainCosts()
|
static TerrainCosts()
|
||||||
{
|
{
|
||||||
for( int i = 0 ; i < 10 ; i++ )
|
for( int i = 0 ; i < 11 ; i++ )
|
||||||
{
|
{
|
||||||
if( i == 4 ) continue;
|
if( i == 4 ) continue;
|
||||||
var section = Rules.AllRules.GetSection( ( (TerrainMovementType)i ).ToString() );
|
var section = Rules.AllRules.GetSection( ( (TerrainMovementType)i ).ToString() );
|
||||||
for( int j = 0 ; j < 4 ; j++ )
|
for( int j = 0 ; j < 4 ; j++ )
|
||||||
{
|
{
|
||||||
string val = section.GetValue( ( (UnitMovementType)j ).ToString(), "0%" );
|
string val = section.GetValue( ( (UnitMovementType)j ).ToString(), "0%" );
|
||||||
costs[ j ][ i ] = 100.0 / double.Parse( val.Substring( 0, val.Length - 1 ) );
|
costs[j][i] = 100f / float.Parse(val.Substring(0, val.Length - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double Cost( UnitMovementType unitMovementType, int r )
|
public static float Cost( UnitMovementType unitMovementType, int r )
|
||||||
{
|
{
|
||||||
return costs[ (byte)unitMovementType ][ r ];
|
return costs[ (byte)unitMovementType ][ r ];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,8 +180,18 @@ namespace OpenRa.Traits
|
|||||||
if (self == underCursor) return null;
|
if (self == underCursor) return null;
|
||||||
|
|
||||||
var isHeal = self.GetPrimaryWeapon().Damage < 0;
|
var isHeal = self.GetPrimaryWeapon().Damage < 0;
|
||||||
if (((underCursor.Owner == self.Owner) ^ isHeal)
|
var forceFire = mi.Modifiers.HasModifier(Modifiers.Ctrl);
|
||||||
&& !mi.Modifiers.HasModifier( Modifiers.Ctrl )) return null;
|
|
||||||
|
if (isHeal)
|
||||||
|
{
|
||||||
|
if (underCursor.Owner == null)
|
||||||
|
return null;
|
||||||
|
if (underCursor.Owner != self.Owner && !forceFire)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if ((underCursor.Owner == self.Owner || underCursor.Owner == null) && !forceFire)
|
||||||
|
return null;
|
||||||
|
|
||||||
if (!Combat.HasAnyValidWeapons(self, underCursor)) return null;
|
if (!Combat.HasAnyValidWeapons(self, underCursor)) return null;
|
||||||
|
|
||||||
|
|||||||
158
OpenRa.Game/Traits/Bridge.cs
Normal file
158
OpenRa.Game/Traits/Bridge.cs
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using OpenRa.Graphics;
|
||||||
|
using OpenRa.FileFormats;
|
||||||
|
using IjwFramework.Collections;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace OpenRa.Traits
|
||||||
|
{
|
||||||
|
class BridgeInfo : ITraitInfo
|
||||||
|
{
|
||||||
|
public readonly bool Long = false;
|
||||||
|
public readonly bool UseAlternateNames = false;
|
||||||
|
public readonly int[] NorthOffset = null;
|
||||||
|
public readonly int[] SouthOffset = null;
|
||||||
|
public object Create(Actor self) { return new Bridge(self); }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Bridge : IRender, ICustomTerrain, INotifyDamage
|
||||||
|
{
|
||||||
|
Dictionary<int2, int> Tiles;
|
||||||
|
List<Dictionary<int2, Sprite>> TileSprites = new List<Dictionary<int2,Sprite>>();
|
||||||
|
List<TileTemplate> Templates = new List<TileTemplate>();
|
||||||
|
Actor self;
|
||||||
|
int state;
|
||||||
|
|
||||||
|
Bridge northNeighbour, southNeighbour;
|
||||||
|
|
||||||
|
public Bridge(Actor self) { this.self = self; self.RemoveOnDeath = false; }
|
||||||
|
|
||||||
|
static string cachedTheater;
|
||||||
|
static Cache<TileReference, Sprite> sprites;
|
||||||
|
|
||||||
|
public IEnumerable<Renderable> Render(Actor self)
|
||||||
|
{
|
||||||
|
foreach (var t in TileSprites[state])
|
||||||
|
yield return new Renderable(t.Value, Game.CellSize * t.Key, PaletteType.Gold);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int StateFromTemplate(TileTemplate t)
|
||||||
|
{
|
||||||
|
var info = self.Info.Traits.Get<BridgeInfo>();
|
||||||
|
if (info.UseAlternateNames)
|
||||||
|
{
|
||||||
|
if (t.Name.EndsWith("d")) return 2;
|
||||||
|
if (t.Name.EndsWith("h")) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return t.Name[t.Name.Length - 1] - 'a';
|
||||||
|
}
|
||||||
|
|
||||||
|
public string NameFromState(TileTemplate t, int state)
|
||||||
|
{
|
||||||
|
var info = self.Info.Traits.Get<BridgeInfo>();
|
||||||
|
if (info.UseAlternateNames)
|
||||||
|
return t.Bridge + new[] { "", "h", "d" }[state];
|
||||||
|
else
|
||||||
|
return t.Bridge + (char)(state + 'a');
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTiles(World world, TileTemplate template, Dictionary<int2, int> replacedTiles)
|
||||||
|
{
|
||||||
|
Tiles = replacedTiles;
|
||||||
|
state = StateFromTemplate(template);
|
||||||
|
|
||||||
|
foreach (var t in replacedTiles.Keys)
|
||||||
|
world.customTerrain[t.X, t.Y] = this;
|
||||||
|
|
||||||
|
if (cachedTheater != world.Map.Theater)
|
||||||
|
{
|
||||||
|
cachedTheater = world.Map.Theater;
|
||||||
|
sprites = new Cache<TileReference, Sprite>(
|
||||||
|
x => SheetBuilder.Add(world.TileSet.GetBytes(x),
|
||||||
|
new Size(Game.CellSize, Game.CellSize)));
|
||||||
|
}
|
||||||
|
|
||||||
|
var numStates = self.Info.Traits.Get<BridgeInfo>().Long ? 6 : 3;
|
||||||
|
for (var n = 0; n < numStates; n++)
|
||||||
|
{
|
||||||
|
var stateTemplate = world.TileSet.Walkability.GetWalkability(NameFromState(template, n));
|
||||||
|
Templates.Add( stateTemplate );
|
||||||
|
|
||||||
|
TileSprites.Add(replacedTiles.ToDictionary(
|
||||||
|
a => a.Key,
|
||||||
|
a => sprites[new TileReference { tile = (ushort)stateTemplate.Index, image = (byte)a.Value }]));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Health = (int)(self.GetMaxHP() * template.HP);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bridge GetNeighbor(World world, int[] offset)
|
||||||
|
{
|
||||||
|
if (offset == null) return null;
|
||||||
|
var pos = self.Location + new int2(offset[0], offset[1]);
|
||||||
|
if (!world.Map.IsInMap(pos.X, pos.Y)) return null;
|
||||||
|
return world.customTerrain[pos.X, pos.Y] as Bridge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FinalizeBridges(World world)
|
||||||
|
{
|
||||||
|
// go looking for our neighbors, if this is a long bridge.
|
||||||
|
var info = self.Info.Traits.Get<BridgeInfo>();
|
||||||
|
if (info.NorthOffset != null)
|
||||||
|
northNeighbour = GetNeighbor(world, info.NorthOffset);
|
||||||
|
if (info.SouthOffset != null)
|
||||||
|
southNeighbour = GetNeighbor(world, info.SouthOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float GetCost(int2 p, UnitMovementType umt)
|
||||||
|
{
|
||||||
|
// just use the standard walkability from templates.ini. no hackery.
|
||||||
|
|
||||||
|
return TerrainCosts.Cost(umt,
|
||||||
|
Templates[state].TerrainType[Tiles[p]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsIntact(Bridge b)
|
||||||
|
{
|
||||||
|
return b != null && b.self.IsInWorld && b.self.Health > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsLong(Bridge b)
|
||||||
|
{
|
||||||
|
return b != null && b.self.IsInWorld && b.self.Info.Traits.Get<BridgeInfo>().Long;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateState()
|
||||||
|
{
|
||||||
|
var ds = self.GetDamageState();
|
||||||
|
if (!self.Info.Traits.Get<BridgeInfo>().Long)
|
||||||
|
{
|
||||||
|
state = (int)ds;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool waterToSouth = !IsIntact(southNeighbour) && (!IsLong(southNeighbour) || !IsIntact(this));
|
||||||
|
bool waterToNorth = !IsIntact(northNeighbour) && (!IsLong(northNeighbour) || !IsIntact(this));
|
||||||
|
|
||||||
|
if (waterToSouth && waterToNorth) { state = 5; return; }
|
||||||
|
if (waterToNorth) { state = 4; return; }
|
||||||
|
if (waterToSouth) { state = 3; return; }
|
||||||
|
state = (int)ds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Damaged(Actor self, AttackInfo e)
|
||||||
|
{
|
||||||
|
if (e.DamageStateChanged)
|
||||||
|
{
|
||||||
|
UpdateState();
|
||||||
|
if (northNeighbour != null) northNeighbour.UpdateState();
|
||||||
|
if (southNeighbour != null) southNeighbour.UpdateState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ namespace OpenRa.Traits
|
|||||||
public readonly int[] SpawnOffset = null;
|
public readonly int[] SpawnOffset = null;
|
||||||
public readonly string[] Produces = { };
|
public readonly string[] Produces = { };
|
||||||
|
|
||||||
public object Create(Actor self) { return new Production(self); }
|
public virtual object Create(Actor self) { return new Production(self); }
|
||||||
}
|
}
|
||||||
|
|
||||||
class Production : IIssueOrder, IResolveOrder, IProducer, ITags
|
class Production : IIssueOrder, IResolveOrder, IProducer, ITags
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ using OpenRa.GameRules;
|
|||||||
|
|
||||||
namespace OpenRa.Traits
|
namespace OpenRa.Traits
|
||||||
{
|
{
|
||||||
class ProductionSurroundInfo : ITraitInfo
|
class ProductionSurroundInfo : ProductionInfo
|
||||||
{
|
{
|
||||||
public object Create(Actor self) { return new ProductionSurround(self); }
|
public override object Create(Actor self) { return new ProductionSurround(self); }
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProductionSurround : Production
|
class ProductionSurround : Production
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ namespace OpenRa.Traits
|
|||||||
public interface IAcceptThief { void OnSteal(Actor self, Actor thief); }
|
public interface IAcceptThief { void OnSteal(Actor self, Actor thief); }
|
||||||
public interface IAcceptSpy { void OnInfiltrate(Actor self, Actor spy); }
|
public interface IAcceptSpy { void OnInfiltrate(Actor self, Actor spy); }
|
||||||
|
|
||||||
|
public interface ICustomTerrain { float GetCost(int2 p, UnitMovementType umt); }
|
||||||
|
|
||||||
interface IProducer
|
interface IProducer
|
||||||
{
|
{
|
||||||
bool Produce( Actor self, ActorInfo producee );
|
bool Produce( Actor self, ActorInfo producee );
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using OpenRa.Effects;
|
|||||||
using OpenRa.Support;
|
using OpenRa.Support;
|
||||||
using OpenRa.FileFormats;
|
using OpenRa.FileFormats;
|
||||||
using OpenRa.Graphics;
|
using OpenRa.Graphics;
|
||||||
|
using OpenRa.Traits;
|
||||||
|
|
||||||
namespace OpenRa
|
namespace OpenRa
|
||||||
{
|
{
|
||||||
@@ -21,6 +22,9 @@ namespace OpenRa
|
|||||||
public readonly Map Map;
|
public readonly Map Map;
|
||||||
public readonly TileSet TileSet;
|
public readonly TileSet TileSet;
|
||||||
|
|
||||||
|
// for tricky things like bridges.
|
||||||
|
public readonly ICustomTerrain[,] customTerrain = new ICustomTerrain[128, 128];
|
||||||
|
|
||||||
public readonly WorldRenderer WorldRenderer;
|
public readonly WorldRenderer WorldRenderer;
|
||||||
internal readonly Minimap Minimap;
|
internal readonly Minimap Minimap;
|
||||||
|
|
||||||
@@ -40,10 +44,11 @@ namespace OpenRa
|
|||||||
oreTicks = oreFrequency;
|
oreTicks = oreFrequency;
|
||||||
Map.InitOreDensity();
|
Map.InitOreDensity();
|
||||||
|
|
||||||
PathFinder = new PathFinder(this);
|
|
||||||
|
|
||||||
CreateActor("World", new int2(int.MaxValue, int.MaxValue), null);
|
CreateActor("World", new int2(int.MaxValue, int.MaxValue), null);
|
||||||
|
|
||||||
|
Bridges.MakeBridges(this);
|
||||||
|
PathFinder = new PathFinder(this);
|
||||||
|
|
||||||
WorldRenderer = new WorldRenderer(this, Game.renderer);
|
WorldRenderer = new WorldRenderer(this, Game.renderer);
|
||||||
Minimap = new Minimap(this, Game.renderer);
|
Minimap = new Minimap(this, Game.renderer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace OpenRa.Mods.RA
|
|||||||
if (!underCursor.traits.Contains<Building>()) return null;
|
if (!underCursor.traits.Contains<Building>()) return null;
|
||||||
|
|
||||||
// todo: other bits
|
// todo: other bits
|
||||||
|
if (underCursor.Owner == null) return null; // don't allow capturing of bridges, etc.
|
||||||
|
|
||||||
return new Order(underCursor.Health <= EngineerDamage ? "Capture" : "Infiltrate",
|
return new Order(underCursor.Health <= EngineerDamage ? "Capture" : "Infiltrate",
|
||||||
self, underCursor, int2.Zero, null);
|
self, underCursor, int2.Zero, null);
|
||||||
|
|||||||
@@ -138,6 +138,10 @@ namespace RulesConverter
|
|||||||
{ "Produces", "Produces" } }
|
{ "Produces", "Produces" } }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ "ProductionSurround", new PL {
|
||||||
|
{ "Produces", "Produces" } }
|
||||||
|
},
|
||||||
|
|
||||||
{ "Minelayer", new PL {
|
{ "Minelayer", new PL {
|
||||||
{ "Mine", "Primary" } }
|
{ "Mine", "Primary" } }
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -28,3 +28,23 @@ MINV:
|
|||||||
Warhead: ATMine
|
Warhead: ATMine
|
||||||
TriggeredBy: Wheel, Track
|
TriggeredBy: Wheel, Track
|
||||||
AvoidFriendly: yes
|
AvoidFriendly: yes
|
||||||
|
|
||||||
|
BR1:
|
||||||
|
Bridge:
|
||||||
|
SouthOffset:0,2
|
||||||
|
BR2:
|
||||||
|
Bridge:
|
||||||
|
NorthOffset:3,0
|
||||||
|
BR3:
|
||||||
|
Bridge:
|
||||||
|
Long: yes
|
||||||
|
NorthOffset: 2,0
|
||||||
|
SouthOffset: 0,1
|
||||||
|
|
||||||
|
BRIDGE1:
|
||||||
|
Bridge:
|
||||||
|
UseAlternateNames: yes
|
||||||
|
|
||||||
|
BRIDGE2:
|
||||||
|
Bridge:
|
||||||
|
UseAlternateNames: yes
|
||||||
|
|||||||
59
ra.yaml
59
ra.yaml
@@ -83,6 +83,63 @@ MINV:
|
|||||||
-Selectable:
|
-Selectable:
|
||||||
-Building:
|
-Building:
|
||||||
|
|
||||||
|
BR1:
|
||||||
|
Bridge:
|
||||||
|
SouthOffset: 0,2
|
||||||
|
Category: Building
|
||||||
|
Selectable:
|
||||||
|
BelowUnits:
|
||||||
|
Building:
|
||||||
|
Footprint: ____ ____
|
||||||
|
Dimensions: 4,2
|
||||||
|
HP: 1000
|
||||||
|
|
||||||
|
BR2:
|
||||||
|
Bridge:
|
||||||
|
NorthOffset: 3,0
|
||||||
|
Category: Building
|
||||||
|
Selectable:
|
||||||
|
BelowUnits:
|
||||||
|
Building:
|
||||||
|
Footprint: ____ ____
|
||||||
|
Dimensions: 4,2
|
||||||
|
HP: 1000
|
||||||
|
|
||||||
|
BR3:
|
||||||
|
Bridge:
|
||||||
|
Long: yes
|
||||||
|
NorthOffset: 2,0
|
||||||
|
SouthOffset: 0,1
|
||||||
|
Category: Building
|
||||||
|
Selectable:
|
||||||
|
BelowUnits:
|
||||||
|
Building:
|
||||||
|
Footprint: ____ ____
|
||||||
|
Dimensions: 4,2
|
||||||
|
HP: 1000
|
||||||
|
|
||||||
|
BRIDGE1:
|
||||||
|
Bridge:
|
||||||
|
UseAlternateNames: yes
|
||||||
|
Category: Building
|
||||||
|
Selectable:
|
||||||
|
BelowUnits:
|
||||||
|
Building:
|
||||||
|
Footprint: _____ _____ _____
|
||||||
|
Dimensions: 5,3
|
||||||
|
HP: 1000
|
||||||
|
|
||||||
|
BRIDGE2:
|
||||||
|
Bridge:
|
||||||
|
UseAlternateNames: yes
|
||||||
|
Category: Building
|
||||||
|
Selectable:
|
||||||
|
BelowUnits:
|
||||||
|
Building:
|
||||||
|
Footprint: _____ _____
|
||||||
|
Dimensions: 5,2
|
||||||
|
HP: 1000
|
||||||
|
|
||||||
V2RL:
|
V2RL:
|
||||||
Inherits: ^Vehicle
|
Inherits: ^Vehicle
|
||||||
Buildable:
|
Buildable:
|
||||||
@@ -999,6 +1056,7 @@ SYRD:
|
|||||||
Sight: 4
|
Sight: 4
|
||||||
RenderBuilding:
|
RenderBuilding:
|
||||||
ProductionSurround:
|
ProductionSurround:
|
||||||
|
Produces: Ship
|
||||||
IronCurtainable:
|
IronCurtainable:
|
||||||
|
|
||||||
SPEN:
|
SPEN:
|
||||||
@@ -1023,6 +1081,7 @@ SPEN:
|
|||||||
Sight: 4
|
Sight: 4
|
||||||
RenderBuilding:
|
RenderBuilding:
|
||||||
ProductionSurround:
|
ProductionSurround:
|
||||||
|
Produces: Ship
|
||||||
IronCurtainable:
|
IronCurtainable:
|
||||||
|
|
||||||
FACT:
|
FACT:
|
||||||
|
|||||||
@@ -2525,6 +2525,14 @@ Wheel=0%
|
|||||||
Float=0%
|
Float=0%
|
||||||
Buildable=no
|
Buildable=no
|
||||||
|
|
||||||
|
; special tile for bridge hacks
|
||||||
|
[Special]
|
||||||
|
Foot=100%
|
||||||
|
Track=100%
|
||||||
|
Wheel=100%
|
||||||
|
Float=100%
|
||||||
|
Buildable=no
|
||||||
|
|
||||||
|
|
||||||
; ******* Random Crate Powerups *******
|
; ******* Random Crate Powerups *******
|
||||||
; This specifies the chance for the specified crate powerup to appear
|
; This specifies the chance for the specified crate powerup to appear
|
||||||
|
|||||||
@@ -1533,6 +1533,8 @@ tiletype8=0
|
|||||||
Name=BRIDGE1
|
Name=BRIDGE1
|
||||||
width=5
|
width=5
|
||||||
height=3
|
height=3
|
||||||
|
bridge=bridge1
|
||||||
|
hp=1
|
||||||
tiletype1=3
|
tiletype1=3
|
||||||
tiletype2=2
|
tiletype2=2
|
||||||
tiletype3=2
|
tiletype3=2
|
||||||
@@ -1548,6 +1550,8 @@ tiletype12=3
|
|||||||
Name=BRIDGE1D
|
Name=BRIDGE1D
|
||||||
width=5
|
width=5
|
||||||
height=3
|
height=3
|
||||||
|
bridge=bridge1
|
||||||
|
hp=0
|
||||||
tiletype1=3
|
tiletype1=3
|
||||||
tiletype2=3
|
tiletype2=3
|
||||||
tiletype3=3
|
tiletype3=3
|
||||||
@@ -1563,6 +1567,8 @@ tiletype12=3
|
|||||||
Name=BRIDGE2
|
Name=BRIDGE2
|
||||||
width=5
|
width=5
|
||||||
height=2
|
height=2
|
||||||
|
bridge=bridge2
|
||||||
|
hp=1
|
||||||
tiletype0=3
|
tiletype0=3
|
||||||
tiletype1=2
|
tiletype1=2
|
||||||
tiletype2=2
|
tiletype2=2
|
||||||
@@ -1577,6 +1583,8 @@ tiletype9=3
|
|||||||
Name=BRIDGE2D
|
Name=BRIDGE2D
|
||||||
width=5
|
width=5
|
||||||
height=2
|
height=2
|
||||||
|
bridge=bridge2
|
||||||
|
hp=0
|
||||||
tiletype0=3
|
tiletype0=3
|
||||||
tiletype1=3
|
tiletype1=3
|
||||||
tiletype2=3
|
tiletype2=3
|
||||||
@@ -2491,6 +2499,8 @@ tiletype3=3
|
|||||||
Name=BR1A
|
Name=BR1A
|
||||||
width=4
|
width=4
|
||||||
height=3
|
height=3
|
||||||
|
bridge=br1
|
||||||
|
hp=1
|
||||||
tiletype1=3
|
tiletype1=3
|
||||||
tiletype2=2
|
tiletype2=2
|
||||||
tiletype4=3
|
tiletype4=3
|
||||||
@@ -2505,6 +2515,8 @@ tiletype11=3
|
|||||||
Name=BR1B
|
Name=BR1B
|
||||||
width=4
|
width=4
|
||||||
height=3
|
height=3
|
||||||
|
bridge=br1
|
||||||
|
hp=.5
|
||||||
tiletype1=3
|
tiletype1=3
|
||||||
tiletype2=6
|
tiletype2=6
|
||||||
tiletype4=3
|
tiletype4=3
|
||||||
@@ -2519,6 +2531,8 @@ tiletype11=3
|
|||||||
Name=BR1C
|
Name=BR1C
|
||||||
width=4
|
width=4
|
||||||
height=3
|
height=3
|
||||||
|
bridge=br1
|
||||||
|
hp=0
|
||||||
tiletype1=3
|
tiletype1=3
|
||||||
tiletype2=3
|
tiletype2=3
|
||||||
tiletype4=3
|
tiletype4=3
|
||||||
@@ -2533,6 +2547,8 @@ tiletype11=3
|
|||||||
Name=BR2A
|
Name=BR2A
|
||||||
width=5
|
width=5
|
||||||
height=3
|
height=3
|
||||||
|
bridge=br2
|
||||||
|
hp=1
|
||||||
tiletype1=3
|
tiletype1=3
|
||||||
tiletype2=2
|
tiletype2=2
|
||||||
tiletype5=3
|
tiletype5=3
|
||||||
@@ -2548,6 +2564,8 @@ tiletype13=3
|
|||||||
Name=BR2B
|
Name=BR2B
|
||||||
width=5
|
width=5
|
||||||
height=3
|
height=3
|
||||||
|
bridge=br2
|
||||||
|
hp=.5
|
||||||
tiletype1=3
|
tiletype1=3
|
||||||
tiletype2=6
|
tiletype2=6
|
||||||
tiletype5=3
|
tiletype5=3
|
||||||
@@ -2563,6 +2581,8 @@ tiletype13=3
|
|||||||
Name=BR2C
|
Name=BR2C
|
||||||
width=5
|
width=5
|
||||||
height=3
|
height=3
|
||||||
|
bridge=br2
|
||||||
|
hp=0
|
||||||
tiletype1=1
|
tiletype1=1
|
||||||
tiletype2=1
|
tiletype2=1
|
||||||
tiletype5=3
|
tiletype5=3
|
||||||
@@ -2578,6 +2598,8 @@ tiletype13=3
|
|||||||
Name=BR3A
|
Name=BR3A
|
||||||
width=4
|
width=4
|
||||||
height=2
|
height=2
|
||||||
|
bridge=br3
|
||||||
|
hp=1
|
||||||
tiletype0=3
|
tiletype0=3
|
||||||
tiletype1=2
|
tiletype1=2
|
||||||
tiletype5=2
|
tiletype5=2
|
||||||
@@ -2588,6 +2610,8 @@ tiletype7=3
|
|||||||
Name=BR3B
|
Name=BR3B
|
||||||
width=4
|
width=4
|
||||||
height=2
|
height=2
|
||||||
|
bridge=br3
|
||||||
|
hp=.5
|
||||||
tiletype0=3
|
tiletype0=3
|
||||||
tiletype1=2
|
tiletype1=2
|
||||||
tiletype5=2
|
tiletype5=2
|
||||||
@@ -2598,6 +2622,8 @@ tiletype7=3
|
|||||||
Name=BR3C
|
Name=BR3C
|
||||||
width=4
|
width=4
|
||||||
height=2
|
height=2
|
||||||
|
bridge=br3
|
||||||
|
hp=0
|
||||||
tiletype0=3
|
tiletype0=3
|
||||||
tiletype1=3
|
tiletype1=3
|
||||||
tiletype5=3
|
tiletype5=3
|
||||||
@@ -2608,6 +2634,8 @@ tiletype7=3
|
|||||||
Name=BR3D
|
Name=BR3D
|
||||||
width=4
|
width=4
|
||||||
height=2
|
height=2
|
||||||
|
bridge=br3
|
||||||
|
hp=0
|
||||||
tiletype0=5
|
tiletype0=5
|
||||||
tiletype1=3
|
tiletype1=3
|
||||||
tiletype5=5
|
tiletype5=5
|
||||||
@@ -2618,6 +2646,8 @@ tiletype7=5
|
|||||||
Name=BR3E
|
Name=BR3E
|
||||||
width=4
|
width=4
|
||||||
height=2
|
height=2
|
||||||
|
bridge=br3
|
||||||
|
hp=0
|
||||||
tiletype0=1
|
tiletype0=1
|
||||||
tiletype1=1
|
tiletype1=1
|
||||||
tiletype5=3
|
tiletype5=3
|
||||||
@@ -2628,6 +2658,8 @@ tiletype7=1
|
|||||||
Name=BR3F
|
Name=BR3F
|
||||||
width=4
|
width=4
|
||||||
height=2
|
height=2
|
||||||
|
bridge=br3
|
||||||
|
hp=0
|
||||||
tiletype0=1
|
tiletype0=1
|
||||||
tiletype1=1
|
tiletype1=1
|
||||||
tiletype5=1
|
tiletype5=1
|
||||||
@@ -2726,6 +2758,8 @@ tiletype0=0
|
|||||||
Name=BRIDGE1H
|
Name=BRIDGE1H
|
||||||
width=5
|
width=5
|
||||||
height=3
|
height=3
|
||||||
|
bridge=bridge1
|
||||||
|
hp=.5
|
||||||
tiletype1=3
|
tiletype1=3
|
||||||
tiletype2=6
|
tiletype2=6
|
||||||
tiletype3=6
|
tiletype3=6
|
||||||
@@ -2741,6 +2775,8 @@ tiletype12=6
|
|||||||
Name=BRIDGE2H
|
Name=BRIDGE2H
|
||||||
width=5
|
width=5
|
||||||
height=2
|
height=2
|
||||||
|
bridge=bridge2
|
||||||
|
hp=.5
|
||||||
tiletype0=3
|
tiletype0=3
|
||||||
tiletype1=6
|
tiletype1=6
|
||||||
tiletype2=6
|
tiletype2=6
|
||||||
@@ -2798,3 +2834,9 @@ tiletype18=2
|
|||||||
tiletype19=2
|
tiletype19=2
|
||||||
tiletype23=2
|
tiletype23=2
|
||||||
tiletype24=2
|
tiletype24=2
|
||||||
|
|
||||||
|
[TEM65534]
|
||||||
|
Name=Bogus
|
||||||
|
width=1
|
||||||
|
height=1
|
||||||
|
tiletype0=10
|
||||||
83
tileSet.til
83
tileSet.til
@@ -91,18 +91,72 @@ TS-
|
|||||||
00eb
|
00eb
|
||||||
br1a
|
br1a
|
||||||
|
|
||||||
|
; long bridge (north end, damaged)
|
||||||
|
TS-
|
||||||
|
1
|
||||||
|
00ec
|
||||||
|
br1b
|
||||||
|
|
||||||
|
; long bridge (north end, broken)
|
||||||
|
TS-
|
||||||
|
1
|
||||||
|
00ed
|
||||||
|
br1c
|
||||||
|
|
||||||
; long bridge (south end)
|
; long bridge (south end)
|
||||||
TS-
|
TS-
|
||||||
1
|
1
|
||||||
00ee
|
00ee
|
||||||
br2a
|
br2a
|
||||||
|
|
||||||
|
; long bridge (south end, damaged)
|
||||||
|
TS-
|
||||||
|
1
|
||||||
|
00ef
|
||||||
|
br2b
|
||||||
|
|
||||||
|
; long bridge (south end, broken)
|
||||||
|
TS-
|
||||||
|
1
|
||||||
|
00f0
|
||||||
|
br2c
|
||||||
|
|
||||||
; long bridge (middle)
|
; long bridge (middle)
|
||||||
TS-
|
TS-
|
||||||
1
|
1
|
||||||
00f1
|
00f1
|
||||||
br3a
|
br3a
|
||||||
|
|
||||||
|
; long bridge (middle, damaged)
|
||||||
|
TS-
|
||||||
|
1
|
||||||
|
00f2
|
||||||
|
br3b
|
||||||
|
|
||||||
|
; long bridge (middle, broken)
|
||||||
|
TS-
|
||||||
|
1
|
||||||
|
00f3
|
||||||
|
br3c
|
||||||
|
|
||||||
|
; long bridge (middle, broken, south end missing)
|
||||||
|
TS-
|
||||||
|
1
|
||||||
|
00f4
|
||||||
|
br3d
|
||||||
|
|
||||||
|
; long bridge (middle, broken, north end missing)
|
||||||
|
TS-
|
||||||
|
1
|
||||||
|
00f5
|
||||||
|
br3e
|
||||||
|
|
||||||
|
; long bridge (water / totally broken)
|
||||||
|
TS-
|
||||||
|
1
|
||||||
|
00f6
|
||||||
|
br3f
|
||||||
|
|
||||||
; long bridge (north surround)
|
; long bridge (north surround)
|
||||||
TS-
|
TS-
|
||||||
1
|
1
|
||||||
@@ -115,24 +169,6 @@ TS-
|
|||||||
017d
|
017d
|
||||||
br2x
|
br2x
|
||||||
|
|
||||||
; long bridge (north end, broken)
|
|
||||||
TS-
|
|
||||||
1
|
|
||||||
00ed
|
|
||||||
br1c
|
|
||||||
|
|
||||||
; long bridge (south end, broken)
|
|
||||||
TS-
|
|
||||||
1
|
|
||||||
00f0
|
|
||||||
br2c
|
|
||||||
|
|
||||||
; long bridge (water / totally broken)
|
|
||||||
TS-
|
|
||||||
1
|
|
||||||
00f6
|
|
||||||
br3f
|
|
||||||
|
|
||||||
; short bridge "/"
|
; short bridge "/"
|
||||||
TS-
|
TS-
|
||||||
1
|
1
|
||||||
@@ -172,6 +208,12 @@ bridge2d
|
|||||||
; short bridge "\" (damaged)
|
; short bridge "\" (damaged)
|
||||||
TS-
|
TS-
|
||||||
1
|
1
|
||||||
|
017b
|
||||||
|
bridge2h
|
||||||
|
|
||||||
|
; short bridge "\" (surround)
|
||||||
|
TS-
|
||||||
|
1
|
||||||
017f
|
017f
|
||||||
bridge2x
|
bridge2x
|
||||||
|
|
||||||
@@ -304,3 +346,8 @@ gflr{0:0000}
|
|||||||
0118
|
0118
|
||||||
gstr{0:0000}
|
gstr{0:0000}
|
||||||
|
|
||||||
|
; bogus
|
||||||
|
TS-
|
||||||
|
1
|
||||||
|
fffe
|
||||||
|
bogus
|
||||||
40
units.ini
40
units.ini
@@ -253,6 +253,11 @@ DOMF
|
|||||||
; pseudo-buildings
|
; pseudo-buildings
|
||||||
MINP
|
MINP
|
||||||
MINV
|
MINV
|
||||||
|
BR1
|
||||||
|
BR2
|
||||||
|
BR3
|
||||||
|
BRIDGE1
|
||||||
|
BRIDGE2
|
||||||
|
|
||||||
|
|
||||||
; `Dimensions` is the size of a box that will include the whole building, excluding bib.
|
; `Dimensions` is the size of a box that will include the whole building, excluding bib.
|
||||||
@@ -533,6 +538,41 @@ Selectable=no
|
|||||||
Traits=Unit,RenderUnit,BelowUnits,InvisibleToOthers
|
Traits=Unit,RenderUnit,BelowUnits,InvisibleToOthers
|
||||||
Selectable=no
|
Selectable=no
|
||||||
|
|
||||||
|
[BR1]
|
||||||
|
Traits=Bridge, BelowUnits, Building
|
||||||
|
Strength=1000
|
||||||
|
Dimensions=4,2
|
||||||
|
Footprint=____ ____
|
||||||
|
Selectable=yes
|
||||||
|
|
||||||
|
[BR2]
|
||||||
|
Traits=Bridge, BelowUnits, Building
|
||||||
|
Strength=1000
|
||||||
|
Dimensions=4,2
|
||||||
|
Footprint=____ ____
|
||||||
|
Selectable=yes ;; temp hack
|
||||||
|
|
||||||
|
[BR3]
|
||||||
|
Traits=Bridge, BelowUnits, Building
|
||||||
|
Strength=1000
|
||||||
|
Dimensions=4,2
|
||||||
|
Footprint=____ ____
|
||||||
|
Selectable=yes ;; temp hack
|
||||||
|
|
||||||
|
[BRIDGE1]
|
||||||
|
Traits=Bridge, BelowUnits, Building
|
||||||
|
Strength=1000
|
||||||
|
Dimensions=5,3
|
||||||
|
Footprint=_____ _____ _____
|
||||||
|
Selectable = yes
|
||||||
|
|
||||||
|
[BRIDGE2]
|
||||||
|
Traits=Bridge, BelowUnits, Building
|
||||||
|
Strength=1000
|
||||||
|
Dimensions=5,2
|
||||||
|
Footprint=_____ _____
|
||||||
|
Selectable = yes
|
||||||
|
|
||||||
[InfantryTypes]
|
[InfantryTypes]
|
||||||
DOG
|
DOG
|
||||||
E1
|
E1
|
||||||
|
|||||||
Reference in New Issue
Block a user