Пример #1
0
        /// <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);
        }
Пример #2
0
        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");
        }