mirror of
https://github.com/RustySamovar/RustySamovar.git
synced 2024-11-25 03:29:38 +00:00
Implement almost proper monster attribute scaling
This commit is contained in:
parent
3053cb987b
commit
616035373d
@ -1,6 +1,8 @@
|
|||||||
// Database Manager
|
// Database Manager
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::collection;
|
||||||
|
|
||||||
use sea_orm::{entity::*, error::*, query::*, DbConn, FromQueryResult, Database};
|
use sea_orm::{entity::*, error::*, query::*, DbConn, FromQueryResult, Database};
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
use crate::JsonManager;
|
use crate::JsonManager;
|
||||||
@ -59,19 +61,6 @@ use super::reliquary_prop::Entity as ReliquaryPropEntity;
|
|||||||
pub use super::furniture_info::Model as FurnitureInfo;
|
pub use super::furniture_info::Model as FurnitureInfo;
|
||||||
use super::furniture_info::Entity as FurnitureInfoEntity;
|
use super::furniture_info::Entity as FurnitureInfoEntity;
|
||||||
|
|
||||||
macro_rules! collection {
|
|
||||||
// map-like
|
|
||||||
($($k:expr => $v:expr),* $(,)?) => {{
|
|
||||||
use std::iter::{Iterator, IntoIterator};
|
|
||||||
Iterator::collect(IntoIterator::into_iter([$(($k, $v),)*]))
|
|
||||||
}};
|
|
||||||
// set-like
|
|
||||||
($($v:expr),* $(,)?) => {{
|
|
||||||
use std::iter::{Iterator, IntoIterator};
|
|
||||||
Iterator::collect(IntoIterator::into_iter([$($v,)*]))
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
trait Block {
|
trait Block {
|
||||||
fn wait(self) -> <Self as futures::Future>::Output
|
fn wait(self) -> <Self as futures::Future>::Output
|
||||||
where Self: Sized, Self: futures::Future
|
where Self: Sized, Self: futures::Future
|
||||||
@ -84,6 +73,7 @@ impl<F,T> Block for F
|
|||||||
where F: futures::Future<Output = T>
|
where F: futures::Future<Output = T>
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct DatabaseManager {
|
pub struct DatabaseManager {
|
||||||
db: DbConn,
|
db: DbConn,
|
||||||
}
|
}
|
||||||
@ -146,6 +136,17 @@ impl DatabaseManager {
|
|||||||
|
|
||||||
return Some(props);
|
return Some(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_player_prop(&self, uid: u32, prop_id: u32) -> Option<i64> {
|
||||||
|
match PlayerPropEntity::find().filter(
|
||||||
|
Condition::all()
|
||||||
|
.add(super::player_prop::Column::Uid.eq(uid))
|
||||||
|
.add(super::player_prop::Column::PropId.eq(prop_id))
|
||||||
|
).one(&self.db).wait() {
|
||||||
|
Ok(prop) => Some(prop?.prop_value), // Returns None if prop is none
|
||||||
|
Err(_) => panic!("DB ERROR!"),
|
||||||
|
}
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
pub fn _get_avatar_props(&self, guid: u64) -> Option<HashMap<u32, i64>> {
|
pub fn _get_avatar_props(&self, guid: u64) -> Option<HashMap<u32, i64>> {
|
||||||
let map = collection! {
|
let map = collection! {
|
||||||
|
16
src/jsonmanager/entity_curve.rs
Normal file
16
src/jsonmanager/entity_curve.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Clone)]
|
||||||
|
#[serde(rename_all="PascalCase")]
|
||||||
|
pub struct CurveInfo {
|
||||||
|
pub r#type: proto::GrowCurveType,
|
||||||
|
pub arith: proto::ArithType,
|
||||||
|
pub value: Option<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Clone)]
|
||||||
|
#[serde(rename_all="PascalCase")]
|
||||||
|
pub struct EntityCurve {
|
||||||
|
pub level: u32,
|
||||||
|
pub curve_infos: Vec<CurveInfo>
|
||||||
|
}
|
15
src/jsonmanager/gadget_prop.rs
Normal file
15
src/jsonmanager/gadget_prop.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Clone)]
|
||||||
|
#[serde(rename_all="PascalCase")]
|
||||||
|
pub struct GadgetProp {
|
||||||
|
pub id: u32,
|
||||||
|
pub hp: f32,
|
||||||
|
pub hp_curve: proto::GrowCurveType,
|
||||||
|
#[serde(default)]
|
||||||
|
pub attack: f32,
|
||||||
|
pub attack_curve: proto::GrowCurveType,
|
||||||
|
#[serde(default)]
|
||||||
|
pub defense: f32,
|
||||||
|
pub defense_curve: proto::GrowCurveType,
|
||||||
|
}
|
26
src/jsonmanager/gather.rs
Normal file
26
src/jsonmanager/gather.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Clone)]
|
||||||
|
#[serde(rename_all="PascalCase")]
|
||||||
|
pub struct BlockLimit {
|
||||||
|
pub block_id: u32,
|
||||||
|
pub count: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Clone)]
|
||||||
|
#[serde(rename_all="PascalCase")]
|
||||||
|
pub struct Gather {
|
||||||
|
pub id: u32,
|
||||||
|
pub area_id: Option<u32>,
|
||||||
|
pub point_type: u32, // TODO: probs an enum?
|
||||||
|
pub gadget_id: u32,
|
||||||
|
pub item_id: u32,
|
||||||
|
pub extra_item_id_vec: Vec<u32>,
|
||||||
|
pub cd: u32,
|
||||||
|
pub priority: u32,
|
||||||
|
pub refresh_id: Option<u32>,
|
||||||
|
pub block_limits: Vec<BlockLimit>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub init_disable_interact: bool,
|
||||||
|
pub save_type: Option<String>, // TODO: this is an enum!
|
||||||
|
}
|
@ -4,8 +4,13 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
use crate::jsonmanager::gather::Gather;
|
||||||
|
|
||||||
use super::avatar_skill_depot::AvatarSkillDepot;
|
use super::avatar_skill_depot::AvatarSkillDepot;
|
||||||
|
use super::entity_curve::EntityCurve;
|
||||||
|
use super::monster::Monster;
|
||||||
|
use super::world_level::WorldLevel;
|
||||||
|
use super::gadget_prop::GadgetProp;
|
||||||
|
|
||||||
struct JsonReader {
|
struct JsonReader {
|
||||||
base_path: String,
|
base_path: String,
|
||||||
@ -14,6 +19,18 @@ struct JsonReader {
|
|||||||
pub struct JsonManager {
|
pub struct JsonManager {
|
||||||
reader: JsonReader,
|
reader: JsonReader,
|
||||||
pub avatar_skill_depot: HashMap<u32,AvatarSkillDepot>,
|
pub avatar_skill_depot: HashMap<u32,AvatarSkillDepot>,
|
||||||
|
pub monster_curves: HashMap<u32,EntityCurve>,
|
||||||
|
pub monsters: HashMap<u32, Monster>,
|
||||||
|
pub world_levels: HashMap<u32, WorldLevel>,
|
||||||
|
pub gadget_props: HashMap<u32, GadgetProp>,
|
||||||
|
pub gadget_curves: HashMap<u32,EntityCurve>,
|
||||||
|
pub gathers: HashMap<u32, Gather>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for JsonManager { // TODO: fucking hack!
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "JsonManager is not debuggable!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JsonManager {
|
impl JsonManager {
|
||||||
@ -21,10 +38,22 @@ impl JsonManager {
|
|||||||
let reader = JsonReader::new(directory);
|
let reader = JsonReader::new(directory);
|
||||||
|
|
||||||
let asd: Vec<AvatarSkillDepot> = reader.read_json_list("AvatarSkillDepot");
|
let asd: Vec<AvatarSkillDepot> = reader.read_json_list("AvatarSkillDepot");
|
||||||
|
let mc: Vec<EntityCurve> = reader.read_json_list("MonsterCurve");
|
||||||
|
let monsters: Vec<Monster> = reader.read_json_list("Monster");
|
||||||
|
let world_levels: Vec<WorldLevel> = reader.read_json_list("WorldLevel");
|
||||||
|
let gadget_props: Vec<GadgetProp> = reader.read_json_list("GadgetProp");
|
||||||
|
let gc: Vec<EntityCurve> = reader.read_json_list("GadgetCurve");
|
||||||
|
let gathers: Vec<Gather> = reader.read_json_list("Gather");
|
||||||
|
|
||||||
return JsonManager {
|
return JsonManager {
|
||||||
reader: reader,
|
reader: reader,
|
||||||
avatar_skill_depot: asd.into_iter().map(|a| (a.id, a)).collect(),
|
avatar_skill_depot: asd.into_iter().map(|a| (a.id, a)).collect(),
|
||||||
|
monster_curves: mc.into_iter().map(|m| (m.level, m)).collect(),
|
||||||
|
monsters: monsters.into_iter().map(|m| (m.id, m)).collect(),
|
||||||
|
world_levels: world_levels.into_iter().map(|wl| (wl.level, wl)).collect(),
|
||||||
|
gadget_props: gadget_props.into_iter().map(|gp| (gp.id, gp)).collect(),
|
||||||
|
gadget_curves: gc.into_iter().map(|g| (g.level, g)).collect(),
|
||||||
|
gathers: gathers.into_iter().map(|g| (g.gadget_id, g)).collect(), // TODO: we index it by gadget_id and not by it's id!
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,7 +72,7 @@ impl JsonReader {
|
|||||||
|
|
||||||
let json_file_path = Path::new(&path);
|
let json_file_path = Path::new(&path);
|
||||||
let json_file_str = read_to_string(json_file_path).unwrap_or_else(|_| panic!("File {} not found", path));
|
let json_file_str = read_to_string(json_file_path).unwrap_or_else(|_| panic!("File {} not found", path));
|
||||||
let data: Vec<T> = serde_json::from_str(&json_file_str).expect("Error while reading json");
|
let data: Vec<T> = serde_json::from_str(&json_file_str).expect(&format!("Error while reading json {}", name));
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,3 +3,10 @@ mod json_manager;
|
|||||||
pub use self::json_manager::JsonManager;
|
pub use self::json_manager::JsonManager;
|
||||||
|
|
||||||
mod avatar_skill_depot;
|
mod avatar_skill_depot;
|
||||||
|
mod entity_curve;
|
||||||
|
mod monster;
|
||||||
|
mod world_level;
|
||||||
|
mod gadget_prop;
|
||||||
|
mod gather;
|
||||||
|
|
||||||
|
pub use entity_curve::{CurveInfo,EntityCurve};
|
92
src/jsonmanager/monster.rs
Normal file
92
src/jsonmanager/monster.rs
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
// TODO: those two structs have fields that are usually missing all together, so it makes sense to omit
|
||||||
|
// an entire record from the list in the generator.
|
||||||
|
// For the sake of being compatible with Dimbreath's data I've chosen this way for now - wrapping real data with Option<>
|
||||||
|
|
||||||
|
#[derive(Deserialize, Clone)]
|
||||||
|
#[serde(rename_all="PascalCase")]
|
||||||
|
pub struct HpDrop {
|
||||||
|
pub drop_id: u32,
|
||||||
|
pub hp_percent: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Clone)]
|
||||||
|
#[serde(rename_all="PascalCase")]
|
||||||
|
pub struct HpDropWrap {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub data: Option<HpDrop>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Clone)]
|
||||||
|
#[serde(rename_all="PascalCase")]
|
||||||
|
pub struct PropGrowCurve {
|
||||||
|
#[serde(default = "PropGrowCurve::default_type")]
|
||||||
|
pub r#type: proto::FightPropType,
|
||||||
|
#[serde(default = "PropGrowCurve::default_curve")]
|
||||||
|
pub grow_curve: proto::GrowCurveType,
|
||||||
|
}
|
||||||
|
// TODO: fucking hack!
|
||||||
|
impl PropGrowCurve {
|
||||||
|
fn default_type() -> proto::FightPropType { proto::FightPropType::FightPropNone }
|
||||||
|
fn default_curve() -> proto::GrowCurveType { proto::GrowCurveType::GrowCurveNone }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#[derive(Deserialize, Clone)]
|
||||||
|
#[serde(rename_all="PascalCase")]
|
||||||
|
pub struct PropGrowCurveWrap {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub data: Option<PropGrowCurve>,
|
||||||
|
}*/
|
||||||
|
|
||||||
|
#[derive(Deserialize, Clone)]
|
||||||
|
#[serde(rename_all="PascalCase")]
|
||||||
|
pub struct Monster {
|
||||||
|
pub id: u32,
|
||||||
|
#[serde(rename = "CampID")]
|
||||||
|
pub camp_id: u32,
|
||||||
|
|
||||||
|
pub monster_name: String,
|
||||||
|
pub r#type: String, // TODO: this is an enum!
|
||||||
|
pub server_script: String,
|
||||||
|
pub affix: Vec<u32>,
|
||||||
|
pub ai: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub is_ai_hash_check: bool,
|
||||||
|
pub equips: Vec<u32>,
|
||||||
|
pub hp_drops: Vec<HpDropWrap>,
|
||||||
|
pub kill_drop_id: Option<u32>,
|
||||||
|
pub exclude_weathers: String,
|
||||||
|
|
||||||
|
#[serde(rename = "FeatureTagGroupID")]
|
||||||
|
pub feature_tag_group_id: u32,
|
||||||
|
#[serde(rename = "MpPropID")]
|
||||||
|
pub mp_prop_id: u32,
|
||||||
|
|
||||||
|
pub hp_base: f32,
|
||||||
|
#[serde(default)] // Missing for Slimes that attack during the tutorial fight
|
||||||
|
pub attack_base: f32,
|
||||||
|
#[serde(default)] // Missing for Dvalin in the aerial fight
|
||||||
|
pub defense_base: f32,
|
||||||
|
|
||||||
|
#[serde(default)] // Missing for Dvalin in the aerial fight
|
||||||
|
pub fire_sub_hurt: f32,
|
||||||
|
#[serde(default)] // Missing for Dvalin in the aerial fight
|
||||||
|
pub grass_sub_hurt: f32,
|
||||||
|
#[serde(default)] // Missing for Dvalin in the aerial fight
|
||||||
|
pub water_sub_hurt: f32,
|
||||||
|
#[serde(default)] // Missing for Dvalin in the aerial fight
|
||||||
|
pub elec_sub_hurt: f32,
|
||||||
|
#[serde(default)] // Missing for Dvalin in the aerial fight
|
||||||
|
pub wind_sub_hurt: f32,
|
||||||
|
#[serde(default)] // Missing for Dvalin in the aerial fight
|
||||||
|
pub ice_sub_hurt: f32,
|
||||||
|
#[serde(default)] // Missing for Dvalin in the aerial fight
|
||||||
|
pub rock_sub_hurt: f32,
|
||||||
|
#[serde(default)] // Missing for Dvalin in the aerial fight
|
||||||
|
pub physical_sub_hurt: f32,
|
||||||
|
|
||||||
|
//pub prop_grow_curves: Vec<PropGrowCurveWrap>,
|
||||||
|
pub prop_grow_curves: Vec<PropGrowCurve>,
|
||||||
|
}
|
8
src/jsonmanager/world_level.rs
Normal file
8
src/jsonmanager/world_level.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Clone)]
|
||||||
|
#[serde(rename_all="PascalCase")]
|
||||||
|
pub struct WorldLevel {
|
||||||
|
pub level: u32,
|
||||||
|
pub monster_level: u32,
|
||||||
|
}
|
@ -2,11 +2,10 @@ use std::collections::HashMap;
|
|||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use lua_serde::from_file;
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
use packet_processor::*;
|
|
||||||
use crate::utils::IdManager;
|
use crate::utils::IdManager;
|
||||||
|
use crate::subsystems::entity_subsystem::{Entity, EntityTrait};
|
||||||
|
|
||||||
|
use lua_serde::from_file;
|
||||||
|
|
||||||
use super::scene_config;
|
use super::scene_config;
|
||||||
|
|
||||||
@ -43,22 +42,6 @@ pub struct InternalGroupData {
|
|||||||
// No extra data here
|
// No extra data here
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,Clone)]
|
|
||||||
pub enum EntityType {
|
|
||||||
Monster(Monster),
|
|
||||||
Npc(Npc),
|
|
||||||
Gadget(Gadget),
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug,Clone)]
|
|
||||||
pub struct Entity {
|
|
||||||
pub entity_id: u32,
|
|
||||||
pub group_id: u32,
|
|
||||||
pub block_id: u32,
|
|
||||||
pub entity: EntityType,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementation of utility functions
|
/// Implementation of utility functions
|
||||||
impl InternalSceneData {
|
impl InternalSceneData {
|
||||||
pub fn get_block_by_pos(&self, pos: &Vector) -> Result<&InternalBlockData, String> {
|
pub fn get_block_by_pos(&self, pos: &Vector) -> Result<&InternalBlockData, String> {
|
||||||
@ -80,89 +63,6 @@ impl InternalSceneData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity {
|
|
||||||
pub fn pos(&self) -> Vector {
|
|
||||||
match &self.entity {
|
|
||||||
EntityType::Monster(m) => m.pos.clone(),
|
|
||||||
EntityType::Npc(n) => n.pos.clone(),
|
|
||||||
EntityType::Gadget(g) => g.pos.clone(),
|
|
||||||
_ => panic!("Unsupported entity type!"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rot(&self) -> Vector {
|
|
||||||
match &self.entity {
|
|
||||||
EntityType::Monster(m) => m.rot.clone(),
|
|
||||||
EntityType::Npc(n) => n.rot.clone(),
|
|
||||||
EntityType::Gadget(g) => g.rot.clone(),
|
|
||||||
_ => panic!("Unsupported entity type!"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn speed(&self) -> Vector {
|
|
||||||
// TODO!
|
|
||||||
Vector { x: 0.0, y: 0.0, z: 0.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn etype(&self) -> i32 {
|
|
||||||
(match &self.entity {
|
|
||||||
EntityType::Monster(_) => proto::ProtEntityType::ProtEntityMonster,
|
|
||||||
EntityType::Npc(n) => proto::ProtEntityType::ProtEntityNpc,
|
|
||||||
EntityType::Gadget(g) => proto::ProtEntityType::ProtEntityGadget,
|
|
||||||
_ => panic!("Unsupported entity type!"),
|
|
||||||
}) as i32
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn convert(&self) -> proto::SceneEntityInfo {
|
|
||||||
let mut sei = build!(SceneEntityInfo {
|
|
||||||
entity_id: self.entity_id,
|
|
||||||
entity_type: self.etype(),
|
|
||||||
motion_info: Some(build!(MotionInfo {
|
|
||||||
pos: Some((&self.pos()).into()),
|
|
||||||
rot: Some((&self.rot()).into()),
|
|
||||||
speed: Some((&self.speed()).into()),
|
|
||||||
})),
|
|
||||||
animator_para_list: vec![],
|
|
||||||
entity_client_data: Some(build!(EntityClientData {})),
|
|
||||||
entity_authority_info: Some(build!(EntityAuthorityInfo {
|
|
||||||
renderer_changed_info: Some(build!(EntityRendererChangedInfo{})),
|
|
||||||
ai_info: Some(build!(SceneEntityAiInfo {
|
|
||||||
is_ai_open: true, // TODO!
|
|
||||||
born_pos: Some((&self.pos()).into()),
|
|
||||||
})),
|
|
||||||
born_pos: Some((&self.pos()).into()),
|
|
||||||
})),
|
|
||||||
});
|
|
||||||
|
|
||||||
sei.entity = Some(match &self.entity {
|
|
||||||
EntityType::Monster(m) => proto::scene_entity_info::Entity::Monster(build!(SceneMonsterInfo {
|
|
||||||
monster_id: m.monster_id,
|
|
||||||
group_id: self.group_id,
|
|
||||||
config_id: m.config_id,
|
|
||||||
authority_peer_id: 1, // TODO: hardcoded value!
|
|
||||||
born_type: proto::MonsterBornType::MonsterBornDefault as i32, // TODO: hardcoded value!
|
|
||||||
block_id: self.block_id,
|
|
||||||
// TODO: level scaling, weapons!
|
|
||||||
})),
|
|
||||||
EntityType::Npc(n) => proto::scene_entity_info::Entity::Npc(build!(SceneNpcInfo {
|
|
||||||
npc_id: n.npc_id,
|
|
||||||
block_id: self.block_id,
|
|
||||||
})),
|
|
||||||
EntityType::Gadget(g) => proto::scene_entity_info::Entity::Gadget(build!(SceneGadgetInfo {
|
|
||||||
gadget_id: g.gadget_id,
|
|
||||||
group_id: self.group_id,
|
|
||||||
config_id: g.config_id,
|
|
||||||
authority_peer_id: 1, // TODO: hardcoded value!
|
|
||||||
is_enable_interact: true,
|
|
||||||
// TODO: collectibles!
|
|
||||||
})),
|
|
||||||
_ => panic!("Unsupported entity type!"),
|
|
||||||
});
|
|
||||||
|
|
||||||
sei
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LuaManager {
|
pub struct LuaManager {
|
||||||
scenes_data: HashMap<u32,InternalSceneData>,
|
scenes_data: HashMap<u32,InternalSceneData>,
|
||||||
@ -254,7 +154,8 @@ impl LuaManager {
|
|||||||
entity_id: entity_id,
|
entity_id: entity_id,
|
||||||
group_id: *group_id,
|
group_id: *group_id,
|
||||||
block_id: block_id,
|
block_id: block_id,
|
||||||
entity: EntityType::Npc(npc.clone()), // TODO: very fucking inefficient!
|
health: 0,
|
||||||
|
entity: Arc::new(npc.clone()), // TODO: very fucking inefficient!
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +167,8 @@ impl LuaManager {
|
|||||||
entity_id: entity_id,
|
entity_id: entity_id,
|
||||||
group_id: *group_id,
|
group_id: *group_id,
|
||||||
block_id: block_id,
|
block_id: block_id,
|
||||||
entity: EntityType::Monster(monster.clone()), // TODO: very fucking inefficient!
|
health: 0,
|
||||||
|
entity: Arc::new(monster.clone()), // TODO: very fucking inefficient!
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +180,8 @@ impl LuaManager {
|
|||||||
entity_id: entity_id,
|
entity_id: entity_id,
|
||||||
group_id: *group_id,
|
group_id: *group_id,
|
||||||
block_id: block_id,
|
block_id: block_id,
|
||||||
entity: EntityType::Gadget(gadget.clone()), // TODO: very fucking inefficient!
|
health: 0,
|
||||||
|
entity: Arc::new(gadget.clone()), // TODO: very fucking inefficient!
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,4 @@ mod lua_manager;
|
|||||||
mod scene_config;
|
mod scene_config;
|
||||||
|
|
||||||
pub use self::lua_manager::LuaManager;
|
pub use self::lua_manager::LuaManager;
|
||||||
pub use self::scene_config::Vector;
|
pub use self::scene_config::{Vector, Monster, Gadget, Npc};
|
||||||
pub use self::lua_manager::Entity;
|
|
@ -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(lum.clone(), packets_to_send_tx.clone());
|
let em = EntitySubsystem::new(lum.clone(), jm.clone(), db.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,
|
||||||
|
400
src/subsystems/entity_subsystem/entities.rs
Normal file
400
src/subsystems/entity_subsystem/entities.rs
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
use actix_web::web::Json;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use rand::{self, Rng};
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
use packet_processor::*;
|
||||||
|
use crate::{DatabaseManager, JsonManager};
|
||||||
|
use crate::jsonmanager::{CurveInfo, EntityCurve};
|
||||||
|
|
||||||
|
use crate::collection;
|
||||||
|
|
||||||
|
use crate::luamanager::{Monster, Npc, Gadget, Vector};
|
||||||
|
use crate::utils::Remapper;
|
||||||
|
|
||||||
|
pub trait EntityTrait {
|
||||||
|
fn id(&self) -> String;
|
||||||
|
fn pos(&self) -> Vector;
|
||||||
|
fn rot(&self) -> Vector;
|
||||||
|
fn speed(&self) -> Vector;
|
||||||
|
fn etype(&self) -> proto::ProtEntityType;
|
||||||
|
fn info(&self, block_id: u32, group_id: u32, jm: &Arc<JsonManager>) -> proto::scene_entity_info::Entity;
|
||||||
|
fn props(&self, world_level: u32, jm: &Arc<JsonManager>, db: &Arc<DatabaseManager>) -> HashMap<u32, i64>;
|
||||||
|
fn fight_props(&self, world_level: u32, jm: &Arc<JsonManager>, db: &Arc<DatabaseManager>) -> HashMap<proto::FightPropType, f32>;
|
||||||
|
fn get_scaled_level(&self, world_level: u32, jm: &Arc<JsonManager>) -> u32;
|
||||||
|
|
||||||
|
fn curve_info_for_level<'a>(&self, list: &'a HashMap<u32, EntityCurve>, level: u32) -> HashMap<u32, &'a CurveInfo> {
|
||||||
|
list[&level].curve_infos.iter()
|
||||||
|
.map(|c| (c.r#type.clone() as u32, c))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_scaled_props(&self, world_level: u32, jm: &Arc<JsonManager>, list: &HashMap<u32, EntityCurve>,
|
||||||
|
scaling_helper: &HashMap<proto::FightPropType, (proto::FightPropType, f32)>,
|
||||||
|
grow_curves: &HashMap<proto::FightPropType, proto::GrowCurveType>) -> HashMap<proto::FightPropType,f32> {
|
||||||
|
let level = self.get_scaled_level(world_level, jm);
|
||||||
|
|
||||||
|
let curve_info = EntityTrait::curve_info_for_level(self, list, level);
|
||||||
|
|
||||||
|
let mut props = HashMap::new();
|
||||||
|
|
||||||
|
for (k, v) in scaling_helper.iter() {
|
||||||
|
let gct = match grow_curves.get(&v.0) {
|
||||||
|
Some(gct) => gct.clone() as u32,
|
||||||
|
None => {
|
||||||
|
println!("No curve {:?} for entity {}!", v.0, self.id());
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let curve = match curve_info.get(&gct) {
|
||||||
|
Some(curve) => curve,
|
||||||
|
None => panic!("Unknown curve {:?} for level {}", gct, level),
|
||||||
|
};
|
||||||
|
|
||||||
|
let scaled_value = match curve.arith {
|
||||||
|
proto::ArithType::ArithMulti => {
|
||||||
|
curve.value.unwrap() * v.1
|
||||||
|
},
|
||||||
|
proto::ArithType::ArithAdd => {
|
||||||
|
println!("Don't know how to use ArithAdd!");
|
||||||
|
v.1
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("Unknown arith type {:?} for curve {:?} (level {})", curve.arith, curve.r#type.clone() as u32, level);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
props.insert(*k, scaled_value);
|
||||||
|
props.insert(v.0, scaled_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for EntityTrait+Sync+Send { // TODO: fucking hack!
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "{{ \npos: {:?},\n rot: {:?},\n speed: {:?}, \netype: {:?},\n}}",
|
||||||
|
self.pos(), self.rot(), self.speed(), self.etype()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug,Clone)]
|
||||||
|
pub struct Entity {
|
||||||
|
pub entity_id: u32,
|
||||||
|
pub group_id: u32,
|
||||||
|
pub block_id: u32,
|
||||||
|
pub health: u32,
|
||||||
|
pub entity: Arc<EntityTrait + Sync + Send>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityTrait for Monster {
|
||||||
|
fn id(&self) -> String {
|
||||||
|
format!("Monster {}", self.monster_id)
|
||||||
|
}
|
||||||
|
fn pos(&self) -> Vector {
|
||||||
|
self.pos.clone()
|
||||||
|
}
|
||||||
|
fn rot(&self) -> Vector {
|
||||||
|
self.rot.clone()
|
||||||
|
}
|
||||||
|
fn speed(&self) -> Vector { // TODO!
|
||||||
|
Vector {x:0.0, y:0.0, z:0.0}
|
||||||
|
}
|
||||||
|
fn etype(&self) -> proto::ProtEntityType {
|
||||||
|
proto::ProtEntityType::ProtEntityMonster
|
||||||
|
}
|
||||||
|
fn info(&self, block_id: u32, group_id: u32, jm: &Arc<JsonManager>) -> proto::scene_entity_info::Entity {
|
||||||
|
let monster_info = &jm.monsters.get(&self.monster_id);
|
||||||
|
|
||||||
|
let affixes = match monster_info {
|
||||||
|
Some(mi) => mi.affix.clone(),
|
||||||
|
None => {
|
||||||
|
println!("No monster info found for monster {}! No affix.", self.monster_id);
|
||||||
|
vec![]
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
proto::scene_entity_info::Entity::Monster(build!(SceneMonsterInfo {
|
||||||
|
monster_id: self.monster_id,
|
||||||
|
group_id: group_id,
|
||||||
|
config_id: self.config_id,
|
||||||
|
authority_peer_id: 1, // TODO: hardcoded value!
|
||||||
|
born_type: proto::MonsterBornType::MonsterBornDefault as i32, // TODO: hardcoded value!
|
||||||
|
block_id: block_id,
|
||||||
|
affix_list: affixes,
|
||||||
|
// TODO: special_name!
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
fn props(&self, world_level: u32, jm: &Arc<JsonManager>, db: &Arc<DatabaseManager>) -> HashMap<u32, i64> {
|
||||||
|
let level = self.get_scaled_level(world_level, jm) as i64;
|
||||||
|
|
||||||
|
collection!{
|
||||||
|
proto::PropType::PropLevel as u32 => level,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn fight_props(&self, world_level: u32, jm: &Arc<JsonManager>, db: &Arc<DatabaseManager>) -> HashMap<proto::FightPropType,f32> {
|
||||||
|
let mut props = HashMap::new();
|
||||||
|
|
||||||
|
let monster_info = &jm.monsters.get(&self.monster_id);
|
||||||
|
|
||||||
|
match monster_info {
|
||||||
|
Some(mi) => {
|
||||||
|
// Non-scaled props
|
||||||
|
|
||||||
|
let non_scaled_props: HashMap<proto::FightPropType,f32> = collection!{
|
||||||
|
proto::FightPropType::FightPropPhysicalSubHurt => mi.physical_sub_hurt,
|
||||||
|
proto::FightPropType::FightPropFireSubHurt => mi.fire_sub_hurt,
|
||||||
|
proto::FightPropType::FightPropElecSubHurt => mi.elec_sub_hurt,
|
||||||
|
proto::FightPropType::FightPropWaterSubHurt => mi.water_sub_hurt,
|
||||||
|
proto::FightPropType::FightPropGrassSubHurt => mi.grass_sub_hurt,
|
||||||
|
proto::FightPropType::FightPropWindSubHurt => mi.wind_sub_hurt,
|
||||||
|
proto::FightPropType::FightPropRockSubHurt => mi.rock_sub_hurt,
|
||||||
|
proto::FightPropType::FightPropIceSubHurt => mi.ice_sub_hurt,
|
||||||
|
};
|
||||||
|
|
||||||
|
props.extend(non_scaled_props);
|
||||||
|
|
||||||
|
// Scaled props
|
||||||
|
|
||||||
|
// Transform monster's dict into usable format
|
||||||
|
let grow_curves: HashMap<proto::FightPropType, proto::GrowCurveType> = mi.prop_grow_curves.iter()
|
||||||
|
//.filter_map(|g| g.data.as_ref())
|
||||||
|
.map(|g| (g.r#type, g.grow_curve.clone()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let scaling_helper: HashMap<proto::FightPropType, (proto::FightPropType, f32)> = collection!{
|
||||||
|
proto::FightPropType::FightPropCurAttack => (
|
||||||
|
proto::FightPropType::FightPropBaseAttack,
|
||||||
|
mi.attack_base,
|
||||||
|
),
|
||||||
|
proto::FightPropType::FightPropCurDefense => (
|
||||||
|
proto::FightPropType::FightPropBaseDefense,
|
||||||
|
mi.defense_base,
|
||||||
|
),
|
||||||
|
proto::FightPropType::FightPropMaxHp => (
|
||||||
|
proto::FightPropType::FightPropBaseHp,
|
||||||
|
mi.hp_base,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
props.extend(
|
||||||
|
self.get_scaled_props(world_level, jm, &jm.monster_curves, &scaling_helper, &grow_curves)
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: hack! Properly calculate HP!
|
||||||
|
match props.get(&proto::FightPropType::FightPropMaxHp) {
|
||||||
|
Some(value) => {
|
||||||
|
props.insert(proto::FightPropType::FightPropCurHp, value * 0.7);
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
println!("Monster {} has no HP!", self.monster_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None=> {
|
||||||
|
println!("No monster info found for monster {}! No fight props.", self.monster_id);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_scaled_level(&self, world_level: u32, jm: &Arc<JsonManager>) -> u32 {
|
||||||
|
let base_level = jm.world_levels[&1].monster_level;
|
||||||
|
|
||||||
|
let max_level = jm.world_levels[&world_level].monster_level;
|
||||||
|
|
||||||
|
let level = max_level - base_level + self.level;
|
||||||
|
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityTrait for Npc {
|
||||||
|
fn id(&self) -> String {
|
||||||
|
format!("Npc {}", self.npc_id)
|
||||||
|
}
|
||||||
|
fn pos(&self) -> Vector {
|
||||||
|
self.pos.clone()
|
||||||
|
}
|
||||||
|
fn rot(&self) -> Vector {
|
||||||
|
self.rot.clone()
|
||||||
|
}
|
||||||
|
fn speed(&self) -> Vector { // TODO!
|
||||||
|
Vector {x:0.0, y:0.0, z:0.0}
|
||||||
|
}
|
||||||
|
fn etype(&self) -> proto::ProtEntityType {
|
||||||
|
proto::ProtEntityType::ProtEntityNpc
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
npc_id: self.npc_id,
|
||||||
|
block_id: block_id,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
fn props(&self, world_level: u32, jm: &Arc<JsonManager>, db: &Arc<DatabaseManager>) -> HashMap<u32, i64> {
|
||||||
|
HashMap::new() // TODO
|
||||||
|
}
|
||||||
|
fn fight_props(&self, world_level: u32, jm: &Arc<JsonManager>, db: &Arc<DatabaseManager>) -> HashMap<proto::FightPropType,f32> {
|
||||||
|
HashMap::new() // TODO
|
||||||
|
}
|
||||||
|
fn get_scaled_level(&self, world_level: u32, jm: &Arc<JsonManager>) -> u32 {
|
||||||
|
/*let base_level = jm.world_levels[&1].monster_level;
|
||||||
|
|
||||||
|
let max_level = jm.world_levels[&world_level].monster_level;
|
||||||
|
|
||||||
|
let level = max_level - base_level + self.level;
|
||||||
|
|
||||||
|
return level;*/
|
||||||
|
return 1; // TODO!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityTrait for Gadget {
|
||||||
|
fn id(&self) -> String {
|
||||||
|
format!("Gadget {}", self.gadget_id)
|
||||||
|
}
|
||||||
|
fn pos(&self) -> Vector {
|
||||||
|
self.pos.clone()
|
||||||
|
}
|
||||||
|
fn rot(&self) -> Vector {
|
||||||
|
self.rot.clone()
|
||||||
|
}
|
||||||
|
fn speed(&self) -> Vector { // TODO!
|
||||||
|
Vector {x:0.0, y:0.0, z:0.0}
|
||||||
|
}
|
||||||
|
fn etype(&self) -> proto::ProtEntityType {
|
||||||
|
proto::ProtEntityType::ProtEntityGadget
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
gadget_id: self.gadget_id,
|
||||||
|
group_id: group_id,
|
||||||
|
config_id: self.config_id,
|
||||||
|
authority_peer_id: 1, // TODO: hardcoded value!
|
||||||
|
is_enable_interact: true,
|
||||||
|
content: self.get_content(jm),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
fn props(&self, world_level: u32, jm: &Arc<JsonManager>, db: &Arc<DatabaseManager>) -> HashMap<u32, i64> {
|
||||||
|
HashMap::new() // TODO
|
||||||
|
}
|
||||||
|
fn fight_props(&self, world_level: u32, jm: &Arc<JsonManager>, db: &Arc<DatabaseManager>) -> HashMap<proto::FightPropType,f32> {
|
||||||
|
let mut props = HashMap::new();
|
||||||
|
|
||||||
|
let gadget_props = jm.gadget_props.get(&self.gadget_id);
|
||||||
|
|
||||||
|
match gadget_props {
|
||||||
|
Some(gp) => {
|
||||||
|
// Scaled props
|
||||||
|
|
||||||
|
// Transform monster's dict into usable format
|
||||||
|
let grow_curves: HashMap<proto::FightPropType, proto::GrowCurveType> = collection!{
|
||||||
|
proto::FightPropType::FightPropBaseHp => gp.hp_curve.clone(),
|
||||||
|
proto::FightPropType::FightPropBaseAttack => gp.attack_curve.clone(),
|
||||||
|
proto::FightPropType::FightPropBaseDefense => gp.defense_curve.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let scaling_helper: HashMap<proto::FightPropType, (proto::FightPropType, f32)> = collection!{
|
||||||
|
proto::FightPropType::FightPropCurAttack => (
|
||||||
|
proto::FightPropType::FightPropBaseAttack,
|
||||||
|
gp.attack,
|
||||||
|
),
|
||||||
|
proto::FightPropType::FightPropCurDefense => (
|
||||||
|
proto::FightPropType::FightPropBaseDefense,
|
||||||
|
gp.defense,
|
||||||
|
),
|
||||||
|
proto::FightPropType::FightPropMaxHp => (
|
||||||
|
proto::FightPropType::FightPropBaseHp,
|
||||||
|
gp.hp,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
props.extend(
|
||||||
|
self.get_scaled_props(world_level, jm, &jm.gadget_curves, &scaling_helper, &grow_curves)
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: hack! Properly calculate HP!
|
||||||
|
match props.get(&proto::FightPropType::FightPropMaxHp) {
|
||||||
|
Some(value) => {
|
||||||
|
props.insert(proto::FightPropType::FightPropCurHp, value * 0.7);
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
println!("Gadget {} has no HP!", self.gadget_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None=> {
|
||||||
|
println!("No gadget info found for gadget {}! No fight props.", self.gadget_id);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
fn get_scaled_level(&self, world_level: u32, jm: &Arc<JsonManager>) -> u32 {
|
||||||
|
/*let base_level = jm.world_levels[&1].monster_level;
|
||||||
|
|
||||||
|
let max_level = jm.world_levels[&world_level].monster_level;
|
||||||
|
|
||||||
|
let level = max_level - base_level + self.level;
|
||||||
|
|
||||||
|
return level;*/
|
||||||
|
return 1; // TODO!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Entity {
|
||||||
|
pub fn pos(&self) -> Vector {
|
||||||
|
self.entity.pos()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn convert(&self, world_level: u32, jm: &Arc<JsonManager>, db: &Arc<DatabaseManager>) -> proto::SceneEntityInfo {
|
||||||
|
let mut sei = build!(SceneEntityInfo {
|
||||||
|
entity_id: self.entity_id,
|
||||||
|
entity_type: self.entity.etype() as i32,
|
||||||
|
motion_info: Some(build!(MotionInfo {
|
||||||
|
pos: Some((&self.entity.pos()).into()),
|
||||||
|
rot: Some((&self.entity.rot()).into()),
|
||||||
|
speed: Some((&self.entity.speed()).into()),
|
||||||
|
})),
|
||||||
|
prop_list: Remapper::remap2(&self.entity.props(world_level, jm, db)),
|
||||||
|
fight_prop_list: Remapper::remap4(&self.entity.fight_props(world_level, jm, db)),
|
||||||
|
animator_para_list: vec![],
|
||||||
|
entity_client_data: Some(build!(EntityClientData {})),
|
||||||
|
entity_authority_info: Some(build!(EntityAuthorityInfo {
|
||||||
|
renderer_changed_info: Some(build!(EntityRendererChangedInfo{})),
|
||||||
|
ai_info: Some(build!(SceneEntityAiInfo {
|
||||||
|
is_ai_open: true, // TODO!
|
||||||
|
born_pos: Some((&self.entity.pos()).into()),
|
||||||
|
})),
|
||||||
|
born_pos: Some((&self.entity.pos()).into()),
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
|
||||||
|
sei.entity = Some(self.entity.info(self.block_id, self.group_id, &jm));
|
||||||
|
|
||||||
|
sei
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Gadget {
|
||||||
|
fn get_content(&self, jm: &Arc<JsonManager>) -> Option<proto::scene_gadget_info::Content> {
|
||||||
|
match jm.gathers.get(&self.gadget_id) { // TODO: worktop and other options are missing!
|
||||||
|
Some(gather) => {
|
||||||
|
println!("GATHERABLE {} FOUND FOR GADGET {}!", gather.item_id, self.gadget_id);
|
||||||
|
Some(proto::scene_gadget_info::Content::GatherGadget(build!(GatherGadgetInfo {
|
||||||
|
item_id: gather.item_id,
|
||||||
|
})))
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
println!("NO CONTENT FOUND FOR GADGET {}!", self.gadget_id);
|
||||||
|
None
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,11 +14,11 @@ use packet_processor_macro::*;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
use packet_processor::*;
|
use packet_processor::*;
|
||||||
use serde_json::de::Read;
|
use serde_json::de::Read;
|
||||||
use crate::LuaManager;
|
use crate::{DatabaseManager, JsonManager, LuaManager};
|
||||||
use crate::utils::{IdManager, TimeManager};
|
use crate::utils::{IdManager, TimeManager};
|
||||||
|
|
||||||
use crate::luamanager::Vector;
|
use crate::luamanager::Vector;
|
||||||
use crate::luamanager::Entity;
|
use super::entities::Entity;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Player {
|
struct Player {
|
||||||
@ -28,6 +28,8 @@ struct Player {
|
|||||||
current_block: u32,
|
current_block: u32,
|
||||||
entities: HashMap<u32, Arc<Entity>>,
|
entities: HashMap<u32, Arc<Entity>>,
|
||||||
lua_manager: Arc<LuaManager>,
|
lua_manager: Arc<LuaManager>,
|
||||||
|
json_manager: Arc<JsonManager>,
|
||||||
|
db_manager: Arc<DatabaseManager>,
|
||||||
packets_to_send_tx: Sender<IpcMessage>,
|
packets_to_send_tx: Sender<IpcMessage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,9 +104,10 @@ impl Player {
|
|||||||
sent_ms: TimeManager::timestamp(),
|
sent_ms: TimeManager::timestamp(),
|
||||||
client_sequence_id: 0,
|
client_sequence_id: 0,
|
||||||
});
|
});
|
||||||
|
let world_level = self.db_manager.get_player_prop(self.player_id, proto::PropType::PropPlayerWorldLevel as u32).unwrap() as u32; // TODO: hardcoded value!
|
||||||
|
|
||||||
build_and_send!(self, player_id, metadata, SceneEntityAppearNotify {
|
build_and_send!(self, player_id, metadata, SceneEntityAppearNotify {
|
||||||
entity_list: spawn_list.iter().map(|e| e.convert()).collect(),
|
entity_list: spawn_list.iter().map(|e| e.convert(world_level, &self.json_manager, &self.db_manager)).collect(),
|
||||||
appear_type: proto::VisionType::VisionBorn as i32,
|
appear_type: proto::VisionType::VisionBorn as i32,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -125,10 +128,12 @@ pub struct EntitySubsystem {
|
|||||||
players: Arc<Mutex<HashMap<u32, Player>>>,
|
players: Arc<Mutex<HashMap<u32, Player>>>,
|
||||||
players_moved: Sender<u32>,
|
players_moved: Sender<u32>,
|
||||||
lua_manager: Arc<LuaManager>,
|
lua_manager: Arc<LuaManager>,
|
||||||
|
json_manager: Arc<JsonManager>,
|
||||||
|
db_manager: Arc<DatabaseManager>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EntitySubsystem {
|
impl EntitySubsystem {
|
||||||
pub fn new(lua_manager: Arc<LuaManager>, packets_to_send_tx: Sender<IpcMessage>) -> EntitySubsystem {
|
pub fn new(lua_manager: Arc<LuaManager>, json_manager: Arc<JsonManager>, db_manager: Arc<DatabaseManager>, 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 {
|
||||||
@ -137,6 +142,8 @@ impl EntitySubsystem {
|
|||||||
players_moved: tx,
|
players_moved: tx,
|
||||||
players: Arc::new(Mutex::new(HashMap::new())),
|
players: Arc::new(Mutex::new(HashMap::new())),
|
||||||
lua_manager: lua_manager,
|
lua_manager: lua_manager,
|
||||||
|
json_manager: json_manager,
|
||||||
|
db_manager: db_manager,
|
||||||
};
|
};
|
||||||
|
|
||||||
es.register();
|
es.register();
|
||||||
@ -244,6 +251,8 @@ impl EntitySubsystem {
|
|||||||
current_scene: 3,
|
current_scene: 3,
|
||||||
entities: HashMap::new(),
|
entities: HashMap::new(),
|
||||||
lua_manager: self.lua_manager.clone(),
|
lua_manager: self.lua_manager.clone(),
|
||||||
|
json_manager: self.json_manager.clone(),
|
||||||
|
db_manager: self.db_manager.clone(),
|
||||||
packets_to_send_tx: self.packets_to_send_tx.clone(),
|
packets_to_send_tx: self.packets_to_send_tx.clone(),
|
||||||
};
|
};
|
||||||
|
|
5
src/subsystems/entity_subsystem/mod.rs
Normal file
5
src/subsystems/entity_subsystem/mod.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
mod entity_subsystem;
|
||||||
|
mod entities;
|
||||||
|
|
||||||
|
pub use self::entity_subsystem::EntitySubsystem;
|
||||||
|
pub use self::entities::{Entity, EntityTrait};
|
@ -1,3 +1,3 @@
|
|||||||
mod entity_subsystem;
|
pub mod entity_subsystem;
|
||||||
|
|
||||||
pub use self::entity_subsystem::EntitySubsystem;
|
pub use self::entity_subsystem::EntitySubsystem;
|
@ -3,6 +3,8 @@ mod data_packet;
|
|||||||
mod id_manager;
|
mod id_manager;
|
||||||
mod time_manager;
|
mod time_manager;
|
||||||
mod avatar_builder;
|
mod avatar_builder;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
mod remapper;
|
mod remapper;
|
||||||
|
|
||||||
pub use self::handshake_packet::HandshakePacket;
|
pub use self::handshake_packet::HandshakePacket;
|
||||||
|
@ -1,5 +1,19 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! collection {
|
||||||
|
// map-like
|
||||||
|
($($k:expr => $v:expr),* $(,)?) => {{
|
||||||
|
use std::iter::{Iterator, IntoIterator};
|
||||||
|
Iterator::collect(IntoIterator::into_iter([$(($k, $v),)*]))
|
||||||
|
}};
|
||||||
|
// set-like
|
||||||
|
($($v:expr),* $(,)?) => {{
|
||||||
|
use std::iter::{Iterator, IntoIterator};
|
||||||
|
Iterator::collect(IntoIterator::into_iter([$($v,)*]))
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Remapper {}
|
pub struct Remapper {}
|
||||||
|
|
||||||
impl Remapper {
|
impl Remapper {
|
||||||
@ -46,4 +60,17 @@ impl Remapper {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remap4(map: &HashMap<proto::FightPropType, f32>) -> Vec<proto::FightPropPair> {
|
||||||
|
let mut ret = vec![];
|
||||||
|
|
||||||
|
for (key, value) in map {
|
||||||
|
let mut pair = proto::FightPropPair::default();
|
||||||
|
pair.prop_type = *key as u32;
|
||||||
|
pair.prop_value = *value;
|
||||||
|
ret.push(pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user