init
This commit is contained in:
207
rust/src/systems/game_manager.rs
Normal file
207
rust/src/systems/game_manager.rs
Normal file
@@ -0,0 +1,207 @@
|
||||
use crate::{
|
||||
core::game_state::GameState, data::day_config::DayConfig, systems::hazard_system::HazardSystem,
|
||||
};
|
||||
use godot::{
|
||||
classes::{Control, Label},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
#[derive(GodotClass)]
|
||||
#[class(base=Node)]
|
||||
pub struct GameManager {
|
||||
#[export]
|
||||
days: Array<Gd<DayConfig>>,
|
||||
|
||||
#[export]
|
||||
game_state: Option<Gd<GameState>>,
|
||||
|
||||
#[export]
|
||||
hazard_system: Option<Gd<HazardSystem>>,
|
||||
#[export]
|
||||
minigame_container: Option<Gd<Node>>,
|
||||
|
||||
#[export]
|
||||
win_screen: Option<Gd<Control>>,
|
||||
#[export]
|
||||
lose_screen: Option<Gd<Control>>,
|
||||
#[export]
|
||||
game_complete_screen: Option<Gd<Control>>,
|
||||
|
||||
#[export]
|
||||
day_label: Option<Gd<Label>>,
|
||||
#[export]
|
||||
main_menu_scene: Option<Gd<PackedScene>>,
|
||||
|
||||
current_day_index: i32,
|
||||
current_mini_game: Option<Gd<Node>>,
|
||||
|
||||
level_ended: bool,
|
||||
|
||||
base: Base<Node>,
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl INode for GameManager {
|
||||
fn init(base: Base<Node>) -> Self {
|
||||
Self {
|
||||
days: Array::new(),
|
||||
game_state: None,
|
||||
hazard_system: None,
|
||||
minigame_container: None,
|
||||
win_screen: None,
|
||||
lose_screen: None,
|
||||
game_complete_screen: None,
|
||||
day_label: None,
|
||||
main_menu_scene: None,
|
||||
current_day_index: 0,
|
||||
current_mini_game: None,
|
||||
level_ended: false,
|
||||
base,
|
||||
}
|
||||
}
|
||||
|
||||
fn ready(&mut self) {
|
||||
let idx = self.current_day_index;
|
||||
self.base_mut()
|
||||
.call_deferred("start_day", &[idx.to_variant()]);
|
||||
}
|
||||
|
||||
fn process(&mut self, _delta: f64) {
|
||||
if self.level_ended {
|
||||
return;
|
||||
}
|
||||
|
||||
let (won, lost) = if let Some(state) = &self.game_state {
|
||||
let bind = state.bind();
|
||||
(bind.get_is_lift_complete(), bind.get_is_lift_failed())
|
||||
} else {
|
||||
(false, false)
|
||||
};
|
||||
|
||||
if won {
|
||||
self.handle_win();
|
||||
self.level_ended = true;
|
||||
} else if lost {
|
||||
self.handle_loss();
|
||||
self.level_ended = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl GameManager {
|
||||
#[func]
|
||||
fn start_day(&mut self, index: i32) {
|
||||
self.level_ended = false;
|
||||
|
||||
if let Some(state) = &self.game_state {
|
||||
let bind = state.bind();
|
||||
|
||||
if let Ok(mut inner) = bind.inner.write() {
|
||||
inner.is_lift_complete = false;
|
||||
inner.is_lift_failed = false;
|
||||
|
||||
inner.lift_progress = 0.0;
|
||||
inner.visual_height = 0.0;
|
||||
inner.lift_effort = 0.0;
|
||||
inner.active_hazards.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if index >= self.days.len() as i32 {
|
||||
self.cleanup_level();
|
||||
if let Some(s) = &mut self.game_complete_screen {
|
||||
s.set_visible(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
self.cleanup_level();
|
||||
|
||||
let config = self.days.get(index as usize).expect("Invalid Day Index");
|
||||
let config_bind = config.bind();
|
||||
|
||||
if let Some(prefab) = &config_bind.mini_game_scene {
|
||||
if let Some(instance) = prefab.instantiate() {
|
||||
if let Some(container) = &mut self.minigame_container {
|
||||
container.add_child(&instance.clone());
|
||||
}
|
||||
|
||||
if let Some(mut system) = instance.get_node_or_null("System") {
|
||||
system.set("target_value", &config_bind.target_weight.to_variant());
|
||||
system.set("gravity", &config_bind.gravity.to_variant());
|
||||
|
||||
if let Some(state) = &self.game_state {
|
||||
system.set("game_state", &state.to_variant());
|
||||
}
|
||||
}
|
||||
self.current_mini_game = Some(instance);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(hs) = &mut self.hazard_system {
|
||||
hs.bind_mut()
|
||||
.set_available_hazards(config_bind.available_hazards.clone());
|
||||
}
|
||||
|
||||
if let Some(l) = &mut self.day_label {
|
||||
l.set_text(&config_bind.day_title);
|
||||
}
|
||||
if let Some(s) = &mut self.win_screen {
|
||||
s.set_visible(false);
|
||||
}
|
||||
if let Some(s) = &mut self.lose_screen {
|
||||
s.set_visible(false);
|
||||
}
|
||||
}
|
||||
|
||||
fn cleanup_level(&mut self) {
|
||||
if let Some(game) = &mut self.current_mini_game {
|
||||
game.queue_free();
|
||||
self.current_mini_game = None;
|
||||
}
|
||||
if let Some(hs) = &mut self.hazard_system {
|
||||
hs.bind_mut().clear_hazards();
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_win(&mut self) {
|
||||
if let Some(s) = &mut self.win_screen {
|
||||
s.set_visible(true);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_loss(&mut self) {
|
||||
if let Some(s) = &mut self.lose_screen {
|
||||
s.set_visible(true);
|
||||
}
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn on_next_day_pressed(&mut self) {
|
||||
self.current_day_index += 1;
|
||||
let idx = self.current_day_index;
|
||||
self.base_mut()
|
||||
.call_deferred("start_day", &[idx.to_variant()]);
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn on_retry_pressed(&mut self) {
|
||||
let idx = self.current_day_index;
|
||||
self.base_mut()
|
||||
.call_deferred("start_day", &[idx.to_variant()]);
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn on_menu_pressed(&mut self) {
|
||||
if let Some(menu) = &self.main_menu_scene {
|
||||
let menu_ref = menu.clone();
|
||||
self.base()
|
||||
.get_tree()
|
||||
.unwrap()
|
||||
.change_scene_to_packed(&menu_ref);
|
||||
} else {
|
||||
self.base().get_tree().unwrap().quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user