Skip to content

Commit

Permalink
Demo 2
Browse files Browse the repository at this point in the history
  • Loading branch information
rewin123 committed Dec 10, 2023
1 parent 2ef8e19 commit f0db426
Show file tree
Hide file tree
Showing 8 changed files with 245 additions and 61 deletions.
130 changes: 130 additions & 0 deletions src/global_task/change_safe_area_size.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
use bevy::prelude::*;
use rand::Rng;

use crate::{storyteller::{Storyteller, GlobalTask}, safe_area::{SafeArea, LandSafeArea}, test_level::LevelSize, GameSet, level_ui::TaskText, GameStuff};

pub struct ChangeSafeAreaSizePlugin;

impl Plugin for ChangeSafeAreaSizePlugin {
fn build(&self, app: &mut App) {
app.add_systems(
OnEnter(GlobalTask::ChangeSafeArea), (start_change_safe_area, apply_deferred).chain())
.add_systems(Update, change_area_system.run_if(in_state(GlobalTask::ChangeSafeArea)).in_set(GameSet::Playing));
}
}

#[derive(Component)]
pub struct ChangeSafeArea {
pub target_scale: f32,
pub start_scale: f32,

pub target_pos : Vec2,
pub start_pos : Vec2,

pub duration: f32,
pub time: f32,

pub start_area: SafeArea
}

const CHANGE_DURATION: f32 = 15.0;

fn start_change_safe_area(
mut commands: Commands,
mut teller : ResMut<Storyteller>,
mut areas: Query<(Entity, &mut SafeArea, &LandSafeArea)>,
leve_size : Res<LevelSize>
) {
let mut rng = rand::thread_rng();
let pos = rng.gen_range(8..=20) as f32;

for (entity, mut area, land) in areas.iter_mut() {

let start_pos = area.get_center();
let start_pos = Vec2::new(start_pos.x, start_pos.z);
let target_pos = Vec2::new(start_pos.x + pos, start_pos.y + pos);

let mut change = ChangeSafeArea {
target_scale: 0.5,
start_scale: 1.0,

target_pos: target_pos,
start_pos: start_pos,

duration: CHANGE_DURATION,
time: 0.0,

start_area: area.clone()
};

commands.entity(entity).insert(change);
}

//generate circle area
let area = SafeArea::Circle {
pos: Vec2::new(-pos, -pos),
radius: leve_size.0 / 4.0
};

commands.spawn((
area.clone(),
LandSafeArea {
start_area: area.clone()
},
ChangeSafeArea {
target_scale: 1.0,
start_scale: 0.0,

target_pos: Vec2::new(-pos, -pos),
start_pos: Vec2::new(-pos, -pos),

duration: CHANGE_DURATION,
time: 0.0,

start_area: area
}
));
}

fn change_area_system(
mut commands: Commands,
mut change: Query<(Entity, &mut ChangeSafeArea)>,
time : Res<Time>,
mut global_task : ResMut<NextState<GlobalTask>>,
mut text : Query<&mut Text, With<TaskText>>
) {

if change.is_empty() {
global_task.set(GlobalTask::None);
for mut t in text.iter_mut() {
t.sections[0].value = "".to_string();
}
return;
}

for mut t in text.iter_mut() {
t.sections[0].value = "The wind has changed. Sheep safe zones are changing!".to_string();
}

for (entity, mut change) in change.iter_mut() {
change.time += time.delta_seconds();

if change.time >= change.duration {
commands.entity(entity).remove::<ChangeSafeArea>();
} else {
let progress = change.time / change.duration;
let scale = change.start_scale + (change.target_scale - change.start_scale) * progress;
let pos = change.start_pos + (change.target_pos - change.start_pos) * progress;

let mut area = change.start_area.get_scaled(scale);
area.set_pos(pos);

commands.entity(entity)
.insert(area.clone())
.insert(LandSafeArea {
start_area: area
})
.insert(GameStuff);
}
}
}
29 changes: 29 additions & 0 deletions src/global_task/evening_warning.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
pub use bevy::prelude::*;

use crate::{level_ui::TaskText, sunday::DayState, storyteller::GlobalTask, GameSet};

pub struct EveningWarningPlugin;

impl Plugin for EveningWarningPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
Update, write_warning_message.run_if(in_state(GlobalTask::None)).run_if(in_state(DayState::Evening)).in_set(GameSet::Playing)
).add_systems(OnExit(DayState::Evening), clear_message.in_set(GameSet::Playing));
}
}

fn write_warning_message(
mut texts : Query<&mut Text, With<TaskText>>
) {
for mut text in texts.iter_mut() {
text.sections[0].value = "The night is coming! Safe zones are disappearing!\nGather the sheep near the torches!".to_string();
}
}

fn clear_message(
mut texts : Query<&mut Text, With<TaskText>>
) {
for mut text in texts.iter_mut() {
text.sections[0].value = "".to_string();
}
}
4 changes: 4 additions & 0 deletions src/global_task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ pub mod collect_sheep_in_area;
pub mod sheep_escape;
pub mod torch_blinking;
pub mod wolf_attack;
pub mod change_safe_area_size;
pub mod evening_warning;

use bevy::prelude::*;

Expand All @@ -12,6 +14,8 @@ impl Plugin for GlobalTaskPlugin {
app.add_plugins((
sheep_escape::SheepEscapePlugin,
torch_blinking::TorchBlinkingPlugin,
change_safe_area_size::ChangeSafeAreaSizePlugin,
evening_warning::EveningWarningPlugin,
));
}
}
6 changes: 3 additions & 3 deletions src/global_task/sheep_escape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,17 @@ fn generate_new_wave(

if *day_state == DayState::Day {
let sheep_count = sheep.iter().count() as f32;
let c = sheep_count * episode_time * 0.2 + 1.0;
let c = sheep_count * episode_time * 0.2 + 10.0;
let mut dt = 5.0 - 1.0 * episode_time;
let n = 1.0 + 1.0 * episode_time;
let n = 1.0 + 3.0 * episode_time;

if level_time < 5.0 {
dt = 2.0;
}

next_wave.0 = Some(SheepWave {
count: c as usize,
beams: n as usize,
beams: n.round() as usize,
time: time.elapsed_seconds() + dt,
});
} else if *day_state == DayState::Night {
Expand Down
6 changes: 5 additions & 1 deletion src/global_task/torch_blinking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ fn update_delight_system(

if ok_torches == status.torches_to_lit.len() {
global_task.set(GlobalTask::None);
if let Ok(mut text) = texts.get_single_mut() {
text.sections[0].value = format!("");
}
return;
} else {
let lived_sheep_count = sheep.iter().count();
if status.start_sheep_count - lived_sheep_count > status.max_dead_sheep {
Expand All @@ -159,7 +163,7 @@ fn update_delight_system(
}

if let Ok(mut text) = texts.get_single_mut() {
text.sections[0].value = format!("The torches are going out! Urgently wake up the shepherd to light the torches!\n{} / {} torches lit\n{} seconds left\nDont let to eat more then {}", ok_torches, status.torches_to_lit.len(), status.time_for_mission, status.max_dead_sheep);
text.sections[0].value = format!("The torches are going out! Urgently wake up the shepherd to light the torches! {} / {} torches lit\n{:.0} seconds left. Dont let to eat more then {}", ok_torches, status.torches_to_lit.len(), status.time_for_mission, status.max_dead_sheep);
}
}
}
Expand Down
29 changes: 22 additions & 7 deletions src/sheep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ pub fn update_scared_sheeps(
>,
dog: Query<&Transform, With<Dog>>,
safeareas: Query<&SafeArea>,
field: ResMut<NNTree>,
) {
let Ok(dog_transform) = dog.get_single() else {
return;
Expand All @@ -372,7 +373,7 @@ pub fn update_scared_sheeps(
} else {
scare.time += time.delta_seconds();

let dog_dpos = dog_transform.translation - t.translation;
let dog_dpos = t.translation - dog_transform.translation;
let dog_distance = dog_dpos.length();

let dir = dog_dpos.normalize_or_zero();
Expand All @@ -392,14 +393,28 @@ pub fn update_scared_sheeps(
.max(SHEEP_SPEED * RANDOM_WALK_SPEED_MULTIPLIER);

if dog_distance < SCARE_MAX_DIST {
if let Some(sa) = nearest_sa {
let dir_to_sa = (sa.get_center() - t.translation).normalize_or_zero();

if dir_to_sa.dot(dir) > 0.0 {
walk.0 = -dir * speed_amount;
let nearest = field.k_nearest_neighbour(t.translation, 7);
let mut mean_nearest_sheep = Vec3::ZERO;
let mut count = 0;
for (pos, _) in nearest.iter().skip(1) {
if (*pos - t.translation).length() < 5.0 {
let ddog = *pos - dog_transform.translation;
if ddog.dot(dog_dpos) >= 0.0 {
mean_nearest_sheep += *pos;
count += 1;
}
}
}
if count > 0 {
let mean_nearest_sheep = mean_nearest_sheep / (count as f32);
if (mean_nearest_sheep - dog_transform.translation).length() < dog_dpos.length() * 0.5 {
walk.0 = dir * speed_amount;
scare.last_vel = walk.0;
} else {
walk.0 = (-dir + dir_to_sa).normalize_or_zero() * speed_amount;
walk.0 = (mean_nearest_sheep - t.translation).normalize_or_zero() * speed_amount;
}
} else {
walk.0 = dir * speed_amount;
scare.last_vel = walk.0;
}
} else {
Expand Down
30 changes: 20 additions & 10 deletions src/storyteller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
use std::time::Duration;

use bevy::prelude::*;
use rand::Rng;

use crate::{
player::Dog,
sheep::{Sheep, StartSheepCount},
sunday::DayState,
GameSet, GameState,
sheep::{Sheep, StartSheepCount, IsScared, GoTo},
sunday::{DayState, EpisodeTime},
GameSet, GameState, test_level::LevelSize,
};

pub struct StorytellerPlugin;
Expand All @@ -18,8 +19,9 @@ impl Plugin for StorytellerPlugin {
fn build(&self, app: &mut App) {
app.insert_resource(Storyteller {
level_start_time: 0.0,
level_duration: 4.0 * 60.0,
level_duration: 6.0 * 60.0,
safearea_count: 1,
change_safe_area_was_spanwed: false
})
.init_resource::<Score>()
.add_systems(
Expand All @@ -42,6 +44,8 @@ pub struct Storyteller {
pub level_start_time: f32,
pub level_duration: f32,
pub safearea_count: u8,

pub change_safe_area_was_spanwed: bool,
}

impl Storyteller {
Expand Down Expand Up @@ -76,11 +80,11 @@ fn setup_delay(mut delay: ResMut<NextTaskDelay>) {
}

fn storyteller_system(
// mut commands: Commands,
// sheep: Query<(Entity, &Transform), (With<Sheep>, Without<IsScared>, Without<GoTo>)>,
// mut teller: ResMut<Storyteller>,
// time: Res<Time>,
// level_size: Res<LevelSize>,
mut commands: Commands,
sheep: Query<(Entity, &Transform), (With<Sheep>, Without<IsScared>, Without<GoTo>)>,
mut teller: ResMut<Storyteller>,
time: Res<Time>,
level_size: Res<LevelSize>,
dog: Query<&Transform, With<Dog>>,

current_task: Res<State<GlobalTask>>,
Expand Down Expand Up @@ -108,7 +112,12 @@ fn storyteller_system(

match &day_state.get() {
DayState::Day => {
next_task.set(GlobalTask::SheepEscape);
if episode_time.0 > 0.5 && !teller.change_safe_area_was_spanwed {
teller.change_safe_area_was_spanwed = true;
next_task.set(GlobalTask::ChangeSafeArea);
} else {
next_task.set(GlobalTask::SheepEscape);
}
}
DayState::Evening => {}
DayState::Night => {
Expand Down Expand Up @@ -186,4 +195,5 @@ pub enum GlobalTask {
WolfAttack,
CollectSheepInArea,
TorchProblem,
ChangeSafeArea
}
Loading

0 comments on commit f0db426

Please sign in to comment.