merged yaml
This commit is contained in:
58
OpenRa.FileFormats/MiniYaml.cs
Executable file
58
OpenRa.FileFormats/MiniYaml.cs
Executable file
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace OpenRa.FileFormats
|
||||
{
|
||||
public class MiniYaml
|
||||
{
|
||||
public string Value;
|
||||
public Dictionary<string, MiniYaml> Nodes = new Dictionary<string,MiniYaml>();
|
||||
|
||||
public MiniYaml( string value ) : this( value, new Dictionary<string, MiniYaml>() ) { }
|
||||
|
||||
public MiniYaml( string value, Dictionary<string, MiniYaml> nodes )
|
||||
{
|
||||
Value = value;
|
||||
Nodes = nodes;
|
||||
}
|
||||
|
||||
public static Dictionary<string, MiniYaml> FromFile( string path )
|
||||
{
|
||||
var lines = File.ReadAllLines( path );
|
||||
|
||||
var levels = new List<Dictionary<string, MiniYaml>>();
|
||||
levels.Add( new Dictionary<string, MiniYaml>() );
|
||||
|
||||
foreach( var line in lines )
|
||||
{
|
||||
var t = line.TrimStart( ' ', '\t' );
|
||||
if( t.Length == 0 || t[ 0 ] == '#' )
|
||||
continue;
|
||||
var level = line.Length - t.Length;
|
||||
|
||||
if( levels.Count <= level )
|
||||
throw new InvalidOperationException( "Bad indent in miniyaml" );
|
||||
while( levels.Count > level + 1 )
|
||||
levels.RemoveAt( levels.Count - 1 );
|
||||
|
||||
var colon = t.IndexOf( ':' );
|
||||
var d = new Dictionary<string, MiniYaml>();
|
||||
|
||||
if( colon == -1 )
|
||||
levels[ level ].Add( t.Trim(), new MiniYaml( null, d ) );
|
||||
else
|
||||
{
|
||||
var value = t.Substring( colon + 1 ).Trim();
|
||||
if( value.Length == 0 )
|
||||
value = null;
|
||||
levels[ level ].Add( t.Substring( 0, colon ).Trim(), new MiniYaml( value, d ) );
|
||||
}
|
||||
levels.Add( d );
|
||||
}
|
||||
return levels[ 0 ];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,7 @@
|
||||
<Compile Include="IniWriter.cs" />
|
||||
<Compile Include="IPaletteRemap.cs" />
|
||||
<Compile Include="Map.cs" />
|
||||
<Compile Include="MiniYaml.cs" />
|
||||
<Compile Include="PackageEntry.cs" />
|
||||
<Compile Include="Package.cs" />
|
||||
<Compile Include="Palette.cs" />
|
||||
|
||||
@@ -12,7 +12,10 @@ namespace OpenRa.Game
|
||||
{
|
||||
[Sync]
|
||||
public readonly TypeDictionary traits = new TypeDictionary();
|
||||
public readonly UnitInfo Info;
|
||||
|
||||
[Obsolete]
|
||||
public readonly LegacyUnitInfo LegacyInfo;
|
||||
public readonly NewUnitInfo Info;
|
||||
|
||||
public readonly uint ActorID;
|
||||
[Sync]
|
||||
@@ -23,33 +26,25 @@ namespace OpenRa.Game
|
||||
public int Health;
|
||||
IActivity currentActivity;
|
||||
|
||||
object ConstructTrait(string traitName)
|
||||
{
|
||||
/* todo: allow mods to introduce traits */
|
||||
var type = typeof(Mobile).Assembly.GetType(typeof(Mobile).Namespace + "." + traitName, true, false);
|
||||
var ctor = type.GetConstructor(new[] { typeof(Actor) });
|
||||
if (ctor == null)
|
||||
throw new InvalidOperationException("Trait {0} does not have the correct constructor: {0}(Actor self)".F(type.Name));
|
||||
return ctor.Invoke(new object[] { this });
|
||||
}
|
||||
|
||||
public Actor( ActorInfo info, int2 location, Player owner )
|
||||
{
|
||||
ActorID = Game.world.NextAID();
|
||||
Info = (UnitInfo)info; // temporary
|
||||
LegacyInfo = (LegacyUnitInfo)info; // temporary
|
||||
Location = location;
|
||||
CenterLocation = Traits.Util.CenterOfCell(Location);
|
||||
Owner = owner;
|
||||
|
||||
if (Info == null) return;
|
||||
if (LegacyInfo == null) return;
|
||||
|
||||
Health = Info.Strength; /* todo: fix walls, etc so this is always true! */
|
||||
Health = LegacyInfo.Strength; /* todo: fix walls, etc so this is always true! */
|
||||
|
||||
if( Info.Traits == null )
|
||||
throw new InvalidOperationException( "No Actor traits for {0}; add Traits= to units.ini for appropriate unit".F(Info.Name) );
|
||||
if( LegacyInfo.Traits == null )
|
||||
throw new InvalidOperationException( "No Actor traits for {0}; add Traits= to units.ini for appropriate unit".F(LegacyInfo.Name) );
|
||||
|
||||
foreach (var traitName in Info.Traits)
|
||||
traits.Add(ConstructTrait(traitName));
|
||||
Info = Rules.NewUnitInfo[LegacyInfo.Name.ToLowerInvariant()];
|
||||
|
||||
foreach (var trait in Info.Traits.WithInterface<ITraitInfo>())
|
||||
traits.Add(trait.Create(this));
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
@@ -75,8 +70,8 @@ namespace OpenRa.Game
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Info != null && Info.SelectionSize != null)
|
||||
return new float2(Info.SelectionSize[0], Info.SelectionSize[1]);
|
||||
if (LegacyInfo != null && LegacyInfo.SelectionSize != null)
|
||||
return new float2(LegacyInfo.SelectionSize[0], LegacyInfo.SelectionSize[1]);
|
||||
|
||||
var firstSprite = Render().FirstOrDefault();
|
||||
if (firstSprite.Sprite == null) return float2.Zero;
|
||||
@@ -102,7 +97,7 @@ namespace OpenRa.Game
|
||||
var loc = mi.Location + Game.viewport.Location;
|
||||
var underCursor = Game.FindUnits(loc, loc).FirstOrDefault();
|
||||
|
||||
if (underCursor != null && !underCursor.Info.Selectable)
|
||||
if (underCursor != null && !underCursor.LegacyInfo.Selectable)
|
||||
underCursor = null;
|
||||
|
||||
return traits.WithInterface<IIssueOrder>()
|
||||
@@ -114,8 +109,8 @@ namespace OpenRa.Game
|
||||
{
|
||||
var size = SelectedSize;
|
||||
var loc = CenterLocation - 0.5f * size;
|
||||
if (Info != null && Info.SelectionSize != null && Info.SelectionSize.Length > 2)
|
||||
loc += new float2(Info.SelectionSize[2], Info.SelectionSize[3]);
|
||||
if (LegacyInfo != null && LegacyInfo.SelectionSize != null && LegacyInfo.SelectionSize.Length > 2)
|
||||
loc += new float2(LegacyInfo.SelectionSize[2], LegacyInfo.SelectionSize[3]);
|
||||
|
||||
if (useAltitude)
|
||||
{
|
||||
@@ -132,7 +127,7 @@ namespace OpenRa.Game
|
||||
public DamageState GetDamageState()
|
||||
{
|
||||
if (Health <= 0) return DamageState.Dead;
|
||||
var halfStrength = Info.Strength * Rules.General.ConditionYellow;
|
||||
var halfStrength = LegacyInfo.Strength * Rules.General.ConditionYellow;
|
||||
return Health < halfStrength ? DamageState.Half : DamageState.Normal;
|
||||
}
|
||||
|
||||
@@ -155,8 +150,8 @@ namespace OpenRa.Game
|
||||
|
||||
Game.world.AddFrameEndTask(w => w.Remove(this));
|
||||
}
|
||||
if (Health > Info.Strength)
|
||||
Health = Info.Strength;
|
||||
if (Health > LegacyInfo.Strength)
|
||||
Health = LegacyInfo.Strength;
|
||||
|
||||
var newState = GetDamageState();
|
||||
|
||||
|
||||
@@ -216,7 +216,7 @@ namespace OpenRa.Game
|
||||
{
|
||||
var hasNewRadar = Game.world.Actors.Any(a => a.Owner == Game.LocalPlayer
|
||||
&& a.traits.Contains<ProvidesRadar>()
|
||||
&& a.traits.Get<ProvidesRadar>().IsActive());
|
||||
&& a.traits.Get<ProvidesRadar>().IsActive(a));
|
||||
|
||||
if (hasNewRadar != hasRadar)
|
||||
{
|
||||
@@ -738,7 +738,7 @@ namespace OpenRa.Game
|
||||
DrawRightAligned( "${0}".F(info.Cost), pos + new int2(-5,5),
|
||||
Game.LocalPlayer.Cash + Game.LocalPlayer.Ore >= info.Cost ? Color.White : Color.Red);
|
||||
|
||||
var bi = info as BuildingInfo;
|
||||
var bi = info as LegacyBuildingInfo;
|
||||
if (bi != null)
|
||||
DrawRightAligned("ϟ{0}".F(bi.Power), pos + new int2(-5, 20),
|
||||
Game.LocalPlayer.PowerProvided - Game.LocalPlayer.PowerDrained + bi.Power >= 0
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace OpenRa.Game
|
||||
|
||||
var distance = (target.CenterLocation - loc).Length*1/24f;
|
||||
var rawDamage = weapon.Damage * (float)Math.Exp(-distance / warhead.Spread);
|
||||
var multiplier = warhead.EffectivenessAgainst(target.Info.Armor);
|
||||
var multiplier = warhead.EffectivenessAgainst(target.LegacyInfo.Armor);
|
||||
return rawDamage * multiplier;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace OpenRa.Game
|
||||
var warhead = Rules.WarheadInfo[weapon.Warhead];
|
||||
var unit = target.traits.GetOrDefault<Unit>();
|
||||
|
||||
if (warhead.EffectivenessAgainst(target.Info.Armor) <= 0)
|
||||
if (warhead.EffectivenessAgainst(target.LegacyInfo.Armor) <= 0)
|
||||
return false;
|
||||
|
||||
if (target.traits.Contains<Submarine>())
|
||||
@@ -68,7 +68,7 @@ namespace OpenRa.Game
|
||||
if (unit != null && unit.Altitude > 0)
|
||||
return projectile.AA;
|
||||
|
||||
if (projectile.UnderWater && !target.Info.WaterBound)
|
||||
if (projectile.UnderWater && !target.LegacyInfo.WaterBound)
|
||||
return false;
|
||||
|
||||
return projectile.AG;
|
||||
@@ -76,10 +76,10 @@ namespace OpenRa.Game
|
||||
|
||||
public static bool HasAnyValidWeapons(Actor self, Actor target)
|
||||
{
|
||||
if (self.Info.Primary != null &&
|
||||
WeaponValidForTarget(Rules.WeaponInfo[self.Info.Primary], target)) return true;
|
||||
if (self.Info.Secondary != null &&
|
||||
WeaponValidForTarget(Rules.WeaponInfo[self.Info.Secondary], target)) return true;
|
||||
if (self.LegacyInfo.Primary != null &&
|
||||
WeaponValidForTarget(Rules.WeaponInfo[self.LegacyInfo.Primary], target)) return true;
|
||||
if (self.LegacyInfo.Secondary != null &&
|
||||
WeaponValidForTarget(Rules.WeaponInfo[self.LegacyInfo.Secondary], target)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ namespace OpenRa.Game.Effects
|
||||
|
||||
public Corpse(Actor fromActor, int death)
|
||||
{
|
||||
anim = new Animation(fromActor.Info.Image ?? fromActor.Info.Name);
|
||||
var info = fromActor.Info.Traits.WithInterface<RenderSimpleInfo>().First();
|
||||
anim = new Animation(info.Image ?? fromActor.Info.Name);
|
||||
anim.PlayThen("die{0}".F(death + 1),
|
||||
() => Game.world.AddFrameEndTask(w => w.Remove(this)));
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace OpenRa.Game
|
||||
world = new World();
|
||||
Game.world.ActorAdded += a =>
|
||||
{
|
||||
if (a.Owner != null && a.Info != null)
|
||||
if (a.Owner != null && a.LegacyInfo != null)
|
||||
a.Owner.Shroud.Explore(a);
|
||||
};
|
||||
|
||||
@@ -311,8 +311,8 @@ namespace OpenRa.Game
|
||||
public static IEnumerable<Actor> SelectActorsInBox(float2 a, float2 b)
|
||||
{
|
||||
return FindUnits(a, b)
|
||||
.Where( x => x.Info.Selectable )
|
||||
.GroupBy(x => (x.Owner == LocalPlayer) ? x.Info.SelectionPriority : 0)
|
||||
.Where( x => x.LegacyInfo.Selectable )
|
||||
.GroupBy(x => (x.Owner == LocalPlayer) ? x.LegacyInfo.SelectionPriority : 0)
|
||||
.OrderByDescending(g => g.Key)
|
||||
.Select( g => g.AsEnumerable() )
|
||||
.DefaultIfEmpty( new Actor[] {} )
|
||||
@@ -322,7 +322,7 @@ namespace OpenRa.Game
|
||||
public static Random SharedRandom = new Random(0); /* for things that require sync */
|
||||
public static Random CosmeticRandom = new Random(); /* for things that are just fluff */
|
||||
|
||||
public static bool CanPlaceBuilding(BuildingInfo building, int2 xy, Actor toIgnore, bool adjust)
|
||||
public static bool CanPlaceBuilding(LegacyBuildingInfo building, int2 xy, Actor toIgnore, bool adjust)
|
||||
{
|
||||
return !Footprint.Tiles(building, xy, adjust).Any(
|
||||
t => !Rules.Map.IsInMap(t.X, t.Y) || Rules.Map.ContainsResource(t) || !Game.IsCellBuildable(t,
|
||||
@@ -330,7 +330,7 @@ namespace OpenRa.Game
|
||||
toIgnore));
|
||||
}
|
||||
|
||||
public static bool IsCloseEnoughToBase(Player p, BuildingInfo bi, int2 position)
|
||||
public static bool IsCloseEnoughToBase(Player p, LegacyBuildingInfo bi, int2 position)
|
||||
{
|
||||
var maxDistance = bi.Adjacent + 1;
|
||||
|
||||
@@ -339,7 +339,7 @@ namespace OpenRa.Game
|
||||
heuristic = loc =>
|
||||
{
|
||||
var b = Game.BuildingInfluence.GetBuildingAt(loc);
|
||||
if (b != null && b.Owner == p && (b.Info as BuildingInfo).BaseNormal) return 0;
|
||||
if (b != null && b.Owner == p && (b.LegacyInfo as LegacyBuildingInfo).BaseNormal) return 0;
|
||||
if ((loc - position).Length > maxDistance)
|
||||
return float.PositiveInfinity; /* not quite right */
|
||||
return 1;
|
||||
|
||||
@@ -1,17 +1,62 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRa.FileFormats;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenRa.Game.GameRules
|
||||
{
|
||||
static class FieldLoader
|
||||
{
|
||||
public static void Load( object self, IniSection ini )
|
||||
public static void Load(object self, IniSection ini)
|
||||
{
|
||||
foreach( var x in ini )
|
||||
foreach (var x in ini)
|
||||
{
|
||||
var field = self.GetType().GetField( x.Key.Trim() );
|
||||
field.SetValue( self, GetValue( field.FieldType, x.Value.Trim() ) );
|
||||
var field = self.GetType().GetField(x.Key.Trim());
|
||||
field.SetValue(self, GetValue(field.FieldType, x.Value.Trim()));
|
||||
}
|
||||
}
|
||||
|
||||
public static void Load(object self, MiniYaml my)
|
||||
{
|
||||
foreach (var x in my.Nodes)
|
||||
{
|
||||
var field = self.GetType().GetField(x.Key.Trim());
|
||||
if (field == null)
|
||||
throw new NotImplementedException("Missing field `{0}` on `{1}`".F(x.Key.Trim(), self.GetType().Name));
|
||||
field.SetValue(self, GetValue(field.FieldType, x.Value.Value.Trim()));
|
||||
}
|
||||
}
|
||||
|
||||
public static void CheckYaml( object self, Dictionary<string, MiniYaml> d )
|
||||
{
|
||||
//foreach( var x in d )
|
||||
//{
|
||||
// if( x.Key == "Tab" ) continue;
|
||||
// if( x.Key == "Description" ) continue;
|
||||
// if( x.Key == "LongDesc" ) continue;
|
||||
|
||||
// var key = x.Key;
|
||||
// if( key == "Prerequisites" ) key = "Prerequisite";
|
||||
// if( key == "HP" ) key = "Strength";
|
||||
// if( key == "Priority" ) key = "SelectionPriority";
|
||||
// if( key == "Bounds" ) key = "SelectionSize";
|
||||
// var field = self.GetType().GetField( key );
|
||||
// var old = field.GetValue( self );
|
||||
// var neww = GetValue( field.FieldType, x.Value.Value.Trim() );
|
||||
// if( old.ToString() != neww.ToString() )
|
||||
// throw new NotImplementedException();
|
||||
//}
|
||||
foreach( var x in d )
|
||||
{
|
||||
var key = x.Key;
|
||||
if( key == "Tab" )
|
||||
continue;
|
||||
if( key == "Prerequisites" ) key = "Prerequisite";
|
||||
if( key == "HP" ) key = "Strength";
|
||||
if( key == "Priority" ) key = "SelectionPriority";
|
||||
if( key == "Bounds" ) key = "SelectionSize";
|
||||
var field = self.GetType().GetField( key.Trim() );
|
||||
field.SetValue( self, GetValue( field.FieldType, x.Value.Value.Trim() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@ namespace OpenRa.Game.GameRules
|
||||
{
|
||||
static class Footprint
|
||||
{
|
||||
public static IEnumerable<int2> Tiles( BuildingInfo buildingInfo, int2 position )
|
||||
public static IEnumerable<int2> Tiles( LegacyBuildingInfo buildingInfo, int2 position )
|
||||
{
|
||||
return Tiles(buildingInfo, position, true);
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> Tiles( BuildingInfo buildingInfo, int2 position, bool adjustForPlacement )
|
||||
public static IEnumerable<int2> Tiles( LegacyBuildingInfo buildingInfo, int2 position, bool adjustForPlacement )
|
||||
{
|
||||
var dim = buildingInfo.Dimensions;
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace OpenRa.Game.GameRules
|
||||
return Tiles( building.unitInfo, a.Location, false );
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> UnpathableTiles( BuildingInfo buildingInfo, int2 position )
|
||||
public static IEnumerable<int2> UnpathableTiles( LegacyBuildingInfo buildingInfo, int2 position )
|
||||
{
|
||||
var footprint = buildingInfo.Footprint.Where( x => !char.IsWhiteSpace( x ) ).ToArray();
|
||||
foreach( var tile in TilesWhere( buildingInfo.Name, buildingInfo.Dimensions, footprint, a => a == 'x' ) )
|
||||
@@ -52,7 +52,7 @@ namespace OpenRa.Game.GameRules
|
||||
yield return new int2( x, y );
|
||||
}
|
||||
|
||||
public static int2 AdjustForBuildingSize( BuildingInfo unitInfo )
|
||||
public static int2 AdjustForBuildingSize( LegacyBuildingInfo unitInfo )
|
||||
{
|
||||
var dim = unitInfo.Dimensions;
|
||||
return new int2( dim.X / 2, dim.Y > 1 ? ( dim.Y + 1 ) / 2 : 0 );
|
||||
|
||||
43
OpenRa.Game/GameRules/NewUnitInfo.cs
Executable file
43
OpenRa.Game/GameRules/NewUnitInfo.cs
Executable file
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRa.FileFormats;
|
||||
using OpenRa.Game.Traits;
|
||||
|
||||
namespace OpenRa.Game.GameRules
|
||||
{
|
||||
class NewUnitInfo
|
||||
{
|
||||
public readonly string Parent;
|
||||
public readonly TypeDictionary Traits = new TypeDictionary();
|
||||
public readonly string Name;
|
||||
|
||||
public NewUnitInfo( string name, MiniYaml node )
|
||||
{
|
||||
Name = name;
|
||||
|
||||
// todo: make inheritance actually work
|
||||
MiniYaml inherit;
|
||||
if( node.Nodes.TryGetValue( "Inherits", out inherit ) )
|
||||
{
|
||||
Parent = inherit.Value;
|
||||
node.Nodes.Remove( "Inherits" );
|
||||
}
|
||||
|
||||
foreach (var t in node.Nodes)
|
||||
Traits.Add(LoadTraitInfo(t.Key, t.Value));
|
||||
}
|
||||
|
||||
static ITraitInfo LoadTraitInfo(string traitName, MiniYaml my)
|
||||
{
|
||||
var fullTypeName = typeof(ITraitInfo).Namespace + "." + traitName + "Info";
|
||||
var info = (ITraitInfo)typeof(ITraitInfo).Assembly.CreateInstance(fullTypeName);
|
||||
|
||||
if (info == null)
|
||||
throw new NotImplementedException("Missing traitinfo type `{0}`".F(fullTypeName));
|
||||
|
||||
FieldLoader.Load(info, my);
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using IjwFramework.Types;
|
||||
using OpenRa.FileFormats;
|
||||
using OpenRa.Game.GameRules;
|
||||
using OpenRa.Game.Traits;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
@@ -12,7 +13,7 @@ namespace OpenRa.Game
|
||||
public static IniFile AllRules;
|
||||
public static Dictionary<string, List<string>> Categories = new Dictionary<string, List<string>>();
|
||||
public static Dictionary<string, string> UnitCategory;
|
||||
public static InfoLoader<UnitInfo> UnitInfo;
|
||||
public static InfoLoader<LegacyUnitInfo> UnitInfo;
|
||||
public static InfoLoader<WeaponInfo> WeaponInfo;
|
||||
public static InfoLoader<WarheadInfo> WarheadInfo;
|
||||
public static InfoLoader<ProjectileInfo> ProjectileInfo;
|
||||
@@ -24,6 +25,8 @@ namespace OpenRa.Game
|
||||
public static Map Map;
|
||||
public static TileSet TileSet;
|
||||
|
||||
public static Dictionary<string, NewUnitInfo> NewUnitInfo;
|
||||
|
||||
public static void LoadRules(string mapFileName, bool useAftermath)
|
||||
{
|
||||
if( useAftermath )
|
||||
@@ -61,13 +64,13 @@ namespace OpenRa.Game
|
||||
"Plane");
|
||||
UnitCategory = Categories.SelectMany(x => x.Value.Select(y => new KeyValuePair<string, string>(y, x.Key))).ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
UnitInfo = new InfoLoader<UnitInfo>(
|
||||
Pair.New<string, Func<string, UnitInfo>>("Building", s => new BuildingInfo(s)),
|
||||
Pair.New<string, Func<string, UnitInfo>>("Defense", s => new BuildingInfo(s)),
|
||||
Pair.New<string, Func<string, UnitInfo>>("Infantry", s => new InfantryInfo(s)),
|
||||
Pair.New<string, Func<string, UnitInfo>>("Vehicle", s => new VehicleInfo(s)),
|
||||
Pair.New<string, Func<string, UnitInfo>>("Ship", s => new VehicleInfo(s)),
|
||||
Pair.New<string, Func<string, UnitInfo>>("Plane", s => new VehicleInfo(s)));
|
||||
UnitInfo = new InfoLoader<LegacyUnitInfo>(
|
||||
Pair.New<string, Func<string, LegacyUnitInfo>>("Building", s => new LegacyBuildingInfo(s)),
|
||||
Pair.New<string, Func<string, LegacyUnitInfo>>("Defense", s => new LegacyBuildingInfo(s)),
|
||||
Pair.New<string, Func<string, LegacyUnitInfo>>("Infantry", s => new InfantryInfo(s)),
|
||||
Pair.New<string, Func<string, LegacyUnitInfo>>("Vehicle", s => new VehicleInfo(s)),
|
||||
Pair.New<string, Func<string, LegacyUnitInfo>>("Ship", s => new VehicleInfo(s)),
|
||||
Pair.New<string, Func<string, LegacyUnitInfo>>("Plane", s => new VehicleInfo(s)));
|
||||
|
||||
LoadCategories(
|
||||
"Weapon",
|
||||
@@ -91,6 +94,10 @@ namespace OpenRa.Game
|
||||
Map = new Map( AllRules );
|
||||
FileSystem.MountTemporary( new Package( Rules.Map.Theater + ".mix" ) );
|
||||
TileSet = new TileSet( Map.TileSuffix );
|
||||
|
||||
NewUnitInfo = new Dictionary<string, NewUnitInfo>();
|
||||
foreach( var kv in MiniYaml.FromFile( "ra.yaml" ) )
|
||||
NewUnitInfo.Add(kv.Key.ToLowerInvariant(), new NewUnitInfo(kv.Key.ToLowerInvariant(), kv.Value));
|
||||
}
|
||||
|
||||
static void LoadCategories(params string[] types)
|
||||
|
||||
@@ -6,13 +6,13 @@ namespace OpenRa.Game.GameRules
|
||||
{
|
||||
class TechTree
|
||||
{
|
||||
readonly Cache<string, List<UnitInfo>> producesIndex = new Cache<string, List<UnitInfo>>( x => new List<UnitInfo>() );
|
||||
readonly Cache<string, List<LegacyUnitInfo>> producesIndex = new Cache<string, List<LegacyUnitInfo>>( x => new List<LegacyUnitInfo>() );
|
||||
|
||||
public TechTree()
|
||||
{
|
||||
foreach( var b in Rules.Categories[ "Building" ] )
|
||||
{
|
||||
var info = (BuildingInfo)Rules.UnitInfo[ b ];
|
||||
var info = (LegacyBuildingInfo)Rules.UnitInfo[ b ];
|
||||
foreach( var p in info.Produces )
|
||||
producesIndex[ p ].Add( info );
|
||||
}
|
||||
@@ -21,12 +21,12 @@ namespace OpenRa.Game.GameRules
|
||||
public Cache<string, List<Actor>> GatherBuildings( Player player )
|
||||
{
|
||||
var ret = new Cache<string, List<Actor>>( x => new List<Actor>() );
|
||||
foreach( var b in Game.world.Actors.Where( x => x.Owner == player && x.Info is BuildingInfo ) )
|
||||
ret[ b.Info.Name ].Add( b );
|
||||
foreach( var b in Game.world.Actors.Where( x => x.Owner == player && x.LegacyInfo is LegacyBuildingInfo ) )
|
||||
ret[ b.LegacyInfo.Name ].Add( b );
|
||||
return ret;
|
||||
}
|
||||
|
||||
public bool CanBuild( UnitInfo unit, Player player, Cache<string, List<Actor>> playerBuildings )
|
||||
public bool CanBuild( LegacyUnitInfo unit, Player player, Cache<string, List<Actor>> playerBuildings )
|
||||
{
|
||||
if( unit.TechLevel == -1 )
|
||||
return false;
|
||||
@@ -59,7 +59,7 @@ namespace OpenRa.Game.GameRules
|
||||
.Where(x => Rules.UnitInfo[x].Owner.Contains(player.Race)); /* todo: fix for dual-race scenarios (captured buildings) */
|
||||
}
|
||||
|
||||
public IEnumerable<UnitInfo> UnitBuiltAt( UnitInfo info )
|
||||
public IEnumerable<LegacyUnitInfo> UnitBuiltAt( LegacyUnitInfo info )
|
||||
{
|
||||
if( info.BuiltAt.Length != 0 )
|
||||
return info.BuiltAt.Select( x => Rules.UnitInfo[ x.ToLowerInvariant() ] );
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace OpenRa.Game.GameRules
|
||||
concrete = 4,
|
||||
}
|
||||
|
||||
public class UnitInfo : ActorInfo
|
||||
public class LegacyUnitInfo : ActorInfo
|
||||
{
|
||||
public readonly string Name;
|
||||
|
||||
@@ -64,19 +64,19 @@ namespace OpenRa.Game.GameRules
|
||||
public readonly int[] PrimaryLocalOffset = { };
|
||||
public readonly int[] SecondaryLocalOffset = { };
|
||||
|
||||
public UnitInfo(string name) { Name = name; }
|
||||
public LegacyUnitInfo(string name) { Name = name; }
|
||||
}
|
||||
|
||||
public class MobileInfo : UnitInfo
|
||||
public class LegacyMobileInfo : LegacyUnitInfo
|
||||
{
|
||||
public readonly int Speed = 0;
|
||||
public readonly bool NoMovingFire = false;
|
||||
public readonly string Voice = "GenericVoice";
|
||||
|
||||
public MobileInfo(string name) : base(name) { }
|
||||
public LegacyMobileInfo(string name) : base(name) { }
|
||||
}
|
||||
|
||||
public class InfantryInfo : MobileInfo
|
||||
public class InfantryInfo : LegacyMobileInfo
|
||||
{
|
||||
public readonly bool C4 = false;
|
||||
public readonly bool FraidyCat = false;
|
||||
@@ -87,14 +87,14 @@ namespace OpenRa.Game.GameRules
|
||||
public InfantryInfo(string name) : base(name) { }
|
||||
}
|
||||
|
||||
public class VehicleInfo : MobileInfo
|
||||
public class VehicleInfo : LegacyMobileInfo
|
||||
{
|
||||
public readonly bool Tracked = false;
|
||||
|
||||
public VehicleInfo(string name) : base(name) { }
|
||||
}
|
||||
|
||||
public class BuildingInfo : UnitInfo
|
||||
public class LegacyBuildingInfo : LegacyUnitInfo
|
||||
{
|
||||
public readonly int2 Dimensions = new int2(1, 1);
|
||||
public readonly string Footprint = "x";
|
||||
@@ -112,6 +112,6 @@ namespace OpenRa.Game.GameRules
|
||||
public readonly int[] RallyPoint = { 1, 3 };
|
||||
public readonly float[] SpawnOffset = null;
|
||||
|
||||
public BuildingInfo(string name) : base(name) { }
|
||||
public LegacyBuildingInfo(string name) : base(name) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace OpenRa.Game.Graphics
|
||||
|
||||
public void GoToStartLocation()
|
||||
{
|
||||
Center(Game.world.Actors.Where(a => a.Info != null && a.Owner == Game.LocalPlayer));
|
||||
Center(Game.world.Actors.Where(a => a.LegacyInfo != null && a.Owner == Game.LocalPlayer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ namespace OpenRa.Game.Graphics
|
||||
lineRenderer.DrawLine(xy + new float2(0, -2), xy + new float2(0, -4), c, c);
|
||||
lineRenderer.DrawLine(Xy + new float2(0, -2), Xy + new float2(0, -4), c, c);
|
||||
|
||||
var healthAmount = (float)selectedUnit.Health / selectedUnit.Info.Strength;
|
||||
var healthAmount = (float)selectedUnit.Health / selectedUnit.LegacyInfo.Strength;
|
||||
var healthColor = (healthAmount < Rules.General.ConditionRed) ? Color.Red
|
||||
: (healthAmount < Rules.General.ConditionYellow) ? Color.Yellow
|
||||
: Color.LimeGreen;
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
<Compile Include="GameRules\ActorInfo.cs" />
|
||||
<Compile Include="GameRules\AftermathInfo.cs" />
|
||||
<Compile Include="GameRules\GeneralInfo.cs" />
|
||||
<Compile Include="GameRules\NewUnitInfo.cs" />
|
||||
<Compile Include="GameRules\SupportPowerInfo.cs" />
|
||||
<Compile Include="GameRules\TechTree.cs" />
|
||||
<Compile Include="GameRules\UserSettings.cs" />
|
||||
@@ -216,6 +217,7 @@
|
||||
<Compile Include="Traits\AutoHeal.cs" />
|
||||
<Compile Include="Traits\AutoTarget.cs" />
|
||||
<Compile Include="Traits\BelowUnits.cs" />
|
||||
<Compile Include="Traits\Buildable.cs" />
|
||||
<Compile Include="Traits\Building.cs" />
|
||||
<Compile Include="Traits\C4Demolition.cs" />
|
||||
<Compile Include="Traits\Cargo.cs" />
|
||||
@@ -241,6 +243,7 @@
|
||||
<Compile Include="Traits\ProvidesRadar.cs" />
|
||||
<Compile Include="Traits\Repairable.cs" />
|
||||
<Compile Include="Traits\Reservable.cs" />
|
||||
<Compile Include="Traits\Selectable.cs" />
|
||||
<Compile Include="Traits\SquishByTank.cs" />
|
||||
<Compile Include="Traits\Plane.cs" />
|
||||
<Compile Include="Traits\ProductionQueue.cs" />
|
||||
@@ -269,7 +272,6 @@
|
||||
<Compile Include="Traits\TakeCover.cs" />
|
||||
<Compile Include="Traits\Thief.cs" />
|
||||
<Compile Include="Traits\TraitsInterfaces.cs" />
|
||||
<Compile Include="Traits\Tree.cs" />
|
||||
<Compile Include="Traits\Turreted.cs" />
|
||||
<Compile Include="Traits\Unit.cs" />
|
||||
<Compile Include="Traits\WaterPaletteRotation.cs" />
|
||||
|
||||
@@ -31,9 +31,9 @@ namespace OpenRa.Game.Orders
|
||||
var underCursor = Game.FindUnits(loc, loc)
|
||||
.Where(a => a.Owner == Game.LocalPlayer
|
||||
&& a.traits.WithInterface<Chronoshiftable>().Any()
|
||||
&& a.Info.Selectable).FirstOrDefault();
|
||||
&& a.LegacyInfo.Selectable).FirstOrDefault();
|
||||
|
||||
var unit = underCursor != null ? underCursor.Info as UnitInfo : null;
|
||||
var unit = underCursor != null ? underCursor.LegacyInfo as LegacyUnitInfo : null;
|
||||
|
||||
if (unit != null)
|
||||
yield return new Order("ChronosphereSelect", underCursor, null, int2.Zero, power.Name);
|
||||
|
||||
@@ -31,9 +31,9 @@ namespace OpenRa.Game.Orders
|
||||
var underCursor = Game.FindUnits(loc, loc)
|
||||
.Where(a => a.Owner == Game.LocalPlayer
|
||||
&& a.traits.Contains<IronCurtainable>()
|
||||
&& a.Info.Selectable).FirstOrDefault();
|
||||
&& a.LegacyInfo.Selectable).FirstOrDefault();
|
||||
|
||||
var unit = underCursor != null ? underCursor.Info as UnitInfo : null;
|
||||
var unit = underCursor != null ? underCursor.LegacyInfo as LegacyUnitInfo : null;
|
||||
|
||||
if (unit != null)
|
||||
yield return new Order("IronCurtain", underCursor, null, int2.Zero, power.Name);
|
||||
|
||||
@@ -6,12 +6,12 @@ namespace OpenRa.Game.Orders
|
||||
class PlaceBuildingOrderGenerator : IOrderGenerator
|
||||
{
|
||||
readonly Actor Producer;
|
||||
readonly BuildingInfo Building;
|
||||
readonly LegacyBuildingInfo Building;
|
||||
|
||||
public PlaceBuildingOrderGenerator(Actor producer, string name)
|
||||
{
|
||||
Producer = producer;
|
||||
Building = (BuildingInfo)Rules.UnitInfo[ name ];
|
||||
Building = (LegacyBuildingInfo)Rules.UnitInfo[ name ];
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(int2 xy, MouseInput mi)
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace OpenRa.Game.Orders
|
||||
var underCursor = Game.FindUnits(loc, loc)
|
||||
.Where(a => a.Owner == Game.LocalPlayer
|
||||
&& a.traits.Contains<Building>()
|
||||
&& a.Info.Selectable).FirstOrDefault();
|
||||
&& a.LegacyInfo.Selectable).FirstOrDefault();
|
||||
|
||||
var building = underCursor != null ? underCursor.Info as BuildingInfo : null;
|
||||
var building = underCursor != null ? underCursor.LegacyInfo as LegacyBuildingInfo : null;
|
||||
|
||||
if (building != null)
|
||||
yield return new Order("PowerDown", underCursor, null, int2.Zero, null);
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace OpenRa.Game.Orders
|
||||
var underCursor = Game.FindUnits(loc, loc)
|
||||
.Where(a => a.Owner == Game.LocalPlayer
|
||||
&& a.traits.Contains<Building>()
|
||||
&& a.Info.Selectable).FirstOrDefault();
|
||||
&& a.LegacyInfo.Selectable).FirstOrDefault();
|
||||
|
||||
var building = underCursor != null ? underCursor.Info as BuildingInfo : null;
|
||||
var building = underCursor != null ? underCursor.LegacyInfo as LegacyBuildingInfo : null;
|
||||
|
||||
if (building != null && building.Repairable && underCursor.Health < building.Strength)
|
||||
yield return new Order("Repair", underCursor, null, int2.Zero, null);
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace OpenRa.Game.Orders
|
||||
var underCursor = Game.FindUnits(loc, loc)
|
||||
.Where(a => a.Owner == Game.LocalPlayer
|
||||
&& a.traits.Contains<Building>()
|
||||
&& a.Info.Selectable).FirstOrDefault();
|
||||
&& a.LegacyInfo.Selectable).FirstOrDefault();
|
||||
|
||||
var building = underCursor != null ? underCursor.Info as BuildingInfo : null;
|
||||
var building = underCursor != null ? underCursor.LegacyInfo as LegacyBuildingInfo : null;
|
||||
|
||||
if (building != null && !building.Unsellable)
|
||||
yield return new Order("Sell", underCursor, null, int2.Zero, null);
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace OpenRa.Game.Orders
|
||||
else
|
||||
return Cursor.MoveBlocked;
|
||||
case "DeployMcv":
|
||||
var factBuildingInfo = (BuildingInfo)Rules.UnitInfo["fact"];
|
||||
var factBuildingInfo = (LegacyBuildingInfo)Rules.UnitInfo["fact"];
|
||||
if (Game.CanPlaceBuilding(factBuildingInfo, a.Location - new int2(1, 1), a, false))
|
||||
return Cursor.Deploy;
|
||||
else
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace OpenRa.Game.Orders
|
||||
Game.world.AddFrameEndTask( _ =>
|
||||
{
|
||||
var queue = order.Player.PlayerActor.traits.Get<Traits.ProductionQueue>();
|
||||
var building = (BuildingInfo)Rules.UnitInfo[ order.TargetString ];
|
||||
var building = (LegacyBuildingInfo)Rules.UnitInfo[ order.TargetString ];
|
||||
var producing = queue.CurrentItem(Rules.UnitCategory[order.TargetString]);
|
||||
if( producing == null || producing.Item != order.TargetString || producing.RemainingTime != 0 )
|
||||
return;
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace OpenRa.Game
|
||||
{
|
||||
OreCapacity = Game.world.Actors
|
||||
.Where(a => a.Owner == this && a.traits.Contains<StoresOre>())
|
||||
.Select(a => a.Info as BuildingInfo)
|
||||
.Select(a => a.LegacyInfo as LegacyBuildingInfo)
|
||||
.Where(b => b != null)
|
||||
.Sum(b => b.Storage);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using IjwFramework.Types;
|
||||
using OpenRa.Game.Graphics;
|
||||
using OpenRa.Game.Traits;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
@@ -32,7 +33,7 @@ namespace OpenRa.Game
|
||||
|
||||
public void Explore(Actor a)
|
||||
{
|
||||
foreach (var t in Game.FindTilesInCircle((1f / Game.CellSize * a.CenterLocation).ToInt2(), a.Info.Sight))
|
||||
foreach (var t in Game.FindTilesInCircle((1f / Game.CellSize * a.CenterLocation).ToInt2(), a.LegacyInfo.Sight))
|
||||
explored[t.X, t.Y] = true;
|
||||
|
||||
dirty = true;
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace OpenRa.Game
|
||||
{
|
||||
if (voicedUnit == null) return;
|
||||
|
||||
var mi = voicedUnit.Info as MobileInfo;
|
||||
var mi = voicedUnit.LegacyInfo as LegacyMobileInfo;
|
||||
if (mi == null) return;
|
||||
|
||||
var vi = Rules.VoiceInfo[mi.Voice];
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace OpenRa.Game.Support
|
||||
{
|
||||
static class PerfHistory
|
||||
{
|
||||
static readonly Color[] colors = { Color.Red, Color.Green, Color.Blue, Color.Yellow, Color.Orange, Color.Fuchsia, Color.Lime, Color.LightBlue };
|
||||
static readonly Color[] colors = { Color.Red, Color.Green, Color.Blue, Color.Yellow, Color.Orange, Color.Fuchsia, Color.Lime, Color.LightBlue, Color.White, Color.Black };
|
||||
static int nextColor;
|
||||
|
||||
public static Cache<string, PerfItem> items = new Cache<string, PerfItem>(
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRa.Game.GameRules;
|
||||
using System.Collections.Generic;
|
||||
using OpenRa.Game.Effects;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class APMineInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new APMine(self); }
|
||||
}
|
||||
|
||||
class APMine : ICrushable, IOccupySpace
|
||||
{
|
||||
readonly Actor self;
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRa.Game.GameRules;
|
||||
using System.Collections.Generic;
|
||||
using OpenRa.Game.Effects;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ATMineInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new ATMine(self); }
|
||||
}
|
||||
|
||||
class ATMine : ICrushable, IOccupySpace
|
||||
{
|
||||
readonly Actor self;
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class AcceptsOreInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new AcceptsOre(self); }
|
||||
}
|
||||
|
||||
class AcceptsOre
|
||||
{
|
||||
public AcceptsOre(Actor self)
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace OpenRa.Game.Traits.Activities
|
||||
|
||||
if (target.Owner == self.Owner)
|
||||
{
|
||||
if (target.Health == target.Info.Strength)
|
||||
if (target.Health == target.LegacyInfo.Strength)
|
||||
return NextActivity;
|
||||
target.InflictDamage(self, -EngineerCapture.EngineerDamage, Rules.WarheadInfo["Super"]);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRa.Game.Traits.Activities
|
||||
|
||||
var desiredFacing = Util.GetFacing(d, unit.Facing);
|
||||
if (unit.Altitude == CruiseAltitude)
|
||||
Util.TickFacing(ref unit.Facing, desiredFacing, self.Info.ROT);
|
||||
Util.TickFacing(ref unit.Facing, desiredFacing, self.LegacyInfo.ROT);
|
||||
var speed = .2f * Util.GetEffectiveSpeed(self);
|
||||
var angle = unit.Facing / 128f * Math.PI;
|
||||
|
||||
|
||||
@@ -30,11 +30,11 @@ namespace OpenRa.Game.Traits.Activities
|
||||
return this;
|
||||
}
|
||||
|
||||
var range = Rules.WeaponInfo[ self.Info.Primary ].Range - 1;
|
||||
var range = Rules.WeaponInfo[ self.LegacyInfo.Primary ].Range - 1;
|
||||
var dist = target.CenterLocation - self.CenterLocation;
|
||||
|
||||
var desiredFacing = Util.GetFacing(dist, unit.Facing);
|
||||
Util.TickFacing(ref unit.Facing, desiredFacing, self.Info.ROT);
|
||||
Util.TickFacing(ref unit.Facing, desiredFacing, self.LegacyInfo.ROT);
|
||||
|
||||
if (!float2.WithinEpsilon(float2.Zero, dist, range * Game.CellSize))
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRa.Game.Traits.Activities
|
||||
}
|
||||
|
||||
var desiredFacing = Util.GetFacing(dist, unit.Facing);
|
||||
Util.TickFacing(ref unit.Facing, desiredFacing, self.Info.ROT);
|
||||
Util.TickFacing(ref unit.Facing, desiredFacing, self.LegacyInfo.ROT);
|
||||
|
||||
var rawSpeed = .2f * Util.GetEffectiveSpeed(self);
|
||||
self.CenterLocation += (rawSpeed / dist.Length) * dist;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace OpenRa.Game.Traits.Activities
|
||||
static Actor ChooseHelipad(Actor self)
|
||||
{
|
||||
return Game.world.Actors.FirstOrDefault(
|
||||
a => a.Info == Rules.UnitInfo["HPAD"] &&
|
||||
a => a.Info == Rules.NewUnitInfo["HPAD"] &&
|
||||
a.Owner == self.Owner &&
|
||||
!Reservable.IsReserved(a));
|
||||
}
|
||||
@@ -26,7 +26,7 @@ namespace OpenRa.Game.Traits.Activities
|
||||
|
||||
if (dest == null)
|
||||
return Util.SequenceActivities(
|
||||
new Turn(self.Info.InitialFacing),
|
||||
new Turn(self.LegacyInfo.InitialFacing),
|
||||
new HeliLand(true),
|
||||
NextActivity);
|
||||
|
||||
@@ -34,12 +34,12 @@ namespace OpenRa.Game.Traits.Activities
|
||||
if (res != null)
|
||||
self.traits.Get<Helicopter>().reservation = res.Reserve(self);
|
||||
|
||||
var offset = (dest.Info as BuildingInfo).SpawnOffset;
|
||||
var offset = (dest.LegacyInfo as LegacyBuildingInfo).SpawnOffset;
|
||||
var offsetVec = offset != null ? new float2(offset[0], offset[1]) : float2.Zero;
|
||||
|
||||
return Util.SequenceActivities(
|
||||
new HeliFly(dest.CenterLocation + offsetVec),
|
||||
new Turn(self.Info.InitialFacing),
|
||||
new Turn(self.LegacyInfo.InitialFacing),
|
||||
new HeliLand(false),
|
||||
new Rearm(),
|
||||
NextActivity);
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRa.Game.Traits.Activities
|
||||
--unit.Altitude;
|
||||
|
||||
var desiredFacing = Util.GetFacing(d, unit.Facing);
|
||||
Util.TickFacing(ref unit.Facing, desiredFacing, self.Info.ROT);
|
||||
Util.TickFacing(ref unit.Facing, desiredFacing, self.LegacyInfo.ROT);
|
||||
var speed = .2f * Util.GetEffectiveSpeed(self);
|
||||
var angle = unit.Facing / 128f * Math.PI;
|
||||
|
||||
|
||||
@@ -16,8 +16,11 @@ namespace OpenRa.Game.Traits.Activities
|
||||
if (isCanceled) return NextActivity;
|
||||
if (remainingTicks == 0)
|
||||
{
|
||||
var costPerHp = (Rules.General.URepairPercent * self.Info.Cost) / self.Info.Strength;
|
||||
var hpToRepair = Math.Min(Rules.General.URepairStep, self.Info.Strength - self.Health);
|
||||
var unitCost = self.Info.Traits.Get<BuildableInfo>().Cost;
|
||||
var hp = self.Info.Traits.WithInterface<OwnedActorInfo>().First().HP;
|
||||
|
||||
var costPerHp = (Rules.General.URepairPercent * unitCost) / hp;
|
||||
var hpToRepair = Math.Min(Rules.General.URepairStep, hp - self.Health);
|
||||
var cost = (int)Math.Ceiling(costPerHp * hpToRepair);
|
||||
if (!self.Owner.TakeCash(cost))
|
||||
{
|
||||
@@ -26,7 +29,7 @@ namespace OpenRa.Game.Traits.Activities
|
||||
}
|
||||
|
||||
self.InflictDamage(self, -hpToRepair, Rules.WarheadInfo["Super"]);
|
||||
if (self.Health == self.Info.Strength)
|
||||
if (self.Health == hp)
|
||||
return NextActivity;
|
||||
|
||||
var hostBuilding = Game.FindUnits(self.CenterLocation, self.CenterLocation)
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace OpenRa.Game.Traits.Activities
|
||||
Actor ChooseAirfield(Actor self)
|
||||
{
|
||||
var airfield = Game.world.Actors
|
||||
.Where(a => a.Info == Rules.UnitInfo["AFLD"] /* todo: generalize this */
|
||||
.Where(a => a.LegacyInfo == Rules.UnitInfo["AFLD"] /* todo: generalize this */
|
||||
&& a.Owner == self.Owner
|
||||
&& !Reservable.IsReserved(a))
|
||||
.FirstOrDefault();
|
||||
@@ -41,7 +41,7 @@ namespace OpenRa.Game.Traits.Activities
|
||||
var unit = self.traits.Get<Unit>();
|
||||
var speed = .2f * Util.GetEffectiveSpeed(self);
|
||||
var approachStart = landPos - new float2(unit.Altitude * speed, 0);
|
||||
var turnRadius = (128f / self.Info.ROT) * speed / (float)Math.PI;
|
||||
var turnRadius = (128f / self.LegacyInfo.ROT) * speed / (float)Math.PI;
|
||||
|
||||
/* work out the center points */
|
||||
var fwd = -float2.FromAngle(unit.Facing / 128f * (float)Math.PI);
|
||||
|
||||
@@ -13,8 +13,9 @@ namespace OpenRa.Game.Traits.Activities
|
||||
|
||||
void DoSell(Actor self)
|
||||
{
|
||||
var refund = Rules.General.RefundPercent
|
||||
* self.Health * self.Info.Cost / self.Info.Strength;
|
||||
var cost = self.Info.Traits.Get<BuildableInfo>().Cost;
|
||||
var hp = self.Info.Traits.WithInterface<OwnedActorInfo>().First().HP;
|
||||
var refund = Rules.General.RefundPercent * self.Health * cost / hp;
|
||||
|
||||
self.Owner.GiveCash((int)refund);
|
||||
self.Health = 0;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace OpenRa.Game.Traits.Activities
|
||||
if( desiredFacing == unit.Facing )
|
||||
return NextActivity;
|
||||
|
||||
Util.TickFacing( ref unit.Facing, desiredFacing, self.Info.ROT );
|
||||
Util.TickFacing( ref unit.Facing, desiredFacing, self.LegacyInfo.ROT );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace OpenRa.Game.Traits.Activities
|
||||
// if we're a thing that can turn, turn to the
|
||||
// right facing for the unload animation
|
||||
var unit = self.traits.GetOrDefault<Unit>();
|
||||
if (unit != null && unit.Facing != self.Info.UnloadFacing)
|
||||
return new Turn(self.Info.UnloadFacing) { NextActivity = this };
|
||||
if (unit != null && unit.Facing != self.LegacyInfo.UnloadFacing)
|
||||
return new Turn(self.LegacyInfo.UnloadFacing) { NextActivity = this };
|
||||
|
||||
// todo: handle the BS of open/close sequences, which are inconsistent,
|
||||
// for reasons that probably make good sense to the westwood guys.
|
||||
|
||||
@@ -6,6 +6,20 @@ using OpenRa.Game.Effects;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class AttackBaseInfo : ITraitInfo
|
||||
{
|
||||
public readonly string PrimaryWeapon = null;
|
||||
public readonly string SecondaryWeapon = null;
|
||||
public readonly int Recoil = 0;
|
||||
public readonly int[] PrimaryLocalOffset = { };
|
||||
public readonly int[] SecondaryLocalOffset = { };
|
||||
public readonly int[] PrimaryOffset = { 0, 0 };
|
||||
public readonly int[] SecondaryOffset = null;
|
||||
public readonly bool MuzzleFlash = false;
|
||||
|
||||
public virtual object Create(Actor self) { return new AttackBase(self); }
|
||||
}
|
||||
|
||||
class AttackBase : IIssueOrder, IResolveOrder, ITick
|
||||
{
|
||||
[Sync] public Actor target;
|
||||
@@ -23,8 +37,8 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
public AttackBase(Actor self)
|
||||
{
|
||||
var primaryWeapon = self.Info.Primary != null ? Rules.WeaponInfo[self.Info.Primary] : null;
|
||||
var secondaryWeapon = self.Info.Secondary != null ? Rules.WeaponInfo[self.Info.Secondary] : null;
|
||||
var primaryWeapon = self.LegacyInfo.Primary != null ? Rules.WeaponInfo[self.LegacyInfo.Primary] : null;
|
||||
var secondaryWeapon = self.LegacyInfo.Secondary != null ? Rules.WeaponInfo[self.LegacyInfo.Secondary] : null;
|
||||
|
||||
primaryBurst = primaryWeapon != null ? primaryWeapon.Burst : 1;
|
||||
secondaryBurst = secondaryWeapon != null ? secondaryWeapon.Burst : 1;
|
||||
@@ -74,18 +88,18 @@ namespace OpenRa.Game.Traits
|
||||
{
|
||||
var unit = self.traits.GetOrDefault<Unit>();
|
||||
|
||||
if (self.Info.Primary != null && CheckFire(self, unit, self.Info.Primary, ref primaryFireDelay,
|
||||
self.Info.PrimaryOffset, ref primaryBurst, self.Info.PrimaryLocalOffset))
|
||||
if (self.LegacyInfo.Primary != null && CheckFire(self, unit, self.LegacyInfo.Primary, ref primaryFireDelay,
|
||||
self.LegacyInfo.PrimaryOffset, ref primaryBurst, self.LegacyInfo.PrimaryLocalOffset))
|
||||
{
|
||||
secondaryFireDelay = Math.Max(4, secondaryFireDelay);
|
||||
primaryRecoil = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.Info.Secondary != null && CheckFire(self, unit, self.Info.Secondary, ref secondaryFireDelay,
|
||||
self.Info.SecondaryOffset ?? self.Info.PrimaryOffset, ref secondaryBurst, self.Info.SecondaryLocalOffset))
|
||||
if (self.LegacyInfo.Secondary != null && CheckFire(self, unit, self.LegacyInfo.Secondary, ref secondaryFireDelay,
|
||||
self.LegacyInfo.SecondaryOffset ?? self.LegacyInfo.PrimaryOffset, ref secondaryBurst, self.LegacyInfo.SecondaryLocalOffset))
|
||||
{
|
||||
if (self.Info.SecondaryOffset != null) secondaryRecoil = 1;
|
||||
if (self.LegacyInfo.SecondaryOffset != null) secondaryRecoil = 1;
|
||||
else primaryRecoil = 1;
|
||||
return;
|
||||
}
|
||||
@@ -127,7 +141,7 @@ namespace OpenRa.Game.Traits
|
||||
var thisTarget = target; // closure.
|
||||
var destUnit = thisTarget.traits.GetOrDefault<Unit>();
|
||||
|
||||
ScheduleDelayedAction(self.Info.FireDelay, () =>
|
||||
ScheduleDelayedAction(self.LegacyInfo.FireDelay, () =>
|
||||
{
|
||||
var srcAltitude = unit != null ? unit.Altitude : 0;
|
||||
var destAltitude = destUnit != null ? destUnit.Altitude : 0;
|
||||
@@ -161,7 +175,7 @@ namespace OpenRa.Game.Traits
|
||||
{
|
||||
if (mi.Button == MouseButton.Left || underCursor == null) return null;
|
||||
if (self == underCursor) return null;
|
||||
var isHeal = Rules.WeaponInfo[self.Info.Primary].Damage < 0;
|
||||
var isHeal = Rules.WeaponInfo[self.LegacyInfo.Primary].Damage < 0;
|
||||
if (((underCursor.Owner == self.Owner) ^ isHeal)
|
||||
&& !mi.Modifiers.HasModifier( Modifiers.Ctrl )) return null;
|
||||
if (!Combat.HasAnyValidWeapons(self, underCursor)) return null;
|
||||
@@ -186,7 +200,7 @@ namespace OpenRa.Game.Traits
|
||||
{
|
||||
const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */
|
||||
/* todo: choose the appropriate weapon, when only one works against this target */
|
||||
var weapon = order.Subject.Info.Primary ?? order.Subject.Info.Secondary;
|
||||
var weapon = order.Subject.LegacyInfo.Primary ?? order.Subject.LegacyInfo.Secondary;
|
||||
|
||||
self.QueueActivity(new Activities.Attack(order.TargetActor,
|
||||
Math.Max(0, (int)Rules.WeaponInfo[weapon].Range - RangeTolerance)));
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class AttackHeliInfo : AttackBaseInfo
|
||||
{
|
||||
public override object Create(Actor self) { return new AttackHeli(self); }
|
||||
}
|
||||
|
||||
class AttackHeli : AttackFrontal
|
||||
{
|
||||
public AttackHeli(Actor self) : base(self, 20) { }
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class AttackPlaneInfo : AttackBaseInfo
|
||||
{
|
||||
public override object Create(Actor self) { return new AttackPlane(self); }
|
||||
}
|
||||
|
||||
class AttackPlane : AttackFrontal
|
||||
{
|
||||
public AttackPlane(Actor self) : base(self, 20) { }
|
||||
|
||||
@@ -3,9 +3,14 @@ using OpenRa.Game.GameRules;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class AttackTurretedInfo : AttackBaseInfo
|
||||
{
|
||||
public override object Create(Actor self) { return new AttackTurreted( self ); }
|
||||
}
|
||||
|
||||
class AttackTurreted : AttackBase, INotifyBuildComplete
|
||||
{
|
||||
public AttackTurreted( Actor self ) : base(self) { self.traits.Get<Turreted>(); }
|
||||
public AttackTurreted(Actor self) : base(self) { }
|
||||
|
||||
public override void Tick(Actor self)
|
||||
{
|
||||
@@ -31,7 +36,7 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */
|
||||
/* todo: choose the appropriate weapon, when only one works against this target */
|
||||
var weapon = order.Subject.Info.Primary ?? order.Subject.Info.Secondary;
|
||||
var weapon = order.Subject.LegacyInfo.Primary ?? order.Subject.LegacyInfo.Secondary;
|
||||
|
||||
if (self.traits.Contains<Mobile>())
|
||||
self.QueueActivity( new Traits.Activities.Follow( order.TargetActor,
|
||||
|
||||
@@ -3,10 +3,10 @@ using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class AutoHealInfo : StatelessTraitInfo<AutoHeal> { }
|
||||
|
||||
class AutoHeal : ITick
|
||||
{
|
||||
public AutoHeal(Actor self) { }
|
||||
|
||||
void AttackTarget(Actor self, Actor target)
|
||||
{
|
||||
var attack = self.traits.WithInterface<AttackBase>().First();
|
||||
@@ -17,23 +17,16 @@ namespace OpenRa.Game.Traits
|
||||
self.CancelActivity();
|
||||
}
|
||||
|
||||
float GetMaximumRange(Actor self)
|
||||
{
|
||||
return new[] { self.Info.Primary, self.Info.Secondary }
|
||||
.Where(w => w != null)
|
||||
.Max(w => Rules.WeaponInfo[w].Range);
|
||||
}
|
||||
|
||||
bool NeedsNewTarget(Actor self)
|
||||
{
|
||||
var attack = self.traits.WithInterface<AttackBase>().First();
|
||||
var range = GetMaximumRange(self);
|
||||
var range = Util.GetMaximumRange(self);
|
||||
|
||||
if (attack.target == null)
|
||||
return true; // he's dead.
|
||||
if ((attack.target.Location - self.Location).LengthSquared > range * range + 2)
|
||||
return true; // wandered off faster than we could follow
|
||||
if (attack.target.Health == attack.target.Info.Strength)
|
||||
if (attack.target.Health == attack.target.Info.Traits.WithInterface<OwnedActorInfo>().First().HP)
|
||||
return true; // fully healed
|
||||
|
||||
return false;
|
||||
@@ -42,7 +35,7 @@ namespace OpenRa.Game.Traits
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
var attack = self.traits.WithInterface<AttackBase>().First();
|
||||
var range = GetMaximumRange(self);
|
||||
var range = Util.GetMaximumRange(self);
|
||||
|
||||
if (NeedsNewTarget(self))
|
||||
AttackTarget(self, ChooseTarget(self, range));
|
||||
@@ -55,7 +48,7 @@ namespace OpenRa.Game.Traits
|
||||
return inRange
|
||||
.Where(a => a.Owner == self.Owner && a != self) /* todo: one day deal with friendly players */
|
||||
.Where(a => Combat.HasAnyValidWeapons(self, a))
|
||||
.Where(a => a.Health < a.Info.Strength)
|
||||
.Where(a => a.Health < a.LegacyInfo.Strength)
|
||||
.OrderBy(a => (a.Location - self.Location).LengthSquared)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class AutoTargetInfo : StatelessTraitInfo<AutoTarget> { }
|
||||
|
||||
class AutoTarget : ITick, INotifyDamage
|
||||
{
|
||||
public AutoTarget(Actor self) {}
|
||||
|
||||
void AttackTarget(Actor self, Actor target)
|
||||
{
|
||||
var attack = self.traits.WithInterface<AttackBase>().First();
|
||||
@@ -13,19 +13,12 @@ namespace OpenRa.Game.Traits
|
||||
attack.ResolveOrder(self, new Order("Attack", self, target, int2.Zero, null));
|
||||
}
|
||||
|
||||
float GetMaximumRange(Actor self)
|
||||
{
|
||||
return new[] { self.Info.Primary, self.Info.Secondary }
|
||||
.Where(w => w != null)
|
||||
.Max(w => Rules.WeaponInfo[w].Range);
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (!self.IsIdle) return;
|
||||
|
||||
var attack = self.traits.WithInterface<AttackBase>().First();
|
||||
var range = GetMaximumRange(self);
|
||||
var range = Util.GetMaximumRange(self);
|
||||
|
||||
if (attack.target == null ||
|
||||
(attack.target.Location - self.Location).LengthSquared > range * range + 2)
|
||||
|
||||
@@ -3,10 +3,10 @@ using System.Linq;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class BelowUnitsInfo : StatelessTraitInfo<BelowUnits> { }
|
||||
|
||||
class BelowUnits : IRenderModifier
|
||||
{
|
||||
public BelowUnits(Actor self) { }
|
||||
|
||||
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
|
||||
{
|
||||
return r.Select(a => a.WithZOffset(-1));
|
||||
|
||||
21
OpenRa.Game/Traits/Buildable.cs
Executable file
21
OpenRa.Game/Traits/Buildable.cs
Executable file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class BuildableInfo : StatelessTraitInfo<Buildable>
|
||||
{
|
||||
public readonly int TechLevel = -1;
|
||||
public readonly string Tab = null;
|
||||
public readonly string[] Prerequisites = { };
|
||||
public readonly Race[] Owner = { };
|
||||
public readonly int Cost = 0;
|
||||
public readonly string Description = "";
|
||||
public readonly string LongDesc = "";
|
||||
public readonly string Icon = null;
|
||||
}
|
||||
|
||||
class Buildable { }
|
||||
}
|
||||
@@ -9,10 +9,35 @@ using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class OwnedActorInfo
|
||||
{
|
||||
public readonly int HP = 0;
|
||||
public readonly ArmorType Armor = ArmorType.none;
|
||||
public readonly bool Crewed = false; // replace with trait?
|
||||
public readonly int InitialFacing = 128;
|
||||
}
|
||||
|
||||
class BuildingInfo : OwnedActorInfo, ITraitInfo
|
||||
{
|
||||
public readonly int Power = 0;
|
||||
public readonly bool RequiresPower = false;
|
||||
public readonly bool BaseNormal = true;
|
||||
public readonly int Adjacent = 1;
|
||||
public readonly bool Bib = false;
|
||||
public readonly bool Capturable = false;
|
||||
public readonly bool Repairable = true;
|
||||
public readonly string Footprint = "x";
|
||||
public readonly string[] Produces = { }; // does this go somewhere else?
|
||||
public readonly int2 Dimensions = new int2(1, 1);
|
||||
public readonly bool WaterBound = false;
|
||||
|
||||
public object Create(Actor self) { return new Building(self); }
|
||||
}
|
||||
|
||||
class Building : INotifyDamage, IResolveOrder, ITick
|
||||
{
|
||||
readonly Actor self;
|
||||
public readonly BuildingInfo unitInfo;
|
||||
public readonly LegacyBuildingInfo unitInfo;
|
||||
[Sync]
|
||||
bool isRepairing = false;
|
||||
[Sync]
|
||||
@@ -24,7 +49,7 @@ namespace OpenRa.Game.Traits
|
||||
public Building(Actor self)
|
||||
{
|
||||
this.self = self;
|
||||
unitInfo = (BuildingInfo)self.Info;
|
||||
unitInfo = (LegacyBuildingInfo)self.LegacyInfo;
|
||||
self.CenterLocation = Game.CellSize
|
||||
* ((float2)self.Location + .5f * (float2)unitInfo.Dimensions);
|
||||
}
|
||||
@@ -79,8 +104,8 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
if (remainingTicks == 0)
|
||||
{
|
||||
var costPerHp = (Rules.General.URepairPercent * self.Info.Cost) / self.Info.Strength;
|
||||
var hpToRepair = Math.Min(Rules.General.URepairStep, self.Info.Strength - self.Health);
|
||||
var costPerHp = (Rules.General.URepairPercent * self.LegacyInfo.Cost) / self.LegacyInfo.Strength;
|
||||
var hpToRepair = Math.Min(Rules.General.URepairStep, self.LegacyInfo.Strength - self.Health);
|
||||
var cost = (int)Math.Ceiling(costPerHp * hpToRepair);
|
||||
if (!self.Owner.TakeCash(cost))
|
||||
{
|
||||
@@ -90,7 +115,7 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
Game.world.AddFrameEndTask(w => w.Add(new RepairIndicator(self)));
|
||||
self.InflictDamage(self, -hpToRepair, Rules.WarheadInfo["Super"]);
|
||||
if (self.Health == self.Info.Strength)
|
||||
if (self.Health == self.LegacyInfo.Strength)
|
||||
{
|
||||
isRepairing = false;
|
||||
return;
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class C4DemolitionInfo : StatelessTraitInfo<C4Demolition> { }
|
||||
|
||||
class C4Demolition : IIssueOrder, IResolveOrder
|
||||
{
|
||||
public C4Demolition(Actor self) { }
|
||||
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
if (mi.Button != MouseButton.Right) return null;
|
||||
|
||||
@@ -7,6 +7,14 @@ using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class CargoInfo : ITraitInfo
|
||||
{
|
||||
public readonly UnitMovementType[] PassengerTypes = { };
|
||||
public readonly int UnloadFacing = 0;
|
||||
|
||||
public object Create(Actor self) { return new Cargo(self); }
|
||||
}
|
||||
|
||||
class Cargo : IPips, IIssueOrder, IResolveOrder
|
||||
{
|
||||
List<Actor> cargo = new List<Actor>();
|
||||
@@ -39,7 +47,7 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
public bool IsFull(Actor self)
|
||||
{
|
||||
return cargo.Count == self.Info.Passengers;
|
||||
return cargo.Count == self.LegacyInfo.Passengers;
|
||||
}
|
||||
|
||||
public bool IsEmpty(Actor self)
|
||||
@@ -56,7 +64,7 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
public IEnumerable<PipType> GetPips( Actor self )
|
||||
{
|
||||
for (var i = 0; i < self.Info.Passengers; i++)
|
||||
for (var i = 0; i < self.LegacyInfo.Passengers; i++)
|
||||
if (i >= cargo.Count)
|
||||
yield return PipType.Transparent;
|
||||
else
|
||||
|
||||
@@ -4,6 +4,11 @@ using OpenRa.Game.Orders;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ChronoshiftDeployInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new ChronoshiftDeploy(self); }
|
||||
}
|
||||
|
||||
class ChronoshiftDeploy : IIssueOrder, IResolveOrder, ISpeedModifier, ITick, IPips
|
||||
{
|
||||
// Recharge logic
|
||||
|
||||
@@ -3,6 +3,9 @@ using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
// this is NOT bound through rules (it belongs on the world actor!)
|
||||
// so no *Info required
|
||||
|
||||
class ChronoshiftPaletteEffect : IPaletteModifier, ITick
|
||||
{
|
||||
const int chronoEffectLength = 20;
|
||||
|
||||
@@ -5,6 +5,11 @@ using System.Linq;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ChronoshiftableInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new Chronoshiftable(self); }
|
||||
}
|
||||
|
||||
class Chronoshiftable : IResolveOrder, ISpeedModifier, ITick
|
||||
{
|
||||
// Return-to-sender logic
|
||||
|
||||
@@ -5,10 +5,10 @@ using System.Text;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ChronosphereInfo : StatelessTraitInfo<Chronosphere> { }
|
||||
|
||||
class Chronosphere : IResolveOrder
|
||||
{
|
||||
public Chronosphere(Actor self) { }
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "PlayAnimation")
|
||||
|
||||
@@ -4,6 +4,11 @@ using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class CloakInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new Cloak(self); }
|
||||
}
|
||||
|
||||
class Cloak : IRenderModifier, INotifyAttack, ITick
|
||||
{
|
||||
[Sync]
|
||||
|
||||
@@ -3,6 +3,11 @@ using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ConstructionYardInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new ConstructionYard(self); }
|
||||
}
|
||||
|
||||
class ConstructionYard : IIssueOrder, IResolveOrder, IMovement
|
||||
{
|
||||
readonly Actor self;
|
||||
|
||||
@@ -6,14 +6,14 @@ using OpenRa.Game.Orders;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class DemoTruckInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new DemoTruck(self); }
|
||||
}
|
||||
|
||||
class DemoTruck : Chronoshiftable, IResolveOrder, INotifyDamage
|
||||
{
|
||||
readonly Actor self;
|
||||
public DemoTruck(Actor self)
|
||||
: base(self)
|
||||
{
|
||||
this.self = self;
|
||||
}
|
||||
public DemoTruck(Actor self) : base(self) {}
|
||||
|
||||
public new void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
@@ -44,7 +44,7 @@ namespace OpenRa.Game.Traits
|
||||
int2 detonateLocation = self.CenterLocation.ToInt2();
|
||||
|
||||
Game.world.AddFrameEndTask(
|
||||
w => w.Add(new Bullet(self.Info.Primary, detonatedBy.Owner, detonatedBy,
|
||||
w => w.Add(new Bullet(self.LegacyInfo.Primary, detonatedBy.Owner, detonatedBy,
|
||||
detonateLocation, detonateLocation, altitude, altitude)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class EngineerCaptureInfo : StatelessTraitInfo<EngineerCapture> { }
|
||||
|
||||
class EngineerCapture : IIssueOrder, IResolveOrder
|
||||
{
|
||||
public const int EngineerDamage = 300; // todo: push into rules, as a weapon
|
||||
|
||||
public EngineerCapture(Actor self) { }
|
||||
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
if (mi.Button != MouseButton.Right) return null;
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ExplodesInfo : StatelessTraitInfo<Explodes> { }
|
||||
|
||||
class Explodes : INotifyDamage
|
||||
{
|
||||
public Explodes(Actor self) {}
|
||||
|
||||
public void Damaged(Actor self, AttackInfo e)
|
||||
{
|
||||
if (self.IsDead)
|
||||
|
||||
@@ -2,13 +2,10 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class FakeInfo : StatelessTraitInfo<Fake> { }
|
||||
|
||||
class Fake : ITags
|
||||
{
|
||||
public Fake(Actor self){}
|
||||
|
||||
public IEnumerable<TagType> GetTags()
|
||||
{
|
||||
yield return TagType.Fake;
|
||||
}
|
||||
public IEnumerable<TagType> GetTags() { yield return TagType.Fake; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class GpsLaunchSite { public GpsLaunchSite(Actor self) { } }
|
||||
class GpsLaunchSiteInfo : StatelessTraitInfo<GpsLaunchSite> { }
|
||||
class GpsLaunchSite { }
|
||||
}
|
||||
|
||||
@@ -3,6 +3,11 @@ using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class HarvesterInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new Harvester(); }
|
||||
}
|
||||
|
||||
class Harvester : IIssueOrder, IResolveOrder, IPips
|
||||
{
|
||||
[Sync]
|
||||
@@ -13,8 +18,6 @@ namespace OpenRa.Game.Traits
|
||||
public bool IsFull { get { return oreCarried + gemsCarried == Rules.General.BailCount; } }
|
||||
public bool IsEmpty { get { return oreCarried == 0 && gemsCarried == 0; } }
|
||||
|
||||
public Harvester(Actor self) { }
|
||||
|
||||
public void AcceptResource(bool isGem)
|
||||
{
|
||||
if (isGem) gemsCarried++;
|
||||
|
||||
@@ -4,6 +4,14 @@ using OpenRa.Game.GameRules;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class HelicopterInfo : ITraitInfo
|
||||
{
|
||||
public readonly int ROT = 0;
|
||||
public readonly int Speed = 0;
|
||||
|
||||
public object Create(Actor self) { return new Helicopter(self); }
|
||||
}
|
||||
|
||||
class Helicopter : IIssueOrder, IResolveOrder, IMovement
|
||||
{
|
||||
public IDisposable reservation;
|
||||
@@ -12,8 +20,8 @@ namespace OpenRa.Game.Traits
|
||||
// todo: push into data!
|
||||
static bool HeliCanEnter(Actor a)
|
||||
{
|
||||
if (a.Info == Rules.UnitInfo["HPAD"]) return true;
|
||||
if (a.Info == Rules.UnitInfo["FIX"]) return true;
|
||||
if (a.LegacyInfo == Rules.UnitInfo["HPAD"]) return true;
|
||||
if (a.LegacyInfo == Rules.UnitInfo["FIX"]) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -44,7 +52,7 @@ namespace OpenRa.Game.Traits
|
||||
{
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new HeliFly(Util.CenterOfCell(order.TargetLocation)));
|
||||
self.QueueActivity(new Turn(self.Info.InitialFacing));
|
||||
self.QueueActivity(new Turn(self.LegacyInfo.InitialFacing));
|
||||
self.QueueActivity(new HeliLand(true));
|
||||
}
|
||||
|
||||
@@ -55,14 +63,14 @@ namespace OpenRa.Game.Traits
|
||||
if (res != null)
|
||||
reservation = res.Reserve(self);
|
||||
|
||||
var offset = (order.TargetActor.Info as BuildingInfo).SpawnOffset;
|
||||
var offset = (order.TargetActor.LegacyInfo as LegacyBuildingInfo).SpawnOffset;
|
||||
var offsetVec = offset != null ? new float2(offset[0], offset[1]) : float2.Zero;
|
||||
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new HeliFly(order.TargetActor.CenterLocation + offsetVec));
|
||||
self.QueueActivity(new Turn(self.Info.InitialFacing));
|
||||
self.QueueActivity(new Turn(self.LegacyInfo.InitialFacing));
|
||||
self.QueueActivity(new HeliLand(false));
|
||||
self.QueueActivity(order.TargetActor.Info == Rules.UnitInfo["HPAD"]
|
||||
self.QueueActivity(order.TargetActor.LegacyInfo == Rules.UnitInfo["HPAD"]
|
||||
? (IActivity)new Rearm() : new Repair());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class InvisibleToOthersInfo : StatelessTraitInfo<InvisibleToOthers> { }
|
||||
|
||||
class InvisibleToOthers : IRenderModifier
|
||||
{
|
||||
public InvisibleToOthers(Actor self) { }
|
||||
|
||||
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
|
||||
{
|
||||
return Game.LocalPlayer == self.Owner
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class IronCurtainInfo : StatelessTraitInfo<IronCurtain> { }
|
||||
|
||||
class IronCurtain : IResolveOrder
|
||||
{
|
||||
public IronCurtain(Actor self) {}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "PlayAnimation")
|
||||
|
||||
@@ -3,13 +3,16 @@ using OpenRa.Game.Effects;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class IronCurtainableInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new IronCurtainable(); }
|
||||
}
|
||||
|
||||
class IronCurtainable : IResolveOrder, IDamageModifier, ITick
|
||||
{
|
||||
[Sync]
|
||||
int RemainingTicks = 0;
|
||||
|
||||
public IronCurtainable(Actor self) { }
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (RemainingTicks > 0)
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class LimitedAmmoInfo : ITraitInfo
|
||||
{
|
||||
public readonly int Ammo = 0;
|
||||
|
||||
public object Create(Actor self) { return new LimitedAmmo(self); }
|
||||
}
|
||||
|
||||
class LimitedAmmo : INotifyAttack, IPips
|
||||
{
|
||||
[Sync]
|
||||
@@ -10,14 +17,14 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
public LimitedAmmo(Actor self)
|
||||
{
|
||||
ammo = self.Info.Ammo;
|
||||
ammo = self.Info.Traits.Get<LimitedAmmoInfo>().Ammo;
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public bool HasAmmo() { return ammo > 0; }
|
||||
public bool GiveAmmo()
|
||||
{
|
||||
if (ammo >= self.Info.Ammo) return false;
|
||||
if (ammo >= self.Info.Traits.Get<LimitedAmmoInfo>().Ammo) return false;
|
||||
++ammo;
|
||||
return true;
|
||||
}
|
||||
@@ -26,7 +33,8 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
public IEnumerable<PipType> GetPips(Actor self)
|
||||
{
|
||||
return Graphics.Util.MakeArray(self.Info.Ammo,
|
||||
var maxAmmo = self.Info.Traits.Get<LimitedAmmoInfo>().Ammo;
|
||||
return Graphics.Util.MakeArray(maxAmmo,
|
||||
i => ammo > i ? PipType.Green : PipType.Transparent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,11 @@ using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class McvDeployInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new McvDeploy(self); }
|
||||
}
|
||||
|
||||
class McvDeploy : IIssueOrder, IResolveOrder
|
||||
{
|
||||
public McvDeploy(Actor self) { }
|
||||
@@ -19,7 +24,7 @@ namespace OpenRa.Game.Traits
|
||||
{
|
||||
if( order.OrderString == "DeployMcv" )
|
||||
{
|
||||
var factBuildingInfo = (BuildingInfo)Rules.UnitInfo[ "fact" ];
|
||||
var factBuildingInfo = (LegacyBuildingInfo)Rules.UnitInfo[ "fact" ];
|
||||
if( Game.CanPlaceBuilding( factBuildingInfo, self.Location - new int2( 1, 1 ), self, false ) )
|
||||
{
|
||||
self.CancelActivity();
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class MineImmune
|
||||
{
|
||||
public MineImmune(Actor self) { }
|
||||
}
|
||||
class MineImmuneInfo : StatelessTraitInfo<MineImmune> { }
|
||||
class MineImmune { }
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class MinelayerInfo : StatelessTraitInfo<Minelayer> { }
|
||||
|
||||
class Minelayer : IIssueOrder, IResolveOrder
|
||||
{
|
||||
public Minelayer(Actor self) { }
|
||||
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
var limitedAmmo = self.traits.GetOrDefault<LimitedAmmo>();
|
||||
@@ -16,7 +13,7 @@ namespace OpenRa.Game.Traits
|
||||
return null;
|
||||
|
||||
// Ensure that the cell is empty except for the minelayer
|
||||
if (Game.UnitInfluence.GetUnitsAt( xy ).Any(a => a != self))
|
||||
if (Game.UnitInfluence.GetUnitsAt(xy).Any(a => a != self))
|
||||
return null;
|
||||
|
||||
if (mi.Button == MouseButton.Right && underCursor == self)
|
||||
@@ -36,7 +33,7 @@ namespace OpenRa.Game.Traits
|
||||
// todo: delay a bit? (req making deploy-mine an activity)
|
||||
|
||||
Game.world.AddFrameEndTask(
|
||||
w => w.Add(new Actor(Rules.UnitInfo[self.Info.Primary], self.Location, self.Owner)));
|
||||
w => w.Add(new Actor(Rules.UnitInfo[self.LegacyInfo.Primary], self.Location, self.Owner)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,15 @@ using OpenRa.Game.GameRules;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class MobileInfo : ITraitInfo
|
||||
{
|
||||
public readonly int Sight = 0;
|
||||
public readonly int ROT = 0;
|
||||
public readonly int Speed = 0;
|
||||
|
||||
public object Create(Actor self) { return new Mobile(self); }
|
||||
}
|
||||
|
||||
class Mobile : IIssueOrder, IResolveOrder, IOccupySpace, IMovement
|
||||
{
|
||||
readonly Actor self;
|
||||
@@ -78,12 +87,12 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
public UnitMovementType GetMovementType()
|
||||
{
|
||||
switch (Rules.UnitCategory[self.Info.Name])
|
||||
switch (Rules.UnitCategory[self.LegacyInfo.Name])
|
||||
{
|
||||
case "Infantry":
|
||||
return UnitMovementType.Foot;
|
||||
case "Vehicle":
|
||||
return (self.Info as VehicleInfo).Tracked ? UnitMovementType.Track : UnitMovementType.Wheel;
|
||||
return (self.LegacyInfo as VehicleInfo).Tracked ? UnitMovementType.Track : UnitMovementType.Wheel;
|
||||
case "Ship":
|
||||
return UnitMovementType.Float;
|
||||
case "Plane":
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class PassengerInfo : StatelessTraitInfo<Passenger> {}
|
||||
|
||||
class Passenger : IIssueOrder, IResolveOrder
|
||||
{
|
||||
public Passenger(Actor self) { }
|
||||
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
if (mi.Button != MouseButton.Right)
|
||||
@@ -23,7 +20,7 @@ namespace OpenRa.Game.Traits
|
||||
return null;
|
||||
|
||||
var umt = self.traits.WithInterface<IMovement>().First().GetMovementType();
|
||||
if (!underCursor.Info.PassengerTypes.Contains(umt))
|
||||
if (!underCursor.LegacyInfo.PassengerTypes.Contains(umt))
|
||||
return null;
|
||||
|
||||
return new Order("EnterTransport", self, underCursor, int2.Zero, null);
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class PlaneInfo : ITraitInfo
|
||||
{
|
||||
public readonly int ROT = 0;
|
||||
public readonly int Speed = 0;
|
||||
|
||||
public object Create(Actor self) { return new Plane(self); }
|
||||
}
|
||||
|
||||
class Plane : IIssueOrder, IResolveOrder, IMovement
|
||||
{
|
||||
public IDisposable reservation;
|
||||
@@ -15,8 +20,8 @@ namespace OpenRa.Game.Traits
|
||||
// todo: push into data!
|
||||
static bool PlaneCanEnter(Actor a)
|
||||
{
|
||||
if (a.Info == Rules.UnitInfo["AFLD"]) return true;
|
||||
if (a.Info == Rules.UnitInfo["FIX"]) return true;
|
||||
if (a.LegacyInfo == Rules.UnitInfo["AFLD"]) return true;
|
||||
if (a.LegacyInfo == Rules.UnitInfo["FIX"]) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -59,7 +64,7 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new ReturnToBase(self, order.TargetActor));
|
||||
self.QueueActivity(order.TargetActor.Info == Rules.UnitInfo["AFLD"]
|
||||
self.QueueActivity(order.TargetActor.LegacyInfo == Rules.UnitInfo["AFLD"]
|
||||
? (IActivity)new Rearm() : new Repair());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
using OpenRa.Game.GameRules;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using OpenRa.Game.GameRules;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ProductionInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new Production(self); }
|
||||
}
|
||||
|
||||
class Production : IIssueOrder, IResolveOrder, IProducer, ITags
|
||||
{
|
||||
bool isPrimary = false;
|
||||
@@ -11,17 +16,17 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
public Production( Actor self ) { }
|
||||
|
||||
public virtual int2? CreationLocation( Actor self, UnitInfo producee )
|
||||
public virtual int2? CreationLocation( Actor self, LegacyUnitInfo producee )
|
||||
{
|
||||
return ( 1 / 24f * self.CenterLocation ).ToInt2();
|
||||
}
|
||||
|
||||
public virtual int CreationFacing( Actor self, Actor newUnit )
|
||||
{
|
||||
return newUnit.Info.InitialFacing;
|
||||
return newUnit.LegacyInfo.InitialFacing;
|
||||
}
|
||||
|
||||
public bool Produce( Actor self, UnitInfo producee )
|
||||
public bool Produce( Actor self, LegacyUnitInfo producee )
|
||||
{
|
||||
var location = CreationLocation( self, producee );
|
||||
if( location == null || Game.UnitInfluence.GetUnitsAt( location.Value ).Any() )
|
||||
@@ -38,7 +43,7 @@ namespace OpenRa.Game.Traits
|
||||
newUnit.QueueActivity( new Activities.Move( rp.rallyPoint, 1 ) );
|
||||
}
|
||||
|
||||
var bi = self.Info as BuildingInfo;
|
||||
var bi = self.LegacyInfo as LegacyBuildingInfo;
|
||||
if (bi != null && bi.SpawnOffset != null)
|
||||
newUnit.CenterLocation = self.CenterLocation
|
||||
+ new float2(bi.SpawnOffset[0], bi.SpawnOffset[1]);
|
||||
@@ -78,12 +83,12 @@ namespace OpenRa.Game.Traits
|
||||
}
|
||||
|
||||
// Cancel existing primaries
|
||||
foreach (var p in (self.Info as BuildingInfo).Produces)
|
||||
foreach (var p in (self.LegacyInfo as LegacyBuildingInfo).Produces)
|
||||
{
|
||||
foreach (var b in Game.world.Actors.Where(x => x.traits.Contains<Production>()
|
||||
&& x.Owner == self.Owner
|
||||
&& x.traits.Get<Production>().IsPrimary == true
|
||||
&& (x.Info as BuildingInfo).Produces.Contains(p)))
|
||||
&& (x.LegacyInfo as LegacyBuildingInfo).Produces.Contains(p)))
|
||||
{
|
||||
b.traits.Get<Production>().SetPrimaryProducer(b, false);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,11 @@ using IjwFramework.Collections;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ProductionQueueInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new ProductionQueue(self); }
|
||||
}
|
||||
|
||||
class ProductionQueue : IResolveOrder, ITick
|
||||
{
|
||||
Actor self;
|
||||
@@ -128,7 +133,7 @@ namespace OpenRa.Game.Traits
|
||||
// Prioritise primary structure in build order
|
||||
var primaryProducers = Game.world.Actors
|
||||
.Where(x => x.traits.Contains<Production>()
|
||||
&& producerTypes.Contains(x.Info)
|
||||
&& producerTypes.Contains(x.LegacyInfo)
|
||||
&& x.Owner == self.Owner
|
||||
&& x.traits.Get<Production>().IsPrimary == true);
|
||||
|
||||
@@ -148,7 +153,7 @@ namespace OpenRa.Game.Traits
|
||||
if (producer == null)
|
||||
{
|
||||
producer = Game.world.Actors
|
||||
.Where( x => producerTypes.Contains( x.Info ) && x.Owner == self.Owner )
|
||||
.Where( x => producerTypes.Contains( x.LegacyInfo ) && x.Owner == self.Owner )
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenRa.Game.GameRules;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ProductionSurroundInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new ProductionSurround(self); }
|
||||
}
|
||||
|
||||
class ProductionSurround : Production
|
||||
{
|
||||
public ProductionSurround(Actor self) : base(self) { }
|
||||
@@ -24,7 +26,7 @@ namespace OpenRa.Game.Traits
|
||||
return null;
|
||||
}
|
||||
|
||||
public override int2? CreationLocation(Actor self, UnitInfo producee)
|
||||
public override int2? CreationLocation(Actor self, LegacyUnitInfo producee)
|
||||
{
|
||||
return FindAdjacentTile(self, producee.WaterBound ?
|
||||
UnitMovementType.Float : UnitMovementType.Wheel); /* hackety hack */
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ProvidesRadarInfo : StatelessTraitInfo<ProvidesRadar> {}
|
||||
|
||||
class ProvidesRadar
|
||||
{
|
||||
Actor self;
|
||||
public ProvidesRadar(Actor self)
|
||||
{
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public bool IsActive()
|
||||
public bool IsActive(Actor self)
|
||||
{
|
||||
// TODO: Check for nearby MRJ
|
||||
|
||||
|
||||
@@ -4,6 +4,11 @@ using OpenRa.Game.Orders;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RallyPointInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new RallyPoint(self); }
|
||||
}
|
||||
|
||||
class RallyPoint : IRender, IIssueOrder, IResolveOrder, ITick
|
||||
{
|
||||
[Sync]
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenRa.Game.Graphics;
|
||||
using OpenRa.Game.Effects;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RenderBuildingInfo : RenderSimpleInfo
|
||||
{
|
||||
public override object Create(Actor self) { return new RenderBuilding(self); }
|
||||
}
|
||||
|
||||
class RenderBuilding : RenderSimple, INotifyDamage, INotifySold
|
||||
{
|
||||
const int SmallBibStart = 1;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RenderBuildingChargeInfo : RenderBuildingInfo
|
||||
{
|
||||
public override object Create(Actor self) { return new RenderBuildingCharge(self); }
|
||||
}
|
||||
|
||||
/* used for tesla */
|
||||
class RenderBuildingCharge : RenderBuilding, INotifyAttack
|
||||
{
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
using System;
|
||||
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RenderBuildingOreInfo : RenderBuildingInfo
|
||||
{
|
||||
public override object Create(Actor self) { return new RenderBuildingOre(self); }
|
||||
}
|
||||
|
||||
class RenderBuildingOre : RenderBuilding, INotifyBuildComplete
|
||||
{
|
||||
public RenderBuildingOre(Actor self)
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RenderBuildingTurretedInfo : RenderBuildingInfo
|
||||
{
|
||||
public override object Create(Actor self) { return new RenderBuildingTurreted(self); }
|
||||
}
|
||||
|
||||
class RenderBuildingTurreted : RenderBuilding, INotifyBuildComplete
|
||||
{
|
||||
public RenderBuildingTurreted(Actor self)
|
||||
|
||||
@@ -4,6 +4,11 @@ using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RenderWarFactoryInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new RenderWarFactory(self); }
|
||||
}
|
||||
|
||||
class RenderWarFactory : IRender, INotifyBuildComplete, INotifyDamage, ITick, INotifyProduction
|
||||
{
|
||||
public Animation roof;
|
||||
@@ -21,7 +26,7 @@ namespace OpenRa.Game.Traits
|
||||
public RenderWarFactory(Actor self)
|
||||
{
|
||||
this.self = self;
|
||||
roof = new Animation(self.Info.Image ?? self.Info.Name);
|
||||
roof = new Animation(self.LegacyInfo.Image ?? self.LegacyInfo.Name);
|
||||
}
|
||||
|
||||
public void BuildingComplete( Actor self )
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRa.Game.Graphics;
|
||||
using OpenRa.Game.GameRules;
|
||||
using OpenRa.Game.Effects;
|
||||
using OpenRa.Game.Effects;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RenderInfantryInfo : RenderSimpleInfo
|
||||
{
|
||||
public override object Create(Actor self) { return new RenderInfantry(self); }
|
||||
}
|
||||
|
||||
class RenderInfantry : RenderSimple, INotifyAttack, INotifyDamage
|
||||
{
|
||||
public RenderInfantry(Actor self)
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using IjwFramework.Collections;
|
||||
using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
abstract class RenderSimpleInfo : ITraitInfo
|
||||
{
|
||||
public readonly string Image = null;
|
||||
|
||||
public abstract object Create(Actor self);
|
||||
}
|
||||
|
||||
abstract class RenderSimple : IRender, ITick
|
||||
{
|
||||
public Dictionary<string, AnimationWithOffset> anims = new Dictionary<string, AnimationWithOffset>();
|
||||
@@ -12,7 +18,7 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
public RenderSimple(Actor self)
|
||||
{
|
||||
anims.Add( "", new Animation( self.Info.Image ?? self.Info.Name ) );
|
||||
anims.Add( "", new Animation( self.LegacyInfo.Image ?? self.LegacyInfo.Name ) );
|
||||
}
|
||||
|
||||
public virtual IEnumerable<Renderable> Render( Actor self )
|
||||
|
||||
@@ -5,6 +5,11 @@ using OpenRa.Game.GameRules;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RenderUnitInfo : RenderSimpleInfo
|
||||
{
|
||||
public override object Create(Actor self) { return new RenderUnit(self); }
|
||||
}
|
||||
|
||||
class RenderUnit : RenderSimple, INotifyDamage
|
||||
{
|
||||
public RenderUnit(Actor self)
|
||||
|
||||
@@ -5,22 +5,25 @@ using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RenderUnitMuzzleFlashInfo : RenderUnitInfo
|
||||
{
|
||||
public override object Create(Actor self) { return new RenderUnitMuzzleFlash(self); }
|
||||
}
|
||||
|
||||
class RenderUnitMuzzleFlash : RenderUnit
|
||||
{
|
||||
public RenderUnitMuzzleFlash(Actor self)
|
||||
: base(self)
|
||||
{
|
||||
if (!self.Info.MuzzleFlash) throw new InvalidOperationException("wtf??");
|
||||
|
||||
var unit = self.traits.Get<Unit>();
|
||||
var attack = self.traits.WithInterface<AttackBase>().First();
|
||||
|
||||
var muzzleFlash = new Animation(self.Info.Name);
|
||||
var muzzleFlash = new Animation(self.LegacyInfo.Name);
|
||||
muzzleFlash.PlayFetchIndex("muzzle",
|
||||
() => (Util.QuantizeFacing(unit.Facing, 8)) * 6 + (int)(attack.primaryRecoil * 5.9f));
|
||||
anims.Add( "muzzle", new AnimationWithOffset(
|
||||
muzzleFlash,
|
||||
() => self.Info.PrimaryOffset.AbsOffset(),
|
||||
() => self.LegacyInfo.PrimaryOffset.AbsOffset(),
|
||||
() => attack.primaryRecoil <= 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RenderUnitReloadInfo : RenderUnitInfo
|
||||
{
|
||||
public override object Create(Actor self) { return new RenderUnitReload(self); }
|
||||
}
|
||||
|
||||
class RenderUnitReload : RenderUnit
|
||||
{
|
||||
public RenderUnitReload(Actor self)
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RenderUnitRotorInfo : RenderUnitInfo
|
||||
{
|
||||
public readonly int[] PrimaryOffset = { 0, 0 };
|
||||
public readonly int[] SecondaryOffset = null;
|
||||
|
||||
public override object Create(Actor self) { return new RenderUnitRotor(self); }
|
||||
}
|
||||
|
||||
class RenderUnitRotor : RenderUnit
|
||||
{
|
||||
public Animation rotorAnim, secondRotorAnim;
|
||||
@@ -10,21 +18,22 @@ namespace OpenRa.Game.Traits
|
||||
: base(self)
|
||||
{
|
||||
var unit = self.traits.Get<Unit>();
|
||||
var info = self.Info.Traits.Get<RenderUnitRotorInfo>();
|
||||
|
||||
rotorAnim = new Animation(self.Info.Name);
|
||||
rotorAnim = new Animation(info.Image ?? self.Info.Name);
|
||||
rotorAnim.PlayRepeating("rotor");
|
||||
anims.Add( "rotor_1", new AnimationWithOffset(
|
||||
rotorAnim,
|
||||
() => Util.GetTurretPosition( self, unit, self.Info.RotorOffset, 0 ),
|
||||
() => Util.GetTurretPosition( self, unit, info.PrimaryOffset, 0 ),
|
||||
null ) );
|
||||
|
||||
if (self.Info.RotorOffset2 == null) return;
|
||||
if (info.SecondaryOffset == null) return;
|
||||
|
||||
secondRotorAnim = new Animation( self.Info.Name );
|
||||
secondRotorAnim = new Animation(info.Image ?? self.Info.Name);
|
||||
secondRotorAnim.PlayRepeating( "rotor2" );
|
||||
anims.Add( "rotor_2", new AnimationWithOffset(
|
||||
secondRotorAnim,
|
||||
() => Util.GetTurretPosition(self, unit, self.Info.RotorOffset2, 0),
|
||||
() => Util.GetTurretPosition(self, unit, info.SecondaryOffset, 0),
|
||||
null ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RenderUnitSpinnerInfo : RenderUnitInfo
|
||||
{
|
||||
public readonly int[] Offset = { 0, 0 };
|
||||
public override object Create(Actor self) { return new RenderUnitSpinner(self); }
|
||||
}
|
||||
|
||||
class RenderUnitSpinner : RenderUnit
|
||||
{
|
||||
public Animation spinnerAnim;
|
||||
|
||||
public RenderUnitSpinner( Actor self )
|
||||
: base(self)
|
||||
{
|
||||
var unit = self.traits.Get<Unit>();
|
||||
var info = self.Info.Traits.Get<RenderUnitSpinnerInfo>();
|
||||
|
||||
spinnerAnim = new Animation( self.Info.Name );
|
||||
var spinnerAnim = new Animation( info.Image ?? self.Info.Name );
|
||||
spinnerAnim.PlayRepeating( "spinner" );
|
||||
anims.Add( "spinner", new AnimationWithOffset(
|
||||
spinnerAnim,
|
||||
() => Util.GetTurretPosition( self, unit, self.Info.PrimaryOffset, 0 ),
|
||||
() => Util.GetTurretPosition( self, unit, info.Offset, 0 ),
|
||||
null ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,13 @@ using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RenderUnitTurretedInfo : RenderUnitInfo
|
||||
{
|
||||
public override object Create(Actor self) { return new RenderUnitTurreted(self); }
|
||||
}
|
||||
|
||||
class RenderUnitTurreted : RenderUnit
|
||||
{
|
||||
public Animation muzzleFlash;
|
||||
|
||||
public RenderUnitTurreted(Actor self)
|
||||
: base(self)
|
||||
{
|
||||
@@ -15,30 +18,30 @@ namespace OpenRa.Game.Traits
|
||||
var turreted = self.traits.Get<Turreted>();
|
||||
var attack = self.traits.WithInterface<AttackBase>().FirstOrDefault();
|
||||
|
||||
var turretAnim = new Animation(self.Info.Name);
|
||||
var turretAnim = new Animation(self.LegacyInfo.Name);
|
||||
turretAnim.PlayFacing( "turret", () => turreted.turretFacing );
|
||||
|
||||
if( self.Info.PrimaryOffset != null )
|
||||
if( self.LegacyInfo.PrimaryOffset != null )
|
||||
anims.Add("turret_1", new AnimationWithOffset(
|
||||
turretAnim,
|
||||
() => Util.GetTurretPosition(self, unit, self.Info.PrimaryOffset, attack.primaryRecoil),
|
||||
() => Util.GetTurretPosition(self, unit, self.LegacyInfo.PrimaryOffset, attack.primaryRecoil),
|
||||
null) { ZOffset = 1 });
|
||||
|
||||
if( self.Info.SecondaryOffset != null )
|
||||
if( self.LegacyInfo.SecondaryOffset != null )
|
||||
anims.Add("turret_2", new AnimationWithOffset(
|
||||
turretAnim,
|
||||
() => Util.GetTurretPosition(self, unit, self.Info.SecondaryOffset, attack.secondaryRecoil),
|
||||
() => Util.GetTurretPosition(self, unit, self.LegacyInfo.SecondaryOffset, attack.secondaryRecoil),
|
||||
null) { ZOffset = 1 });
|
||||
|
||||
if( self.Info.MuzzleFlash )
|
||||
if( self.LegacyInfo.MuzzleFlash )
|
||||
{
|
||||
muzzleFlash = new Animation( self.Info.Name );
|
||||
var muzzleFlash = new Animation( self.LegacyInfo.Name );
|
||||
muzzleFlash.PlayFetchIndex( "muzzle",
|
||||
() => ( Util.QuantizeFacing( self.traits.Get<Turreted>().turretFacing, 8 ) ) * 6
|
||||
+ (int)( attack.primaryRecoil * 5.9f ) ); /* hack: recoil can be 1.0f, but don't overflow into next anim */
|
||||
anims.Add( "muzzle_flash", new AnimationWithOffset(
|
||||
muzzleFlash,
|
||||
() => Util.GetTurretPosition( self, unit, self.Info.PrimaryOffset, attack.primaryRecoil ),
|
||||
() => Util.GetTurretPosition( self, unit, self.LegacyInfo.PrimaryOffset, attack.primaryRecoil ),
|
||||
() => attack.primaryRecoil <= 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,11 @@ using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RepairableInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new Repairable(self); }
|
||||
}
|
||||
|
||||
class Repairable : IIssueOrder, IResolveOrder
|
||||
{
|
||||
IDisposable reservation;
|
||||
@@ -16,7 +21,7 @@ namespace OpenRa.Game.Traits
|
||||
if (mi.Button != MouseButton.Right) return null;
|
||||
if (underCursor == null) return null;
|
||||
|
||||
if (underCursor.Info == Rules.UnitInfo["FIX"]
|
||||
if (underCursor.LegacyInfo == Rules.UnitInfo["FIX"]
|
||||
&& underCursor.Owner == self.Owner
|
||||
&& !Reservable.IsReserved(underCursor))
|
||||
return new Order("Enter", self, underCursor, int2.Zero, null);
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ReservableInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new Reservable(self); }
|
||||
}
|
||||
|
||||
class Reservable : ITick
|
||||
{
|
||||
public Reservable(Actor self) { }
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class SeedsOreInfo : StatelessTraitInfo<SeedsOre> {}
|
||||
|
||||
class SeedsOre : ITick
|
||||
{
|
||||
public SeedsOre( Actor self ) {}
|
||||
|
||||
const double OreSeedProbability = .05; // todo: push this out into rules
|
||||
|
||||
public void Tick(Actor self)
|
||||
|
||||
16
OpenRa.Game/Traits/Selectable.cs
Executable file
16
OpenRa.Game/Traits/Selectable.cs
Executable file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class SelectableInfo : StatelessTraitInfo<Selectable>
|
||||
{
|
||||
public readonly int Priority = 10;
|
||||
public readonly int[] Bounds = null;
|
||||
public readonly string Voice = "GenericVoice";
|
||||
}
|
||||
|
||||
class Selectable {}
|
||||
}
|
||||
@@ -5,6 +5,11 @@ using OpenRa.Game.GameRules;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class SquishByTankInfo : ITraitInfo
|
||||
{
|
||||
public object Create(Actor self) { return new SquishByTank(self); }
|
||||
}
|
||||
|
||||
class SquishByTank : ICrushable
|
||||
{
|
||||
readonly Actor self;
|
||||
|
||||
@@ -3,21 +3,18 @@ using System;
|
||||
using OpenRa.Game.GameRules;
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class StoresOreInfo : StatelessTraitInfo<StoresOre>
|
||||
{
|
||||
public readonly int Pips = 0;
|
||||
public readonly int Capacity = 0;
|
||||
}
|
||||
|
||||
class StoresOre : IPips, IAcceptThief
|
||||
{
|
||||
public const int MaxStealAmount = 100; //todo: How is cash stolen determined?
|
||||
|
||||
readonly Actor self;
|
||||
|
||||
public StoresOre(Actor self)
|
||||
{
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public void OnSteal(Actor self, Actor thief)
|
||||
{
|
||||
// Steal half the ore the building holds
|
||||
var toSteal = (self.Info as BuildingInfo).Storage/2;
|
||||
var toSteal = self.Info.Traits.Get<StoresOreInfo>().Capacity / 2;
|
||||
self.Owner.TakeCash(toSteal);
|
||||
thief.Owner.GiveCash(toSteal);
|
||||
|
||||
@@ -31,15 +28,12 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
public IEnumerable<PipType> GetPips(Actor self)
|
||||
{
|
||||
for (int i = 0; i < self.Info.OrePips; i++)
|
||||
{
|
||||
if (Game.LocalPlayer.GetSiloFullness() > i * 1.0f / self.Info.OrePips)
|
||||
{
|
||||
yield return PipType.Yellow;
|
||||
continue;
|
||||
}
|
||||
yield return PipType.Transparent;
|
||||
}
|
||||
var numPips = self.Info.Traits.Get<StoresOreInfo>().Pips;
|
||||
|
||||
return Graphics.Util.MakeArray( numPips,
|
||||
i => (Game.LocalPlayer.GetSiloFullness() > i * 1.0f / numPips)
|
||||
? PipType.Yellow : PipType.Transparent );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user