Everything compiles

main
Elijah Voigt 1 month ago
parent c3cd7f87b6
commit acbf89a077

@ -2,9 +2,9 @@ use bevy::{color::palettes::css::*, prelude::*};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(DefaultPlugins {})
.insert_resource(ClearColor(WHITE.into()))
.add_event::<CameraMovement>()
.add_message::<CameraMovement>()
.add_systems(Startup, setup_2d)
.add_systems(Update, (move_camera, track_camera_movement, parallax))
.run();
@ -82,7 +82,7 @@ fn move_camera(keys: Res<ButtonInput<KeyCode>>, mut camera: Single<&mut Transfor
struct CameraMovement(Vec3);
fn track_camera_movement(
mut events: EventWriter<CameraMovement>,
mut events: MessageWriter<CameraMovement>,
camera: Query<&Transform, (With<Camera>, Changed<Transform>)>,
mut last: Local<Vec3>,
) {

@ -4,7 +4,7 @@ fn main() {
App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
resolution: (640.0, 480.0).into(),
resolution: (640, 480).into(),
..default()
}),
..default()

@ -3,6 +3,7 @@ use games::*;
fn main() {
App::new()
.add_plugins((BaseGamePlugin {
target_resolution: (640, 480).into(),
name: "parallax example".into(),
title: "Parallax".into(),
game_type: GameType::Two,

@ -1,5 +1,3 @@
use avian3d::math::Vector;
// TEMP
use avian2d::prelude::*;
use bevy::{color::palettes::css::*, prelude::*};
@ -14,7 +12,7 @@ fn main() {
.add_systems(Update, draw_gizmos)
.add_systems(
Update,
event_detection.run_if(on_message::<CollisionStarted>.or(on_message::<CollisionEnded>)),
event_detection.run_if(on_message::<CollisionStart>.or(on_message::<CollisionEnd>)),
)
.add_observer(set_tree_position)
.run();
@ -63,7 +61,7 @@ fn setup(
commands.spawn((
Player,
RigidBody::Kinematic,
ExternalImpulse::default().with_persistence(true),
ConstantForce::default(),
Collider::rectangle(50.0, 50.0),
Mesh2d(meshes.add(Rectangle::new(50.0, 50.0))),
MeshMaterial2d(materials.add(Color::from(RED))),
@ -87,11 +85,7 @@ fn setup(
));
}
fn set_tree_position(
event: On<Add, TreePos>,
tree_pos: Query<&TreePos>,
mut commands: Commands,
) {
fn set_tree_position(event: On<Add, TreePos>, tree_pos: Query<&TreePos>, mut commands: Commands) {
let TreePos(pos) = tree_pos.get(event.entity).unwrap();
let x = if (*pos) > 0 {
(200.0 * (*pos) as f32) - 100.0
@ -104,13 +98,13 @@ fn set_tree_position(
fn move_player(
keyboard_input: Res<ButtonInput<KeyCode>>,
mut player: Single<&mut ExternalImpulse, With<Player>>,
mut player: Single<Forces, With<Player>>,
) {
const SPEED: f32 = 5.0;
if keyboard_input.pressed(KeyCode::ArrowLeft) {
player.set_impulse(Vec2::NEG_X * SPEED);
player.apply_local_force(Vec2::NEG_X * SPEED);
} else if keyboard_input.pressed(KeyCode::ArrowRight) {
player.set_impulse(Vec2::X * SPEED);
player.apply_local_force(Vec2::X * SPEED);
}
}
@ -132,15 +126,26 @@ fn draw_gizmos(mut gizmos: Gizmos, play_area: Single<&GlobalTransform, With<Rend
}
fn event_detection(
mut start_events: MessageReader<CollisionStarted>,
mut end_events: MessageReader<CollisionEnded>,
player: Single<&Player>,
mut start_events: MessageReader<CollisionStart>,
mut end_events: MessageReader<CollisionEnd>,
trees: Query<&TreePos>,
keyboard_input: Res<ButtonInput<KeyCode>>,
) {
debug_assert!(!(start_events.is_empty() && end_events.is_empty()));
let s = start_events.read().map(|CollisionStarted(a, b)| (a, b));
let e = end_events.read().map(|CollisionEnded(a, b)| (a, b));
let s = start_events.read().map(
|CollisionStart {
collider1,
collider2,
..
}| (collider1, collider2),
);
let e = end_events.read().map(
|CollisionEnd {
collider1,
collider2,
..
}| (collider1, collider2),
);
let mut events = s.chain(e);
let current_tree = events.find_map(|(a, b)| {
info!("{a:?}, {b:?}");

@ -1,222 +0,0 @@
use bevy::{
color::palettes::css::{BLUE, GREEN},
render::mesh::{SphereKind, SphereMeshBuilder},
};
use bevy_rapier3d::rapier::prelude::CollisionEventFlags;
use games::*;
/// Example showing using Rapier3d to do area intersection
///
/// Have you ever wanted to detect if a character is within some bounds?
/// This shows how to do that.
fn main() {
App::new()
.add_plugins(BaseGamePlugin::default())
.init_resource::<InsideArea>()
.add_systems(
Startup,
(
setup_physics_scene,
setup_ui,
position_camera.after(create_camera_3d),
),
)
.add_systems(
Update,
(
control_ball,
process_events,
sync_resource_to_ui::<InsideArea>.run_if(resource_changed::<InsideArea>),
)
.run_if(in_state(LoadingState::Idle)),
)
.run();
}
/// Which area the sphere is in/touching
#[derive(Component, Debug, Clone)]
enum AreaMarker {
Green,
Blue,
}
/// Setup a basic scene with:
/// * Floor
/// * A light for dramatic shadows
/// * A sphere that can move
/// * Two cubes that designate area intersection
fn setup_physics_scene(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// Create the ground.
// Make this a physical looking object
commands.spawn((
Collider::cuboid(100.0, 0.1, 100.0),
Transform::from_xyz(0.0, -1.0, 0.0),
Pickable::IGNORE,
Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(50.0)))),
MeshMaterial3d(materials.add(StandardMaterial {
base_color: RED.into(),
..Default::default()
})),
));
commands.spawn((
SpotLight {
color: WHITE.into(),
intensity: 10_000_000.0,
shadows_enabled: true,
..default()
},
Transform::from_xyz(0.0, 10.0, 10.0).looking_at(Vec3::ZERO, Vec3::Y),
));
// Create the bouncing ball.
commands.spawn((
RigidBody::Dynamic,
GravityScale(1.0),
Collider::ball(0.5),
ColliderMassProperties::Mass(2.0),
Restitution::coefficient(0.7),
ExternalImpulse::default(),
Transform::from_xyz(0.0, 4.0, 0.0),
ActiveEvents::all(),
Name::new("Ball"),
Mesh3d(meshes.add(SphereMeshBuilder::new(
0.5,
SphereKind::Uv {
sectors: 10,
stacks: 10,
},
))),
MeshMaterial3d(materials.add(StandardMaterial {
base_color: WHITE.into(),
..Default::default()
})),
));
// Create a box that the ball can pass into/through
commands.spawn((
Sensor,
Collider::cuboid(1.0, 1.0, 1.0),
Transform::from_xyz(0.0, 0.0, 2.0),
Mesh3d(meshes.add(Cuboid::new(2.0, 2.0, 2.0))),
Name::new("Green Area"),
MeshMaterial3d(materials.add(StandardMaterial {
base_color: GREEN.with_alpha(0.5).into(),
alpha_mode: AlphaMode::Blend,
..Default::default()
})),
AreaMarker::Green,
));
// Create a box that the ball can pass into/through
commands.spawn((
Sensor,
Collider::cuboid(1.0, 1.0, 1.0),
Transform::from_xyz(0.0, 0.0, -2.0),
Mesh3d(meshes.add(Cuboid::new(2.0, 2.0, 2.0))),
Name::new("Blue Area"),
MeshMaterial3d(materials.add(StandardMaterial {
base_color: BLUE.with_alpha(0.5).into(),
alpha_mode: AlphaMode::Blend,
..Default::default()
})),
AreaMarker::Blue,
));
}
/// Setup the UI for this example that indicates if the game "sees" the sphere
/// is inside the cube
fn setup_ui(mut commands: Commands) {
commands.spawn((
Node {
align_self: AlignSelf::Start,
justify_self: JustifySelf::Center,
..default()
},
Text("Placeholder".into()),
SyncResource::<InsideArea>::default(),
));
}
/// Position the world camera to get a better view
fn position_camera(mut query: Query<&mut Transform, (With<Camera>, With<Camera3d>)>) {
query.iter_mut().for_each(|mut t| {
*t = Transform::from_xyz(10.0, 10.0, 10.0).looking_at(Vec3::ZERO, Vec3::Y);
})
}
/// Control the ball based on arrow keys
fn control_ball(keys: Res<ButtonInput<KeyCode>>, mut ball: Single<&mut ExternalImpulse>) {
if keys.pressed(KeyCode::ArrowUp) {
ball.torque_impulse = Vec3::new(0.0, 0.0, 0.1);
}
if keys.pressed(KeyCode::ArrowDown) {
ball.torque_impulse = Vec3::new(0.0, 0.0, -0.1);
}
if keys.pressed(KeyCode::ArrowLeft) {
ball.torque_impulse = Vec3::new(0.1, 0.0, 0.0);
}
if keys.pressed(KeyCode::ArrowRight) {
ball.torque_impulse = Vec3::new(-0.1, 0.0, 0.0);
}
}
/// Maps CollisionEvent to a game-specific construct (did X enter/exit an area)
#[derive(Debug)]
enum WithinBounds {
Enter(Entity, Entity),
Exit(Entity, Entity),
}
/// Resource tracking what box the sphere is in
#[derive(Resource, Debug, Default, Clone)]
struct InsideArea(Option<AreaMarker>);
impl Display for InsideArea {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self.0 {
Some(AreaMarker::Blue) => write!(f, "Ball IS touching the BLUE box"),
Some(AreaMarker::Green) => write!(f, "Ball IS touching the GREEN box"),
None => write!(f, "Ball is NOT touching ANY box"),
}
}
}
/// Read collision events and procss them into resource updates to be displayed to the user
fn process_events(
mut events: MessageReader<CollisionEvent>,
areas: Query<&AreaMarker>,
mut inside: ResMut<InsideArea>,
) {
events
.read()
.filter_map(|collision_event| match collision_event {
CollisionEvent::Started(a, b, flags) => {
(*flags == CollisionEventFlags::SENSOR).then_some(WithinBounds::Enter(*a, *b))
}
CollisionEvent::Stopped(a, b, flags) => {
(*flags == CollisionEventFlags::SENSOR).then_some(WithinBounds::Exit(*a, *b))
}
})
.for_each(|within_bounds| match within_bounds {
WithinBounds::Enter(a, b) => {
if let Ok(x) = areas.get(a) {
inside.0 = Some(x.clone());
} else if let Ok(x) = areas.get(b) {
inside.0 = Some(x.clone());
}
}
WithinBounds::Exit(a, b) => {
if areas.contains(a) || areas.contains(b) {
inside.0 = None;
}
}
})
}

@ -85,11 +85,13 @@ fn setup_nav_tree(mut commands: Commands) {
))
.with_children(|parent| {
(0..5).for_each(|_| {
let title: String = lipsum_title_with_rng(thread_rng())
.split_whitespace()
.take(2)
.intersperse(" ")
.collect();
let title: String = Iterator::intersperse(
lipsum_title_with_rng(thread_rng())
.split_whitespace()
.take(2),
" ",
)
.collect();
parent.spawn((
children![Text::new(title),],
Node {
@ -137,7 +139,7 @@ fn control_menu(
hover_map: Res<HoverMap>,
) {
over_events.read().for_each(|over| {
let root = children.root_ancestor(over.target);
let root = children.root_ancestor(over.entity);
parents.iter_descendants(root).for_each(|child| {
if let Ok(mut n) = nav.get_mut(child) {
@ -157,9 +159,9 @@ fn control_menu(
// For all pointer out events
out_events.read().for_each(|out| {
// If a relative of out.target is hovered, do nothing
// If a relative of out.entity is hovered, do nothing
// Otherwise set to closed
let root = children.root_ancestor(out.target);
let root = children.root_ancestor(out.entity);
let tree_still_hovered = parents
.iter_descendants(root)
.any(|child| is_hovered.contains(&&child));

@ -3,7 +3,7 @@ use games::*;
fn main() {
App::new()
.add_plugins(BaseGamePlugin {
target_resolution: (360.0, 640.0).into(),
target_resolution: (360, 640).into(),
..default()
})
.add_systems(Startup, init_window_info)

@ -587,10 +587,7 @@ fn init_ui(mut commands: Commands, server: Res<AssetServer>) {
#[cfg(not(target_arch = "wasm32"))]
{
fn quit_game(
_event: On<Pointer<Click>>,
mut exit: MessageWriter<AppExit>,
) {
fn quit_game(_event: On<Pointer<Click>>, mut exit: MessageWriter<AppExit>) {
warn!("Quitting game");
exit.write(AppExit::Success);
}
@ -879,15 +876,11 @@ fn un_pause_game(mut next: ResMut<NextState<PlayerState>>) {
#[derive(Component, Clone, Message, EntityEvent)]
struct Flap {
entity: Entity
entity: Entity,
}
// Observer for flapping
fn flap(
event: On<Flap>,
mut bird: Query<Forces, With<Bird>>,
mut flaps: ResMut<Flaps>,
) {
fn flap(event: On<Flap>, mut bird: Query<Forces, With<Bird>>, mut flaps: ResMut<Flaps>) {
debug!("real flap for {:?}", event.entity);
// Increment flap stat
flaps.0 += 1;
@ -1149,28 +1142,40 @@ fn manage_score(
) {
match state.get() {
PlayerState::Rewind => {
start.read().for_each(|CollisionStart { collider1, collider2, .. }| {
// Set score to collided hitbox
if let Ok(Batch(this)) = hitboxes.get(*collider1) {
debug!("[Rewind] Setting score to {this}");
score.0 = this.saturating_sub(1);
} else if let Ok(Batch(this)) = hitboxes.get(*collider2) {
debug!("[Rewind] Setting score to {this}");
score.0 = this.saturating_sub(1);
}
})
start.read().for_each(
|CollisionStart {
collider1,
collider2,
..
}| {
// Set score to collided hitbox
if let Ok(Batch(this)) = hitboxes.get(*collider1) {
debug!("[Rewind] Setting score to {this}");
score.0 = this.saturating_sub(1);
} else if let Ok(Batch(this)) = hitboxes.get(*collider2) {
debug!("[Rewind] Setting score to {this}");
score.0 = this.saturating_sub(1);
}
},
)
}
_ => {
end.read().for_each(|CollisionEnd { collider1, collider2, .. }| {
// Set score to collided hitbox
if let Ok(Batch(this)) = hitboxes.get(*collider2) {
debug!("[Alive] Setting score to {this}");
score.0 = *this;
} else if let Ok(Batch(this)) = hitboxes.get(*collider1) {
debug!("[Alive] Setting score to {this}");
score.0 = *this;
}
})
end.read().for_each(
|CollisionEnd {
collider1,
collider2,
..
}| {
// Set score to collided hitbox
if let Ok(Batch(this)) = hitboxes.get(*collider2) {
debug!("[Alive] Setting score to {this}");
score.0 = *this;
} else if let Ok(Batch(this)) = hitboxes.get(*collider1) {
debug!("[Alive] Setting score to {this}");
score.0 = *this;
}
},
)
}
}
}
@ -1192,8 +1197,20 @@ fn move_batches(
state: Res<State<PlayerState>>,
mut commands: Commands,
) {
let s = start.read().map(|CollisionStart { collider1, collider2, .. }| (collider1, collider2));
let e = end.read().map(|CollisionEnd { collider1, collider2, .. }| (collider1, collider2));
let s = start.read().map(
|CollisionStart {
collider1,
collider2,
..
}| (collider1, collider2),
);
let e = end.read().map(
|CollisionEnd {
collider1,
collider2,
..
}| (collider1, collider2),
);
let c = s.chain(e);
c.for_each(|(a, b)| {
debug!("[batches] Collision {a} -> {b}");

@ -1,5 +1,4 @@
#![feature(try_blocks)]
// Bevy basically forces "complex types" with Querys
#![allow(clippy::type_complexity)]
@ -71,10 +70,10 @@ fn main() {
.after(clear_line),
assert_grid_position_uniqueness.run_if(any_component_changed::<GridPosition>),
sync_health
.run_if(any_component_changed::<Health>.or(any_component_added::<Health>)),
.run_if(any_component_changed::<Health>.or(any_component_added::<Health>)),
damage_on_place_shape.run_if(any_component_removed::<Shape>),
damage_on_clear_line.run_if(any_component_removed::<LineBlock>),
damage_over_time.run_if(clock_cycle(5.0))
damage_over_time.run_if(clock_cycle(5.0)),
),
)
// UI systems
@ -140,16 +139,16 @@ struct GridPosition {
}
impl GridPosition {
fn with_offset(self, other_x: isize, other_y: isize) -> Result<GridPosition, GameError> {
fn with_offset(self, other_x: isize, other_y: isize) -> Result<GridPosition, OutOfBoundsError> {
let x = self.x as isize + other_x;
let y = self.y as isize + other_y;
if x >= X_MAX as isize {
Err(GameError::OutOfBoundsLeft)
Err(OutOfBoundsError::Left)
} else if x < 0 {
Err(GameError::OutOfBoundsRight)
Err(OutOfBoundsError::Right)
} else if y < 0 {
Err(GameError::OutOfBoundsDown)
Err(OutOfBoundsError::Down)
} else {
Ok(GridPosition {
x: x as usize,
@ -166,15 +165,13 @@ impl Display for GridPosition {
}
#[derive(Error, Debug, PartialEq)]
enum GameError {
enum OutOfBoundsError {
#[error("Coordinates are out of bounds: Left")]
OutOfBoundsLeft,
Left,
#[error("Coordinates are out of bounds: Right")]
OutOfBoundsRight,
Right,
#[error("Coordinates are out of bounds: Down")]
OutOfBoundsDown,
#[error("Coordiante collision")]
Collision,
Down,
}
impl Default for GridPosition {
@ -690,8 +687,8 @@ impl Shape {
fn coordinates(
&self,
center: &GridPosition,
) -> impl Iterator<Item = Result<GridPosition, GameError>> {
let mut v: Vec<Result<GridPosition, GameError>> = Vec::new();
) -> impl Iterator<Item = Result<GridPosition, OutOfBoundsError>> {
let mut v: Vec<Result<GridPosition, OutOfBoundsError>> = Vec::new();
match self {
Self::M4(inner) => {
for (i, y) in (-1..3).rev().enumerate() {
@ -837,19 +834,34 @@ fn kb_input(
// Up arrow should rotate if in falling mode
// Only move up if in falling::off mode
KeyCode::ArrowUp => {
commands.entity(e).trigger(|entity| Movement { entity, direction: MovementDirection::Rotate });
commands.entity(e).trigger(|entity| Movement {
entity,
direction: MovementDirection::Rotate,
});
}
KeyCode::ArrowDown => {
commands.entity(e).trigger(|entity| Movement { entity, direction: MovementDirection::Down });
commands.entity(e).trigger(|entity| Movement {
entity,
direction: MovementDirection::Down,
});
}
KeyCode::ArrowLeft => {
commands.entity(e).trigger(|entity| Movement { entity, direction: MovementDirection::Left });
commands.entity(e).trigger(|entity| Movement {
entity,
direction: MovementDirection::Left,
});
}
KeyCode::ArrowRight => {
commands.entity(e).trigger(|entity| Movement { entity, direction: MovementDirection::Right });
commands.entity(e).trigger(|entity| Movement {
entity,
direction: MovementDirection::Right,
});
}
KeyCode::Enter => {
commands.entity(e).trigger(|entity| Movement { entity, direction: MovementDirection::Skip });
commands.entity(e).trigger(|entity| Movement {
entity,
direction: MovementDirection::Skip,
});
}
KeyCode::Space => {
commands.entity(e).trigger(|entity| Swap { entity });
@ -876,7 +888,10 @@ fn kb_input(
fn falling(mut shape: Query<Entity, With<Shape>>, mut commands: Commands) {
shape.iter_mut().for_each(|e| {
debug!("Making {:?} fall", e);
commands.entity(e).trigger(|entity| Movement { entity, direction: MovementDirection::Down });
commands.entity(e).trigger(|entity| Movement {
entity,
direction: MovementDirection::Down,
});
});
}
@ -994,7 +1009,7 @@ fn adjust_block_lines(
/// Swap the current piece out
#[derive(EntityEvent, Message, Copy, Clone, PartialEq)]
struct Swap {
entity: Entity
entity: Entity,
}
/// Movement events evented on the piece
@ -1038,7 +1053,10 @@ fn movement(
.collect(),
};
let new_shape = match event.event().direction {
MovementDirection::Down | MovementDirection::Left | MovementDirection::Right | MovementDirection::Skip => *this_shape,
MovementDirection::Down
| MovementDirection::Left
| MovementDirection::Right
| MovementDirection::Skip => *this_shape,
MovementDirection::Rotate => this_shape.rotated(),
};
debug!(
@ -1048,23 +1066,21 @@ fn movement(
);
for position in new_positions {
match position {
Err(GameError::OutOfBoundsLeft) | Err(GameError::OutOfBoundsRight) => (), // Do nothing
Err(GameError::OutOfBoundsDown) => {
Err(OutOfBoundsError::Left) | Err(OutOfBoundsError::Right) => (), // Do nothing
Err(OutOfBoundsError::Down) => {
commands.entity(event.entity).remove::<Shape>();
}
Err(GameError::Collision) => panic!("This shouldn't happen!"),
Ok(new_center) => {
let new_blocks = new_shape.coordinates(&new_center);
for block_gp in new_blocks {
match block_gp {
Err(GameError::OutOfBoundsLeft) | Err(GameError::OutOfBoundsRight) => {
Err(OutOfBoundsError::Left) | Err(OutOfBoundsError::Right) => {
return;
} // Do nothing
Err(GameError::OutOfBoundsDown) => {
Err(OutOfBoundsError::Down) => {
commands.entity(event.entity).remove::<Shape>();
return;
}
Err(GameError::Collision) => panic!("This shouldn't happen!"),
Ok(gp) => {
for other_gp in inactive.iter() {
// If there would be a collision between blocks
@ -1209,13 +1225,10 @@ fn sync_health(
#[derive(Message, EntityEvent)]
struct Damage {
entity: Entity,
quantity: f32
quantity: f32,
}
fn deal_damage(
event: On<Damage>,
mut healths: Query<&mut Health>
) {
fn deal_damage(event: On<Damage>, mut healths: Query<&mut Health>) {
healths.get_mut(event.entity).unwrap().0 -= event.event().quantity
}
@ -1226,7 +1239,10 @@ fn damage_on_place_shape(
) {
events.read().for_each(|_| {
enemies.iter().for_each(|e| {
commands.entity(e).trigger(|entity| Damage { entity, quantity: 1.0 });
commands.entity(e).trigger(|entity| Damage {
entity,
quantity: 1.0,
});
});
});
}
@ -1238,14 +1254,17 @@ fn damage_on_clear_line(
) {
events.read().for_each(|_| {
enemies.iter().for_each(|e| {
commands.entity(e).trigger(|entity| Damage { entity, quantity: 1.0 });
commands.entity(e).trigger(|entity| Damage {
entity,
quantity: 1.0,
});
});
});
}
fn damage_over_time(
protagonist: Single<Entity, With<Protagonist>>,
mut commands: Commands,
) {
commands.entity(*protagonist).trigger(|entity| Damage { entity, quantity: 1.0 });
fn damage_over_time(protagonist: Single<Entity, With<Protagonist>>, mut commands: Commands) {
commands.entity(*protagonist).trigger(|entity| Damage {
entity,
quantity: 1.0,
});
}

@ -14,7 +14,8 @@ impl Plugin for TreesDebugPlugin {
.run_if(on_message::<Pointer<Over>>.or(on_message::<Pointer<Out>>)),
hide_menu.run_if(any_component_changed::<NavState>),
clear_monologue.run_if(any_component_changed::<NavState>),
control_menu.run_if(on_message::<Pointer<Over>>.or(on_message::<Pointer<Out>>)),
control_menu
.run_if(on_message::<Pointer<Over>>.or(on_message::<Pointer<Out>>)),
delete_tree.run_if(on_message::<Pointer<Click>>),
drag_tree.run_if(on_message::<Pointer<Drag>>),
)
@ -278,6 +279,7 @@ fn monologue_asset_tooltip(
mut over_events: MessageReader<Pointer<Over>>,
mut out_events: MessageReader<Pointer<Out>>,
mut tooltip: ResMut<ToolTip>,
server: Res<AssetServer>,
trees: Query<(&Tree, Option<&TreeMonologue>)>,
) {
out_events
@ -291,12 +293,10 @@ fn monologue_asset_tooltip(
.read()
.filter_map(|Pointer { entity, .. }| trees.contains(*entity).then_some(*entity))
.for_each(|e| match trees.get(e) {
Ok((_tree, Some(TreeMonologue(id)))) => {
match todo!("Get path for this asset") {
Some(p) => tooltip.insert("Script", format!("{p}")),
None => tooltip.insert("Script", "A".into()),
}
}
Ok((_tree, Some(TreeMonologue(id)))) => match server.get_path(*id) {
Some(p) => tooltip.insert("Script", format!("{p}")),
None => tooltip.insert("Script", "A".into()),
},
Ok((_tree, None)) => {
tooltip.insert("Script", "N/A".into());
}

@ -457,6 +457,7 @@ fn assign_monologue_to_tree(
query: Query<Entity, (With<Tree>, Without<TreeMonologue>)>,
mut notice: ResMut<Notice>,
mut commands: Commands,
server: Res<AssetServer>,
) {
// Kinda a weird hack because query does not update
// If we do this inline we assign new monologues to the same first tree
@ -467,10 +468,10 @@ fn assign_monologue_to_tree(
// Get a valid tree to assign an entity to
if let Some(tree) = t.next() {
// Create the TreeMonologue component
let monologue = TreeMonologue(event.0.clone());
let monologue = TreeMonologue(event.0);
// Insert the component to the entity
commands.entity(tree).insert(monologue);
} else if let Some(path) = todo!("event.0.path() -> assetId") {
} else if let Some(path) = server.get_path(event.0) {
error!("No trees avaliable for {path:?}");
notice.0 = format!("No trees avaliable for {path:?}");
} else {

@ -19,14 +19,13 @@ pub use std::fmt::Display;
// Community libraries
pub use bevy::{
asset::{AssetLoader, AssetMetaCheck, LoadContext, LoadState, LoadedFolder, io::Reader, RenderAssetUsages, uuid_handle},
math::{FloatOrd},
camera::{*, primitives::*, visibility::*},
asset::{
AssetLoader, AssetMetaCheck, LoadContext, LoadState, LoadedFolder, RenderAssetUsages,
io::Reader, uuid_handle,
},
camera::{primitives::*, visibility::*, *},
color::palettes::css::*,
gizmos::{aabb::AabbGizmoPlugin, light::LightGizmoPlugin},
render::{
render_resource::{Extent3d, TextureDimension, TextureFormat, TextureUsages},
},
input::{
ButtonState,
common_conditions::{input_just_pressed, input_just_released, input_pressed},
@ -34,16 +33,18 @@ pub use bevy::{
mouse::MouseMotion,
mouse::{MouseScrollUnit, MouseWheel},
},
math::FloatOrd,
pbr::wireframe::{WireframeConfig, WireframePlugin},
platform::{collections::HashMap, hash::RandomState},
prelude::*,
reflect::TypePath,
render::render_resource::{Extent3d, TextureDimension, TextureFormat, TextureUsages},
sprite_render::*,
window::{WindowResized, WindowResolution},
};
pub use itertools::Itertools;
pub use serde::Deserialize;
pub use thiserror::Error;
pub use itertools::Itertools;
// Internal modules
pub use base_game::*;

@ -39,11 +39,7 @@ impl Default for Style {
}
fn add_ui_button(added: Query<Entity, Added<Button>>, mut commands: Commands) {
fn over(
event: On<Pointer<Over>>,
mut query: Query<&mut BorderColor>,
style: Res<Style>,
) {
fn over(event: On<Pointer<Over>>, mut query: Query<&mut BorderColor>, style: Res<Style>) {
if let Ok(mut bc) = query.get_mut(event.entity) {
debug!("pointer over {:?}", event.entity);
bc.set_all(style.accent);

Loading…
Cancel
Save