diff --git a/documentation/Data File Details.txt b/documentation/Data File Details.txt index 509c6d5..93f4fb3 100644 --- a/documentation/Data File Details.txt +++ b/documentation/Data File Details.txt @@ -1,5 +1,5 @@ .CSO FILES { - + Chunk type ICFE // Interface. Describes any interfaces, and implementing classes, present in the source HLSL. ISGN // Input signature @@ -13,7 +13,7 @@ SHEX // Shader (SM5) SPDB // Shader debugging info (new-style) STAT // Statistics. Useful statistics about the shader, such as instruction count, declaration count, etc. - + DXBL 16 byte Checksum // Proprietary, likely cannot determine 04 byte ??? // Always 1 @@ -24,9 +24,9 @@ 04 byte OSGN chunk offset 04 byte SHDR chunk offset 04 byte STAT chunk offset - + CHUNKS { - + RDEF 04 byte Remaining chunk byte size 04 byte Constant buffer count @@ -38,25 +38,25 @@ 02 byte Program type 04 byte Bitflags 04 byte Offset to "creator" string - + ISGN 04 byte Remaining chunk byte size - + OSGN 04 byte Remaining chunk byte size - + SHDR 04 byte Remaining chunk byte size - + STAT 04 byte Remaining chunk byte size - + } - + } .MDT FILES { - + CODES DETAILS 0x05 XX YY XX = script number? YY = character id 0x08 XX YY ZZ XX = ???, YY = ???(noticed either 0x21 or 0x41), ZZ = ???(only been 0x01) @@ -70,114 +70,114 @@ 0x1A next page 0x1D FF XX pause(frame/tick?) 0x1F next line - + Likely Codes 0x02 0x04 1 byte 0x14 0x1B 1 byte 0x?? 0x70 - - + + 0x0000 - Header Length(always 0x200) - - + + 0x0008 - # Map Entry Locations 32 byte Entries 0x000C - Map Entry Locations Offset - + 0x0010 - ??? 0x0014 - ??? - + 0x0018 - # of Intances 30 Byte Entries 0x001C - Instances Offset - + 0x0020 - # of HTA 72 byte Entries(lots of floating point numbers) 0x0024 - HTA Offset - + 0x0028 - # of Movement Scripts? // 92 bytes per entry 0x002C - Movement Scripts Offset - + 0x0030 - # of Unknown 148 byte Entries 0x0034 - Unknown Offset - + 0x0038 - # of Enemy Groups Positions 104 Byte Entries 0x003C - Enemy Groups Positions Offset - + 0x0040 - # of Unknown 192 byte Entries 0x0044 - Unknown Offset - + 0x0048 - # of Enemy Group Data 120 Byte Entries 0x004C - Enemy Group Data Offset - + 0x0050 - # of MOS 32 byte Entries 0x0054 - MOS Offset - + 0x0058 - # of Unknown 8 byte Entries(pure floating point numbers) 0x005C - Unknown Offset - + 0x0060 - # of unknown 4 byte Entries 0x0064 - Unknown Offset - + 0x0068 - # of Unknown 12 byte Entries 0x006C - Unknown offset - + 0x0070 - # of Unknown 64 byte Entires(check D800.mdt) 0x0074 - Unknown Offset - + 0x0078 - Dialogue Byte Length 0x007C - Dialogue Offset - + 0x0080 - # of Unknown 12 Byte Entries 0x0084 - Unknown Entries Offset - + 0x0088 - # of Unknown 16 Byte Entries 0x008C - Unknown Entries Offset - + 0x0090 - # of Unknown 8 Byte Entries 0x0094 - Unknown Entries Offset - + 0x0098 - # of Icon 32 Byte Entries(overworld interactables) 0x009C - Icon Entries Offset - + 0x00A0 - # of Unknown Bytes 0x00A4 - Offset to Unknown Data - + 0x00A8 - Shop Data Length 0x00AC - Shop Data Offset - + 0x00B0 - ???(so far, always 0x0000) 0x00B4 - ???(so far, always 0x0000) - + 0x00B8 - # of Unknown 18 Byte Entries 0x00BC - Unknown Entries Offset - + 0x00C0 - # of Unknown 128 Byte Entries 0x00C4 - Unknown Entries Offset - + 0x00C8 - # of Unknown 116 byte Entries(lots of floating point numbers) 0x00CC - Unknown Offset - - 0x00D0 - - 0x00D4 - - + + 0x00D0 - + 0x00D4 - + 0x00D8 - # of Unknown 44 Bytes 0x00DC - Unknown Offset - + 0x00E0 - # of Unknown 112(?) Bytes 0x00E4 - Unknown Offset - + 0x00E8 - Unknown Offset(0x20(32) Bytes) - 0x00EC - - - 0x00F0 - - 0x00F4 - - - 0x00F8 - - 0x00FC - - + 0x00EC - + + 0x00F0 - + 0x00F4 - + + 0x00F8 - + 0x00FC - + MAP ENTRIES { - + 04 byte Map ID // map entered from 04 byte X Position // position player enters map 04 byte Y Position @@ -186,7 +186,7 @@ 04 byte ??? float 04 byte ??? 04 byte 0xFF/0x00 - + 2000.mdt East Silesia East Silesia? @@ -200,11 +200,11 @@ Carbo House 4 Garmia Tower Witt Forest - + } INSTANCES { - + 02 byte ID 02 byte Index 02 byte ??? @@ -218,11 +218,11 @@ 04 byte CX Float 04 byte CY Float 04 byte CZ Float - + } - + HTA { (Center = (Minimum + Maximum) / 2) // Hit Detection, things like steam vents in Baked Plains, wall objects inside map, and map entrances) - + 01 byte Shape 01 byte Type 01 byte Trigger @@ -237,11 +237,11 @@ 04 byte Y Maximum 04 byte Z Maximum 32 byte ??? - + } - + Scripts { //tells entity to do action/move to specified coordinates - + 40 byte ??? 04 byte X coord offset? 04 byte Y coord offset? @@ -255,11 +255,11 @@ 02 byte ??? 01 byte ??? // when transition begins, this handles which direction character moves, likely a reference to an HTA 01 byte ??? // unsure, crashes game if wrong - + } - + Enemy Positions(104 byte entries) { - + 02 byte Index 02 byte ??? 04 byte X position minimum @@ -270,44 +270,44 @@ 04 byte Y Position 04 byte Z Position 24 byte ???(6 sets of x, y, z coordinates) - + } - + ENEMY DATA(120 byte) { - + 02 byte Index 22 byte ??? 02 byte ??? 02 byte # of enemy 02 byte Enemy ID - + } - + MOS Status { // appear to be visible effects that happen(i.e. - steam in Baked Plains) - + 02 byte ID + 1 02 byte Index(from Dreamcast debug) 04 byte ??? 02 byte X(?) Position 02 byte Y(?) Position 02 byte Z(?) Position - 18 byte ??? - + 12 byte ??? + } - + ICONS { - + 01 byte ID 03 byte ??? 04 byte X Position 04 byte Y Position 04 byte Z Position - 04 byte + 04 byte 04 byte Y Angle? 08 byte ??? 06 byte Item Offsets(2 byte) 02 byte Flag - + } @@ -315,7 +315,7 @@ ryudo script 0x2804 first dialogue 0x1A880 0x1AB40 in here Elena turns right, and waves - + } MODELS { // All Ninja formats use POF0, which means pointers go from the start of the chunk, not file @@ -323,9 +323,9 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o // NPC/Playables have MCS_ segment, enemies do not, these segments can only be found in content/data/afs/map so far // POF0 segments can be found within content/data/afs/model(includes model and sometimes PVRT) for each playable/enemy or C0?/c0?_*.dat for playables(includes MCS_ and model motions) // need to find NPC POF0 segments - + .CHR { // NPC/ENEMY - + CDDH segment(only the very first NJCM of file) 04 byte remaining header byte length 04 byte number of entries @@ -338,8 +338,8 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o NJCM segment POF0 segment // required MCS_ segment // for playable/NPC - - + + 4 byte remaining length 4 byte number of entries 4 byte ??? @@ -351,7 +351,7 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o NJCM segment POF0 segment // required MCS_ segment // for playable/NPC - + GPHD segment(only the very first NMDM in file) 4 byte remaining header byte length 4 byte GPHD index(which GPHD number within the file)(?) @@ -363,7 +363,7 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o 0xFF padded to nearest 4 bytes NMDM segment(x amount of NMDM sections based on MIXL) POF0 segment // required - + GAMT segment 4 byte remaining header byte length 4 byte ??? // Only 0 or 1 so far @@ -375,11 +375,11 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o 0xFF padded to nearest 4 bytes NMDM segment(x amount of NMDM sections based on MIXL) POF0 segment // required - + } - + .CHR2 { // EXTRA MOTION DATA - + CDDH segment 04 byte remaining header byte length 04 byte number of entries @@ -399,7 +399,7 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o 4 byte ??? //only 0 or 1 so far NMDM segment POF0 segment // required - + 2000.chr Elena First NMDM @@ -408,34 +408,34 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o 3: running 4: standing(bobbing) 5: standing(back straight, bobbing) - + } - + .MNJ { //ENVIRONMENT MODELS - - - + + + } - + GBIX(Global Index) { - + 4 byte remaining length 4 byte Global Index 4 byte 0x00000000 or 0x20202020 - + } - + NJTL { // Ninja Texlist(texture list?) - + 4 byte remaining header byte length - - + + } - + NJCM { // Ninja Chunk Model Tree - + Chunk header types { - + 0x00 - 0x00 null 0x01 - 0x05 Bits 01 NJD_CB_BA //Alpha blend 3 bits for alpha SRC and 3 bits for alpha DST @@ -487,9 +487,9 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o 4A NJD_CS_UVN2 //index0(16), U0a(16), V0a(16), U0b(16), V0b(16) 10 bytes 4B NJD_CS_UVH2 //index0(16), U0a(16), V0a(16), U0b(16), V0b(16) 10 bytes 0xFF - 0xFF End - + } - + 4 byte remaining length // does not contain these 4 bytes, will lead straight to next section, likely a POF0 4 byte evaluation flag 0x00000001 Don't apply translation, when x, y, z are 0 @@ -518,16 +518,16 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o 4[3] byte float scale 4 byte child object pointer // from start of model chunk 4 byte sibling object pointer // from start of model chunk - + /* for bones(it seems they will always be the first thing, might be all bases of the model themselves) the 4[3] byte float position is the "offset" from 1.0 x, 1.0 y, 1.0 z origin(the 1.0, 1.0, 1.0 origin should be the 4[3] byte float scale) */ - + Bits Chunk 2 byte chunk head 2 byte chunk flag - + Tiny Chunk 1 byte chunk head 1 byte chunk flag @@ -540,7 +540,7 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o 13 bits texture ID // least significant 1 bit super sample 2 bit filter mode // most significant - + Material Chunk 1 byte chunk head 1 byte chunk flag @@ -548,7 +548,7 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o 4 byte diffuse color // chunk head & 0x01 4 byte specular color // chunk head & 0x02 4 byte ambient color // chunk head & 0x04 - + Vertex Chunk 1 byte chunk head 1 byte chunk flag @@ -557,18 +557,18 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o 2 byte vertex count ? byte vertex data 4[3] byte vertex - + Strip Chunk 1 byte chunk head 1 byte chunk flag 2 byte chunk length in 2 bytes 2 byte chunk count ? byte strip data - + } - + NMDM { // Ninja Model Motion - + 4 byte remaining length 1 byte[remaining length] chunk body 4 byte motion data @@ -581,25 +581,25 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o 0x03 factor count 0x40 spline interpolation 0x80 user interpolation - + NJS_MDATA(Motion Data) 4[int_fp] byte factor pointer 4[3] byte factor count - + } - + NJTL { // Ninja Textlist(texture list?) - + 4 byte remaining length 4 byte NJS_TEXNAME pointer(offset from current position) 2 byte number of textures 4 byte texture number 8 byte ??? - + } - + PVRT { - + 4 byte remaining length 1 byte pixel format // 2 byte per pixel 0x00 ARGB1555 // 1-bit A, 5-bit RGB @@ -622,34 +622,34 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o 2 byte texture height ? byte palatte data ? byte texture data // if mipmap, go smallest to largest - + } - + POF0 { - + 4 byte remaining length 4 byte ??? - + } - + MCS_ { - + 4 byte remaining length 2 byte num 4 byte chunks 2 byte ??? - + } *.PVP FILES { - + F_ICON_32.PVP == F_FACE_SP.PVP - + PVPL 4 byte remaining length 4 byte ??? // 0x06000000 4 byte ??? // 0x00000001 - - + + } } @@ -667,39 +667,39 @@ MODELS { // All Ninja formats use POF0, which means pointers go from the start o } FONT FILE { - + xls_data/gr2us.dat Follows unicode dictionary starting at 0x20(space) } TB_SPCL.BIN(24 byte entries) { - + 1 byte Attack Offset 1 byte Attack Starting Level 2 byte Story Flag Requirement - + } - + TB_SKILL.BIN(24 byte entries) { - + 1 byte Skill Offset 1 byte Starting Level 1 byte Skillbook Level Requirement 1 byte Unknown - + } TB_MAGIC.BIN(72 byte entries) { - + 1 byte Attack Offset 1 byte Attack Starting Level 1 byte Mana Egg Level Requirement 1 byte Unknown - + } - + TB_LVUP.BIN(24 byte entries)(Starts @ Lvl 1) { - + 4 byte EXP Requirement 2 byte HP Increase 2 byte MP Increase @@ -711,11 +711,11 @@ TB_LVUP.BIN(24 byte entries)(Starts @ Lvl 1) { 2 byte MAG Increase 2 byte MEN Increase 2 byte Skill Slot Increase - + } - + PC_INIT.BIN(80 byte entries) { - + 4 byte EXP Starting 38 byte Unknown 1 byte Attack SP Recovery @@ -727,11 +727,11 @@ PC_INIT.BIN(80 byte entries) { 1 byte Move Evasion 1 byte R_KB 32 byte Unknown - + } TB_SHOP.BIN(164 byte entries) { //TB_SHOP.BIN is not used, data is stored in relevant *.MDT files - + 2 byte Map Name(by folder name) 2 byte Number of catagories(?) 8 byte "weapons" @@ -749,11 +749,11 @@ TB_SHOP.BIN(164 byte entries) { //TB_SHOP.BIN is not used, data is stored in rel 8 byte "regional" 24 byte Item Listing 2 byte Item "ID"(offset by 0x0008) - + } SAVE FILES { - + Stats offset 0x308(108 byte entries) 12 byte Name(Trailing 0's) 2 byte Level @@ -781,18 +781,18 @@ SAVE FILES { 2 byte Skill Slots 30 byte ??? 160 byte copy of relevant TB_SPCL.BIN data(including story flags) - + } - + ENEMY FILES { - + AI DATA 0x01 Entry AI 0x06 HP Threshold? AI - + d18_0 - Mottled Spider 0x0000 - Required to properly link enemy data - + 0x0034 - Offset to Enemy Data 0x0038 - Enemy Data Length 0x003C - Offset to Moves Data @@ -801,5 +801,5 @@ ENEMY FILES { 0x0048 - Enemy Data v2 Length 0x004C - Offset to Moves Data v2 0x0050 - Moves Data v2 Length - -} \ No newline at end of file + +} diff --git a/src/G2DataGUI.Common/Data/Maps/Map.cs b/src/G2DataGUI.Common/Data/Maps/Map.cs index b0eca13..c90a45b 100644 --- a/src/G2DataGUI.Common/Data/Maps/Map.cs +++ b/src/G2DataGUI.Common/Data/Maps/Map.cs @@ -10,6 +10,7 @@ public class Map public List Entries { get; set; } = new(); public List Instances { get; set; } = new(); public List HTAs { get; set; } = new(); + public List Scripts { get; set; } = new(); public List EnemyPositions { get; set; } = new(); public List EnemyGroups { get; set; } = new(); public List MOSs { get; set; } = new(); @@ -48,6 +49,12 @@ public static Map ReadMap(FileStream reader, string filepath) map.HTAs.Add(MapHTA.ReadMapHTA(reader)); } + reader.Seek(map.Header.OffsetScripts, SeekOrigin.Begin); + for (var index = 0; index < map.Header.NumScripts; index++) + { + map.Scripts.Add(MapScript.ReadMapScript(reader, index)); + } + reader.Seek(map.Header.OffsetEnemyPos, SeekOrigin.Begin); for (var index = 0; index < map.Header.NumEnemyPos; index++) { @@ -116,11 +123,41 @@ public void WriteMap() hta.WriteMapHTA(writer); } + writer.Seek(Header.OffsetScripts, SeekOrigin.Begin); + foreach (var script in Scripts) + { + script.WriteMapScript(writer); + } + writer.Seek(Header.OffsetEnemyPos, SeekOrigin.Begin); foreach (var position in EnemyPositions) { position.WriteMapEnemyPosition(writer); } + + writer.Seek(Header.OffsetEnemyGroups, SeekOrigin.Begin); + foreach (var group in EnemyGroups) + { + group.WriteMapEnemyGroup(writer); + } + + writer.Seek(Header.OffsetMOS, SeekOrigin.Begin); + foreach (var mos in MOSs) + { + mos.WriteMapMOS(writer); + } + + writer.Seek(Header.OffsetIcons, SeekOrigin.Begin); + foreach (var icon in Icons) + { + icon.WriteMapIcon(writer); + } + + writer.Seek(Header.OffsetShop, SeekOrigin.Begin); + if (Shop != null) + { + Shop.WriteMapShop(writer); + } } /// diff --git a/src/G2DataGUI.Common/Data/Maps/MapMOS.cs b/src/G2DataGUI.Common/Data/Maps/MapMOS.cs index 6bd8d66..ce02215 100644 --- a/src/G2DataGUI.Common/Data/Maps/MapMOS.cs +++ b/src/G2DataGUI.Common/Data/Maps/MapMOS.cs @@ -8,13 +8,17 @@ public class MapMOS { public ushort Id { get; set; } public ushort Index { get; set; } - public int Unknown1 { get; set; } + public byte Unknown1 { get; set; } + public byte Unknown2 { get; set; } + public byte Unknown3 { get; set; } + public byte Unknown4 { get; set; } public Vector3 Position { get; set; } - public int Unknown2 { get; set; } - public int Unknown3 { get; set; } - public int Unknown4 { get; set; } - public int Unknown5 { get; set; } + public short Unknown5 { get; set; } public short Unknown6 { get; set; } + public short Unknown7 { get; set; } + public short Unknown8 { get; set; } + public short Unknown9 { get; set; } + public short Unknown10 { get; set; } public static MapMOS ReadMapMOS(Stream reader) { @@ -22,13 +26,17 @@ public static MapMOS ReadMapMOS(Stream reader) { Id = reader.ReadRawUShort(), Index = reader.ReadRawUShort(), - Unknown1 = reader.ReadRawInt(), + Unknown1 = reader.ReadRawByte(), + Unknown2 = reader.ReadRawByte(), + Unknown3 = reader.ReadRawByte(), + Unknown4 = reader.ReadRawByte(), Position = Vector3.ReadVector3(reader), - Unknown2 = reader.ReadRawInt(), - Unknown3 = reader.ReadRawInt(), - Unknown4 = reader.ReadRawInt(), - Unknown5 = reader.ReadRawInt(), + Unknown5 = reader.ReadRawShort(), Unknown6 = reader.ReadRawShort(), + Unknown7 = reader.ReadRawShort(), + Unknown8 = reader.ReadRawShort(), + Unknown9 = reader.ReadRawShort(), + Unknown10 = reader.ReadRawShort(), }; return mos; @@ -38,12 +46,16 @@ public void WriteMapMOS(Stream writer) { writer.WriteRawUShort(Id); writer.WriteRawUShort(Index); - writer.WriteRawInt(Unknown1); + writer.WriteRawByte(Unknown1); + writer.WriteRawByte(Unknown2); + writer.WriteRawByte(Unknown3); + writer.WriteRawByte(Unknown4); Position.WriteVector3(writer); - writer.WriteRawInt(Unknown2); - writer.WriteRawInt(Unknown3); - writer.WriteRawInt(Unknown4); - writer.WriteRawInt(Unknown5); + writer.WriteRawShort(Unknown5); writer.WriteRawShort(Unknown6); + writer.WriteRawShort(Unknown7); + writer.WriteRawShort(Unknown8); + writer.WriteRawShort(Unknown9); + writer.WriteRawShort(Unknown10); } } diff --git a/src/G2DataGUI.Common/Data/Maps/MapScript.cs b/src/G2DataGUI.Common/Data/Maps/MapScript.cs new file mode 100644 index 0000000..e5479aa --- /dev/null +++ b/src/G2DataGUI.Common/Data/Maps/MapScript.cs @@ -0,0 +1,93 @@ +using System.IO; +using G2DataGUI.Common.Data.Common; +using G2DataGUI.IO.Streams; + +namespace G2DataGUI.Common.Data.Maps; +public class MapScript +{ + // used for UI list + public int Index { get; set; } + + public byte[] Unknown1 { get; set; } + public Vector3 Offset { get; set; } = new(); + public float Direction { get; set; } + public byte TransitionEffect { get; set; } + public byte Unknown2 { get; set; } + public byte Unknown3 { get; set; } + public byte Unknown4 { get; set; } + public short MapID { get; set; } + public short Unknown5 { get; set; } + public byte Unknown6 { get; set; } + public byte Unknown7 { get; set; } + public short Unknown8 { get; set; } + public byte Unknown9 { get; set; } + public byte Unknown10 { get; set; } + public byte Unknown11 { get; set; } + public byte Unknown12 { get; set; } + public byte Unknown13 { get; set; } + public byte Unknown14 { get; set; } + public byte Unknown15 { get; set; } + public byte Unknown16 { get; set; } + public byte Unknown17 { get; set; } + public byte[] Unknown18 { get; set; } + + public static uint Unknown1Length => 40; + public static uint Unknown18Length => 15; + + public static MapScript ReadMapScript(Stream reader, int index) + { + MapScript mapScript = new() + { + Index = index, + Unknown1 = reader.ReadRawByteArray(Unknown1Length), + Offset = Vector3.ReadVector3(reader), + Direction = reader.ReadRawFloat(), + TransitionEffect = reader.ReadRawByte(), + Unknown2 = reader.ReadRawByte(), + Unknown3 = reader.ReadRawByte(), + Unknown4 = reader.ReadRawByte(), + MapID = reader.ReadRawShort(), + Unknown5 = reader.ReadRawShort(), + Unknown6 = reader.ReadRawByte(), + Unknown7 = reader.ReadRawByte(), + Unknown8 = reader.ReadRawShort(), + Unknown9 = reader.ReadRawByte(), + Unknown10 = reader.ReadRawByte(), + Unknown11 = reader.ReadRawByte(), + Unknown12 = reader.ReadRawByte(), + Unknown13 = reader.ReadRawByte(), + Unknown14 = reader.ReadRawByte(), + Unknown15 = reader.ReadRawByte(), + Unknown16 = reader.ReadRawByte(), + Unknown17 = reader.ReadRawByte(), + Unknown18 = reader.ReadRawByteArray(Unknown18Length), + }; + return mapScript; + } + + public void WriteMapScript(Stream writer) + { + writer.WriteRawByteArray(Unknown1); + Offset.WriteVector3(writer); + writer.WriteRawFloat(Direction); + writer.WriteRawByte(TransitionEffect); + writer.WriteRawByte(Unknown2); + writer.WriteRawByte(Unknown3); + writer.WriteRawByte(Unknown4); + writer.WriteRawShort(MapID); + writer.WriteRawShort(Unknown5); + writer.WriteRawByte(Unknown6); + writer.WriteRawByte(Unknown7); + writer.WriteRawShort(Unknown8); + writer.WriteRawByte(Unknown9); + writer.WriteRawByte(Unknown10); + writer.WriteRawByte(Unknown11); + writer.WriteRawByte(Unknown12); + writer.WriteRawByte(Unknown13); + writer.WriteRawByte(Unknown14); + writer.WriteRawByte(Unknown15); + writer.WriteRawByte(Unknown16); + writer.WriteRawByte(Unknown17); + writer.WriteRawByteArray(Unknown18); + } +} diff --git a/src/G2DataGUI/App.axaml.cs b/src/G2DataGUI/App.axaml.cs index 4326684..e96516b 100644 --- a/src/G2DataGUI/App.axaml.cs +++ b/src/G2DataGUI/App.axaml.cs @@ -9,12 +9,9 @@ namespace G2DataGUI; public class App : Application { - public override void Initialize() - { - AvaloniaXamlLoader.Load(this); - } + public override void Initialize() => AvaloniaXamlLoader.Load(this); - public override void OnFrameworkInitializationCompleted() + public override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { @@ -23,4 +20,4 @@ public override void OnFrameworkInitializationCompleted() base.OnFrameworkInitializationCompleted(); } -} \ No newline at end of file +} diff --git a/src/G2DataGUI/UI/ViewModels/MapScriptsViewModel.cs b/src/G2DataGUI/UI/ViewModels/MapScriptsViewModel.cs new file mode 100644 index 0000000..c2d8916 --- /dev/null +++ b/src/G2DataGUI/UI/ViewModels/MapScriptsViewModel.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using G2DataGUI.Common.Data.Maps; +using G2DataGUI.UI.Common.ViewModels; + +namespace G2DataGUI.UI.ViewModels; + +public class MapScriptsViewModel : BaseViewModel +{ + private List _selectedMapScripts = new(); + private int _selectedMapScriptIndex; + private MapScript _selectedMapScriptItem; + + public static MapScriptsViewModel Instance { get; private set; } = new(); + + private MapScriptsViewModel() + { + + } + + public List SelectedMapScripts + { + get => _selectedMapScripts; + set + { + _selectedMapScripts = value == null ? new List() : value; + SelectedMapScriptIndex = 0; + OnPropertyChanged(nameof(SelectedMapScripts)); + OnPropertyChanged(nameof(HasMapScripts)); + OnPropertyChanged(nameof(SelectedMapScriptIndex)); + } + } + + public bool HasMapScripts => SelectedMapScripts.Count > 0; + + public int SelectedMapScriptIndex + { + get => _selectedMapScriptIndex; + set + { + if (value < 0) + { + value = 0; + } + + if (value >= SelectedMapScripts.Count) + { + return; + } + + _selectedMapScriptIndex = value; + SelectedMapScriptItem = SelectedMapScripts[value]; + } + } + + public MapScript SelectedMapScriptItem + { + get => _selectedMapScriptItem; + set + { + _selectedMapScriptItem = value; + OnPropertyChanged(nameof(SelectedMapScriptItem)); + } + } +} diff --git a/src/G2DataGUI/UI/ViewModels/MapsViewModel.cs b/src/G2DataGUI/UI/ViewModels/MapsViewModel.cs index ca07156..f9e5689 100644 --- a/src/G2DataGUI/UI/ViewModels/MapsViewModel.cs +++ b/src/G2DataGUI/UI/ViewModels/MapsViewModel.cs @@ -13,6 +13,7 @@ public sealed class MapsViewModel : BaseViewModel private readonly MapEntriesViewModel _entriesViewModel = MapEntriesViewModel.Instance; private readonly MapInstancesViewModel _instancesViewModel = MapInstancesViewModel.Instance; private readonly MapHTAsViewModel _htaViewModel = MapHTAsViewModel.Instance; + private readonly MapScriptsViewModel _scriptsViewModel = MapScriptsViewModel.Instance; private readonly MapEnemyPositionsViewModel _enemyPositionsViewModel = MapEnemyPositionsViewModel.Instance; private readonly MapEnemyGroupsViewModel _enemyGroupsViewModel = MapEnemyGroupsViewModel.Instance; private readonly MapMOSsViewModel _mosViewModel = MapMOSsViewModel.Instance; @@ -60,6 +61,7 @@ public Map SelectedMapItem _entriesViewModel.SelectedMapEntries = value.Entries; _instancesViewModel.SelectedMapInstances = value.Instances; _htaViewModel.SelectedMapHTAs = value.HTAs; + _scriptsViewModel.SelectedMapScripts = value.Scripts; _enemyPositionsViewModel.SelectedMapEnemyPositions = value.EnemyPositions; _enemyGroupsViewModel.SelectedMapEnemyGroups = value.EnemyGroups; _mosViewModel.SelectedMapMOSs = value.MOSs; diff --git a/src/G2DataGUI/UI/Views/Content/MapMOSs.axaml b/src/G2DataGUI/UI/Views/Content/MapMOSs.axaml index bc3cbda..7f8829d 100644 --- a/src/G2DataGUI/UI/Views/Content/MapMOSs.axaml +++ b/src/G2DataGUI/UI/Views/Content/MapMOSs.axaml @@ -121,16 +121,16 @@ + Minimum="0" + Maximum="256" /> + Minimum="0" + Maximum="256" /> @@ -143,16 +143,16 @@ + Minimum="0" + Maximum="256" /> + Minimum="0" + Maximum="256" /> @@ -165,8 +165,8 @@ + Minimum="-32768" + Maximum="32767" /> @@ -177,6 +177,50 @@ Maximum="32767" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/G2DataGUI/UI/Views/Content/MapScripts.axaml b/src/G2DataGUI/UI/Views/Content/MapScripts.axaml new file mode 100644 index 0000000..835aa53 --- /dev/null +++ b/src/G2DataGUI/UI/Views/Content/MapScripts.axaml @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/G2DataGUI/UI/Views/Content/MapScripts.axaml.cs b/src/G2DataGUI/UI/Views/Content/MapScripts.axaml.cs new file mode 100644 index 0000000..aaa0d00 --- /dev/null +++ b/src/G2DataGUI/UI/Views/Content/MapScripts.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia.Controls; +using G2DataGUI.UI.ViewModels; + +namespace G2DataGUI.UI.Views.Content; + +public partial class MapScripts : UserControl +{ + public MapScripts() + { + DataContext = MapScriptsViewModel.Instance; + InitializeComponent(); + } +} diff --git a/src/G2DataGUI/UI/Views/Content/Maps.axaml b/src/G2DataGUI/UI/Views/Content/Maps.axaml index a9fee07..3686451 100644 --- a/src/G2DataGUI/UI/Views/Content/Maps.axaml +++ b/src/G2DataGUI/UI/Views/Content/Maps.axaml @@ -55,6 +55,7 @@ + @@ -76,6 +77,8 @@ Tag="MapInstancesPage" /> +