Skip to content

Commit

Permalink
Refactor to substates
Browse files Browse the repository at this point in the history
Still need to migrate some logic into `StateScoped`.
  • Loading branch information
Shatur committed Jul 20, 2024
1 parent 7684ed3 commit e5ed2a1
Show file tree
Hide file tree
Showing 43 changed files with 247 additions and 361 deletions.
9 changes: 4 additions & 5 deletions app/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ use bevy_replicon_renet::{
use clap::{Args, Parser, Subcommand};

use project_harmonia_base::{
core::GameState,
game_world::{
actor::SelectedActor,
city::{ActiveCity, City},
family::{Family, FamilyMembers},
GameLoad, GameWorld,
GameLoad, GameWorld, WorldState,
},
message::{error_message, Message},
network::{self, DEFAULT_PORT},
Expand Down Expand Up @@ -89,7 +88,7 @@ impl CliPlugin {

fn quick_load(
mut commands: Commands,
mut game_state: ResMut<NextState<GameState>>,
mut world_state: ResMut<NextState<WorldState>>,
cli: Res<Cli>,
cities: Query<(Entity, &City)>,
families: Query<(&Family, &FamilyMembers)>,
Expand All @@ -103,7 +102,7 @@ impl CliPlugin {
.with_context(|| format!("unable to find city named {name}"))?;

commands.entity(entity).insert(ActiveCity);
game_state.set(GameState::City);
world_state.set(WorldState::City);
}
QuickLoad::Family { name } => {
let (_, members) = families
Expand All @@ -115,7 +114,7 @@ impl CliPlugin {
.first()
.expect("family should contain at least one actor");
commands.entity(entity).insert(SelectedActor);
game_state.set(GameState::Family);
world_state.set(WorldState::Family);
}
}
}
Expand Down
14 changes: 5 additions & 9 deletions base/src/core.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
use bevy::prelude::*;
use strum::EnumIter;

pub(super) struct CorePlugin;

impl Plugin for CorePlugin {
fn build(&self, app: &mut App) {
app.init_state::<GameState>();
app.init_state::<GameState>()
.enable_state_scoped_entities::<GameState>();
}
}

#[derive(States, Clone, Copy, Debug, Eq, Hash, PartialEq, Default, EnumIter)]
#[derive(States, Clone, PartialEq, Eq, Hash, Debug, Default)]
pub enum GameState {
#[default]
MainMenu,
WorldBrowser,
FamilyEditor,
World,
City,
Family,
Menu,
InGame,
}
23 changes: 20 additions & 3 deletions base/src/game_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ impl Plugin for GameWorldPlugin {
ObjectPlugin,
PlayerCameraPlugin,
))
.add_sub_state::<WorldState>()
.enable_state_scoped_entities::<WorldState>()
.add_event::<GameSave>()
.add_event::<GameLoad>()
.add_systems(Update, Self::start_game.run_if(client_just_connected))
Expand All @@ -54,7 +56,8 @@ impl Plugin for GameWorldPlugin {
Self::save
.pipe(error_message)
.run_if(on_event::<GameSave>()),
);
)
.add_systems(OnExit(GameState::InGame), Self::cleanup);
}
}

Expand Down Expand Up @@ -112,15 +115,19 @@ impl GameWorldPlugin {
}

scene_spawner.spawn_dynamic(scenes.add(scene));
game_state.set(GameState::World);
game_state.set(GameState::InGame);

Ok(())
}

fn start_game(mut commands: Commands, mut game_state: ResMut<NextState<GameState>>) {
info!("joining replicated world");
commands.insert_resource(GameWorld::default());
game_state.set(GameState::World);
game_state.set(GameState::InGame);
}

fn cleanup(mut commands: Commands) {
commands.remove_resource::<GameWorld>();
}
}

Expand All @@ -140,6 +147,16 @@ pub struct GameWorld {
pub name: String,
}

#[derive(SubStates, Clone, PartialEq, Eq, Hash, Debug, Default)]
#[source(GameState = GameState::InGame)]
pub enum WorldState {
#[default]
World,
FamilyEditor,
City,
Family,
}

#[derive(PhysicsLayer)]
pub(super) enum Layer {
Ground,
Expand Down
14 changes: 8 additions & 6 deletions base/src/game_world/actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ use num_enum::IntoPrimitive;
use serde::{Deserialize, Serialize};
use strum::{Display, EnumIter};

use super::hover::{highlighting::OutlineHighlightingExt, Hoverable};
use super::{
hover::{highlighting::OutlineHighlightingExt, Hoverable},
WorldState,
};
use crate::{
asset::collection::{AssetCollection, Collection},
core::GameState,
game_world::GameWorld,
};
use animation_state::{AnimationState, AnimationStatePlugin};
use human::HumanPlugin;
Expand All @@ -40,21 +42,21 @@ impl Plugin for ActorPlugin {
.replicate::<FirstName>()
.replicate::<Sex>()
.replicate::<LastName>()
.add_systems(OnExit(GameState::Family), Self::remove_selection)
.add_systems(OnExit(WorldState::Family), Self::remove_selection)
.add_systems(
PreUpdate,
Self::init
.after(ClientSet::Receive)
.run_if(resource_exists::<GameWorld>),
.run_if(in_state(GameState::InGame)),
)
.add_systems(
Update,
Self::update_names.run_if(resource_exists::<GameWorld>),
Self::update_names.run_if(in_state(GameState::InGame)),
)
.add_systems(
SpawnScene,
Self::init_children
.run_if(resource_exists::<GameWorld>)
.run_if(in_state(GameState::InGame))
.after(scene::scene_spawner_system),
)
.add_systems(PostUpdate, Self::ensure_single_selection);
Expand Down
9 changes: 3 additions & 6 deletions base/src/game_world/actor/animation_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use strum::EnumCount;
use super::{ActorAnimation, Movement, Sex};
use crate::{
asset::collection::Collection,
game_world::GameWorld,
core::GameState,
navigation::{NavPath, Navigation},
};

Expand All @@ -21,13 +21,10 @@ impl Plugin for AnimationStatePlugin {
.add_systems(
SpawnScene,
Self::init_scene
.run_if(resource_exists::<GameWorld>)
.run_if(in_state(GameState::InGame))
.after(scene::scene_spawner_system),
)
.add_systems(
PostUpdate,
Self::update.run_if(resource_exists::<GameWorld>),
);
.add_systems(PostUpdate, Self::update.run_if(in_state(GameState::InGame)));
}
}

Expand Down
6 changes: 3 additions & 3 deletions base/src/game_world/actor/human.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
core::GameState,
game_world::{
family::{editor::EditableActor, FamilyScene},
GameWorld,
WorldState,
},
};

Expand All @@ -31,13 +31,13 @@ impl Plugin for HumanPlugin {
PreUpdate,
Self::update_sex
.after(ClientSet::Receive)
.run_if(resource_exists::<GameWorld>),
.run_if(in_state(GameState::InGame)),
)
.add_systems(
Update,
(
Self::init_needs, // Should run after `ParentSync` to detect if needs was initialized correctly.
Self::init_children.run_if(in_state(GameState::FamilyEditor)),
Self::init_children.run_if(in_state(WorldState::FamilyEditor)),
),
);
}
Expand Down
4 changes: 2 additions & 2 deletions base/src/game_world/actor/needs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bevy::{prelude::*, time::common_conditions::on_timer};
use bevy_replicon::prelude::*;
use serde::{Deserialize, Serialize};

use crate::game_world::GameWorld;
use crate::core::GameState;

pub(super) struct NeedsPlugin;

Expand Down Expand Up @@ -35,7 +35,7 @@ impl Plugin for NeedsPlugin {
Self::init_bladder,
)
.after(ClientSet::Receive)
.run_if(resource_exists::<GameWorld>),
.run_if(in_state(GameState::InGame)),
)
.add_systems(
Update,
Expand Down
2 changes: 0 additions & 2 deletions base/src/game_world/actor/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use leafwing_input_manager::common_conditions::action_just_pressed;
use serde::{de::DeserializeSeed, Deserialize, Serialize};

use crate::{
core::GameState,
game_world::{
actor::{animation_state::AnimationState, Actor},
family::FamilyMode,
Expand Down Expand Up @@ -56,7 +55,6 @@ impl Plugin for TaskPlugin {
Update,
TaskListSet
.run_if(action_just_pressed(Action::Confirm))
.run_if(in_state(GameState::Family))
.run_if(in_state(FamilyMode::Life)),
)
.add_systems(
Expand Down
4 changes: 2 additions & 2 deletions base/src/game_world/actor/task/friendly/tell_secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ use serde::{Deserialize, Serialize};

use crate::{
asset::collection::Collection,
core::GameState,
game_world::{
actor::{
animation_state::{AnimationState, Montage, MontageFinished},
task::{linked_task::LinkedTask, Task, TaskGroups, TaskList, TaskListSet, TaskState},
Actor, ActorAnimation, Movement,
},
hover::Hovered,
GameWorld,
},
navigation::{following::Following, NavPath, Navigation},
};
Expand All @@ -37,7 +37,7 @@ impl Plugin for TellSecretPlugin {
Self::start_listening,
Self::finish,
)
.run_if(resource_exists::<GameWorld>),
.run_if(in_state(GameState::InGame)),
);
}
}
Expand Down
4 changes: 2 additions & 2 deletions base/src/game_world/actor/task/move_here.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use oxidized_navigation::{NavMesh, NavMeshSettings};
use serde::{Deserialize, Serialize};

use crate::{
core::GameState,
game_world::{
actor::{
task::{Task, TaskGroups, TaskList, TaskListSet, TaskState},
Movement,
},
city::Ground,
hover::Hovered,
GameWorld,
},
navigation::{ComputePath, NavPath, Navigation},
};
Expand All @@ -25,7 +25,7 @@ impl Plugin for MoveHerePlugin {
.add_systems(
Update,
(Self::add_to_list.in_set(TaskListSet), Self::finish)
.run_if(resource_exists::<GameWorld>),
.run_if(in_state(GameState::InGame)),
)
// Should run in `PostUpdate` to let tiles initialize.
.add_systems(PostUpdate, Self::start_navigation.run_if(has_authority));
Expand Down
12 changes: 7 additions & 5 deletions base/src/game_world/building/lot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ use bevy_replicon::prelude::*;
use serde::{Deserialize, Serialize};
use strum::{Display, EnumIter};

use crate::{game_world::GameWorld, math::polygon::Polygon};
use crate::{core::GameState, game_world::city::CityMode, math::polygon::Polygon};
use creating_lot::CreatingLotPlugin;
use moving_lot::MovingLotPlugin;

pub(super) struct LotPlugin;

impl Plugin for LotPlugin {
fn build(&self, app: &mut App) {
app.init_state::<LotTool>()
app.add_sub_state::<LotTool>()
.enable_state_scoped_entities::<LotTool>()
.add_plugins((CreatingLotPlugin, MovingLotPlugin))
.register_type::<Vec<Vec2>>()
.register_type::<LotVertices>()
Expand All @@ -27,12 +28,12 @@ impl Plugin for LotPlugin {
PreUpdate,
Self::init
.after(ClientSet::Receive)
.run_if(resource_exists::<GameWorld>),
.run_if(in_state(GameState::InGame)),
)
.add_systems(
PostUpdate,
(
Self::draw_lines.run_if(resource_exists::<GameWorld>),
Self::draw_lines.run_if(in_state(GameState::InGame)),
(
Self::create.before(ServerSet::StoreHierarchy),
Self::apply_movement,
Expand Down Expand Up @@ -118,8 +119,9 @@ impl LotPlugin {
}

#[derive(
Clone, Component, Copy, Debug, Default, Display, EnumIter, Eq, Hash, PartialEq, States,
Clone, Component, Copy, Debug, Default, Display, EnumIter, Eq, Hash, PartialEq, SubStates,
)]
#[source(CityMode = CityMode::Lots)]
pub enum LotTool {
#[default]
Create,
Expand Down
5 changes: 0 additions & 5 deletions base/src/game_world/building/lot/creating_lot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use leafwing_input_manager::common_conditions::action_just_pressed;

use super::{LotCreate, LotEventConfirmed, LotTool, LotVertices, UnconfirmedLot};
use crate::{
core::GameState,
game_world::{
city::{ActiveCity, CityMode},
player_camera::CameraCaster,
Expand All @@ -22,8 +21,6 @@ impl Plugin for CreatingLotPlugin {
PreUpdate,
Self::end_creating
.after(ClientSet::Receive)
.run_if(in_state(GameState::City))
.run_if(in_state(CityMode::Lots))
.run_if(in_state(LotTool::Create))
.run_if(on_event::<LotEventConfirmed>()),
)
Expand All @@ -37,8 +34,6 @@ impl Plugin for CreatingLotPlugin {
Self::confirm.run_if(action_just_pressed(Action::Confirm)),
Self::end_creating.run_if(action_just_pressed(Action::Cancel)),
)
.run_if(in_state(GameState::City))
.run_if(in_state(CityMode::Lots))
.run_if(in_state(LotTool::Create)),
);
}
Expand Down
Loading

0 comments on commit e5ed2a1

Please sign in to comment.