diff --git a/src/inventory/ui.rs b/src/inventory/ui.rs index d8c9a9a..013e910 100644 --- a/src/inventory/ui.rs +++ b/src/inventory/ui.rs @@ -27,7 +27,10 @@ pub struct UiItem(pub Entity); pub struct HoveredItem; #[derive(Component, Reflect)] -pub struct DraggedItem(pub Item); +pub struct HoveredSlot; + +#[derive(Component, Reflect)] +pub struct DraggedItem(pub Item, pub UVec2); fn ui_item_node_data(item: &Item) -> (Val, Val, Val, Val, UiTransform) { match item.rotated { @@ -63,9 +66,21 @@ fn reset_slots_colors(query: Query<&mut ImageNode, With>) { } } -fn on_slot_over(e: On>, mut query: Query<&mut ImageNode, With>) { - if let Ok(mut image) = query.get_mut(e.event_target()) { +fn on_slot_over( + e: On>, + mut commands: Commands, + mut image_query: Query<&mut ImageNode, With>, + hovered_slots: Query>, + has_dragged_item: Option>>, +) { + if let Ok(mut image) = image_query.get_mut(e.event_target()) { image.color = Color::WHITE.darker(0.3); + }; + for slot_id in hovered_slots { + commands.entity(slot_id).remove::(); + } + if has_dragged_item.is_none() { + commands.entity(e.event_target()).insert(HoveredSlot); } } @@ -104,13 +119,19 @@ fn on_item_drag_start( mut commands: Commands, ui_query: Query<&UiItem, With>, item_query: Query<&Item>, + hovered_slot: Single<&UiInventorySlot, With> ) { if let Ok(ui_item) = ui_query.get(e.event_target()) { let Ok(item) = item_query.get(ui_item.0) else { error!("UiItem {} is pointing to non-existing Item", e.event_target()); return; }; - commands.entity(e.event_target()).insert(DraggedItem(item.clone())); + let Some(item_position) = item.position else { + return; + }; + let slot_position = hovered_slot.0; + let diff = slot_position - item_position; + commands.entity(e.event_target()).insert(DraggedItem(item.clone(), diff)); } } @@ -138,6 +159,7 @@ fn on_item_drag_drop( ui_inventory_query: Query<&UiInventory>, mut item_query: Query<&mut Item>, slot_query: Query<(&ChildOf, &UiInventorySlot, Option<&Children>)>, + slot_id_query: Query<(Entity, &UiInventorySlot, &ChildOf), With>, inventory_query: Query<(&Inventory, Option<&Children>)>, ) { let Ok((ui_item_entity, UiItem(item_entity), mut dragged_item, node, ui_transform)) = ui_item_query.get_mut(event.dropped) else { @@ -161,16 +183,25 @@ fn on_item_drag_drop( None => &[], }; + let actual_position = new_position.as_ivec2() - dragged_item.1.as_ivec2(); + info!("{actual_position:?}"); let temp_item = &mut dragged_item.0; - temp_item.position = Some(*new_position); + if actual_position.is_negative_bitmask() == 0 { + temp_item.position = Some(actual_position.as_uvec2()); + } + + let Some((slot_id, _, _)) = slot_id_query.iter().find(|(_, slot_pos, slot_parent_id)| slot_pos.0 == temp_item.position.unwrap() && slot_parent_id == &slot_parent) else { + return; + }; if inventory.can_replace(item_query.as_readonly(), items, *item_entity, temp_item) { let mut item = item_query.get_mut(*item_entity).unwrap(); item.position = temp_item.position; item.size = temp_item.size; item.rotated = temp_item.rotated; - commands.entity(ui_item_entity).insert(ChildOf(event.event_target())); + commands.entity(ui_item_entity).insert(ChildOf(slot_id)); commands.entity(*item_entity).insert(ChildOf(*inventory_id)); + commands.entity(slot_id).insert(HoveredSlot); update_ui_node(item.as_ref(), node, ui_transform); } else { if let Ok(item) = item_query.get(*item_entity) { @@ -202,6 +233,7 @@ pub fn on_ui_rotate( let (was_rotated, item) = match maybe_dragged { Some(mut temp_item) => { temp_item.0.rotate(); + temp_item.1 = uvec2(temp_item.1.y, temp_item.1.x); (true, Some(temp_item.0.clone())) }, None => { diff --git a/src/tests.rs b/src/tests.rs index ead9dc3..ad8978b 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -198,7 +198,7 @@ mod inventory { inventory_query: Query<(&Inventory, &Children)>, ) { let (inventory, children) = inventory_query.single().unwrap(); - let (replacable_id, DraggedItem(replacing_item), RotatingMarker(assertion)) = replacable_item.single() + let (replacable_id, DraggedItem(replacing_item, _), RotatingMarker(assertion)) = replacable_item.single() .unwrap(); if *assertion { assert!(inventory.can_replace(item_query, children, replacable_id, replacing_item)); @@ -369,7 +369,7 @@ mod inventory { let system = world.register_system(replace_item); world.spawn(inventory()) - .with_child((item_a(), DraggedItem(item_c()), RotatingMarker(true))) + .with_child((item_a(), DraggedItem(item_c(), UVec2::ZERO), RotatingMarker(true))) .with_child(item_b()) .with_child(item_d()); @@ -383,7 +383,7 @@ mod inventory { let system = world.register_system(replace_item); world.spawn(inventory()) - .with_child((item_a(), DraggedItem(item_c()), RotatingMarker(false))) + .with_child((item_a(), DraggedItem(item_c(), UVec2::ZERO), RotatingMarker(false))) .with_child(item_b()) .with_child(item_c()) .with_child(item_d());