
Apakah Anda ingat banyak game Rusia? Kualitatif? Berkesan? Ya, benar. Jika Anda berusia di atas 35 atau Anda adalah penggemar industri game Rusia, maka Anda mungkin akrab dengan Cursed Lands.
Kisah itu dimulai dengan sangat biasa: musim panas, panas. Tidak ada yang istimewa untuk dilakukan, dan ketika dengan malas menelusuri isi hard drive laptop, tatapanku menangkap sebuah folder dengan ikon naga yang sudah dikenalnya yang telah menganggur selama beberapa tahun.
Penggemar game apa yang tidak tertarik untuk mengetahui apa yang ada di dalamnya?
Pendahuluan
Cursed Lands - atau, sebagaimana mereka dipanggil di luar CIS, Evil Islands: Curse of the Lost Soul , game siluman-RPG yang dirilis pada 2000. Game ini dikembangkan oleh Nival Interactive, yang pada waktu itu telah memantapkan dirinya sebagai rangkaian game Alloda (Rage of Mages di luar negeri). Sebagian besar lulusan Universitas Negeri Moskow bekerja di dalamnya - mereka cukup mampu mewujudkan salah satu game pertama dengan dunia yang sepenuhnya tiga dimensi.
Pada tahun 2010, Mail.Ru ( informasi ) mentransfer judul, tetapi permainan masih dijual di toko GOG atas nama Nival.
Relatif baru-baru ini, permainan berusia 18 tahun - ulang tahun dianggap 26 Oktober, tanggal rilis di CIS. Terlepas dari usia, server master resmi masih dalam pelayanan: secara berkala, seseorang memutuskan untuk merangkak melalui hutan Gipat dan memukul selusin atau dua kerangka dengan satu regu kawan.
Secara singkat tentang artikel tersebut
Awalnya, tujuan saya hanya menulis konverter satu arah "untuk saya sendiri" di Python 3, menggunakan perpustakaan standar eksklusif. Namun, dalam prosesnya, dokumentasi tentang format dimulai dengan lancar, upaya untuk membakukan output entah bagaimana. Untuk beberapa format, struktur dijelaskan menggunakan Struct Kaitai . Akibatnya, semuanya menghasilkan penulisan artikel ini dan wiki dalam format.
Saya segera mencatat: sebagian besar file game telah diteliti, editor fan telah ditulis untuk mereka. Namun, informasi ini sangat terfragmentasi, dan tidak ada deskripsi lengkap tentang format dalam domain publik, juga tidak ada set yang memadai untuk membuat modifikasi.
... dan cara membacanya
Skema (file .ksy) disediakan untuk semua format, yang dapat dikonversi dalam dua klik menjadi kode dalam beberapa bahasa paling populer.
Sayangnya, sudah pada tahap akhir penulisan artikel ini, saya menemukan bahwa Habr yang terhormat tidak dapat menyoroti YAML (dan JSON), dan semua skema menggunakannya. Ini seharusnya bukan masalah besar, tetapi jika tidak nyaman untuk membaca skema, saya dapat menyarankan Anda untuk menyalinnya ke editor pihak ketiga, misalnya, PLTN.
Sumber daya dan tempat tinggal mereka
Gim ini adalah aplikasi portabel yang berisi mesin dengan perpustakaan, peluncur dan, bahkan, sumber daya yang dikemas.
Ini menarik: pengaturan gim hampir seluruhnya disimpan dalam registri. Bug kamera dalam versi GOG disebabkan oleh fakta bahwa penginstal tidak mendaftarkan nilai default yang benar.
Sekilas tentang isi folder game, kami segera melihat beberapa ekstensi file baru: ASI dan REG.
Yang pertama adalah perpustakaan yang dinamis, yang tidak akan kami pertimbangkan (ini dilakukan oleh spesialis dalam rekayasa terbalik), tetapi yang kedua adalah format file hak milik pertama dari game.
REG
File jenis ini adalah serialisasi biner dari file INI teks yang terkenal.
Konten dibagi menjadi beberapa bagian yang menyimpan kunci dan nilainya. File REG mempertahankan hierarki ini, tetapi mempercepat membaca dan mem-parsing data - pada tahun 2000, ini tampaknya penting.
Secara umum, Anda dapat menggambarkan struktur diagram ini:

Deskripsi strukturmeta: id: reg title: Evil Islands, REG file (packed INI) application: Evil Islands file-extension: reg license: MIT endian: le doc: Packed INI file seq: - id: magic contents: [0xFB, 0x3E, 0xAB, 0x45] doc: Magic bytes - id: sections_count type: u2 doc: Number of sections - id: sections_offsets type: section_offset doc: Sections offset table repeat: expr repeat-expr: sections_count types: section_offset: doc: Section position in file seq: - id: order type: s2 doc: Section order number - id: offset type: u4 doc: Global offset of section in file instances: section: pos: offset type: section types: section: doc: Section representation seq: - id: keys_count type: u2 doc: Number of keys in section - id: name_len type: u2 doc: Section name lenght - id: name type: str encoding: cp1251 size: name_len doc: Section name - id: keys type: key doc: Section's keys repeat: expr repeat-expr: keys_count types: key: doc: Named key seq: - id: order type: s2 doc: Key order in section - id: offset type: u4 doc: Key offset in section instances: key_record: pos: _parent._parent.offset + offset type: key_data key_data: seq: - id: packed_type type: u1 doc: Key value info - id: name_len type: u2 doc: Key name lenght - id: name type: str encoding: cp1251 size: name_len doc: Key name - id: value type: value doc: Key value instances: is_array: value: packed_type > 127 doc: Is this key contain array value_type: value: packed_type & 0x7F doc: Key value type types: value: doc: Key value seq: - id: array_size type: u2 if: _parent.is_array doc: Value array size - id: data type: switch-on: _parent.value_type cases: 0: s4 1: f4 2: string repeat: expr repeat-expr: '_parent.is_array ? array_size : 1' doc: Key value data string: doc: Sized string seq: - id: len type: u2 doc: String lenght - id: value type: str encoding: cp1251 size: len doc: String
Ini menarik: pada tahun 2002, Nival berbagi beberapa alat dengan komunitas permainan ( snapshot situs ) - salah satunya adalah serializer INI di REG. Seperti yang Anda duga, deserializer segera muncul, meskipun bukan yang resmi.
Dengan folder mulai diurutkan, mari kita beralih ke subdirektori.
Tampilan pertama jatuh pada folder Kamera yang berisi file CAM.
Cam
Format yang sangat sederhana adalah hanya mengemas posisi kamera dari waktu ke waktu. Kamera dijelaskan oleh posisi dan rotasi. Dua bidang lainnya mungkin adalah waktu dan langkah dalam urutan gerakan.

Deskripsi struktur meta: id: cam title: Evil Islands, CAM file (cameras) application: Evil Islands file-extension: cam license: MIT endian: le doc: Camera representation seq: - id: cams type: camera repeat: eos types: vec3: doc: 3d vector seq: - id: x type: f4 doc: x axis - id: y type: f4 doc: y axis - id: z type: f4 doc: z axis quat: doc: quaternion seq: - id: w type: f4 doc: w component - id: x type: f4 doc: x component - id: y type: f4 doc: y component - id: z type: f4 doc: z component camera: doc: Camera parameters seq: - id: unkn0 type: u4 doc: unknown - id: unkn1 type: u4 doc: unknown - id: position type: vec3 doc: camera's position - id: rotation type: quat doc: camera's rotation
Di folder berikutnya - Res, (tidak terduga!) File RES yang arsip disimpan.
RES
Format ini terkadang disembunyikan di bawah ekstensi lain, tetapi aslinya masih persis RES.
Struktur data sangat khas untuk arsip dengan akses acak ke file: ada tabel untuk menyimpan informasi tentang file di dalamnya, daftar nama, dan isi file.
Struktur direktori terkandung langsung dalam nama-nama.
Perlu dicatat dua fakta yang sangat menarik:
- Arsip dioptimalkan untuk memuat informasi file ke daftar tertaut dengan hashing tertutup.
- Anda dapat menyimpan konten file satu kali, tetapi merujuknya dengan nama yang berbeda. Sejauh yang saya tahu, fakta ini digunakan dalam repack penggemar, di mana ukuran permainan sangat berkurang karena ini. Dalam distribusi asli, pengoptimalan arsip tidak digunakan.

Deskripsi struktur meta: id: res title: Evil Islands, RES file (resources archive) application: Evil Islands file-extension: res license: MIT endian: le doc: Resources archive seq: - id: magic contents: [0x3C, 0xE2, 0x9C, 0x01] doc: Magic bytes - id: files_count type: u4 doc: Number of files in archive - id: filetable_offset type: u4 doc: Filetable offset - id: nametable_size type: u4 doc: Size of filenames instances: nametable_offset: value: filetable_offset + 22 * files_count doc: Offset of filenames table filetable: pos: filetable_offset type: file_record repeat: expr repeat-expr: files_count doc: Files metadata table types: file_record: doc: File metadata seq: - id: next_index type: s4 doc: Next file index - id: file_size type: u4 doc: Size of file in bytes - id: file_offset type: u4 doc: File data offset - id: last_change type: u4 doc: Unix timestamp of last change time - id: name_len type: u2 doc: Lenght of filename - id: name_offset type: u4 doc: Filename offset in name array instances: name: io: _root._io pos: name_offset + _parent.nametable_offset type: str encoding: cp1251 size: name_len doc: File name data: io: _root._io pos: file_offset size: file_size doc: Content of file
Ini menarik: dalam versi Rusia dari gim ini, arsip Speech.res berisi dua subdirektori s dan t dengan konten yang benar-benar identik, itulah sebabnya ukuran arsip dua kali lebih besar - itulah sebabnya gim tidak muat pada satu CD.
Sekarang Anda dapat membuka zip semua arsip (dapat disarangkan):
- RES hanyalah sebuah arsip,
- MPR - lanskap level game,
- MQ - informasi tentang tugas multiplayer,
- ANM - satu set animasi,
- MOD - model 3d,
- BON - lokasi tulang model.
Jika file di dalam arsip tidak memiliki ekstensi, kami akan meletakkan ekstensi induk - untuk arsip BON dan ANM.
Anda juga dapat membagi semua file yang diterima menjadi empat grup:
- Tekstur
- Basis data
- Model
- Level file.
Mari kita mulai dengan yang sederhana - dengan tekstur.
MMP
Sebenarnya, teksturnya. Ini memiliki judul kecil yang menunjukkan parameter gambar, jumlah level MIP dan kompresi yang digunakan. Setelah header adalah level gambar MIP dalam urutan ukuran menurun.

Deskripsi struktur meta: id: mmp title: Evil Islands, MMP file (texture) application: Evil Islands file-extension: mmp license: MIT endian: le doc: MIP-mapping texture seq: - id: magic contents: [0x4D, 0x4D, 0x50, 0x00] doc: Magic bytes - id: width type: u4 doc: Texture width - id: height type: u4 doc: Texture height - id: mip_levels_count type: u4 doc: Number of MIP-mapping stored levels - id: fourcc type: u4 enum: pixel_formats doc: FourCC label of pixel format - id: bits_per_pixel type: u4 doc: Number of bits per pixel - id: alpha_format type: channel_format doc: Description of alpha bits - id: red_format type: channel_format doc: Description of red bits - id: green_format type: channel_format doc: Description of green bits - id: blue_format type: channel_format doc: Description of blue bits - id: unused size: 4 doc: Empty space - id: base_texture type: switch-on: fourcc cases: 'pixel_formats::argb4': block_custom 'pixel_formats::dxt1': block_dxt1 'pixel_formats::dxt3': block_dxt3 'pixel_formats::pnt3': block_pnt3 'pixel_formats::r5g6b5': block_custom 'pixel_formats::a1r5g5b5': block_custom 'pixel_formats::argb8': block_custom _: block_custom types: block_pnt3: seq: - id: raw size: _root.bits_per_pixel block_dxt1: seq: - id: raw size: _root.width * _root.height >> 1 block_dxt3: seq: - id: raw size: _root.width * _root.height block_custom: seq: - id: lines type: line_custom repeat: expr repeat-expr: _root.height types: line_custom: seq: - id: pixels type: pixel_custom repeat: expr repeat-expr: _root.width types: pixel_custom: seq: - id: raw type: switch-on: _root.bits_per_pixel cases: 8: u1 16: u2 32: u4 instances: alpha: value: '_root.alpha_format.count == 0 ? 255 : 255 * ((raw & _root.alpha_format.mask) >> _root.alpha_format.shift) / (_root.alpha_format.mask >> _root.alpha_format.shift)' red: value: '255 * ((raw & _root.red_format.mask) >> _root.red_format.shift) / (_root.red_format.mask >> _root.red_format.shift)' green: value: '255 * ((raw & _root.green_format.mask) >> _root.green_format.shift) / (_root.green_format.mask >> _root.green_format.shift)' blue: value: '255 * ((raw & _root.blue_format.mask) >> _root.blue_format.shift) / (_root.blue_format.mask >> _root.blue_format.shift)' channel_format: doc: Description of bits for color channel seq: - id: mask type: u4 doc: Binary mask for channel bits - id: shift type: u4 doc: Binary shift for channel bits - id: count type: u4 doc: Count of channel bits enums: pixel_formats: 0x00004444: argb4 0x31545844: dxt1 0x33545844: dxt3 0x33544E50: pnt3 0x00005650: r5g6b5 0x00005551: a1r5g5b5 0x00008888: argb8
Kemungkinan format kemasan piksel:
fourcc | Deskripsi |
---|
44 44 00 00 | ARGB4 |
44 58 54 31 | Dxt1 |
44 58 54 33 | Dxt3 |
50 4E 54 33 | PNT3 - RLE Compressed ARGB8 |
50 56 00 00 | R5G5B5 |
51 55 00 00 | A1R5G5B5 |
88 88 00 00 | ARGB8 |
Tentang PNT3Jika format gambar adalah PNT3 , maka struktur piksel setelah dibongkar adalah ARGB8; bits_per_pixel
- ukuran gambar terkompresi dalam byte.
Membongkar PNT3
n = 0 destination = b"" while src < size: v = int.from_bytes(source[src:src + 4], byteorder='little') src += 4 if v > 1000000 or v == 0: n += 1 else: destination += source[src - (1 + n) * 4:src - 4] destination += b"\x00" * v n = 0
Ini menarik: beberapa tekstur dipantulkan secara vertikal (atau ada juga yang tidak tercermin?).
Dan permainan ini sangat iri dengan transparansi - jika gambar menggunakan saluran alpha, warna piksel transparan harus benar-benar hitam. Atau putih - itulah keberuntungannya.
Format sederhana sudah berakhir, mari kita beralih ke yang lebih kaku - pada satu waktu, jajaran pembuat mod dengan marah menyimpan alat pengeditan mereka sendiri untuk format berikut, dan tidak sia-sia. Aku sudah memperingatkanmu.
Database (* DB dan lainnya)
Format ini sangat tidak nyaman untuk dijelaskan - pada dasarnya, ini adalah pohon node serial (atau tabel catatan). File terdiri dari beberapa tabel dengan tipe bidang yang ditentukan. Struktur umum: tabel bersarang di simpul "root" yang umum, catatan adalah simpul di dalam tabel.
Di setiap node, jenis dan ukurannya ditentukan:
unsigned char type_index; unsigned char raw_size;
Jenis bidang tabel diambil oleh indeks dari format string untuk tabel, tipe nyata ditentukan oleh nilai yang diperoleh.
Jenis bidangpenunjukan | deskripsi |
---|
S | tali |
Saya | 4b int |
U | 4b tidak ditandatangani |
F | 4b mengapung |
X | bit byte |
f | array mengambang |
saya | array int |
B | bool |
b | array bool |
H | byte hex tidak dikenal |
T | waktu |
0 | tidak disebutkan |
1 | 0FII |
2 | SUFF |
3 | FFFF |
4 | 0SISS |
5 | 0SISS00000U |
Deskripsi pangkalanItem (.idb)
meja | struktur |
---|
Material | SSSIFFFIFIFfIX |
Senjata | SSISIIIFFFFIFIXB00000IHFFFfHHFF |
Armor | SSISIIIFFFFIFIXB00000ffBiHH |
Item cepat | SSISIIIFFFFIFIXB00000IIFFSbH |
Item pencarian | SSISIIIFFFFIFIXB00000Is |
Menjual Barang | SSISIIIFFFFIFIXB00000IHI |
Switch (.ldb)
meja | struktur |
---|
Ganti prototipe | SfIFTSSS |
Keterampilan dan Keterampilan (.pdb)
meja | struktur |
---|
Kemampuan | SSI0000000s |
Keterampilan | SSI0000000SSIIIFFFIIIIBI |
Jejak kaki (prints.db)
meja | struktur |
---|
Jejak darah | 0S11 |
Jejak api | 0S110000001 |
Jejak kaki | 0S11 |
Mantra (.sdb)
meja | struktur |
---|
Prototipe | SSSFIFIFFFFIIIIUSSIIbIXFFFFF |
Pengubah | SSFIFFISX |
Pola | 0SssSX |
Templat Armor | 0SssSX |
Pola Senjata | 0SssSX |
Makhluk (.udb)
meja | struktur |
---|
Bagian yang rusak | SffUU |
Ras | SUFFUUFfFUUf222222000000000000SssFSsfUUfUUIUSBFUUUU |
Prototipe monster | SSIUIFFFSFFFFFFFFFUFFFFFFff33sfssSFFFFFUFUSF |
NPC | SUFFFFbbssssFUB |
Teriakan (acks.db)
meja | struktur |
---|
Jawabannya | 0S0000000044444444444444444444445444444444444 |
Jeritan | 0S0000000044444 |
Lainnya | 0S0000000044 |
Quests (.qdb)
meja | struktur |
---|
Misi | SFIISIIs |
Briefing | SFFsSsssssI |
Ini menarik: 16 Januari 2002 Nival memposting basis sumber untuk multiplayer dalam format csv, serta utilitas-konverter dalam format game ( snapshot situs ). Secara alami, konverter terbalik tidak lambat muncul. Ada juga setidaknya dua dokumen yang menggambarkan bidang dan jenisnya dari pembuat mod, tetapi membacanya sangat sulit.
Adb
Basis data animasi untuk jenis unit tertentu. Berbeda dengan * DB yang disebutkan di atas, itu cukup "manusia" - itu adalah tabel tingkat tunggal dengan ukuran bidang statis.

Deskripsi struktur meta: id: adb title: Evil Islands, ADB file (animations database) application: Evil Islands file-extension: adb license: MIT endian: le doc: Animations database seq: - id: magic contents: [0x41, 0x44, 0x42, 0x00] doc: Magic bytes - id: animations_count type: u4 doc: Number of animations in base - id: unit_name type: str encoding: cp1251 size: 24 doc: Name of unit - id: min_height type: f4 doc: Minimal height of unit - id: mid_height type: f4 doc: Middle height of unit - id: max_height type: f4 doc: Maximal height of unit - id: animations type: animation doc: Array of animations repeat: expr repeat-expr: animations_count types: animation: doc: Animation's parameters seq: - id: name type: str encoding: cp1251 size: 16 doc: Animation's name - id: number type: u4 doc: Index in animations array - id: additionals type: additional doc: Packed structure with animation parameters - id: action_probability type: u4 doc: Percents of action probability - id: animation_length type: u4 doc: Lenght of animation in game ticks - id: movement_speed type: f4 doc: Movement speed - id: start_show_hide1 type: u4 - id: start_show_hide2 type: u4 - id: start_step_sound1 type: u4 - id: start_step_sound2 type: u4 - id: start_step_sound3 type: u4 - id: start_step_sound4 type: u4 - id: start_hit_frame type: u4 - id: start_special_sound type: u4 - id: spec_sound_id1 type: u4 - id: spec_sound_id2 type: u4 - id: spec_sound_id3 type: u4 - id: spec_sound_id4 type: u4 types: additional: seq: - id: packed type: u8 instances: weapons: value: 'packed & 127' allowed_states: value: '(packed >> 15) & 7' action_type: value: '(packed >> 18) & 15' action_modifyer: value: '(packed >> 22) & 255' animation_stage: value: '(packed >> 30) & 3' action_forms: value: '(packed >> 36) & 63'
Ini menarik: untuk beberapa unit, format basis data yang terpotong sebagian digunakan, yang jarang dieksplorasi.
Setelah berurusan dengan basis data, kami menyatakan jeda iklan. Tetapi kami tidak akan mengiklankan apa pun - bukan metode kami. Lebih baik menunjukkan apa yang berguna selanjutnya - bagaimana nama file makhluk.
Nama ini dikumpulkan dari kelompok dua karakter - singkatan dari "level" logis.
Misalnya, karakter wanita akan tidak unhufe
- Unit > Human > Female
, dan initwesp
- Inventory > Item > Weapon > Spear
, yaitu, tombak dalam inventaris (bukan bagian belakang, dan itu bagus).
Elemen lengkap pohon nama: un: # unit an: # animal wi: # wild ti # tiger ba # bat bo # boar hy # hyen de # deer gi # rat ra # rat cr # crawler wo # wolf ho: # home co # cow pi # pig do # dog ho # horse ha # hare or: # orc fe # female ma # male mo: # monster co # column (menu) un # unicorn cu # Curse be # beholder tr # troll el # elemental su # succub (harpie) ba # banshee dr # driad sh # shadow li # lizard sk # skeleton sp # spider go # golem, goblin ri # Rick og # ogre zo # zombie bi # Rik's dragon cy # cyclope dg # dragon wi # willwisp mi # octopus to # toad hu: # human fe # female ma # male in: # inventory it: # item qu # quest qi # interactive ar: # armor pl # plate gl # gloves lg # leggins bt # boots sh # shirt hl # helm pt # pants li: # loot mt # material tr # trade we: # weapon hm # hammer dg # dagger sp # spear cb # crossbow sw # sword ax # axe bw # bow gm # game menu fa: # faces un: # unit an: # animal wi: # wild ti: # tiger face # face ba: # bat face # face bo: # boar face # face de: # deer face # face ra: # rat face # face cr: # crawler face # face wo: # wolf face # face ho: # home co: # cow face # face pi: # pig face # face do: # dog face # face ho: # horse face # face ha: # hare face # face hu: # human fe: # female fa # me # th # ma: # male fa # me # th # mo: # monster to: # toad face # face tr: # troll face # face or: # orc face # face sp: # spider face # face li: # lizard face # face na: # nature fl: # flora bu # bush te # termitary tr # tree li # waterplant wa # waterfall sk # sky st # stone ef: # effects cu # ar # co # components st: # static si # switch bu: # building to # tower ho # house tr # trap br # bridge ga # gate we # well (waterhole) wa: # wall me # medium li # light to # torch st # static
Ini menarik: menurut klasifikasi ini, jamur adalah pohon, golem dengan goblin adalah saudara, dan Tka-Rick adalah monster. Juga di sini Anda dapat melihat nama monster yang "berfungsi", curiga mirip dengan yang dimiliki D & D - pemirsa (mata jahat), succub (harpy), ogre (cannibal), driad (rimbawan).
Setelah beristirahat secara moral, kami langsung terjun ke dalam model. Mereka disajikan dalam beberapa format yang dihubungkan bersama.
Lnk
Logikanya - dasar dari model. Menjelaskan hierarki bagian-bagian model, dalam hal pemodelan 3d modern - hierarki tulang.

Deskripsi struktur meta: id: lnk title: Evil Islands, LNK file (bones hierarchy) application: Evil Islands file-extension: lnk license: MIT endian: le doc: Bones hierarchy seq: - id: bones_count type: u4 doc: Number of bones - id: bones_array type: bone repeat: expr repeat-expr: bones_count doc: Array of bones types: bone: doc: Bone node seq: - id: bone_name_len type: u4 doc: Length of bone's name - id: bone_name type: str encoding: cp1251 size: bone_name_len doc: Bone's name - id: parent_name_len type: u4 doc: Length of bone's parent name - id: parent_name type: str encoding: cp1251 size: parent_name_len doc: Bone's parent name
Nama induk tulang induk adalah string kosong (panjang 0).
Ada tulang, namun, tidak cukup untuk memberi nama dan menyatukannya - Anda harus mengumpulkannya menjadi kerangka.
Bon
Disebutkan sebelumnya, format ini (jika bukan arsip) mengatur posisi bagian (tulang) model relatif terhadap bagian induk. Hanya offset yang disimpan, tanpa rotasi - salah satu perbedaan dari format modern.

Deskripsi struktur meta: id: bon title: Evil Islands, BON file (bone position) application: Evil Islands file-extension: bon license: MIT endian: le doc: Bone position seq: - id: position type: vec3 doc: Bone translation repeat: eos types: vec3: doc: 3d vector seq: - id: x type: f4 doc: x axis - id: y type: f4 doc: y axis - id: z type: f4 doc: z axis
Seperti yang Anda lihat, ada terlalu banyak angka untuk satu offset - faktanya adalah bahwa di sini kita pertama kali menemukan salah satu fitur kunci dari mesin game - interpolasi model trilinear.
Cara kerjanya: model memiliki tiga parameter interpolasi - kondisional, kekuatan, ketangkasan, pertumbuhan. Ada juga 8 keadaan ekstrim model. Dengan menggunakan parameter, kita bisa mendapatkan model akhir dengan interpolasi trilinear.
Algoritma itu sendiri def trilinear(val, coefs=[0, 0, 0]):
Ini menarik: interpolasi model trilinear digunakan untuk menghidupkan beberapa objek, misalnya, membuka pintu batu dan peti.
Sekarang saatnya untuk melihat bagian-bagian dari model itu sendiri.
Gbr
Mungkin reli ini tidak mungkin dimengerti. Anda dapat menemukan deskripsinya dan plug-in untuk blender di internet, tetapi bahkan dengan mereka kesadarannya tidak langsung datang. Lihatlah:

Deskripsi struktur meta: id: fig title: Evil Islands, FIG file (figure) application: Evil Islands file-extension: fig license: MIT endian: le doc: 3d mesh seq: - id: magic contents: [0x46, 0x49, 0x47, 0x38] doc: Magic bytes - id: vertex_count type: u4 doc: Number of vertices blocks - id: normal_count type: u4 doc: Number of normals blocks - id: texcoord_count type: u4 doc: Number of UV pairs - id: index_count type: u4 doc: Number of indeces - id: vertex_components_count type: u4 doc: Number of vertex components - id: morph_components_count type: u4 doc: Number of morphing components - id: unknown contents: [0, 0, 0, 0] doc: Unknown (aligment) - id: group type: u4 doc: Render group - id: texture_index type: u4 doc: Texture offset - id: center type: vec3 doc: Center of mesh repeat: expr repeat-expr: 8 - id: aabb_min type: vec3 doc: AABB point of mesh repeat: expr repeat-expr: 8 - id: aabb_max type: vec3 doc: AABB point of mesh repeat: expr repeat-expr: 8 - id: radius type: f4 doc: Radius of boundings repeat: expr repeat-expr: 8 - id: vertex_array type: vertex_block doc: Blocks of raw vertex data repeat: expr repeat-expr: 8 - id: normal_array type: vec4x4 doc: Packed normal data repeat: expr repeat-expr: normal_count - id: texcoord_array type: vec2 doc: Texture coordinates data repeat: expr repeat-expr: texcoord_count - id: index_array type: u2 doc: Triangles indeces repeat: expr repeat-expr: index_count - id: vertex_components_array type: vertex_component doc: Vertex components array repeat: expr repeat-expr: vertex_components_count - id: morph_components_array type: morph_component doc: Morphing components array repeat: expr repeat-expr: morph_components_count types: morph_component: doc: Morphing components indeces seq: - id: morph_index type: u2 doc: Index of morphing data - id: vertex_index type: u2 doc: Index of vertex vertex_component: doc: Vertex components indeces seq: - id: position_index type: u2 doc: Index of position data - id: normal_index type: u2 doc: Index of normal data - id: texture_index type: u2 doc: Index of texcoord data vec2: doc: 2d vector seq: - id: u type: f4 doc: u axis - id: v type: f4 doc: v axis vec3: doc: 3d vector seq: - id: x type: f4 doc: x axis - id: y type: f4 doc: y axis - id: z type: f4 doc: z axis vec3x4: doc: 3d vector with 4 values per axis seq: - id: x type: f4 doc: x axis repeat: expr repeat-expr: 4 - id: y type: f4 doc: y axis repeat: expr repeat-expr: 4 - id: z type: f4 doc: z axis repeat: expr repeat-expr: 4 vertex_block: doc: Vertex raw block seq: - id: block type: vec3x4 doc: Vertex data repeat: expr repeat-expr: _root.vertex_count vec4x4: doc: 4d vector with 4 values per axis seq: - id: x type: f4 doc: x axis repeat: expr repeat-expr: 4 - id: y type: f4 doc: y axis repeat: expr repeat-expr: 4 - id: z type: f4 doc: z axis repeat: expr repeat-expr: 4 - id: w type: f4 doc: w axis repeat: expr repeat-expr: 4
Apa kesulitannya? Jadi bagaimanapun, data normals dan simpul disimpan dalam blok 4, dan simpul juga diatur dalam 8 blok untuk interpolasi.
Ini menarik: mungkin, pengelompokan semacam itu dibuat untuk mempercepat pemrosesan dengan bantuan instruksi SSE yang muncul dalam prosesor Intel sejak 1999.
Kita membaca dan menyusun model, tetapi ada sesuatu yang hilang. Tepat - animasi!
Anm
Animasi disimpan dalam bentuk komponen sebagai status kunci. Fakta yang menarik adalah bahwa ia mendukung tidak hanya animasi kerangka, tetapi juga verteks morphing.

Deskripsi struktur meta: id: anm title: Evil Islands, ANM file (bone animation) application: Evil Islands file-extension: anm license: MIT endian: le doc: Bone animation seq: - id: rotation_frames_count type: u4 doc: Number of rotation frames - id: rotation_frames type: quat repeat: expr repeat-expr: rotation_frames_count doc: Bone rotations - id: translation_frames_count type: u4 doc: Number of translation frames - id: translation_frames type: vec3 repeat: expr repeat-expr: translation_frames_count doc: Bone translation - id: morphing_frames_count type: u4 doc: Number of morphing frames - id: morphing_vertex_count type: u4 doc: Number of vertices with morphing - id: morphing_frames type: morphing_frame repeat: expr repeat-expr: morphing_frames_count doc: Array of morphing frames types: vec3: doc: 3d vector seq: - id: x type: f4 doc: x axis - id: y type: f4 doc: y axis - id: z type: f4 doc: z axis quat: doc: quaternion seq: - id: w type: f4 doc: w component - id: x type: f4 doc: x component - id: y type: f4 doc: y component - id: z type: f4 doc: z component morphing_frame: doc: Array of verteces morphing seq: - id: vertex_shift type: vec3 repeat: expr repeat-expr: _parent.morphing_vertex_count doc: Morphing shift per vertex
Itu saja - sekarang kami memiliki model lengkap, Anda dapat mengagumi kadal pertapa yang baru saja dirender:

Momen nostalgiaCari tahu apa yang dibutuhkan Kadal
Percakapan dengan kadal di rumahnya
Hermit Lizard: Kamu telah datang, kawan. Ini bagus.
Zach: Hanya itu yang ingin kau katakan padaku?
Lizard Hermit: Anda sedang terburu-buru lagi. Saya ingat pertanyaan Anda dan akan menjawabnya. Saya datang ke orang-orang dengan besi untuk membuat kesepakatan. Tapi saya melihat bagaimana mereka lakukan pada Anda. Mereka tidak memegang kata-kata, saya berhenti mempercayai mereka. Anda menepati janji Anda. Kesepakatan akan ditawarkan kepada Anda.
Kadal Hermit: Orang-orang menyukai emas. Kadal emas tidak menarik. Anda akan menyelesaikan tugas saya, dan saya akan memberi Anda emas yang saya miliki. Ada banyak emas.
Zach (serius dan tanpa banyak minat) : Hmm ... Emas ... Itu pasti tidak akan sakit ...
Zach: Akan lebih baik jika kamu bisa membantuku mencari tahu di mana penyihir tua yang kucari selama ini. Lagi pula, kadal adalah orang kuno, dan Anda bisa mengetahuinya!
Hermit Lizard: Anda benar. Kadal adalah orang kuno. Saya bisa mengumpulkan semua yang kita tahu tentang orang tua itu. Apakah Anda setuju untuk menyelesaikan misi saya?
Zach: Bicara apa! Anggap saja semuanya sudah dilakukan.
Kadal Hermit (serius) : Sudah selesai? Apakah Anda ingin menipu saya?
Zach: Sebenarnya, saya ingin membuat lelucon, kalau tidak Anda benar-benar serius.
Kadal Pertapa: Begitu . Ini sebuah lelucon. Saya kira saya bisa membuat lelucon juga. Lalu. Dan sekarang saya ingin Anda mengembalikan air ke Kanal. Para Orc mencuri air dari kami.
Kadal Hermit: Pergi ke selatan di sepanjang air. Anda akan melihat bendungan dan Terusan. Bendungan harus dinaikkan. Leverage. Saya akan memberikannya. Saluran harus diblokir. Batu itu. Saya tidak akan memberi batu. Dia sudah berbaring di tepi Kanal. Hulu bendungan. Batu itu berat. Ketika para orc menggali, mereka mengangkatnya untuk waktu yang lama. Jika Anda mendorongnya, dia akan jatuh kembali dengan cepat.
Lizard Hermit: Setelah itu, kembali. Saya akan menceritakan semua yang saya pelajari tentang Pesulap tua itu.
Zach: Tangan di tangan! Tapi omong-omong, jika Anda menambahkan sedikit koin ke cerita, saya tidak akan tersinggung sama sekali.
Kadal Pertapa: Untuk koin, pergi ke kerabat saya yang tinggal di dangkal lebih jauh di selatan. Pergi ke pulau berpasir terjauh, yang ketiga berturut-turut. Harta akan menjadi milik Anda!
Lizard Hermit (untuk dirinya sendiri) : Strange. Pria ini suka humor. Saya sedang bercanda. Pria itu tidak tertawa. Sangat aneh.
Sekarang - yang paling menarik: bagaimana peta disimpan.
MP
Ini adalah file header peta. Karena kebetulan yang tidak menguntungkan, ekstensi tersebut bertepatan dengan yang terjadi pada penyimpanan multipemain, yang tidak akan kami pertimbangkan.
Pertama, Anda perlu memberikan gambaran umum tentang lanskap:
- jumlah "potongan" - potongan kartu 32x32 meter;
- tinggi maksimum (karena ketinggian simpul disimpan dalam skala bilangan bulat);
- jumlah ubin atlases.
, β , .

meta: id: mp title: Evil Islands, MP file (map header) application: Evil Islands file-extension: mp license: MIT endian: le doc: Map header seq: - id: magic contents: [0x72, 0xF6, 0x4A, 0xCE] doc: Magic bytes - id: max_altitude type: f4 doc: Maximal height of terrain - id: x_chunks_count type: u4 doc: Number of sectors by x - id: y_chunks_count type: u4 doc: Number of sectors by y - id: textures_count type: u4 doc: Number of texture files - id: texture_size type: u4 doc: Size of texture in pixels by side - id: tiles_count type: u4 doc: Number of tiles - id: tile_size type: u4 doc: Size of tile in pixels by side - id: materials_count type: u2 doc: Number of materials - id: animated_tiles_count type: u4 doc: Number of animated tiles - id: materials type: material doc: Map materials repeat: expr repeat-expr: materials_count - id: id_array type: u4 doc: Tile type repeat: expr repeat-expr: tiles_count enum: tile_type - id: animated_tiles type: animated_tile doc: Animated tiles repeat: expr repeat-expr: animated_tiles_count types: material: doc: Material parameters seq: - id: type type: u4 doc: Material type by enum: terrain_type - id: color type: rgba doc: RGBA diffuse color - id: self_illumination type: f4 doc: Self illumination - id: wave_multiplier type: f4 doc: Wave speed multiplier - id: warp_speed type: f4 doc: Warp speed multiplier - id: unknown size: 12 types: rgba: doc: RGBA color seq: - id: r type: f4 doc: Red channel - id: g type: f4 doc: Green channel - id: b type: f4 doc: Blue channel - id: a type: f4 doc: Alpha channel enums: terrain_type: 0: base 1: water_notexture 2: grass 3: water animated_tile: doc: Animated tile parameters seq: - id: start_index type: u2 doc: First tile of animation - id: length type: u2 doc: Animation frames count enums: tile_type: 0: grass 1: ground 2: stone 3: sand 4: rock 5: field 6: water 7: road 8: empty 9: snow 10: ice 11: drygrass 12: snowballs 13: lava 14: swamp 15: highrock
material type | Jenis |
---|
0 | grass |
1 | ground |
2 | stone |
3 | sand |
4 | rock |
5 | field |
6 | water |
7 | road |
8 | (empty) |
9 | snow |
10 | ice |
11 | drygrass |
12 | snowballs |
13 | lava |
14 | swamp |
15 | highrock |
, Res/aiinfo.res/tileDesc.reg
.
: , β .
: .
. !
SEC
β 3232 . , ZonenameXXXYYY
.

meta: id: sec title: Evil Islands, SEC file (map sector) application: Evil Islands file-extension: sec license: MIT endian: le doc: Map sector seq: - id: magic contents: [0x74, 0xF7, 0x4B, 0xCF] doc: Magic bytes - id: liquids type: u1 doc: Liquids layer indicator - id: vertexes type: vertex doc: Vertex array 33x33 repeat: expr repeat-expr: 1089 - id: liquid_vertexes type: vertex doc: Vertex array 33x33 if: liquids != 0 repeat: expr repeat-expr: 'liquids != 0 ? 1089 : 0' - id: tiles type: tile doc: Tile array 16x16 repeat: expr repeat-expr: 256 - id: liquid_tiles type: tile doc: Tile array 16x16 if: liquids != 0 repeat: expr repeat-expr: 'liquids != 0 ? 256 : 0' - id: liquid_material type: u2 doc: Index of material if: liquids != 0 repeat: expr repeat-expr: 'liquids != 0 ? 256 : 0' types: vertex: doc: Vertex data seq: - id: x_shift type: s1 doc: Shift by x axis - id: y_shift type: s1 doc: Shift by y axis - id: altitude type: u2 doc: Height (z position) - id: packed_normal type: normal doc: Packed normal normal: doc: Normal (3d vector) seq: - id: packed type: u4 doc: Normal packed in 4b instances: x: doc: Unpacked x component value: packed >> 11 & 0x7FF y: doc: Unpacked y component value: packed & 0x7FF z: doc: Unpacked z component value: packed >> 22 tile: doc: Tile parameters seq: - id: packed type: u2 doc: Tile information packed in 2b instances: index: doc: Tile index in texture value: packed & 63 texture: doc: Texture index value: packed >> 6 & 255 rotation: doc: Tile rotation (*90 degrees) value: packed >> 14 & 3
β .
10 z, 11 x y
unsigned packed_normal; float x = ((float)((packed_normal >> 11) & 0x7FF) - 1000.0f) / 1000.0f; float y = ((float)(packed_normal & 0x7FF) - 1000.0f) / 1000.0f; float z = (float)(packed_normal >> 22) / 1000.0f;
6 , 8 , 2
unsigned short texture; unsigned char tile_index = f & 63; unsigned char texture_index = (f >> 6) & 255; unsigned char rotation = (f >> 14) & 3;
3d33 33 , , 3232 . β 1 .
:
x = x + x_offset / 254
y = y + y_offset / 254
z = altitude / 65535 * max_altitude ( .mp )
"", :
0 1 2 *-*-* |\|\| ~ 33 *-*-* |\|\| ~ 66 *-*-* ~ ~ ~
, , 1616 . β 2 . , 90 .
. , , ID , MP .
: MP, , : ID , - .
ID β .
β :

- β , .
MOB
( ) , , : . β " ", .
, ( ).
:
typedef structure { unsigned type_id; unsigned size; byte data[size - 8]; } node;
(, !)
( , )
meta: id: mob title: Evil Islands, MOB file (map entities) application: Evil Islands file-extension: mob license: MIT endian: le doc: Map entities tree seq: - id: root_node type: node doc: Root node types: node: doc: Entity node seq: - id: type_id type: u4 doc: Node children type ID - id: size type: u4 doc: Node full size - id: data type: node_data size: size - 8 doc: Node stored data node_data: doc: Node data seq: - id: value type: switch-on: _parent.type_id cases: 0xA000: node 0x00001E00: node 0x00001E01: node 0x00001E02: node 0x00001E03: node 0x00001E0B: node 0x00001E0E: node 0x0000A000: node 0x0000AA01: node 0x0000ABD0: node 0x0000B000: node 0x0000B001: node 0x0000CC01: node 0x0000DD01: node 0x0000E000: node 0x0000E001: node 0x0000F000: node 0x0000FF00: node 0x0000FF01: node 0x0000FF02: node 0xBBAB0000: node 0xBBAC0000: node 0xBBBB0000: node 0xBBBC0000: node 0xBBBD0000: node 0xBBBE0000: node 0xBBBF0000: node 0xDDDDDDD1: node _: u1 doc: Node elements repeat: eos
| () | |
---|
AiGraph | | |
AreaArray | | |
Byte | 1 | 1 |
Diplomacy | 4096 | 32x32 2 |
Dword | 4 | 4 |
Mengapung | 4 | 4 |
LeverStats | 12 | |
Null | 0 | |
Plot | 12 | 3 floats (vec3) |
Plot2DArray | | |
Quaternion | 16 | 4 floats (vec4) |
Record | >8 | |
Rectangle | | |
Tali | | |
StringArray | >4 | |
StringEncrypted | >4 | |
UnitStats | 180 | |
Unknown | | |
type_idtype_id | | |
---|
0x00000000 | Record | ROOT |
0x00001E00 | Record | VSS_SECTION |
0x00001E01 | Record | VSS_TRIGER |
0x00001E02 | Record | VSS_CHECK |
0x00001E03 | Record | VSS_PATH |
0x00001E04 | Dword | VSS_ID |
0x00001E05 | Rectangle | VSS_RECT |
0x00001E06 | Dword | VSS_SRC_ID |
0x00001E07 | Dword | VSS_DST_ID |
0x00001E08 | Tali | VSS_TITLE |
0x00001E09 | Tali | VSS_COMMANDS |
0x00001E0A | Byte | VSS_ISSTART |
0x00001E0B | Record | VSS_LINK |
0x00001E0C | Tali | VSS_GROUP |
0x00001E0D | Byte | VSS_IS_USE_GROUP |
0x00001E0E | Record | VSS_VARIABLE |
0x00001E0F | StringArray | VSS_BS_CHECK |
0x00001E10 | StringArray | VSS_BS_COMMANDS |
0x00001E11 | Tali | VSS_CUSTOM_SRIPT |
0x0000A000 | Record | OBJECTDBFILE |
0x0000AA00 | Null | LIGHT_SECTION |
0x0000AA01 | Record | LIGHT |
0x0000AA02 | Mengapung | LIGHT_RANGE |
0x0000AA03 | Tali | LIGHT_NAME |
0x0000AA04 | Plot | LIGHT_POSITION |
0x0000AA05 | Dword | LIGHT_ID |
0x0000AA06 | Byte | LIGHT_SHADOW |
0x0000AA07 | Plot | LIGHT_COLOR |
0x0000AA08 | Tali | LIGHT_COMMENTS |
0x0000ABD0 | Record | WORLD_SET |
0x0000ABD1 | Plot | WS_WIND_DIR |
0x0000ABD2 | Mengapung | WS_WIND_STR |
0x0000ABD3 | Mengapung | WS_TIME |
0x0000ABD4 | Mengapung | WS_AMBIENT |
0x0000ABD5 | Mengapung | WS_SUN_LIGHT |
0x0000B000 | Record | OBJECTSECTION |
0x0000B001 | Record | OBJECT |
0x0000B002 | Dword | NID |
0x0000B003 | Dword | OBJTYPE |
0x0000B004 | Tali | OBJNAME |
0x0000B005 | Null | OBJINDEX |
0x0000B006 | Tali | OBJTEMPLATE |
0x0000B007 | Tali | OBJPRIMTXTR |
0x0000B008 | Tali | OBJSECTXTR |
0x0000B009 | Plot | OBJPOSITION |
0x0000B00A | Quaternion | OBJROTATION |
0x0000B00B | Null | OBJTEXTURE |
0x0000B00C | Plot | OBJCOMPLECTION |
0x0000B00D | StringArray | OBJBODYPARTS |
0x0000B00E | Tali | PARENTTEMPLATE |
0x0000B00F | Tali | OBJCOMMENTS |
0x0000B010 | Null | OBJ_DEF_LOGIC |
0x0000B011 | Byte | OBJ_PLAYER |
0x0000B012 | Dword | OBJ_PARENT_ID |
0x0000B013 | Byte | OBJ_USE_IN_SCRIPT |
0x0000B014 | Byte | OBJ_IS_SHADOW |
0x0000B015 | Null | OBJ_R |
0x0000B016 | Tali | OBJ_QUEST_INFO |
0x0000C000 | Null | SC_OBJECTDBFILE |
0x0000CC00 | Null | SOUND_SECTION |
0x0000CC01 | Record | SOUND |
0x0000CC02 | Dword | SOUND_ID |
0x0000CC03 | Plot | SOUND_POSITION |
0x0000CC04 | Dword | SOUND_RANGE |
0x0000CC05 | Tali | SOUND_NAME |
0x0000CC06 | Dword | SOUND_MIN |
0x0000CC07 | Dword | SOUND_MAX |
0x0000CC08 | Tali | SOUND_COMMENTS |
0x0000CC09 | Null | SOUND_VOLUME |
0x0000CC0A | StringArray | SOUND_RESNAME |
0x0000CC0B | Dword | SOUND_RANGE2 |
0x0000CC0D | Byte | SOUND_AMBIENT |
0x0000CC0E | Byte | SOUND_IS_MUSIC |
0x0000D000 | Null | PR_OBJECTDBFILE |
0x0000DD00 | Null | PARTICL_SECTION |
0x0000DD01 | Record | PARTICL |
0x0000DD02 | Dword | PARTICL_ID |
0x0000DD03 | Plot | PARTICL_POSITION |
0x0000DD04 | Tali | PARTICL_COMMENTS |
0x0000DD05 | Tali | PARTICL_NAME |
0x0000DD06 | Dword | PARTICL_TYPE |
0x0000DD07 | Mengapung | PARTICL_SCALE |
0x0000E000 | Record | DIRICTORY |
0x0000E001 | Record | FOLDER |
0x0000E002 | Tali | DIR_NAME |
0x0000E003 | Dword | DIR_NINST |
0x0000E004 | Dword | DIR_PARENT_FOLDER |
0x0000E005 | Byte | DIR_TYPE |
0x0000F000 | Record | DIRICTORY_ELEMENTS |
0x0000FF00 | Record | SEC_RANGE |
0x0000FF01 | Record | MAIN_RANGE |
0x0000FF02 | Record | RANGE |
0x0000FF05 | Dword | MIN_ID |
0x0000FF06 | Dword | MAX_ID |
0x31415926 | AiGraph | AIGRAPH |
0xACCEECCA | Tali | SS_TEXT_OLD |
0xACCEECCB | StringEncrypted | SS_TEXT |
0xBBAB0000 | Record | MAGIC_TRAP |
0xBBAB0001 | Dword | MT_DIPLOMACY |
0xBBAB0002 | Tali | MT_SPELL |
0xBBAB0003 | AreaArray | MT_AREAS |
0xBBAB0004 | Plot2DArray | MT_TARGETS |
0xBBAB0005 | Dword | MT_CAST_INTERVAL |
0xBBAC0000 | Record | LEVER |
0xBBAC0001 | Null | LEVER_SCIENCE_STATS |
0xBBAC0002 | Byte | LEVER_CUR_STATE |
0xBBAC0003 | Byte | LEVER_TOTAL_STATE |
0xBBAC0004 | Byte | LEVER_IS_CYCLED |
0xBBAC0005 | Byte | LEVER_CAST_ONCE |
0xBBAC0006 | LeverStats | LEVER_SCIENCE_STATS_NEW |
0xBBAC0007 | Byte | LEVER_IS_DOOR |
0xBBAC0008 | Byte | LEVER_RECALC_GRAPH |
0xBBBB0000 | Record | UNIT |
0xBBBB0001 | Null | UNIT_R |
0xBBBB0002 | Tali | UNIT_PROTOTYPE |
0xBBBB0003 | Null | UNIT_ITEMS |
0xBBBB0004 | UnitStats | UNIT_STATS |
0xBBBB0005 | StringArray | UNIT_QUEST_ITEMS |
0xBBBB0006 | StringArray | UNIT_QUICK_ITEMS |
0xBBBB0007 | StringArray | UNIT_SPELLS |
0xBBBB0008 | StringArray | UNIT_WEAPONS |
0xBBBB0009 | StringArray | UNIT_ARMORS |
0xBBBB000A | Byte | UNIT_NEED_IMPORT |
0xBBBC0000 | Record | UNIT_LOGIC |
0xBBBC0001 | Null | UNIT_LOGIC_AGRESSIV |
0xBBBC0002 | Byte | UNIT_LOGIC_CYCLIC |
0xBBBC0003 | Dword | UNIT_LOGIC_MODEL |
0xBBBC0004 | Mengapung | UNIT_LOGIC_GUARD_R |
0xBBBC0005 | Plot | UNIT_LOGIC_GUARD_PT |
0xBBBC0006 | Byte | UNIT_LOGIC_NALARM |
0xBBBC0007 | Byte | UNIT_LOGIC_USE |
0xBBBC0008 | Null | UNIT_LOGIC_REVENGE |
0xBBBC0009 | Null | UNIT_LOGIC_FEAR |
0xBBBC000A | Mengapung | UNIT_LOGIC_WAIT |
0xBBBC000B | Byte | UNIT_LOGIC_ALARM_CONDITION |
0xBBBC000C | Mengapung | UNIT_LOGIC_HELP |
0xBBBC000D | Byte | UNIT_LOGIC_ALWAYS_ACTIVE |
0xBBBC000E | Byte | UNIT_LOGIC_AGRESSION_MODE |
0xBBBD0000 | Record | GUARD_PT |
0xBBBD0001 | Plot | GUARD_PT_POSITION |
0xBBBD0002 | Null | GUARD_PT_ACTION |
0xBBBE0000 | Record | ACTION_PT |
0xBBBE0001 | Plot | ACTION_PT_LOOK_PT |
0xBBBE0002 | Dword | ACTION_PT_WAIT_SEG |
0xBBBE0003 | Dword | ACTION_PT_TURN_SPEED |
0xBBBE0004 | Byte | ACTION_PT_FLAGS |
0xBBBF0000 | Record | TORCH |
0xBBBF0001 | Mengapung | TORCH_STRENGHT |
0xBBBF0002 | Plot | TORCH_PTLINK |
0xBBBF0003 | Tali | TORCH_SOUND |
0xDDDDDDD1 | Record | DIPLOMATION |
0xDDDDDDD2 | Diplomacy | DIPLOMATION_FOF |
0xDDDDDDD3 | StringArray | DIPLOMATION_PL_NAMES |
0xFFFFFFFF | Unknown | UNKNOWN |
β , , Nival, β , ( , ).
unsigned key; for (size_t i = 0; i < size; i++) { key += (((((key * 13) << 4) + key) << 8) - key) * 4 + 2531011; data[i] ^= key >> 16; }
: , ( ) . , , , .
( , , β Windows 98):

: , . , ( , , " : ", ).
, , - - , , Collada :

. , .
, . - , β - , . , -...
β !
UPD (23.01.2019):
, : github .
, (, "" ).
- http://gipatgroup.org/utilities β EiEdit (.res, .*db), MobSurgeon (.mob)
- http://svn.gipat.org/trac/GGWiki β EiEdit (.res, .*db), MobSurgeon (.mob), .mp, .sec, .*db
- https://github.com/demothorg/eifixer β
- https://github.com/konstvest/ei_figer β Blender .lnk, .fig, .bon, .anm
- https://github.com/demothorg/ei-tools β (.mob, .lnk, .mpr, .res) +
- https://github.com/konstvest/ei_maper β (.mpr, .mp, .sec, .mob)
- https://github.com/chemmalion/EIDBEditor β (.*db)
- https://gitlab.com/ykurganov/open-evil-islands β ,