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 ) );
};
public static void Load(object self, MiniYaml my) { Load(self, my.Nodes); }
public static void Load(object self, Dictionary<string, MiniYaml> my)
public static void Load( object self, MiniYaml my )
{
foreach (var x in my)
foreach( var x in my.Nodes )
if (!x.Key.StartsWith("-"))
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()
@@ -59,6 +61,8 @@ namespace OpenRA.FileFormats
if( field == null )
UnknownFieldAction( key.Trim(), self.GetType() );
else if( field.HasAttribute<FieldFromYamlKeyAttribute>() )
return;
else
field.SetValue( self, GetValue( field.Name, field.FieldType, value ) );
}
@@ -150,10 +154,18 @@ namespace OpenRA.FileFormats
{
public static MiniYaml Save(object o)
{
return new MiniYaml(null, o.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance)
.ToDictionary(
f => f.Name,
f => new MiniYaml(FormatValue(o, f))));
var dict = new Dictionary<string, MiniYaml>();
string root = null;
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)
@@ -187,4 +199,6 @@ namespace OpenRA.FileFormats
: v.ToString();
}
}
public class FieldFromYamlKeyAttribute : Attribute { }
}

View File

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

View File

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

View File

@@ -125,18 +125,17 @@ namespace OpenRA
{
string[] vals = kv.Value.Value.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(a.Id, a);
Actors.Add( "Actor" + actors++, new ActorReference( vals[ 0 ] )
{
new LocationInit( new int2( int.Parse( loc[ 0 ] ), int.Parse( loc[ 1 ] ) ) ),
new OwnerInit( "Neutral" ),
} );
}
}
else
{
foreach( var kv in yaml[ "Actors" ].Nodes )
{
kv.Value.Nodes.Add( "Type", new MiniYaml( kv.Value.Value ) );
var a = new ActorReference(kv.Key, kv.Value);
Actors.Add(a.Id, a);
}
Actors.Add( kv.Key, new ActorReference( kv.Value.Value, kv.Value.Nodes ) );
}
// Smudges
@@ -174,8 +173,8 @@ namespace OpenRA
root.Add("Actors",
new MiniYaml( null, Actors.ToDictionary(
a => "{0}".F(a.Key),
a => FieldSaver.Save(a.Value))));
x => x.Key,
x => x.Value.Save() ) ) );
root.Add("Waypoints", MiniYaml.FromDictionary<string, int2>(Waypoints));
root.Add("Smudges", MiniYaml.FromList<SmudgeReference>(Smudges));

View File

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

View File

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