ui: Inventory item rotation

- Fixed rotated item position
This commit is contained in:
Alexey 2026-03-12 13:08:08 +03:00
commit beacc28ace
2 changed files with 48 additions and 29 deletions

View file

@ -20,7 +20,26 @@ pub struct UiInventorySlot(UVec2);
pub struct UiItem(Entity); pub struct UiItem(Entity);
#[derive(Component)] #[derive(Component)]
pub struct HoveredItem(Entity); pub struct HoveredItem;
fn ui_item_node_data(item: &Item) -> (Val, Val, Val, Val, UiTransform) {
match item.rotated {
true => (
percent(50. * (item.size.x as f32 - item.size.y as f32)),
percent(50. * (item.size.y as f32 - item.size.x as f32)),
percent(100. * item.size.y as f32),
percent(100. * item.size.x as f32),
UiTransform::from_rotation(Rot2::radians(-FRAC_PI_2)),
),
false => (
auto(),
auto(),
percent(100. * item.size.x as f32),
percent(100. * item.size.y as f32),
UiTransform::default(),
),
}
}
fn on_slot_over(e: On<Pointer<Over>>, mut query: Query<&mut ImageNode, With<UiInventorySlot>>) { fn on_slot_over(e: On<Pointer<Over>>, mut query: Query<&mut ImageNode, With<UiInventorySlot>>) {
if let Ok(mut image) = query.get_mut(e.event_target()) { if let Ok(mut image) = query.get_mut(e.event_target()) {
@ -36,7 +55,7 @@ fn on_slot_out(e: On<Pointer<Out>>, mut query: Query<&mut ImageNode, With<UiInve
fn on_item_over(e: On<Pointer<Over>>, mut commands: Commands, query: Query<Entity, With<UiItem>>) { fn on_item_over(e: On<Pointer<Over>>, mut commands: Commands, query: Query<Entity, With<UiItem>>) {
if let Ok(_) = query.get(e.event_target()) { if let Ok(_) = query.get(e.event_target()) {
commands.entity(e.event_target()).insert(HoveredItem(e.event_target())); commands.entity(e.event_target()).insert(HoveredItem);
} }
} }
@ -95,15 +114,15 @@ fn on_item_drag_drop(
} }
} }
fn on_ui_rotate( pub fn on_ui_rotate(
event: On<UiRotateEvent>, _: On<UiRotateEvent>,
item_query: Query<&Item>, mut item_query: Query<&mut Item>,
mut mut_item_query: Query<(&ChildOf, &mut Item)>, parent_query: Query<&ChildOf>,
inventory_query: Query<(&Inventory, Option<&Children>)>, inventory_query: Query<(&Inventory, Option<&Children>)>,
ui_item_query: Query<(&mut UiItem, &mut Node), With<HoveredItem>>, ui_item_query: Query<(&UiItem, &mut UiTransform, &mut Node), With<HoveredItem>>,
) { ) {
for (mut ui_item, mut node) in ui_item_query { for (ui_item, mut ui_transform, mut node) in ui_item_query {
let Ok((item_parent, mut mut_item)) = mut_item_query.get_mut(ui_item.0) else { let Ok(item_parent) = parent_query.get(ui_item.0) else {
continue; continue;
}; };
let Ok((inventory, children)) = inventory_query.get(item_parent.0) else { let Ok((inventory, children)) = inventory_query.get(item_parent.0) else {
@ -115,7 +134,18 @@ fn on_ui_rotate(
None => &[], None => &[],
}; };
// TODO if inventory.can_rotate(item_query.as_readonly(), children, ui_item.0) {
let Ok(mut item) = item_query.get_mut(ui_item.0) else {
continue;
};
item.rotate();
let (left, top, min_width, min_height, new_ui_transform) = ui_item_node_data(&item);
node.left = left;
node.top = top;
node.min_width = min_width;
node.min_height = min_height;
ui_transform.rotation = new_ui_transform.rotation;
}
} }
} }
@ -165,7 +195,6 @@ fn inventory_slot_bundle(x: u32, y: u32, image: Handle<Image>) -> impl Bundle {
height: percent(100.), height: percent(100.),
grid_column: GridPlacement::start(x as i16 + 1), grid_column: GridPlacement::start(x as i16 + 1),
grid_row: GridPlacement::start(y as i16 + 1), grid_row: GridPlacement::start(y as i16 + 1),
align_items: AlignItems::Start,
..default() ..default()
}, },
Pickable { Pickable {
@ -178,22 +207,7 @@ fn inventory_slot_bundle(x: u32, y: u32, image: Handle<Image>) -> impl Bundle {
} }
fn ui_item_bundle(item: &Item, item_entity: Entity, image: Handle<Image>) -> impl Bundle { fn ui_item_bundle(item: &Item, item_entity: Entity, image: Handle<Image>) -> impl Bundle {
let (left, top, min_width, min_height, ui_transform) = match item.rotated { let (left, top, min_width, min_height, ui_transform) = ui_item_node_data(item);
true => (
percent(100.),
percent(-100.),
percent(100. * item.size.y as f32),
percent(100. * item.size.x as f32),
UiTransform::from_rotation(Rot2::radians(-FRAC_PI_2)),
),
false => (
auto(),
auto(),
percent(100. * item.size.x as f32),
percent(100. * item.size.y as f32),
UiTransform::default(),
),
};
( (
UiItem(item_entity), UiItem(item_entity),
ImageNode { ImageNode {

View file

@ -83,13 +83,17 @@ fn setup_global(mut commands: Commands) {
impl Plugin for ExpeditionPlugin { impl Plugin for ExpeditionPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_plugins(input::InputAssetPlugin::<InputAction>::default()) app.add_plugins((
input::InputAssetPlugin::<InputAction>::default(),
input::InputAssetPlugin::<UiAction>::default(),
))
.init_state::<GameState>() .init_state::<GameState>()
.insert_resource(ui::WindowSize::default()) .insert_resource(ui::WindowSize::default())
.add_systems(Startup, (player::setup_player, setup_global)) .add_systems(Startup, (player::setup_player, setup_global))
.add_systems(Update, ( .add_systems(Update, (
player::handle_input, player::handle_input,
ui::update_window_size, ui::update_window_size,
ui::handle_input,
insert_entity_name, insert_entity_name,
)) ))
.add_systems(OnEnter(GameState::Inventory), inventory::ui::setup_ui_inventory) .add_systems(OnEnter(GameState::Inventory), inventory::ui::setup_ui_inventory)
@ -99,6 +103,7 @@ impl Plugin for ExpeditionPlugin {
.register_type::<inventory::item::Item>() .register_type::<inventory::item::Item>()
.register_type::<inventory::ui::UiItem>() .register_type::<inventory::ui::UiItem>()
.register_type::<inventory::ui::UiInventorySlot>() .register_type::<inventory::ui::UiInventorySlot>()
.register_type::<inventory::ui::UiInventory>(); .register_type::<inventory::ui::UiInventory>()
.add_observer(inventory::ui::on_ui_rotate);
} }
} }