Merge pull request #10857 from pchote/map-format-more

Remove hardcoded map options and videos from the Map format.
This commit is contained in:
abcdefg30
2016-03-08 21:52:52 +01:00
225 changed files with 1904 additions and 1478 deletions

View File

@@ -44,7 +44,6 @@ namespace OpenRA
public readonly IReadOnlyDictionary<string, string> Packages;
public readonly IReadOnlyDictionary<string, string> MapFolders;
public readonly MiniYaml LoadScreen;
public readonly MiniYaml LobbyDefaults;
public readonly Dictionary<string, string> RequiresMods;
public readonly Dictionary<string, Pair<string, int>> Fonts;
@@ -98,9 +97,6 @@ namespace OpenRA
if (!yaml.TryGetValue("LoadScreen", out LoadScreen))
throw new InvalidDataException("`LoadScreen` section is not defined.");
if (!yaml.TryGetValue("LobbyDefaults", out LobbyDefaults))
throw new InvalidDataException("`LobbyDefaults` section is not defined.");
Fonts = yaml["Fonts"].ToDictionary(my =>
{
var nd = my.ToDictionary();

View File

@@ -56,50 +56,6 @@ namespace OpenRA
}
}
public class MapOptions
{
public bool? Cheats;
public bool? Crates;
public bool? Creeps;
public bool? Fog;
public bool? Shroud;
public bool? AllyBuildRadius;
public int? StartingCash;
public string TechLevel;
public bool ConfigurableStartingUnits = true;
public string[] Difficulties = { };
public bool? ShortGame;
public void UpdateServerSettings(Session.Global settings)
{
if (Cheats.HasValue)
settings.AllowCheats = Cheats.Value;
if (Crates.HasValue)
settings.Crates = Crates.Value;
if (Creeps.HasValue)
settings.Creeps = Creeps.Value;
if (Fog.HasValue)
settings.Fog = Fog.Value;
if (Shroud.HasValue)
settings.Shroud = Shroud.Value;
if (AllyBuildRadius.HasValue)
settings.AllyBuildRadius = AllyBuildRadius.Value;
if (StartingCash.HasValue)
settings.StartingCash = StartingCash.Value;
if (ShortGame.HasValue)
settings.ShortGame = ShortGame.Value;
}
}
public class MapVideos
{
public string BackgroundInfo;
public string Briefing;
public string GameStart;
public string GameWon;
public string GameLost;
}
[Flags]
public enum MapVisibility
{
@@ -110,7 +66,7 @@ namespace OpenRA
public class Map : IReadOnlyFileSystem
{
public const int SupportedMapFormat = 8;
public const int SupportedMapFormat = 9;
public const int MaxTilesInCircleRange = 50;
public readonly MapGrid Grid;
@@ -130,10 +86,8 @@ namespace OpenRA
public string Title;
public string Type = "Conquest";
public string Description;
public string Author;
public string Tileset;
public bool AllowStartUnitConfig = true;
public Bitmap CustomPreview;
public bool InvalidCustomRules { get; private set; }
@@ -145,30 +99,6 @@ namespace OpenRA
return SubCellOffsets[(int)subCell];
}
[FieldLoader.LoadUsing("LoadOptions")] public MapOptions Options;
static object LoadOptions(MiniYaml y)
{
var options = new MapOptions();
var nodesDict = y.ToDictionary();
if (nodesDict.ContainsKey("Options"))
FieldLoader.Load(options, nodesDict["Options"]);
return options;
}
[FieldLoader.LoadUsing("LoadVideos")] public MapVideos Videos;
static object LoadVideos(MiniYaml y)
{
var videos = new MapVideos();
var nodesDict = y.ToDictionary();
if (nodesDict.ContainsKey("Videos"))
FieldLoader.Load(videos, nodesDict["Videos"]);
return videos;
}
public static string ComputeUID(IReadOnlyPackage package)
{
// UID is calculated by taking an SHA1 of the yaml and binary data
@@ -270,13 +200,10 @@ namespace OpenRA
var tileRef = new TerrainTile(tileset.Templates.First().Key, 0);
Title = "Name your map here";
Description = "Describe your map here";
Author = "Your name here";
MapSize = new int2(size);
Tileset = tileset.Id;
Videos = new MapVideos();
Options = new MapOptions();
MapResources = Exts.Lazy(() => new CellLayer<ResourceTile>(Grid.Type, size));
@@ -500,7 +427,6 @@ namespace OpenRA
"MapFormat",
"RequiresMod",
"Title",
"Description",
"Author",
"Tileset",
"MapSize",
@@ -517,12 +443,7 @@ namespace OpenRA
root.Add(new MiniYamlNode(field, FieldSaver.FormatValue(this, f)));
}
root.Add(new MiniYamlNode("Videos", FieldSaver.SaveDifferences(Videos, new MapVideos())));
root.Add(new MiniYamlNode("Options", FieldSaver.SaveDifferences(Options, new MapOptions())));
root.Add(new MiniYamlNode("Players", null, PlayerDefinitions));
root.Add(new MiniYamlNode("Actors", null, ActorDefinitions));
root.Add(new MiniYamlNode("Smudges", null, SmudgeDefinitions));
root.Add(new MiniYamlNode("Rules", null, RuleDefinitions));
@@ -858,10 +779,10 @@ namespace OpenRA
ProjectedCellBounds = new ProjectedCellRegion(this, tl, br);
}
public void FixOpenAreas(Ruleset rules)
public void FixOpenAreas()
{
var r = new Random();
var tileset = rules.TileSets[Tileset];
var tileset = Rules.TileSets[Tileset];
for (var j = Bounds.Top; j < Bounds.Bottom; j++)
{

View File

@@ -190,8 +190,8 @@ namespace OpenRA.Network
public bool Fog = true;
public bool AllyBuildRadius = true;
public int StartingCash = 5000;
public string TechLevel = "none";
public string StartingUnitsClass = "none";
public string TechLevel;
public string StartingUnitsClass;
public string GameSpeedType = "default";
public bool ShortGame = true;
public bool AllowVersionMismatch;

View File

@@ -154,16 +154,14 @@ namespace OpenRA.Server
}
};
FieldLoader.Load(LobbyInfo.GlobalSettings, modData.Manifest.LobbyDefaults);
foreach (var t in serverTraits.WithInterface<INotifyServerStart>())
t.ServerStarted(this);
Log.Write("server", "Initial mod: {0}", ModData.Manifest.Mod.Id);
Log.Write("server", "Initial map: {0}", LobbyInfo.GlobalSettings.Map);
new Thread(_ =>
{
foreach (var t in serverTraits.WithInterface<INotifyServerStart>())
t.ServerStarted(this);
Log.Write("server", "Initial mod: {0}", ModData.Manifest.Mod.Id);
Log.Write("server", "Initial map: {0}", LobbyInfo.GlobalSettings.Map);
var timeout = serverTraits.WithInterface<ITick>().Min(t => t.TickTimeout);
for (;;)
{
@@ -608,10 +606,7 @@ namespace OpenRA.Server
DispatchOrders(toDrop, frame, new byte[] { 0xbf });
if (!Conns.Any())
{
FieldLoader.Load(LobbyInfo.GlobalSettings, ModData.Manifest.LobbyDefaults);
TempBans.Clear();
}
if (Conns.Any() || LobbyInfo.GlobalSettings.Dedicated)
SyncLobbyClients();

View File

@@ -14,17 +14,46 @@ namespace OpenRA.Traits
[Desc("Attach this to the player actor.")]
public class DeveloperModeInfo : ITraitInfo
{
[Desc("Default value of the developer mode checkbox in the lobby.")]
public bool Enabled = false;
[Desc("Prevent the developer mode state from being changed in the lobby.")]
public bool Locked = false;
[Desc("Default cash bonus granted by the give cash cheat.")]
public int Cash = 20000;
[Desc("Growth steps triggered by the grow resources button.")]
public int ResourceGrowth = 100;
[Desc("Enable the fast build cheat by default.")]
public bool FastBuild;
[Desc("Enable the fast support powers cheat by default.")]
public bool FastCharge;
[Desc("Enable the disable visibility cheat by default.")]
public bool DisableShroud;
public bool PathDebug;
[Desc("Enable the unlimited power cheat by default.")]
public bool UnlimitedPower;
[Desc("Enable the build anywhere cheat by default.")]
public bool BuildAnywhere;
[Desc("Enable the path debug overlay by default.")]
public bool PathDebug;
[Desc("Enable the combat geometry overlay by default.")]
public bool ShowCombatGeometry;
[Desc("Enable the debug geometry overlay by default.")]
public bool ShowDebugGeometry;
[Desc("Enable the depth buffer overlay by default.")]
public bool ShowDepthPreview;
[Desc("Enable the actor tags overlay by default.")]
public bool ShowActorTags;
public object Create(ActorInitializer init) { return new DeveloperMode(this); }

View File

@@ -16,9 +16,15 @@ namespace OpenRA.Traits
{
public class PlayerResourcesInfo : ITraitInfo
{
[Desc("Starting cash options that are available in the lobby options.")]
public readonly int[] SelectableCash = { 2500, 5000, 10000, 20000 };
[Desc("Default starting cash option: should be one of the SelectableCash options.")]
public readonly int DefaultCash = 5000;
[Desc("Force the DefaultCash option by disabling changes in the lobby.")]
public readonly bool DefaultCashLocked = false;
public object Create(ActorInitializer init) { return new PlayerResources(init.Self, this); }
}

View File

@@ -18,6 +18,18 @@ namespace OpenRA.Traits
[Desc("Required for shroud and fog visibility checks. Add this to the player actor.")]
public class ShroudInfo : ITraitInfo
{
[Desc("Default value of the fog checkbox in the lobby.")]
public bool FogEnabled = true;
[Desc("Prevent the fog enabled state from being changed in the lobby.")]
public bool FogLocked = false;
[Desc("Default value of the explore map checkbox in the lobby.")]
public bool ExploredMapEnabled = false;
[Desc("Prevent the explore map enabled state from being changed in the lobby.")]
public bool ExploredMapLocked = false;
public object Create(ActorInitializer init) { return new Shroud(init.Self); }
}

View File

@@ -732,6 +732,10 @@
<Compile Include="Traits\Render\WithGateSpriteBody.cs" />
<Compile Include="ColorValidator.cs" />
<Compile Include="UtilityCommands\ResizeMapCommand.cs" />
<Compile Include="Traits\World\MapCreeps.cs" />
<Compile Include="Traits\World\MapBuildRadius.cs" />
<Compile Include="Traits\World\MapOptions.cs" />
<Compile Include="Traits\World\MissionData.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>

View File

@@ -348,7 +348,6 @@ namespace OpenRA.Mods.Common.Server
var oldSlots = server.LobbyInfo.Slots.Keys.ToArray();
LoadMap(server);
SetDefaultDifficulty(server);
// Reset client states
foreach (var c in server.LobbyInfo.Clients)
@@ -408,7 +407,8 @@ namespace OpenRA.Mods.Common.Server
return true;
}
if (server.Map.Options.Cheats.HasValue)
var devMode = server.Map.Rules.Actors["player"].TraitInfo<DeveloperModeInfo>();
if (devMode.Locked)
{
server.SendOrderTo(conn, "Message", "Map has disabled cheat configuration.");
return true;
@@ -431,7 +431,8 @@ namespace OpenRA.Mods.Common.Server
return true;
}
if (server.Map.Options.Shroud.HasValue)
var shroud = server.Map.Rules.Actors["player"].TraitInfo<ShroudInfo>();
if (shroud.ExploredMapLocked)
{
server.SendOrderTo(conn, "Message", "Map has disabled shroud configuration.");
return true;
@@ -454,7 +455,8 @@ namespace OpenRA.Mods.Common.Server
return true;
}
if (server.Map.Options.Fog.HasValue)
var shroud = server.Map.Rules.Actors["player"].TraitInfo<ShroudInfo>();
if (shroud.FogLocked)
{
server.SendOrderTo(conn, "Message", "Map has disabled fog configuration.");
return true;
@@ -518,7 +520,8 @@ namespace OpenRA.Mods.Common.Server
return true;
}
if (server.Map.Options.Crates.HasValue)
var crateSpawner = server.Map.Rules.Actors["world"].TraitInfoOrDefault<CrateSpawnerInfo>();
if (crateSpawner == null || crateSpawner.Locked)
{
server.SendOrderTo(conn, "Message", "Map has disabled crate configuration.");
return true;
@@ -541,7 +544,8 @@ namespace OpenRA.Mods.Common.Server
return true;
}
if (server.Map.Options.Creeps.HasValue)
var mapCreeps = server.Map.Rules.Actors["world"].TraitInfoOrDefault<MapCreepsInfo>();
if (mapCreeps == null || mapCreeps.Locked)
{
server.SendOrderTo(conn, "Message", "Map has disabled Creeps spawning configuration.");
return true;
@@ -564,7 +568,8 @@ namespace OpenRA.Mods.Common.Server
return true;
}
if (server.Map.Options.AllyBuildRadius.HasValue)
var mapBuildRadius = server.Map.Rules.Actors["world"].TraitInfoOrDefault<MapBuildRadiusInfo>();
if (mapBuildRadius == null || mapBuildRadius.AllyBuildRadiusLocked)
{
server.SendOrderTo(conn, "Message", "Map has disabled ally build radius configuration.");
return true;
@@ -581,19 +586,23 @@ namespace OpenRA.Mods.Common.Server
{ "difficulty",
s =>
{
if (!server.Map.Options.Difficulties.Any())
return true;
if (!client.IsAdmin)
{
server.SendOrderTo(conn, "Message", "Only the host can set that option.");
return true;
}
if (s != null && !server.Map.Options.Difficulties.Contains(s))
var mapOptions = server.Map.Rules.Actors["world"].TraitInfo<MapOptionsInfo>();
if (mapOptions.DifficultyLocked || !mapOptions.Difficulties.Any())
{
server.SendOrderTo(conn, "Message", "Map has disabled difficulty configuration.");
return true;
}
if (s != null && !mapOptions.Difficulties.Contains(s))
{
server.SendOrderTo(conn, "Message", "Invalid difficulty selected: {0}".F(s));
server.SendOrderTo(conn, "Message", "Supported values: {0}".F(server.Map.Options.Difficulties.JoinWith(", ")));
server.SendOrderTo(conn, "Message", "Supported values: {0}".F(mapOptions.Difficulties.JoinWith(", ")));
return true;
}
@@ -613,7 +622,8 @@ namespace OpenRA.Mods.Common.Server
return true;
}
if (!server.Map.Options.ConfigurableStartingUnits)
var startingUnits = server.Map.Rules.Actors["world"].TraitInfoOrDefault<SpawnMPUnitsInfo>();
if (startingUnits == null || startingUnits.Locked)
{
server.SendOrderTo(conn, "Message", "Map has disabled start unit configuration.");
return true;
@@ -644,13 +654,14 @@ namespace OpenRA.Mods.Common.Server
return true;
}
if (server.Map.Options.StartingCash.HasValue)
var playerResources = server.Map.Rules.Actors["player"].TraitInfo<PlayerResourcesInfo>();
if (playerResources.DefaultCashLocked)
{
server.SendOrderTo(conn, "Message", "Map has disabled cash configuration.");
return true;
}
var startingCashOptions = server.Map.Rules.Actors["player"].TraitInfo<PlayerResourcesInfo>().SelectableCash;
var startingCashOptions = playerResources.SelectableCash;
var requestedCash = Exts.ParseIntegerInvariant(s);
if (!startingCashOptions.Contains(requestedCash))
{
@@ -675,7 +686,8 @@ namespace OpenRA.Mods.Common.Server
return true;
}
if (server.Map.Options.TechLevel != null)
var mapOptions = server.Map.Rules.Actors["world"].TraitInfo<MapOptionsInfo>();
if (mapOptions.TechLevelLocked)
{
server.SendOrderTo(conn, "Message", "Map has disabled Tech configuration.");
return true;
@@ -931,7 +943,8 @@ namespace OpenRA.Mods.Common.Server
return true;
}
if (server.Map.Options.ShortGame.HasValue)
var mapOptions = server.Map.Rules.Actors["world"].TraitInfo<MapOptionsInfo>();
if (mapOptions.ShortGameLocked)
{
server.SendOrderTo(conn, "Message", "Map has disabled short game configuration.");
return true;
@@ -982,7 +995,6 @@ namespace OpenRA.Mods.Common.Server
public void ServerStarted(S server)
{
LoadMap(server);
SetDefaultDifficulty(server);
}
static Session.Slot MakeSlotFromPlayerReference(PlayerReference pr)
@@ -1001,6 +1013,33 @@ namespace OpenRA.Mods.Common.Server
};
}
public static void LoadMapSettings(Session.Global gs, Map map)
{
var devMode = map.Rules.Actors["player"].TraitInfo<DeveloperModeInfo>();
gs.AllowCheats = devMode.Enabled;
var crateSpawner = map.Rules.Actors["world"].TraitInfoOrDefault<CrateSpawnerInfo>();
gs.Crates = crateSpawner != null && crateSpawner.Enabled;
var shroud = map.Rules.Actors["player"].TraitInfo<ShroudInfo>();
gs.Fog = shroud.FogEnabled;
gs.Shroud = !shroud.ExploredMapEnabled;
var resources = map.Rules.Actors["player"].TraitInfo<PlayerResourcesInfo>();
gs.StartingCash = resources.DefaultCash;
var startingUnits = map.Rules.Actors["world"].TraitInfoOrDefault<SpawnMPUnitsInfo>();
gs.StartingUnitsClass = startingUnits == null ? "none" : startingUnits.StartingUnitsClass;
var mapBuildRadius = map.Rules.Actors["world"].TraitInfoOrDefault<MapBuildRadiusInfo>();
gs.AllyBuildRadius = mapBuildRadius != null && mapBuildRadius.AllyBuildRadiusEnabled;
var mapOptions = map.Rules.Actors["world"].TraitInfo<MapOptionsInfo>();
gs.ShortGame = mapOptions.ShortGameEnabled;
gs.TechLevel = mapOptions.TechLevel;
gs.Difficulty = mapOptions.Difficulty ?? mapOptions.Difficulties.FirstOrDefault();
}
static void LoadMap(S server)
{
server.Map = new Map(server.ModData, server.ModData.MapCache[server.LobbyInfo.GlobalSettings.Map].Package);
@@ -1011,19 +1050,7 @@ namespace OpenRA.Mods.Common.Server
.Where(s => s != null)
.ToDictionary(s => s.PlayerReference, s => s);
server.Map.Options.UpdateServerSettings(server.LobbyInfo.GlobalSettings);
}
static void SetDefaultDifficulty(S server)
{
if (!server.Map.Options.Difficulties.Any())
{
server.LobbyInfo.GlobalSettings.Difficulty = null;
return;
}
if (!server.Map.Options.Difficulties.Contains(server.LobbyInfo.GlobalSettings.Difficulty))
server.LobbyInfo.GlobalSettings.Difficulty = server.Map.Options.Difficulties.First();
LoadMapSettings(server.LobbyInfo.GlobalSettings, server.Map);
}
static HSLColor SanitizePlayerColor(S server, HSLColor askedColor, int playerIndex, Connection connectionToEcho = null)

View File

@@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Server
return;
var defaults = new Session.Global();
FieldLoader.Load(defaults, Game.ModData.Manifest.LobbyDefaults);
LobbyCommands.LoadMapSettings(defaults, server.Map);
if (server.LobbyInfo.GlobalSettings.AllowCheats != defaults.AllowCheats)
server.SendOrderTo(conn, "Message", "Allow Cheats: {0}".F(server.LobbyInfo.GlobalSettings.AllowCheats));

View File

@@ -40,8 +40,7 @@ namespace OpenRA.Mods.Common.Traits
public ProvidesTechPrerequisite(ProvidesTechPrerequisiteInfo info, ActorInitializer init)
{
this.info = info;
var tech = init.World.Map.Options.TechLevel ?? init.World.LobbyInfo.GlobalSettings.TechLevel;
enabled = info.Name == tech;
enabled = info.Name == init.World.LobbyInfo.GlobalSettings.TechLevel;
}
}
}

View File

@@ -20,6 +20,12 @@ namespace OpenRA.Mods.Common.Traits
{
public class CrateSpawnerInfo : ITraitInfo
{
[Desc("Default value of the crates checkbox in the lobby.")]
public readonly bool Enabled = true;
[Desc("Prevent the crates state from being changed in the lobby.")]
public readonly bool Locked = false;
[Desc("Minimum number of crates.")]
public readonly int Minimum = 1;
@@ -42,14 +48,14 @@ namespace OpenRA.Mods.Common.Traits
public readonly int WaterChance = 20;
[ActorReference]
[Desc("Crate actors to drop")]
[Desc("Crate actors to drop.")]
public readonly string[] CrateActors = { "crate" };
[Desc("Chance of each crate actor spawning")]
[Desc("Chance of each crate actor spawning.")]
public readonly int[] CrateActorShares = { 10 };
[ActorReference]
[Desc("If a DeliveryAircraft: is specified, then this actor will deliver crates")]
[Desc("If a DeliveryAircraft: is specified, then this actor will deliver crates.")]
public readonly string DeliveryAircraft = null;
[Desc("Number of facings that the delivery aircraft may approach from.")]

View File

@@ -0,0 +1,28 @@
#region Copyright & License Information
/*
* Copyright 2007-2016 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, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System.Collections.Generic;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Controls the build radius checkboxes in the lobby options.")]
public class MapBuildRadiusInfo : TraitInfo<MapBuildRadius>
{
[Desc("Default value of the ally build radius checkbox in the lobby.")]
public readonly bool AllyBuildRadiusEnabled = true;
[Desc("Prevent the ally build radius state from being changed in the lobby.")]
public readonly bool AllyBuildRadiusLocked = false;
}
public class MapBuildRadius { }
}

View File

@@ -0,0 +1,28 @@
#region Copyright & License Information
/*
* Copyright 2007-2016 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, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System.Collections.Generic;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Controls the 'Creeps' checkbox in the lobby options.")]
public class MapCreepsInfo : TraitInfo<MapCreeps>
{
[Desc("Default value of the creeps checkbox in the lobby.")]
public readonly bool Enabled = true;
[Desc("Prevent the creeps state from being changed in the lobby.")]
public readonly bool Locked = false;
}
public class MapCreeps { }
}

View File

@@ -0,0 +1,43 @@
#region Copyright & License Information
/*
* Copyright 2007-2016 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, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System.Collections.Generic;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Controls the map difficulty, tech level, and short game lobby options.")]
public class MapOptionsInfo : TraitInfo<MapOptions>
{
[Desc("Default value of the short game checkbox in the lobby.")]
public readonly bool ShortGameEnabled = true;
[Desc("Prevent the short game enabled state from being changed in the lobby.")]
public readonly bool ShortGameLocked = false;
[Desc("Default tech level.")]
public readonly string TechLevel = "Unrestricted";
[Desc("Prevent the tech level from being changed in the lobby.")]
public readonly bool TechLevelLocked = false;
[Desc("Difficulty levels supported by the map.")]
public readonly string[] Difficulties = { };
[Desc("Default difficulty level.")]
public readonly string Difficulty = null;
[Desc("Prevent the difficulty from being changed in the lobby.")]
public readonly bool DifficultyLocked = false;
}
public class MapOptions { }
}

View File

@@ -0,0 +1,40 @@
#region Copyright & License Information
/*
* Copyright 2007-2016 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, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System.Collections.Generic;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Defines the FMVs that can be played by missions.")]
public class MissionDataInfo : TraitInfo<MissionData>
{
[Desc("Briefing text displayed in the mission browser.")]
public readonly string Briefing;
[Desc("Played by the \"Background Info\" button in the mission browser.")]
public readonly string BackgroundVideo;
[Desc("Played by the \"Briefing\" button in the mission browser.")]
public readonly string BriefingVideo;
[Desc("Automatically played before starting the mission.")]
public readonly string StartVideo;
[Desc("Automatically played when the player wins the mission.")]
public readonly string WinVideo;
[Desc("Automatically played when the player loses the mission.")]
public readonly string LossVideo;
}
public class MissionData { }
}

View File

@@ -18,7 +18,13 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Spawn base actor at the spawnpoint and support units in an annulus around the base actor. Both are defined at MPStartUnits. Attach this to the world actor.")]
public class SpawnMPUnitsInfo : TraitInfo<SpawnMPUnits>, Requires<MPStartLocationsInfo>, Requires<MPStartUnitsInfo> { }
public class SpawnMPUnitsInfo : TraitInfo<SpawnMPUnits>, Requires<MPStartLocationsInfo>, Requires<MPStartUnitsInfo>
{
public readonly string StartingUnitsClass = "none";
[Desc("Prevent the starting units option from being changed in the lobby.")]
public bool Locked = false;
}
public class SpawnMPUnits : IWorldLoaded
{

View File

@@ -33,9 +33,9 @@ namespace OpenRA.Mods.Common.UtilityCommands
public ModData ModData;
public Map Map;
public Ruleset Rules;
public List<string> Players = new List<string>();
public MapPlayers MapPlayers;
public MiniYaml Rules = new MiniYaml("");
public bool ValidateArguments(string[] args)
{
@@ -49,7 +49,6 @@ namespace OpenRA.Mods.Common.UtilityCommands
// HACK: The engine code assumes that Game.modData is set.
Game.ModData = modData;
Rules = modData.RulesetCache.Load(modData.DefaultFileSystem);
var filename = args[1];
using (var stream = modData.DefaultFileSystem.Open(filename))
@@ -62,14 +61,12 @@ namespace OpenRA.Mods.Common.UtilityCommands
ValidateMapFormat(format);
var tileset = GetTileset(mapSection);
Map = new Map(modData, Rules.TileSets[tileset], MapSize, MapSize)
Map = new Map(modData, modData.DefaultRules.TileSets[tileset], MapSize, MapSize)
{
Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename)),
Author = "Westwood Studios"
};
Map.Description = ExtractBriefing(file);
Map.RequiresMod = modData.Manifest.Mod.Id;
SetBounds(Map, mapSection);
@@ -77,7 +74,8 @@ namespace OpenRA.Mods.Common.UtilityCommands
ReadPacks(file, filename);
ReadTrees(file);
Map.Videos = LoadVideos(file, "BASIC");
LoadVideos(file, "BASIC");
LoadBriefing(file);
ReadActors(file);
@@ -93,7 +91,9 @@ namespace OpenRA.Mods.Common.UtilityCommands
Map.PlayerDefinitions = MapPlayers.ToMiniYaml();
}
Map.FixOpenAreas(Rules);
Map.FixOpenAreas();
Map.RuleDefinitions = Rules.Nodes;
var dest = Path.GetFileNameWithoutExtension(args[1]) + ".oramap";
var package = new ZipFile(modData.ModFiles, dest, true);
@@ -119,17 +119,34 @@ namespace OpenRA.Mods.Common.UtilityCommands
public abstract void ValidateMapFormat(int format);
static string ExtractBriefing(IniFile file)
void LoadBriefing(IniFile file)
{
var briefingSection = file.GetSection("Briefing", true);
if (briefingSection == null)
return string.Empty;
return;
var briefing = new StringBuilder();
foreach (var s in briefingSection)
briefing.AppendLine(s.Value);
return briefing.Replace("\n", " ").ToString();
if (briefing.Length == 0)
return;
var worldNode = Rules.Nodes.FirstOrDefault(n => n.Key == "World");
if (worldNode == null)
{
worldNode = new MiniYamlNode("World", new MiniYaml("", new List<MiniYamlNode>()));
Rules.Nodes.Add(worldNode);
}
var missionData = worldNode.Value.Nodes.FirstOrDefault(n => n.Key == "MissionData");
if (missionData == null)
{
missionData = new MiniYamlNode("MissionData", new MiniYaml("", new List<MiniYamlNode>()));
worldNode.Value.Nodes.Add(missionData);
}
missionData.Value.Nodes.Add(new MiniYamlNode("Briefing", briefing.Replace("\n", " ").ToString()));
}
static void SetBounds(Map map, IniSection mapSection)
@@ -146,10 +163,9 @@ namespace OpenRA.Mods.Common.UtilityCommands
public abstract void ReadPacks(IniFile file, string filename);
static MapVideos LoadVideos(IniFile file, string section)
void LoadVideos(IniFile file, string section)
{
var videos = new MapVideos();
var videos = new List<MiniYamlNode>();
foreach (var s in file.GetSection(section))
{
if (s.Value != "x" && s.Value != "<none>")
@@ -157,32 +173,49 @@ namespace OpenRA.Mods.Common.UtilityCommands
switch (s.Key)
{
case "Intro":
videos.BackgroundInfo = s.Value.ToLower() + ".vqa";
videos.Add(new MiniYamlNode("BackgroundVideo", s.Value.ToLower() + ".vqa"));
break;
case "Brief":
videos.Briefing = s.Value.ToLower() + ".vqa";
videos.Add(new MiniYamlNode("BriefingVideo", s.Value.ToLower() + ".vqa"));
break;
case "Action":
videos.GameStart = s.Value.ToLower() + ".vqa";
videos.Add(new MiniYamlNode("StartVideo", s.Value.ToLower() + ".vqa"));
break;
case "Win":
videos.GameWon = s.Value.ToLower() + ".vqa";
videos.Add(new MiniYamlNode("WinVideo", s.Value.ToLower() + ".vqa"));
break;
case "Lose":
videos.GameLost = s.Value.ToLower() + ".vqa";
videos.Add(new MiniYamlNode("LossVideo", s.Value.ToLower() + ".vqa"));
break;
}
}
}
return videos;
if (videos.Any())
{
var worldNode = Rules.Nodes.FirstOrDefault(n => n.Key == "World");
if (worldNode == null)
{
worldNode = new MiniYamlNode("World", new MiniYaml("", new List<MiniYamlNode>()));
Rules.Nodes.Add(worldNode);
}
var missionData = worldNode.Value.Nodes.FirstOrDefault(n => n.Key == "MissionData");
if (missionData == null)
{
missionData = new MiniYamlNode("MissionData", new MiniYaml("", new List<MiniYamlNode>()));
worldNode.Value.Nodes.Add(missionData);
}
missionData.Value.Nodes.AddRange(videos);
}
}
public virtual void ReadActors(IniFile file)
{
LoadActors(file, "STRUCTURES", Players, MapSize, Rules, Map);
LoadActors(file, "UNITS", Players, MapSize, Rules, Map);
LoadActors(file, "INFANTRY", Players, MapSize, Rules, Map);
LoadActors(file, "STRUCTURES", Players, MapSize, Map);
LoadActors(file, "UNITS", Players, MapSize, Map);
LoadActors(file, "INFANTRY", Players, MapSize, Map);
}
public abstract void LoadPlayer(IniFile file, string section);
@@ -298,7 +331,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
mapPlayers.Players[section] = pr;
}
public static void LoadActors(IniFile file, string section, List<string> players, int mapSize, Ruleset rules, Map map)
public static void LoadActors(IniFile file, string section, List<string> players, int mapSize, Map map)
{
foreach (var s in file.GetSection(section, true))
{
@@ -334,7 +367,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
var actorCount = map.ActorDefinitions.Count;
if (!rules.Actors.ContainsKey(parts[1].ToLowerInvariant()))
if (!map.Rules.Actors.ContainsKey(parts[1].ToLowerInvariant()))
Console.WriteLine("Ignoring unknown actor type: `{0}`".F(parts[1].ToLowerInvariant()));
else
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, actor.Save()));

View File

@@ -10,6 +10,8 @@
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using OpenRA.FileSystem;
namespace OpenRA.Mods.Common.UtilityCommands
@@ -23,13 +25,10 @@ namespace OpenRA.Mods.Common.UtilityCommands
return args.Length >= 3;
}
[Desc("MAP", "CURRENTENGINE", "Upgrade map rules to the latest engine version.")]
public void Run(ModData modData, string[] args)
public static void UpgradeMap(ModData modData, IReadWritePackage package, int engineDate)
{
// HACK: The engine code assumes that Game.modData is set.
Game.ModData = modData;
UpgradeRules.UpgradeMapFormat(modData, package);
var engineDate = Exts.ParseIntegerInvariant(args[2]);
if (engineDate < UpgradeRules.MinimumSupportedVersion)
{
Console.WriteLine("Unsupported engine version. Use the release-{0} utility to update to that version, and then try again",
@@ -37,9 +36,6 @@ namespace OpenRA.Mods.Common.UtilityCommands
return;
}
var package = modData.ModFiles.OpenWritablePackage(args[1]);
UpgradeRules.UpgradeMapFormat(modData, package);
var map = new Map(modData, package);
UpgradeRules.UpgradeWeaponRules(engineDate, ref map.WeaponDefinitions, null, 0);
UpgradeRules.UpgradeActorRules(engineDate, ref map.RuleDefinitions, null, 0);
@@ -47,5 +43,16 @@ namespace OpenRA.Mods.Common.UtilityCommands
UpgradeRules.UpgradeActors(engineDate, ref map.ActorDefinitions, null, 0);
map.Save(package);
}
[Desc("MAP", "CURRENTENGINE", "Upgrade map rules to the latest engine version.")]
public void Run(ModData modData, string[] args)
{
// HACK: The engine code assumes that Game.modData is set.
Game.ModData = modData;
var package = modData.ModFiles.OpenWritablePackage(args[1]);
var engineDate = Exts.ParseIntegerInvariant(args[2]);
UpgradeMap(modData, package, engineDate);
}
}
}

View File

@@ -74,22 +74,45 @@ namespace OpenRA.Mods.Common.UtilityCommands
ProcessYaml("Chrome Metrics", modData.Manifest.ChromeMetrics, modData, engineDate, UpgradeRules.UpgradeChromeMetrics);
ProcessYaml("Chrome Layout", modData.Manifest.ChromeLayout, modData, engineDate, UpgradeRules.UpgradeChromeLayout);
// The map cache won't be valid if there was a map format upgrade, so walk the map packages manually
// Only upgrade system maps - user maps must be updated manually using --upgrade-map
Console.WriteLine("Processing Maps:");
var mapPreviews = modData.MapCache
.Where(m => m.Status == MapStatus.Available);
foreach (var p in mapPreviews)
foreach (var kv in modData.Manifest.MapFolders)
{
var package = (IReadWritePackage)p.Package;
Console.WriteLine("\t" + package.Name);
UpgradeRules.UpgradeMapFormat(modData, package);
var name = kv.Key;
var classification = string.IsNullOrEmpty(kv.Value)
? MapClassification.Unknown : Enum<MapClassification>.Parse(kv.Value);
var map = new Map(modData, package);
UpgradeRules.UpgradeActorRules(engineDate, ref map.RuleDefinitions, null, 0);
UpgradeRules.UpgradeWeaponRules(engineDate, ref map.WeaponDefinitions, null, 0);
UpgradeRules.UpgradePlayers(engineDate, ref map.PlayerDefinitions, null, 0);
UpgradeRules.UpgradeActors(engineDate, ref map.ActorDefinitions, null, 0);
map.Save(package);
if (classification != MapClassification.System)
continue;
var optional = name.StartsWith("~");
if (optional)
name = name.Substring(1);
try
{
using (var package = (IReadWritePackage)modData.ModFiles.OpenPackage(name))
{
foreach (var map in package.Contents)
{
try
{
using (var mapPackage = modData.ModFiles.OpenPackage(map, package))
{
if (mapPackage != null)
UpgradeMapCommand.UpgradeMap(modData, (IReadWritePackage)mapPackage, engineDate);
}
}
catch (Exception e)
{
Console.WriteLine("Failed to upgrade map {0}", map);
Console.WriteLine("Error was: {0}", e.ToString());
}
}
}
}
catch { }
}
}
}

View File

@@ -728,10 +728,6 @@ namespace OpenRA.Mods.Common.UtilityCommands
if (mapFormat < 6)
throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(mapFormat, package.Name));
// Nothing to do
if (mapFormat >= 8)
return;
// Format 6 -> 7 combined the Selectable and UseAsShellmap flags into the Class enum
if (mapFormat < 7)
{
@@ -790,6 +786,169 @@ namespace OpenRA.Mods.Common.UtilityCommands
}
}
// Format 8 -> 9 moved map options and videos from the map file itself to traits
if (mapFormat < 9)
{
var rules = yaml.Nodes.FirstOrDefault(n => n.Key == "Rules");
var worldNode = rules.Value.Nodes.FirstOrDefault(n => n.Key == "World");
if (worldNode == null)
worldNode = new MiniYamlNode("World", new MiniYaml("", new List<MiniYamlNode>()));
var playerNode = rules.Value.Nodes.FirstOrDefault(n => n.Key == "Player");
if (playerNode == null)
playerNode = new MiniYamlNode("Player", new MiniYaml("", new List<MiniYamlNode>()));
var visibilityNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Visibility");
if (visibilityNode != null)
{
var visibility = FieldLoader.GetValue<MapVisibility>("Visibility", visibilityNode.Value.Value);
if (visibility.HasFlag(MapVisibility.MissionSelector))
{
var missionData = new MiniYamlNode("MissionData", new MiniYaml("", new List<MiniYamlNode>()));
worldNode.Value.Nodes.Add(missionData);
var description = yaml.Nodes.FirstOrDefault(n => n.Key == "Description");
if (description != null)
missionData.Value.Nodes.Add(new MiniYamlNode("Briefing", description.Value.Value));
var videos = yaml.Nodes.FirstOrDefault(n => n.Key == "Videos");
if (videos != null && videos.Value.Nodes.Any())
{
var backgroundVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "BackgroundInfo");
if (backgroundVideo != null)
missionData.Value.Nodes.Add(new MiniYamlNode("BackgroundVideo", backgroundVideo.Value.Value));
var briefingVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "Briefing");
if (briefingVideo != null)
missionData.Value.Nodes.Add(new MiniYamlNode("BriefingVideo", briefingVideo.Value.Value));
var startVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "GameStart");
if (startVideo != null)
missionData.Value.Nodes.Add(new MiniYamlNode("StartVideo", startVideo.Value.Value));
var winVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "GameWon");
if (winVideo != null)
missionData.Value.Nodes.Add(new MiniYamlNode("WinVideo", winVideo.Value.Value));
var lossVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "GameLost");
if (lossVideo != null)
missionData.Value.Nodes.Add(new MiniYamlNode("LossVideo", lossVideo.Value.Value));
}
}
}
var mapOptions = yaml.Nodes.FirstOrDefault(n => n.Key == "Options");
if (mapOptions != null)
{
var cheats = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Cheats");
if (cheats != null)
{
worldNode.Value.Nodes.Add(new MiniYamlNode("DeveloperMode", new MiniYaml("", new List<MiniYamlNode>()
{
new MiniYamlNode("Locked", "True"),
new MiniYamlNode("Enabled", cheats.Value.Value)
})));
}
var crates = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Crates");
if (crates != null && !worldNode.Value.Nodes.Any(n => n.Key == "-CrateSpawner"))
{
if (!FieldLoader.GetValue<bool>("crates", crates.Value.Value))
worldNode.Value.Nodes.Add(new MiniYamlNode("-CrateSpawner", new MiniYaml("")));
}
var creeps = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Creeps");
if (creeps != null)
{
worldNode.Value.Nodes.Add(new MiniYamlNode("MapCreeps", new MiniYaml("", new List<MiniYamlNode>()
{
new MiniYamlNode("Locked", "True"),
new MiniYamlNode("Enabled", creeps.Value.Value)
})));
}
var fog = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Fog");
var shroud = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Shroud");
if (fog != null || shroud != null)
{
var shroudNode = new MiniYamlNode("Shroud", new MiniYaml("", new List<MiniYamlNode>()));
playerNode.Value.Nodes.Add(shroudNode);
if (fog != null)
{
shroudNode.Value.Nodes.Add(new MiniYamlNode("FogLocked", "True"));
shroudNode.Value.Nodes.Add(new MiniYamlNode("FogEnabled", fog.Value.Value));
}
if (shroud != null)
{
var enabled = FieldLoader.GetValue<bool>("shroud", shroud.Value.Value);
shroudNode.Value.Nodes.Add(new MiniYamlNode("ExploredMapLocked", "True"));
shroudNode.Value.Nodes.Add(new MiniYamlNode("ExploredMapEnabled", FieldSaver.FormatValue(!enabled)));
}
}
var allyBuildRadius = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "AllyBuildRadius");
if (allyBuildRadius != null)
{
worldNode.Value.Nodes.Add(new MiniYamlNode("MapBuildRadius", new MiniYaml("", new List<MiniYamlNode>()
{
new MiniYamlNode("AllyBuildRadiusLocked", "True"),
new MiniYamlNode("AllyBuildRadiusEnabled", allyBuildRadius.Value.Value)
})));
}
var startingCash = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "StartingCash");
if (startingCash != null)
{
playerNode.Value.Nodes.Add(new MiniYamlNode("PlayerResources", new MiniYaml("", new List<MiniYamlNode>()
{
new MiniYamlNode("DefaultCashLocked", "True"),
new MiniYamlNode("DefaultCash", startingCash.Value.Value)
})));
}
var startingUnits = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "ConfigurableStartingUnits");
if (startingUnits != null && !worldNode.Value.Nodes.Any(n => n.Key == "-SpawnMPUnits"))
{
worldNode.Value.Nodes.Add(new MiniYamlNode("SpawnMPUnits", new MiniYaml("", new List<MiniYamlNode>()
{
new MiniYamlNode("Locked", "True"),
})));
}
var techLevel = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "TechLevel");
var difficulties = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Difficulties");
var shortGame = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "ShortGame");
if (techLevel != null || difficulties != null || shortGame != null)
{
var optionsNode = new MiniYamlNode("MapOptions", new MiniYaml("", new List<MiniYamlNode>()));
worldNode.Value.Nodes.Add(optionsNode);
if (techLevel != null)
{
optionsNode.Value.Nodes.Add(new MiniYamlNode("TechLevelLocked", "True"));
optionsNode.Value.Nodes.Add(new MiniYamlNode("TechLevel", techLevel.Value.Value));
}
if (difficulties != null)
optionsNode.Value.Nodes.Add(new MiniYamlNode("Difficulties", difficulties.Value.Value));
if (shortGame != null)
{
optionsNode.Value.Nodes.Add(new MiniYamlNode("ShortGameLocked", "True"));
optionsNode.Value.Nodes.Add(new MiniYamlNode("ShortGameEnabled", shortGame.Value.Value));
}
}
}
if (worldNode.Value.Nodes.Any() && !rules.Value.Nodes.Contains(worldNode))
rules.Value.Nodes.Add(worldNode);
if (playerNode.Value.Nodes.Any() && !rules.Value.Nodes.Contains(playerNode))
rules.Value.Nodes.Add(playerNode);
}
yaml.Nodes.First(n => n.Key == "MapFormat").Value = new MiniYaml(Map.SupportedMapFormat.ToString());
package.Update("map.yaml", Encoding.UTF8.GetBytes(yaml.Nodes.WriteToString()));

View File

@@ -63,7 +63,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
map.SetBounds(tl, br);
map.PlayerDefinitions = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length).ToMiniYaml();
map.FixOpenAreas(world.Map.Rules);
map.FixOpenAreas();
Action<string> afterSave = uid =>
{

View File

@@ -52,10 +52,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var author = widget.Get<TextFieldWidget>("AUTHOR");
author.Text = map.Author;
// TODO: This should use a multi-line textfield once they exist
var description = widget.Get<TextFieldWidget>("DESCRIPTION");
description.Text = map.Description;
// TODO: This should use a multi-selection dropdown once they exist
var visibilityDropdown = widget.Get<DropDownButtonWidget>("VISIBILITY_DROPDOWN");
{
@@ -160,7 +156,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return;
map.Title = title.Text;
map.Description = description.Text;
map.Author = author.Text;
map.Visibility = (MapVisibility)Enum.Parse(typeof(MapVisibility), visibilityDropdown.Text);

View File

@@ -9,6 +9,7 @@
*/
#endregion
using OpenRA.Mods.Common.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic
@@ -24,12 +25,16 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var mapDescriptionPanel = widget.Get<ScrollPanelWidget>("MAP_DESCRIPTION_PANEL");
var mapDescription = widget.Get<LabelWidget>("MAP_DESCRIPTION");
var mapFont = Game.Renderer.Fonts[mapDescription.Font];
var text = world.Map.Description != null ? world.Map.Description.Replace("\\n", "\n") : "";
text = WidgetUtils.WrapText(text, mapDescription.Bounds.Width, mapFont);
mapDescription.Text = text;
mapDescription.Bounds.Height = mapFont.Measure(text).Y;
mapDescriptionPanel.ScrollToTop();
mapDescriptionPanel.Layout.AdjustChildren();
var missionData = world.Map.Rules.Actors["world"].TraitInfoOrDefault<MissionDataInfo>();
if (missionData != null)
{
var text = WidgetUtils.WrapText(missionData.Briefing.Replace("\\n", "\n"), mapDescription.Bounds.Width, mapFont);
mapDescription.Text = text;
mapDescription.Bounds.Height = mapFont.Measure(text).Y;
mapDescriptionPanel.ScrollToTop();
mapDescriptionPanel.Layout.AdjustChildren();
}
}
}
}

View File

@@ -63,10 +63,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (world.LocalPlayer != null)
{
var scriptContext = world.WorldActor.TraitOrDefault<LuaScript>();
var video = world.LocalPlayer.WinState == WinState.Won ? world.Map.Videos.GameWon : world.Map.Videos.GameLost;
if (!string.IsNullOrEmpty(video) && !(scriptContext != null && scriptContext.FatalErrorOccurred))
Media.PlayFMVFullscreen(world, video, () => { });
var missionData = world.WorldActor.Info.TraitInfoOrDefault<MissionDataInfo>();
if (missionData != null && !(scriptContext != null && scriptContext.FatalErrorOccurred))
{
var video = world.LocalPlayer.WinState == WinState.Won ? missionData.WinVideo : missionData.LossVideo;
if (!string.IsNullOrEmpty(video))
Media.PlayFMVFullscreen(world, video, () => { });
}
}
var optionsButton = playerRoot.GetOrNull<MenuButtonWidget>("OPTIONS_BUTTON");

View File

@@ -349,8 +349,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var allowCheats = optionsBin.GetOrNull<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
if (allowCheats != null)
{
var cheatsLocked = new CachedTransform<Map, bool>(
map => map.Rules.Actors["player"].TraitInfo<DeveloperModeInfo>().Locked);
allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
allowCheats.IsDisabled = () => configurationDisabled() || Map.Options.Cheats.HasValue;
allowCheats.IsDisabled = () => configurationDisabled() || cheatsLocked.Update(Map);
allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command(
"allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
}
@@ -358,8 +361,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var crates = optionsBin.GetOrNull<CheckboxWidget>("CRATES_CHECKBOX");
if (crates != null)
{
var cratesLocked = new CachedTransform<Map, bool>(map =>
{
var crateSpawner = map.Rules.Actors["world"].TraitInfoOrDefault<CrateSpawnerInfo>();
return crateSpawner == null || crateSpawner.Locked;
});
crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates;
crates.IsDisabled = () => configurationDisabled() || Map.Options.Crates.HasValue;
crates.IsDisabled = () => configurationDisabled() || cratesLocked.Update(Map);
crates.OnClick = () => orderManager.IssueOrder(Order.Command(
"crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
}
@@ -367,8 +376,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var creeps = optionsBin.GetOrNull<CheckboxWidget>("CREEPS_CHECKBOX");
if (creeps != null)
{
var creepsLocked = new CachedTransform<Map, bool>(map =>
{
var mapCreeps = map.Rules.Actors["world"].TraitInfoOrDefault<MapCreepsInfo>();
return mapCreeps == null || mapCreeps.Locked;
});
creeps.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Creeps;
creeps.IsDisabled = () => configurationDisabled() || Map.Options.Creeps.HasValue;
creeps.IsDisabled = () => configurationDisabled() || creepsLocked.Update(Map);
creeps.OnClick = () => orderManager.IssueOrder(Order.Command(
"creeps {0}".F(!orderManager.LobbyInfo.GlobalSettings.Creeps)));
}
@@ -376,8 +391,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var allybuildradius = optionsBin.GetOrNull<CheckboxWidget>("ALLYBUILDRADIUS_CHECKBOX");
if (allybuildradius != null)
{
var allyBuildRadiusLocked = new CachedTransform<Map, bool>(map =>
{
var mapBuildRadius = map.Rules.Actors["world"].TraitInfoOrDefault<MapBuildRadiusInfo>();
return mapBuildRadius == null || mapBuildRadius.AllyBuildRadiusLocked;
});
allybuildradius.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius;
allybuildradius.IsDisabled = () => configurationDisabled() || Map.Options.AllyBuildRadius.HasValue;
allybuildradius.IsDisabled = () => configurationDisabled() || allyBuildRadiusLocked.Update(Map);
allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command(
"allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius)));
}
@@ -385,8 +406,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var shortGame = optionsBin.GetOrNull<CheckboxWidget>("SHORTGAME_CHECKBOX");
if (shortGame != null)
{
var shortGameLocked = new CachedTransform<Map, bool>(
map => map.Rules.Actors["world"].TraitInfo<MapOptionsInfo>().ShortGameLocked);
shortGame.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.ShortGame;
shortGame.IsDisabled = () => configurationDisabled() || Map.Options.ShortGame.HasValue;
shortGame.IsDisabled = () => configurationDisabled() || shortGameLocked.Update(Map);
shortGame.OnClick = () => orderManager.IssueOrder(Order.Command(
"shortgame {0}".F(!orderManager.LobbyInfo.GlobalSettings.ShortGame)));
}
@@ -394,12 +418,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var difficulty = optionsBin.GetOrNull<DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");
if (difficulty != null)
{
difficulty.IsVisible = () => Map != null && Map.Options.Difficulties.Any();
difficulty.IsDisabled = configurationDisabled;
var mapOptions = new CachedTransform<Map, MapOptionsInfo>(
map => map.Rules.Actors["world"].TraitInfo<MapOptionsInfo>());
difficulty.IsVisible = () => Map != null && mapOptions.Update(Map).Difficulties.Any();
difficulty.IsDisabled = () => configurationDisabled() || mapOptions.Update(Map).DifficultyLocked;
difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
difficulty.OnMouseDown = _ =>
{
var options = Map.Options.Difficulties.Select(d => new DropDownOption
var options = mapOptions.Update(Map).Difficulties.Select(d => new DropDownOption
{
Title = d,
IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
@@ -420,19 +447,27 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var startingUnits = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGUNITS_DROPDOWNBUTTON");
if (startingUnits != null)
{
var startUnitsInfo = modRules.Actors["world"].TraitInfos<MPStartUnitsInfo>();
var classes = startUnitsInfo.Select(a => a.Class).Distinct();
var startUnitsInfos = new CachedTransform<Map, IEnumerable<MPStartUnitsInfo>>(
map => map.Rules.Actors["world"].TraitInfos<MPStartUnitsInfo>());
var startUnitsLocked = new CachedTransform<Map, bool>(map =>
{
var spawnUnitsInfo = map.Rules.Actors["world"].TraitInfoOrDefault<SpawnMPUnitsInfo>();
return spawnUnitsInfo == null || spawnUnitsInfo.Locked;
});
Func<string, string> className = c =>
{
var selectedClass = startUnitsInfo.Where(s => s.Class == c).Select(u => u.ClassName).FirstOrDefault();
var selectedClass = startUnitsInfos.Update(Map).Where(s => s.Class == c).Select(u => u.ClassName).FirstOrDefault();
return selectedClass != null ? selectedClass : c;
};
startingUnits.IsDisabled = () => configurationDisabled() || !Map.Options.ConfigurableStartingUnits;
startingUnits.IsDisabled = () => configurationDisabled() || startUnitsLocked.Update(Map);
startingUnits.GetText = () => MapPreview.Status != MapStatus.Available ||
Map == null || !Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
Map == null || startUnitsLocked.Update(Map) ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
startingUnits.OnMouseDown = _ =>
{
var classes = startUnitsInfos.Update(Map).Select(a => a.Class).Distinct();
var options = classes.Select(c => new DropDownOption
{
Title = className(c),
@@ -456,12 +491,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var startingCash = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON");
if (startingCash != null)
{
startingCash.IsDisabled = () => configurationDisabled() || Map.Options.StartingCash.HasValue;
var playerResources = new CachedTransform<Map, PlayerResourcesInfo>(
map => map.Rules.Actors["player"].TraitInfo<PlayerResourcesInfo>());
startingCash.IsDisabled = () => configurationDisabled() || playerResources.Update(Map).DefaultCashLocked;
startingCash.GetText = () => MapPreview.Status != MapStatus.Available ||
Map == null || Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
Map == null || playerResources.Update(Map).DefaultCashLocked ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
startingCash.OnMouseDown = _ =>
{
var options = modRules.Actors["player"].TraitInfo<PlayerResourcesInfo>().SelectableCash.Select(c => new DropDownOption
var options = playerResources.Update(Map).SelectableCash.Select(c => new DropDownOption
{
Title = "${0}".F(c),
IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingCash == c,
@@ -482,19 +520,23 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var techLevel = optionsBin.GetOrNull<DropDownButtonWidget>("TECHLEVEL_DROPDOWNBUTTON");
if (techLevel != null)
{
var techTraits = modRules.Actors["player"].TraitInfos<ProvidesTechPrerequisiteInfo>().ToList();
techLevel.IsVisible = () => techTraits.Count > 0;
var mapOptions = new CachedTransform<Map, MapOptionsInfo>(
map => map.Rules.Actors["world"].TraitInfo<MapOptionsInfo>());
var techLevels = new CachedTransform<Map, List<ProvidesTechPrerequisiteInfo>>(
map => map.Rules.Actors["player"].TraitInfos<ProvidesTechPrerequisiteInfo>().ToList());
techLevel.IsVisible = () => Map != null && techLevels.Update(Map).Any();
var techLevelDescription = optionsBin.GetOrNull<LabelWidget>("TECHLEVEL_DESC");
if (techLevelDescription != null)
techLevelDescription.IsVisible = () => techTraits.Count > 0;
techLevelDescription.IsVisible = techLevel.IsVisible;
techLevel.IsDisabled = () => configurationDisabled() || Map.Options.TechLevel != null || techTraits.Count <= 1;
techLevel.IsDisabled = () => configurationDisabled() || mapOptions.Update(Map).TechLevelLocked;
techLevel.GetText = () => MapPreview.Status != MapStatus.Available ||
Map == null || Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel);
Map == null || mapOptions.Update(Map).TechLevelLocked ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel);
techLevel.OnMouseDown = _ =>
{
var options = techTraits.Select(c => new DropDownOption
var options = techLevels.Update(Map).Select(c => new DropDownOption
{
Title = "{0}".F(c.Name),
IsSelected = () => orderManager.LobbyInfo.GlobalSettings.TechLevel == c.Name,
@@ -553,8 +595,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var exploredMap = optionsBin.GetOrNull<CheckboxWidget>("EXPLORED_MAP_CHECKBOX");
if (exploredMap != null)
{
var exploredMapLocked = new CachedTransform<Map, bool>(
map => map.Rules.Actors["player"].TraitInfo<ShroudInfo>().ExploredMapLocked);
exploredMap.IsChecked = () => !orderManager.LobbyInfo.GlobalSettings.Shroud;
exploredMap.IsDisabled = () => configurationDisabled() || Map.Options.Shroud.HasValue;
exploredMap.IsDisabled = () => configurationDisabled() || exploredMapLocked.Update(Map);
exploredMap.OnClick = () => orderManager.IssueOrder(Order.Command(
"shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud)));
}
@@ -562,8 +607,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var enableFog = optionsBin.GetOrNull<CheckboxWidget>("FOG_CHECKBOX");
if (enableFog != null)
{
var fogLocked = new CachedTransform<Map, bool>(
map => map.Rules.Actors["player"].TraitInfo<ShroudInfo>().FogLocked);
enableFog.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Fog;
enableFog.IsDisabled = () => configurationDisabled() || Map.Options.Fog.HasValue;
enableFog.IsDisabled = () => configurationDisabled() || fogLocked.Update(Map);
enableFog.OnClick = () => orderManager.IssueOrder(Order.Command(
"fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog)));
}
@@ -761,11 +809,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
// Tell the server that we have the map
orderManager.IssueOrder(Order.Command("state {0}".F(Session.ClientState.NotReady)));
// Restore default starting cash if the last map set it to something invalid
var pri = modRules.Actors["player"].TraitInfo<PlayerResourcesInfo>();
if (!currentMap.Options.StartingCash.HasValue && !pri.SelectableCash.Contains(orderManager.LobbyInfo.GlobalSettings.StartingCash))
orderManager.IssueOrder(Order.Command("startingcash {0}".F(pri.DefaultCash)));
}
});
}).Start();

View File

@@ -15,6 +15,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Traits;
using OpenRA.Network;
using OpenRA.Primitives;
using OpenRA.Widgets;
@@ -177,15 +178,51 @@ namespace OpenRA.Mods.Common.Widgets.Logic
selectedMapPreview = preview;
// Cache the rules on a background thread to avoid jank
new Thread(() => selectedMap.PreloadRules()).Start();
var difficultyDisabled = true;
var difficulties = new string[0];
var briefingVideo = selectedMap.Videos.Briefing;
var briefingVideoVisible = briefingVideo != null;
var briefingVideoDisabled = !(briefingVideoVisible && modData.DefaultFileSystem.Exists(briefingVideo));
var briefingVideo = "";
var briefingVideoVisible = false;
var briefingVideoDisabled = true;
var infoVideo = selectedMap.Videos.BackgroundInfo;
var infoVideoVisible = infoVideo != null;
var infoVideoDisabled = !(infoVideoVisible && modData.DefaultFileSystem.Exists(infoVideo));
var infoVideo = "";
var infoVideoVisible = false;
var infoVideoDisabled = true;
var map = selectedMap;
new Thread(() =>
{
map.PreloadRules();
var mapOptions = map.Rules.Actors["world"].TraitInfo<MapOptionsInfo>();
difficulty = mapOptions.Difficulty ?? mapOptions.Difficulties.FirstOrDefault();
difficulties = mapOptions.Difficulties;
difficultyDisabled = mapOptions.DifficultyLocked || mapOptions.Difficulties.Length <= 1;
var missionData = map.Rules.Actors["world"].TraitInfoOrDefault<MissionDataInfo>();
if (missionData != null)
{
briefingVideo = missionData.BriefingVideo;
briefingVideoVisible = briefingVideo != null;
briefingVideoDisabled = !(briefingVideoVisible && modData.DefaultFileSystem.Exists(briefingVideo));
infoVideo = missionData.BackgroundVideo;
infoVideoVisible = infoVideo != null;
infoVideoDisabled = !(infoVideoVisible && modData.DefaultFileSystem.Exists(infoVideo));
var briefing = WidgetUtils.WrapText(missionData.Briefing.Replace("\\n", "\n"), description.Bounds.Width, descriptionFont);
var height = descriptionFont.Measure(briefing).Y;
Game.RunAfterTick(() =>
{
if (map == selectedMap)
{
description.Text = briefing;
description.Bounds.Height = height;
descriptionPanel.Layout.AdjustChildren();
}
});
}
}).Start();
startBriefingVideoButton.IsVisible = () => briefingVideoVisible && playingVideo != PlayingVideo.Briefing;
startBriefingVideoButton.IsDisabled = () => briefingVideoDisabled || playingVideo != PlayingVideo.None;
@@ -195,22 +232,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
startInfoVideoButton.IsDisabled = () => infoVideoDisabled || playingVideo != PlayingVideo.None;
startInfoVideoButton.OnClick = () => PlayVideo(videoPlayer, infoVideo, PlayingVideo.Info, () => StopVideo(videoPlayer));
var text = selectedMap.Description != null ? selectedMap.Description.Replace("\\n", "\n") : "";
text = WidgetUtils.WrapText(text, description.Bounds.Width, descriptionFont);
description.Text = text;
description.Bounds.Height = descriptionFont.Measure(text).Y;
descriptionPanel.ScrollToTop();
descriptionPanel.Layout.AdjustChildren();
if (difficultyButton != null)
{
difficultyButton.IsDisabled = () => !selectedMap.Options.Difficulties.Any();
difficulty = selectedMap.Options.Difficulties.FirstOrDefault();
difficultyButton.IsDisabled = () => difficultyDisabled;
difficultyButton.GetText = () => difficulty ?? "Normal";
difficultyButton.OnMouseDown = _ =>
{
var options = selectedMap.Options.Difficulties.Select(d => new DropDownOption
var options = difficulties.Select(d => new DropDownOption
{
Title = d,
IsSelected = () => difficulty == d,
@@ -304,18 +334,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (selectedMap.InvalidCustomRules)
return;
var gameStartVideo = selectedMap.Videos.GameStart;
var orders = new[] {
Order.Command("gamespeed {0}".F(gameSpeed)),
Order.Command("difficulty {0}".F(difficulty)),
Order.Command("state {0}".F(Session.ClientState.Ready))
};
if (gameStartVideo != null && modData.DefaultFileSystem.Exists(gameStartVideo))
var missionData = selectedMap.Rules.Actors["world"].TraitInfoOrDefault<MissionDataInfo>();
if (missionData != null && missionData.StartVideo != null && modData.DefaultFileSystem.Exists(missionData.StartVideo))
{
var fsPlayer = fullscreenVideoPlayer.Get<VqaPlayerWidget>("PLAYER");
fullscreenVideoPlayer.Visible = true;
PlayVideo(fsPlayer, gameStartVideo, PlayingVideo.GameStart, () =>
PlayVideo(fsPlayer, missionData.StartVideo, PlayingVideo.GameStart, () =>
{
StopVideo(fsPlayer);
Game.CreateAndStartLocalServer(selectedMapPreview.Uid, orders, onStart);

View File

@@ -226,7 +226,7 @@ namespace OpenRA.Mods.RA.UtilityCommands
public override void ReadActors(IniFile file)
{
base.ReadActors(file);
LoadActors(file, "SHIPS", Players, MapSize, Rules, Map);
LoadActors(file, "SHIPS", Players, MapSize, Map);
}
}
}

View File

@@ -236,7 +236,6 @@ namespace OpenRA.Mods.TS.UtilityCommands
map.MapTiles = Exts.Lazy(() => new CellLayer<TerrainTile>(map.Grid.Type, size));
map.MapHeight = Exts.Lazy(() => new CellLayer<byte>(map.Grid.Type, size));
map.Options = new MapOptions();
map.RequiresMod = modData.Manifest.Mod.Id;
return map;

View File

@@ -31,8 +31,6 @@ ChromeMetrics:
Fonts:
LobbyDefaults:
SoundFormats:
SpriteFormats:

View File

@@ -78,7 +78,7 @@ Background@SAVE_MAP_PANEL:
X: (WINDOW_RIGHT - WIDTH)/2
Y: (WINDOW_BOTTOM - HEIGHT)/2
Width: 345
Height: 264
Height: 229
Children:
Label@LABEL_TITLE:
Text: Save Map
@@ -89,7 +89,7 @@ Background@SAVE_MAP_PANEL:
Align: Center
Background@SAVE_MAP_BACKGROUND:
Width: PARENT_RIGHT
Height: 230
Height: 195
Background: panel-black
Children:
Label@TITLE_LABEL:
@@ -118,60 +118,47 @@ Background@SAVE_MAP_PANEL:
Width: 220
MaxLength: 50
Height: 25
Label@DESCRIPTION_LABEL:
X: 10
Y: 84
Width: 95
Height: 25
Align: Right
Text: Description:
TextField@DESCRIPTION:
X: 110
Y: 85
Width: 220
MaxLength: 50
Height: 25
Label@VISIBILITY_LABEL:
X: 10
Y: 119
Y: 84
Width: 95
Height: 25
Align: Right
Text: Visibility:
DropDownButton@VISIBILITY_DROPDOWN:
X: 110
Y: 120
Y: 85
Width: 220
Height: 25
Font: Regular
Label@DIRECTORY_LABEL:
X: 10
Y: 154
Y: 119
Width: 95
Height: 25
Align: Right
Text: Directory:
DropDownButton@DIRECTORY_DROPDOWN:
X: 110
Y: 155
Y: 120
Width: 220
Height: 25
Font: Regular
Label@FILENAME_LABEL:
X: 10
Y: 189
Y: 154
Width: 95
Height: 25
Align: Right
Text: Filename:
TextField@FILENAME:
X: 110
Y: 190
Y: 155
Width: 105
Height: 25
DropDownButton@TYPE_DROPDOWN:
X: 220
Y: 190
Y: 155
Width: 110
Height: 25
Font: Regular

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: C&C64 Special Ops - GDI 1
Description: Nod is experimenting on civilians with Tiberium. Use the commando to take out the SAM sites surrounding the dropoff area. With the SAMs gone you will then get an airstrike. Take out the Obelisk and an MCV will be delivered to help you to locate and destroy the biochem facility.
Author: Westwood Studios
Tileset: TEMPERAT
@@ -18,22 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
GameStart: obel.vqa
GameWon: orcabomb.vqa
GameLost: cutout.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 10000
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@Nod:
Name: Nod
@@ -758,10 +740,32 @@ Rules:
PanelName: MISSION_OBJECTIVES
MusicPlaylist:
StartingMusic: aoi
MissionData:
Briefing: Nod is experimenting on civilians with Tiberium. Use the commando to take out the SAM sites surrounding the dropoff area. With the SAMs gone you will then get an airstrike. Take out the Obelisk and an MCV will be delivered to help you to locate and destroy the biochem facility.
StartVideo: obel.vqa
WinVideo: orcabomb.vqa
LossVideo: cutout.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
Player:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 10000
^Vehicle:
Tooltip:
GenericVisibility: Enemy

Binary file not shown.

Binary file not shown.

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Strange Behavior
Description: There have been some reports of strange animals in this area. \n\nTake your units to investigate, and report back your findings.
Author: Westwood Studios
Tileset: JUNGLE
@@ -18,22 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: generic.vqa
GameStart: dino.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 0
ConfigurableStartingUnits: False
Difficulties: Easy, Normal
ShortGame: False
Players:
PlayerReference@Neutral:
Name: Neutral
@@ -361,7 +343,7 @@ Actors:
Location: 21,15
Owner: Civilian
Actor117: v06
Owner: Neutral # TREX can't attack it
Owner: Neutral
Location: 21,8
Actor100: v07
Location: 12,12
@@ -443,6 +425,14 @@ Rules:
MissionObjectives:
EarlyGameOver: true
EnemyWatcher:
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 0
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -453,6 +443,20 @@ Rules:
PanelName: MISSION_OBJECTIVES
MusicPlaylist:
StartingMusic: j1
MissionData:
Briefing: There have been some reports of strange animals in this area. \n\nTake your units to investigate, and report back your findings.
BriefingVideo: generic.vqa
StartVideo: dino.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
Difficulties: Easy, Normal
ShortGameLocked: True
ShortGameEnabled: False
^Vehicle:
Tooltip:
GenericVisibility: Enemy

Binary file not shown.

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Storm the Beachhead
Description: Use the units provided to protect the Mobile Construction Vehicle (MCV).\n\nYou should then deploy the MCV by selecting it with a left-click and then right-clicking on it.\n\nThen you can begin to build up a base. Start with a Power Plant.\n\nFinally, search out and destroy all enemy Nod units in the surrounding area.
Author: Westwood Studios
Tileset: TEMPERAT
@@ -18,24 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
BackgroundInfo: intro2.vqa
Briefing: gdi1.vqa
GameStart: landing.vqa
GameWon: consyard.vqa
GameLost: gameover.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 5000
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@Nod:
Name: Nod
@@ -442,10 +422,34 @@ Rules:
PanelName: MISSION_OBJECTIVES
MusicPlaylist:
StartingMusic: aoi
MissionData:
Briefing: Use the units provided to protect the Mobile Construction Vehicle (MCV).\n\nYou should then deploy the MCV by selecting it with a left-click and then right-clicking on it.\n\nThen you can begin to build up a base. Start with a Power Plant.\n\nFinally, search out and destroy all enemy Nod units in the surrounding area.
BackgroundVideo: intro2.vqa
BriefingVideo: gdi1.vqa
StartVideo: landing.vqa
WinVideo: consyard.vqa
LossVideo: gameover.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
Player:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 5000
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Knock out the Refinery
Description: Defend your position, deploy the MCV, then build a sizable force to search out and destroy the Nod base in the area.\n\nAll Nod units and structures must be either destroyed or captured to complete objective.
Author: Westwood Studios
Tileset: TEMPERAT
@@ -18,22 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: gdi2.vqa
GameWon: flag.vqa
GameLost: gameover.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 5000
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@GDI:
Name: GDI
@@ -669,10 +651,32 @@ Rules:
PanelName: MISSION_OBJECTIVES
MusicPlaylist:
StartingMusic: befeared
MissionData:
Briefing: Defend your position, deploy the MCV, then build a sizable force to search out and destroy the Nod base in the area.\n\nAll Nod units and structures must be either destroyed or captured to complete objective.
BriefingVideo: gdi2.vqa
WinVideo: flag.vqa
LossVideo: gameover.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
Player:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 5000
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Destroy The SAM Sites
Description: Build up forces to destroy Nod base.\n\nOnce all Nod SAM sites are neutralized then air support will be provided to combat obstacles such as turrets.\n\nDestroy all units and structures to complete the mission objective.
Author: Westwood Studios
Tileset: TEMPERAT
@@ -18,23 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: gdi3.vqa
GameStart: samdie.vqa
GameWon: bombaway.vqa
GameLost: gameover.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 5000
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@Nod:
Name: Nod
@@ -744,10 +725,33 @@ Rules:
PanelName: MISSION_OBJECTIVES
MusicPlaylist:
StartingMusic: crep226m
MissionData:
Briefing: Build up forces to destroy Nod base.\n\nOnce all Nod SAM sites are neutralized then air support will be provided to combat obstacles such as turrets.\n\nDestroy all units and structures to complete the mission objective.
BriefingVideo: gdi3.vqa
StartVideo: samdie.vqa
WinVideo: bombaway.vqa
LossVideo: gameover.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
Player:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 5000
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Get the Rods back (a)
Description: Nod has captured classified GDI property.\n\nYou must find and retrieve the stolen equipment.\n\nIt is being transported in a shipping crate.\n\nUse the new APC to strategically transport infantry through Nod forces.
Author: Westwood Studios
Tileset: TEMPERAT
@@ -18,24 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
BackgroundInfo: bkground.vqa
Briefing: gdi4b.vqa
GameStart: nitejump.vqa
GameWon: burdet1.vqa
GameLost: gameover.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 0
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@Nod:
Name: Nod
@@ -503,10 +483,34 @@ Rules:
PanelName: MISSION_OBJECTIVES
MusicPlaylist:
StartingMusic: fist226m
MissionData:
Briefing: Nod has captured classified GDI property.\n\nYou must find and retrieve the stolen equipment.\n\nIt is being transported in a shipping crate.\n\nUse the new APC to strategically transport infantry through Nod forces.
BackgroundVideo: bkground.vqa
BriefingVideo: gdi4b.vqa
StartVideo: nitejump.vqa
WinVideo: burdet1.vqa
LossVideo: gameover.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
Player:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 0
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Get the Rods back (b)
Description: Nod has captured classified GDI property.\n\nYou must find and retrieve the stolen equipment.\n\nIt is being transported in a shipping crate.\n\nUse the new APC to strategically transport infantry through Nod forces.
Author: Westwood Studios
Tileset: TEMPERAT
@@ -18,24 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
BackgroundInfo: bkground.vqa
Briefing: gdi4b.vqa
GameStart: nitejump.vqa
GameWon: burdet1.vqa
GameLost: gameover.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 0
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@Nod:
Name: Nod
@@ -574,10 +554,34 @@ Rules:
PanelName: MISSION_OBJECTIVES
MusicPlaylist:
StartingMusic: fist226m
MissionData:
Briefing: Nod has captured classified GDI property.\n\nYou must find and retrieve the stolen equipment.\n\nIt is being transported in a shipping crate.\n\nUse the new APC to strategically transport infantry through Nod forces.
BackgroundVideo: bkground.vqa
BriefingVideo: gdi4b.vqa
StartVideo: nitejump.vqa
WinVideo: burdet1.vqa
LossVideo: gameover.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
Player:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 0
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Take Białystok
Description: Nod is moving to capture and hold a civilian town.\n\nYour mission is to reach the town first and hold off invading Nod units until GDI reinforcements can arrive.\n\nAll invading Nod units must be destroyed.
Author: Westwood Studios
Tileset: TEMPERAT
@@ -18,24 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
BackgroundInfo: bkground.vqa
Briefing: gdi4a.vqa
GameStart: nodsweep.vqa
GameWon: burdet1.vqa
GameLost: gameover.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 0
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@Neutral:
Name: Neutral
@@ -801,10 +781,34 @@ Rules:
PanelName: MISSION_OBJECTIVES
MusicPlaylist:
StartingMusic: ind
MissionData:
Briefing: Nod is moving to capture and hold a civilian town.\n\nYour mission is to reach the town first and hold off invading Nod units until GDI reinforcements can arrive.\n\nAll invading Nod units must be destroyed.
BackgroundVideo: bkground.vqa
BriefingVideo: gdi4a.vqa
StartVideo: nodsweep.vqa
WinVideo: burdet1.vqa
LossVideo: gameover.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
Player:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 0
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Repair the GDI base (a)
Description: A GDI field base is under attack. They have fended off one attack but will not survive another.\n\nMove to the base, repair the structures and then launch a strike force to destroy the Nod base in the area.\n\nDestroy all Nod units and structures.
Author: Westwood Studios
Tileset: TEMPERAT
@@ -18,25 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
BackgroundInfo: podium.vqa
Briefing: gdi5.vqa
GameStart: seige.vqa
GameWon: nodlose.vqa
GameLost: gdilose.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 2000
ConfigurableStartingUnits: False
Difficulties: Easy, Normal, Hard
ShortGame: False
Players:
PlayerReference@Nod:
Name: Nod
@@ -814,11 +793,36 @@ Rules:
PanelName: MISSION_OBJECTIVES
MusicPlaylist:
StartingMusic: rain
MissionData:
Briefing: A GDI field base is under attack. They have fended off one attack but will not survive another.\n\nMove to the base, repair the structures and then launch a strike force to destroy the Nod base in the area.\n\nDestroy all Nod units and structures.
BackgroundVideo: podium.vqa
BriefingVideo: gdi5.vqa
StartVideo: seige.vqa
WinVideo: nodlose.vqa
LossVideo: gdilose.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
Difficulties: Easy, Normal, Hard
ShortGameLocked: True
ShortGameEnabled: False
Player:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
EnemyWatcher:
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 2000
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Repair the GDI base (b)
Description: A GDI field base is under attack. They have fended off one attack but will not survive another.\n\nMove to the base, repair the structures and then launch a strike force to destroy the Nod base in the area.\n\nDestroy all Nod units and structures.
Author: Westwood Studios
Tileset: TEMPERAT
@@ -18,24 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
BackgroundInfo: podium.vqa
Briefing: gdi5.vqa
GameStart: seige.vqa
GameWon: nodlose.vqa
GameLost: gdilose.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 4000
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@Nod:
Name: Nod
@@ -660,6 +640,14 @@ Rules:
EnemyWatcher:
MusicPlaylist:
StartingMusic: rain
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 4000
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -668,6 +656,22 @@ Rules:
PanelName: MISSION_OBJECTIVES
LuaScript:
Scripts: gdi05b.lua
MissionData:
Briefing: A GDI field base is under attack. They have fended off one attack but will not survive another.\n\nMove to the base, repair the structures and then launch a strike force to destroy the Nod base in the area.\n\nDestroy all Nod units and structures.
BackgroundVideo: podium.vqa
BriefingVideo: gdi5.vqa
StartVideo: seige.vqa
WinVideo: nodlose.vqa
LossVideo: gdilose.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Infiltrate Nod Base
Description: Use a GDI Commando to infiltrate the Nod base. **** ** destroy the ******** so that the base is incapacitated. Get in, hit it, and get the **** out.
Author: Westwood Studios
Tileset: TEMPERAT
@@ -18,24 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: gdi6.vqa
GameStart: nitejump.vqa
GameWon: sabotage.vqa
GameLost: gdilose.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 0
ConfigurableStartingUnits: False
Difficulties: Easy, Normal, Hard
ShortGame: True
Players:
PlayerReference@Neutral:
Name: Neutral
@@ -1085,10 +1065,34 @@ Rules:
Green: 0.85
Blue: 1.5
Ambient: 0.35
MissionData:
Briefing: Use a GDI Commando to infiltrate the Nod base. **** ** destroy the ******** so that the base is incapacitated. Get in, hit it, and get the **** out.
BriefingVideo: gdi6.vqa
StartVideo: nitejump.vqa
WinVideo: sabotage.vqa
LossVideo: gdilose.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
Difficulties: Easy, Normal, Hard
ShortGameLocked: True
ShortGameEnabled: True
Player:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 0
^Vehicle:
Tooltip:
GenericVisibility: Enemy

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Nikoomba's Demise
Description: In order for the Brotherhood to gain a foothold, we must begin by eliminating certain elements.\n\nNikoomba, the nearby village's leader, is one such element.\n\nHis views and ours do not coincide.\n\nHe and his whole group must be eliminated.
Author: Westwood Studios
Tileset: DESERT
@@ -18,22 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
BackgroundInfo: intro2.vqa
Briefing: nod1.vqa
GameLost: nodlose.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 0
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@Neutral:
Name: Neutral
@@ -295,6 +277,14 @@ Rules:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 0
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -306,6 +296,20 @@ Rules:
MusicPlaylist:
StartingMusic: nomercy
VictoryMusic: nod_win1
MissionData:
Briefing: In order for the Brotherhood to gain a foothold, we must begin by eliminating certain elements.\n\nNikoomba, the nearby village's leader, is one such element.\n\nHis views and ours do not coincide.\n\nHe and his whole group must be eliminated.
BackgroundVideo: intro2.vqa
BriefingVideo: nod1.vqa
LossVideo: nodlose.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
C10:
Tooltip:
Name: Nikoomba

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Invasion of Egypt (a)
Description: GDI has kept a stranglehold on Egypt for many years. Set up a forward attack base in your area. To do this you must select your Mobile Construction Vehicle (MCV) and right click on it. From here you can begin to build a base. This area contains plenty of Tiberium, so establishing the base should be easy.
Author: Westwood Studios
Tileset: DESERT
@@ -18,23 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: nod2.vqa
GameStart: seige.vqa
GameWon: airstrk.vqa
GameLost: deskill.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 4000
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@GDI:
Name: GDI
@@ -235,6 +216,14 @@ Rules:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 4000
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -246,6 +235,21 @@ Rules:
MusicPlaylist:
StartingMusic: ind2
VictoryMusic: nod_win1
MissionData:
Briefing: GDI has kept a stranglehold on Egypt for many years. Set up a forward attack base in your area. To do this you must select your Mobile Construction Vehicle (MCV) and right click on it. From here you can begin to build a base. This area contains plenty of Tiberium, so establishing the base should be easy.
BriefingVideo: nod2.vqa
StartVideo: seige.vqa
WinVideo: airstrk.vqa
LossVideo: deskill.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Invasion of Egypt (b)
Description: GDI has kept a stranglehold on Egypt for many years. Set up a forward attack base in your area. To do this you must select your Mobile Construction Vehicle (MCV) and right click on it. From here you can begin to build a base. This area contains plenty of Tiberium, so establishing the base should be easy.
Author: Westwood Studios
Tileset: DESERT
@@ -18,23 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: nod2.vqa
GameStart: seige.vqa
GameWon: airstrk.vqa
GameLost: deskill.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 4000
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@GDI:
Name: GDI
@@ -277,6 +258,14 @@ Rules:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 4000
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -288,6 +277,21 @@ Rules:
MusicPlaylist:
StartingMusic: ind2
VictoryMusic: nod_win1
MissionData:
Briefing: GDI has kept a stranglehold on Egypt for many years. Set up a forward attack base in your area. To do this you must select your Mobile Construction Vehicle (MCV) and right click on it. From here you can begin to build a base. This area contains plenty of Tiberium, so establishing the base should be easy.
BriefingVideo: nod2.vqa
StartVideo: seige.vqa
WinVideo: airstrk.vqa
LossVideo: deskill.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Sudanese Prison Break (a)
Description: GDI has established a prison camp, where they are detaining some of the local political leaders.\n\nKane wishes to liberate these victims.\n\nDestroy the GDI forces and capture the prison, do not destroy it.
Author: Westwood Studios
Tileset: DESERT
@@ -18,23 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: nod3.vqa
GameStart: dessweep.vqa
GameWon: desflees.vqa
GameLost: flag.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 4000
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@Neutral:
Name: Neutral
@@ -471,6 +452,14 @@ Rules:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 4000
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -482,6 +471,21 @@ Rules:
MusicPlaylist:
StartingMusic: chrg226m
VictoryMusic: nod_win1
MissionData:
Briefing: GDI has established a prison camp, where they are detaining some of the local political leaders.\n\nKane wishes to liberate these victims.\n\nDestroy the GDI forces and capture the prison, do not destroy it.
BriefingVideo: nod3.vqa
StartVideo: dessweep.vqa
WinVideo: desflees.vqa
LossVideo: flag.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Sudanese Prison Break (b)
Description: GDI has established a prison camp, where they are detaining some of the local political leaders.\n\nKane wishes to liberate these victims.\n\nDestroy the GDI forces and capture the prison, do not destroy it.
Author: Westwood Studios
Tileset: DESERT
@@ -18,23 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: nod3.vqa
GameStart: dessweep.vqa
GameWon: desflees.vqa
GameLost: flag.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 4000
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@Neutral:
Name: Neutral
@@ -515,6 +496,14 @@ Rules:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 4000
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -526,6 +515,21 @@ Rules:
MusicPlaylist:
StartingMusic: chrg226m
VictoryMusic: nod_win1
MissionData:
Briefing: GDI has established a prison camp, where they are detaining some of the local political leaders.\n\nKane wishes to liberate these victims.\n\nDestroy the GDI forces and capture the prison, do not destroy it.
BriefingVideo: nod3.vqa
StartVideo: dessweep.vqa
WinVideo: desflees.vqa
LossVideo: flag.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Mao Civil War (a)
Description: A small village friendly to our cause has been increasingly harassed by GDI, and the Brotherhood wishes you to assist them in their efforts.\n\nSeek out the enemy village and destroy it. The event will be disguised as a GDI attack.
Author: Westwood Studios
Tileset: DESERT
@@ -18,22 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: nod4b.vqa
GameStart: retro.vqa
GameLost: deskill.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 0
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@Neutral:
Name: Neutral
@@ -579,6 +561,14 @@ Rules:
MissionObjectives:
EarlyGameOver: true
EnemyWatcher:
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 0
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -590,6 +580,20 @@ Rules:
MusicPlaylist:
StartingMusic: valkyrie
VictoryMusic: nod_win1
MissionData:
Briefing: A small village friendly to our cause has been increasingly harassed by GDI, and the Brotherhood wishes you to assist them in their efforts.\n\nSeek out the enemy village and destroy it. The event will be disguised as a GDI attack.
BriefingVideo: nod4b.vqa
StartVideo: retro.vqa
LossVideo: deskill.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Oum Hadjer (b)
Description: A small village friendly to our cause has been increasingly harassed by GDI, and the Brotherhood wishes you to assist them in their efforts.\n\nSeek out the enemy village and destroy it. The event will be disguised as a GDI attack.
Author: Westwood Studios
Tileset: DESERT
@@ -18,21 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: nod4b.vqa
GameLost: nodlose.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 0
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@GDI:
Name: GDI
@@ -516,6 +499,14 @@ Rules:
MissionObjectives:
EarlyGameOver: true
EnemyWatcher:
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 0
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -527,6 +518,19 @@ Rules:
MusicPlaylist:
StartingMusic: warfare
VictoryMusic: nod_win1
MissionData:
Briefing: A small village friendly to our cause has been increasingly harassed by GDI, and the Brotherhood wishes you to assist them in their efforts.\n\nSeek out the enemy village and destroy it. The event will be disguised as a GDI attack.
BriefingVideo: nod4b.vqa
LossVideo: nodlose.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Warthog Hunt
Description: Our brothers within GDI tell us of A-10 strike jets scheduled to be deployed here soon. Our suppliers have delivered new Surface to Air Missiles to aid you. Use the SAMs to defend your base, then seek out their base and destroy it.
Author: Westwood Studios
Tileset: DESERT
@@ -18,24 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
BackgroundInfo: sethpre.vqa
Briefing: nod5.vqa
GameStart: samsite.vqa
GameWon: insites.vqa
GameLost: flag.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 5000
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@GDI:
Name: GDI
@@ -418,6 +398,14 @@ Rules:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 5000
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -429,6 +417,22 @@ Rules:
MusicPlaylist:
StartingMusic: airstrik
VictoryMusic: nod_win1
MissionData:
Briefing: Our brothers within GDI tell us of A-10 strike jets scheduled to be deployed here soon. Our suppliers have delivered new Surface to Air Missiles to aid you. Use the SAMs to defend your base, then seek out their base and destroy it.
BackgroundVideo: sethpre.vqa
BriefingVideo: nod5.vqa
StartVideo: samsite.vqa
WinVideo: insites.vqa
LossVideo: flag.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Steal The Detonator (a)
Description: GDI has imported a Nuclear Detonator in an attempt to sway a few local political leaders. Penetrate the base and steal the detonator. A chopper will be sent to meet you at a designated landing zone. Look for the landing flare once you have stolen the device.
Author: Westwood Studios
Tileset: DESERT
@@ -18,22 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: nod6.vqa
GameStart: sundial.vqa
GameLost: banner.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 0
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@Neutral:
Name: Neutral
@@ -684,6 +666,14 @@ Rules:
MissionObjectives:
EarlyGameOver: true
EnemyWatcher:
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 0
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -695,6 +685,20 @@ Rules:
MusicPlaylist:
StartingMusic: rout
VictoryMusic: nod_win1
MissionData:
Briefing: GDI has imported a Nuclear Detonator in an attempt to sway a few local political leaders. Penetrate the base and steal the detonator. A chopper will be sent to meet you at a designated landing zone. Look for the landing flare once you have stolen the device.
BriefingVideo: nod6.vqa
StartVideo: sundial.vqa
LossVideo: banner.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Steal The Detonator (b)
Description: GDI has imported a Nuclear Detonator in an attempt to sway a few local political leaders. Penetrate the base and steal the detonator. A chopper will be sent to meet you at a designated landing zone. Look for the landing flare once you have stolen the device.
Author: Westwood Studios
Tileset: DESERT
@@ -18,22 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: nod6.vqa
GameStart: sundial.vqa
GameLost: banner.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 0
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@GDI:
Name: GDI
@@ -628,6 +610,14 @@ Rules:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 0
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -639,6 +629,20 @@ Rules:
MusicPlaylist:
StartingMusic: rout
VictoryMusic: nod_win1
MissionData:
Briefing: GDI has imported a Nuclear Detonator in an attempt to sway a few local political leaders. Penetrate the base and steal the detonator. A chopper will be sent to meet you at a designated landing zone. Look for the landing flare once you have stolen the device.
BriefingVideo: nod6.vqa
StartVideo: sundial.vqa
LossVideo: banner.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
^Vehicle:
Tooltip:
GenericVisibility: Enemy

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: Steal The Detonator (c)
Description: GDI has imported a Nuclear Detonator in an attempt to sway a few local political leaders. Penetrate the base and steal the detonator. A chopper will be sent to meet you at a designated landing zone. Look for the landing flare once you have stolen the device.
Author: Westwood Studios
Tileset: DESERT
@@ -18,22 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: nod6.vqa
GameStart: sundial.vqa
GameLost: banner.vqa
Options:
Crates: False
Creeps: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 4000
ConfigurableStartingUnits: False
ShortGame: False
Players:
PlayerReference@GDI:
Name: GDI
@@ -512,6 +494,14 @@ Rules:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 4000
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -523,6 +513,20 @@ Rules:
MusicPlaylist:
StartingMusic: rout
VictoryMusic: nod_win1
MissionData:
Briefing: GDI has imported a Nuclear Detonator in an attempt to sway a few local political leaders. Penetrate the base and steal the detonator. A chopper will be sent to meet you at a designated landing zone. Look for the landing flare once you have stolen the device.
BriefingVideo: nod6.vqa
StartVideo: sundial.vqa
LossVideo: banner.vqa
MapCreeps:
Locked: True
Enabled: False
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
ShortGameLocked: True
ShortGameEnabled: False
^Vehicle:
Tooltip:
GenericVisibility: Enemy

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: shellmap
Description: CNC Shellmap
Author: Chris Forbes
Tileset: WINTER
@@ -18,10 +16,6 @@ Visibility: Shellmap
Type: Shellmap
Videos:
Options:
Players:
PlayerReference@Nod:
Name: Nod

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: cnc
Title: The Hot Box
Description: Drop Zone for CnC
Author: Dan9550
Tileset: DESERT
@@ -18,18 +16,6 @@ Visibility: Lobby
Type: Drop Zone
Videos:
Options:
Crates: True
Fog: False
Shroud: False
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 5000
TechLevel: Unrestricted
ConfigurableStartingUnits: False
Players:
PlayerReference@Neutral:
Name: Neutral
@@ -218,6 +204,12 @@ Rules:
InitialSpawnDelay: 0
-SpawnMPUnits:
-MPStartLocations:
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
TechLevelLocked: True
TechLevel: Unrestricted
UNITCRATE:
Inherits: ^Crate
GiveUnitCrateAction@stnk:
@@ -241,6 +233,15 @@ Rules:
MustBeDestroyed:
RequiredForShortGame: true
-AttackMove:
Player:
Shroud:
FogLocked: True
FogEnabled: False
ExploredMapLocked: True
ExploredMapEnabled: True
PlayerResources:
DefaultCashLocked: True
DefaultCash: 5000
Sequences:

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -162,15 +162,6 @@ ServerTraits:
MasterServerPinger
LobbySettingsNotification
LobbyDefaults:
AllowCheats: false
Crates: true
StartingUnitsClass: light
FragileAlliances: false
Shroud: true
Fog: true
TechLevel: Unrestricted
ChromeMetrics:
common|metrics.yaml
cnc|metrics.yaml

View File

@@ -72,7 +72,10 @@ World:
ResourceClaimLayer:
PathfinderDebugOverlay:
WarheadDebugOverlay:
MapCreeps:
SpawnMapActors:
MapBuildRadius:
MapOptions:
MPStartLocations:
CreateMPPlayers:
MPStartUnits@mcvonly:
@@ -135,6 +138,7 @@ World:
BaseActor: mcv
SupportActors: e1,e1,e1,e1,e1,e2,e2,e2,e3,e3,apc,mtnk
SpawnMPUnits:
StartingUnitsClass: light
CrateSpawner:
Minimum: 1
Maximum: 6

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: d2k
Title: Atreides 01a
Description: Harvest Spice from the Imperial Basin. Construct a Spice Refinery and defend it against the Harkonnen troops scattered throughout the basin. You have been assigned only limited offensive forces - use them wisely.\n\nYou will have to learn the subtleties of mining as you go, but remember to build Silos to store the Spice. When you run out of storage space you can not gather more Spice. Also, any building without adequate concrete foundation will need immediate repair and be vulnerable to erosive damage from the harsh environment. Your greatest adversary may be the elements.\n\nGood luck.\n
Author: Westwood Studios
Tileset: ARRAKIS
@@ -18,22 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: A_BR01_E.VQA
Options:
Crates: False
Creeps: True
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 2300
TechLevel: Low
ConfigurableStartingUnits: False
Difficulties: Easy, Normal, Hard
ShortGame: False
Players:
PlayerReference@Neutral:
Name: Neutral
@@ -134,6 +116,14 @@ Rules:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 2300
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -145,6 +135,21 @@ Rules:
WormManager:
Minimum: 1
Maximum: 1
MissionData:
Briefing: Harvest Spice from the Imperial Basin. Construct a Spice Refinery and defend it against the Harkonnen troops scattered throughout the basin. You have been assigned only limited offensive forces - use them wisely.\n\nYou will have to learn the subtleties of mining as you go, but remember to build Silos to store the Spice. When you run out of storage space you can not gather more Spice. Also, any building without adequate concrete foundation will need immediate repair and be vulnerable to erosive damage from the harsh environment. Your greatest adversary may be the elements.\n\nGood luck.\n
BriefingVideo: A_BR01_E.VQA
MapCreeps:
Locked: True
Enabled: True
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
TechLevelLocked: True
TechLevel: Low
Difficulties: Easy, Normal, Hard
ShortGameLocked: True
ShortGameEnabled: False
construction_yard:
Production:
Produces: Building

View File

@@ -1,11 +1,9 @@
MapFormat: 8
MapFormat: 9
RequiresMod: d2k
Title: Atreides 01b
Description: Harvest Spice from the Imperial Basin. Construct a Spice Refinery and defend it against the Harkonnen troops scattered throughout the basin. You have been assigned only limited offensive forces - use them wisely.\n\nYou will have to learn the subtleties of mining as you go, but remember to build Silos to store the Spice. When you run out of storage space you can not gather more Spice. Also, any building without adequate concrete foundation will need immediate repair and be vulnerable to erosive damage from the harsh environment. Your greatest adversary may be the elements.\n\nGood luck.\n
Author: Westwood Studios
Tileset: ARRAKIS
@@ -18,22 +16,6 @@ Visibility: MissionSelector
Type: Campaign
Videos:
Briefing: A_BR01_E.VQA
Options:
Crates: False
Creeps: True
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 2300
TechLevel: Low
ConfigurableStartingUnits: False
Difficulties: Easy, Normal, Hard
ShortGame: False
Players:
PlayerReference@Neutral:
Name: Neutral
@@ -133,6 +115,14 @@ Rules:
-ConquestVictoryConditions:
MissionObjectives:
EarlyGameOver: true
Shroud:
FogLocked: True
FogEnabled: True
ExploredMapLocked: True
ExploredMapEnabled: False
PlayerResources:
DefaultCashLocked: True
DefaultCash: 2300
World:
-CrateSpawner:
-SpawnMPUnits:
@@ -144,6 +134,21 @@ Rules:
WormManager:
Minimum: 1
Maximum: 1
MissionData:
Briefing: Harvest Spice from the Imperial Basin. Construct a Spice Refinery and defend it against the Harkonnen troops scattered throughout the basin. You have been assigned only limited offensive forces - use them wisely.\n\nYou will have to learn the subtleties of mining as you go, but remember to build Silos to store the Spice. When you run out of storage space you can not gather more Spice. Also, any building without adequate concrete foundation will need immediate repair and be vulnerable to erosive damage from the harsh environment. Your greatest adversary may be the elements.\n\nGood luck.\n
BriefingVideo: A_BR01_E.VQA
MapCreeps:
Locked: True
Enabled: True
MapBuildRadius:
AllyBuildRadiusLocked: True
AllyBuildRadiusEnabled: False
MapOptions:
TechLevelLocked: True
TechLevel: Low
Difficulties: Easy, Normal, Hard
ShortGameLocked: True
ShortGameEnabled: False
construction_yard:
Production:
Produces: Building

Some files were not shown because too many files have changed in this diff Show More