Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 62 additions & 2 deletions ryot/src/bevy_ryot/drawing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ use crate::bevy_ryot::{AppearanceDescriptor, InternalContentState};
use crate::directional::*;
use crate::layer::*;
use crate::position::{Sector, SpriteMovement, TilePosition};
use crate::prelude::map::MapTiles;
use bevy::prelude::*;
use bevy::render::view::{check_visibility, VisibilitySystems, VisibleEntities};

mod brushes;
pub use brushes::*;

pub use brushes::*;
mod commands;
pub use commands::*;

pub use commands::*;
mod systems;
pub use systems::*;

Expand All @@ -22,6 +23,7 @@ pub struct DrawingPlugin;
impl Plugin for DrawingPlugin {
fn build(&self, app: &mut App) {
app.register_type::<Layer>()
.add_systems(Update, (find_canvas_border_entities, fade_in_or_out))
.add_systems(
PostUpdate,
apply_detail_level_to_visibility
Expand Down Expand Up @@ -339,3 +341,61 @@ fn apply_detail_level_to_visibility(
visible_entities.entities = entities;
}
}

#[derive(Component, Debug, Clone, Default)]
pub struct FadeAway(bool);

fn find_canvas_border_entities(
tiles: Res<MapTiles>,
mut commands: Commands,
mut q_sector: Query<&Sector, With<Camera>>,
) {
for sector in q_sector.iter_mut() {
let inner_min = (sector.min.x + 1, sector.min.y + 1);
let inner_max = (sector.max.x - 1, sector.max.y - 1);
let outer_min = (sector.min.x - 5, sector.min.y - 5);
let outer_max = (sector.max.x + 5, sector.max.y + 5);

for x in outer_min.0..=outer_max.0 {
for y in outer_min.1..=outer_max.1 {
let pos = TilePosition::new(x, y, 0);
let Some(tile) = tiles.get(&pos) else {
continue;
};

for (_, entity) in tile.into_iter() {
if x < inner_min.0 || x > inner_max.0 || y < inner_min.1 || y > inner_max.1 {
commands.entity(entity).insert(FadeAway(true));
} else {
commands.entity(entity).insert(FadeAway(false));
}
}
}
}
}
}

fn fade_in_or_out(
time: Res<Time>,
mut commands: Commands,
mut tiles_query: Query<
(Entity, &mut Sprite, &FadeAway),
(Without<Deletion>, With<TileComponent>),
>,
) {
for (entity, mut sprite, fade_away) in tiles_query.iter_mut() {
let alpha = sprite.color.a();

if fade_away.0 {
if alpha > 0.0 {
sprite.color.set_a(alpha - 1.5 * time.delta_seconds());
}
} else {
if alpha < 1.0 {
sprite.color.set_a(alpha + time.delta_seconds());
} else {
commands.entity(entity).remove::<FadeAway>();
}
}
}
}
61 changes: 55 additions & 6 deletions ryot/src/bevy_ryot/drawing/systems/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
//! The systems are used to draw the map and the entities that are on it.
//! The systems manipulate basic drawing entities that are added by the drawing commands.
//! Those entities are the trigger for the drawing systems within the ECS.
use crate::bevy_ryot::drawing::{DrawingBundle, TileComponent};
use crate::bevy_ryot::map::MapTiles;
use crate::bevy_ryot::AppearanceDescriptor;
use crate::position::TilePosition;
use crate::Layer;
use bevy::prelude::{Entity, Query, ResMut, SystemSet, Visibility, With};
use crate::prelude::drawing::TileComponent;
use crate::prelude::{drawing::*, map::*, position::*, *};
use bevy::prelude::*;
use bevy::sprite::Anchor;
use bevy::utils::HashMap;

mod deletion;
pub use deletion::*;
Expand Down Expand Up @@ -80,3 +79,53 @@ pub fn get_top_most_visible_for_tile(

None
}

pub fn apply_elevation<C: ContentAssets>(
content_assets: Res<C>,
mut q_tile: Query<
(
&mut Sprite,
&Layer,
&TilePosition,
&Visibility,
&AppearanceDescriptor,
),
(
With<TileComponent>,
Or<(Changed<Visibility>, Added<Visibility>)>,
),
>,
mut elevation_per_pos: Local<HashMap<TilePosition, u32>>,
) {
let appearances = content_assets.prepared_appearances();

for (mut sprite, layer, tile_pos, visibility, appearance_desc) in q_tile.iter_mut() {
let Layer::Bottom(_) = layer else {
continue;
};

let elevation = (|| -> Option<u32> {
appearances
.get_for_group(appearance_desc.group, appearance_desc.id)?
.clone()
.flags?
.height?
.elevation
})()
.unwrap_or(0);

let tile_elevation = elevation_per_pos.entry(*tile_pos).or_default();
let delta = *tile_elevation as f32 / 32.;

sprite.anchor = Anchor::Custom(Vec2::new(
(0.5 + delta).clamp(0.5, 1.5),
(-0.5 - delta).clamp(-1.5, -0.5),
));

if visibility == Visibility::Hidden {
*tile_elevation -= elevation;
} else {
*tile_elevation += elevation;
}
}
}
2 changes: 1 addition & 1 deletion ryot/src/bevy_ryot/sprite_animations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ pub fn toggle_sprite_animation(mut enabled: ResMut<SpriteAnimationEnabled>) {

/// A system that animates the sprites based on the `AnimationSprite` component.
/// It's meant to run every frame to update the animation of the entities.
/// It will only run if the entity has a `TextureAtlasSprite` and an `AnimationSprite` component.
/// It will only run if the entity has a `TextureAtlas` and an `AnimationSprite` component.
pub(crate) fn animate_sprite_system(
time: Res<Time>,
mut synced_timers: ResMut<SynchronizedAnimationTimers>,
Expand Down
2 changes: 2 additions & 0 deletions ryot_compass/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use bevy::prelude::*;
use bevy::window::PrimaryWindow;
use bevy::winit::WinitWindows;
use bevy_egui::EguiContexts;
use ryot::bevy_ryot::drawing::apply_elevation;
use ryot::prelude::*;
use ryot_compass::*;
use std::io::Cursor;
Expand Down Expand Up @@ -70,6 +71,7 @@ fn main() {
DrawingPlugin::<CompassContentAssets>::default(),
ErrorPlugin,
))
.add_systems(Update, apply_elevation::<CompassContentAssets>)
.add_systems(Startup, set_window_icon)
.add_systems(Startup, setup_window);

Expand Down