diff --git a/assets/resources.apack b/assets/resources.apack index b86836b74e6ca4c0ab25130fde60a57cbfb88de4..c2669d0b236ff87a757b1a5f33cff77febb1dbfc 100644 --- a/assets/resources.apack +++ b/assets/resources.apack @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0104e32f553d939d5f9d7c0346282da2705062194ccca0540cdeab540fdadf30 -size 1930616 +oid sha256:c7d3705a1bcb0534de927d60743ca9e4f33352bbefeaf1618d6eb91f102639fc +size 1930588 diff --git a/game_core/src/world/hunger.rs b/game_core/src/world/hunger.rs index d1e63a7f0f43c05fc57df1b6413397c69028fec1..005047e6c468b708e84e2d9d450e3e9d2a31b361 100644 --- a/game_core/src/world/hunger.rs +++ b/game_core/src/world/hunger.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use bevy::prelude::{Component, EventReader, Mut, Query, With, Without}; +use bevy::prelude::{Component, Entity, EventReader, Mut, Query, With, Without}; use serde::{Deserialize, Serialize}; use crate::const_data::get_goods_from_name_checked; @@ -126,3 +126,10 @@ fn process_hunger_state<'a>( hunger_state.sustenance = target - deficit; } } + +pub fn handle_entity_starvation( + food_query: Query<(Entity, &HungerState)>, + player_query: Query<(), With<Player>>, + town_query: Query<&TownName>, +) { +} diff --git a/game_core/src/world/spawning.rs b/game_core/src/world/spawning.rs index 5ba14443bf89c2d160684d0dbdb8883a56c7fc81..daf6e6a901fd1dbd6034b2e522276c17abf0f2e2 100644 --- a/game_core/src/world/spawning.rs +++ b/game_core/src/world/spawning.rs @@ -1,7 +1,13 @@ use std::collections::HashMap; +use std::time::Duration; +use bevy::math::vec3; use bevy::prelude::*; use bevy_ecs_tilemap::prelude::*; +use bevy_tweening::lens::TransformPositionLens; +use bevy_tweening::{ + Animator, EaseFunction, EaseMethod, RepeatCount, RepeatStrategy, Sequence, Tracks, Tween, +}; use ldtk_rust::EntityInstance; use micro_banimate::definitions::SimpleAnimationBundle; use num_traits::AsPrimitive; @@ -14,7 +20,9 @@ use crate::system::camera::ChaseCam; use crate::world::encounters::WorldZones; use crate::world::towns::{CurrentResidence, TownBundle, TownPaths}; use crate::world::travel::DistanceTravelled; -use crate::world::utils::{grid_to_px, px_to_grid, ActiveLevel, WorldLinked, TILE_SCALE_F32}; +use crate::world::utils::{ + entity_to_worldspace, grid_to_px, px_to_grid, ActiveLevel, WorldLinked, TILE_SCALE_F32, +}; use crate::world::world_query::MapQuery; use crate::world::{ EncounterState, HungerState, TownName, TradeManifest, TradeManifestTickState, TradingState, @@ -291,6 +299,8 @@ pub fn populate_world( let mut name = String::new(); let mut manifest_name = String::new(); + let (cx, cy) = entity_to_worldspace(level.px_hei, instance); + instance .field_instances .iter() @@ -307,12 +317,12 @@ pub fn populate_world( }); if manifest_name.is_empty() { - (name, String::from("whitestone")) + (name, String::from("whitestone"), Vec3::new(cx, cy, 500.0)) } else { - (name, manifest_name) + (name, manifest_name, Vec3::new(cx, cy, 500.0)) } }) - .map(|(name, manifest)| { + .map(|(name, manifest, transform)| { let handle = assets.trade_manifest(manifest); let asset = manifests.get(&handle).unwrap(); @@ -326,6 +336,10 @@ pub fn populate_world( trade_state: trade.clone(), hunger_state: hunger.clone(), manifest_state: tick.clone(), + world_linked: WorldLinked, + location: TransformBundle::from_transform(Transform::from_translation( + transform, + )), }, None => TownBundle { town_name: TownName(name.clone()), @@ -336,11 +350,16 @@ pub fn populate_world( }, hunger_state: HungerState::initial_town(), manifest_state: TradeManifestTickState::default(), + world_linked: WorldLinked, + location: TransformBundle::from_transform(Transform::from_translation( + transform, + )), }, } }) .for_each(|bundle| { - commands.spawn((WorldLinked, bundle)); + let ent = commands.spawn((bundle, VisibilityBundle::default())).id(); + apply_skull_marker(&mut commands, &assets, ent); }); commands.insert_resource(trade_routes); @@ -348,6 +367,31 @@ pub fn populate_world( } } +pub fn apply_skull_marker(commands: &mut Commands, assets: &Res<AssetHandles>, entity: Entity) { + commands.entity(entity).with_children(|builder| { + let tween = Tween::new( + EaseFunction::SineInOut, + Duration::from_secs(2), + TransformPositionLens { + start: vec3(0.0, 0.0, 400.0), + end: vec3(0.0, 2.0, 400.0), + }, + ) + .with_repeat_strategy(RepeatStrategy::MirroredRepeat) + .with_repeat_count(RepeatCount::Infinite); + + builder.spawn(( + SpriteSheetBundle { + sprite: TextureAtlasSprite::new(42), + texture_atlas: assets.atlas("icons"), + transform: Transform::from_xyz(0.0, 0.0, 400.0), + ..Default::default() + }, + Animator::new(tween), + )); + }); +} + pub fn clean_game_state( mut commands: Commands, world_entities: Query<Entity, (Without<TileStorage>, With<WorldLinked>)>, diff --git a/game_core/src/world/towns.rs b/game_core/src/world/towns.rs index d696048daeeb76869a5626f6870f644d8af3ebe0..b0e6bc1fb62a326482cb5da866742a51bc58e5e0 100644 --- a/game_core/src/world/towns.rs +++ b/game_core/src/world/towns.rs @@ -1,5 +1,5 @@ use bevy::math::{vec2, Vec2}; -use bevy::prelude::{Bundle, Component, Handle, Resource}; +use bevy::prelude::{Bundle, Component, Handle, Resource, TransformBundle}; use bevy::utils::HashMap; use ldtk_rust::{EntityInstance, Level}; use serde::{Deserialize, Serialize}; @@ -7,7 +7,7 @@ use serde_json::Value; use crate::world::trading::TradeManifestTickState; use crate::world::utils::{grid_to_px, px_to_grid}; -use crate::world::{HungerState, TradeManifest, TradingState}; +use crate::world::{HungerState, TradeManifest, TradingState, WorldLinked}; pub type Town = String; @@ -270,4 +270,6 @@ pub struct TownBundle { pub hunger_state: HungerState, pub manifest: Handle<TradeManifest>, pub manifest_state: TradeManifestTickState, + pub world_linked: WorldLinked, + pub location: TransformBundle, }