use std::collections::HashMap; use specs::{ World, WorldExt, Join, Entity, RunNow }; use crate::{ controls::Control, worldmessages::WorldMessage, resources::{ Size, Output, Input, NewEntities, Spawn as SpawnPosition, Players, Emigration, Time, RoomFlags }, components::{ Position, Serialise, Player, Inventory, Health, Removed, Clan }, Encyclopedia, roomtemplate::RoomTemplate, savestate::SaveState, Template, playerstate::{PlayerState, RoomPos}, componentwrapper::extract_parameter, Pos, PlayerId, RoomId, aerr, Result, Timestamp, systems::{ Move, RegisterNew, ControlInput, View, Remove, Create, Take, Migrate, Use, Attacking, Trapping, Fight, Heal, UpdateCooldowns, ControlAI, Die, Spawn, Interact, DropLoot, Timeout, Clear, Building, SpawnTrigger, Replace, SpawnCheck, } }; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum RoomType { Normal, Purgatory } pub struct Room { world: World, pub id: RoomId, places: HashMap, room_type: RoomType } macro_rules! register_insert { ($world: expr, ($($comp: ident),*), ($($res: ident),*)) => { $( $world.register::(); )* $( $world.insert(crate::resources::$res::default()); )* } } impl Room { pub fn new(id: RoomId, encyclopedia: Encyclopedia, room_type: RoomType) -> Room { let mut world = World::new(); world.insert(NewEntities::new(encyclopedia)); register_insert!( world, (Position, Visible, Controller, Movable, New, Removed, Moved, Player, Inventory, Health, Serialise, RoomExit, Entered, TriggerBox, Trap, Fighter, Healing, ControlCooldown, Autofight, MonsterAI, AttackInbox, Item, Spawner, Clan, Faction, Interactable, Loot, Timer, TimeOffset, Flags, Ear, Build, Whitelist, Minable, LootHolder, OnSpawn, Substitute, Stats, Requirements), (Ground, Input, Output, Size, Spawn, Players, Emigration, Time, RoomFlags) ); Room { world, id, places: HashMap::new(), room_type } } pub fn load_from_template(&mut self, template: &RoomTemplate) -> Result<()> { let (width, height) = template.size; self.world.fetch_mut::().width = width; self.world.fetch_mut::().height = height; self.world.fetch_mut::().pos = template.spawn; self.world.insert::(template.flags.clone()); for (idx, templates) in template.field.iter().enumerate() { let x = (idx as i64) % width; let y = (idx as i64) / width; for template in templates { self.create_entity(template.clone().unsaved(), Pos{x, y})?; } } for (name, place) in &template.places { self.places.insert(name.clone(), *place); } Ok(()) } pub fn view(&self) -> HashMap { self.world.fetch::().output.clone() } pub fn update(&mut self, timestamp: Timestamp) { self.world.fetch_mut::