forked from NewEriduPubSec/JaneDoe-ZS
SceneUnitManager: create default scene units
This commit is contained in:
parent
d3cd213d27
commit
d196ef861a
14 changed files with 237248 additions and 166 deletions
236871
assets/FileCfg/MainCityObjectTemplateTb.json
Normal file
236871
assets/FileCfg/MainCityObjectTemplateTb.json
Normal file
File diff suppressed because it is too large
Load diff
28
nap_data/src/tables/main_city_object_template.rs
Normal file
28
nap_data/src/tables/main_city_object_template.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
template_id!(MainCityObject u32 tag_id);
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
pub struct MainCityObjectTemplate {
|
||||
#[serde(rename = "TagID")]
|
||||
pub tag_id: MainCityObjectID,
|
||||
#[serde(rename = "NPCID")]
|
||||
pub npc_id: u32,
|
||||
pub create_position: String,
|
||||
pub create_type: u32,
|
||||
#[serde(rename = "DefaultInteractIDs")]
|
||||
pub default_interact_ids: Vec<u32>,
|
||||
pub interact_name: String,
|
||||
pub interact_shape: u32,
|
||||
pub interact_scale: String,
|
||||
pub focus_interact_scale: f32,
|
||||
pub camera_story_key: String,
|
||||
}
|
||||
|
||||
impl MainCityObjectTemplate {
|
||||
pub fn get_section_name(&self) -> String {
|
||||
let section_name = self.create_position.split('_').next().unwrap();
|
||||
format!("SectionName_{section_name}")
|
||||
}
|
||||
}
|
|
@ -82,4 +82,5 @@ template_tables! {
|
|||
PostGirlConfigTemplate;
|
||||
TrainingQuestTemplate;
|
||||
WeaponTemplate;
|
||||
MainCityObjectTemplate;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ pub async fn on_get_tips_info(
|
|||
Ok(GetTipsInfoScRsp {
|
||||
retcode: Retcode::RetSucc.into(),
|
||||
tips_info: Some(TipsInfo::default()),
|
||||
ofolagfmcmo: req.ofolagfmcmo, // tips group type
|
||||
r#type: req.r#type, // tips group type
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ req_handlers! {
|
|||
world::StartTrialFightingMission;
|
||||
world::EndBattle;
|
||||
world::LeaveCurDungeon;
|
||||
world::InteractWithUnit;
|
||||
client_systems::ReportUiLayoutPlatform;
|
||||
client_systems::PlayerOperation;
|
||||
client_systems::UnlockNewbieGroup;
|
||||
|
|
|
@ -125,7 +125,7 @@ pub async fn on_beginner_battle_rebegin(
|
|||
pub async fn on_enter_section(
|
||||
_session: &NetSession,
|
||||
_player: &mut Player,
|
||||
_req: EnterSectionCsReq,
|
||||
req: EnterSectionCsReq,
|
||||
) -> NetResult<EnterSectionScRsp> {
|
||||
Ok(EnterSectionScRsp {
|
||||
retcode: Retcode::RetSucc.into(),
|
||||
|
@ -203,3 +203,15 @@ pub async fn on_leave_cur_dungeon(
|
|||
retcode: Retcode::RetSucc.into(),
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn on_interact_with_unit(
|
||||
_session: &NetSession,
|
||||
_player: &mut Player,
|
||||
req: InteractWithUnitCsReq,
|
||||
) -> NetResult<InteractWithUnitScRsp> {
|
||||
tracing::info!("interact: {req:?}");
|
||||
|
||||
Ok(InteractWithUnitScRsp {
|
||||
retcode: Retcode::RetSucc.into(),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,13 +2,19 @@ use data::tables::{AvatarBaseID, SectionConfigID};
|
|||
use proto::*;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::logic::{math::Vector3f, time::MainCityTime, ESceneType};
|
||||
use crate::logic::{
|
||||
math::Vector3f,
|
||||
scene::{SceneUnit, SceneUnitManager},
|
||||
time::MainCityTime,
|
||||
ESceneType,
|
||||
};
|
||||
|
||||
use super::NapGameMode;
|
||||
|
||||
pub struct FrontendGame {
|
||||
section_id: SectionConfigID,
|
||||
frontend_avatar_id: AvatarBaseID,
|
||||
scene_unit_mgr: SceneUnitManager,
|
||||
camera_x: u32,
|
||||
camera_y: u32,
|
||||
born_pos: String,
|
||||
|
@ -34,6 +40,7 @@ impl FrontendGame {
|
|||
let instance = Self {
|
||||
section_id,
|
||||
main_city_time,
|
||||
scene_unit_mgr: SceneUnitManager::new(section_id),
|
||||
frontend_avatar_id: avatar_id,
|
||||
camera_x: 0xFFFFFFFF,
|
||||
camera_y: 0xFFFFFFFF,
|
||||
|
@ -67,6 +74,12 @@ impl NapGameMode for FrontendGame {
|
|||
position: self.avatar_pos.to_vec(),
|
||||
rotation: self.avatar_rot.to_vec(),
|
||||
}),
|
||||
scene_unit_list: self
|
||||
.scene_unit_mgr
|
||||
.unit_vec
|
||||
.iter()
|
||||
.map(SceneUnit::protocol_info)
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
|
|
|
@ -22,3 +22,33 @@ impl Vector3f {
|
|||
self.x == 0.0 && self.y == 0.0 && self.z == 0.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct InteractScale {
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
pub z: f64,
|
||||
pub w: f64,
|
||||
pub r: f64,
|
||||
}
|
||||
|
||||
impl InteractScale {
|
||||
pub fn from_str(s: &str) -> Option<Self> {
|
||||
let scale = s
|
||||
.split(',')
|
||||
.map(|c| c.parse::<f64>().unwrap_or_default())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if scale.len() == 5 {
|
||||
Some(Self {
|
||||
x: scale[0],
|
||||
y: scale[1],
|
||||
z: scale[2],
|
||||
w: scale[3],
|
||||
r: scale[4],
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ pub mod math;
|
|||
pub mod player;
|
||||
pub mod procedure;
|
||||
pub mod role;
|
||||
pub mod scene;
|
||||
pub mod time;
|
||||
|
||||
pub use enums::*;
|
||||
|
|
28
nap_gameserver/src/logic/scene/interact.rs
Normal file
28
nap_gameserver/src/logic/scene/interact.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use proto::{InteractInfo, InteractTarget};
|
||||
|
||||
use crate::logic::math::InteractScale;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InteractComponent {
|
||||
pub interact_id: u32,
|
||||
pub participators: HashMap<u32, String>,
|
||||
pub scale: InteractScale,
|
||||
}
|
||||
|
||||
impl InteractComponent {
|
||||
pub fn to_client(&self) -> InteractInfo {
|
||||
InteractInfo {
|
||||
interact_id: self.interact_id as i32,
|
||||
participators: self.participators.clone(),
|
||||
interact_target_list: vec![InteractTarget::Npc.into()], // TODO
|
||||
scale_x: self.scale.x,
|
||||
scale_y: self.scale.y,
|
||||
scale_z: self.scale.z,
|
||||
scale_w: self.scale.w,
|
||||
scale_r: self.scale.r,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
7
nap_gameserver/src/logic/scene/mod.rs
Normal file
7
nap_gameserver/src/logic/scene/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
mod interact;
|
||||
mod unit;
|
||||
mod unit_mgr;
|
||||
|
||||
pub use interact::InteractComponent;
|
||||
pub use unit::SceneUnit;
|
||||
pub use unit_mgr::SceneUnitManager;
|
65
nap_gameserver/src/logic/scene/unit.rs
Normal file
65
nap_gameserver/src/logic/scene/unit.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use data::tables::MainCityObjectID;
|
||||
use proto::SceneUnitProtocolInfo;
|
||||
|
||||
use crate::logic::math::InteractScale;
|
||||
|
||||
use super::InteractComponent;
|
||||
|
||||
pub struct SceneUnit {
|
||||
pub tag: u32,
|
||||
pub interacts: HashMap<u32, InteractComponent>,
|
||||
}
|
||||
|
||||
impl SceneUnit {
|
||||
pub fn new(template_id: MainCityObjectID) -> Self {
|
||||
let template = template_id.template();
|
||||
|
||||
Self {
|
||||
tag: template.tag_id.value(),
|
||||
interacts: Self::create_default_interacts(
|
||||
&template.default_interact_ids,
|
||||
template.tag_id.value(),
|
||||
&template.interact_name,
|
||||
&template.interact_scale,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn protocol_info(&self) -> SceneUnitProtocolInfo {
|
||||
SceneUnitProtocolInfo {
|
||||
is_interactable: !self.interacts.is_empty(),
|
||||
tag: self.tag,
|
||||
interacts_info: self
|
||||
.interacts
|
||||
.iter()
|
||||
.map(|(id, comp)| (*id, comp.to_client()))
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn create_default_interacts(
|
||||
interact_ids: &[u32],
|
||||
tag: u32,
|
||||
name: &str,
|
||||
scale: &str,
|
||||
) -> HashMap<u32, InteractComponent> {
|
||||
let scale = InteractScale::from_str(scale).unwrap_or_default();
|
||||
|
||||
interact_ids
|
||||
.iter()
|
||||
.map(|id| {
|
||||
(
|
||||
*id,
|
||||
InteractComponent {
|
||||
participators: HashMap::from([(tag, name.to_string())]),
|
||||
interact_id: tag,
|
||||
scale: scale.clone(),
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
25
nap_gameserver/src/logic/scene/unit_mgr.rs
Normal file
25
nap_gameserver/src/logic/scene/unit_mgr.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use data::tables::{self, SectionConfigID};
|
||||
|
||||
use super::SceneUnit;
|
||||
|
||||
pub struct SceneUnitManager {
|
||||
pub unit_vec: Vec<SceneUnit>,
|
||||
}
|
||||
|
||||
impl SceneUnitManager {
|
||||
pub fn new(section_id: SectionConfigID) -> Self {
|
||||
let section_template = section_id.template();
|
||||
|
||||
let unit_vec = tables::main_city_object_template_tb::iter()
|
||||
.filter(|tmpl| tmpl.get_section_name() == section_template.section_name)
|
||||
.filter(|tmpl| {
|
||||
tmpl.create_type == 0
|
||||
&& !tmpl.create_position.contains("Test")
|
||||
&& !tmpl.default_interact_ids.is_empty()
|
||||
})
|
||||
.map(|tmpl| SceneUnit::new(tmpl.tag_id))
|
||||
.collect();
|
||||
|
||||
Self { unit_vec }
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue