Skip to content

Commit d01d49e

Browse files
authored
Merge pull request #23 from thefifthmatt/master
DarkScript3.4.2
2 parents 2bca268 + ee52a7d commit d01d49e

21 files changed

Lines changed: 2266 additions & 629 deletions

DarkScript3/CondTestingTool.cs

Lines changed: 178 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
5+
using System.Net;
56
using System.Text;
67
using System.Threading.Tasks;
78
using Newtonsoft.Json;
@@ -34,7 +35,11 @@ public void Run(string[] args)
3435
{
3536
// This file ended up being more than just cond testing, but hack pile of one-time
3637
// scripts still basically applies to these as well.
37-
if (args.Contains("gen"))
38+
if (args.Contains("ac6"))
39+
{
40+
DumpAc6Unknown();
41+
}
42+
else if (args.Contains("gen"))
3843
{
3944
DumpEldenNew(args);
4045
}
@@ -48,20 +53,21 @@ public void Run(string[] args)
4853
}
4954
}
5055

56+
private static readonly Dictionary<string, int> Types = new Dictionary<string, int>()
57+
{
58+
["byte"] = 0,
59+
["ushort"] = 1,
60+
["uint"] = 2,
61+
["sbyte"] = 3,
62+
["short"] = 4,
63+
["int"] = 5,
64+
["float"] = 6,
65+
};
66+
private static readonly Dictionary<int, string> RevTypes = Types.ToDictionary(e => e.Value, e => e.Key);
67+
5168
public void DumpTypes()
5269
{
5370
InstructionDocs docs = new InstructionDocs("er-common.emedf.json");
54-
Dictionary<string, int> types = new Dictionary<string, int>()
55-
{
56-
["byte"] = 0,
57-
["ushort"] = 1,
58-
["uint"] = 2,
59-
["sbyte"] = 3,
60-
["short"] = 4,
61-
["int"] = 5,
62-
["float"] = 6,
63-
};
64-
Dictionary<int, string> revTypes = types.ToDictionary(e => e.Value, e => e.Key);
6571
SortedDictionary<(string, string), List<string>> cmdsByType = new SortedDictionary<(string, string), List<string>>();
6672
foreach (EMEDF.ClassDoc bank in docs.DOC.Classes.OrderBy(i => i.Index))
6773
{
@@ -71,7 +77,7 @@ public void DumpTypes()
7177
string name = instr.DisplayName;
7278
foreach (EMEDF.ArgDoc arg in instr.Arguments)
7379
{
74-
string type = revTypes[(int)arg.Type];
80+
string type = RevTypes[(int)arg.Type];
7581
if (arg.EnumName == null && type != "float")
7682
{
7783
var key = (arg.Name, type);
@@ -120,24 +126,11 @@ public void DumpEldenUnknown()
120126
}
121127
}
122128

123-
public void DumpEldenNew(ICollection<string> opt)
129+
private EMEDF.ArgDoc ParseArgType(string text)
124130
{
125-
doc = EMEDF.ReadFile($"DarkScript3/Resources/er-common.emedf.json");
126-
Dictionary<string, int> types = new Dictionary<string, int>()
127-
{
128-
["byte"] = 0,
129-
["ushort"] = 1,
130-
["uint"] = 2,
131-
["sbyte"] = 3,
132-
["short"] = 4,
133-
["int"] = 5,
134-
["float"] = 6,
135-
// ["uint"] = 8,
136-
};
137-
Dictionary<int, string> revTypes = types.ToDictionary(e => e.Value, e => e.Key);
138131
string getType(string prefix)
139132
{
140-
foreach (KeyValuePair<string, int> type in types)
133+
foreach (KeyValuePair<string, int> type in Types)
141134
{
142135
if (prefix.StartsWith(type.Key + " ")) return type.Key;
143136
}
@@ -151,11 +144,41 @@ EMEDF.EnumDoc getEnum(string prefix)
151144
}
152145
return null;
153146
}
147+
string desc = text.Split('=')[0].Trim();
148+
EMEDF.EnumDoc enumDoc = null;
149+
string type = getType(desc);
150+
if (type == null)
151+
{
152+
enumDoc = getEnum(desc);
153+
if (enumDoc == null) throw new Exception($"Can't parse {text}");
154+
desc = desc.Substring(enumDoc.Name.Length).Trim();
155+
type = getType(desc);
156+
if (type == null) throw new Exception($"Can't parse type in {text}");
157+
}
158+
desc = desc.Substring(type.Length).Trim();
159+
EMEDF.ArgDoc argDoc = new EMEDF.ArgDoc
160+
{
161+
Name = desc,
162+
Type = Types[type],
163+
EnumName = enumDoc?.Name,
164+
Default = desc == "Number of Target Characters" ? 1 : 0,
165+
Min = 0,
166+
Max = 0,
167+
Increment = 0,
168+
FormatString = type == "float" ? "%0.3f" : "%d",
169+
};
170+
if (argDoc.Name == "Parameters") argDoc.Vararg = true;
171+
return argDoc;
172+
}
173+
174+
public void DumpEldenNew(ICollection<string> opt)
175+
{
176+
doc = EMEDF.ReadFile($"DarkScript3/Resources/er-common.emedf.json");
154177
string getArgKey(EMEDF.ArgDoc argDoc)
155178
{
156179
List<string> parts = new List<string>();
157180
if (argDoc.EnumName != null) parts.Add(argDoc.EnumName);
158-
if (!revTypes.TryGetValue((int)argDoc.Type, out string typeName)) throw new Exception($"Unknown type in {argDoc.Name}: {argDoc.Type}");
181+
if (!RevTypes.TryGetValue((int)argDoc.Type, out string typeName)) throw new Exception($"Unknown type in {argDoc.Name}: {argDoc.Type}");
159182
parts.Add(typeName);
160183
parts.Add(argDoc.Name);
161184
return string.Join(" ", parts);
@@ -213,40 +236,16 @@ string getMinorDetailDesc(EMEDF.ArgDoc argDoc)
213236
}
214237
EMEDF.ArgDoc getArg(string text, string debugInfo = "")
215238
{
216-
string desc = text.Split('=')[0].Trim();
217-
EMEDF.EnumDoc enumDoc = null;
218-
string type = getType(desc);
219-
if (type == null)
220-
{
221-
enumDoc = getEnum(desc);
222-
if (enumDoc == null) throw new Exception($"Can't parse {text}");
223-
desc = desc.Substring(enumDoc.Name.Length).Trim();
224-
type = getType(desc);
225-
if (type == null) throw new Exception($"Can't parse type in {text}");
226-
}
227-
desc = desc.Substring(type.Length).Trim();
228-
EMEDF.ArgDoc argDoc = new EMEDF.ArgDoc
229-
{
230-
Name = desc,
231-
Type = types[type],
232-
EnumName = enumDoc?.Name,
233-
// TODO: Definitely make this non-zero when required
234-
Default = desc == "Number of Target Characters" ? 1 : 0,
235-
// TODO: Fill these in
236-
Min = 0,
237-
Max = 0,
238-
Increment = 0,
239-
FormatString = type == "float" ? "%0.3f" : "%d",
240-
};
239+
EMEDF.ArgDoc argDoc = ParseArgType(text);
241240
// It seems enums don't get default values etc.
242241
if (argDoc.EnumName == null)
243242
{
244243
string argKey = getArgKey(argDoc);
245244
EMEDF.ArgDoc old = null;
246-
if (!desc.StartsWith("Unknown"))
245+
if (!argDoc.Name.StartsWith("Unknown"))
247246
{
248247
exampleDocs.TryGetValue(argKey, out old);
249-
if (old == null && type == "uint" && desc.EndsWith("Entity ID"))
248+
if (old == null && RevTypes[(int)argDoc.Type] == "uint" && argDoc.Name.EndsWith("Entity ID"))
250249
{
251250
exampleDocs.TryGetValue("uint Target Entity ID", out old);
252251
}
@@ -352,6 +351,129 @@ public void RunEldenTests(IList<string> args)
352351
}
353352
}
354353

354+
public void DumpAc6Unknown()
355+
{
356+
InstructionDocs docs = new InstructionDocs("er-common.emedf.json");
357+
doc = docs.DOC;
358+
SortedSet<(int, int)> used = new();
359+
Dictionary<(int, int), int> bad = new();
360+
Dictionary<(int, int), SortedSet<int>> badBytes = new();
361+
string dir = @"C:\Program Files (x86)\Steam\steamapps\common\ARMORED CORE VI FIRES OF RUBICON\Game\event";
362+
foreach (string path in Directory.GetFiles(dir, "*.emevd.dcx"))
363+
{
364+
string fileName = Path.GetFileName(path);
365+
emevd = EMEVD.Read(path);
366+
foreach (EMEVD.Event e in emevd.Events)
367+
{
368+
Dictionary<EMEVD.Parameter, string> pn = e.Parameters.ToDictionary(p => p, p => $"X{p.SourceStartByte}_{p.ByteCount}");
369+
for (int i = 0; i < e.Instructions.Count; i++)
370+
{
371+
EMEVD.Instruction ins = e.Instructions[i];
372+
var insId = (ins.Bank, ins.ID);
373+
used.Add(insId);
374+
try
375+
{
376+
EMEDF.InstrDoc instrDoc = doc[ins.Bank][ins.ID];
377+
List<object> args = docs.UnpackArgsWithParams(
378+
ins, i, instrDoc, pn, (argDoc, val) => argDoc.GetDisplayValue(val));
379+
}
380+
catch (Exception ex)
381+
{
382+
int len = ins.ArgData.Length / 4;
383+
bad[insId] = len;
384+
if (!badBytes.ContainsKey(insId)) badBytes[insId] = new();
385+
for (int k = 0; k < ins.ArgData.Length; k++)
386+
{
387+
if (ins.ArgData[k] != 0)
388+
{
389+
badBytes[insId].Add(k);
390+
}
391+
}
392+
}
393+
}
394+
}
395+
}
396+
foreach (var insId in used)
397+
{
398+
(int bank, int id) = insId;
399+
string insStr = InstructionDocs.FormatInstructionID(bank, id);
400+
string name = $"XUnknown {insStr}";
401+
List<string> args;
402+
if (bad.TryGetValue(insId, out int len))
403+
{
404+
bool init = bank == 2000 && (id == 7 || id == 8);
405+
if (init) len = 3;
406+
ISet<int> bytes = badBytes[insId];
407+
string byteChar(int i) => bytes.Contains(i) ? "X" : "0";
408+
string bytesChar(int i) => $"{byteChar(i)}{byteChar(i + 1)}{byteChar(i + 2)}{byteChar(i + 3)}";
409+
args = Enumerable.Range(0, len).Select(i => $"uint Unknown{i * 4}_{bytesChar(i * 4)}").ToList();
410+
if (bank < 100)
411+
{
412+
args.RemoveAt(0);
413+
int maxByte = bytes.Where(x => x < 4).OrderByDescending(x => x).FirstOrDefault();
414+
for (int i = maxByte; i >= 0; i--)
415+
{
416+
string s = i == 0 ? "Condition Group sbyte Result Condition Group" : $"sbyte Unknown{i}_{byteChar(i)}";
417+
args.Insert(0, s);
418+
}
419+
}
420+
else if (init) args[2] = "uint Parameters";
421+
}
422+
else
423+
{
424+
EMEDF.InstrDoc instrDoc = doc[bank][id];
425+
name = instrDoc.Name;
426+
args = instrDoc.Arguments.Select(a => (a.EnumName == null ? "" : $"{a.EnumName} ") + $"{RevTypes[(int)a.Type]} {a.Name}").ToList();
427+
}
428+
Console.WriteLine($"{insStr}, {name}{string.Join("", args.Select(s => $", {s}"))}");
429+
}
430+
}
431+
432+
public void AddUnknownValues(EMEDF emedf, string csv)
433+
{
434+
doc = emedf;
435+
foreach (string line in File.ReadAllLines(csv))
436+
{
437+
string[] cells = line.Split(",").Select(s => s.Trim()).ToArray();
438+
string cmd = cells[0];
439+
int bank, id;
440+
try
441+
{
442+
(bank, id) = InstructionDocs.ParseInstructionID(cmd);
443+
}
444+
catch (FormatException)
445+
{
446+
continue;
447+
}
448+
string name = cells[1].Trim(new[] { '?', ' ' });
449+
List<EMEDF.ArgDoc> args = cells.Skip(2)
450+
.Where(c => !string.IsNullOrWhiteSpace(c))
451+
.Select(c => ParseArgType(c))
452+
.ToList();
453+
EMEDF.ClassDoc classDoc = doc[bank];
454+
if (classDoc == null)
455+
{
456+
doc.Classes.Add(new EMEDF.ClassDoc { Name = "Unk", Index = bank, Instructions = new() });
457+
}
458+
EMEDF.InstrDoc instrDoc = doc[bank][id];
459+
if (instrDoc == null)
460+
{
461+
instrDoc = new EMEDF.InstrDoc
462+
{
463+
Name = name,
464+
Index = id,
465+
Arguments = args.ToArray(),
466+
};
467+
doc[bank].Instructions.Add(instrDoc);
468+
}
469+
}
470+
doc.Classes = doc.Classes.OrderBy(x => x.Index).ToList();
471+
foreach (EMEDF.ClassDoc classDoc in doc.Classes)
472+
{
473+
classDoc.Instructions = classDoc.Instructions.OrderBy(x => x.Index).ToList();
474+
}
475+
}
476+
355477
public void ValidateEmedf(ICollection<string> opt)
356478
{
357479
InstructionDocs docs = new InstructionDocs("er-common.emedf.json");

DarkScript3/EMEDF.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ public static EMEDF ReadStream(string resource)
4242
return ReadText(input);
4343
}
4444

45+
public void WriteFile(string path)
46+
{
47+
string output = JsonConvert.SerializeObject(this, Formatting.Indented).Replace("\r\n", "\n");
48+
File.WriteAllText(path, output);
49+
}
50+
4551
public class ClassDoc
4652
{
4753
[JsonProperty(PropertyName = "name", Order = 1)]

DarkScript3/EMEDF2HTML.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public static void Generate(string[] args)
6262
};
6363
private readonly Dictionary<string, Regex> elidedEmevd = new Dictionary<string, Regex>()
6464
{
65-
["er"] = new Regex(@"^(m60|m3[0-2])"),
65+
["er"] = new Regex(@"^(m60|m61|m3[0-2]|m4[0-3])"),
6666
};
6767
private readonly Dictionary<string, string> specialCommands = new Dictionary<string, string>
6868
{

DarkScript3/EditorGUI.cs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -340,22 +340,8 @@ public bool CancelWithUnsavedChanges()
340340
public void SaveJSFile()
341341
{
342342
var sb = new StringBuilder();
343-
sb.AppendLine("// ==EMEVD==");
344-
sb.AppendLine($"// @docs {Docs.ResourceString}");
345-
sb.AppendLine($"// @compress {Scripter.EVD.Compression}");
346-
sb.AppendLine($"// @game {Scripter.EVD.Format}");
347-
if (Docs.IsASCIIStringData)
348-
sb.AppendLine($"// @string {Encoding.ASCII.GetString(Scripter.EVD.StringData)}");
349-
else
350-
sb.AppendLine($"// @string {Encoding.Unicode.GetString(Scripter.EVD.StringData)}");
351-
sb.AppendLine($"// @linked [{string.Join(",", Scripter.EVD.LinkedFileOffsets)}]");
352-
foreach (KeyValuePair<string, string> extra in Settings.SettingsDict)
353-
{
354-
sb.AppendLine($"// @{extra.Key} {extra.Value}");
355-
}
356-
sb.AppendLine($"// @version {ProgramVersion.VERSION}");
357-
sb.AppendLine("// ==/EMEVD==");
358-
sb.AppendLine("");
343+
HeaderData header = HeaderData.Create(Scripter, Docs, Settings.SettingsDict);
344+
header.Write(sb, Docs);
359345
sb.AppendLine(editor.Text);
360346
File.WriteAllText($"{Scripter.EMEVDPath}.js", sb.ToString());
361347
FileVersion = ProgramVersion.VERSION;
@@ -500,7 +486,7 @@ private void Editor_ToolTipNeeded(object sender, ToolTipNeededEventArgs e)
500486
// TODO: Can this be simplified to be more consistent?
501487
return;
502488
}
503-
(string title, string text) = ToolTips[e.HoveredWord];
489+
(string title, string text) = ToolTips[hoveredWord];
504490
string s = title + "\n" + text;
505491
ShowTip(s, p);
506492
HoverTipRange = tipRange;

0 commit comments

Comments
 (0)