diff --git a/src/luamanager/lua_manager.rs b/src/luamanager/lua_manager.rs index 34ea5e9..e618977 100644 --- a/src/luamanager/lua_manager.rs +++ b/src/luamanager/lua_manager.rs @@ -3,19 +3,21 @@ use std::result::Result; use lua_serde::from_file; +use super::scene_config; + use super::scene_config::Group; use super::scene_config::Block; use super::scene_config::Scene; #[derive(Debug)] -struct InternalSceneData { +pub struct InternalSceneData { pub scene_id: u32, pub scene: Scene, pub blocks: HashMap, } #[derive(Debug)] -struct InternalBlockData { +pub struct InternalBlockData { pub scene_id: u32, pub block_id: u32, pub block: Block, @@ -23,7 +25,7 @@ struct InternalBlockData { } #[derive(Debug)] -struct InternalGroupData { +pub struct InternalGroupData { pub scene_id: u32, pub block_id: u32, pub group_id: u32, @@ -31,6 +33,21 @@ struct InternalGroupData { // No extra data here } +/// Implementation of utility functions +impl InternalSceneData { + pub fn get_block_by_pos(&self, pos: &proto::Vector) -> Result<&InternalBlockData, String> { + for (key, value) in self.scene.block_rects.iter() { + if value.contains(pos.x, pos.z) { + let id = self.scene.blocks[&key]; + return Ok(&self.blocks[&id]); + } + } + + return Err(format!("Block in coords {}, {} not found!", pos.x, pos.z)); + } +} + +#[derive(Debug)] pub struct LuaManager { scenes_data: HashMap, } @@ -51,6 +68,14 @@ impl LuaManager { } } + pub fn get_scene_by_id(&self, scene_id: u32) -> Result<&InternalSceneData, String> { + if self.scenes_data.contains_key(&scene_id) { + return Ok(&self.scenes_data[&scene_id]); + } + + return Err(format!("Scene {} not found!", scene_id)); + } + fn load_scenes(directory: &str, scenes_to_load: &Vec) -> HashMap { scenes_to_load .iter() diff --git a/src/luamanager/scene_config.rs b/src/luamanager/scene_config.rs index 937434d..855d7be 100644 --- a/src/luamanager/scene_config.rs +++ b/src/luamanager/scene_config.rs @@ -1,3 +1,4 @@ +use num_traits::Float; use std::collections::HashMap; use serde::Deserialize; @@ -5,27 +6,70 @@ use serde::Deserialize; // sceneX.lua #[derive(Deserialize, PartialEq, Debug)] -pub struct Vector { +pub struct Vector { #[serde(default)] - pub x: T, + pub x: f32, #[serde(default)] - pub y: T, + pub y: f32, #[serde(default)] - pub z: T, + pub z: f32, +} + +impl Vector { + pub fn new(x: f32, y: f32, z: f32) -> Self { + Vector { + x, + y, + z + } + } + + pub fn add(&self, other: &Self) -> Vector { + Vector { + x: self.x + other.x, + y: self.y + other.y, + z: self.z + other.z, + } + } + + pub fn sub(&self, other: &Self) -> Vector { + Vector { + x: self.x - other.x, + y: self.y - other.y, + z: self.z - other.z, + } + } + + pub fn lensq(&self) -> f32 { + self.x*self.x + self.y*self.y + self.z*self.z + } + + pub fn len(&self) -> f32 { + self.lensq().sqrt() + } } #[derive(Deserialize, PartialEq, Debug)] pub struct BlockRect { - pub min: Vector, - pub max: Vector, + pub min: Vector, + pub max: Vector, +} + +impl BlockRect { + pub fn contains(&self, x: f32, z: f32) -> bool { + self.min.x <= x && + self.min.z <= z && + self.max.x > x && + self.max.z > z + } } #[derive(Deserialize, PartialEq, Debug)] pub struct SceneConfig { - pub born_rot: Vector, - pub born_pos: Vector, - pub begin_pos: Vector, - pub size: Vector, + pub born_rot: Vector, + pub born_pos: Vector, + pub begin_pos: Vector, + pub size: Vector, #[serde(default)] pub die_y: f32, } @@ -56,7 +100,7 @@ pub struct GroupInfo { pub dynamic_load: bool, pub id: u32, pub area: Option, - pub pos: Vector, + pub pos: Vector, pub business: Option, } @@ -130,8 +174,8 @@ pub struct Variable { #[derive(Deserialize, PartialEq, Debug)] pub struct Monster { - pub rot: Vector, - pub pos: Vector, + pub rot: Vector, + pub pos: Vector, pub config_id: u32, pub level: u32, pub monster_id: u32, @@ -139,8 +183,8 @@ pub struct Monster { #[derive(Deserialize, PartialEq, Debug)] pub struct Npc { - pub rot: Vector, - pub pos: Vector, + pub rot: Vector, + pub pos: Vector, pub config_id: u32, pub npc_id: u32, @@ -150,8 +194,8 @@ pub struct Npc { #[derive(Deserialize, PartialEq, Debug)] pub struct Gadget { - pub rot: Vector, - pub pos: Vector, + pub rot: Vector, + pub pos: Vector, pub config_id: u32, pub level: u32, pub gadget_id: u32, @@ -175,4 +219,4 @@ pub struct Gadget { pub struct ExploreInfo { pub exp: u32, pub name: String, -} \ No newline at end of file +} diff --git a/src/server/game_server.rs b/src/server/game_server.rs index 43c2935..a964e23 100644 --- a/src/server/game_server.rs +++ b/src/server/game_server.rs @@ -29,7 +29,7 @@ impl GameServer { let jm = Arc::new(JsonManager::new("./data/json")); let lm = LoginManager::new(db.clone(), jm.clone(), packets_to_send_tx.clone()); let lum = Arc::new(LuaManager::new("./data/lua")); - let em = EntitySubsystem::new(packets_to_send_tx.clone()); + let em = EntitySubsystem::new(lum.clone(), packets_to_send_tx.clone()); let gs = GameServer { packets_to_process_rx: packets_to_process_rx, diff --git a/src/subsystems/entity_subsystem.rs b/src/subsystems/entity_subsystem.rs index f681aff..ff8d3df 100644 --- a/src/subsystems/entity_subsystem.rs +++ b/src/subsystems/entity_subsystem.rs @@ -13,19 +13,57 @@ use proto::{PacketId, CombatTypeArgument, ForwardType, ProtEntityType}; use packet_processor_macro::*; #[macro_use] use packet_processor::*; -use crate::utils::IdManager; +use serde_json::de::Read; +use crate::LuaManager; +use crate::utils::{IdManager, TimeManager}; #[derive(Debug, Clone)] struct Player { player_id: u32, pos: proto::Vector, + current_scene: u32, current_block: u32, + entities: HashMap, + lua_manager: Arc, + packets_to_send_tx: Sender, } -#[derive(Debug)] +impl Player { + const DESPAWN_DISTANCE: f32 = 10.0; + const SPAWN_DISTANCE: f32 = 8.0; + const RESPAWN_TIME: i32 = 10; // In seconds + + pub fn despawn_everything(&self) { + let entity_list: Vec = self.entities.iter().map(|(k, v)| *k).collect(); + + if entity_list.len() > 0 { + // TODO: HACK! + let player_id = self.player_id; + let metadata = &build!(PacketHead { + sent_ms: TimeManager::timestamp(), + client_sequence_id: 0, + }); + + build_and_send!(self, player_id, metadata, SceneEntityDisappearNotify { + entity_list: entity_list, + disappear_type: proto::VisionType::VisionMiss as i32, + }) + } + } + + pub fn position_changed(&mut self) { + // 1. Go through the list of spawned entities and despawn those that are too far from us + // 2. Go through the list of available entities and spawn those that are close to us and their respawn timeout (in case of collectibles and monsters) is over + + } + + // Gatherable stuff is described in GatherExcelConfigData +} + +#[derive(Debug,Clone)] pub struct Entity { - health: i32, entity_id: u32, + health: i32, } #[packet_processor( @@ -35,10 +73,11 @@ pub struct EntitySubsystem { packets_to_send_tx: Sender, players: Arc>>, players_moved: Sender, + lua_manager: Arc, } impl EntitySubsystem { - pub fn new(packets_to_send_tx: Sender) -> EntitySubsystem { + pub fn new(lua_manager: Arc, packets_to_send_tx: Sender) -> EntitySubsystem { let (tx, rx): (Sender, Receiver) = mpsc::channel(); let mut es = EntitySubsystem { @@ -46,6 +85,7 @@ impl EntitySubsystem { packet_callbacks: HashMap::new(), players_moved: tx, players: Arc::new(Mutex::new(HashMap::new())), + lua_manager: lua_manager, }; es.register(); @@ -55,21 +95,33 @@ impl EntitySubsystem { return es; } - fn run(&mut self, mut rx: Receiver) { + fn run(&self, mut rx: Receiver) { let players = self.players.clone(); + let lua_manager = self.lua_manager.clone(); - thread::spawn(move|| { + thread::spawn(move || { loop { let player_id = rx.recv().unwrap(); - let mut player = match players.lock() { - Ok(mut players) => players.get_mut(&player_id).unwrap().clone(), + match players.lock() { + Ok(mut players) => { + let mut player = &mut players.get_mut(&player_id).unwrap(); + let scene = lua_manager.get_scene_by_id(player.current_scene).unwrap(); + let block = scene.get_block_by_pos(&player.pos); + + match block { + Ok(block) => + if player.current_block != block.block_id { + println!("Player {:?} moved to the block {:?}", player, block.block_id); + player.current_block = block.block_id; + }, + Err(_) => {/* TODO? */}, + }; + + player.position_changed(); + }, Err(_) => panic!("Failed to grab player data!"), }; - - println!("Player {:?} moved!", player); - - // TODO: get block! } }); } @@ -135,6 +187,10 @@ impl EntitySubsystem { player_id: user_id, pos: pos, current_block: 0, + current_scene: 3, + entities: HashMap::new(), + lua_manager: self.lua_manager.clone(), + packets_to_send_tx: self.packets_to_send_tx.clone(), }; entry.insert(player);