use std::collections::HashMap; use crate::components::dialog::{ DialogBubbleComponent, DialogOutcomeEvent, DialogProjectileComponent, DialogSourceComponent, }; use crate::components::dissolve::DissolveComponent; use crate::components::follow::FollowComponent; use crate::components::lights::spot::SpotlightComponent; use crate::components::player_states::{ FallingState, IdleState, JumpingState, LeapingState, RollingState, WalkingState, }; use crate::components::tree_instances::TreeInstancesComponent; use crate::components::trigger::{TriggerComponent, TriggerEvent}; use crate::components::{ CameraComponent, InputComponent, JumpComponent, MeshComponent, MovementComponent, PhysicsComponent, RotateComponent, }; use crate::debug::DebugMode; use crate::entity::{EntityHandle, EntityManager}; use crate::render::snow::SnowLayer; use crate::states::state::StateMachine; pub use crate::utility::transform::Transform; pub struct Storage { pub components: HashMap, } impl Storage { pub fn new() -> Self { Self { components: HashMap::new(), } } pub fn insert(&mut self, entity: EntityHandle, component: T) { self.components.insert(entity, component); } pub fn get(&self, entity: EntityHandle) -> Option<&T> { self.components.get(&entity) } pub fn get_mut(&mut self, entity: EntityHandle) -> Option<&mut T> { self.components.get_mut(&entity) } pub fn with(&self, entity: EntityHandle, f: F) -> Option where F: FnOnce(&T) -> R, { self.components.get(&entity).map(f) } pub fn with_mut(&mut self, entity: EntityHandle, f: F) -> Option where F: FnOnce(&mut T) -> R, { self.components.get_mut(&entity).map(f) } pub fn remove(&mut self, entity: EntityHandle) { self.components.remove(&entity); } pub fn all(&self) -> Vec { self.components.keys().copied().collect() } } pub struct World { pub entities: EntityManager, pub transforms: Storage, pub meshes: Storage, pub physics: Storage, pub movements: Storage, pub jumps: Storage, pub inputs: Storage, pub player_tags: Storage<()>, pub state_machines: Storage, pub idle_states: Storage, pub walking_states: Storage, pub jumping_states: Storage, pub falling_states: Storage, pub leaping_states: Storage, pub rolling_states: Storage, pub cameras: Storage, pub spotlights: Storage, pub tree_tags: Storage<()>, pub dissolves: Storage, pub follows: Storage, pub rotates: Storage, pub tree_instances: Storage, pub names: Storage, pub triggers: Storage, pub trigger_events: Vec, pub dialog_sources: Storage, pub dialog_bubbles: Storage, pub dialog_projectiles: Storage, pub bubble_tags: Storage<()>, pub projectile_tags: Storage<()>, pub dialog_outcomes: Vec, // --- singleton state (not per-entity) --- pub snow_layer: Option, pub debug_mode: DebugMode, } impl World { pub fn new() -> Self { Self { entities: EntityManager::new(), transforms: Storage::new(), meshes: Storage::new(), physics: Storage::new(), movements: Storage::new(), jumps: Storage::new(), inputs: Storage::new(), player_tags: Storage::new(), state_machines: Storage::new(), idle_states: Storage::new(), walking_states: Storage::new(), jumping_states: Storage::new(), falling_states: Storage::new(), leaping_states: Storage::new(), rolling_states: Storage::new(), cameras: Storage::new(), spotlights: Storage::new(), tree_tags: Storage::new(), dissolves: Storage::new(), follows: Storage::new(), rotates: Storage::new(), tree_instances: Storage::new(), names: Storage::new(), triggers: Storage::new(), trigger_events: Vec::new(), dialog_sources: Storage::new(), dialog_bubbles: Storage::new(), dialog_projectiles: Storage::new(), bubble_tags: Storage::new(), projectile_tags: Storage::new(), dialog_outcomes: Vec::new(), snow_layer: None, debug_mode: DebugMode::default(), } } pub fn spawn(&mut self) -> EntityHandle { self.entities.spawn() } pub fn despawn(&mut self, entity: EntityHandle) { self.transforms.remove(entity); self.meshes.remove(entity); self.physics.remove(entity); self.movements.remove(entity); self.jumps.remove(entity); self.inputs.remove(entity); self.player_tags.remove(entity); self.state_machines.remove(entity); self.idle_states.remove(entity); self.walking_states.remove(entity); self.jumping_states.remove(entity); self.falling_states.remove(entity); self.leaping_states.remove(entity); self.rolling_states.remove(entity); self.cameras.remove(entity); self.spotlights.remove(entity); self.tree_tags.remove(entity); self.dissolves.remove(entity); self.follows.remove(entity); self.rotates.remove(entity); self.tree_instances.remove(entity); self.names.remove(entity); self.triggers.remove(entity); self.dialog_sources.remove(entity); self.dialog_bubbles.remove(entity); self.dialog_projectiles.remove(entity); self.bubble_tags.remove(entity); self.projectile_tags.remove(entity); self.entities.despawn(entity); } pub fn active_camera(&self) -> Option<(EntityHandle, &CameraComponent)> { self.cameras .components .iter() .find(|(_, cam)| cam.is_active) .map(|(e, c)| (*e, c)) } pub fn active_camera_position(&self) -> glam::Vec3 { self.active_camera() .and_then(|(entity, _)| self.transforms.get(entity)) .map(|t| t.position) .unwrap_or(glam::Vec3::ZERO) } pub fn player_position(&self) -> glam::Vec3 { self.player_tags .all() .first() .and_then(|e| self.transforms.get(*e)) .map(|t| t.position) .unwrap_or(glam::Vec3::ZERO) } }