public Player(World world, Session.Client client, PlayerReference pr) { string botType; World = world; InternalName = pr.Name; PlayerReference = pr; // Real player or host-created bot if (client != null) { ClientIndex = client.Index; Color = client.Color; PlayerName = client.Name; botType = client.Bot; Faction = ChooseFaction(world, client.Faction, !pr.LockFaction); DisplayFaction = ChooseDisplayFaction(world, client.Faction); } else { // Map player ClientIndex = 0; // Owned by the host (TODO: fix this) Color = pr.Color; PlayerName = pr.Name; NonCombatant = pr.NonCombatant; Playable = pr.Playable; Spectating = pr.Spectating; botType = pr.Bot; Faction = ChooseFaction(world, pr.Faction, false); DisplayFaction = ChooseDisplayFaction(world, pr.Faction); } PlayerActor = world.CreateActor("Player", new TypeDictionary { new OwnerInit(this) }); Shroud = PlayerActor.Trait <Shroud>(); fogVisibilities = PlayerActor.TraitsImplementing <IFogVisibilityModifier>().ToArray(); // Enable the bot logic on the host IsBot = botType != null; if (IsBot && Game.IsHost) { var logic = PlayerActor.TraitsImplementing <IBot>().FirstOrDefault(b => b.Info.Name == botType); if (logic == null) { Log.Write("debug", "Invalid bot type: {0}", botType); } else { logic.Activate(this); } } stanceColors.Self = ChromeMetrics.Get <Color>("PlayerStanceColorSelf"); stanceColors.Allies = ChromeMetrics.Get <Color>("PlayerStanceColorAllies"); stanceColors.Enemies = ChromeMetrics.Get <Color>("PlayerStanceColorEnemies"); stanceColors.Neutrals = ChromeMetrics.Get <Color>("PlayerStanceColorNeutrals"); }
public Player(World world, Session.Client client, PlayerReference pr) { string botType; World = world; InternalName = pr.Name; PlayerReference = pr; // Real player or host-created bot if (client != null) { ClientIndex = client.Index; Color = client.Color; PlayerName = client.Name; botType = client.Bot; Faction = ChooseFaction(world, client.Faction, !pr.LockFaction); DisplayFaction = ChooseDisplayFaction(world, client.Faction); } else { // Map player ClientIndex = 0; // Owned by the host (TODO: fix this) Color = pr.Color; PlayerName = pr.Name; NonCombatant = pr.NonCombatant; Playable = pr.Playable; Spectating = pr.Spectating; botType = pr.Bot; Faction = ChooseFaction(world, pr.Faction, false); DisplayFaction = ChooseDisplayFaction(world, pr.Faction); } PlayerActor = world.CreateActor("Player", new TypeDictionary { new OwnerInit(this) }); Shroud = PlayerActor.Trait<Shroud>(); fogVisibilities = PlayerActor.TraitsImplementing<IFogVisibilityModifier>().ToArray(); // Enable the bot logic on the host IsBot = botType != null; if (IsBot && Game.IsHost) { var logic = PlayerActor.TraitsImplementing<IBot>().FirstOrDefault(b => b.Info.Name == botType); if (logic == null) Log.Write("debug", "Invalid bot type: {0}", botType); else logic.Activate(this); } stanceColors.Self = ChromeMetrics.Get<Color>("PlayerStanceColorSelf"); stanceColors.Allies = ChromeMetrics.Get<Color>("PlayerStanceColorAllies"); stanceColors.Enemies = ChromeMetrics.Get<Color>("PlayerStanceColorEnemies"); stanceColors.Neutrals = ChromeMetrics.Get<Color>("PlayerStanceColorNeutrals"); }
public Player(World world, Session.Client client, Session.Slot slot, PlayerReference pr) { World = world; InternalName = pr.Name; PlayerReference = pr; string botType = null; // Real player or host-created bot if (client != null) { ClientIndex = client.Index; Color = client.Color; PlayerName = client.Name; botType = client.Bot; Country = ChooseCountry(world, client.Race, !pr.LockRace); DisplayCountry = ChooseDisplayCountry(world, client.Race); } else { // Map player ClientIndex = 0; // Owned by the host (TODO: fix this) Color = pr.Color; PlayerName = pr.Name; NonCombatant = pr.NonCombatant; Playable = pr.Playable; Spectating = pr.Spectating; botType = pr.Bot; Country = ChooseCountry(world, pr.Race, false); DisplayCountry = ChooseDisplayCountry(world, pr.Race); } PlayerActor = world.CreateActor("Player", new TypeDictionary { new OwnerInit(this) }); Shroud = PlayerActor.Trait <Shroud>(); // Enable the bot logic on the host IsBot = botType != null; if (IsBot && Game.IsHost) { var logic = PlayerActor.TraitsImplementing <IBot>() .FirstOrDefault(b => b.Info.Name == botType); if (logic == null) { Log.Write("debug", "Invalid bot type: {0}", botType); } else { logic.Activate(this); } } }
public Player(World world, Session.Client client, Session.Slot slot, PlayerReference pr) { World = world; InternalName = pr.Name; PlayerReference = pr; string botType = null; // Real player or host-created bot if (client != null) { ClientIndex = client.Index; Color = client.Color; PlayerName = client.Name; botType = client.Bot; Country = ChooseCountry(world, client.Race, !pr.LockRace); DisplayCountry = ChooseDisplayCountry(world, client.Race); } else { // Map player ClientIndex = 0; // Owned by the host (TODO: fix this) Color = pr.Color; PlayerName = pr.Name; NonCombatant = pr.NonCombatant; Playable = pr.Playable; Spectating = pr.Spectating; botType = pr.Bot; Country = ChooseCountry(world, pr.Race, false); DisplayCountry = ChooseDisplayCountry(world, pr.Race); } PlayerActor = world.CreateActor("Player", new TypeDictionary { new OwnerInit(this) }); Shroud = PlayerActor.Trait<Shroud>(); // Enable the bot logic on the host IsBot = botType != null; if (IsBot && Game.IsHost) { var logic = PlayerActor.TraitsImplementing<IBot>() .FirstOrDefault(b => b.Info.Name == botType); if (logic == null) Log.Write("debug", "Invalid bot type: {0}", botType); else logic.Activate(this); } }
public void MakeDefaultPlayers() { var firstRace = OpenRA.Rules.Info["world"].Traits .WithInterface <CountryInfo>().First(c => c.Selectable).Race; if (!Players.ContainsKey("Neutral")) { Players.Add("Neutral", new PlayerReference { Name = "Neutral", Race = firstRace, OwnsWorld = true, NonCombatant = true }); } var numSpawns = GetSpawnPoints().Length; for (var index = 0; index < numSpawns; index++) { if (Players.ContainsKey("Multi{0}".F(index))) { continue; } var p = new PlayerReference { Name = "Multi{0}".F(index), Race = "Random", Playable = true, DefaultStartingUnits = true, Enemies = new[] { "Creeps" } }; Players.Add(p.Name, p); } Players.Add("Creeps", new PlayerReference { Name = "Creeps", Race = firstRace, NonCombatant = true, Enemies = Players.Where(p => p.Value.Playable).Select(p => p.Key).ToArray() }); }
public MapPlayers(Ruleset rules, int playerCount) { var firstFaction = rules.Actors["world"].TraitInfos<FactionInfo>() .First(f => f.Selectable).InternalName; Players = new Dictionary<string, PlayerReference> { { "Neutral", new PlayerReference { Name = "Neutral", Faction = firstFaction, OwnsWorld = true, NonCombatant = true } }, { "Creeps", new PlayerReference { Name = "Creeps", Faction = firstFaction, NonCombatant = true, Enemies = Exts.MakeArray(playerCount, i => "Multi{0}".F(i)) } } }; for (var index = 0; index < playerCount; index++) { var p = new PlayerReference { Name = "Multi{0}".F(index), Faction = "Random", Playable = true, Enemies = new[] { "Creeps" } }; Players.Add(p.Name, p); } }
public MapPlayers(Ruleset rules, int playerCount) { var firstFaction = rules.Actors["world"].TraitInfos <FactionInfo>() .First(f => f.Selectable).InternalName; Players = new Dictionary <string, PlayerReference> { { "Neutral", new PlayerReference { Name = "Neutral", Faction = firstFaction, OwnsWorld = true, NonCombatant = true } }, { "Creeps", new PlayerReference { Name = "Creeps", Faction = firstFaction, NonCombatant = true, Enemies = Exts.MakeArray(playerCount, i => "Multi{0}".F(i)) } } }; for (var index = 0; index < playerCount; index++) { var p = new PlayerReference { Name = "Multi{0}".F(index), Faction = "Random", Playable = true, Enemies = new[] { "Creeps" } }; Players.Add(p.Name, p); } }
// Support upgrading format 5 maps to a more // recent version by defining upgradeForMod. public Map(string path, string upgradeForMod) { Path = path; Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue); AssertExists("map.yaml"); AssertExists("map.bin"); var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml"))); FieldLoader.Load(this, yaml); // Support for formats 1-3 dropped 2011-02-11. // Use release-20110207 to convert older maps to format 4 // Use release-20110511 to convert older maps to format 5 if (MapFormat < 5) { throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path)); } // Format 5 -> 6 enforces the use of RequiresMod if (MapFormat == 5) { if (upgradeForMod == null) { throw new InvalidDataException("Map format {0} is not supported, but can be upgraded.\n File: {1}".F(MapFormat, path)); } Console.WriteLine("Upgrading {0} from Format 5 to Format 6", path); // TODO: This isn't very nice, but there is no other consistent way // of finding the mod early during the engine initialization. RequiresMod = upgradeForMod; } var nd = yaml.ToDictionary(); // Load players foreach (var my in nd["Players"].ToDictionary().Values) { var player = new PlayerReference(my); Players.Add(player.Name, player); } Actors = Exts.Lazy(() => { var ret = new Dictionary <string, ActorReference>(); foreach (var kv in nd["Actors"].ToDictionary()) { ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.ToDictionary())); } return(ret); }); // Smudges Smudges = Exts.Lazy(() => { var ret = new List <SmudgeReference>(); foreach (var name in nd["Smudges"].ToDictionary().Keys) { var vals = name.Split(' '); var loc = vals[1].Split(','); ret.Add(new SmudgeReference(vals[0], new int2( Exts.ParseIntegerInvariant(loc[0]), Exts.ParseIntegerInvariant(loc[1])), Exts.ParseIntegerInvariant(vals[2]))); } return(ret); }); RuleDefinitions = MiniYaml.NodesOrEmpty(yaml, "Rules"); SequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Sequences"); VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences"); WeaponDefinitions = MiniYaml.NodesOrEmpty(yaml, "Weapons"); VoiceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Voices"); NotificationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Notifications"); TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations"); MapTiles = Exts.Lazy(() => LoadMapTiles()); MapResources = Exts.Lazy(() => LoadResourceTiles()); TileShape = Game.modData.Manifest.TileShape; // The Uid is calculated from the data on-disk, so // format changes must be flushed to disk. // TODO: this isn't very nice if (MapFormat < 6) { Save(path); } Uid = ComputeHash(); if (Container.Exists("map.png")) { CustomPreview = new Bitmap(Container.GetContent("map.png")); } PostInit(); }
public Player(World world, Session.Client client, PlayerReference pr, MersenneTwister playerRandom) { World = world; InternalName = pr.Name; PlayerReference = pr; inMissionMap = world.Map.Visibility.HasFlag(MapVisibility.MissionSelector); // Real player or host-created bot if (client != null) { ClientIndex = client.Index; Color = client.Color; PlayerName = ResolvePlayerName(client, world.LobbyInfo.Clients, world.Map.Rules.Actors["player"].TraitInfos <IBotInfo>()); BotType = client.Bot; Faction = ResolveFaction(world, client.Faction, playerRandom, !pr.LockFaction); DisplayFaction = ResolveDisplayFaction(world, client.Faction); var assignSpawnPoints = world.WorldActor.TraitOrDefault <IAssignSpawnPoints>(); HomeLocation = assignSpawnPoints?.AssignHomeLocation(world, client, playerRandom) ?? pr.HomeLocation; SpawnPoint = assignSpawnPoints?.SpawnPointForPlayer(this) ?? client.SpawnPoint; DisplaySpawnPoint = client.SpawnPoint; Handicap = client.Handicap; } else { // Map player ClientIndex = 0; // Owned by the host (TODO: fix this) Color = pr.Color; PlayerName = pr.Name; NonCombatant = pr.NonCombatant; Playable = pr.Playable; spectating = pr.Spectating; BotType = pr.Bot; Faction = ResolveFaction(world, pr.Faction, playerRandom, false); DisplayFaction = ResolveDisplayFaction(world, pr.Faction); HomeLocation = pr.HomeLocation; SpawnPoint = DisplaySpawnPoint = 0; Handicap = pr.Handicap; } if (!spectating) { PlayerMask = new LongBitSet <PlayerBitMask>(InternalName); } // Set this property before running any Created callbacks on the player actor IsBot = BotType != null; // Special case handling is required for the Player actor: // Since Actor.Created would be called before PlayerActor is assigned here // querying player traits in INotifyCreated.Created would crash. // Therefore assign the uninitialized actor and run the Created callbacks // by calling Initialize ourselves. var playerActorType = world.Type == WorldType.Editor ? EditorPlayerActorType : PlayerActorType; PlayerActor = new Actor(world, playerActorType, new TypeDictionary { new OwnerInit(this) }); PlayerActor.Initialize(true); Shroud = PlayerActor.Trait <Shroud>(); FrozenActorLayer = PlayerActor.TraitOrDefault <FrozenActorLayer>(); // Enable the bot logic on the host if (IsBot && Game.IsHost) { var logic = PlayerActor.TraitsImplementing <IBot>().FirstOrDefault(b => b.Info.Type == BotType); if (logic == null) { Log.Write("debug", "Invalid bot type: {0}", BotType); } else { logic.Activate(this); } } stanceColors.Self = ChromeMetrics.Get <Color>("PlayerStanceColorSelf"); stanceColors.Allies = ChromeMetrics.Get <Color>("PlayerStanceColorAllies"); stanceColors.Enemies = ChromeMetrics.Get <Color>("PlayerStanceColorEnemies"); stanceColors.Neutrals = ChromeMetrics.Get <Color>("PlayerStanceColorNeutrals"); unlockRenderPlayer = PlayerActor.TraitsImplementing <IUnlocksRenderPlayer>().ToArray(); }
public Player(World world, Session.Client client, PlayerReference pr) { World = world; InternalName = pr.Name; PlayerReference = pr; inMissionMap = world.Map.Visibility.HasFlag(MapVisibility.MissionSelector); // Real player or host-created bot if (client != null) { ClientIndex = client.Index; Color = client.Color; if (client.Bot != null) { var botInfo = world.Map.Rules.Actors["player"].TraitInfos <IBotInfo>().First(b => b.Type == client.Bot); var botsOfSameType = world.LobbyInfo.Clients.Where(c => c.Bot == client.Bot).ToArray(); PlayerName = botsOfSameType.Length == 1 ? botInfo.Name : "{0} {1}".F(botInfo.Name, botsOfSameType.IndexOf(client) + 1); } else { PlayerName = client.Name; } BotType = client.Bot; Faction = ChooseFaction(world, client.Faction, !pr.LockFaction); DisplayFaction = ChooseDisplayFaction(world, client.Faction); } else { // Map player ClientIndex = 0; // Owned by the host (TODO: fix this) Color = pr.Color; PlayerName = pr.Name; NonCombatant = pr.NonCombatant; Playable = pr.Playable; Spectating = pr.Spectating; BotType = pr.Bot; Faction = ChooseFaction(world, pr.Faction, false); DisplayFaction = ChooseDisplayFaction(world, pr.Faction); } var playerActorType = world.Type == WorldType.Editor ? "EditorPlayer" : "Player"; PlayerActor = world.CreateActor(playerActorType, new TypeDictionary { new OwnerInit(this) }); Shroud = PlayerActor.Trait <Shroud>(); // Enable the bot logic on the host IsBot = BotType != null; if (IsBot && Game.IsHost) { var logic = PlayerActor.TraitsImplementing <IBot>().FirstOrDefault(b => b.Info.Type == BotType); if (logic == null) { Log.Write("debug", "Invalid bot type: {0}", BotType); } else { logic.Activate(this); } } stanceColors.Self = ChromeMetrics.Get <Color>("PlayerStanceColorSelf"); stanceColors.Allies = ChromeMetrics.Get <Color>("PlayerStanceColorAllies"); stanceColors.Enemies = ChromeMetrics.Get <Color>("PlayerStanceColorEnemies"); stanceColors.Neutrals = ChromeMetrics.Get <Color>("PlayerStanceColorNeutrals"); unlockRenderPlayer = PlayerActor.TraitsImplementing <IUnlocksRenderPlayer>().ToArray(); }
public Map(string path) { Path = path; Container = FileSystem.OpenPackage(path, int.MaxValue); AssertExists("map.yaml"); AssertExists("map.bin"); var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml"))); FieldLoader.Load(this, yaml); Uid = ComputeHash(); // Support for formats 1-3 dropped 2011-02-11. // Use release-20110207 to convert older maps to format 4 // Use release-20110511 to convert older maps to format 5 if (MapFormat < 5) { throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path)); } // Load players foreach (var kv in yaml.NodesDict["Players"].NodesDict) { var player = new PlayerReference(kv.Value); Players.Add(player.Name, player); } Actors = Lazy.New(() => { var ret = new Dictionary <string, ActorReference>(); foreach (var kv in yaml.NodesDict["Actors"].NodesDict) { ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.NodesDict)); } return(ret); }); // Smudges Smudges = Lazy.New(() => { var ret = new List <SmudgeReference>(); foreach (var kv in yaml.NodesDict["Smudges"].NodesDict) { var vals = kv.Key.Split(' '); var loc = vals[1].Split(','); ret.Add(new SmudgeReference(vals[0], new int2(int.Parse(loc[0]), int.Parse(loc[1])), int.Parse(vals[2]))); } return(ret); }); Rules = NodesOrEmpty(yaml, "Rules"); Sequences = NodesOrEmpty(yaml, "Sequences"); Weapons = NodesOrEmpty(yaml, "Weapons"); Voices = NodesOrEmpty(yaml, "Voices"); CustomTerrain = new string[MapSize.X, MapSize.Y]; MapTiles = Lazy.New(() => LoadMapTiles()); MapResources = Lazy.New(() => LoadResourceTiles()); }
public void MakeDefaultPlayers() { var firstRace = Rules.Actors["world"].Traits .WithInterface<CountryInfo>().First(c => c.Selectable).Race; if (!Players.ContainsKey("Neutral")) Players.Add("Neutral", new PlayerReference { Name = "Neutral", Race = firstRace, OwnsWorld = true, NonCombatant = true }); var numSpawns = GetSpawnPoints().Length; for (var index = 0; index < numSpawns; index++) { if (Players.ContainsKey("Multi{0}".F(index))) continue; var p = new PlayerReference { Name = "Multi{0}".F(index), Race = "Random", Playable = true, Enemies = new[] { "Creeps" } }; Players.Add(p.Name, p); } Players.Add("Creeps", new PlayerReference { Name = "Creeps", Race = firstRace, NonCombatant = true, Enemies = Players.Where(p => p.Value.Playable).Select(p => p.Key).ToArray() }); }
// Support upgrading format 5 maps to a more // recent version by defining upgradeForMod. public Map(string path, string upgradeForMod) { Path = path; Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue); AssertExists("map.yaml"); AssertExists("map.bin"); var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml"))); FieldLoader.Load(this, yaml); // Support for formats 1-3 dropped 2011-02-11. // Use release-20110207 to convert older maps to format 4 // Use release-20110511 to convert older maps to format 5 if (MapFormat < 5) throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path)); // Format 5 -> 6 enforces the use of RequiresMod if (MapFormat == 5) { if (upgradeForMod == null) throw new InvalidDataException("Map format {0} is not supported, but can be upgraded.\n File: {1}".F(MapFormat, path)); Console.WriteLine("Upgrading {0} from Format 5 to Format 6", path); // TODO: This isn't very nice, but there is no other consistent way // of finding the mod early during the engine initialization. RequiresMod = upgradeForMod; } var nd = yaml.ToDictionary(); // Load players foreach (var my in nd["Players"].ToDictionary().Values) { var player = new PlayerReference(my); Players.Add(player.Name, player); } Actors = Exts.Lazy(() => { var ret = new Dictionary<string, ActorReference>(); foreach (var kv in nd["Actors"].ToDictionary()) ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.ToDictionary())); return ret; }); // Smudges Smudges = Exts.Lazy(() => { var ret = new List<SmudgeReference>(); foreach (var name in nd["Smudges"].ToDictionary().Keys) { var vals = name.Split(' '); var loc = vals[1].Split(','); ret.Add(new SmudgeReference(vals[0], new int2( Exts.ParseIntegerInvariant(loc[0]), Exts.ParseIntegerInvariant(loc[1])), Exts.ParseIntegerInvariant(vals[2]))); } return ret; }); RuleDefinitions = MiniYaml.NodesOrEmpty(yaml, "Rules"); SequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Sequences"); VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences"); WeaponDefinitions = MiniYaml.NodesOrEmpty(yaml, "Weapons"); VoiceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Voices"); NotificationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Notifications"); TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations"); MapTiles = Exts.Lazy(() => LoadMapTiles()); MapResources = Exts.Lazy(() => LoadResourceTiles()); TileShape = Game.modData.Manifest.TileShape; // The Uid is calculated from the data on-disk, so // format changes must be flushed to disk. // TODO: this isn't very nice if (MapFormat < 6) Save(path); Uid = ComputeHash(); if (Container.Exists("map.png")) CustomPreview = new Bitmap(Container.GetContent("map.png")); PostInit(); }
// The standard constructor for most purposes public Map(string path) { Path = path; Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue); AssertExists("map.yaml"); AssertExists("map.bin"); var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml"), path)); FieldLoader.Load(this, yaml); // Support for formats 1-3 dropped 2011-02-11. // Use release-20110207 to convert older maps to format 4 // Use release-20110511 to convert older maps to format 5 // Use release-20141029 to convert older maps to format 6 if (MapFormat < 6) { throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path)); } var nd = yaml.ToDictionary(); // Format 6 -> 7 combined the Selectable and UseAsShellmap flags into the Class enum if (MapFormat < 7) { MiniYaml useAsShellmap; if (nd.TryGetValue("UseAsShellmap", out useAsShellmap) && bool.Parse(useAsShellmap.Value)) { Visibility = MapVisibility.Shellmap; } else if (Type == "Mission" || Type == "Campaign") { Visibility = MapVisibility.MissionSelector; } } // Load players foreach (var my in nd["Players"].ToDictionary().Values) { var player = new PlayerReference(my); Players.Add(player.Name, player); } Actors = Exts.Lazy(() => { var ret = new Dictionary <string, ActorReference>(); foreach (var kv in nd["Actors"].ToDictionary()) { ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.ToDictionary())); } return(ret); }); // Smudges Smudges = Exts.Lazy(() => { var ret = new List <SmudgeReference>(); foreach (var name in nd["Smudges"].ToDictionary().Keys) { var vals = name.Split(' '); var loc = vals[1].Split(','); ret.Add(new SmudgeReference(vals[0], new int2( Exts.ParseIntegerInvariant(loc[0]), Exts.ParseIntegerInvariant(loc[1])), Exts.ParseIntegerInvariant(vals[2]))); } return(ret); }); RuleDefinitions = MiniYaml.NodesOrEmpty(yaml, "Rules"); SequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Sequences"); VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences"); WeaponDefinitions = MiniYaml.NodesOrEmpty(yaml, "Weapons"); VoiceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Voices"); NotificationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Notifications"); TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations"); MapTiles = Exts.Lazy(() => LoadMapTiles()); MapResources = Exts.Lazy(() => LoadResourceTiles()); MapHeight = Exts.Lazy(() => LoadMapHeight()); TileShape = Game.ModData.Manifest.TileShape; SubCellOffsets = Game.ModData.Manifest.SubCellOffsets; LastSubCell = (SubCell)(SubCellOffsets.Length - 1); DefaultSubCell = (SubCell)Game.ModData.Manifest.SubCellDefaultIndex; if (Container.Exists("map.png")) { using (var dataStream = Container.GetContent("map.png")) CustomPreview = new Bitmap(dataStream); } PostInit(); // The Uid is calculated from the data on-disk, so // format changes must be flushed to disk. // TODO: this isn't very nice if (MapFormat < 7) { Save(path); } Uid = ComputeHash(); }