diff --git a/Cargo.lock b/Cargo.lock index 98f1e8a..0cf2131 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -273,6 +273,24 @@ dependencies = [ "futures-lite", ] +[[package]] +name = "async-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" +dependencies = [ + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix 1.1.3", + "slab", + "windows-sys 0.61.2", +] + [[package]] name = "async-lock" version = "3.4.2" @@ -921,6 +939,7 @@ dependencies = [ "bevy_post_process", "bevy_ptr", "bevy_reflect", + "bevy_remote", "bevy_render", "bevy_scene", "bevy_shader", @@ -1201,6 +1220,31 @@ dependencies = [ "uuid", ] +[[package]] +name = "bevy_remote" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0129e24bf3e281dd52996a9290c35f8c4821ca09e1ce8b8b222671e1ad9da0c" +dependencies = [ + "anyhow", + "async-channel", + "async-io", + "bevy_app", + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_log", + "bevy_platform", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "http-body-util", + "hyper", + "serde", + "serde_json", + "smol-hyper", +] + [[package]] name = "bevy_render" version = "0.18.0" @@ -1394,6 +1438,7 @@ checksum = "990ffedd374dd2c4fe8f0fd4bcefd5617d1ee59164b6c3fcc356a69b48e26e8e" dependencies = [ "async-channel", "async-executor", + "async-io", "async-task", "atomic-waker", "bevy_platform", @@ -2816,6 +2861,72 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", +] + [[package]] name = "image" version = "0.25.9" @@ -4367,6 +4478,19 @@ dependencies = [ "xkeysym", ] +[[package]] +name = "smol-hyper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7428a49d323867702cd12b97b08a6b0104f39ec13b49117911f101271321bc1a" +dependencies = [ + "async-executor", + "async-io", + "futures-io", + "hyper", + "pin-project-lite", +] + [[package]] name = "smol_str" version = "0.2.2" @@ -4582,6 +4706,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +dependencies = [ + "pin-project-lite", +] + [[package]] name = "toml" version = "0.9.12+spec-1.1.0" diff --git a/Cargo.toml b/Cargo.toml index 6801f05..56f07ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ version = "0.1.0" edition = "2024" [dependencies] -bevy = { version = "0.18.0", features = ["debug"] } +bevy = { version = "0.18.0", features = ["bevy_remote", "debug"] } bevy_common_assets = { version = "0.15.0", features = ["toml"] } bevy_input = { version = "0.18.0", features = ["serde", "serialize"] } leafwing-input-manager = "0.20.0" diff --git a/src/inventory/item.rs b/src/inventory/item.rs index 334a3b3..e3523b1 100644 --- a/src/inventory/item.rs +++ b/src/inventory/item.rs @@ -2,7 +2,7 @@ use std::mem::swap; use bevy::prelude::*; -#[derive(Component, Clone, Debug)] +#[derive(Component, Clone, Debug, Reflect)] pub struct Item { pub size: UVec2, pub position: Option, diff --git a/src/inventory/mod.rs b/src/inventory/mod.rs index eb9abca..54a7b9a 100644 --- a/src/inventory/mod.rs +++ b/src/inventory/mod.rs @@ -3,13 +3,13 @@ use bevy::prelude::*; pub mod item; pub mod ui; -#[derive(Component)] +#[derive(Component, Reflect)] pub struct Inventory { pub size: UVec2, } /// Marker that this inventory will show up when UI is built -#[derive(Component)] +#[derive(Component, Reflect)] pub struct ActiveInventory; impl Inventory { diff --git a/src/inventory/ui.rs b/src/inventory/ui.rs index ad72efd..2ccbcd9 100644 --- a/src/inventory/ui.rs +++ b/src/inventory/ui.rs @@ -1,25 +1,45 @@ use std::f32::consts::FRAC_PI_2; -use bevy::prelude::*; +use bevy::{ecs::component::{ComponentId, ComponentIdFor}, prelude::*}; use crate::{inventory::{ActiveInventory, Inventory, item::Item}, ui::{UiRoot, WindowSize}}; const UI_SLOT_ASSET_PATH: &'static str = "sprites/ui/inventory_slot.png"; const TEMP_ITEM_PATH: &'static str = "sprites/items/choco_bar.png"; -#[derive(Component)] +#[derive(Component, Reflect)] #[require(Node)] pub struct UiInventory; -#[derive(Component)] +#[derive(Component, Reflect)] #[require(Node, ImageNode)] pub struct UiInventorySlot(UVec2); -#[derive(Component)] +#[derive(Component, Reflect)] #[require(Node, ImageNode)] pub struct UiItem(Entity); -fn ui_inventory_bundle(inventory: &Inventory, window_size: &Res) -> impl Bundle { +fn on_item_drag_drop( + event: On>, + ui_item_query: Query<&UiItem>, + slot_query: Query<(&UiInventorySlot, Option<&Children>)>, +) { + info!("dragdrop {} {}", event.dropped, event.event_target()); + let Ok(ui_item) = ui_item_query.get(event.dropped) else { + return; + }; + let Ok((slot, _)) = slot_query.get(event.event_target()) else { + return; + }; + + info!("Item {:?} dropped on {:?}", ui_item.0, slot.0); +} + +fn ui_inventory_bundle( + inventory: &Inventory, + window_size: &Res, + _slot_id: ComponentId, +) -> impl Bundle { let window_ratio = window_size.aspect_ratio(); let (width, height) = { if window_ratio >= 1. { @@ -41,6 +61,10 @@ fn ui_inventory_bundle(inventory: &Inventory, window_size: &Res) -> grid_auto_rows: vec![GridTrack::percent(100. / inventory.size.y as f32)], ..default() }, + Pickable::IGNORE, + GlobalZIndex::default(), + Observer::new(on_item_drag_drop) +// .with_component(slot_id), ) } @@ -60,6 +84,10 @@ fn inventory_slot_bundle(x: u32, y: u32, image: Handle) -> impl Bundle { align_items: AlignItems::Start, ..default() }, + Pickable { + should_block_lower: true, + is_hoverable: true, + }, ) } @@ -97,6 +125,10 @@ fn ui_item_bundle(item: &Item, item_entity: Entity, image: Handle) -> imp BackgroundColor(Color::hsla(0., 0., 0., 0.5)), ui_transform, GlobalZIndex(1), + Pickable { + should_block_lower: false, + is_hoverable: true, + }, ) } @@ -106,6 +138,7 @@ pub fn setup_ui_inventory( inventory_query: Query<(&Inventory, Option<&Children>), With>, item_query: Query<&Item>, root_query: Query>, + slot_id: ComponentIdFor, window_size: Res, ) { let Ok(root) = root_query.single() else { @@ -129,7 +162,7 @@ pub fn setup_ui_inventory( } None => Vec::new(), }; - let inventory_entity = commands.spawn(ui_inventory_bundle(inventory, &window_size)) + let inventory_entity = commands.spawn(ui_inventory_bundle(inventory, &window_size, slot_id.get())) .with_children(|commands| { for x in 0..inventory.size.x { for y in 0..inventory.size.y { let mut slot_commands = commands.spawn(inventory_slot_bundle(x, y, ui_slot_image.clone())); @@ -139,7 +172,8 @@ pub fn setup_ui_inventory( } } } }).id(); - commands.entity(root).add_child(inventory_entity); + commands.entity(root) + .add_child(inventory_entity); // for simplicity we'll show only first inventory break; diff --git a/src/lib.rs b/src/lib.rs index 058853f..c45a167 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,6 +73,12 @@ impl Plugin for ExpeditionPlugin { ui::update_window_size, )) .add_systems(OnEnter(GameState::Inventory), inventory::ui::setup_ui_inventory) - .add_systems(OnExit(GameState::Inventory), inventory::ui::clear_ui_inventory); + .add_systems(OnExit(GameState::Inventory), inventory::ui::clear_ui_inventory) + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::(); } } diff --git a/src/main.rs b/src/main.rs index 4f85e42..a162af9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use bevy::prelude::*; +use bevy::{prelude::*, remote::{RemotePlugin, http::RemoteHttpPlugin}}; use expedition_demo::ExpeditionPlugin; @@ -6,5 +6,7 @@ fn main() { App::new() .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) .add_plugins(ExpeditionPlugin) + .add_plugins(RemotePlugin::default()) + .add_plugins(RemoteHttpPlugin::default()) .run(); } diff --git a/src/player.rs b/src/player.rs index 5968cf3..06dfcd0 100644 --- a/src/player.rs +++ b/src/player.rs @@ -3,7 +3,7 @@ use leafwing_input_manager::prelude::*; use crate::{GameState, InputAction as Action, inventory::{ActiveInventory, Inventory, item::Item}}; -#[derive(Component)] +#[derive(Component, Reflect)] pub struct Player { // px/s speed: f32, diff --git a/src/ui.rs b/src/ui.rs index 0d70e7e..4851272 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,6 +1,6 @@ use bevy::{prelude::*, window::WindowResized}; -#[derive(Component)] +#[derive(Component, Reflect)] #[require(Node)] pub struct UiRoot; @@ -24,6 +24,7 @@ impl UiRoot { justify_self: JustifySelf::Center, ..default() }, + Pickable::IGNORE, ) } }