Merge branch 'master' of https://git.xeondev.com/ObolSquad/trigger-rs
This commit is contained in:
commit
94af165a63
20 changed files with 716 additions and 24 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3751,6 +3751,7 @@ version = "0.0.1"
|
|||
dependencies = [
|
||||
"num_enum",
|
||||
"prost",
|
||||
"trigger-fileconfig",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
pub const MALE_AVATAR_ID: u32 = 2011;
|
||||
pub const FEMALE_AVATAR_ID: u32 = 2021;
|
||||
|
||||
pub fn is_player_avatar(id: u32) -> bool {
|
||||
id == MALE_AVATAR_ID || id == FEMALE_AVATAR_ID
|
||||
}
|
||||
|
||||
pub fn is_valid_talent_switch(v: &[bool]) -> bool {
|
||||
v.len() == 6
|
||||
&& v[0..3]
|
||||
|
|
|
@ -4,6 +4,7 @@ pub mod dungeon_util;
|
|||
pub mod equip_util;
|
||||
pub mod gm_util;
|
||||
mod player;
|
||||
pub mod scene;
|
||||
pub mod scene_util;
|
||||
|
||||
pub use player::NapPlayer;
|
||||
|
|
|
@ -8,7 +8,7 @@ use role::RoleModel;
|
|||
use scene::SceneModel;
|
||||
use trigger_database::{entity::*, prelude::*, DatabaseConnection};
|
||||
use trigger_fileconfig::NapFileCfg;
|
||||
use trigger_logic::scene::ESceneType;
|
||||
use trigger_logic::{scene::ESceneType, template_ext::TemplateExt};
|
||||
use trigger_protocol::PlayerInfo;
|
||||
use trigger_sv::message::GameStateData;
|
||||
use yorozuya::YorozuyaModel;
|
||||
|
@ -62,11 +62,8 @@ impl NapPlayer {
|
|||
player_uid,
|
||||
};
|
||||
|
||||
let Some((player_basic_info, is_new_player)) =
|
||||
player_util::load_player_basic_info(database, player_uid, create_if_not_exists).await
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
let (player_basic_info, is_new_player) =
|
||||
player_util::load_player_basic_info(database, player_uid, create_if_not_exists).await?;
|
||||
|
||||
let role_model = RoleModel::init(context.clone()).await;
|
||||
let item_model = ItemModel::init(context.clone()).await;
|
||||
|
@ -95,6 +92,28 @@ impl NapPlayer {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn beginner_procedure_id(&self) -> Option<i32> {
|
||||
(self.player_basic_info.beginner_procedure_id != -1)
|
||||
.then_some(self.player_basic_info.beginner_procedure_id)
|
||||
}
|
||||
|
||||
pub async fn advance_beginner_procedure(&mut self, id: i32) {
|
||||
let active_model = player_basic_info::ActiveModel {
|
||||
beginner_procedure_id: Set(self
|
||||
.context
|
||||
.filecfg
|
||||
.is_last_procedure(id)
|
||||
.then_some(-1)
|
||||
.unwrap_or(id)),
|
||||
..self.player_basic_info.clone().into()
|
||||
};
|
||||
|
||||
self.player_basic_info = active_model
|
||||
.update(self.context.database)
|
||||
.await
|
||||
.expect("player_basic_info::update failed");
|
||||
}
|
||||
|
||||
pub fn build_state_reentrant_data(&self, scene: &scene_info::Model) -> Option<GameStateData> {
|
||||
match ESceneType::try_from(scene.scene_type).unwrap() {
|
||||
ESceneType::Hall => Some(GameStateData::Hall {
|
||||
|
@ -106,6 +125,31 @@ impl NapPlayer {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn select_role(&mut self, avatar_id: u32) {
|
||||
let mut active_model: player_basic_info::ActiveModel =
|
||||
self.player_basic_info.clone().into();
|
||||
|
||||
active_model.set(
|
||||
player_basic_info::Column::AvatarId,
|
||||
(avatar_id as i32).into(),
|
||||
);
|
||||
|
||||
active_model.set(
|
||||
player_basic_info::Column::PlayerAvatarId,
|
||||
(avatar_id as i32).into(),
|
||||
);
|
||||
|
||||
active_model.set(
|
||||
player_basic_info::Column::ControlAvatarId,
|
||||
(avatar_id as i32).into(),
|
||||
);
|
||||
|
||||
self.player_basic_info = active_model
|
||||
.update(self.context.database)
|
||||
.await
|
||||
.expect("player_basic_info::update failed");
|
||||
}
|
||||
|
||||
pub async fn set_control_avatars(&mut self, player_avatar_id: u32, control_avatar_id: u32) {
|
||||
let mut active_model: player_basic_info::ActiveModel =
|
||||
self.player_basic_info.clone().into();
|
||||
|
|
|
@ -32,9 +32,10 @@ fn create_default_player_basic_info(player_uid: i32) -> player_basic_info::Activ
|
|||
nick_name: String::from("ReversedRooms"),
|
||||
level: 60,
|
||||
exp: 0,
|
||||
avatar_id: 2021,
|
||||
player_avatar_id: 2021,
|
||||
control_avatar_id: 1361,
|
||||
avatar_id: 0,
|
||||
player_avatar_id: 0,
|
||||
control_avatar_id: 0,
|
||||
beginner_procedure_id: 0,
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
|
22
crates/game-server/src/logic/scene/mod.rs
Normal file
22
crates/game-server/src/logic/scene/mod.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
use trigger_logic::scene::ESceneType;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ServerlessStateData {
|
||||
FreshScene { procedure_id: i32 },
|
||||
}
|
||||
|
||||
impl ServerlessStateData {
|
||||
pub fn protocol_scene_data(&self) -> trigger_protocol::SceneData {
|
||||
use trigger_protocol::*;
|
||||
|
||||
match self {
|
||||
Self::FreshScene { procedure_id } => SceneData {
|
||||
scene_type: ESceneType::Fresh.into(),
|
||||
fresh_scene_info: Some(FreshSceneInfo {
|
||||
last_procedure_id: *procedure_id as u32,
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,10 +4,9 @@ use trigger_codegen::handlers;
|
|||
#[handlers]
|
||||
mod player_module {
|
||||
use tracing::debug;
|
||||
use trigger_logic::template_ext::TemplateExt;
|
||||
use trigger_sv::{net::ServerType, time_util};
|
||||
|
||||
use crate::logic::avatar_util;
|
||||
|
||||
pub async fn on_get_player_info(
|
||||
context: &mut MessageContext<'_, '_>,
|
||||
_request: GetPlayerInfoCsReq,
|
||||
|
@ -39,6 +38,34 @@ mod player_module {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn on_select_role(
|
||||
context: &mut MessageContext<'_, '_>,
|
||||
request: SelectRoleCsReq,
|
||||
) -> SelectRoleScRsp {
|
||||
if let Some(procedure_id) = context.player.beginner_procedure_id() {
|
||||
if context
|
||||
.state
|
||||
.filecfg
|
||||
.procedure_allows_select_role(procedure_id + 1)
|
||||
&& context
|
||||
.state
|
||||
.filecfg
|
||||
.is_player_avatar(request.avatar_id as i32)
|
||||
{
|
||||
context.player.select_role(request.avatar_id).await;
|
||||
|
||||
context.add_notify(PlayerSyncScNotify {
|
||||
player_info: Some(context.player.get_protocol_player_info()),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
return SelectRoleScRsp { retcode: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
SelectRoleScRsp { retcode: 1 }
|
||||
}
|
||||
|
||||
pub async fn on_get_authkey(
|
||||
context: &mut MessageContext<'_, '_>,
|
||||
request: GetAuthkeyCsReq,
|
||||
|
@ -69,8 +96,14 @@ mod player_module {
|
|||
context: &mut MessageContext<'_, '_>,
|
||||
request: SwitchRoleCsReq,
|
||||
) -> SwitchRoleScRsp {
|
||||
if avatar_util::is_player_avatar(request.player_avatar_id)
|
||||
&& (avatar_util::is_player_avatar(request.control_avatar_id)
|
||||
if context
|
||||
.state
|
||||
.filecfg
|
||||
.is_player_avatar(request.player_avatar_id as i32)
|
||||
&& (context
|
||||
.state
|
||||
.filecfg
|
||||
.is_player_avatar(request.control_avatar_id as i32)
|
||||
|| context
|
||||
.player
|
||||
.role_model
|
||||
|
|
|
@ -5,11 +5,28 @@ use trigger_codegen::handlers;
|
|||
mod scene_module {
|
||||
use tracing::debug;
|
||||
use trigger_logic::scene::{ELocalPlayType, ESceneType};
|
||||
use trigger_sv::message::GameStateData;
|
||||
use trigger_sv::{
|
||||
message::{AvailableServerProtocolMessage, GameStateData},
|
||||
net::ServerType,
|
||||
};
|
||||
|
||||
use crate::logic::{dungeon_util, scene_util};
|
||||
use crate::logic::{dungeon_util, scene::ServerlessStateData, scene_util};
|
||||
|
||||
pub async fn on_enter_world(context: &mut MessageContext<'_, '_>, _request: EnterWorldCsReq) {
|
||||
if let Some(procedure_id) = context.player.beginner_procedure_id() {
|
||||
debug!("entering beginner procedure, id: {procedure_id}");
|
||||
|
||||
context
|
||||
.session
|
||||
.load_serverless_state(
|
||||
ServerlessStateData::FreshScene { procedure_id },
|
||||
context.request_id,
|
||||
EnterWorldScRsp::default(),
|
||||
)
|
||||
.await;
|
||||
return;
|
||||
}
|
||||
|
||||
let scene_model = &mut context.player.scene_model;
|
||||
|
||||
let scene_to_enter = match scene_model.get_current_scene().await {
|
||||
|
@ -24,7 +41,6 @@ mod scene_module {
|
|||
};
|
||||
|
||||
let scene_to_enter = if scene_to_enter.is_none() {
|
||||
// TODO: first scene to be created should be the 'Fresh' scene (beginner procedure)
|
||||
debug!(
|
||||
"player with uid {} has no scene to enter, default hall scene will be created",
|
||||
context.session.player_uid
|
||||
|
@ -149,6 +165,104 @@ mod scene_module {
|
|||
.await;
|
||||
}
|
||||
|
||||
pub async fn on_advance_beginner_procedure(
|
||||
context: &mut MessageContext<'_, '_>,
|
||||
request: AdvanceBeginnerProcedureCsReq,
|
||||
) {
|
||||
let rsp = if let Some(procedure_id) = context.player.beginner_procedure_id() {
|
||||
if request.procedure_id == procedure_id + 1 {
|
||||
context
|
||||
.player
|
||||
.advance_beginner_procedure(request.procedure_id)
|
||||
.await;
|
||||
|
||||
let rsp = AdvanceBeginnerProcedureScRsp {
|
||||
retcode: 0,
|
||||
next_procedure_id: request.procedure_id,
|
||||
};
|
||||
|
||||
if context.player.beginner_procedure_id().is_none() {
|
||||
// Beginner procedure finished, enter the hall scene now
|
||||
let scene_model = &mut context.player.scene_model;
|
||||
let scene = scene_model.create_scene_info(ESceneType::Hall).await;
|
||||
scene_model.set_default_scene(&scene).await;
|
||||
|
||||
context
|
||||
.session
|
||||
.change_game_state(
|
||||
context.request_id,
|
||||
rsp,
|
||||
context.player.build_state_reentrant_data(&scene).unwrap(),
|
||||
&scene,
|
||||
context.player,
|
||||
false,
|
||||
)
|
||||
.await;
|
||||
|
||||
None
|
||||
} else {
|
||||
Some(rsp)
|
||||
}
|
||||
} else {
|
||||
debug!(
|
||||
"invalid procedure transition (from: {}, to: {})",
|
||||
procedure_id, request.procedure_id
|
||||
);
|
||||
|
||||
Some(AdvanceBeginnerProcedureScRsp {
|
||||
retcode: 1,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
Some(AdvanceBeginnerProcedureScRsp {
|
||||
retcode: 1,
|
||||
..Default::default()
|
||||
})
|
||||
};
|
||||
|
||||
if let Some(rsp) = rsp {
|
||||
context
|
||||
.session
|
||||
.network_mgr
|
||||
.send_to(
|
||||
ServerType::GateServer,
|
||||
0,
|
||||
AvailableServerProtocolMessage {
|
||||
session_id: context.session.id,
|
||||
ack_request_id: context.request_id,
|
||||
notifies: Vec::new(),
|
||||
response: Some(rsp.into()),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn on_beginnerbattle_begin(
|
||||
_context: &mut MessageContext<'_, '_>,
|
||||
request: BeginnerbattleBeginCsReq,
|
||||
) -> BeginnerbattleBeginScRsp {
|
||||
BeginnerbattleBeginScRsp {
|
||||
retcode: 0,
|
||||
battle_uid: request.battle_id as i64,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn on_beginnerbattle_rebegin(
|
||||
_context: &mut MessageContext<'_, '_>,
|
||||
_request: BeginnerbattleRebeginCsReq,
|
||||
) -> BeginnerbattleRebeginScRsp {
|
||||
BeginnerbattleRebeginScRsp { retcode: 0 }
|
||||
}
|
||||
|
||||
pub async fn on_beginnerbattle_end(
|
||||
_context: &mut MessageContext<'_, '_>,
|
||||
_request: BeginnerbattleEndCsReq,
|
||||
) -> BeginnerbattleEndScRsp {
|
||||
BeginnerbattleEndScRsp { retcode: 0 }
|
||||
}
|
||||
|
||||
pub async fn on_active_hollow_check_point(
|
||||
_context: &mut MessageContext<'_, '_>,
|
||||
request: ActiveHollowCheckPointCsReq,
|
||||
|
|
|
@ -185,6 +185,18 @@ mod client_systems_module {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn on_end_newbie(
|
||||
_context: &mut MessageContext<'_, '_>,
|
||||
request: EndNewbieCsReq,
|
||||
) -> EndNewbieScRsp {
|
||||
debug!("EndNewbie({})", request.group_id);
|
||||
|
||||
EndNewbieScRsp {
|
||||
retcode: 0,
|
||||
group_id: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn on_get_trashbin_hermit_data(
|
||||
_context: &mut MessageContext<'_, '_>,
|
||||
_request: GetTrashbinHermitDataCsReq,
|
||||
|
|
|
@ -35,4 +35,11 @@ mod workbench_module {
|
|||
abyss_reward_data: Some(AbyssRewardData::default()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn on_unlock_clue_item(
|
||||
_context: &mut MessageContext<'_, '_>,
|
||||
_request: UnlockClueItemCsReq,
|
||||
) -> UnlockClueItemScRsp {
|
||||
UnlockClueItemScRsp { retcode: 0 }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use trigger_sv::{
|
|||
net::{ServerNetworkManager, ServerType},
|
||||
};
|
||||
|
||||
use crate::logic::{scene_util, NapPlayer};
|
||||
use crate::logic::{scene::ServerlessStateData, scene_util, NapPlayer};
|
||||
|
||||
pub mod message;
|
||||
|
||||
|
@ -50,6 +50,31 @@ impl GameSession {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn load_serverless_state(
|
||||
&self,
|
||||
state_data: ServerlessStateData,
|
||||
ack_request_id: u32,
|
||||
response: impl Into<ProtocolUnit>,
|
||||
) {
|
||||
let enter_scene_notify = trigger_protocol::EnterSceneScNotify {
|
||||
scene: Some(state_data.protocol_scene_data()),
|
||||
dungeon: None,
|
||||
};
|
||||
|
||||
self.network_mgr
|
||||
.send_to(
|
||||
ServerType::GateServer,
|
||||
0,
|
||||
AvailableServerProtocolMessage {
|
||||
session_id: self.id,
|
||||
ack_request_id,
|
||||
notifies: vec![enter_scene_notify.into()],
|
||||
response: Some(response.into()),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn change_game_state(
|
||||
&self,
|
||||
ack_request_id: u32,
|
||||
|
|
|
@ -11,6 +11,7 @@ pub struct Model {
|
|||
pub avatar_id: i32,
|
||||
pub player_avatar_id: i32,
|
||||
pub control_avatar_id: i32,
|
||||
pub beginner_procedure_id: i32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
|
|
|
@ -395,6 +395,15 @@ table ConditionConfigTemplate {
|
|||
type: int;
|
||||
}
|
||||
|
||||
table ProcedureConfigTemplate {
|
||||
procedure_id: int;
|
||||
procedure_type: int;
|
||||
content_id: string;
|
||||
jump_tos: [int];
|
||||
procedure_banks: [string];
|
||||
procedure_event: string;
|
||||
}
|
||||
|
||||
table AvatarBattleTemplate {
|
||||
id: int;
|
||||
unk_1: [int];
|
||||
|
@ -621,6 +630,10 @@ table ConditionConfigTemplateTb {
|
|||
data: [ConditionConfigTemplate];
|
||||
}
|
||||
|
||||
table ProcedureConfigTemplateTb {
|
||||
data: [ProcedureConfigTemplate];
|
||||
}
|
||||
|
||||
table AvatarBattleTemplateTb {
|
||||
data: [AvatarBattleTemplate];
|
||||
}
|
||||
|
|
|
@ -7366,6 +7366,188 @@ impl core::fmt::Debug for ConditionConfigTemplate<'_> {
|
|||
ds.finish()
|
||||
}
|
||||
}
|
||||
pub enum ProcedureConfigTemplateOffset {}
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
||||
pub struct ProcedureConfigTemplate<'a> {
|
||||
pub _tab: flatbuffers::Table<'a>,
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Follow<'a> for ProcedureConfigTemplate<'a> {
|
||||
type Inner = ProcedureConfigTemplate<'a>;
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self { _tab: flatbuffers::Table::new(buf, loc) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ProcedureConfigTemplate<'a> {
|
||||
pub const VT_PROCEDURE_ID: flatbuffers::VOffsetT = 4;
|
||||
pub const VT_PROCEDURE_TYPE: flatbuffers::VOffsetT = 6;
|
||||
pub const VT_CONTENT_ID: flatbuffers::VOffsetT = 8;
|
||||
pub const VT_JUMP_TOS: flatbuffers::VOffsetT = 10;
|
||||
pub const VT_PROCEDURE_BANKS: flatbuffers::VOffsetT = 12;
|
||||
pub const VT_PROCEDURE_EVENT: flatbuffers::VOffsetT = 14;
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
|
||||
ProcedureConfigTemplate { _tab: table }
|
||||
}
|
||||
#[allow(unused_mut)]
|
||||
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>(
|
||||
_fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>,
|
||||
args: &'args ProcedureConfigTemplateArgs<'args>
|
||||
) -> flatbuffers::WIPOffset<ProcedureConfigTemplate<'bldr>> {
|
||||
let mut builder = ProcedureConfigTemplateBuilder::new(_fbb);
|
||||
if let Some(x) = args.procedure_event { builder.add_procedure_event(x); }
|
||||
if let Some(x) = args.procedure_banks { builder.add_procedure_banks(x); }
|
||||
if let Some(x) = args.jump_tos { builder.add_jump_tos(x); }
|
||||
if let Some(x) = args.content_id { builder.add_content_id(x); }
|
||||
builder.add_procedure_type(args.procedure_type);
|
||||
builder.add_procedure_id(args.procedure_id);
|
||||
builder.finish()
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
pub fn procedure_id(&self) -> i32 {
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<i32>(ProcedureConfigTemplate::VT_PROCEDURE_ID, Some(0)).unwrap()}
|
||||
}
|
||||
#[inline]
|
||||
pub fn procedure_type(&self) -> i32 {
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<i32>(ProcedureConfigTemplate::VT_PROCEDURE_TYPE, Some(0)).unwrap()}
|
||||
}
|
||||
#[inline]
|
||||
pub fn content_id(&self) -> Option<&'a str> {
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(ProcedureConfigTemplate::VT_CONTENT_ID, None)}
|
||||
}
|
||||
#[inline]
|
||||
pub fn jump_tos(&self) -> Option<flatbuffers::Vector<'a, i32>> {
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, i32>>>(ProcedureConfigTemplate::VT_JUMP_TOS, None)}
|
||||
}
|
||||
#[inline]
|
||||
pub fn procedure_banks(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>> {
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>>>(ProcedureConfigTemplate::VT_PROCEDURE_BANKS, None)}
|
||||
}
|
||||
#[inline]
|
||||
pub fn procedure_event(&self) -> Option<&'a str> {
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(ProcedureConfigTemplate::VT_PROCEDURE_EVENT, None)}
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for ProcedureConfigTemplate<'_> {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<i32>("procedure_id", Self::VT_PROCEDURE_ID, false)?
|
||||
.visit_field::<i32>("procedure_type", Self::VT_PROCEDURE_TYPE, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<&str>>("content_id", Self::VT_CONTENT_ID, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, i32>>>("jump_tos", Self::VT_JUMP_TOS, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<&'_ str>>>>("procedure_banks", Self::VT_PROCEDURE_BANKS, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<&str>>("procedure_event", Self::VT_PROCEDURE_EVENT, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct ProcedureConfigTemplateArgs<'a> {
|
||||
pub procedure_id: i32,
|
||||
pub procedure_type: i32,
|
||||
pub content_id: Option<flatbuffers::WIPOffset<&'a str>>,
|
||||
pub jump_tos: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a, i32>>>,
|
||||
pub procedure_banks: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>>>,
|
||||
pub procedure_event: Option<flatbuffers::WIPOffset<&'a str>>,
|
||||
}
|
||||
impl<'a> Default for ProcedureConfigTemplateArgs<'a> {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
ProcedureConfigTemplateArgs {
|
||||
procedure_id: 0,
|
||||
procedure_type: 0,
|
||||
content_id: None,
|
||||
jump_tos: None,
|
||||
procedure_banks: None,
|
||||
procedure_event: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ProcedureConfigTemplateBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> {
|
||||
fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>,
|
||||
start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
|
||||
}
|
||||
impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ProcedureConfigTemplateBuilder<'a, 'b, A> {
|
||||
#[inline]
|
||||
pub fn add_procedure_id(&mut self, procedure_id: i32) {
|
||||
self.fbb_.push_slot::<i32>(ProcedureConfigTemplate::VT_PROCEDURE_ID, procedure_id, 0);
|
||||
}
|
||||
#[inline]
|
||||
pub fn add_procedure_type(&mut self, procedure_type: i32) {
|
||||
self.fbb_.push_slot::<i32>(ProcedureConfigTemplate::VT_PROCEDURE_TYPE, procedure_type, 0);
|
||||
}
|
||||
#[inline]
|
||||
pub fn add_content_id(&mut self, content_id: flatbuffers::WIPOffset<&'b str>) {
|
||||
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(ProcedureConfigTemplate::VT_CONTENT_ID, content_id);
|
||||
}
|
||||
#[inline]
|
||||
pub fn add_jump_tos(&mut self, jump_tos: flatbuffers::WIPOffset<flatbuffers::Vector<'b , i32>>) {
|
||||
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(ProcedureConfigTemplate::VT_JUMP_TOS, jump_tos);
|
||||
}
|
||||
#[inline]
|
||||
pub fn add_procedure_banks(&mut self, procedure_banks: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<&'b str>>>) {
|
||||
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(ProcedureConfigTemplate::VT_PROCEDURE_BANKS, procedure_banks);
|
||||
}
|
||||
#[inline]
|
||||
pub fn add_procedure_event(&mut self, procedure_event: flatbuffers::WIPOffset<&'b str>) {
|
||||
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(ProcedureConfigTemplate::VT_PROCEDURE_EVENT, procedure_event);
|
||||
}
|
||||
#[inline]
|
||||
pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> ProcedureConfigTemplateBuilder<'a, 'b, A> {
|
||||
let start = _fbb.start_table();
|
||||
ProcedureConfigTemplateBuilder {
|
||||
fbb_: _fbb,
|
||||
start_: start,
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn finish(self) -> flatbuffers::WIPOffset<ProcedureConfigTemplate<'a>> {
|
||||
let o = self.fbb_.end_table(self.start_);
|
||||
flatbuffers::WIPOffset::new(o.value())
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for ProcedureConfigTemplate<'_> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let mut ds = f.debug_struct("ProcedureConfigTemplate");
|
||||
ds.field("procedure_id", &self.procedure_id());
|
||||
ds.field("procedure_type", &self.procedure_type());
|
||||
ds.field("content_id", &self.content_id());
|
||||
ds.field("jump_tos", &self.jump_tos());
|
||||
ds.field("procedure_banks", &self.procedure_banks());
|
||||
ds.field("procedure_event", &self.procedure_event());
|
||||
ds.finish()
|
||||
}
|
||||
}
|
||||
pub enum AvatarBattleTemplateOffset {}
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
||||
|
@ -11904,6 +12086,103 @@ impl core::fmt::Debug for ConditionConfigTemplateTb<'_> {
|
|||
ds.finish()
|
||||
}
|
||||
}
|
||||
pub enum ProcedureConfigTemplateTbOffset {}
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
||||
pub struct ProcedureConfigTemplateTb<'a> {
|
||||
pub _tab: flatbuffers::Table<'a>,
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Follow<'a> for ProcedureConfigTemplateTb<'a> {
|
||||
type Inner = ProcedureConfigTemplateTb<'a>;
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self { _tab: flatbuffers::Table::new(buf, loc) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ProcedureConfigTemplateTb<'a> {
|
||||
pub const VT_DATA: flatbuffers::VOffsetT = 4;
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
|
||||
ProcedureConfigTemplateTb { _tab: table }
|
||||
}
|
||||
#[allow(unused_mut)]
|
||||
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>(
|
||||
_fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>,
|
||||
args: &'args ProcedureConfigTemplateTbArgs<'args>
|
||||
) -> flatbuffers::WIPOffset<ProcedureConfigTemplateTb<'bldr>> {
|
||||
let mut builder = ProcedureConfigTemplateTbBuilder::new(_fbb);
|
||||
if let Some(x) = args.data { builder.add_data(x); }
|
||||
builder.finish()
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
pub fn data(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<ProcedureConfigTemplate<'a>>>> {
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<ProcedureConfigTemplate>>>>(ProcedureConfigTemplateTb::VT_DATA, None)}
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for ProcedureConfigTemplateTb<'_> {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<ProcedureConfigTemplate>>>>("data", Self::VT_DATA, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct ProcedureConfigTemplateTbArgs<'a> {
|
||||
pub data: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<ProcedureConfigTemplate<'a>>>>>,
|
||||
}
|
||||
impl<'a> Default for ProcedureConfigTemplateTbArgs<'a> {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
ProcedureConfigTemplateTbArgs {
|
||||
data: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ProcedureConfigTemplateTbBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> {
|
||||
fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>,
|
||||
start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
|
||||
}
|
||||
impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ProcedureConfigTemplateTbBuilder<'a, 'b, A> {
|
||||
#[inline]
|
||||
pub fn add_data(&mut self, data: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<ProcedureConfigTemplate<'b >>>>) {
|
||||
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(ProcedureConfigTemplateTb::VT_DATA, data);
|
||||
}
|
||||
#[inline]
|
||||
pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> ProcedureConfigTemplateTbBuilder<'a, 'b, A> {
|
||||
let start = _fbb.start_table();
|
||||
ProcedureConfigTemplateTbBuilder {
|
||||
fbb_: _fbb,
|
||||
start_: start,
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn finish(self) -> flatbuffers::WIPOffset<ProcedureConfigTemplateTb<'a>> {
|
||||
let o = self.fbb_.end_table(self.start_);
|
||||
flatbuffers::WIPOffset::new(o.value())
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for ProcedureConfigTemplateTb<'_> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let mut ds = f.debug_struct("ProcedureConfigTemplateTb");
|
||||
ds.field("data", &self.data());
|
||||
ds.finish()
|
||||
}
|
||||
}
|
||||
pub enum AvatarBattleTemplateTbOffset {}
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ file_cfg! {
|
|||
WeaponTemplateTb;
|
||||
EquipmentTemplateTb;
|
||||
EquipmentSuitTemplateTb;
|
||||
ProcedureConfigTemplateTb;
|
||||
UnlockConfigTemplateTb;
|
||||
PostGirlConfigTemplateTb;
|
||||
ArchiveFileQuestTemplateTb;
|
||||
|
|
|
@ -6,3 +6,5 @@ version.workspace = true
|
|||
[dependencies]
|
||||
num_enum.workspace = true
|
||||
prost.workspace = true
|
||||
|
||||
trigger-fileconfig.workspace = true
|
||||
|
|
|
@ -3,3 +3,4 @@ pub mod item;
|
|||
pub mod quest;
|
||||
pub mod scene;
|
||||
pub mod skill;
|
||||
pub mod template_ext;
|
||||
|
|
|
@ -107,3 +107,9 @@ impl From<Vec<f64>> for Vector3f {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ESceneType> for u32 {
|
||||
fn from(value: ESceneType) -> Self {
|
||||
i16::from(value) as u32
|
||||
}
|
||||
}
|
||||
|
|
42
crates/trigger-logic/src/template_ext.rs
Normal file
42
crates/trigger-logic/src/template_ext.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
use trigger_fileconfig::NapFileCfg;
|
||||
|
||||
pub trait TemplateExt {
|
||||
fn is_player_avatar(&self, avatar_id: i32) -> bool;
|
||||
fn procedure_allows_select_role(&self, procedure_id: i32) -> bool;
|
||||
fn is_last_procedure(&self, procedure_id: i32) -> bool;
|
||||
}
|
||||
|
||||
impl TemplateExt for NapFileCfg {
|
||||
fn is_player_avatar(&self, avatar_id: i32) -> bool {
|
||||
self.avatar_base_template_tb()
|
||||
.data()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.find_map(|tmpl| (tmpl.id() == avatar_id && tmpl.camp() == 0).then_some(true))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn procedure_allows_select_role(&self, procedure_id: i32) -> bool {
|
||||
self.procedure_config_template_tb()
|
||||
.data()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.find_map(|tmpl| {
|
||||
(tmpl.procedure_id() == procedure_id && tmpl.procedure_type() == 4).then_some(true)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn is_last_procedure(&self, procedure_id: i32) -> bool {
|
||||
// faggots nuked JumpTos from client data btw!
|
||||
|
||||
self.procedure_config_template_tb()
|
||||
.data()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.max_by_key(|tmpl| tmpl.procedure_id())
|
||||
.unwrap()
|
||||
.procedure_id()
|
||||
== procedure_id
|
||||
}
|
||||
}
|
|
@ -85,6 +85,18 @@ pub struct PlayerLogoutScRsp {
|
|||
pub retcode: i32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(9)]
|
||||
pub struct SelectRoleCsReq {
|
||||
pub avatar_id: u32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(10)]
|
||||
pub struct SelectRoleScRsp {
|
||||
pub retcode: i32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(80)]
|
||||
pub struct SwitchRoleCsReq {
|
||||
|
@ -269,6 +281,7 @@ pub struct SceneData {
|
|||
pub local_play_type: u32,
|
||||
pub hall_scene_info: Option<HallSceneInfo>,
|
||||
pub fight_scene_info: Option<FightSceneInfo>,
|
||||
pub fresh_scene_info: Option<FreshSceneInfo>,
|
||||
pub rally_scene_info: Option<RallySceneInfo>,
|
||||
}
|
||||
|
||||
|
@ -322,6 +335,11 @@ pub struct FightSceneInfo {
|
|||
pub level_reward_info: Option<LevelRewardInfo>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
|
||||
pub struct FreshSceneInfo {
|
||||
pub last_procedure_id: u32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
|
||||
pub struct PublicVariable {
|
||||
pub r#type: u32,
|
||||
|
@ -561,6 +579,59 @@ pub struct ActiveHollowCheckPointScRsp {
|
|||
pub retcode: i32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(477)]
|
||||
pub struct AdvanceBeginnerProcedureCsReq {
|
||||
pub procedure_id: i32,
|
||||
pub params: i32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(478)]
|
||||
pub struct AdvanceBeginnerProcedureScRsp {
|
||||
pub retcode: i32,
|
||||
pub next_procedure_id: i32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(479)]
|
||||
pub struct BeginnerbattleBeginCsReq {
|
||||
pub battle_id: i32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(480)]
|
||||
pub struct BeginnerbattleBeginScRsp {
|
||||
pub retcode: i32,
|
||||
pub battle_uid: i64,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(481)]
|
||||
pub struct BeginnerbattleRebeginCsReq {
|
||||
pub battle_id: i32,
|
||||
pub battle_uid: i64,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(482)]
|
||||
pub struct BeginnerbattleRebeginScRsp {
|
||||
pub retcode: i32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(483)]
|
||||
pub struct BeginnerbattleEndCsReq {
|
||||
pub battle_id: i32,
|
||||
pub battle_uid: i64,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(484)]
|
||||
pub struct BeginnerbattleEndScRsp {
|
||||
pub retcode: i32,
|
||||
}
|
||||
|
||||
// Quest
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
|
||||
|
@ -1273,6 +1344,19 @@ pub struct GetNewsStandDataScRsp {
|
|||
pub news_stand_data: Option<NewsStandData>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(1323)]
|
||||
pub struct EndNewbieCsReq {
|
||||
pub group_id: u32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(1324)]
|
||||
pub struct EndNewbieScRsp {
|
||||
pub retcode: i32,
|
||||
pub group_id: u32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(1340)]
|
||||
pub struct GetTrashbinHermitDataCsReq {}
|
||||
|
@ -1490,6 +1574,16 @@ pub struct GetWorkbenchDataScRsp {
|
|||
pub workbench_data: Option<WorkbenchData>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(2002)]
|
||||
pub struct UnlockClueItemCsReq {}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(2003)]
|
||||
pub struct UnlockClueItemScRsp {
|
||||
pub retcode: i32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
|
||||
#[id(2010)]
|
||||
pub struct GetPartnerDataCsReq {}
|
||||
|
|
Loading…
Reference in a new issue