feat: Implemented crates functionality

This commit is contained in:
Alexey 2026-03-19 11:24:10 +03:00
commit d65ca6fe97
4 changed files with 105 additions and 26 deletions

View file

@ -2,7 +2,7 @@ use std::f32::consts::FRAC_PI_2;
use bevy::{ecs::relationship::RelatedSpawner, prelude::*, ui_widgets::{ControlOrientation, CoreScrollbarThumb, Scrollbar}};
use crate::{inventory::{ActiveInventory, Inventory, item::Item}, ui::{UiRoot, UiRotateEvent}};
use crate::{inventory::{ActiveInventory, Inventory, item::Item}, player::Player, ui::{UiRoot, UiRotateEvent}};
const UI_SLOT_ASSET_PATH: &'static str = "sprites/ui/inventory_slot.png";
const TEMP_ITEM_PATH: &'static str = "sprites/items/choco_bar.png";
@ -254,11 +254,13 @@ pub fn on_ui_rotate(
}
}
fn ui_manager_bundle(children: Vec<Entity>) -> impl Bundle {
fn ui_manager_bundle(children: Vec<Entity>, aligned_left: bool) -> impl Bundle {
let left = if aligned_left { Val::ZERO } else { percent(50.) };
(
UiInventoryManager,
Node {
position_type: PositionType::Absolute,
left,
width: percent(50.),
height: percent(100.),
scrollbar_width: 8.,
@ -353,6 +355,7 @@ fn inventory_slot_bundle(x: u32, y: u32, image: Handle<Image>) -> impl Bundle {
should_block_lower: true,
is_hoverable: true,
},
GlobalZIndex(1),
BackgroundColor::DEFAULT,
Name::new(format!("UiInventorySlot({x},{y})")),
)
@ -376,7 +379,7 @@ fn ui_item_bundle(item: &Item, item_entity: Entity, image: Handle<Image>) -> imp
},
BackgroundColor(Color::hsla(0., 0., 0., 0.5)),
ui_transform,
GlobalZIndex(1),
GlobalZIndex(2),
Pickable {
should_block_lower: false,
is_hoverable: true,
@ -391,7 +394,9 @@ fn ui_item_bundle(item: &Item, item_entity: Entity, image: Handle<Image>) -> imp
pub fn setup_ui_inventory(
mut commands: Commands,
asset_server: Res<AssetServer>,
inventory_query: Query<(Entity, &Inventory, Option<&Children>), With<ActiveInventory>>,
inventory_query: Query<(Option<&ChildOf>, Entity, &Inventory, Option<&Children>)>,
player_query: Query<(), With<Player>>,
active_inventory_query: Query<Entity, With<ActiveInventory>>,
item_query: Query<&Item>,
root_query: Query<Entity, With<UiRoot>>,
) {
@ -401,17 +406,30 @@ pub fn setup_ui_inventory(
};
let ui_slot_image: Handle<Image> = asset_server.load(UI_SLOT_ASSET_PATH);
let temp_item_image: Handle<Image> = asset_server.load(TEMP_ITEM_PATH);
let mut inventory_ids = Vec::new();
for (inventory_entity, inventory, children) in inventory_query.iter().sort::<Entity>() {
let (mut player_inventory_ids, mut active_inventory_ids) = (Vec::new(), Vec::new());
for (inventory_parent, inventory_entity, inventory, children) in inventory_query.iter().sort::<Entity>() {
let is_player = match inventory_parent {
Some(parent) => {
if player_query.get(parent.0)
.is_ok() { true }
else {
if active_inventory_query.get(inventory_entity)
.is_ok() { false }
else { continue; }
}
},
None => {
if active_inventory_query.get(inventory_entity)
.is_ok() { false }
else { continue; }
},
};
let items = match children {
Some(children) => {
children.iter().filter_map(|item_entity| {
match item_query.get(item_entity) {
Ok(item) => Some((item, item_entity)),
Err(err) => {
warn!("Error querying item {item_entity}: {err}");
None
},
Err(_) => None,
}
}).collect::<Vec<(&Item, Entity)>>()
}
@ -437,10 +455,18 @@ pub fn setup_ui_inventory(
}
} }
}).id();
inventory_ids.push(inventory_id);
if is_player {
player_inventory_ids.push(inventory_id);
} else {
active_inventory_ids.push(inventory_id);
}
}
let inventory_manager = commands.spawn(ui_manager_bundle(inventory_ids)).id();
commands.entity(root).add_child(inventory_manager);
let player_inventory_manager = commands.spawn(ui_manager_bundle(player_inventory_ids, true)).id();
let active_inventory_manager = commands.spawn(ui_manager_bundle(active_inventory_ids, false)).id();
for entity in active_inventory_query {
commands.entity(entity).remove::<ActiveInventory>();
}
commands.entity(root).add_children(&[player_inventory_manager, active_inventory_manager]);
}
pub fn clear_ui_inventory(