mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-06-15 17:44:25 +08:00
Add title support for scn script
This commit is contained in:
@@ -211,6 +211,10 @@ pub struct Arg {
|
||||
/// Kirikiri language list. First language code is code for language index 1.
|
||||
pub kirikiri_languages: Option<Vec<String>>,
|
||||
#[cfg(feature = "kirikiri")]
|
||||
#[arg(long, global = true, action = ArgAction::SetTrue, alias = "kr-title")]
|
||||
/// Whether to handle title in Kirikiri SCN script.
|
||||
pub kirikiri_title: bool,
|
||||
#[cfg(feature = "kirikiri")]
|
||||
#[arg(long, global = true, action = ArgAction::SetTrue, alias = "kr-no-empty-lines", alias = "kirikiri-no-empty-lines")]
|
||||
/// Remove empty lines in Kirikiri KS script.
|
||||
pub kirikiri_remove_empty_lines: bool,
|
||||
|
||||
@@ -55,6 +55,36 @@ pub enum PsbValueFixed {
|
||||
CompilerBinaryTree,
|
||||
}
|
||||
|
||||
impl From<String> for PsbValueFixed {
|
||||
fn from(value: String) -> Self {
|
||||
PsbValueFixed::String(PsbString::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bool> for PsbValueFixed {
|
||||
fn from(value: bool) -> Self {
|
||||
PsbValueFixed::Bool(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i64> for PsbValueFixed {
|
||||
fn from(value: i64) -> Self {
|
||||
PsbValueFixed::Number(PsbNumber::Integer(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f64> for PsbValueFixed {
|
||||
fn from(value: f64) -> Self {
|
||||
PsbValueFixed::Number(PsbNumber::Double(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f32> for PsbValueFixed {
|
||||
fn from(value: f32) -> Self {
|
||||
PsbValueFixed::Number(PsbNumber::Float(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl PsbValueFixed {
|
||||
/// Converts this value to original PSB value type.
|
||||
pub fn to_psb(self, warn_on_none: bool) -> PsbValue {
|
||||
@@ -204,6 +234,20 @@ impl PsbValueFixed {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pushes a new member to a list. If this value is not a list, it will be converted to a list.
|
||||
pub fn push_member<T: Into<PsbValueFixed>>(&mut self, value: T) {
|
||||
match self {
|
||||
PsbValueFixed::List(l) => {
|
||||
l.values.push(value.into());
|
||||
}
|
||||
_ => {
|
||||
*self = PsbValueFixed::List(PsbListFixed {
|
||||
values: vec![value.into()],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the resource ID if this value is a resource reference.
|
||||
pub fn resource_id(&self) -> Option<u64> {
|
||||
match self {
|
||||
|
||||
@@ -1921,6 +1921,8 @@ fn main() {
|
||||
flac_compression_level: arg.flac_compression_level,
|
||||
#[cfg(feature = "artemis")]
|
||||
artemis_asb_format_lua: !arg.artemis_asb_no_format_lua,
|
||||
#[cfg(feature = "kirikiri")]
|
||||
kirikiri_title: arg.kirikiri_title,
|
||||
};
|
||||
match &arg.command {
|
||||
args::Command::Export { input, output } => {
|
||||
|
||||
@@ -116,6 +116,7 @@ pub struct ScnScript {
|
||||
chat_key: Option<String>,
|
||||
chat_json: Option<Arc<HashMap<String, String>>>,
|
||||
custom_yaml: bool,
|
||||
title: bool,
|
||||
}
|
||||
|
||||
impl ScnScript {
|
||||
@@ -152,6 +153,7 @@ impl ScnScript {
|
||||
chat_key: config.kirikiri_chat_key.clone(),
|
||||
chat_json: config.kirikiri_chat_json.clone(),
|
||||
custom_yaml: config.custom_yaml,
|
||||
title: config.kirikiri_title,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -222,6 +224,22 @@ impl Script for ScnScript {
|
||||
PsbValueFixed::Object(obj) => obj,
|
||||
_ => return Err(anyhow::anyhow!("scene at index {} is not an object", i)),
|
||||
};
|
||||
if self.title {
|
||||
if let Some(title) = scene["title"].as_str() {
|
||||
messages.push(Message {
|
||||
name: None,
|
||||
message: title.to_string(),
|
||||
});
|
||||
}
|
||||
if scene["title"].is_list() {
|
||||
if let Some(title) = scene["title"][self.language_index].as_str() {
|
||||
messages.push(Message {
|
||||
name: None,
|
||||
message: title.to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(PsbValueFixed::List(texts)) = scene.get_value("texts") {
|
||||
for (j, text) in texts.iter().enumerate() {
|
||||
if let PsbValueFixed::List(text) = text {
|
||||
@@ -430,6 +448,55 @@ impl Script for ScnScript {
|
||||
if !scene.is_object() {
|
||||
return Err(anyhow::anyhow!("scene at {} is not an object", i));
|
||||
}
|
||||
if self.title {
|
||||
if scene["title"].is_string() {
|
||||
let m = match cur_mes {
|
||||
Some(m) => m,
|
||||
None => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"No enough messages. (title at scene {i})"
|
||||
));
|
||||
}
|
||||
};
|
||||
let mut title = m.message.clone();
|
||||
if let Some(replacement) = replacement {
|
||||
for (key, value) in replacement.map.iter() {
|
||||
title = title.replace(key, value);
|
||||
}
|
||||
}
|
||||
if self.language_index == 0 {
|
||||
scene["title"].set_string(title);
|
||||
} else {
|
||||
let ori_title = scene["title"].as_str().unwrap_or("").to_string();
|
||||
while scene["title"].len() < self.language_index {
|
||||
scene["title"].push_member(ori_title.clone());
|
||||
}
|
||||
scene["title"].push_member(title);
|
||||
}
|
||||
cur_mes = mes.next();
|
||||
} else if scene["title"].is_list() {
|
||||
let m = match cur_mes {
|
||||
Some(m) => m,
|
||||
None => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"No enough messages. (title at scene {i})"
|
||||
));
|
||||
}
|
||||
};
|
||||
let mut title = m.message.clone();
|
||||
if let Some(replacement) = replacement {
|
||||
for (key, value) in replacement.map.iter() {
|
||||
title = title.replace(key, value);
|
||||
}
|
||||
}
|
||||
let ori_title = scene["title"][0].as_str().unwrap_or("").to_string();
|
||||
while scene["title"].len() <= self.language_index {
|
||||
scene["title"].push_member(ori_title.clone());
|
||||
}
|
||||
scene["title"][self.language_index].set_string(title);
|
||||
cur_mes = mes.next();
|
||||
}
|
||||
}
|
||||
if scene["texts"].is_list() {
|
||||
for (j, text) in scene["texts"].members_mut().enumerate() {
|
||||
if text.is_list() {
|
||||
|
||||
@@ -419,6 +419,9 @@ pub struct ExtraConfig {
|
||||
#[default(true)]
|
||||
/// Format lua code in Artemis ASB script(.asb/.iet) when exporting.
|
||||
pub artemis_asb_format_lua: bool,
|
||||
#[cfg(feature = "kirikiri")]
|
||||
/// Whether to handle title in Kirikiri SCN script.
|
||||
pub kirikiri_title: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
|
||||
|
||||
Reference in New Issue
Block a user