mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-09 17:19:15 -10:00
Save and load creative toolbars with the toolbar keys
This commit is contained in:
1 parent
91e332a5eb
commit
85f34393fe
3 files changed
+70
-1
No files matched your search
@@ -34,6 +34,7 @@ mod consume;
|
||||
mod control;
|
||||
mod copper_golems;
|
||||
mod creaking;
|
||||
mod creative_hotbar;
|
||||
mod creatures;
|
||||
mod crossbow;
|
||||
pub(crate) mod cushions;
|
||||
@@ -11471,7 +11472,7 @@ impl Game<'_> {
|
||||
| KeyCode::Digit9
|
||||
if self.screen == Screen::Playing =>
|
||||
{
|
||||
self.selected = match key {
|
||||
let slot = match key {
|
||||
KeyCode::Digit1 => 0,
|
||||
KeyCode::Digit2 => 1,
|
||||
KeyCode::Digit3 => 2,
|
||||
@@ -11482,6 +11483,15 @@ impl Game<'_> {
|
||||
KeyCode::Digit8 => 7,
|
||||
_ => 8,
|
||||
};
|
||||
// Minecraft.handleKeybinds: a creative player holding the load
|
||||
// or save toolbar key loads or saves a toolbar instead (load
|
||||
// first when both are held).
|
||||
let load = self.mapped_key_down("key.loadToolbarActivator");
|
||||
if self.creative && (load || self.mapped_key_down("key.saveToolbarActivator")) {
|
||||
self.hotbar_load_or_save(slot, load);
|
||||
} else {
|
||||
self.selected = slot;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
//! The creative toolbars, `hotbar.nbt` beside `options.txt`: hold the save or
|
||||
//! load key and press a hotbar key (`Minecraft.handleKeybinds`).
|
||||
use super::Game;
|
||||
use horizon_client::{hotbar, keybinds, text::Text};
|
||||
|
||||
impl Game<'_> {
|
||||
/// Whether the key bound to `mapping` is held.
|
||||
pub(super) fn mapped_key_down(&self, mapping: &str) -> bool {
|
||||
keybinds::key_code(self.settings.keys.get(mapping))
|
||||
.is_some_and(|k| self.physical_keys.contains(&k))
|
||||
}
|
||||
|
||||
/// `CreativeModeInventoryScreen.handleHotbarLoadOrSave` for the hotbar key
|
||||
/// `index`: load puts the saved row in the hotbar (the creative slot
|
||||
/// packets follow from the inventory change), save stores the hotbar and
|
||||
/// says so on the action bar.
|
||||
pub(super) fn hotbar_load_or_save(&mut self, index: usize, load: bool) {
|
||||
let path = Self::options_path().with_file_name("hotbar.nbt");
|
||||
let known = |id: &str| self.res.items().get(id).is_some();
|
||||
let mut rows = hotbar::load(&path, &known);
|
||||
if load {
|
||||
for (slot, stack) in rows[index].iter().enumerate() {
|
||||
self.inventory[slot] = stack.clone();
|
||||
}
|
||||
return;
|
||||
}
|
||||
rows[index] = self.inventory[..hotbar::SIZE].to_vec();
|
||||
let _ = hotbar::save(&path, &rows);
|
||||
let key = |mapping: &str| keybinds::display_name(self.settings.keys.get(mapping));
|
||||
let message = Text::translate(
|
||||
"inventory.hotbarSaved",
|
||||
&[
|
||||
key("key.loadToolbarActivator"),
|
||||
key(&format!("key.hotbar.{}", index + 1)),
|
||||
],
|
||||
);
|
||||
self.titles.set_overlay(message, false);
|
||||
}
|
||||
}
|
||||
@@ -119,3 +119,23 @@ pub fn load(path: &Path, known: &dyn Fn(&str) -> bool) -> Vec<Hotbar> {
|
||||
_ => (0..GROUPS).map(|_| empty()).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// `HotbarManager.save`: the nine rows with the current data version, each
|
||||
/// stack as `ItemStack.OPTIONAL_CODEC` writes it (an empty one is `{}`).
|
||||
pub fn save(path: &Path, rows: &[Hotbar]) -> crate::Result<()> {
|
||||
let mut entries = vec![(
|
||||
JavaString::from("DataVersion"),
|
||||
Tag::Int(horizon_world::DATA_VERSION),
|
||||
)];
|
||||
for (i, row) in rows.iter().enumerate() {
|
||||
let stacks = row.iter().map(|s| match s {
|
||||
Some(s) => save::item_to_nbt(s),
|
||||
None => Tag::compound(Vec::<(&str, Tag)>::new()),
|
||||
});
|
||||
entries.push((
|
||||
JavaString::from(i.to_string().as_str()),
|
||||
Tag::List(stacks.collect()),
|
||||
));
|
||||
}
|
||||
save::write_dat(path, Tag::compound(entries))
|
||||
}
|
||||
Reference in new issue
Block a user