M sqlite_conv/src/main.rs => sqlite_conv/src/main.rs +18 -1
@@ 271,6 271,17 @@ fn scripts_to_new_db<P: AsRef<std::path::Path>>(base_path: P, dbpath: P) {
.unwrap();
tx.execute(
+ "create table BreakTable (
+ file_name text not null,
+ unk1 int not null,
+ unk2 int not null,
+ foreign key(file_name) references scripts(file_name)
+) strict;",
+ [],
+ )
+ .unwrap();
+
+ tx.execute(
"create table AlgoTable (
file_name text not null,
action_or_magic_id int,
@@ 369,7 380,7 @@ fn scripts_to_new_db<P: AsRef<std::path::Path>>(base_path: P, dbpath: P) {
}
fn insert_script_entry_data(tx: &rusqlite::Transaction, script_name: &str, entry: &tocs::script::ScriptEntry) {
- use tocs::script::{ActionTableEntry, AlgoTableEntry, ScriptEntry, SummonTableEntry};
+ use tocs::script::{ActionTableEntry, AlgoTableEntry, BreakTableEntry, ScriptEntry, SummonTableEntry};
match entry {
ScriptEntry::ActionTable(entries) => {
@@ 475,6 486,12 @@ fn insert_script_entry_data(tx: &rusqlite::Transaction, script_name: &str, entry
.unwrap();
}
}
+ ScriptEntry::BreakTable(entries) => {
+ for BreakTableEntry { unk1, unk2 } in entries {
+ tx.execute("insert into BreakTable values (?, ?, ?)", [&script_name as &dyn rusqlite::types::ToSql, &unk1 as _, &unk2 as _])
+ .unwrap();
+ }
+ }
ScriptEntry::SummonTable(entries) => {
for SummonTableEntry { unk1, unk2, monster } in entries {
tx.execute(
M tocs/src/script/deser.rs => tocs/src/script/deser.rs +16 -1
@@ 1,4 1,4 @@
-use super::{ActionTableEntry, AlgoTableEntry, Effect, Script, ScriptEntry, ScriptNamePadding, SummonTableEntry, WeaponAtt};
+use super::{ActionTableEntry, AlgoTableEntry, BreakTableEntry, Effect, Script, ScriptEntry, ScriptNamePadding, SummonTableEntry, WeaponAtt};
use crate::io::MemReader;
@@ 111,6 111,7 @@ pub fn parse(data: &[u8]) -> Option<Script> {
let table = match name.to_str() {
"ActionTable" => ScriptEntry::ActionTable(read_action_table_entries(table_data)?),
"AlgoTable" => ScriptEntry::AlgoTable(read_algo_table_entries(table_data)?),
+ "BreakTable" => ScriptEntry::BreakTable(read_break_table_entries(table_data)?),
"SummonTable" => ScriptEntry::SummonTable(read_summon_table_entries(table_data)?),
"WeaponAttTable" => ScriptEntry::WeaponAttTable(read_weapon_att_table(table_data)?),
_ => ScriptEntry::Generic {
@@ 263,6 264,20 @@ pub fn read_algo_table_entries(data: &[u8]) -> Option<std::vec::Vec<AlgoTableEnt
Some(entries)
}
+pub fn read_break_table_entries(data: &[u8]) -> Option<std::vec::Vec<BreakTableEntry>> {
+ let mut reader = MemReader::new(data);
+ let mut entries = std::vec::Vec::with_capacity(data.len() / 32);
+
+ while !reader.at_end() {
+ let unk1 = reader.read_i16_le()?;
+ let unk2 = reader.read_i16_le()?;
+
+ entries.push(BreakTableEntry { unk1, unk2 });
+ }
+
+ Some(entries)
+}
+
pub fn read_summon_table_entries(data: &[u8]) -> Option<std::vec::Vec<SummonTableEntry>> {
let mut reader = MemReader::new(data);
let mut entries = std::vec::Vec::with_capacity(data.len() / 32);
M tocs/src/script/mod.rs => tocs/src/script/mod.rs +9 -0
@@ 28,6 28,7 @@ pub enum ScriptNamePadding {
pub enum ScriptEntry {
ActionTable(std::vec::Vec<ActionTableEntry>),
AlgoTable(std::vec::Vec<AlgoTableEntry>),
+ BreakTable(std::vec::Vec<BreakTableEntry>),
SummonTable(std::vec::Vec<SummonTableEntry>),
WeaponAttTable(WeaponAtt),
Generic { name: PaddedAsciiString<1>, data: std::vec::Vec<u8> },
@@ 38,6 39,7 @@ impl ScriptEntry {
match self {
ScriptEntry::ActionTable { .. } => 12,
ScriptEntry::AlgoTable { .. } => 10,
+ ScriptEntry::BreakTable { .. } => 11,
ScriptEntry::SummonTable { .. } => 12,
ScriptEntry::WeaponAttTable { .. } => 15,
ScriptEntry::Generic { name, .. } => name.len_with_padding().get(),
@@ 49,6 51,7 @@ impl ScriptEntry {
// TODO: constify PaddedAsciiStr
ScriptEntry::ActionTable { .. } => PaddedAsciiStr::new("ActionTable").unwrap(),
ScriptEntry::AlgoTable { .. } => PaddedAsciiStr::new("AlgoTable").unwrap(),
+ ScriptEntry::BreakTable { .. } => PaddedAsciiStr::new("BreakTable").unwrap(),
ScriptEntry::SummonTable { .. } => PaddedAsciiStr::new("SummonTable").unwrap(),
ScriptEntry::WeaponAttTable { .. } => PaddedAsciiStr::new("WeaponAttTable").unwrap(),
ScriptEntry::Generic { name, .. } => name.as_padded_ascii_str(),
@@ 105,6 108,12 @@ pub struct AlgoTableEntry {
}
#[derive(Debug, Clone)]
+pub struct BreakTableEntry {
+ pub unk1: i16,
+ pub unk2: i16,
+}
+
+#[derive(Debug, Clone)]
pub struct SummonTableEntry {
pub unk1: u16,
pub unk2: u16,
M tocs/src/script/ser.rs => tocs/src/script/ser.rs +22 -13
@@ 1,4 1,4 @@
-use super::{ActionTableEntry, AlgoTableEntry, Script, ScriptEntry, ScriptNamePadding, SummonTableEntry, WeaponAtt};
+use super::{ActionTableEntry, AlgoTableEntry, BreakTableEntry, Script, ScriptEntry, ScriptNamePadding, SummonTableEntry, WeaponAtt};
use crate::io::MemWriter;
pub fn serialize(script: &Script) -> Option<std::vec::Vec<u8>> {
@@ 124,6 124,7 @@ impl ScriptEntry {
match self {
ScriptEntry::ActionTable(entries) => entries.iter().try_for_each(|entry| entry.serialize_data(writer))?,
ScriptEntry::AlgoTable(entries) => entries.iter().try_for_each(|entry| entry.serialize_data(writer))?,
+ ScriptEntry::BreakTable(entries) => entries.iter().try_for_each(|entry| entry.serialize_data(writer))?,
ScriptEntry::SummonTable(entries) => entries.iter().try_for_each(|entry| entry.serialize_data(writer))?,
ScriptEntry::WeaponAttTable(att) => att.serialize_data(writer)?,
ScriptEntry::Generic { name: _, data } => {
@@ 132,6 133,17 @@ impl ScriptEntry {
}
Some(())
}
+
+ fn data_len(&self) -> usize {
+ match self {
+ ScriptEntry::ActionTable(entries) => 212 * entries.len(),
+ ScriptEntry::AlgoTable(entries) => 32 * entries.len(),
+ ScriptEntry::BreakTable(entries) => 4 * entries.len(),
+ ScriptEntry::SummonTable(entries) => 36 * entries.len(),
+ ScriptEntry::WeaponAttTable(_) => 4,
+ ScriptEntry::Generic { name: _, data } => data.len(),
+ }
+ }
}
impl ActionTableEntry {
@@ 216,6 228,15 @@ impl AlgoTableEntry {
}
}
+impl BreakTableEntry {
+ fn serialize_data(&self, writer: &mut MemWriter) -> Option<()> {
+ let Self { unk1, unk2 } = self;
+ writer.write_i16_le(*unk1);
+ writer.write_i16_le(*unk2);
+ Some(())
+ }
+}
+
impl SummonTableEntry {
fn serialize_data(&self, writer: &mut MemWriter) -> Option<()> {
let Self { unk1, unk2, monster } = self;
@@ 236,15 257,3 @@ impl WeaponAtt {
Some(())
}
}
-
-impl ScriptEntry {
- fn data_len(&self) -> usize {
- match self {
- ScriptEntry::ActionTable(entries) => 212 * entries.len(),
- ScriptEntry::AlgoTable(entries) => 32 * entries.len(),
- ScriptEntry::SummonTable(entries) => 36 * entries.len(),
- ScriptEntry::WeaponAttTable(_) => 4,
- ScriptEntry::Generic { name: _, data } => data.len(),
- }
- }
-}