Introduce a mod/map upgrade tool.

This commit is contained in:
Paul Chote
2013-12-26 18:41:21 +13:00
parent 0b8dafcdf0
commit bd334a6295
5 changed files with 218 additions and 3 deletions

View File

@@ -146,7 +146,7 @@ namespace OpenRA
return map;
}
Dictionary<string, Map> FindMaps()
public Dictionary<string, Map> FindMaps()
{
var paths = Manifest.MapFolders.SelectMany(f => FindMapsIn(f));
var ret = new Dictionary<string, Map>();

View File

@@ -324,7 +324,7 @@ namespace OpenRA.Utility
}
[Desc("MAPFILE", "MOD", "Upgrade a version 5 map to version 6.")]
public static void UpgradeMap(string[] args)
public static void UpgradeV5Map(string[] args)
{
var map = args[1];
var mod = args[2];

View File

@@ -76,6 +76,7 @@
<ItemGroup>
<Compile Include="Command.cs" />
<Compile Include="Program.cs" />
<Compile Include="UpgradeRules.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">

View File

@@ -29,7 +29,9 @@ namespace OpenRA.Utility
{ "--docs", Command.ExtractTraitDocs },
{ "--map-hash", Command.GetMapHash },
{ "--map-preview", Command.GenerateMinimap },
{ "--map-upgrade", Command.UpgradeMap },
{ "--map-upgrade-v5", Command.UpgradeV5Map },
{ "--upgrade-map", UpgradeRules.UpgradeMap },
{ "--upgrade-mod", UpgradeRules.UpgradeMod },
};
static void Main(string[] args)

View File

@@ -0,0 +1,212 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using OpenRA.FileFormats;
using OpenRA.FileFormats.Graphics;
using OpenRA.GameRules;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Utility
{
public static class UpgradeRules
{
static void ConvertFloatToRange(ref string input)
{
var value = float.Parse(input);
var cells = (int)value;
var subcells = (int)(1024 * value) - 1024 * cells;
input = "{0}c{1}".F(cells, subcells);
}
static void ConvertPxToRange(ref string input)
{
ConvertPxToRange(ref input, 1, 1);
}
static void ConvertPxToRange(ref string input, int scaleMult, int scaleDiv)
{
var value = int.Parse(input);
var world = value * 1024 * scaleMult / (scaleDiv * Game.CellSize);
var cells = world / 1024;
var subcells = world - 1024 * cells;
input = cells != 0 ? "{0}c{1}".F(cells, subcells) : subcells.ToString();
}
static void ConvertAngle(ref string input)
{
var value = float.Parse(input);
input = WAngle.ArcTan((int)(value * 4 * 1024), 1024).ToString();
}
static void ConvertInt2ToWVec(ref string input)
{
var offset = FieldLoader.GetValue<int2>("(value)", input);
var world = new WVec(offset.X * 1024 / Game.CellSize, offset.Y * 1024 / Game.CellSize, 0);
input = world.ToString();
}
static void UpgradeActorRules(int engineVersion, ref List<MiniYamlNode> nodes, MiniYamlNode parent, int depth)
{
var parentKey = parent != null ? parent.Key.Split('@').First() : null;
foreach (var node in nodes)
{
// Weapon definitions were converted to world coordinates
if (engineVersion < 20131226)
{
if (depth == 2 && parentKey == "Exit" && node.Key == "SpawnOffset")
ConvertInt2ToWVec(ref node.Value.Value);
if (depth == 2 && (parentKey == "Aircraft" || parentKey == "Helicopter" || parentKey == "Plane"))
{
if (node.Key == "CruiseAltitude")
ConvertPxToRange(ref node.Value.Value);
if (node.Key == "Speed")
ConvertPxToRange(ref node.Value.Value, 7, 32);
}
if (depth == 2 && parentKey == "Mobile" && node.Key == "Speed")
ConvertPxToRange(ref node.Value.Value, 1, 3);
if (depth == 2 && parentKey == "Health" && node.Key == "Radius")
ConvertPxToRange(ref node.Value.Value);
}
UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1);
}
}
static void UpgradeWeaponRules(int engineVersion, ref List<MiniYamlNode> nodes, MiniYamlNode parent, int depth)
{
var parentKey = parent != null ? parent.Key.Split('@').First() : null;
foreach (var node in nodes)
{
// Weapon definitions were converted to world coordinates
if (engineVersion < 20131226)
{
if (depth == 1)
{
switch (node.Key)
{
case "Range":
case "MinRange":
ConvertFloatToRange(ref node.Value.Value);
break;
default:
break;
}
}
if (depth == 2 && parentKey == "Projectile")
{
switch (node.Key)
{
case "Inaccuracy":
ConvertPxToRange(ref node.Value.Value);
break;
case "Angle":
ConvertAngle(ref node.Value.Value);
break;
case "Speed":
{
if (parent.Value.Value == "Missile")
ConvertPxToRange(ref node.Value.Value, 1, 5);
if (parent.Value.Value == "Bullet")
ConvertPxToRange(ref node.Value.Value, 2, 5);
break;
}
default:
break;
}
}
if (depth == 2 && parentKey == "Warhead")
{
switch (node.Key)
{
case "Spread":
ConvertPxToRange(ref node.Value.Value);
break;
default:
break;
}
}
}
UpgradeWeaponRules(engineVersion, ref node.Value.Nodes, node, depth + 1);
}
}
[Desc("MAP", "CURRENTENGINE", "Upgrade map rules to the latest engine version.")]
public static void UpgradeMap(string[] args)
{
var map = new Map(args[1]);
var engineDate = int.Parse(args[2]);
Game.modData = new ModData(map.RequiresMod);
UpgradeWeaponRules(engineDate, ref map.Weapons, null, 0);
UpgradeActorRules(engineDate, ref map.Rules, null, 0);
map.Save(args[1]);
}
[Desc("MOD", "CURRENTENGINE", "Upgrade mod rules to the latest engine version.")]
public static void UpgradeMod(string[] args)
{
var mod = args[1];
var engineDate = int.Parse(args[2]);
Game.modData = new ModData(mod);
Console.WriteLine("Processing Rules:");
foreach (var filename in Game.modData.Manifest.Rules)
{
Console.WriteLine("\t" + filename);
var yaml = MiniYaml.FromFile(filename);
UpgradeActorRules(engineDate, ref yaml, null, 0);
using (var file = new StreamWriter(filename))
file.WriteLine(yaml.WriteToString());
}
Console.WriteLine("Processing Weapons:");
foreach (var filename in Game.modData.Manifest.Weapons)
{
Console.WriteLine("\t" + filename);
var yaml = MiniYaml.FromFile(filename);
UpgradeWeaponRules(engineDate, ref yaml, null, 0);
using (var file = new StreamWriter(filename))
file.WriteLine(yaml.WriteToString());
}
Console.WriteLine("Processing Maps:");
foreach (var map in Game.modData.FindMaps().Values)
{
Console.WriteLine("\t" + map.Path);
UpgradeActorRules(engineDate, ref map.Rules, null, 0);
UpgradeWeaponRules(engineDate, ref map.Weapons, null, 0);
map.Save(map.Path);
}
}
}
}