mirror of
https://github.com/Theaninova/mhlib.git
synced 2026-01-10 12:02:51 +00:00
ui
This commit is contained in:
@@ -7,10 +7,13 @@
|
|||||||
[sub_resource type="GDScript" id="GDScript_oemh7"]
|
[sub_resource type="GDScript" id="GDScript_oemh7"]
|
||||||
script/source = "extends MarginContainer
|
script/source = "extends MarginContainer
|
||||||
|
|
||||||
|
const Profile = preload(\"res://mhjnr/profile/player_profile.gd\")
|
||||||
|
|
||||||
@export var entry: String = \"main\"
|
@export var entry: String = \"main\"
|
||||||
@export var window_size: Vector2i = Vector2i(800, 600)
|
@export var window_size: Vector2i = Vector2i(800, 600)
|
||||||
|
|
||||||
var menu: Node
|
var menu: Node
|
||||||
|
var profile: Profile
|
||||||
@onready var translations: Translation = load(\"datafile://data/text.csv\")
|
@onready var translations: Translation = load(\"datafile://data/text.csv\")
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
@@ -52,15 +55,37 @@ func _on_minimize_pressed() -> void:
|
|||||||
func _on_close_pressed() -> void:
|
func _on_close_pressed() -> void:
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
|
|
||||||
|
func _on_action_CheckStartGame() -> void:
|
||||||
|
var level = profile.current_level
|
||||||
|
if level == 0:
|
||||||
|
set_menu(\"screen_set1\")
|
||||||
|
else:
|
||||||
|
set_menu(\"screen_set2\")
|
||||||
|
|
||||||
|
func _on_action_SelectProfile(id: String) -> void:
|
||||||
|
profile = load(\"user://profile_%02d.tres\" % (id.to_int() + 1))
|
||||||
|
if profile == null:
|
||||||
|
set_menu(\"profile_create\")
|
||||||
|
else:
|
||||||
|
set_menu(\"main\")
|
||||||
|
|
||||||
|
func _on_action_ProfileCreated() -> void:
|
||||||
|
profile = Profile.new()
|
||||||
|
profile.name = menu.find_child(\"profile1\").text
|
||||||
|
ResourceSaver.save(profile, \"user://profile_01.tres\")
|
||||||
|
set_menu(\"main\")
|
||||||
|
|
||||||
func _on_action_SetMenu(name: String) -> void:
|
func _on_action_SetMenu(name: String) -> void:
|
||||||
set_menu(name)
|
set_menu(name)
|
||||||
|
|
||||||
func _on_action_CheckStartGame() -> void:
|
|
||||||
print(\"CheckStartGame\")
|
|
||||||
|
|
||||||
func _on_action_DisplayEndscreen() -> void:
|
func _on_action_DisplayEndscreen() -> void:
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
|
|
||||||
|
func _on_action_StartGame() -> void:
|
||||||
|
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_RESIZE_DISABLED, false)
|
||||||
|
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
|
||||||
|
get_tree().change_scene_to_file(\"res://mhjnr/level.tscn\")
|
||||||
|
|
||||||
"
|
"
|
||||||
|
|
||||||
[node name="Root" type="MarginContainer"]
|
[node name="Root" type="MarginContainer"]
|
||||||
@@ -71,6 +96,7 @@ grow_horizontal = 2
|
|||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
theme = ExtResource("1_o0c21")
|
theme = ExtResource("1_o0c21")
|
||||||
script = SubResource("GDScript_oemh7")
|
script = SubResource("GDScript_oemh7")
|
||||||
|
entry = "profile_start_select"
|
||||||
|
|
||||||
[node name="Titlebar" type="HBoxContainer" parent="."]
|
[node name="Titlebar" type="HBoxContainer" parent="."]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use crate::formats::datafile::FileEntry;
|
|||||||
use crate::formats::level::LevelLayer;
|
use crate::formats::level::LevelLayer;
|
||||||
use crate::formats::rle::RleImage;
|
use crate::formats::rle::RleImage;
|
||||||
use crate::formats::sprites::Sprites;
|
use crate::formats::sprites::Sprites;
|
||||||
use crate::formats::txt::{decrypt_txt, DecryptError};
|
use crate::formats::txt::{decrypt_exposed_txt, decrypt_txt, DecryptError};
|
||||||
use crate::formats::ui_xml::UiTag;
|
use crate::formats::ui_xml::UiTag;
|
||||||
use binrw::BinRead;
|
use binrw::BinRead;
|
||||||
use encoding_rs::WINDOWS_1252;
|
use encoding_rs::WINDOWS_1252;
|
||||||
@@ -93,6 +93,10 @@ where
|
|||||||
Ok(DatafileFile::Sprites(
|
Ok(DatafileFile::Sprites(
|
||||||
Sprites::parse(decr.as_str()).map_err(custom_err)?,
|
Sprites::parse(decr.as_str()).map_err(custom_err)?,
|
||||||
))
|
))
|
||||||
|
} else if stem.starts_with("profile") || stem.starts_with("highscores") {
|
||||||
|
Ok(DatafileFile::Txt(
|
||||||
|
decrypt_exposed_txt(decr).map_err(custom_err)?,
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(DatafileFile::Txt(decr))
|
Ok(DatafileFile::Txt(decr))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ pub enum UiTag {
|
|||||||
Image(UiImage),
|
Image(UiImage),
|
||||||
TextButton(UiTextButton),
|
TextButton(UiTextButton),
|
||||||
TextArea(UiTextArea),
|
TextArea(UiTextArea),
|
||||||
|
TextField(UiTextField),
|
||||||
StaticText(UiStaticText),
|
StaticText(UiStaticText),
|
||||||
ToggleButton(UiToggleButton),
|
ToggleButton(UiToggleButton),
|
||||||
}
|
}
|
||||||
@@ -20,6 +21,24 @@ pub struct UiMenu {
|
|||||||
pub children: Vec<UiTag>,
|
pub children: Vec<UiTag>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct UiTextField {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub text: String,
|
||||||
|
#[serde(deserialize_with = "deserialize_vec2")]
|
||||||
|
pub position: [i32; 2],
|
||||||
|
#[serde(rename = "bufferVar")]
|
||||||
|
pub buffer_var: String,
|
||||||
|
#[serde(deserialize_with = "deserialize_vec4")]
|
||||||
|
pub area: [i32; 4],
|
||||||
|
#[serde(rename = "halign", default)]
|
||||||
|
pub horizontal_align: HorizontalAlign,
|
||||||
|
#[serde(rename = "fademode")]
|
||||||
|
pub fade_mode: FadeMode,
|
||||||
|
#[serde(rename = "OnSelect")]
|
||||||
|
pub on_select: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct UiImage {
|
pub struct UiImage {
|
||||||
pub texture: String,
|
pub texture: String,
|
||||||
@@ -172,12 +191,18 @@ where
|
|||||||
to_vec2::<D>(String::deserialize(deserializer)?)
|
to_vec2::<D>(String::deserialize(deserializer)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_vec2<'de, D>(buf: String) -> Result<[i32; 2], D::Error>
|
fn deserialize_vec4<'de, D>(deserializer: D) -> Result<[i32; 4], D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let mut values: Vec<Result<i32, D::Error>> = buf
|
to_vec4::<D>(String::deserialize(deserializer)?)
|
||||||
.split(',')
|
}
|
||||||
|
|
||||||
|
fn to_vec<'de, D>(buf: String) -> Result<Vec<i32>, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
buf.split(',')
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|value| {
|
.map(|value| {
|
||||||
// there's some typos so we have to cover that...
|
// there's some typos so we have to cover that...
|
||||||
@@ -186,9 +211,29 @@ where
|
|||||||
.parse::<i32>()
|
.parse::<i32>()
|
||||||
.map_err(|err| Error::custom(err.to_string()))
|
.map_err(|err| Error::custom(err.to_string()))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect()
|
||||||
let y = values.pop().ok_or(Error::custom("InvalidField"))??;
|
}
|
||||||
let x = values.pop().ok_or(Error::custom("InvalidField"))??;
|
|
||||||
|
fn to_vec4<'de, D>(buf: String) -> Result<[i32; 4], D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let mut values = to_vec::<D>(buf)?;
|
||||||
|
let w = values.pop().ok_or(Error::custom("InvalidField"))?;
|
||||||
|
let z = values.pop().ok_or(Error::custom("InvalidField"))?;
|
||||||
|
let y = values.pop().ok_or(Error::custom("InvalidField"))?;
|
||||||
|
let x = values.pop().ok_or(Error::custom("InvalidField"))?;
|
||||||
|
|
||||||
|
Ok([x, y, z, w])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_vec2<'de, D>(buf: String) -> Result<[i32; 2], D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let mut values = to_vec::<D>(buf)?;
|
||||||
|
let y = values.pop().ok_or(Error::custom("InvalidField"))?;
|
||||||
|
let x = values.pop().ok_or(Error::custom("InvalidField"))?;
|
||||||
|
|
||||||
Ok([x, y])
|
Ok([x, y])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use godot::builtin::{Array, Dictionary, GodotString, ToVariant, Vector2};
|
|||||||
use godot::engine::control::LayoutPreset;
|
use godot::engine::control::LayoutPreset;
|
||||||
use godot::engine::global::HorizontalAlignment;
|
use godot::engine::global::HorizontalAlignment;
|
||||||
use godot::engine::node::InternalMode;
|
use godot::engine::node::InternalMode;
|
||||||
use godot::engine::{load, Button, Control, Label, Node, SpinBox, TextureRect};
|
use godot::engine::{load, Button, Control, Label, LineEdit, Node, SpinBox, TextureRect};
|
||||||
use godot::obj::{Gd, Inherits, Share};
|
use godot::obj::{Gd, Inherits, Share};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
@@ -43,6 +43,19 @@ pub fn convert_ui(ui: UiTag, base_path: &str) -> Gd<Node> {
|
|||||||
attach_children(&mut text_area, area.children, base_path);
|
attach_children(&mut text_area, area.children, base_path);
|
||||||
text_area.upcast()
|
text_area.upcast()
|
||||||
}
|
}
|
||||||
|
UiTag::TextField(field) => {
|
||||||
|
let mut text_field = LineEdit::new_alloc();
|
||||||
|
if let Some(name) = field.name {
|
||||||
|
text_field.set_name(name.into());
|
||||||
|
}
|
||||||
|
text_field.set_text(field.text.into());
|
||||||
|
text_field.set_horizontal_alignment(field.horizontal_align.into());
|
||||||
|
text_field.set_position(to_vec2([field.area[0], field.area[1]]), false);
|
||||||
|
text_field.set_size(to_vec2([field.area[2], field.area[3]]), false);
|
||||||
|
text_field.set_meta("buffer_var".into(), field.buffer_var.to_variant());
|
||||||
|
attach_call_meta(&mut text_field, field.on_select);
|
||||||
|
text_field.upcast()
|
||||||
|
}
|
||||||
UiTag::ToggleButton(toggle) => {
|
UiTag::ToggleButton(toggle) => {
|
||||||
let mut spin_box = SpinBox::new_alloc();
|
let mut spin_box = SpinBox::new_alloc();
|
||||||
spin_box.set_position(to_vec2(toggle.position), false);
|
spin_box.set_position(to_vec2(toggle.position), false);
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ fn extract(datafile: &Datafile, file: &mut File) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let file_name = Some(NullString::from(
|
let file_name = Some(NullString::from("data\\profile_00.txt"));
|
||||||
"data\\menu\\screens\\options_controls.xml",
|
|
||||||
));
|
|
||||||
let dat_path = "E:\\Games\\Schatzjäger\\data\\datafile.dat";
|
let dat_path = "E:\\Games\\Schatzjäger\\data\\datafile.dat";
|
||||||
|
|
||||||
let mut file = File::open(dat_path).unwrap();
|
let mut file = File::open(dat_path).unwrap();
|
||||||
@@ -102,7 +100,10 @@ fn main() {
|
|||||||
let sprites = Sprites::parse(decr.as_str()).unwrap();
|
let sprites = Sprites::parse(decr.as_str()).unwrap();
|
||||||
println!("{:#?}", sprites);
|
println!("{:#?}", sprites);
|
||||||
} else {
|
} else {
|
||||||
println!("{}", decrypt_txt(data.into_iter()).unwrap())
|
println!(
|
||||||
|
"{}",
|
||||||
|
decrypt_exposed_txt(decrypt_txt(data.into_iter()).unwrap()).unwrap()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some("rle") => {
|
Some("rle") => {
|
||||||
|
|||||||
Reference in New Issue
Block a user