/// <summary> /// Creates a RawNPC from an NPC by copying everything except for the strings, which it looks up in the `stringSectionTable` and adds to the `stringRelocTable`. /// </summary> /// <param name="npc">The source NPC</param> /// <param name="stringSectionTable">The table where the string pointers are stored</param> /// <param name="stringRelocTable">The table it adds the string pointer references to, for relocation. Can be left as null</param> /// <returns>The output RawNPC</returns> public static RawNpc From(Npc npc, Dictionary <string, Pointer> stringSectionTable, SortedDictionary <long, Pointer> stringRelocTable = null, long baseOffset = 0) { object rawNPC = new RawNpc(); foreach (FieldInfo rawNpcField in typeof(RawNpc).GetFields()) { FieldInfo npcField = typeof(Npc).GetField(rawNpcField.Name); if (npcField == null) { throw new Exception($"Didn't find field `{rawNpcField.Name}` in type NPC"); } if (rawNpcField.FieldType == typeof(Pointer) && npcField.FieldType == typeof(string)) { string str = (string)npcField.GetValue(npc); Pointer stringPointer = str != null ? stringSectionTable[str] : Pointer.NULL; if (stringRelocTable != null) { stringRelocTable.Add(rawNpcField.GetFieldOffset() + baseOffset, stringPointer); } else { rawNpcField.SetValue(rawNPC, stringPointer); } } else if (npcField.FieldType.BaseType == typeof(Enum)) { rawNpcField.SetValue(rawNPC, npcField.GetValue(npc)); } else if (npcField.FieldType == typeof(bool)) { rawNpcField.SetValue(rawNPC, (bool)npcField.GetValue(npc) ? 1 : 0); } else if (npcField.FieldType == rawNpcField.FieldType) { rawNpcField.SetValue(rawNPC, npcField.GetValue(npc)); } else { throw new Exception($"Types `{npcField.FieldType}` and `{rawNpcField.FieldType}` didn't match on field `{npcField.Name}`"); } } return((RawNpc)rawNPC); }
public override string ToString() { Type type = GetType(); FieldInfo[] fields = type.GetFields(); PropertyInfo[] properties = type.GetProperties(); RawNpc rawNpc = this; Dictionary <string, object> values = new Dictionary <string, object>(); Array.ForEach(fields, (field) => values.Add(field.Name, field.GetValue(rawNpc))); Array.ForEach(properties, (property) => { if (property.CanRead) { values.Add(property.Name, property.GetValue(rawNpc, null)); } }); return($"RawNPC{{{string.Join(", ", values.Select((key) => $"{key.Key}: {key.Value}").Take(5))} + {Math.Max(values.Count - 5, 0)} more"); }