Further migration to 0.17. Saving my place again

main
Elijah Voigt 1 month ago
parent 602d6a923e
commit c3cd7f87b6

@ -15,7 +15,7 @@ fn main() {
title: "flappy bird (with rewind)".into(), title: "flappy bird (with rewind)".into(),
name: "flappy".into(), name: "flappy".into(),
game_type: GameType::Two, game_type: GameType::Two,
target_resolution: (360.0, 640.0).into(), target_resolution: (360, 640).into(),
..default() ..default()
}, },
Physics2dPlugin, Physics2dPlugin,
@ -99,8 +99,8 @@ fn main() {
(update_tooltip, debug_trail).run_if(in_state(DebuggingState::On)), (update_tooltip, debug_trail).run_if(in_state(DebuggingState::On)),
// TODO: Add run_if to this system // TODO: Add run_if to this system
update_batch_position.run_if(any_component_changed::<Batch>), update_batch_position.run_if(any_component_changed::<Batch>),
move_batches.run_if(on_message::<CollisionStarted>.or(on_message::<CollisionEnded>)), move_batches.run_if(on_message::<CollisionStart>.or(on_message::<CollisionEnd>)),
manage_score.run_if(on_message::<CollisionStarted>.or(on_message::<CollisionEnded>)), manage_score.run_if(on_message::<CollisionStart>.or(on_message::<CollisionEnd>)),
shimmer_button::<RewindButton>.run_if(in_state(PlayerState::Stasis)), shimmer_button::<RewindButton>.run_if(in_state(PlayerState::Stasis)),
shimmer_button::<FlapButton>.run_if(in_state(PlayerState::Pause)), shimmer_button::<FlapButton>.run_if(in_state(PlayerState::Pause)),
), ),
@ -142,7 +142,7 @@ struct Tape {
capacity: usize, capacity: usize,
linear_velocities: VecDeque<LinearVelocity>, linear_velocities: VecDeque<LinearVelocity>,
angular_velocities: VecDeque<AngularVelocity>, angular_velocities: VecDeque<AngularVelocity>,
external_impulses: VecDeque<ExternalImpulse>, constant_forces: VecDeque<ConstantForce>,
positions: VecDeque<Position>, positions: VecDeque<Position>,
rotations: VecDeque<Rotation>, rotations: VecDeque<Rotation>,
} }
@ -153,7 +153,7 @@ impl Tape {
capacity, capacity,
linear_velocities: VecDeque::with_capacity(capacity), linear_velocities: VecDeque::with_capacity(capacity),
angular_velocities: VecDeque::with_capacity(capacity), angular_velocities: VecDeque::with_capacity(capacity),
external_impulses: VecDeque::with_capacity(capacity), constant_forces: VecDeque::with_capacity(capacity),
positions: VecDeque::with_capacity(capacity), positions: VecDeque::with_capacity(capacity),
rotations: VecDeque::with_capacity(capacity), rotations: VecDeque::with_capacity(capacity),
} }
@ -163,7 +163,7 @@ impl Tape {
&mut self, &mut self,
lv: LinearVelocity, lv: LinearVelocity,
av: AngularVelocity, av: AngularVelocity,
ei: ExternalImpulse, ei: ConstantForce,
p: Position, p: Position,
r: Rotation, r: Rotation,
) { ) {
@ -171,14 +171,14 @@ impl Tape {
if self.linear_velocities.len() == self.capacity { if self.linear_velocities.len() == self.capacity {
self.linear_velocities.pop_front().unwrap(); self.linear_velocities.pop_front().unwrap();
self.angular_velocities.pop_front().unwrap(); self.angular_velocities.pop_front().unwrap();
self.external_impulses.pop_front().unwrap(); self.constant_forces.pop_front().unwrap();
self.positions.pop_front().unwrap(); self.positions.pop_front().unwrap();
self.rotations.pop_front().unwrap(); self.rotations.pop_front().unwrap();
} }
self.linear_velocities.push_back(lv); self.linear_velocities.push_back(lv);
self.angular_velocities.push_back(av); self.angular_velocities.push_back(av);
self.external_impulses.push_back(ei); self.constant_forces.push_back(ei);
self.positions.push_back(p); self.positions.push_back(p);
self.rotations.push_back(r); self.rotations.push_back(r);
} }
@ -188,7 +188,7 @@ impl Tape {
) -> Option<( ) -> Option<(
LinearVelocity, LinearVelocity,
AngularVelocity, AngularVelocity,
ExternalImpulse, ConstantForce,
Position, Position,
Rotation, Rotation,
)> { )> {
@ -197,10 +197,10 @@ impl Tape {
} else { } else {
let lv = self.linear_velocities.pop_back().unwrap(); let lv = self.linear_velocities.pop_back().unwrap();
let av = self.angular_velocities.pop_back().unwrap(); let av = self.angular_velocities.pop_back().unwrap();
let ei = self.external_impulses.pop_back().unwrap(); let cf = self.constant_forces.pop_back().unwrap();
let p = self.positions.pop_back().unwrap(); let p = self.positions.pop_back().unwrap();
let r = self.rotations.pop_back().unwrap(); let r = self.rotations.pop_back().unwrap();
Some((lv, av, ei, p, r)) Some((lv, av, cf, p, r))
} }
} }
} }
@ -214,7 +214,7 @@ fn init_bird(mut commands: Commands, bird_assets: Res<BirdAssets>) {
RigidBody::Static, RigidBody::Static,
Collider::rectangle(1.0, 1.0), Collider::rectangle(1.0, 1.0),
Mass(10.0), Mass(10.0),
ExternalImpulse::default().with_persistence(false), ConstantForce::default(),
MaxLinearSpeed(500.0), MaxLinearSpeed(500.0),
); );
@ -349,7 +349,7 @@ fn populate_ceiling(
} }
fn move_pipe( fn move_pipe(
event: On<OnInsert, Batch>, event: On<Insert, Batch>,
mut pipes: Query<(&Batch, &Pipe, &mut Transform)>, mut pipes: Query<(&Batch, &Pipe, &mut Transform)>,
rand: Res<Rand>, rand: Res<Rand>,
) { ) {
@ -524,42 +524,42 @@ fn init_ui(mut commands: Commands, server: Res<AssetServer>) {
parent.spawn(( parent.spawn((
Text::new("Game Over...?"), Text::new("Game Over...?"),
TextColor(BLACK.into()), TextColor(BLACK.into()),
TextLayout::new_with_justify(JustifyText::Center), TextLayout::new_with_justify(Justify::Center),
)); ));
parent.spawn(( parent.spawn((
SyncResource::<Score>::default(), SyncResource::<Score>::default(),
Text::default(), Text::default(),
TextColor(BLACK.into()), TextColor(BLACK.into()),
TextLayout::new_with_justify(JustifyText::Center), TextLayout::new_with_justify(Justify::Center),
)); ));
parent.spawn(( parent.spawn((
SyncResource::<LongestRun>::default(), SyncResource::<LongestRun>::default(),
Text::default(), Text::default(),
TextColor(BLACK.into()), TextColor(BLACK.into()),
TextLayout::new_with_justify(JustifyText::Center), TextLayout::new_with_justify(Justify::Center),
)); ));
parent.spawn(( parent.spawn((
SyncResource::<Deaths>::default(), SyncResource::<Deaths>::default(),
Text::default(), Text::default(),
TextColor(BLACK.into()), TextColor(BLACK.into()),
TextLayout::new_with_justify(JustifyText::Center), TextLayout::new_with_justify(Justify::Center),
)); ));
parent.spawn(( parent.spawn((
SyncResource::<Flaps>::default(), SyncResource::<Flaps>::default(),
Text::default(), Text::default(),
TextColor(BLACK.into()), TextColor(BLACK.into()),
TextLayout::new_with_justify(JustifyText::Center), TextLayout::new_with_justify(Justify::Center),
)); ));
parent.spawn(( parent.spawn((
SyncResource::<RewindFrames>::default(), SyncResource::<RewindFrames>::default(),
Text::default(), Text::default(),
TextColor(BLACK.into()), TextColor(BLACK.into()),
TextLayout::new_with_justify(JustifyText::Center), TextLayout::new_with_justify(Justify::Center),
)); ));
parent.spawn(( parent.spawn((
Text::new("Press R to Rewind"), Text::new("Press R to Rewind"),
TextColor(BLACK.into()), TextColor(BLACK.into()),
TextLayout::new_with_justify(JustifyText::Center), TextLayout::new_with_justify(Justify::Center),
)); ));
parent parent
.spawn((Node { .spawn((Node {
@ -589,7 +589,7 @@ fn init_ui(mut commands: Commands, server: Res<AssetServer>) {
{ {
fn quit_game( fn quit_game(
_event: On<Pointer<Click>>, _event: On<Pointer<Click>>,
mut exit: EventWriter<AppExit>, mut exit: MessageWriter<AppExit>,
) { ) {
warn!("Quitting game"); warn!("Quitting game");
exit.write(AppExit::Success); exit.write(AppExit::Success);
@ -629,7 +629,7 @@ fn init_ui(mut commands: Commands, server: Res<AssetServer>) {
children![( children![(
Text::new(credits_str), Text::new(credits_str),
TextColor(BLACK.into()), TextColor(BLACK.into()),
TextLayout::new_with_justify(JustifyText::Center) TextLayout::new_with_justify(Justify::Center)
)], )],
)) ))
.with_children(|parent| { .with_children(|parent| {
@ -734,7 +734,7 @@ fn init_ui(mut commands: Commands, server: Res<AssetServer>) {
Text::new("Rewind!\n(Hold R)"), Text::new("Rewind!\n(Hold R)"),
TextColor(BLACK.into()), TextColor(BLACK.into()),
TextFont::from_font_size(20.0), TextFont::from_font_size(20.0),
TextLayout::new_with_justify(JustifyText::Center) TextLayout::new_with_justify(Justify::Center)
), ),
], ],
)) ))
@ -766,7 +766,7 @@ fn init_ui(mut commands: Commands, server: Res<AssetServer>) {
Text::new("Flap!\n(Spacebar)"), Text::new("Flap!\n(Spacebar)"),
TextColor(BLACK.into()), TextColor(BLACK.into()),
TextFont::from_font_size(20.0), TextFont::from_font_size(20.0),
TextLayout::new_with_justify(JustifyText::Center) TextLayout::new_with_justify(Justify::Center)
), ),
( (
ImageNode { ImageNode {
@ -797,7 +797,7 @@ fn init_ui(mut commands: Commands, server: Res<AssetServer>) {
SyncResource::<Score>::default(), SyncResource::<Score>::default(),
Text::default(), Text::default(),
TextColor(BLACK.into()), TextColor(BLACK.into()),
TextLayout::new_with_justify(JustifyText::Center), TextLayout::new_with_justify(Justify::Center),
)], )],
)); ));
} }
@ -845,16 +845,16 @@ fn init_background(
} }
} }
fn start_rewind(_event: On<Pointer<Pressed>>, mut next: ResMut<NextState<PlayerState>>) { fn start_rewind(_event: On<Pointer<Press>>, mut next: ResMut<NextState<PlayerState>>) {
next.set(PlayerState::Rewind); next.set(PlayerState::Rewind);
} }
fn end_rewind(_event: On<Pointer<Released>>, mut next: ResMut<NextState<PlayerState>>) { fn end_rewind(_event: On<Pointer<Release>>, mut next: ResMut<NextState<PlayerState>>) {
next.set(PlayerState::Alive); next.set(PlayerState::Alive);
} }
fn flap_button( fn flap_button(
_event: On<Pointer<Pressed>>, _event: On<Pointer<Press>>,
mut commands: Commands, mut commands: Commands,
bird: Single<Entity, With<Bird>>, bird: Single<Entity, With<Bird>>,
curr: Res<State<PlayerState>>, curr: Res<State<PlayerState>>,
@ -865,7 +865,7 @@ fn flap_button(
} }
let e = *bird; let e = *bird;
debug!("Flapping {:?}", e); debug!("Flapping {:?}", e);
commands.event_targets(Flap, e); commands.trigger(Flap { entity: e });
} }
/// Pause the game when the player presses "Escape" /// Pause the game when the player presses "Escape"
@ -877,13 +877,15 @@ fn un_pause_game(mut next: ResMut<NextState<PlayerState>>) {
next.set(PlayerState::Alive); next.set(PlayerState::Alive);
} }
#[derive(Component, Clone, Message)] #[derive(Component, Clone, Message, EntityEvent)]
struct Flap; struct Flap {
entity: Entity
}
// Observer for flapping // Observer for flapping
fn flap( fn flap(
event: On<Flap>, event: On<Flap>,
mut bird: Query<&mut ExternalImpulse, With<Bird>>, mut bird: Query<Forces, With<Bird>>,
mut flaps: ResMut<Flaps>, mut flaps: ResMut<Flaps>,
) { ) {
debug!("real flap for {:?}", event.entity); debug!("real flap for {:?}", event.entity);
@ -892,7 +894,7 @@ fn flap(
// Flap birds wings // Flap birds wings
if let Ok(mut f) = bird.get_mut(event.entity) { if let Ok(mut f) = bird.get_mut(event.entity) {
f.apply_impulse(Vec2::Y * 5000.0 + Vec2::X * 1000.0); f.apply_local_linear_impulse(Vec2::Y * 5000.0 + Vec2::X * 1000.0);
} }
} }
@ -916,7 +918,7 @@ fn flap_kb(
birds.iter().for_each(|e| { birds.iter().for_each(|e| {
debug!("Flapping {:?}", e); debug!("Flapping {:?}", e);
commands.event_targets(Flap, e); commands.trigger(Flap { entity: e });
}); });
} }
@ -941,7 +943,7 @@ fn record(
( (
&LinearVelocity, &LinearVelocity,
&AngularVelocity, &AngularVelocity,
&ExternalImpulse, &ConstantForce,
&Position, &Position,
&Rotation, &Rotation,
&mut Tape, &mut Tape,
@ -956,7 +958,7 @@ fn record(
); );
birds.iter_mut().for_each(|(lv, av, ei, p, r, mut tape)| { birds.iter_mut().for_each(|(lv, av, ei, p, r, mut tape)| {
tape.push(*lv, *av, *ei, *p, *r); tape.push(*lv, *av, ei.clone(), *p, *r);
}); });
} }
@ -967,7 +969,7 @@ fn rewind(
( (
&mut LinearVelocity, &mut LinearVelocity,
&mut AngularVelocity, &mut AngularVelocity,
&mut ExternalImpulse, // TODO: Need to re-add impulse here
&mut Position, &mut Position,
&mut Rotation, &mut Rotation,
&mut Tape, &mut Tape,
@ -984,11 +986,11 @@ fn rewind(
birds birds
.iter_mut() .iter_mut()
.for_each(|(mut lv, mut av, mut ei, mut p, mut r, mut tape)| { .for_each(|(mut lv, mut av, mut p, mut r, mut tape)| {
if let Some((new_lv, new_av, new_ei, new_p, new_r)) = tape.pop() { if let Some((new_lv, new_av, _new_ei, new_p, new_r)) = tape.pop() {
lv.0 = new_lv.0; lv.0 = new_lv.0;
av.0 = new_av.0; av.0 = new_av.0;
ei.set_impulse(new_ei.impulse()); // TODO: Need to re-add impulse here
p.0 = new_p.0; p.0 = new_p.0;
*r = new_r; *r = new_r;
frames.0 += 1; frames.0 += 1;
@ -1016,15 +1018,16 @@ fn detect_dead(
} }
} }
fn alive_bird(mut bird: Single<&mut RigidBody, With<Bird>>) { fn alive_bird(bird: Single<Entity, With<Bird>>, mut commands: Commands) {
debug!("Setting bird to Dynamic"); debug!("Setting bird to Dynamic");
**bird = RigidBody::Dynamic; commands.entity(*bird).remove::<RigidBodyDisabled>();
} }
fn pause_bird( fn pause_bird(
state: Res<State<PlayerState>>, state: Res<State<PlayerState>>,
mut bird: Single<&mut RigidBody, With<Bird>>, bird: Single<Entity, With<Bird>>,
mut deaths: ResMut<Deaths>, mut deaths: ResMut<Deaths>,
mut commands: Commands,
) { ) {
// Increment death count // Increment death count
if state.get() == &PlayerState::Stasis { if state.get() == &PlayerState::Stasis {
@ -1032,7 +1035,7 @@ fn pause_bird(
} }
debug!("Setting bird to Static"); debug!("Setting bird to Static");
**bird = RigidBody::Static; commands.entity(*bird).insert(RigidBodyDisabled);
} }
fn camera_follow_bird( fn camera_follow_bird(
@ -1138,32 +1141,32 @@ impl Display for Deaths {
} }
fn manage_score( fn manage_score(
mut start: MessageReader<CollisionStarted>, mut start: MessageReader<CollisionStart>,
mut end: MessageReader<CollisionEnded>, mut end: MessageReader<CollisionEnd>,
state: Res<State<PlayerState>>, state: Res<State<PlayerState>>,
hitboxes: Query<&Batch, With<Hitbox>>, hitboxes: Query<&Batch, With<Hitbox>>,
mut score: ResMut<Score>, mut score: ResMut<Score>,
) { ) {
match state.get() { match state.get() {
PlayerState::Rewind => { PlayerState::Rewind => {
start.read().for_each(|CollisionStarted(a, b)| { start.read().for_each(|CollisionStart { collider1, collider2, .. }| {
// Set score to collided hitbox // Set score to collided hitbox
if let Ok(Batch(this)) = hitboxes.get(*a) { if let Ok(Batch(this)) = hitboxes.get(*collider1) {
debug!("[Rewind] Setting score to {this}"); debug!("[Rewind] Setting score to {this}");
score.0 = this.saturating_sub(1); score.0 = this.saturating_sub(1);
} else if let Ok(Batch(this)) = hitboxes.get(*b) { } else if let Ok(Batch(this)) = hitboxes.get(*collider2) {
debug!("[Rewind] Setting score to {this}"); debug!("[Rewind] Setting score to {this}");
score.0 = this.saturating_sub(1); score.0 = this.saturating_sub(1);
} }
}) })
} }
_ => { _ => {
end.read().for_each(|CollisionEnded(a, b)| { end.read().for_each(|CollisionEnd { collider1, collider2, .. }| {
// Set score to collided hitbox // Set score to collided hitbox
if let Ok(Batch(this)) = hitboxes.get(*b) { if let Ok(Batch(this)) = hitboxes.get(*collider2) {
debug!("[Alive] Setting score to {this}"); debug!("[Alive] Setting score to {this}");
score.0 = *this; score.0 = *this;
} else if let Ok(Batch(this)) = hitboxes.get(*a) { } else if let Ok(Batch(this)) = hitboxes.get(*collider1) {
debug!("[Alive] Setting score to {this}"); debug!("[Alive] Setting score to {this}");
score.0 = *this; score.0 = *this;
} }
@ -1182,15 +1185,15 @@ fn manage_score(
/// Finally we iterate over all entities with the old batch ID and upsert the new batch ID /// Finally we iterate over all entities with the old batch ID and upsert the new batch ID
/// This includes root batch entities as well as pipes and hitboxes /// This includes root batch entities as well as pipes and hitboxes
fn move_batches( fn move_batches(
mut start: MessageReader<CollisionStarted>, mut start: MessageReader<CollisionStart>,
mut end: MessageReader<CollisionEnded>, mut end: MessageReader<CollisionEnd>,
hitboxes: Query<Entity, With<Hitbox>>, hitboxes: Query<Entity, With<Hitbox>>,
batches: Query<(Entity, &Batch)>, batches: Query<(Entity, &Batch)>,
state: Res<State<PlayerState>>, state: Res<State<PlayerState>>,
mut commands: Commands, mut commands: Commands,
) { ) {
let s = start.read().map(|CollisionStarted(a, b)| (a, b)); let s = start.read().map(|CollisionStart { collider1, collider2, .. }| (collider1, collider2));
let e = end.read().map(|CollisionEnded(a, b)| (a, b)); let e = end.read().map(|CollisionEnd { collider1, collider2, .. }| (collider1, collider2));
let c = s.chain(e); let c = s.chain(e);
c.for_each(|(a, b)| { c.for_each(|(a, b)| {
debug!("[batches] Collision {a} -> {b}"); debug!("[batches] Collision {a} -> {b}");

@ -44,7 +44,7 @@ fn drag_tree(
debug_assert_eq!(*state.get(), DebuggingState::On); debug_assert_eq!(*state.get(), DebuggingState::On);
events.read().for_each(|event| { events.read().for_each(|event| {
if let Ok(mut t) = query.get_mut(event.target) { if let Ok(mut t) = query.get_mut(event.entity) {
let world_position = window let world_position = window
.cursor_position() .cursor_position()
.and_then(|cursor| camera.0.viewport_to_world(camera.1, cursor).ok()) .and_then(|cursor| camera.0.viewport_to_world(camera.1, cursor).ok())
@ -164,7 +164,7 @@ fn control_menu(
hover_map: Res<HoverMap>, hover_map: Res<HoverMap>,
) { ) {
over_events.read().for_each(|over| { over_events.read().for_each(|over| {
let root = nav_children.root_ancestor(over.target); let root = nav_children.root_ancestor(over.entity);
nav_parents.iter_descendants(root).for_each(|child| { nav_parents.iter_descendants(root).for_each(|child| {
if let Ok(mut n) = nav.get_mut(child) { if let Ok(mut n) = nav.get_mut(child) {
@ -184,9 +184,9 @@ fn control_menu(
// For all pointer out events // For all pointer out events
out_events.read().for_each(|out| { 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 // Otherwise set to closed
let root = children.root_ancestor(out.target); let root = children.root_ancestor(out.entity);
let tree_still_hovered = parents let tree_still_hovered = parents
.iter_descendants(root) .iter_descendants(root)
.any(|child| is_hovered.contains(&&child)); .any(|child| is_hovered.contains(&&child));
@ -215,7 +215,7 @@ fn add_dialog_option(event: On<Add, DialogOption>, mut commands: Commands) {
width: Val::Percent(100.0), width: Val::Percent(100.0),
..default() ..default()
}) })
.insert(TextLayout::new_with_justify(JustifyText::Center)) .insert(TextLayout::new_with_justify(Justify::Center))
.insert(TextColor(ORANGE.into())) .insert(TextColor(ORANGE.into()))
.observe(choose_dialog_option) .observe(choose_dialog_option)
.observe(hover_dialog_option_over) .observe(hover_dialog_option_over)
@ -224,7 +224,7 @@ fn add_dialog_option(event: On<Add, DialogOption>, mut commands: Commands) {
fn assign_monologue_event( fn assign_monologue_event(
event: On<Pointer<Click>>, event: On<Pointer<Click>>,
mut events: EventWriter<AssignMonologue>, mut events: MessageWriter<AssignMonologue>,
monologues: Query<&TreeMonologue>, monologues: Query<&TreeMonologue>,
) { ) {
let TreeMonologue(handle) = monologues.get(event.entity).unwrap(); let TreeMonologue(handle) = monologues.get(event.entity).unwrap();
@ -232,7 +232,7 @@ fn assign_monologue_event(
} }
/// Observer for the "Plant a new tree" button in the debug UI /// Observer for the "Plant a new tree" button in the debug UI
fn spawn_tree(_event: On<Pointer<Click>>, mut events: EventWriter<PlantTree>) { fn spawn_tree(_event: On<Pointer<Click>>, mut events: MessageWriter<PlantTree>) {
events.write(PlantTree(None)); events.write(PlantTree(None));
} }
@ -266,9 +266,9 @@ fn delete_tree(
query: Query<Entity, With<Tree>>, query: Query<Entity, With<Tree>>,
) { ) {
events.read().for_each(|event| { events.read().for_each(|event| {
if matches!(event.event.button, PointerButton::Middle) && query.contains(event.target) { if matches!(event.event.button, PointerButton::Middle) && query.contains(event.entity) {
debug!("Middle Click -> Despawning {}", event.target); debug!("Middle Click -> Despawning {}", event.entity);
commands.entity(event.target).despawn(); commands.entity(event.entity).despawn();
} }
}) })
} }
@ -291,10 +291,12 @@ fn monologue_asset_tooltip(
.read() .read()
.filter_map(|Pointer { entity, .. }| trees.contains(*entity).then_some(*entity)) .filter_map(|Pointer { entity, .. }| trees.contains(*entity).then_some(*entity))
.for_each(|e| match trees.get(e) { .for_each(|e| match trees.get(e) {
Ok((_tree, Some(TreeMonologue(handle)))) => match handle.path() { Ok((_tree, Some(TreeMonologue(id)))) => {
Some(p) => tooltip.insert("Script", format!("{p}")), match todo!("Get path for this asset") {
None => tooltip.insert("Script", "A".into()), Some(p) => tooltip.insert("Script", format!("{p}")),
}, None => tooltip.insert("Script", "A".into()),
}
}
Ok((_tree, None)) => { Ok((_tree, None)) => {
tooltip.insert("Script", "N/A".into()); tooltip.insert("Script", "N/A".into());
} }
@ -305,7 +307,7 @@ fn monologue_asset_tooltip(
/// When a dialog option is chosen (clicked on) we do the following: /// When a dialog option is chosen (clicked on) we do the following:
fn choose_dialog_option( fn choose_dialog_option(
event: On<Pointer<Click>>, event: On<Pointer<Click>>,
mut dialog_events: EventWriter<DialogEvent>, mut dialog_events: MessageWriter<DialogEvent>,
mut commands: Commands, mut commands: Commands,
texts: Query<&Text>, texts: Query<&Text>,
options: Query<Entity, With<DialogOption>>, options: Query<Entity, With<DialogOption>>,
@ -337,9 +339,9 @@ fn preview_monologue(
mut commands: Commands, mut commands: Commands,
) { ) {
// Get the handle for this button's monologuie // Get the handle for this button's monologuie
if let Ok(TreeMonologue(handle)) = tree_monologue.get(event.entity) { if let Ok(TreeMonologue(id)) = tree_monologue.get(event.entity) {
// Get the monologue data // Get the monologue data
if let Some(monologue) = monologues.get(handle) { if let Some(monologue) = monologues.get(*id) {
commands.entity(*container).despawn_related::<Children>(); commands.entity(*container).despawn_related::<Children>();
// Spawn the monologue // Spawn the monologue
@ -396,9 +398,9 @@ fn spawn_debug_buttons(
.trim_prefix("trees/") .trim_prefix("trees/")
.trim_suffix(".mono"), .trim_suffix(".mono"),
), ),
TextLayout::new(JustifyText::Left, LineBreak::WordBoundary), TextLayout::new(Justify::Left, LineBreak::WordBoundary),
], ],
TreeMonologue(handle.clone()), TreeMonologue(handle.id()),
MonologuesList, MonologuesList,
)) ))
.observe(assign_monologue_event) .observe(assign_monologue_event)

@ -20,9 +20,9 @@ fn main() {
}) })
.add_plugins(MonologueAssetsPlugin) .add_plugins(MonologueAssetsPlugin)
.add_plugins(TreesDebugPlugin) .add_plugins(TreesDebugPlugin)
.add_event::<DialogEvent>() .add_message::<DialogEvent>()
.add_event::<PlantTree>() .add_message::<PlantTree>()
.add_event::<AssignMonologue>() .add_message::<AssignMonologue>()
.init_state::<DialogState>() .init_state::<DialogState>()
.insert_resource(ClearColor(WHITE.into())) .insert_resource(ClearColor(WHITE.into()))
.add_systems( .add_systems(
@ -69,7 +69,7 @@ fn main() {
struct Tree; struct Tree;
#[derive(Component, PartialEq, Clone)] #[derive(Component, PartialEq, Clone)]
struct TreeMonologue(Handle<Monologue>); struct TreeMonologue(AssetId<Monologue>);
/// Initialize the trees, currently placeholders /// Initialize the trees, currently placeholders
/// Trees are 2d cards in a 3d world for flexibility /// Trees are 2d cards in a 3d world for flexibility
@ -149,7 +149,7 @@ fn auto_scroll(
); );
scroll_positions.iter_mut().for_each(|mut sp| { scroll_positions.iter_mut().for_each(|mut sp| {
sp.offset_y = f32::MAX; sp.y = f32::MAX;
}); });
} }
@ -164,7 +164,7 @@ struct DialogLine;
/// Events that drive the dialog engine /// Events that drive the dialog engine
#[derive(Message, PartialEq)] #[derive(Message, PartialEq)]
enum DialogEvent { enum DialogEvent {
Start(Entity, Handle<Monologue>), Start(Entity, AssetId<Monologue>),
NextBatch, NextBatch,
End, End,
} }
@ -184,14 +184,14 @@ enum DialogState {
/// Start dialog /// Start dialog
fn start_dialog( fn start_dialog(
mut click_events: MessageReader<Pointer<Click>>, mut click_events: MessageReader<Pointer<Click>>,
mut dialog_events: EventWriter<DialogEvent>, mut dialog_events: MessageWriter<DialogEvent>,
query: Query<&TreeMonologue, With<Tree>>, query: Query<&TreeMonologue, With<Tree>>,
) { ) {
click_events.read().for_each(|event| { click_events.read().for_each(|event| {
debug!("Click event detected in start dialog systme"); debug!("Click event detected in start dialog systme");
if let Ok(TreeMonologue(handle)) = query.get(event.target) { if let Ok(TreeMonologue(id)) = query.get(event.entity) {
debug!("Tree Monologue received, sending start dialog event"); debug!("Tree Monologue received, sending start dialog event");
dialog_events.write(DialogEvent::Start(event.target, handle.clone())); dialog_events.write(DialogEvent::Start(event.entity, id.clone()));
dialog_events.write(DialogEvent::NextBatch); dialog_events.write(DialogEvent::NextBatch);
} }
}) })
@ -200,12 +200,12 @@ fn start_dialog(
/// When dialog is complete and you click away from the dialog box, close it out /// When dialog is complete and you click away from the dialog box, close it out
fn end_dialog( fn end_dialog(
mut click_events: MessageReader<Pointer<Click>>, mut click_events: MessageReader<Pointer<Click>>,
mut dialog_events: EventWriter<DialogEvent>, mut dialog_events: MessageWriter<DialogEvent>,
query: Query<Entity, Or<(With<TreeMonologue>, With<DialogBox>, With<DialogOption>)>>, query: Query<Entity, Or<(With<TreeMonologue>, With<DialogBox>, With<DialogOption>)>>,
) { ) {
click_events.read().for_each(|event| { click_events.read().for_each(|event| {
debug!("Click even evented end of dialog: {:?}", event.target); debug!("Click even evented end of dialog: {:?}", event.entity);
if !query.contains(event.target) { if !query.contains(event.entity) {
dialog_events.write(DialogEvent::End); dialog_events.write(DialogEvent::End);
} }
}); });
@ -220,7 +220,7 @@ fn dialog_engine(
// EntityCommands for Dialog Box // EntityCommands for Dialog Box
mut commands: Commands, mut commands: Commands,
// Handle to "active" monologue // Handle to "active" monologue
mut handle: Local<Handle<Monologue>>, mut asset_id: Local<AssetId<Monologue>>,
// Track active entity as well as the monologue // Track active entity as well as the monologue
mut tree_entity: Local<Option<Entity>>, mut tree_entity: Local<Option<Entity>>,
// Index into "active" monologue // Index into "active" monologue
@ -239,14 +239,14 @@ fn dialog_engine(
events.read().for_each(|event| { events.read().for_each(|event| {
match event { match event {
DialogEvent::Start(e, h) => { DialogEvent::Start(e, id) => {
debug!("Dialog start: {:?}", h); debug!("Dialog start: {:?}", id);
// Set state to "Active" // Set state to "Active"
next_state.set(DialogState::Ongoing); next_state.set(DialogState::Ongoing);
// Copy monologue asset into local // Copy monologue asset into local
*handle = h.clone(); *asset_id = id.clone();
*tree_entity = Some(*e); *tree_entity = Some(*e);
} }
DialogEvent::NextBatch => { DialogEvent::NextBatch => {
@ -254,7 +254,7 @@ fn dialog_engine(
commands.entity(*dialog_box).with_children(|parent| { commands.entity(*dialog_box).with_children(|parent| {
// Fetch this monologue from the assets // Fetch this monologue from the assets
if let Some(monologue) = monologues.get(handle.clone().id()) { if let Some(monologue) = monologues.get(asset_id.clone()) {
// Fetch this batch of options // Fetch this batch of options
if let Some(batch) = monologue.get(*idx) { if let Some(batch) = monologue.get(*idx) {
// Spawn the dialog options in the dialog box // Spawn the dialog options in the dialog box
@ -262,7 +262,7 @@ fn dialog_engine(
parent.spawn(( parent.spawn((
Text::new(line.clone()), Text::new(line.clone()),
DialogOption, DialogOption,
TextLayout::new(JustifyText::Left, LineBreak::NoWrap), TextLayout::new(Justify::Left, LineBreak::NoWrap),
)); ));
}); });
*idx += 1; *idx += 1;
@ -290,7 +290,7 @@ fn dialog_engine(
*idx = 0; *idx = 0;
// Wipe the current handle from context // Wipe the current handle from context
*handle = Handle::default(); *asset_id = AssetId::default();
// Set state to "Active" // Set state to "Active"
next_state.set(DialogState::None); next_state.set(DialogState::None);
@ -389,21 +389,21 @@ fn scale_window(events: MessageReader<WindowResized>, mut window: Single<&mut Wi
} }
/// Load all monologues so they are in the asset store and event on-load events /// Load all monologues so they are in the asset store and event on-load events
fn load_monologues(server: ResMut<AssetServer>, mut loaded_assets: Local<Vec<Handle<Monologue>>>) { fn load_monologues(server: ResMut<AssetServer>, mut loaded_assets: Local<Vec<AssetId<Monologue>>>) {
*loaded_assets = include_str!("../../../assets/trees/MONOLOGUES") *loaded_assets = include_str!("../../../assets/trees/MONOLOGUES")
.split("\n") .split("\n")
.map(|path| server.load(path)) .map(|path| server.load(path).id())
.collect(); .collect();
} }
#[derive(Message)] #[derive(Message)]
struct PlantTree(Option<Handle<Monologue>>); struct PlantTree(Option<AssetId<Monologue>>);
/// Plan a tree in the world /// Plan a tree in the world
/// Handles random placement, 3d model, materials, and observers /// Handles random placement, 3d model, materials, and observers
fn handle_plant_tree( fn handle_plant_tree(
mut events: MessageReader<PlantTree>, mut events: MessageReader<PlantTree>,
mut assignments: EventWriter<AssignMonologue>, mut assignments: MessageWriter<AssignMonologue>,
trees: Query<Entity, With<Tree>>, trees: Query<Entity, With<Tree>>,
server: Res<AssetServer>, server: Res<AssetServer>,
mut commands: Commands, mut commands: Commands,
@ -442,14 +442,14 @@ fn handle_plant_tree(
tree.insert((mesh, material, transform)); tree.insert((mesh, material, transform));
if let Some(handle) = assignment { if let Some(id) = assignment {
assignments.write(AssignMonologue(handle.clone())); assignments.write(AssignMonologue(id.clone()));
} }
}); });
} }
#[derive(Message, Debug)] #[derive(Message, Debug)]
struct AssignMonologue(Handle<Monologue>); struct AssignMonologue(AssetId<Monologue>);
/// Assign the given monologue to a tree /// Assign the given monologue to a tree
fn assign_monologue_to_tree( fn assign_monologue_to_tree(
@ -470,7 +470,7 @@ fn assign_monologue_to_tree(
let monologue = TreeMonologue(event.0.clone()); let monologue = TreeMonologue(event.0.clone());
// Insert the component to the entity // Insert the component to the entity
commands.entity(tree).insert(monologue); commands.entity(tree).insert(monologue);
} else if let Some(path) = event.0.path() { } else if let Some(path) = todo!("event.0.path() -> assetId") {
error!("No trees avaliable for {path:?}"); error!("No trees avaliable for {path:?}");
notice.0 = format!("No trees avaliable for {path:?}"); notice.0 = format!("No trees avaliable for {path:?}");
} else { } else {
@ -481,12 +481,12 @@ fn assign_monologue_to_tree(
} }
/// On startup, plant a forest (add a few trees to the game) /// On startup, plant a forest (add a few trees to the game)
fn plant_forest(monos: Res<Assets<Monologue>>, mut e_trees: EventWriter<PlantTree>) { fn plant_forest(monos: Res<Assets<Monologue>>, mut e_trees: MessageWriter<PlantTree>) {
let mut i = 10; let mut i = 10;
for id in monos.ids() { for id in monos.ids() {
debug!("Planting tree with monologue {:?}", id); debug!("Planting tree with monologue {:?}", id);
if i > 5 { if i > 5 {
e_trees.write(PlantTree(Some(Handle::Weak(id)))); e_trees.write(PlantTree(Some(id)));
} else if i > 0 { } else if i > 0 {
e_trees.write(PlantTree(None)); e_trees.write(PlantTree(None));
} else { } else {

@ -19,7 +19,7 @@ pub use std::fmt::Display;
// Community libraries // Community libraries
pub use bevy::{ pub use bevy::{
asset::{AssetLoader, AssetMetaCheck, LoadContext, LoadState, LoadedFolder, io::Reader, RenderAssetUsages}, asset::{AssetLoader, AssetMetaCheck, LoadContext, LoadState, LoadedFolder, io::Reader, RenderAssetUsages, uuid_handle},
math::{FloatOrd}, math::{FloatOrd},
camera::{*, primitives::*, visibility::*}, camera::{*, primitives::*, visibility::*},
color::palettes::css::*, color::palettes::css::*,

@ -6,7 +6,7 @@ pub struct Physics3dPlugin;
impl Plugin for Physics3dPlugin { impl Plugin for Physics3dPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_plugins((PhysicsDebugPlugin::default(), PhysicsPlugins::default())) app.add_plugins((PhysicsDebugPlugin, PhysicsPlugins::default()))
.add_systems( .add_systems(
Update, Update,
toggle_physics_debug_render.run_if(state_changed::<DebuggingState>), toggle_physics_debug_render.run_if(state_changed::<DebuggingState>),

Loading…
Cancel
Save