diff --git a/README.md b/README.md
index 1614ef7e..61150281 100644
--- a/README.md
+++ b/README.md
@@ -8,8 +8,8 @@
`Parsec` is a simple .NET parsing library for `Shaiya` file formats which provides easy to use APIs
for serialization and deserialization of the game's file formats, including JSON and CSV support.
-Parsec works on any .NET Standard 2.0 compliant platform, including .NET 7.0, .NET Framework 4.6.1+, .NET Core 2.0+,
-Unity's Mono and Godot.
+Parsec works on any .NET Standard 2.0 compliant platform, including .NET 5+, .NET Framework 4.6.1+, .NET Core 2.0+,
+Unity and Godot.
## Supported file formats
@@ -26,6 +26,7 @@ Unity's Mono and Godot.
- `NpcSkill.SData`
- `svmap`
- `WLD`
+- `dg`
- `ANI`
- `3DC`
- `3DO`
@@ -72,7 +73,7 @@ might not work with them.
### Prerequisites
-- `.NET 7 SDK (recommended)` or any `.NET Standard 2.0` compliant platform
+- `.NET 8 SDK (recommended)` or any `.NET Standard 2.0` compliant platform
## Documentation
diff --git a/samples/Data/Sample.Data.csproj b/samples/Data/Sample.Data.csproj
index 1717dd1b..20c36da8 100644
--- a/samples/Data/Sample.Data.csproj
+++ b/samples/Data/Sample.Data.csproj
@@ -2,8 +2,7 @@
Exe
- net7.0
- 10
+ net8.0
diff --git a/samples/Files/Program.cs b/samples/Files/Program.cs
index 46fee6d6..1507e80c 100644
--- a/samples/Files/Program.cs
+++ b/samples/Files/Program.cs
@@ -1,6 +1,6 @@
-using Parsec;
-using Parsec.Shaiya.SData;
-using Parsec.Shaiya.Skill;
+using System;
+using Parsec;
+using Parsec.Shaiya.Svmap;
namespace Sample.Files;
@@ -8,12 +8,27 @@ internal static class Program
{
private static void Main(string[] args)
{
- SData.DecryptFile("/home/matias/Desktop/DBSkillData.SData", "/home/matias/Desktop/DBSkillData.dec.SData");
+ // This sample shows how you can convert a shaiya file format (in this case svmap) into json to be able to
+ // edit its properties as plain text, and then, convert it back to its original format
- var skillData = ParsecReader.FromFile("/home/matias/Desktop/DBSkillData.dec.SData");
+ // Step 1: Read a svmap from a file
+ var svmap = ParsecReader.FromFile("2.svmap");
- skillData.Write("/home/matias/Desktop/DBSkillData.dec.new.SData");
+ // You can go through and modify its properties here too
+ foreach (var npc in svmap.Npcs)
+ {
+ Console.WriteLine($"NpcId: {npc.NpcId}, Type: {npc.NpcType}");
+ }
- var newSkillData = ParsecReader.FromFile("/home/matias/Desktop/DBSkillData.dec.new.SData");
+ // Step 2: Export svmap as JSON
+ svmap.WriteJson("2.svmap.json");
+
+ // Step 3: Modify the json file in any text editor
+
+ // Step 4: Read svmap from the modified JSON file
+ var svmapFromJson = ParsecReader.FromJsonFile("2.svmap.json");
+
+ // Step 5: Write the edited instance as .svmap
+ svmapFromJson.Write("2.edited.svmap");
}
}
diff --git a/samples/Files/Sample.Files.csproj b/samples/Files/Sample.Files.csproj
index 70c68f19..8be3be82 100644
--- a/samples/Files/Sample.Files.csproj
+++ b/samples/Files/Sample.Files.csproj
@@ -2,8 +2,7 @@
Exe
- net7.0
- 10
+ net8.0
Sample.Files
diff --git a/samples/Godot/Mob_Elk_01.3DC b/samples/Godot/Mob_Elk_01.3DC
deleted file mode 100644
index 631b383c..00000000
Binary files a/samples/Godot/Mob_Elk_01.3DC and /dev/null differ
diff --git a/samples/Godot/Mob_Elk_01.dds b/samples/Godot/Mob_Elk_01.dds
deleted file mode 100644
index 16663859..00000000
Binary files a/samples/Godot/Mob_Elk_01.dds and /dev/null differ
diff --git a/samples/Godot/README.md b/samples/Godot/README.md
deleted file mode 100644
index 153d4e38..00000000
--- a/samples/Godot/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Parsec Godot Sample
-This sample illustrates how Parsec can be used to load Shaiya assets into a `Godot` project.
-
-## Prerequisites
-- `Godot 3 (Mono Version)`
-
-## Usage
-Camera movement is done via the [Simple Free-Look Camera](https://godotengine.org/asset-library/asset/701) asset.
-
-Use **W** and **S** to move forward and backward.
-
-Use **A** and **D** to move left and right.
-
-Use **Q** and **E** to move up and down.
-
-Roll the **scroll wheel** to increase and decrease movement speed.
-
-Hold down the **right mouse button** to rotate the camera.
\ No newline at end of file
diff --git a/samples/Godot/Scene.tscn b/samples/Godot/Scene.tscn
deleted file mode 100644
index a1ed3982..00000000
--- a/samples/Godot/Scene.tscn
+++ /dev/null
@@ -1,27 +0,0 @@
-[gd_scene load_steps=5 format=2]
-
-[ext_resource path="res://ShaiyaMeshInstance.cs" type="Script" id=1]
-[ext_resource path="res://camera.gd" type="Script" id=2]
-[ext_resource path="res://default_env.tres" type="Environment" id=5]
-
-[sub_resource type="ArrayMesh" id=1]
-
-[node name="Spatial" type="Spatial"]
-
-[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
-environment = ExtResource( 5 )
-
-[node name="DirectionalLight" type="DirectionalLight" parent="WorldEnvironment"]
-transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.65182, 2.90436, -3.64679 )
-shadow_enabled = true
-shadow_bias = 0.0
-directional_shadow_mode = 0
-directional_shadow_max_distance = 40.0
-
-[node name="MeshInstance" type="MeshInstance" parent="."]
-mesh = SubResource( 1 )
-script = ExtResource( 1 )
-
-[node name="Camera" type="Camera" parent="."]
-transform = Transform( -0.00188498, 0, 0.999998, 0, 1, 0, -0.999998, 0, -0.00188498, 2.94621, 0.445381, -0.262532 )
-script = ExtResource( 2 )
diff --git a/samples/Godot/Shaiya.png b/samples/Godot/Shaiya.png
deleted file mode 100644
index 8c7f272d..00000000
Binary files a/samples/Godot/Shaiya.png and /dev/null differ
diff --git a/samples/Godot/ShaiyaGodotProject.csproj b/samples/Godot/ShaiyaGodotProject.csproj
deleted file mode 100644
index 12e11cd2..00000000
--- a/samples/Godot/ShaiyaGodotProject.csproj
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- net472
- ShaiyaGodotProject
-
-
-
-
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
-
diff --git a/samples/Godot/ShaiyaGodotProject.sln b/samples/Godot/ShaiyaGodotProject.sln
deleted file mode 100644
index 12d2f0be..00000000
--- a/samples/Godot/ShaiyaGodotProject.sln
+++ /dev/null
@@ -1,27 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShaiyaGodotProject", "ShaiyaGodotProject.csproj", "{6D73B1F4-0EE8-49B1-BFB3-E221D28FB500}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Parsec", "..\..\src\Parsec\Parsec.csproj", "{290EBC41-B130-4B73-9FA8-EC71A3190280}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- ExportDebug|Any CPU = ExportDebug|Any CPU
- ExportRelease|Any CPU = ExportRelease|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6D73B1F4-0EE8-49B1-BFB3-E221D28FB500}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6D73B1F4-0EE8-49B1-BFB3-E221D28FB500}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6D73B1F4-0EE8-49B1-BFB3-E221D28FB500}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
- {6D73B1F4-0EE8-49B1-BFB3-E221D28FB500}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
- {6D73B1F4-0EE8-49B1-BFB3-E221D28FB500}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
- {6D73B1F4-0EE8-49B1-BFB3-E221D28FB500}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
- {290EBC41-B130-4B73-9FA8-EC71A3190280}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {290EBC41-B130-4B73-9FA8-EC71A3190280}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {290EBC41-B130-4B73-9FA8-EC71A3190280}.ExportDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {290EBC41-B130-4B73-9FA8-EC71A3190280}.ExportDebug|Any CPU.Build.0 = Debug|Any CPU
- {290EBC41-B130-4B73-9FA8-EC71A3190280}.ExportRelease|Any CPU.ActiveCfg = Debug|Any CPU
- {290EBC41-B130-4B73-9FA8-EC71A3190280}.ExportRelease|Any CPU.Build.0 = Debug|Any CPU
- EndGlobalSection
-EndGlobal
diff --git a/samples/Godot/ShaiyaMeshInstance.cs b/samples/Godot/ShaiyaMeshInstance.cs
deleted file mode 100644
index ec2264ab..00000000
--- a/samples/Godot/ShaiyaMeshInstance.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using System.Linq;
-using Godot;
-using Godot.Collections;
-using Parsec;
-using Parsec.Shaiya._3DC;
-
-namespace ShaiyaGodotProject
-{
- public class ShaiyaMeshInstance : MeshInstance
- {
- private string _3dcPath = "Mob_Elk_01.3DC";
- private string _ddsPath = "Mob_Elk_01.dds";
-
- public override void _Ready()
- {
- var obj = Reader.ReadFromFile<_3DC>(_3dcPath);
-
- var surfaceArray = new Array();
- surfaceArray.Resize((int)ArrayMesh.ArrayType.Max);
-
- var vertices = new Array();
- var uvs = new Array();
- var normals = new Array();
- var indices = new Array();
-
- foreach (var vertex in obj.Vertices)
- {
- vertices.Add(new Vector3(vertex.Coordinates.X, vertex.Coordinates.Y, vertex.Coordinates.Z));
- normals.Add(new Vector3(vertex.Normal.X, vertex.Normal.Y, vertex.Normal.Z));
- uvs.Add(new Vector2(vertex.UV.X, vertex.UV.Y));
- }
-
- foreach (var face in obj.Faces)
- {
- indices.Add(face.VertexIndex1);
- indices.Add(face.VertexIndex3);
- indices.Add(face.VertexIndex2);
- }
-
- surfaceArray[(int)Mesh.ArrayType.Vertex] = vertices.ToArray();
- surfaceArray[(int)Mesh.ArrayType.TexUv] = uvs.ToArray();
- surfaceArray[(int)Mesh.ArrayType.Normal] = normals.ToArray();
- surfaceArray[(int)Mesh.ArrayType.Index] = indices.ToArray();
-
- var arrayMesh = new ArrayMesh();
- arrayMesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, surfaceArray);
- Mesh = arrayMesh;
-
- var texture = GD.Load(_ddsPath);
- var material = new SpatialMaterial
- {
- AlbedoTexture = texture
- };
-
- MaterialOverride = material;
- }
- }
-}
diff --git a/samples/Godot/camera.gd b/samples/Godot/camera.gd
deleted file mode 100644
index 9adf3482..00000000
--- a/samples/Godot/camera.gd
+++ /dev/null
@@ -1,106 +0,0 @@
-extends Camera
-
-export(float, 0.0, 1.0) var sensitivity = 0.25
-
-# Mouse state
-var _mouse_position = Vector2(0.0, 0.0)
-var _total_pitch = 0.0
-
-# Movement state
-var _direction = Vector3(0.0, 0.0, 0.0)
-var _velocity = Vector3(0.0, 0.0, 0.0)
-var _acceleration = 30
-var _deceleration = -10
-var _vel_multiplier = 4
-
-# Keyboard state
-var _w = false
-var _s = false
-var _a = false
-var _d = false
-var _q = false
-var _e = false
-
-
-func _input(event):
- # Receives mouse motion
- if event is InputEventMouseMotion:
- _mouse_position = event.relative
-
- # Receives mouse button input
- if event is InputEventMouseButton:
- match event.button_index:
- BUTTON_RIGHT: # Only allows rotation if right click down
- Input.set_mouse_mode(
- Input.MOUSE_MODE_CAPTURED if event.pressed else Input.MOUSE_MODE_VISIBLE
- )
- BUTTON_WHEEL_UP: # Increases max velocity
- _vel_multiplier = clamp(_vel_multiplier * 1.1, 0.2, 20)
- BUTTON_WHEEL_DOWN: # Decereases max velocity
- _vel_multiplier = clamp(_vel_multiplier / 1.1, 0.2, 20)
-
- # Receives key input
- if event is InputEventKey:
- match event.scancode:
- KEY_W:
- _w = event.pressed
- KEY_S:
- _s = event.pressed
- KEY_A:
- _a = event.pressed
- KEY_D:
- _d = event.pressed
- KEY_Q:
- _q = event.pressed
- KEY_E:
- _e = event.pressed
-
-
-# Updates mouselook and movement every frame
-func _process(delta):
- _update_mouselook()
- _update_movement(delta)
-
-
-# Updates camera movement
-func _update_movement(delta):
- # Computes desired direction from key states
- _direction = Vector3(
- _d as float - _a as float, _e as float - _q as float, _s as float - _w as float
- )
-
- # Computes the change in velocity due to desired direction and "drag"
- # The "drag" is a constant acceleration on the camera to bring it's velocity to 0
- var offset = (
- _direction.normalized() * _acceleration * _vel_multiplier * delta
- + _velocity.normalized() * _deceleration * _vel_multiplier * delta
- )
-
- # Checks if we should bother translating the camera
- if _direction == Vector3.ZERO and offset.length_squared() > _velocity.length_squared():
- # Sets the velocity to 0 to prevent jittering due to imperfect deceleration
- _velocity = Vector3.ZERO
- else:
- # Clamps speed to stay within maximum value (_vel_multiplier)
- _velocity.x = clamp(_velocity.x + offset.x, -_vel_multiplier, _vel_multiplier)
- _velocity.y = clamp(_velocity.y + offset.y, -_vel_multiplier, _vel_multiplier)
- _velocity.z = clamp(_velocity.z + offset.z, -_vel_multiplier, _vel_multiplier)
-
- translate(_velocity * delta)
-
-
-# Updates mouse look
-func _update_mouselook():
- # Only rotates mouse if the mouse is captured
- if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
- _mouse_position *= sensitivity
- var yaw = _mouse_position.x
- var pitch = _mouse_position.y
- _mouse_position = Vector2(0, 0)
-
- # Prevents looking up/down too far
- pitch = clamp(pitch, -90 - _total_pitch, 90 - _total_pitch)
- _total_pitch += pitch
-
- rotate_y(deg2rad(-yaw))
- rotate_object_local(Vector3(1, 0, 0), deg2rad(-pitch))
diff --git a/samples/Godot/default_env.tres b/samples/Godot/default_env.tres
deleted file mode 100644
index 94d8fe64..00000000
--- a/samples/Godot/default_env.tres
+++ /dev/null
@@ -1,11 +0,0 @@
-[gd_resource type="Environment" load_steps=2 format=2]
-
-[sub_resource type="ProceduralSky" id=1]
-
-[resource]
-background_mode = 3
-background_sky = SubResource( 1 )
-background_color = Color( 0.866667, 0.866667, 0.866667, 1 )
-background_energy = 1.5
-tonemap_mode = 2
-tonemap_white = 6.0
diff --git a/samples/Godot/project.godot b/samples/Godot/project.godot
deleted file mode 100644
index 496c5492..00000000
--- a/samples/Godot/project.godot
+++ /dev/null
@@ -1,32 +0,0 @@
-; Engine configuration file.
-; It's best edited using the editor UI and not directly,
-; since the parameters that go here are not all obvious.
-;
-; Format:
-; [section] ; section goes between []
-; param=value ; assign values to parameters
-
-config_version=4
-
-[application]
-
-config/name="ShaiyaGodotProject"
-run/main_scene="res://Scene.tscn"
-boot_splash/bg_color=Color( 0.141176, 0.141176, 0.141176, 1 )
-config/icon="res://Shaiya.png"
-
-[gui]
-
-common/drop_mouse_on_gui_input_disabled=true
-
-[mono]
-
-project/assembly_name="ShaiyaGodotProject"
-
-[physics]
-
-common/enable_pause_aware_picking=true
-
-[rendering]
-
-environment/default_environment="res://default_env.tres"
diff --git a/samples/SData/Sample.SData.csproj b/samples/SData/Sample.SData.csproj
index e336a48a..2672bebd 100644
--- a/samples/SData/Sample.SData.csproj
+++ b/samples/SData/Sample.SData.csproj
@@ -2,8 +2,7 @@
Exe
- net7.0
- 10
+ net8.0
diff --git a/src/Parsec/Common/Episode.cs b/src/Parsec/Common/Episode.cs
index 38741b3c..e9e1c0fb 100644
--- a/src/Parsec/Common/Episode.cs
+++ b/src/Parsec/Common/Episode.cs
@@ -2,10 +2,17 @@
public enum Episode
{
- Unknown,
- EP4,
- EP5,
- EP6,
- EP7,
- EP8
+ Unknown = 0,
+
+ EP4 = 40,
+
+ EP5 = 50,
+
+ EP6 = 60,
+
+ EP6_4 = 64,
+
+ EP7 = 70,
+
+ EP8 = 80
}
diff --git a/src/Parsec/Parsec.csproj b/src/Parsec/Parsec.csproj
index 6573c81e..7d7b749f 100644
--- a/src/Parsec/Parsec.csproj
+++ b/src/Parsec/Parsec.csproj
@@ -4,24 +4,24 @@
10
AnyCPU;x86
true
- 1.0.1
+ 1.1.1
Matias Ramirez
- Matias Ramirez 2022
+ Matias Ramirez 2021
https://github.com/matigramirez/Parsec
https://github.com/matigramirez/Parsec
csharp, shaiya, file, parser, dotnet
Parsec is a simple file parsing library for Shaiya file formats built with C# and .NET Standard 2.0. Its goal is to make reading and manipulating the game's file formats with ease.
false
- netstandard2.0;net6.0;net7.0
+ netstandard2.0;net6.0;net7.0;net8.0
true
enable
-
+
-
+
diff --git a/src/Parsec/Serialization/SBinaryReader.cs b/src/Parsec/Serialization/SBinaryReader.cs
index a19799f5..68f7449b 100644
--- a/src/Parsec/Serialization/SBinaryReader.cs
+++ b/src/Parsec/Serialization/SBinaryReader.cs
@@ -46,6 +46,11 @@ public void ResetBuffer(byte[] buffer)
_binaryReader = new BinaryReader(memoryStream);
}
+ ///
+ /// Current position in the stream
+ ///
+ public long Position => _binaryReader.BaseStream.Position;
+
///
/// Length of the stream
///
diff --git a/src/Parsec/Shaiya/Cash/CashProduct.cs b/src/Parsec/Shaiya/Cash/CashProduct.cs
index 7ab9a7d4..b7ea702b 100644
--- a/src/Parsec/Shaiya/Cash/CashProduct.cs
+++ b/src/Parsec/Shaiya/Cash/CashProduct.cs
@@ -10,7 +10,7 @@ public sealed class CashProduct : ISerializable
public uint Bag { get; set; }
- public uint Unknown { get; set; }
+ public uint Icon { get; set; }
public uint Cost { get; set; }
@@ -26,7 +26,7 @@ public void Read(SBinaryReader binaryReader)
{
Index = binaryReader.ReadUInt32();
Bag = binaryReader.ReadUInt32();
- Unknown = binaryReader.ReadUInt32();
+ Icon = binaryReader.ReadUInt32();
Cost = binaryReader.ReadUInt32();
Items = binaryReader.ReadList(24).ToList();
ProductName = binaryReader.ReadString();
@@ -43,7 +43,7 @@ public void Write(SBinaryWriter binaryWriter)
{
binaryWriter.Write(Index);
binaryWriter.Write(Bag);
- binaryWriter.Write(Unknown);
+ binaryWriter.Write(Icon);
binaryWriter.Write(Cost);
binaryWriter.Write(Items.Take(24).ToSerializable(), lengthPrefixed: false);
diff --git a/src/Parsec/Shaiya/Common/BoundingBox.cs b/src/Parsec/Shaiya/Common/BoundingBox.cs
index cea198f0..ef400363 100644
--- a/src/Parsec/Shaiya/Common/BoundingBox.cs
+++ b/src/Parsec/Shaiya/Common/BoundingBox.cs
@@ -1,4 +1,5 @@
-using Parsec.Serialization;
+using Newtonsoft.Json;
+using Parsec.Serialization;
using Parsec.Shaiya.Core;
namespace Parsec.Shaiya.Common;
@@ -19,6 +20,7 @@ public struct BoundingBox : ISerializable
///
public Vector3 UpperLimit { get; set; }
+ [JsonIgnore]
public double Radius
{
get
diff --git a/src/Parsec/Shaiya/Common/String256.cs b/src/Parsec/Shaiya/Common/String256.cs
index 1ac276d0..d92e7353 100644
--- a/src/Parsec/Shaiya/Common/String256.cs
+++ b/src/Parsec/Shaiya/Common/String256.cs
@@ -1,4 +1,5 @@
using System.Text;
+using Newtonsoft.Json;
using Parsec.Serialization;
using Parsec.Shaiya.Core;
@@ -8,6 +9,7 @@ public sealed class String256 : ISerializable
{
public string Value { get; set; } = string.Empty;
+ [JsonIgnore]
public char PaddingChar { get; set; } = '\0';
public void Read(SBinaryReader binaryReader)
diff --git a/src/Parsec/Shaiya/Common/Vector2.cs b/src/Parsec/Shaiya/Common/Vector2.cs
index 8cd94336..52249ca2 100644
--- a/src/Parsec/Shaiya/Common/Vector2.cs
+++ b/src/Parsec/Shaiya/Common/Vector2.cs
@@ -38,6 +38,7 @@ public void Write(SBinaryWriter binaryWriter)
binaryWriter.Write(Y);
}
+ [JsonIgnore]
public double Length => Math.Sqrt(X * X + Y * Y);
public static Vector2 operator +(Vector2 vec1, Vector2 vec2) => new(vec1.X + vec2.X, vec1.Y + vec2.Y);
diff --git a/src/Parsec/Shaiya/Common/Vector3.cs b/src/Parsec/Shaiya/Common/Vector3.cs
index 949a3a1f..4ca79865 100644
--- a/src/Parsec/Shaiya/Common/Vector3.cs
+++ b/src/Parsec/Shaiya/Common/Vector3.cs
@@ -46,6 +46,7 @@ public void Write(SBinaryWriter binaryWriter)
binaryWriter.Write(Z);
}
+ [JsonIgnore]
public double Length => Math.Sqrt(X * X + Y * Y + Z * Z);
public static Vector3 operator +(Vector3 vec1, Vector3 vec2) => new(vec1.X + vec2.X, vec1.Y + vec2.Y, vec1.Z + vec2.Z);
diff --git a/src/Parsec/Shaiya/Dg/Dg.cs b/src/Parsec/Shaiya/Dg/Dg.cs
new file mode 100644
index 00000000..8c16e6c9
--- /dev/null
+++ b/src/Parsec/Shaiya/Dg/Dg.cs
@@ -0,0 +1,66 @@
+using Parsec.Extensions;
+using Parsec.Serialization;
+using Parsec.Shaiya.Common;
+using Parsec.Shaiya.Core;
+
+namespace Parsec.Shaiya.Dg;
+
+public class Dg : FileBase
+{
+ public BoundingBox BoundingBox { get; set; }
+
+ public List TextureNames { get; set; } = new();
+
+ public int UnknownInt32 { get; set; }
+
+ public List Nodes { get; set; } = new();
+
+ public override string Extension => "dg";
+
+ protected override void Read(SBinaryReader binaryReader)
+ {
+ BoundingBox = binaryReader.Read();
+ TextureNames = binaryReader.ReadList().ToList();
+ UnknownInt32 = binaryReader.ReadInt32();
+
+ while (true)
+ {
+ if (binaryReader.Position == binaryReader.StreamLength)
+ {
+ break;
+ }
+
+ // When value is 1, node data follows, otherwise node reading must be skipped
+ var value = binaryReader.ReadInt32();
+
+ if (value > 0)
+ {
+ var node = binaryReader.Read();
+ Nodes.Add(node);
+ }
+ else
+ {
+ Nodes.Add(null);
+ }
+ }
+ }
+
+ protected override void Write(SBinaryWriter binaryWriter)
+ {
+ binaryWriter.Write(BoundingBox);
+ binaryWriter.Write(TextureNames.ToSerializable());
+ binaryWriter.Write(UnknownInt32);
+
+ foreach (var node in Nodes)
+ {
+ if (node == null)
+ {
+ binaryWriter.Write(0);
+ continue;
+ }
+
+ binaryWriter.Write(1);
+ binaryWriter.Write(node);
+ }
+ }
+}
diff --git a/src/Parsec/Shaiya/Dg/DgCollisionMesh.cs b/src/Parsec/Shaiya/Dg/DgCollisionMesh.cs
new file mode 100644
index 00000000..05e7b0c5
--- /dev/null
+++ b/src/Parsec/Shaiya/Dg/DgCollisionMesh.cs
@@ -0,0 +1,31 @@
+using Parsec.Extensions;
+using Parsec.Serialization;
+using Parsec.Shaiya.Common;
+using Parsec.Shaiya.Core;
+
+namespace Parsec.Shaiya.Dg;
+
+public class DgCollisionMesh : ISerializable
+{
+ ///
+ /// Vertices of the 3d object.
+ ///
+ public List Vertices { get; set; } = new();
+
+ ///
+ /// Triangular faces (polygons) of the 3d object.
+ ///
+ public List Faces { get; set; } = new();
+
+ public void Read(SBinaryReader binaryReader)
+ {
+ Vertices = binaryReader.ReadList().ToList();
+ Faces = binaryReader.ReadList().ToList();
+ }
+
+ public void Write(SBinaryWriter binaryWriter)
+ {
+ binaryWriter.Write(Vertices.ToSerializable());
+ binaryWriter.Write(Faces.ToSerializable());
+ }
+}
diff --git a/src/Parsec/Shaiya/Dg/DgCollisionMeshVertex.cs b/src/Parsec/Shaiya/Dg/DgCollisionMeshVertex.cs
new file mode 100644
index 00000000..47046f0c
--- /dev/null
+++ b/src/Parsec/Shaiya/Dg/DgCollisionMeshVertex.cs
@@ -0,0 +1,26 @@
+using Parsec.Serialization;
+using Parsec.Shaiya.Common;
+using Parsec.Shaiya.Core;
+
+namespace Parsec.Shaiya.Dg;
+
+///
+/// Represents a vertex used in DG collision objects
+///
+public sealed class DgCollisionMeshVertex : ISerializable
+{
+ ///
+ /// Coordinates of the vertex in the 3D space.
+ ///
+ public Vector3 Coordinates { get; set; }
+
+ public void Read(SBinaryReader binaryReader)
+ {
+ Coordinates = binaryReader.Read();
+ }
+
+ public void Write(SBinaryWriter binaryWriter)
+ {
+ binaryWriter.Write(Coordinates);
+ }
+}
diff --git a/src/Parsec/Shaiya/Dg/DgMesh.cs b/src/Parsec/Shaiya/Dg/DgMesh.cs
new file mode 100644
index 00000000..c5bde923
--- /dev/null
+++ b/src/Parsec/Shaiya/Dg/DgMesh.cs
@@ -0,0 +1,29 @@
+using Parsec.Extensions;
+using Parsec.Serialization;
+using Parsec.Shaiya.Common;
+using Parsec.Shaiya.Core;
+
+namespace Parsec.Shaiya.Dg;
+
+public class DgMesh : ISerializable
+{
+ public AlphaBlendingMode AlphaBlendingMode { get; set; }
+
+ public List Vertices { get; set; } = new();
+
+ public List Faces { get; set; } = new();
+
+ public void Read(SBinaryReader binaryReader)
+ {
+ AlphaBlendingMode = (AlphaBlendingMode)binaryReader.ReadInt32();
+ Vertices = binaryReader.ReadList().ToList();
+ Faces = binaryReader.ReadList().ToList();
+ }
+
+ public void Write(SBinaryWriter binaryWriter)
+ {
+ binaryWriter.Write((int)AlphaBlendingMode);
+ binaryWriter.Write(Vertices.ToSerializable());
+ binaryWriter.Write(Faces.ToSerializable());
+ }
+}
diff --git a/src/Parsec/Shaiya/Dg/DgMeshCollisionType.cs b/src/Parsec/Shaiya/Dg/DgMeshCollisionType.cs
new file mode 100644
index 00000000..875d9b66
--- /dev/null
+++ b/src/Parsec/Shaiya/Dg/DgMeshCollisionType.cs
@@ -0,0 +1,7 @@
+namespace Parsec.Shaiya.Dg;
+
+public enum DgMeshCollisionType
+{
+ Transparent = 0,
+ Collision = 1
+}
diff --git a/src/Parsec/Shaiya/Dg/DgMeshVertex.cs b/src/Parsec/Shaiya/Dg/DgMeshVertex.cs
new file mode 100644
index 00000000..cc2d82bd
--- /dev/null
+++ b/src/Parsec/Shaiya/Dg/DgMeshVertex.cs
@@ -0,0 +1,51 @@
+using Parsec.Serialization;
+using Parsec.Shaiya.Common;
+using Parsec.Shaiya.Core;
+
+namespace Parsec.Shaiya.Dg;
+
+public class DgMeshVertex : ISerializable
+{
+ ///
+ /// Vertex coordinates in the 3D space
+ ///
+ public Vector3 Coordinates { get; set; }
+
+ ///
+ /// Vertex normal used for lighting
+ ///
+ public Vector3 Normal { get; set; }
+
+ ///
+ /// SMODs don't have bones, that's why this value is always -1.
+ ///
+ public int BoneId { get; set; } = -1;
+
+ ///
+ /// Texture mapping
+ ///
+ public Vector2 TextureUV { get; set; }
+
+ ///
+ /// Lightmap mapping
+ ///
+ public Vector2 LightmapUV { get; set; }
+
+ public void Read(SBinaryReader binaryReader)
+ {
+ Coordinates = binaryReader.Read();
+ Normal = binaryReader.Read();
+ BoneId = binaryReader.ReadInt32();
+ TextureUV = binaryReader.Read();
+ LightmapUV = binaryReader.Read();
+ }
+
+ public void Write(SBinaryWriter binaryWriter)
+ {
+ binaryWriter.Write(Coordinates);
+ binaryWriter.Write(Normal);
+ binaryWriter.Write(BoneId);
+ binaryWriter.Write(TextureUV);
+ binaryWriter.Write(LightmapUV);
+ }
+}
diff --git a/src/Parsec/Shaiya/Dg/DgNode.cs b/src/Parsec/Shaiya/Dg/DgNode.cs
new file mode 100644
index 00000000..92b1293c
--- /dev/null
+++ b/src/Parsec/Shaiya/Dg/DgNode.cs
@@ -0,0 +1,55 @@
+using Parsec.Extensions;
+using Parsec.Serialization;
+using Parsec.Shaiya.Common;
+using Parsec.Shaiya.Core;
+
+namespace Parsec.Shaiya.Dg;
+
+public class DgNode : ISerializable
+{
+ // TODO: Check
+ public Vector3 Center { get; set; }
+
+ // TODO: Check
+ public BoundingBox ViewBox { get; set; }
+
+ // TODO: Check
+ public BoundingBox CollisionBox { get; set; }
+
+ public List Objects { get; set; } = new();
+
+ public DgMeshCollisionType CollisionType { get; set; }
+
+ public DgCollisionMesh CollisionMesh { get; set; } = new();
+
+ public void Read(SBinaryReader binaryReader)
+ {
+ Center = binaryReader.Read();
+ ViewBox = binaryReader.Read();
+ CollisionBox = binaryReader.Read();
+
+ Objects = binaryReader.ReadList().ToList();
+
+ CollisionType = (DgMeshCollisionType)binaryReader.ReadInt32();
+
+ if (CollisionType == DgMeshCollisionType.Collision)
+ {
+ // Read extra node info
+ CollisionMesh = binaryReader.Read();
+ }
+ }
+
+ public void Write(SBinaryWriter binaryWriter)
+ {
+ binaryWriter.Write(Center);
+ binaryWriter.Write(ViewBox);
+ binaryWriter.Write(CollisionBox);
+ binaryWriter.Write(Objects.ToSerializable());
+ binaryWriter.Write((int)CollisionType);
+
+ if (CollisionType == DgMeshCollisionType.Collision)
+ {
+ binaryWriter.Write(CollisionMesh);
+ }
+ }
+}
diff --git a/src/Parsec/Shaiya/Dg/DgObject.cs b/src/Parsec/Shaiya/Dg/DgObject.cs
new file mode 100644
index 00000000..354f9198
--- /dev/null
+++ b/src/Parsec/Shaiya/Dg/DgObject.cs
@@ -0,0 +1,24 @@
+using Parsec.Extensions;
+using Parsec.Serialization;
+using Parsec.Shaiya.Core;
+
+namespace Parsec.Shaiya.Dg;
+
+public class DgObject : ISerializable
+{
+ public int TextureIndex { get; set; }
+
+ public List Meshes { get; set; } = new();
+
+ public void Read(SBinaryReader binaryReader)
+ {
+ TextureIndex = binaryReader.ReadInt32();
+ Meshes = binaryReader.ReadList().ToList();
+ }
+
+ public void Write(SBinaryWriter binaryWriter)
+ {
+ binaryWriter.Write(TextureIndex);
+ binaryWriter.Write(Meshes.ToSerializable());
+ }
+}
diff --git a/src/Parsec/Shaiya/DualLayerClothes/DualLayerClothes.cs b/src/Parsec/Shaiya/DualLayerClothes/DualLayerClothes.cs
index 22c5b8a8..f5117680 100644
--- a/src/Parsec/Shaiya/DualLayerClothes/DualLayerClothes.cs
+++ b/src/Parsec/Shaiya/DualLayerClothes/DualLayerClothes.cs
@@ -1,9 +1,13 @@
-using Parsec.Extensions;
+using System.Globalization;
+using System.Text;
+using CsvHelper;
+using Parsec.Common;
+using Parsec.Extensions;
using Parsec.Serialization;
namespace Parsec.Shaiya.DualLayerClothes;
-public sealed class DualLayerClothes : SData.SData
+public sealed class DualLayerClothes : SData.SData, ICsv
{
public List Records { get; set; } = new();
@@ -16,4 +20,28 @@ protected override void Write(SBinaryWriter binaryWriter)
{
binaryWriter.Write(Records.ToSerializable());
}
+
+ public static DualLayerClothes FromCsv(string csvPath, Encoding? encoding = null)
+ {
+ encoding ??= Encoding.ASCII;
+
+ using var reader = new StreamReader(csvPath, encoding);
+ using var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture);
+ var records = csvReader.GetRecords().ToList();
+
+ var dualLayerClothes = new DualLayerClothes
+ {
+ Records = records
+ };
+
+ return dualLayerClothes;
+ }
+
+ public void WriteCsv(string outputPath, Encoding? encoding = null)
+ {
+ encoding ??= Encoding;
+ using var writer = new StreamWriter(outputPath, false, encoding);
+ using var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture);
+ csvWriter.WriteRecords(Records);
+ }
}
diff --git a/src/Parsec/Shaiya/Item/Item.cs b/src/Parsec/Shaiya/Item/Item.cs
index a4e4b5f2..a4fe7eef 100644
--- a/src/Parsec/Shaiya/Item/Item.cs
+++ b/src/Parsec/Shaiya/Item/Item.cs
@@ -30,6 +30,11 @@ protected override void Write(SBinaryWriter binaryWriter)
/// instance
public static Item FromCsv(string csvPath, Episode episode, Encoding? encoding = null)
{
+ if (episode >= Episode.EP8)
+ {
+ throw new Exception("Item format is not supported for EP8 and above, use ItemData instead.");
+ }
+
encoding ??= Encoding.ASCII;
// Read item definitions from csv
@@ -60,7 +65,7 @@ public static Item FromCsv(string csvPath, Episode episode, Encoding? encoding =
public void WriteCsv(string outputPath, Encoding? encoding = null)
{
- encoding = Encoding;
+ encoding ??= Encoding;
using var writer = new StreamWriter(outputPath, false, encoding);
using var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture);
diff --git a/src/Parsec/Shaiya/Item/ItemDefinition.cs b/src/Parsec/Shaiya/Item/ItemDefinition.cs
index 9858d8e3..ce591f26 100644
--- a/src/Parsec/Shaiya/Item/ItemDefinition.cs
+++ b/src/Parsec/Shaiya/Item/ItemDefinition.cs
@@ -55,12 +55,10 @@ public sealed class ItemDefinition : ISerializable
public ushort ReqWis { get; set; }
- public ushort ReqLuc { get; set; }
+ public uint ReqLuc { get; set; }
public ushort ReqVg { get; set; }
- public ushort Unknown { get; set; }
-
public byte ReqOg { get; set; }
public byte ReqIg { get; set; }
@@ -185,18 +183,20 @@ public void Read(SBinaryReader binaryReader)
ReqRec = binaryReader.ReadUInt16();
ReqInt = binaryReader.ReadUInt16();
ReqWis = binaryReader.ReadUInt16();
- ReqLuc = binaryReader.ReadUInt16();
- ReqVg = binaryReader.ReadUInt16();
- if (episode >= Episode.EP6)
+ if (episode >= Episode.EP6_4)
+ {
+ ReqLuc = binaryReader.ReadUInt32();
+ }
+ else
{
- Unknown = binaryReader.ReadUInt16();
+ ReqLuc = binaryReader.ReadUInt16();
}
+ ReqVg = binaryReader.ReadUInt16();
ReqOg = binaryReader.ReadByte();
ReqIg = binaryReader.ReadByte();
-
if (episode <= Episode.EP5)
{
Range = binaryReader.ReadByte();
@@ -286,20 +286,23 @@ public void Write(SBinaryWriter binaryWriter)
binaryWriter.Write(ReqRec);
binaryWriter.Write(ReqInt);
binaryWriter.Write(ReqWis);
- binaryWriter.Write(ReqLuc);
- binaryWriter.Write(ReqVg);
- if (episode >= Episode.EP6)
+ if (episode >= Episode.EP6_4)
{
- binaryWriter.Write(Unknown);
+ binaryWriter.Write(ReqLuc);
+ }
+ else
+ {
+ binaryWriter.Write((ushort)ReqLuc);
}
+ binaryWriter.Write(ReqVg);
binaryWriter.Write(ReqOg);
binaryWriter.Write(ReqIg);
if (episode <= Episode.EP5)
{
- binaryWriter.Write(Range);
+ binaryWriter.Write((byte)Range);
}
else
{
diff --git a/src/Parsec/Shaiya/KillStatus/KillStatusFaction.cs b/src/Parsec/Shaiya/KillStatus/KillStatusFaction.cs
index faaa8372..351b039f 100644
--- a/src/Parsec/Shaiya/KillStatus/KillStatusFaction.cs
+++ b/src/Parsec/Shaiya/KillStatus/KillStatusFaction.cs
@@ -3,6 +3,5 @@ namespace Parsec.Shaiya.KillStatus;
public enum KillStatusFaction : byte
{
Light,
- Fury,
- Any
+ Fury
}
diff --git a/src/Parsec/Shaiya/Monster/DBMonsterDataRecord.cs b/src/Parsec/Shaiya/Monster/DBMonsterDataRecord.cs
index b53f0552..cefbe1cf 100644
--- a/src/Parsec/Shaiya/Monster/DBMonsterDataRecord.cs
+++ b/src/Parsec/Shaiya/Monster/DBMonsterDataRecord.cs
@@ -251,6 +251,44 @@ public void Read(SBinaryReader binaryReader)
Skill2 = binaryReader.ReadInt64();
Skill3 = binaryReader.ReadInt64();
Skill4 = binaryReader.ReadInt64();
+ Skill5 = binaryReader.ReadInt64();
+ Skill6 = binaryReader.ReadInt64();
+ NormalTime = binaryReader.ReadInt64();
+ NormalStep = binaryReader.ReadInt64();
+ ChaseTime = binaryReader.ReadInt64();
+ ChaseStep = binaryReader.ReadInt64();
+ ChaseRange = binaryReader.ReadInt64();
+ AttackAni1 = binaryReader.ReadInt64();
+ AttackType1 = binaryReader.ReadInt64();
+ AttackTime1 = binaryReader.ReadInt64();
+ AttackRange1 = binaryReader.ReadInt64();
+ Attack1 = binaryReader.ReadInt64();
+ AttackPlus1 = binaryReader.ReadInt64();
+ AttackAttrib1 = binaryReader.ReadInt64();
+ AttackSpecial1 = binaryReader.ReadInt64();
+ AttackOk1 = binaryReader.ReadInt64();
+ AttackAni2 = binaryReader.ReadInt64();
+ AttackType2 = binaryReader.ReadInt64();
+ AttackTime2 = binaryReader.ReadInt64();
+ AttackRange2 = binaryReader.ReadInt64();
+ Attack2 = binaryReader.ReadInt64();
+ AttackPlus2 = binaryReader.ReadInt64();
+ AttackAttrib2 = binaryReader.ReadInt64();
+ AttackSpecial2 = binaryReader.ReadInt64();
+ AttackOk2 = binaryReader.ReadInt64();
+ AttackAni3 = binaryReader.ReadInt64();
+ AttackType3 = binaryReader.ReadInt64();
+ AttackTime3 = binaryReader.ReadInt64();
+ AttackRange3 = binaryReader.ReadInt64();
+ Attack3 = binaryReader.ReadInt64();
+ AttackPlus3 = binaryReader.ReadInt64();
+ AttackAttrib3 = binaryReader.ReadInt64();
+ AttackSpecial3 = binaryReader.ReadInt64();
+ AttackOk3 = binaryReader.ReadInt64();
+ ColorType = binaryReader.ReadInt64();
+ ColorHue = binaryReader.ReadInt64();
+ ColorSaturation = binaryReader.ReadInt64();
+ ColorLight = binaryReader.ReadInt64();
}
public void Write(SBinaryWriter binaryWriter)
@@ -311,5 +349,43 @@ public void Write(SBinaryWriter binaryWriter)
binaryWriter.Write(Skill2);
binaryWriter.Write(Skill3);
binaryWriter.Write(Skill4);
+ binaryWriter.Write(Skill5);
+ binaryWriter.Write(Skill6);
+ binaryWriter.Write(NormalTime);
+ binaryWriter.Write(NormalStep);
+ binaryWriter.Write(ChaseTime);
+ binaryWriter.Write(ChaseStep);
+ binaryWriter.Write(ChaseRange);
+ binaryWriter.Write(AttackAni1);
+ binaryWriter.Write(AttackType1);
+ binaryWriter.Write(AttackTime1);
+ binaryWriter.Write(AttackRange1);
+ binaryWriter.Write(Attack1);
+ binaryWriter.Write(AttackPlus1);
+ binaryWriter.Write(AttackAttrib1);
+ binaryWriter.Write(AttackSpecial1);
+ binaryWriter.Write(AttackOk1);
+ binaryWriter.Write(AttackAni2);
+ binaryWriter.Write(AttackType2);
+ binaryWriter.Write(AttackTime2);
+ binaryWriter.Write(AttackRange2);
+ binaryWriter.Write(Attack2);
+ binaryWriter.Write(AttackPlus2);
+ binaryWriter.Write(AttackAttrib2);
+ binaryWriter.Write(AttackSpecial2);
+ binaryWriter.Write(AttackOk2);
+ binaryWriter.Write(AttackAni3);
+ binaryWriter.Write(AttackType3);
+ binaryWriter.Write(AttackTime3);
+ binaryWriter.Write(AttackRange3);
+ binaryWriter.Write(Attack3);
+ binaryWriter.Write(AttackPlus3);
+ binaryWriter.Write(AttackAttrib3);
+ binaryWriter.Write(AttackSpecial3);
+ binaryWriter.Write(AttackOk3);
+ binaryWriter.Write(ColorType);
+ binaryWriter.Write(ColorHue);
+ binaryWriter.Write(ColorSaturation);
+ binaryWriter.Write(ColorLight);
}
}
diff --git a/src/Parsec/Shaiya/Monster/MonsterRecord.cs b/src/Parsec/Shaiya/Monster/MonsterRecord.cs
index 6972a444..3a130f30 100644
--- a/src/Parsec/Shaiya/Monster/MonsterRecord.cs
+++ b/src/Parsec/Shaiya/Monster/MonsterRecord.cs
@@ -11,9 +11,9 @@ public sealed class MonsterRecord : ISerializable
public short Level { get; set; }
- public byte AI { get; set; }
+ public byte Ai { get; set; }
- public int HP { get; set; }
+ public int Hp { get; set; }
public byte Day { get; set; }
@@ -31,17 +31,17 @@ public sealed class MonsterRecord : ISerializable
public byte AttackType1 { get; set; }
- public byte AttackElement1 { get; set; }
+ public byte AttackAni1 { get; set; }
public byte AttackType2 { get; set; }
- public byte AttackRange2 { get; set; }
+ public byte AttackAni2 { get; set; }
public byte AttackType3 { get; set; }
- public byte Unknown1 { get; set; }
+ public byte AttackAni3 { get; set; }
- public byte Unknown2 { get; set; }
+ public byte AttackPlus3 { get; set; }
public short QuestItemId { get; set; }
@@ -50,8 +50,8 @@ public void Read(SBinaryReader binaryReader)
MobName = binaryReader.ReadString();
ModelId = binaryReader.ReadInt16();
Level = binaryReader.ReadInt16();
- AI = binaryReader.ReadByte();
- HP = binaryReader.ReadInt32();
+ Ai = binaryReader.ReadByte();
+ Hp = binaryReader.ReadInt32();
Day = binaryReader.ReadByte();
Size = binaryReader.ReadByte();
Element = binaryReader.ReadByte();
@@ -60,12 +60,12 @@ public void Read(SBinaryReader binaryReader)
ChaseTime = binaryReader.ReadInt32();
ChaseStep = binaryReader.ReadByte();
AttackType1 = binaryReader.ReadByte();
- AttackElement1 = binaryReader.ReadByte();
+ AttackAni1 = binaryReader.ReadByte();
AttackType2 = binaryReader.ReadByte();
- AttackRange2 = binaryReader.ReadByte();
+ AttackAni2 = binaryReader.ReadByte();
AttackType3 = binaryReader.ReadByte();
- Unknown1 = binaryReader.ReadByte();
- Unknown2 = binaryReader.ReadByte();
+ AttackAni3 = binaryReader.ReadByte();
+ AttackPlus3 = binaryReader.ReadByte();
QuestItemId = binaryReader.ReadInt16();
}
@@ -74,8 +74,8 @@ public void Write(SBinaryWriter binaryWriter)
binaryWriter.Write(MobName);
binaryWriter.Write(ModelId);
binaryWriter.Write(Level);
- binaryWriter.Write(AI);
- binaryWriter.Write(HP);
+ binaryWriter.Write(Ai);
+ binaryWriter.Write(Hp);
binaryWriter.Write(Day);
binaryWriter.Write(Size);
binaryWriter.Write(Element);
@@ -84,12 +84,12 @@ public void Write(SBinaryWriter binaryWriter)
binaryWriter.Write(ChaseTime);
binaryWriter.Write(ChaseStep);
binaryWriter.Write(AttackType1);
- binaryWriter.Write(AttackElement1);
+ binaryWriter.Write(AttackAni1);
binaryWriter.Write(AttackType2);
- binaryWriter.Write(AttackRange2);
+ binaryWriter.Write(AttackAni2);
binaryWriter.Write(AttackType3);
- binaryWriter.Write(Unknown1);
- binaryWriter.Write(Unknown2);
+ binaryWriter.Write(AttackAni3);
+ binaryWriter.Write(AttackPlus3);
binaryWriter.Write(QuestItemId);
}
}
diff --git a/src/Parsec/Shaiya/SData/BinarySData.cs b/src/Parsec/Shaiya/SData/BinarySData.cs
index 9edfeefa..2b7b7cdc 100644
--- a/src/Parsec/Shaiya/SData/BinarySData.cs
+++ b/src/Parsec/Shaiya/SData/BinarySData.cs
@@ -62,7 +62,7 @@ protected override void Write(SBinaryWriter binaryWriter)
public void WriteCsv(string outputPath, Encoding? encoding = null)
{
- encoding ??= Encoding.ASCII;
+ encoding ??= Encoding;
using var writer = new StreamWriter(outputPath, false, encoding);
using var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture);
csvWriter.WriteRecords(Records);
diff --git a/src/Parsec/Shaiya/Wld/WldMusicZone.cs b/src/Parsec/Shaiya/Wld/WldMusicZone.cs
index 20a2efb2..5dd7a599 100644
--- a/src/Parsec/Shaiya/Wld/WldMusicZone.cs
+++ b/src/Parsec/Shaiya/Wld/WldMusicZone.cs
@@ -30,11 +30,6 @@ public sealed class WldMusicZone : ISerializable
///
public int Unknown { get; set; }
- [JsonConstructor]
- public WldMusicZone()
- {
- }
-
public void Read(SBinaryReader binaryReader)
{
BoundingBox = binaryReader.Read();
diff --git a/tests/Parsec.Tests/Parsec.Tests.csproj b/tests/Parsec.Tests/Parsec.Tests.csproj
index 3c014cc5..00b61646 100644
--- a/tests/Parsec.Tests/Parsec.Tests.csproj
+++ b/tests/Parsec.Tests/Parsec.Tests.csproj
@@ -1,21 +1,19 @@
-
+ net8.0
false
-
- net7.0
-
-
-
-
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -710,7 +708,7 @@
PreserveNewest
-
+
PreserveNewest
@@ -794,5 +792,32 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
diff --git a/tests/Parsec.Tests/Shaiya/Dg/DgTests.cs b/tests/Parsec.Tests/Shaiya/Dg/DgTests.cs
new file mode 100644
index 00000000..7ceb267a
--- /dev/null
+++ b/tests/Parsec.Tests/Shaiya/Dg/DgTests.cs
@@ -0,0 +1,30 @@
+namespace Parsec.Tests.Shaiya.Dg;
+
+public class DgTests
+{
+ [Theory]
+ [InlineData("R1_Dun1_2F.dg")]
+ [InlineData("r1_dun3.dg")]
+ [InlineData("r1_dun3_01.dg")]
+ [InlineData("r1_dun3_02.dg")]
+ [InlineData("r1_dun3_boss.dg")]
+ [InlineData("R1_Trade.dg")]
+ [InlineData("R2_Dun1.dg")]
+ public void DgMultipleReadWriteTest(string fileName)
+ {
+ var filePath = $"Shaiya/Dg/{fileName}";
+ var outputPath = $"Shaiya/Dg/output_{fileName}";
+ var jsonPath = $"Shaiya/Dg/{fileName}.json";
+
+ var dg = ParsecReader.FromFile(filePath);
+ dg.Write(outputPath);
+ dg.WriteJson(jsonPath);
+
+ var outputDg = ParsecReader.FromFile(outputPath);
+ var dgFromJson = ParsecReader.FromJsonFile(jsonPath);
+
+ // Check bytes
+ Assert.Equal(dg.GetBytes(), outputDg.GetBytes());
+ Assert.Equal(dg.GetBytes(), dgFromJson.GetBytes());
+ }
+}
diff --git a/tests/Parsec.Tests/Shaiya/Dg/R1_Dun1_2F.dg b/tests/Parsec.Tests/Shaiya/Dg/R1_Dun1_2F.dg
new file mode 100644
index 00000000..133c5de7
Binary files /dev/null and b/tests/Parsec.Tests/Shaiya/Dg/R1_Dun1_2F.dg differ
diff --git a/tests/Parsec.Tests/Shaiya/Dg/R1_Trade.dg b/tests/Parsec.Tests/Shaiya/Dg/R1_Trade.dg
new file mode 100644
index 00000000..0e55262c
Binary files /dev/null and b/tests/Parsec.Tests/Shaiya/Dg/R1_Trade.dg differ
diff --git a/tests/Parsec.Tests/Shaiya/Dg/R2_Dun1.dg b/tests/Parsec.Tests/Shaiya/Dg/R2_Dun1.dg
new file mode 100644
index 00000000..699916c5
Binary files /dev/null and b/tests/Parsec.Tests/Shaiya/Dg/R2_Dun1.dg differ
diff --git a/tests/Parsec.Tests/Shaiya/Dg/r1_dun3.dg b/tests/Parsec.Tests/Shaiya/Dg/r1_dun3.dg
new file mode 100644
index 00000000..9b66af91
Binary files /dev/null and b/tests/Parsec.Tests/Shaiya/Dg/r1_dun3.dg differ
diff --git a/tests/Parsec.Tests/Shaiya/Dg/r1_dun3_01.dg b/tests/Parsec.Tests/Shaiya/Dg/r1_dun3_01.dg
new file mode 100644
index 00000000..4a51b97e
Binary files /dev/null and b/tests/Parsec.Tests/Shaiya/Dg/r1_dun3_01.dg differ
diff --git a/tests/Parsec.Tests/Shaiya/Dg/r1_dun3_02.dg b/tests/Parsec.Tests/Shaiya/Dg/r1_dun3_02.dg
new file mode 100644
index 00000000..fc09a1ee
Binary files /dev/null and b/tests/Parsec.Tests/Shaiya/Dg/r1_dun3_02.dg differ
diff --git a/tests/Parsec.Tests/Shaiya/Dg/r1_dun3_boss.dg b/tests/Parsec.Tests/Shaiya/Dg/r1_dun3_boss.dg
new file mode 100644
index 00000000..422db1fc
Binary files /dev/null and b/tests/Parsec.Tests/Shaiya/Dg/r1_dun3_boss.dg differ
diff --git a/tests/Parsec.Tests/Shaiya/Item/ItemEp6_1251.SData b/tests/Parsec.Tests/Shaiya/Item/ItemEp64_1251.SData
similarity index 100%
rename from tests/Parsec.Tests/Shaiya/Item/ItemEp6_1251.SData
rename to tests/Parsec.Tests/Shaiya/Item/ItemEp64_1251.SData
diff --git a/tests/Parsec.Tests/Shaiya/Item/ItemTests.cs b/tests/Parsec.Tests/Shaiya/Item/ItemTests.cs
index 38337efb..a9179199 100644
--- a/tests/Parsec.Tests/Shaiya/Item/ItemTests.cs
+++ b/tests/Parsec.Tests/Shaiya/Item/ItemTests.cs
@@ -20,28 +20,40 @@ public void ItemEp5CsvTest()
}
[Fact]
- public void ItemEp6CsvTest()
+ public void ItemEp5ReadWriteTest()
{
- const string filePath = "Shaiya/Item/ItemEp6.SData";
- const string csvPath = "Shaiya/Item/ItemEp6.SData.csv";
+ const string filePath = "Shaiya/Item/ItemEp5.SData";
+ const string outputPath = "Shaiya/Item/ItemEp5.written.SData";
+
+ var item = ParsecReader.FromFile(filePath, Episode.EP5, TestEncodings.Encoding1252);
+ item.WriteEncrypted(outputPath);
+
+ Assert.Equal(FileHash.Checksum(filePath), FileHash.Checksum(outputPath));
+ }
+
+ [Fact]
+ public void ItemEp64CsvTest()
+ {
+ const string filePath = "Shaiya/Item/Item_ES_ps0224.SData";
+ const string csvPath = "Shaiya/Item/Item_ES_ps0224.SData.csv";
- var item = ParsecReader.FromFile(filePath, Episode.EP6);
+ var item = ParsecReader.FromFile(filePath, Episode.EP6_4, TestEncodings.Encoding1252);
item.WriteCsv(csvPath);
- var itemFromCsv = Parsec.Shaiya.Item.Item.FromCsv(csvPath, Episode.EP6);
- Assert.Equal(item.GetBytes(Episode.EP6), itemFromCsv.GetBytes(Episode.EP6));
+ var itemFromCsv = Parsec.Shaiya.Item.Item.FromCsv(csvPath, Episode.EP6_4, TestEncodings.Encoding1252);
+ Assert.Equal(item.GetBytes(Episode.EP6_4, TestEncodings.Encoding1252), itemFromCsv.GetBytes(Episode.EP6_4, TestEncodings.Encoding1252));
}
[Fact]
- public void ItemEp6Csv_EncodingTest()
+ public void ItemEp64Csv_EncodingTest()
{
- const string filePath = "Shaiya/Item/ItemEp6_1251.SData";
- const string csvPath = "Shaiya/Item/ItemEp6_1252.SData.csv";
+ const string filePath = "Shaiya/Item/ItemEp64_1251.SData";
+ const string csvPath = "Shaiya/Item/ItemEp64_1251.SData.csv";
var encoding = TestEncodings.Encoding1251;
- var item = ParsecReader.FromFile(filePath, Episode.EP6, encoding);
+ var item = ParsecReader.FromFile(filePath, Episode.EP6_4, encoding);
item.WriteCsv(csvPath, encoding);
- var itemFromCsv = Parsec.Shaiya.Item.Item.FromCsv(csvPath, Episode.EP6, encoding);
- Assert.Equal(item.GetBytes(Episode.EP6), itemFromCsv.GetBytes(Episode.EP6));
+ var itemFromCsv = Parsec.Shaiya.Item.Item.FromCsv(csvPath, Episode.EP6_4, encoding);
+ Assert.Equal(item.GetBytes(Episode.EP6_4), itemFromCsv.GetBytes(Episode.EP6_4));
}
[Fact]
diff --git a/tests/Parsec.Tests/Shaiya/Item/Item_ES_ps0224.SData b/tests/Parsec.Tests/Shaiya/Item/Item_ES_ps0224.SData
new file mode 100644
index 00000000..80e7d25c
Binary files /dev/null and b/tests/Parsec.Tests/Shaiya/Item/Item_ES_ps0224.SData differ
diff --git a/tests/Parsec.Tests/Shaiya/Item/Item_US_ps0216.SData b/tests/Parsec.Tests/Shaiya/Item/Item_US_ps0216.SData
new file mode 100644
index 00000000..66cfe7f2
Binary files /dev/null and b/tests/Parsec.Tests/Shaiya/Item/Item_US_ps0216.SData differ
diff --git a/tests/Parsec.Tests/Shaiya/SData/SDataTests.cs b/tests/Parsec.Tests/Shaiya/SData/SDataTests.cs
index e2cdf544..f6257eec 100644
--- a/tests/Parsec.Tests/Shaiya/SData/SDataTests.cs
+++ b/tests/Parsec.Tests/Shaiya/SData/SDataTests.cs
@@ -60,7 +60,7 @@ public void SDataDecryptionTest()
const string encryptedOutputPath = "Shaiya/SData/ItemEp6.encrypted.SData";
const string decryptedOutputPath = "Shaiya/SData/ItemEp6.decrypted.SData";
- var item = ParsecReader.FromFile(EncryptedSDataFilePath, Episode.EP6);
+ var item = ParsecReader.FromFile(EncryptedSDataFilePath, Episode.EP6_4);
item.WriteEncrypted(encryptedOutputPath);
item.WriteDecrypted(decryptedOutputPath);