Track current block for the player

This commit is contained in:
Nobody 2022-02-07 23:17:43 +05:00
parent 5e3e03710e
commit 8b6f33421c
4 changed files with 159 additions and 34 deletions

View File

@ -3,19 +3,21 @@ use std::result::Result;
use lua_serde::from_file; use lua_serde::from_file;
use super::scene_config;
use super::scene_config::Group; use super::scene_config::Group;
use super::scene_config::Block; use super::scene_config::Block;
use super::scene_config::Scene; use super::scene_config::Scene;
#[derive(Debug)] #[derive(Debug)]
struct InternalSceneData { pub struct InternalSceneData {
pub scene_id: u32, pub scene_id: u32,
pub scene: Scene, pub scene: Scene,
pub blocks: HashMap<u32,InternalBlockData>, pub blocks: HashMap<u32,InternalBlockData>,
} }
#[derive(Debug)] #[derive(Debug)]
struct InternalBlockData { pub struct InternalBlockData {
pub scene_id: u32, pub scene_id: u32,
pub block_id: u32, pub block_id: u32,
pub block: Block, pub block: Block,
@ -23,7 +25,7 @@ struct InternalBlockData {
} }
#[derive(Debug)] #[derive(Debug)]
struct InternalGroupData { pub struct InternalGroupData {
pub scene_id: u32, pub scene_id: u32,
pub block_id: u32, pub block_id: u32,
pub group_id: u32, pub group_id: u32,
@ -31,6 +33,21 @@ struct InternalGroupData {
// No extra data here // 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 { pub struct LuaManager {
scenes_data: HashMap<u32,InternalSceneData>, scenes_data: HashMap<u32,InternalSceneData>,
} }
@ -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<u32>) -> HashMap<u32,InternalSceneData> { fn load_scenes(directory: &str, scenes_to_load: &Vec<u32>) -> HashMap<u32,InternalSceneData> {
scenes_to_load scenes_to_load
.iter() .iter()

View File

@ -1,3 +1,4 @@
use num_traits::Float;
use std::collections::HashMap; use std::collections::HashMap;
use serde::Deserialize; use serde::Deserialize;
@ -5,27 +6,70 @@ use serde::Deserialize;
// sceneX.lua // sceneX.lua
#[derive(Deserialize, PartialEq, Debug)] #[derive(Deserialize, PartialEq, Debug)]
pub struct Vector<T> { pub struct Vector {
#[serde(default)] #[serde(default)]
pub x: T, pub x: f32,
#[serde(default)] #[serde(default)]
pub y: T, pub y: f32,
#[serde(default)] #[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)] #[derive(Deserialize, PartialEq, Debug)]
pub struct BlockRect { pub struct BlockRect {
pub min: Vector<f32>, pub min: Vector,
pub max: Vector<f32>, 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)] #[derive(Deserialize, PartialEq, Debug)]
pub struct SceneConfig { pub struct SceneConfig {
pub born_rot: Vector<f32>, pub born_rot: Vector,
pub born_pos: Vector<f32>, pub born_pos: Vector,
pub begin_pos: Vector<f32>, pub begin_pos: Vector,
pub size: Vector<f32>, pub size: Vector,
#[serde(default)] #[serde(default)]
pub die_y: f32, pub die_y: f32,
} }
@ -56,7 +100,7 @@ pub struct GroupInfo {
pub dynamic_load: bool, pub dynamic_load: bool,
pub id: u32, pub id: u32,
pub area: Option<u32>, pub area: Option<u32>,
pub pos: Vector<f32>, pub pos: Vector,
pub business: Option<Business>, pub business: Option<Business>,
} }
@ -130,8 +174,8 @@ pub struct Variable {
#[derive(Deserialize, PartialEq, Debug)] #[derive(Deserialize, PartialEq, Debug)]
pub struct Monster { pub struct Monster {
pub rot: Vector<f32>, pub rot: Vector,
pub pos: Vector<f32>, pub pos: Vector,
pub config_id: u32, pub config_id: u32,
pub level: u32, pub level: u32,
pub monster_id: u32, pub monster_id: u32,
@ -139,8 +183,8 @@ pub struct Monster {
#[derive(Deserialize, PartialEq, Debug)] #[derive(Deserialize, PartialEq, Debug)]
pub struct Npc { pub struct Npc {
pub rot: Vector<f32>, pub rot: Vector,
pub pos: Vector<f32>, pub pos: Vector,
pub config_id: u32, pub config_id: u32,
pub npc_id: u32, pub npc_id: u32,
@ -150,8 +194,8 @@ pub struct Npc {
#[derive(Deserialize, PartialEq, Debug)] #[derive(Deserialize, PartialEq, Debug)]
pub struct Gadget { pub struct Gadget {
pub rot: Vector<f32>, pub rot: Vector,
pub pos: Vector<f32>, pub pos: Vector,
pub config_id: u32, pub config_id: u32,
pub level: u32, pub level: u32,
pub gadget_id: u32, pub gadget_id: u32,

View File

@ -29,7 +29,7 @@ impl GameServer {
let jm = Arc::new(JsonManager::new("./data/json")); let jm = Arc::new(JsonManager::new("./data/json"));
let lm = LoginManager::new(db.clone(), jm.clone(), packets_to_send_tx.clone()); let lm = LoginManager::new(db.clone(), jm.clone(), packets_to_send_tx.clone());
let lum = Arc::new(LuaManager::new("./data/lua")); 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 { let gs = GameServer {
packets_to_process_rx: packets_to_process_rx, packets_to_process_rx: packets_to_process_rx,

View File

@ -13,19 +13,57 @@ use proto::{PacketId, CombatTypeArgument, ForwardType, ProtEntityType};
use packet_processor_macro::*; use packet_processor_macro::*;
#[macro_use] #[macro_use]
use packet_processor::*; use packet_processor::*;
use crate::utils::IdManager; use serde_json::de::Read;
use crate::LuaManager;
use crate::utils::{IdManager, TimeManager};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct Player { struct Player {
player_id: u32, player_id: u32,
pos: proto::Vector, pos: proto::Vector,
current_scene: u32,
current_block: u32, current_block: u32,
entities: HashMap<u32,Entity>,
lua_manager: Arc<LuaManager>,
packets_to_send_tx: Sender<IpcMessage>,
} }
#[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<u32> = 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 { pub struct Entity {
health: i32,
entity_id: u32, entity_id: u32,
health: i32,
} }
#[packet_processor( #[packet_processor(
@ -35,10 +73,11 @@ pub struct EntitySubsystem {
packets_to_send_tx: Sender<IpcMessage>, packets_to_send_tx: Sender<IpcMessage>,
players: Arc<Mutex<HashMap<u32, Player>>>, players: Arc<Mutex<HashMap<u32, Player>>>,
players_moved: Sender<u32>, players_moved: Sender<u32>,
lua_manager: Arc<LuaManager>,
} }
impl EntitySubsystem { impl EntitySubsystem {
pub fn new(packets_to_send_tx: Sender<IpcMessage>) -> EntitySubsystem { pub fn new(lua_manager: Arc<LuaManager>, packets_to_send_tx: Sender<IpcMessage>) -> EntitySubsystem {
let (tx, rx): (Sender<u32>, Receiver<u32>) = mpsc::channel(); let (tx, rx): (Sender<u32>, Receiver<u32>) = mpsc::channel();
let mut es = EntitySubsystem { let mut es = EntitySubsystem {
@ -46,6 +85,7 @@ impl EntitySubsystem {
packet_callbacks: HashMap::new(), packet_callbacks: HashMap::new(),
players_moved: tx, players_moved: tx,
players: Arc::new(Mutex::new(HashMap::new())), players: Arc::new(Mutex::new(HashMap::new())),
lua_manager: lua_manager,
}; };
es.register(); es.register();
@ -55,21 +95,33 @@ impl EntitySubsystem {
return es; return es;
} }
fn run(&mut self, mut rx: Receiver<u32>) { fn run(&self, mut rx: Receiver<u32>) {
let players = self.players.clone(); let players = self.players.clone();
let lua_manager = self.lua_manager.clone();
thread::spawn(move || { thread::spawn(move || {
loop { loop {
let player_id = rx.recv().unwrap(); let player_id = rx.recv().unwrap();
let mut player = match players.lock() { match players.lock() {
Ok(mut players) => players.get_mut(&player_id).unwrap().clone(), Ok(mut players) => {
Err(_) => panic!("Failed to grab player data!"), 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? */},
}; };
println!("Player {:?} moved!", player); player.position_changed();
},
// TODO: get block! Err(_) => panic!("Failed to grab player data!"),
};
} }
}); });
} }
@ -135,6 +187,10 @@ impl EntitySubsystem {
player_id: user_id, player_id: user_id,
pos: pos, pos: pos,
current_block: 0, 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); entry.insert(player);