Monsters now have weapons!

This commit is contained in:
Nobody 2022-04-04 23:48:11 +05:00
parent f233de8202
commit 00f40d2bde
4 changed files with 73 additions and 18 deletions

View File

@ -6,7 +6,7 @@ use rand::{self, Rng};
#[macro_use] #[macro_use]
use packet_processor::*; use packet_processor::*;
use crate::{DatabaseManager, JsonManager}; use crate::{DatabaseManager, EntityManager, JsonManager};
use crate::jsonmanager::{CurveInfo, EntityCurve}; use crate::jsonmanager::{CurveInfo, EntityCurve};
use crate::collection; use crate::collection;
@ -119,6 +119,16 @@ impl EntityTrait for Monster {
}, },
}; };
let weapon_list: Vec<_> = self.weapons_list.iter()
.map(|mwi| {
build!(SceneWeaponInfo {
entity_id: mwi.entity_id,
gadget_id: mwi.gadget_id,
ability_info: Some(build!(AbilitySyncStateInfo { is_inited: true, })),
// TODO: there're many more fields!
})
}).collect();
proto::scene_entity_info::Entity::Monster(build!(SceneMonsterInfo { proto::scene_entity_info::Entity::Monster(build!(SceneMonsterInfo {
monster_id: self.monster_id, monster_id: self.monster_id,
group_id: group_id, group_id: group_id,
@ -127,7 +137,8 @@ impl EntityTrait for Monster {
born_type: proto::MonsterBornType::MonsterBornDefault as i32, // TODO: hardcoded value! born_type: proto::MonsterBornType::MonsterBornDefault as i32, // TODO: hardcoded value!
block_id: block_id, block_id: block_id,
affix_list: affixes, affix_list: affixes,
// TODO: special_name! weapon_list: weapon_list,
// TODO: special_name_id, title_id, pose_id!
})) }))
} }
fn props(&self, world_level: u32, jm: &Arc<JsonManager>, db: &Arc<DatabaseManager>) -> HashMap<u32, i64> { fn props(&self, world_level: u32, jm: &Arc<JsonManager>, db: &Arc<DatabaseManager>) -> HashMap<u32, i64> {
@ -231,7 +242,7 @@ impl EntityTrait for Npc {
fn etype(&self) -> proto::ProtEntityType { fn etype(&self) -> proto::ProtEntityType {
proto::ProtEntityType::ProtEntityNpc proto::ProtEntityType::ProtEntityNpc
} }
fn info(&self, block_id: u32, group_id: u32, jm: &Arc<JsonManager>,) -> proto::scene_entity_info::Entity { fn info(&self, block_id: u32, group_id: u32, jm: &Arc<JsonManager>) -> proto::scene_entity_info::Entity {
proto::scene_entity_info::Entity::Npc(build!(SceneNpcInfo { proto::scene_entity_info::Entity::Npc(build!(SceneNpcInfo {
npc_id: self.npc_id, npc_id: self.npc_id,
block_id: block_id, block_id: block_id,
@ -271,7 +282,7 @@ impl EntityTrait for Gadget {
fn etype(&self) -> proto::ProtEntityType { fn etype(&self) -> proto::ProtEntityType {
proto::ProtEntityType::ProtEntityGadget proto::ProtEntityType::ProtEntityGadget
} }
fn info(&self, block_id: u32, group_id: u32, jm: &Arc<JsonManager>,) -> proto::scene_entity_info::Entity { fn info(&self, block_id: u32, group_id: u32, jm: &Arc<JsonManager>) -> proto::scene_entity_info::Entity {
proto::scene_entity_info::Entity::Gadget(build!(SceneGadgetInfo { proto::scene_entity_info::Entity::Gadget(build!(SceneGadgetInfo {
gadget_id: self.gadget_id, gadget_id: self.gadget_id,
group_id: group_id, group_id: group_id,

View File

@ -6,6 +6,7 @@ use crate::utils::IdManager;
use crate::entitymanager::{Entity, EntityTrait}; use crate::entitymanager::{Entity, EntityTrait};
use lua_serde::from_file; use lua_serde::from_file;
use crate::JsonManager;
use super::scene_config; use super::scene_config;
@ -16,6 +17,7 @@ pub use super::scene_config::Vector;
pub use super::scene_config::Monster; pub use super::scene_config::Monster;
pub use super::scene_config::Npc; pub use super::scene_config::Npc;
pub use super::scene_config::Gadget; pub use super::scene_config::Gadget;
pub use super::scene_config::MonsterWeaponInfo;
#[derive(Debug)] #[derive(Debug)]
pub struct InternalSceneData { pub struct InternalSceneData {
@ -66,6 +68,7 @@ impl InternalSceneData {
#[derive(Debug)] #[derive(Debug)]
pub struct LuaManager { pub struct LuaManager {
scenes_data: HashMap<u32,InternalSceneData>, scenes_data: HashMap<u32,InternalSceneData>,
last_entity_id: u32,
} }
// TODO: Hack-y stuff! // TODO: Hack-y stuff!
@ -74,13 +77,16 @@ macro_rules! block_name { () => ("{}/Scene/{}/scene{}_block{}.lua")}
macro_rules! group_name { () => ("{}/Scene/{}/scene{}_group{}.lua")} macro_rules! group_name { () => ("{}/Scene/{}/scene{}_group{}.lua")}
impl LuaManager { impl LuaManager {
pub fn new(directory: &str) -> LuaManager { pub fn new(directory: &str, jm: &Arc<JsonManager>) -> LuaManager {
let mut entity_id_counter: u32 = 1;
let scenes_to_load = vec![3]; // TODO! let scenes_to_load = vec![3]; // TODO!
let scenes = Self::load_scenes(directory, &scenes_to_load); let scenes = Self::load_scenes(directory, jm, &scenes_to_load, &mut entity_id_counter);
LuaManager { LuaManager {
scenes_data: scenes, scenes_data: scenes,
last_entity_id: entity_id_counter,
} }
} }
@ -92,23 +98,21 @@ impl LuaManager {
return Err(format!("Scene {} not found!", 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, jm: &Arc<JsonManager>, scenes_to_load: &Vec<u32>, entity_id_counter: &mut u32) -> HashMap<u32,InternalSceneData> {
scenes_to_load scenes_to_load
.iter() .iter()
.map(|scene_id| (*scene_id, Self::load_scene(directory, *scene_id))) .map(|scene_id| (*scene_id, Self::load_scene(directory, jm, *scene_id, entity_id_counter)))
.collect() .collect()
} }
fn load_scene(directory: &str, scene_id: u32) -> InternalSceneData { fn load_scene(directory: &str, jm: &Arc<JsonManager>, scene_id: u32, entity_id_counter: &mut u32) -> InternalSceneData {
let mut entity_id_counter: u32 = 1;
let filename = format!(scene_name!(), directory, scene_id, scene_id); let filename = format!(scene_name!(), directory, scene_id, scene_id);
let scene: Scene = from_file(&filename).unwrap(); // TODO: error handling! let scene: Scene = from_file(&filename).unwrap(); // TODO: error handling!
let blocks = scene.blocks let blocks = scene.blocks
.iter() .iter()
.map(|(key, block_id)| (*block_id, Self::load_block(directory, scene_id, *block_id, &mut entity_id_counter))) .map(|(key, block_id)| (*block_id, Self::load_block(directory, jm, scene_id, *block_id, entity_id_counter)))
.collect(); .collect();
InternalSceneData { InternalSceneData {
@ -118,7 +122,7 @@ impl LuaManager {
} }
} }
fn load_block(directory: &str, scene_id: u32, block_id: u32, entity_id_counter: &mut u32) -> InternalBlockData { fn load_block(directory: &str, jm: &Arc<JsonManager>, scene_id: u32, block_id: u32, entity_id_counter: &mut u32) -> InternalBlockData {
let filename = format!(block_name!(), directory, scene_id, scene_id, block_id); let filename = format!(block_name!(), directory, scene_id, scene_id, block_id);
let block: Block = from_file(&filename).unwrap(); // TODO: error handling! let block: Block = from_file(&filename).unwrap(); // TODO: error handling!
@ -127,12 +131,12 @@ impl LuaManager {
// TODO: should be this! But some groups are missing // TODO: should be this! But some groups are missing
block.groups block.groups
.iter() .iter()
.map(|(key, group_info)| (group_info.id, Self::load_group(directory, scene_id, block_id, group_info.id).unwrap() /* Unwrap to make compiler happy*/)) .map(|(key, group_info)| (group_info.id, Self::load_group(directory, jm, scene_id, block_id, group_info.id).unwrap() /* Unwrap to make compiler happy*/))
.collect() .collect()
} else { } else {
let (groups, errors): (Vec<_>, Vec<_>) = block.groups let (groups, errors): (Vec<_>, Vec<_>) = block.groups
.iter() .iter()
.map(|(key, group_info)| (group_info.id, Self::load_group(directory, scene_id, block_id, group_info.id))) .map(|(key, group_info)| (group_info.id, Self::load_group(directory, jm, scene_id, block_id, group_info.id)))
.partition(|(group_id, result)| result.is_ok()); .partition(|(group_id, result)| result.is_ok());
let groups = groups.into_iter().map(|(group_id, result)| (group_id, result.unwrap())).collect(); let groups = groups.into_iter().map(|(group_id, result)| (group_id, result.unwrap())).collect();
@ -163,12 +167,39 @@ impl LuaManager {
let entity_id = IdManager::get_entity_id_by_type_and_sub_id(&proto::ProtEntityType::ProtEntityMonster, *entity_id_counter); let entity_id = IdManager::get_entity_id_by_type_and_sub_id(&proto::ProtEntityType::ProtEntityMonster, *entity_id_counter);
*entity_id_counter = *entity_id_counter + 1; *entity_id_counter = *entity_id_counter + 1;
let real_monster_id = monster.monster_id;
let monster_info = &jm.monsters.get(&real_monster_id);
let mut monster = monster.clone();
monster.weapons_list = match monster_info {
Some(mi) => {
// TODO: HACK! There's usually at most two values, one of them sometimes nonzero
mi.equips.iter()
.filter(|id| **id > 0)
.map(|id| {
let mwi = MonsterWeaponInfo {
entity_id: IdManager::get_entity_id_by_type_and_sub_id(&proto::ProtEntityType::ProtEntityWeapon, *entity_id_counter),
gadget_id: *id,
};
*entity_id_counter = *entity_id_counter + 1;
mwi
})
.collect()
},
None => {
println!("No monster info found for monster {}! No weapon.", real_monster_id);
vec![]
},
};
entities.insert(entity_id, Arc::new(Entity { entities.insert(entity_id, Arc::new(Entity {
entity_id: entity_id, entity_id: entity_id,
group_id: *group_id, group_id: *group_id,
block_id: block_id, block_id: block_id,
health: 0, health: 0,
entity: Arc::new(monster.clone()), // TODO: very fucking inefficient! entity: Arc::new(monster), // TODO: very fucking inefficient!
})); }));
} }
@ -195,7 +226,7 @@ impl LuaManager {
} }
} }
fn load_group(directory: &str, scene_id: u32, block_id: u32, group_id: u32) -> Result<(InternalGroupData), std::io::Error> { fn load_group(directory: &str, jm: &Arc<JsonManager>, scene_id: u32, block_id: u32, group_id: u32) -> Result<(InternalGroupData), std::io::Error> {
let filename = format!(group_name!(), directory, scene_id, scene_id, group_id); let filename = format!(group_name!(), directory, scene_id, scene_id, group_id);
//let group: Group = from_file(&filename).unwrap(); // TODO: error handling! //let group: Group = from_file(&filename).unwrap(); // TODO: error handling!
let group: Group = from_file(&filename)?; let group: Group = from_file(&filename)?;

View File

@ -3,6 +3,13 @@ use std::collections::HashMap;
use serde::Deserialize; use serde::Deserialize;
// Custom types that are NOT (de)serialized!
#[derive(PartialEq, Debug, Clone)]
pub struct MonsterWeaponInfo {
pub entity_id: u32,
pub gadget_id: u32,
}
// sceneX.lua // sceneX.lua
#[derive(Deserialize, PartialEq, Debug, Clone)] #[derive(Deserialize, PartialEq, Debug, Clone)]
@ -191,6 +198,12 @@ pub struct Monster {
pub config_id: u32, pub config_id: u32,
pub level: u32, pub level: u32,
pub monster_id: u32, pub monster_id: u32,
/*
This is an artificial field that is not serialized nor deserialized
*/
#[serde(skip)]
pub weapons_list: Vec<MonsterWeaponInfo>,
} }
#[derive(Deserialize, PartialEq, Debug, Clone)] #[derive(Deserialize, PartialEq, Debug, Clone)]

View File

@ -30,7 +30,7 @@ impl GameServer {
pub fn new(packets_to_process_rx: mpsc::Receiver<IpcMessage>, packets_to_send_tx: mpsc::Sender<IpcMessage>) -> GameServer { pub fn new(packets_to_process_rx: mpsc::Receiver<IpcMessage>, packets_to_send_tx: mpsc::Sender<IpcMessage>) -> GameServer {
let jm = Arc::new(JsonManager::new("./data/json")); let jm = Arc::new(JsonManager::new("./data/json"));
let db = Arc::new(DatabaseManager::new("sqlite://./database.db3", jm.clone())); let db = Arc::new(DatabaseManager::new("sqlite://./database.db3", jm.clone()));
let lum = Arc::new(LuaManager::new("./data/lua")); let lum = Arc::new(LuaManager::new("./data/lua", &jm.clone()));
let em = Arc::new(EntityManager::new(lum.clone(),jm.clone(), db.clone(), packets_to_send_tx.clone())); let em = Arc::new(EntityManager::new(lum.clone(),jm.clone(), db.clone(), packets_to_send_tx.clone()));
let lm = LoginManager::new(db.clone(), jm.clone(), em.clone(),packets_to_send_tx.clone()); let lm = LoginManager::new(db.clone(), jm.clone(), em.clone(),packets_to_send_tx.clone());