diff --git a/Makefile b/Makefile index 08505885fd..d407aa0682 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ CSC = dmcs CSFLAGS = -nologo -warn:4 -debug:full -optimize- -codepage:utf8 -unsafe -warnaserror DEFINE = DEBUG;TRACE -COMMON_LIBS = System.dll System.Core.dll System.Drawing.dll System.Xml.dll thirdparty/ICSharpCode.SharpZipLib.dll thirdparty/FuzzyLogicLibrary.dll thirdparty/Mono.Nat.dll thirdparty/MaxMind.Db.dll thirdparty/MaxMind.GeoIP2.dll thirdparty/Eluant.dll +COMMON_LIBS = System.dll System.Core.dll System.Data.dll System.Data.DataSetExtensions.dll System.Drawing.dll System.Xml.dll thirdparty/ICSharpCode.SharpZipLib.dll thirdparty/FuzzyLogicLibrary.dll thirdparty/Mono.Nat.dll thirdparty/MaxMind.Db.dll thirdparty/MaxMind.GeoIP2.dll thirdparty/Eluant.dll diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 2fb5a9408d..080772d489 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -534,6 +534,9 @@ + + + diff --git a/OpenRA.Mods.RA/UtilityCommands/ActorStatsExport.cs b/OpenRA.Mods.RA/UtilityCommands/ActorStatsExport.cs new file mode 100644 index 0000000000..5c405328ba --- /dev/null +++ b/OpenRA.Mods.RA/UtilityCommands/ActorStatsExport.cs @@ -0,0 +1,99 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 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.Data; +using System.Linq; +using OpenRA.GameRules; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA.UtilityCommands +{ + public static class ActorStatsExport + { + public static DataTable GenerateTable() + { + var rules = Game.modData.RulesetCache.LoadDefaultRules(); + + var table = new DataTable(); + table.Columns.Add("Name", typeof(string)); + table.Columns.Add("Cost", typeof(int)); + table.Columns.Add("HitPoints", typeof(int)); + table.Columns.Add("Armor", typeof(string)); + table.Columns.Add("Damage /s", typeof(float)); + + var armorList = new List(); + foreach (var actorInfo in rules.Actors.Values) + { + var armor = actorInfo.Traits.GetOrDefault(); + if (armor != null) + if (!armorList.Contains(armor.Type)) + armorList.Add(armor.Type); + } + + armorList.Sort(); + foreach (var armorType in armorList) + table.Columns.Add("vs. " + armorType, typeof(float)); + + foreach (var actorInfo in rules.Actors.Values) + { + if (actorInfo.Name.StartsWith("^")) + continue; + + var buildable = actorInfo.Traits.GetOrDefault(); + if (buildable == null) + continue; + + var row = table.NewRow(); + var tooltip = actorInfo.Traits.GetOrDefault(); + row["Name"] = tooltip != null ? tooltip.Name : actorInfo.Name; + + var value = actorInfo.Traits.GetOrDefault(); + row["Cost"] = value != null ? value.Cost : 0; + + var health = actorInfo.Traits.GetOrDefault(); + row["HitPoints"] = health != null ? health.HP : 0; + + var armor = actorInfo.Traits.GetOrDefault(); + row["Armor"] = armor != null ? armor.Type : ""; + + var armaments = actorInfo.Traits.WithInterface(); + if (armaments.Any()) + { + var weapons = armaments.Select(a => rules.Weapons[a.Weapon.ToLowerInvariant()]); + foreach (var weapon in weapons) + { + var warhead = weapon.Warheads.FirstOrDefault(w => (w is DamageWarhead)) as DamageWarhead; + if (warhead != null) + { + var rateOfFire = weapon.ReloadDelay > 1 ? weapon.ReloadDelay : 1; + var burst = weapon.Burst; + var delay = weapon.BurstDelay; + var damage = warhead.Damage; + var damagePerSecond = (1000f / Game.Timestep) * (damage * burst) / (delay + burst * rateOfFire); + row["Damage /s"] = Math.Round(damagePerSecond, 1, MidpointRounding.AwayFromZero); + + foreach (var armorType in armorList) + { + var vs = warhead.Versus.ContainsKey(armorType) ? warhead.Versus[armorType] : 100; + row["vs. " + armorType] = Math.Round(damagePerSecond * vs / 100, 1, MidpointRounding.AwayFromZero); + } + } + } + } + + table.Rows.Add(row); + } + + return table; + } + } +} \ No newline at end of file diff --git a/OpenRA.Mods.RA/UtilityCommands/ExportCharacterSeparatedRules.cs b/OpenRA.Mods.RA/UtilityCommands/ExportCharacterSeparatedRules.cs new file mode 100644 index 0000000000..23f12bf7b0 --- /dev/null +++ b/OpenRA.Mods.RA/UtilityCommands/ExportCharacterSeparatedRules.cs @@ -0,0 +1,32 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 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.IO; + +namespace OpenRA.Mods.RA.UtilityCommands +{ + class ExportCharacterSeparatedRules : IUtilityCommand + { + public string Name { get { return "--generate-dps-table"; } } + + [Desc("Export the damage per second evaluation into a CSV file for inspection.")] + public void Run(ModData modData, string[] args) + { + Game.modData = modData; + var table = ActorStatsExport.GenerateTable(); + var filename = "{0}-mod-dps.csv".F(Game.modData.Manifest.Mod.Id); + using (var outfile = new StreamWriter(filename)) + outfile.Write(table.ToCharacterSeparatedValues(";", true)); + Console.WriteLine("{0} has been saved.".F(filename)); + Console.WriteLine("Open as values separated by semicolon."); + } + } +} diff --git a/OpenRA.Mods.RA/UtilityCommands/Extensions.cs b/OpenRA.Mods.RA/UtilityCommands/Extensions.cs new file mode 100644 index 0000000000..0d89099819 --- /dev/null +++ b/OpenRA.Mods.RA/UtilityCommands/Extensions.cs @@ -0,0 +1,54 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 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.Data; +using System.Text; + +namespace OpenRA.Mods.RA.UtilityCommands +{ + public static class Extensions + { + public static string ToCharacterSeparatedValues(this DataTable table, string delimiter, bool includeHeader) + { + var result = new StringBuilder(); + + if (includeHeader) + { + foreach (DataColumn column in table.Columns) + { + result.Append(column.ColumnName); + result.Append(delimiter); + } + + result.Remove(result.Length, 0); + result.AppendLine(); + } + + foreach (DataRow row in table.Rows) + { + for (var x = 0; x < table.Columns.Count; x++) + { + if (x != 0) + result.Append(delimiter); + + result.Append(row[table.Columns[x]]); + } + + result.AppendLine(); + } + + result.Remove(result.Length, 0); + result.AppendLine(); + + return result.ToString(); + } + } +} \ No newline at end of file