use the new actorinit stuff when loading map yaml

This commit is contained in:
Bob
2010-08-01 15:25:57 +12:00
parent 10b7ece62e
commit 970eb4d6e1
8 changed files with 104 additions and 28 deletions

View File

@@ -28,13 +28,15 @@ namespace OpenRA.FileFormats
throw new NotImplementedException( "FieldLoader: Missing field `{0}` on `{1}`".F( s, f.Name ) ); throw new NotImplementedException( "FieldLoader: Missing field `{0}` on `{1}`".F( s, f.Name ) );
}; };
public static void Load(object self, MiniYaml my) { Load(self, my.Nodes); } public static void Load( object self, MiniYaml my )
public static void Load(object self, Dictionary<string, MiniYaml> my)
{ {
foreach (var x in my) foreach( var x in my.Nodes )
if (!x.Key.StartsWith("-")) if (!x.Key.StartsWith("-"))
LoadField(self, x.Key, x.Value.Value); LoadField(self, x.Key, x.Value.Value);
foreach( var field in self.GetType().GetFields())
if( field.HasAttribute<FieldFromYamlKeyAttribute>() )
field.SetValue( self, GetValue( field.Name, field.FieldType, my.Value ) );
} }
public static T Load<T>(MiniYaml y) where T : new() public static T Load<T>(MiniYaml y) where T : new()
@@ -58,7 +60,9 @@ namespace OpenRA.FileFormats
var field = self.GetType().GetField( key.Trim() ); var field = self.GetType().GetField( key.Trim() );
if( field == null ) if( field == null )
UnknownFieldAction(key.Trim(), self.GetType()); UnknownFieldAction( key.Trim(), self.GetType() );
else if( field.HasAttribute<FieldFromYamlKeyAttribute>() )
return;
else else
field.SetValue( self, GetValue( field.Name, field.FieldType, value ) ); field.SetValue( self, GetValue( field.Name, field.FieldType, value ) );
} }
@@ -150,10 +154,18 @@ namespace OpenRA.FileFormats
{ {
public static MiniYaml Save(object o) public static MiniYaml Save(object o)
{ {
return new MiniYaml(null, o.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance) var dict = new Dictionary<string, MiniYaml>();
.ToDictionary( string root = null;
f => f.Name,
f => new MiniYaml(FormatValue(o, f)))); foreach( var f in o.GetType().GetFields( BindingFlags.Public | BindingFlags.Instance ) )
{
if( f.HasAttribute<FieldFromYamlKeyAttribute>() )
root = FormatValue( o, f );
else
dict.Add( f.Name, new MiniYaml( FormatValue( o, f ) ) );
}
return new MiniYaml( root, dict );
} }
public static MiniYaml SaveDifferences(object o, object from) public static MiniYaml SaveDifferences(object o, object from)
@@ -187,4 +199,6 @@ namespace OpenRA.FileFormats
: v.ToString(); : v.ToString();
} }
} }
public class FieldFromYamlKeyAttribute : Attribute { }
} }

View File

@@ -76,7 +76,6 @@
<Compile Include="Support\Stopwatch.cs" /> <Compile Include="Support\Stopwatch.cs" />
<Compile Include="Support\Timer.cs" /> <Compile Include="Support\Timer.cs" />
<Compile Include="TypeDictionary.cs" /> <Compile Include="TypeDictionary.cs" />
<Compile Include="Map\ActorReference.cs" />
<Compile Include="Map\TileReference.cs" /> <Compile Include="Map\TileReference.cs" />
<Compile Include="Map\Terrain.cs" /> <Compile Include="Map\Terrain.cs" />
<Compile Include="Primitives\Cache.cs" /> <Compile Include="Primitives\Cache.cs" />

View File

@@ -49,8 +49,11 @@ namespace OpenRA
public class LocationInit : IActorInit<int2> public class LocationInit : IActorInit<int2>
{ {
[FieldFromYamlKey]
public readonly int2 value = int2.Zero; public readonly int2 value = int2.Zero;
public LocationInit() { }
public LocationInit( int2 init ) public LocationInit( int2 init )
{ {
value = init; value = init;
@@ -64,9 +67,17 @@ namespace OpenRA
public class OwnerInit : IActorInit<Player> public class OwnerInit : IActorInit<Player>
{ {
[FieldFromYamlKey]
public readonly string PlayerName = "Neutral"; public readonly string PlayerName = "Neutral";
Player player; Player player;
public OwnerInit() { }
public OwnerInit( string playerName )
{
this.PlayerName = playerName;
}
public OwnerInit( Player player ) public OwnerInit( Player player )
{ {
this.player = player; this.player = player;

53
OpenRA.Game/ActorReference.cs Executable file
View File

@@ -0,0 +1,53 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see LICENSE.
*/
#endregion
using System.Collections.Generic;
using System.Collections;
namespace OpenRA.FileFormats
{
public class ActorReference : IEnumerable
{
public readonly string Type;
public readonly TypeDictionary InitDict;
public ActorReference( string type ) : this( type, new Dictionary<string, MiniYaml>() ) { }
public ActorReference( string type, Dictionary<string, MiniYaml> inits )
{
Type = type;
InitDict = new TypeDictionary();
foreach( var i in inits )
InitDict.Add( LoadInit( i.Key, i.Value ) );
}
static IActorInit LoadInit(string traitName, MiniYaml my)
{
var info = Game.CreateObject<IActorInit>(traitName + "Init");
FieldLoader.Load(info, my);
return info;
}
public MiniYaml Save()
{
var ret = new MiniYaml( Type );
foreach( var init in InitDict )
{
var initName = init.GetType().Name;
ret.Nodes.Add( initName.Substring( 0, initName.Length - 4 ), FieldSaver.Save( init ) );
}
return ret;
}
// for initialization syntax
public void Add( object o ) { InitDict.Add( o ); }
public IEnumerator GetEnumerator() { return InitDict.GetEnumerator(); }
}
}

View File

@@ -14,7 +14,7 @@ using System.Linq;
using OpenRA.FileFormats; using OpenRA.FileFormats;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.GameRules namespace OpenRA
{ {
public class ActorInfo public class ActorInfo
{ {

View File

@@ -123,20 +123,19 @@ namespace OpenRA
int actors = 0; int actors = 0;
foreach (var kv in yaml["Actors"].Nodes) foreach (var kv in yaml["Actors"].Nodes)
{ {
string[] vals = kv.Value.Value.Split(' '); string[] vals = kv.Value.Value.Split(' ');
string[] loc = vals[2].Split(','); string[] loc = vals[2].Split(',');
var a = new ActorReference("Actor"+actors++, vals[0], new int2(int.Parse(loc[0]), int.Parse(loc[1])), "Neutral"); Actors.Add( "Actor" + actors++, new ActorReference( vals[ 0 ] )
Actors.Add(a.Id, a); {
new LocationInit( new int2( int.Parse( loc[ 0 ] ), int.Parse( loc[ 1 ] ) ) ),
new OwnerInit( "Neutral" ),
} );
} }
} }
else else
{ {
foreach (var kv in yaml["Actors"].Nodes) foreach( var kv in yaml[ "Actors" ].Nodes )
{ Actors.Add( kv.Key, new ActorReference( kv.Value.Value, kv.Value.Nodes ) );
kv.Value.Nodes.Add( "Type", new MiniYaml( kv.Value.Value ) );
var a = new ActorReference(kv.Key, kv.Value);
Actors.Add(a.Id, a);
}
} }
// Smudges // Smudges
@@ -173,10 +172,10 @@ namespace OpenRA
p => FieldSaver.Save(p.Value)))); p => FieldSaver.Save(p.Value))));
root.Add("Actors", root.Add("Actors",
new MiniYaml(null, Actors.ToDictionary( new MiniYaml( null, Actors.ToDictionary(
a => "{0}".F(a.Key), x => x.Key,
a => FieldSaver.Save(a.Value)))); x => x.Value.Save() ) ) );
root.Add("Waypoints", MiniYaml.FromDictionary<string, int2>(Waypoints)); root.Add("Waypoints", MiniYaml.FromDictionary<string, int2>(Waypoints));
root.Add("Smudges", MiniYaml.FromList<SmudgeReference>(Smudges)); root.Add("Smudges", MiniYaml.FromList<SmudgeReference>(Smudges));
root.Add("Rules", new MiniYaml(null, Rules)); root.Add("Rules", new MiniYaml(null, Rules));

View File

@@ -228,6 +228,7 @@
<Name>OpenRA.FileFormats</Name> <Name>OpenRA.FileFormats</Name>
</ProjectReference> </ProjectReference>
<Compile Include="ActorInitializer.cs" /> <Compile Include="ActorInitializer.cs" />
<Compile Include="ActorReference.cs" />
<Compile Include="Map.cs" /> <Compile Include="Map.cs" />
<Compile Include="Widgets\Delegates\DeveloperModeDelegate.cs" /> <Compile Include="Widgets\Delegates\DeveloperModeDelegate.cs" />
</ItemGroup> </ItemGroup>

View File

@@ -25,8 +25,7 @@ namespace OpenRA.Mods.RA
Game.skipMakeAnims = true; // rude hack Game.skipMakeAnims = true; // rude hack
foreach (var actorReference in world.Map.Actors) foreach (var actorReference in world.Map.Actors)
MapActors[actorReference.Key] = world.CreateActor(actorReference.Value.Type, actorReference.Value.Location, MapActors[actorReference.Key] = world.CreateActor(actorReference.Value.Type, actorReference.Value.InitDict);
world.players.Values.FirstOrDefault(p => p.InternalName == actorReference.Value.Owner));
Game.skipMakeAnims = false; Game.skipMakeAnims = false;
} }