Files
snow_trail/src/world.rs
2026-03-28 11:24:11 +01:00

224 lines
6.9 KiB
Rust

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<T>
{
pub components: HashMap<EntityHandle, T>,
}
impl<T> Storage<T>
{
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<F, R>(&self, entity: EntityHandle, f: F) -> Option<R>
where
F: FnOnce(&T) -> R,
{
self.components.get(&entity).map(f)
}
pub fn with_mut<F, R>(&mut self, entity: EntityHandle, f: F) -> Option<R>
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<EntityHandle>
{
self.components.keys().copied().collect()
}
}
pub struct World
{
pub entities: EntityManager,
pub transforms: Storage<Transform>,
pub meshes: Storage<MeshComponent>,
pub physics: Storage<PhysicsComponent>,
pub movements: Storage<MovementComponent>,
pub jumps: Storage<JumpComponent>,
pub inputs: Storage<InputComponent>,
pub player_tags: Storage<()>,
pub state_machines: Storage<StateMachine>,
pub idle_states: Storage<IdleState>,
pub walking_states: Storage<WalkingState>,
pub jumping_states: Storage<JumpingState>,
pub falling_states: Storage<FallingState>,
pub leaping_states: Storage<LeapingState>,
pub rolling_states: Storage<RollingState>,
pub cameras: Storage<CameraComponent>,
pub spotlights: Storage<SpotlightComponent>,
pub tree_tags: Storage<()>,
pub dissolves: Storage<DissolveComponent>,
pub follows: Storage<FollowComponent>,
pub rotates: Storage<RotateComponent>,
pub tree_instances: Storage<TreeInstancesComponent>,
pub names: Storage<String>,
pub triggers: Storage<TriggerComponent>,
pub trigger_events: Vec<TriggerEvent>,
pub dialog_sources: Storage<DialogSourceComponent>,
pub dialog_bubbles: Storage<DialogBubbleComponent>,
pub dialog_projectiles: Storage<DialogProjectileComponent>,
pub bubble_tags: Storage<()>,
pub projectile_tags: Storage<()>,
pub dialog_outcomes: Vec<DialogOutcomeEvent>,
// --- singleton state (not per-entity) ---
pub snow_layer: Option<SnowLayer>,
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)
}
}