Arcanum файлы : SEC (часть вторая)

Стены. Сегодня я нашел время продолжить работу над sec файлами. Рассмотрим OBJECT TYPE 0 (WALL).
Если бы стены могли сдерживать наш рост, все крестьяне были бы карликами, а короли — великанами.

Создадим пару зданий.





На данной картинке 48 обьектов (0х30). Считаются внутренние и внешние стены. 

Если предыдущий OBJECT TYPE SCENERY имел следующую структуру,

04BYTE HEADER
24BYTE PRO_GUID -> 4BYTE PRO_ID
24BYTE OBJ_GUID -> 4BYTE GLOBAL_CHANGE_FLAG
04BYTE PRO_TYPE
11BYTE SYS_FLAG
04BYTE LOCATION FLAG
04BYTE OFFSET_X (OPTIONAL)
04BYTE OFFSET_Y (OPTIONAL)
04BYTE DELTA_X
04BYTE DELTA_Y
04BYTE FLAGS
ХХ + PROPERTY (OPTIONAL)

= 83 BYTE OR 91 /w offset

То сейчас всё гораздо проще.


04BYTE HEADER
24BYTE PRO_GUID -> 4BYTE PRO_ID
24BYTE OBJ_GUID -> 4BYTE GLOBAL_CHANGE_FLAG
04BYTE PRO_TYPE
14BYTE SYS_FLAGS
01BYTE DIRECTION FLAG
04BYTE FLAGS 0
04BYTE OFFSET_X (OPTIONAL)
04BYTE OFFSET_Y (OPTIONAL)
04BYTE FLAGS 1

Рассмотрим внимательнее:


77 00 00 00 01 00 00 00 72 F3 5D 01 FD 03 00 00
02 00 00 00 6A F3 5D 01 E2 9D E9 FE 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 03 00 03 00 04 00 00 00  | 00 - WALL
00 00 00 00 00 00 00 88 C1 12 01 06 00 00 00 02
00 00 00 00 40 00 00

77 00 00 00 01 00 00 00 8A F3 5D 01 00 04 00 00  | 00 04 00 00
02 00 00 00 82 F3 5D 01 52 15 61 2F 00 00 00 00
00 00 00 00 D4 58 5D 8E A1 AF 5B 47 A4 9E 7A 1F
B9 D6 61 26 00 00 00 00 03 00 03 00 04 00 00 00  | 00 - WALL
00 00 00 00 00 00 00 88 01 10 01 02 00 00 00 02

00 00 00 00 40 00 00

Координаты тайлов стен выделены зеленым и ведут отсчет от LOC 0,0. 





Флаги
SYS_FLAG и FLAG_1 уже известны нам по OBJ TYPE 0x03.
FLAG_0 : из того, что мне удалось выяснить

77 00 00 00 01 00 00 00 72 F3 5D 01 FD 03 00 00
02 00 00 00 6A F3 5D 01 E2 9D E9 FE 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 03 00 03 00 04 00 00 00
00 00 00 00 00 00 11 3A C0 12 01 07 00 00 00 02

00 00 00 00 40 00 00


88 - VARIANT
11 / 00 - DIRECTION HOR / VER



До назначения оставшихся 3 байт я не догнал. К сожалению.

У меня интересовались что там вообще в ToEE. В общем вот

        public GameObject Read()
        {
            var version = reader.ReadInt32();
            if (version != 0x77) {
                throw new InvalidDataException("Unknown object file version: " + version);
            }

            var obj = new GameObject();

            obj.ProtoId = reader.ReadObjectGuid();

            if (obj.ProtoId.IsProto)
            {
                throw new InvalidDataException("Proto not supported at this point.");
            }

            obj.Id = reader.ReadObjectGuid();

            obj.Type = (ObjectType) reader.ReadUInt32();
           
            var propCollectionItems = reader.ReadInt16(); // Actually not really used anymore
            Console.WriteLine("count " + propCollectionItems);
            var bitmapLength = ObjectFieldBitmap.GetLengthForType(obj.Type);

            var bitmap = new uint[bitmapLength];
            for (var i = 0; i < bitmap.Length; ++i)
            {
                bitmap[i] = reader.ReadUInt32();
            }

            foreach (var field in ObjectTypeFields.Get(obj.Type))
            {
                var fieldDef = ObjectFieldDefs.Get(field);
                // Check if it's set in the bitmap
               
                if ((bitmap[fieldDef.BitmapIndex] & fieldDef.BitmapMask) != 0)
                {
                    var value = ReadFieldValue(fieldDef, reader);
                    if (value != null)
                    {
                        obj.Properties[field] = value;
                    }
                }
               
            }

            return obj;
        }


В чем же разница ? Возьмем рандомный OBJ TYPE SCENERY :

77 00 00 00 01 00 00 00 CA F5 5D 01 C9 0F 00 00
02 00 00 00 C2 F5 5D 01 C9 E7 16 C9 00 00 00 00
00 00 00 00 55 8A 15 8B 3B AE 4B 44 AE 63 65 4D
C6 05 B1 B1 03 00 00 00 04 00 0E 00 04 00 00 00
00 00 00 00 00 00 00 00 00 00 00 FB FF FF FF 30
48 40 00

После чтения obj.Type мы читаем propCollectionItems (0х04), (который зачем-то обозван как signed) а затем и bitmapLength согласно типу объекта.

      case ObjectType.Scenery:
           result = ObjectFieldDefs.Get(ObjectField.SceneryPadI64as1).BitmapIndex;
           break;


           => мы должны прочитать 5 * UInt32 ( выделено желтым ). А это означает что мы уже просрали свойство delta_x.

По уму бы поудалять лишние свойства из исходников ToEE, но для этого надо знать какие из них лишние, а какие - нет.





Комментарии