mirror of
https://github.com/redstrate/Kawari.git
synced 2025-07-10 07:57:46 +00:00
Refactor lua.rs: (#109)
-The match has been moved into src/ipc/zone/event_scene.rs and slimmed down -EventScene now provides a function to decide the opcode based on how many params it has -The tests for EventScene were updated to acommodate the new changes
This commit is contained in:
parent
0cf359e8c9
commit
22dc1dbaaa
4 changed files with 142 additions and 147 deletions
|
@ -1,11 +1,14 @@
|
||||||
use binrw::binrw;
|
use binrw::binrw;
|
||||||
|
|
||||||
use crate::common::ObjectTypeId;
|
use crate::common::ObjectTypeId;
|
||||||
|
use crate::ipc::zone::{ServerZoneIpcData, ServerZoneIpcType};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[brw(little)]
|
#[brw(little)]
|
||||||
#[derive(Debug, Clone)]
|
#[brw(import{max_params: usize})]
|
||||||
pub struct EventScene<const MAX_PARAMS: usize> {
|
#[brw(assert(params.len() <= max_params, "Too many params! {} > {}", params.len(), max_params))]
|
||||||
|
pub struct EventScene {
|
||||||
pub actor_id: ObjectTypeId,
|
pub actor_id: ObjectTypeId,
|
||||||
pub event_id: u32,
|
pub event_id: u32,
|
||||||
pub scene: u16,
|
pub scene: u16,
|
||||||
|
@ -15,10 +18,12 @@ pub struct EventScene<const MAX_PARAMS: usize> {
|
||||||
pub params_count: u8,
|
pub params_count: u8,
|
||||||
// Extra padding seems needed after or the client will seemingly softlock even with 2 params, possibly used for alignment?
|
// Extra padding seems needed after or the client will seemingly softlock even with 2 params, possibly used for alignment?
|
||||||
#[brw(pad_before = 3, pad_after = 4)]
|
#[brw(pad_before = 3, pad_after = 4)]
|
||||||
pub params: [u32; MAX_PARAMS],
|
#[br(count = max_params)]
|
||||||
|
#[bw(pad_size_to = 4 * max_params)]
|
||||||
|
pub params: Vec<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const MAX_PARAMS: usize> Default for EventScene<{ MAX_PARAMS }> {
|
impl Default for EventScene {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
actor_id: ObjectTypeId::default(),
|
actor_id: ObjectTypeId::default(),
|
||||||
|
@ -27,11 +32,58 @@ impl<const MAX_PARAMS: usize> Default for EventScene<{ MAX_PARAMS }> {
|
||||||
scene_flags: 0,
|
scene_flags: 0,
|
||||||
unk1: 0,
|
unk1: 0,
|
||||||
params_count: 0,
|
params_count: 0,
|
||||||
params: [0u32; MAX_PARAMS],
|
params: Vec::<u32>::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EventScene {
|
||||||
|
pub fn package_scene(&self) -> Option<(ServerZoneIpcType, ServerZoneIpcData)> {
|
||||||
|
let op_code;
|
||||||
|
let data;
|
||||||
|
match self.params.len() {
|
||||||
|
// TODO: it would be nice to avoid cloning if possible
|
||||||
|
0..=2 => {
|
||||||
|
op_code = ServerZoneIpcType::EventScene;
|
||||||
|
data = ServerZoneIpcData::EventScene { data: self.clone() };
|
||||||
|
}
|
||||||
|
3..=4 => {
|
||||||
|
op_code = ServerZoneIpcType::EventScene4;
|
||||||
|
data = ServerZoneIpcData::EventScene4 { data: self.clone() };
|
||||||
|
}
|
||||||
|
5..=8 => {
|
||||||
|
op_code = ServerZoneIpcType::EventScene8;
|
||||||
|
data = ServerZoneIpcData::EventScene8 { data: self.clone() };
|
||||||
|
}
|
||||||
|
9..=16 => {
|
||||||
|
op_code = ServerZoneIpcType::EventScene16;
|
||||||
|
data = ServerZoneIpcData::EventScene16 { data: self.clone() };
|
||||||
|
}
|
||||||
|
17..=32 => {
|
||||||
|
op_code = ServerZoneIpcType::EventScene32;
|
||||||
|
data = ServerZoneIpcData::EventScene32 { data: self.clone() };
|
||||||
|
}
|
||||||
|
33..=64 => {
|
||||||
|
op_code = ServerZoneIpcType::EventScene64;
|
||||||
|
data = ServerZoneIpcData::EventScene64 { data: self.clone() };
|
||||||
|
}
|
||||||
|
65..=128 => {
|
||||||
|
op_code = ServerZoneIpcType::EventScene128;
|
||||||
|
data = ServerZoneIpcData::EventScene128 { data: self.clone() };
|
||||||
|
}
|
||||||
|
129..255 => {
|
||||||
|
op_code = ServerZoneIpcType::EventScene255;
|
||||||
|
data = ServerZoneIpcData::EventScene255 { data: self.clone() };
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some((op_code, data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::{fs::read, io::Cursor, path::PathBuf};
|
use std::{fs::read, io::Cursor, path::PathBuf};
|
||||||
|
@ -50,7 +102,8 @@ mod tests {
|
||||||
let buffer = read(d).unwrap();
|
let buffer = read(d).unwrap();
|
||||||
let mut buffer = Cursor::new(&buffer);
|
let mut buffer = Cursor::new(&buffer);
|
||||||
|
|
||||||
let event_play = EventScene::<2>::read_le(&mut buffer).unwrap();
|
let event_play =
|
||||||
|
EventScene::read_le_args(&mut buffer, EventSceneBinReadArgs { max_params: 2 }).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
event_play.actor_id,
|
event_play.actor_id,
|
||||||
ObjectTypeId {
|
ObjectTypeId {
|
||||||
|
|
|
@ -252,21 +252,53 @@ pub enum ServerZoneIpcData {
|
||||||
ContainerInfo(ContainerInfo),
|
ContainerInfo(ContainerInfo),
|
||||||
/// Sent to tell the client to play a scene
|
/// Sent to tell the client to play a scene
|
||||||
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene))]
|
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene))]
|
||||||
EventScene(EventScene<2>),
|
#[brw(little)]
|
||||||
|
EventScene {
|
||||||
|
#[brw(args { max_params: 2 } )]
|
||||||
|
data: EventScene,
|
||||||
|
},
|
||||||
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene4))]
|
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene4))]
|
||||||
EventScene4(EventScene<4>),
|
#[brw(little)]
|
||||||
|
EventScene4 {
|
||||||
|
#[brw(args { max_params: 4 } )]
|
||||||
|
data: EventScene,
|
||||||
|
},
|
||||||
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene8))]
|
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene8))]
|
||||||
EventScene8(EventScene<8>),
|
#[brw(little)]
|
||||||
|
EventScene8 {
|
||||||
|
#[brw(args { max_params: 8 } )]
|
||||||
|
data: EventScene,
|
||||||
|
},
|
||||||
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene16))]
|
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene16))]
|
||||||
EventScene16(EventScene<16>),
|
#[brw(little)]
|
||||||
|
EventScene16 {
|
||||||
|
#[brw(args { max_params: 16 } )]
|
||||||
|
data: EventScene,
|
||||||
|
},
|
||||||
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene32))]
|
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene32))]
|
||||||
EventScene32(EventScene<32>),
|
#[brw(little)]
|
||||||
|
EventScene32 {
|
||||||
|
#[brw(args { max_params: 32 } )]
|
||||||
|
data: EventScene,
|
||||||
|
},
|
||||||
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene64))]
|
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene64))]
|
||||||
EventScene64(EventScene<64>),
|
#[brw(little)]
|
||||||
|
EventScene64 {
|
||||||
|
#[brw(args { max_params: 64 } )]
|
||||||
|
data: EventScene,
|
||||||
|
},
|
||||||
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene128))]
|
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene128))]
|
||||||
EventScene128(EventScene<128>),
|
#[brw(little)]
|
||||||
|
EventScene128 {
|
||||||
|
#[brw(args { max_params: 128 } )]
|
||||||
|
data: EventScene,
|
||||||
|
},
|
||||||
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene255))]
|
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene255))]
|
||||||
EventScene255(EventScene<255>),
|
#[brw(little)]
|
||||||
|
EventScene255 {
|
||||||
|
#[brw(args { max_params: 255 } )]
|
||||||
|
data: EventScene,
|
||||||
|
},
|
||||||
/// Sent to tell the client to load a scene, but not play it
|
/// Sent to tell the client to load a scene, but not play it
|
||||||
#[br(pre_assert(*magic == ServerZoneIpcType::EventStart))]
|
#[br(pre_assert(*magic == ServerZoneIpcType::EventStart))]
|
||||||
EventStart(EventStart),
|
EventStart(EventStart),
|
||||||
|
@ -651,35 +683,51 @@ mod tests {
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
ServerZoneIpcType::EventScene,
|
ServerZoneIpcType::EventScene,
|
||||||
ServerZoneIpcData::EventScene(EventScene::default()),
|
ServerZoneIpcData::EventScene {
|
||||||
|
data: EventScene::default(),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
ServerZoneIpcType::EventScene4,
|
ServerZoneIpcType::EventScene4,
|
||||||
ServerZoneIpcData::EventScene4(EventScene::<4>::default()),
|
ServerZoneIpcData::EventScene4 {
|
||||||
|
data: EventScene::default(),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
ServerZoneIpcType::EventScene8,
|
ServerZoneIpcType::EventScene8,
|
||||||
ServerZoneIpcData::EventScene8(EventScene::<8>::default()),
|
ServerZoneIpcData::EventScene8 {
|
||||||
|
data: EventScene::default(),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
ServerZoneIpcType::EventScene16,
|
ServerZoneIpcType::EventScene16,
|
||||||
ServerZoneIpcData::EventScene16(EventScene::<16>::default()),
|
ServerZoneIpcData::EventScene16 {
|
||||||
|
data: EventScene::default(),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
ServerZoneIpcType::EventScene32,
|
ServerZoneIpcType::EventScene32,
|
||||||
ServerZoneIpcData::EventScene32(EventScene::<32>::default()),
|
ServerZoneIpcData::EventScene32 {
|
||||||
|
data: EventScene::default(),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
ServerZoneIpcType::EventScene64,
|
ServerZoneIpcType::EventScene64,
|
||||||
ServerZoneIpcData::EventScene64(EventScene::<64>::default()),
|
ServerZoneIpcData::EventScene64 {
|
||||||
|
data: EventScene::default(),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
ServerZoneIpcType::EventScene128,
|
ServerZoneIpcType::EventScene128,
|
||||||
ServerZoneIpcData::EventScene128(EventScene::<128>::default()),
|
ServerZoneIpcData::EventScene128 {
|
||||||
|
data: EventScene::default(),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
ServerZoneIpcType::EventScene255,
|
ServerZoneIpcType::EventScene255,
|
||||||
ServerZoneIpcData::EventScene255(EventScene::<255>::default()),
|
ServerZoneIpcData::EventScene255 {
|
||||||
|
data: EventScene::default(),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
ServerZoneIpcType::EventStart,
|
ServerZoneIpcType::EventStart,
|
||||||
|
|
141
src/world/lua.rs
141
src/world/lua.rs
|
@ -125,131 +125,26 @@ impl LuaPlayer {
|
||||||
event_id: u32,
|
event_id: u32,
|
||||||
scene: u16,
|
scene: u16,
|
||||||
scene_flags: u32,
|
scene_flags: u32,
|
||||||
params: &[u32],
|
params: Vec<u32>,
|
||||||
) {
|
) {
|
||||||
let op_code;
|
let scene = EventScene {
|
||||||
let data;
|
actor_id: target,
|
||||||
match params.len() {
|
event_id,
|
||||||
// TODO: it would be nice to de-duplicate these
|
scene,
|
||||||
0..=2 => {
|
scene_flags,
|
||||||
let mut scene = EventScene {
|
params_count: params.len() as u8,
|
||||||
actor_id: target,
|
params: params.clone(),
|
||||||
event_id,
|
..Default::default()
|
||||||
scene,
|
};
|
||||||
scene_flags,
|
|
||||||
params_count: params.len() as u8,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
scene.params[..params.len()].copy_from_slice(¶ms[0..params.len()]);
|
|
||||||
|
|
||||||
op_code = ServerZoneIpcType::EventScene;
|
if let Some((op_code, data)) = scene.package_scene() {
|
||||||
data = ServerZoneIpcData::EventScene(scene);
|
self.create_segment_self(op_code, data);
|
||||||
}
|
} else {
|
||||||
3..=4 => {
|
let error_message = "Unsupported amount of parameters in play_scene! This is likely a bug in your script! Cancelling event...".to_string();
|
||||||
let mut scene = EventScene::<4> {
|
tracing::warn!(error_message);
|
||||||
actor_id: target,
|
self.send_message(&error_message, 0);
|
||||||
event_id,
|
self.finish_event(event_id);
|
||||||
scene,
|
|
||||||
scene_flags,
|
|
||||||
params_count: params.len() as u8,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
scene.params[..params.len()].copy_from_slice(¶ms[0..params.len()]);
|
|
||||||
|
|
||||||
op_code = ServerZoneIpcType::EventScene4;
|
|
||||||
data = ServerZoneIpcData::EventScene4(scene);
|
|
||||||
}
|
|
||||||
5..=8 => {
|
|
||||||
let mut scene = EventScene::<8> {
|
|
||||||
actor_id: target,
|
|
||||||
event_id,
|
|
||||||
scene,
|
|
||||||
scene_flags,
|
|
||||||
params_count: params.len() as u8,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
scene.params[..params.len()].copy_from_slice(¶ms[0..params.len()]);
|
|
||||||
|
|
||||||
op_code = ServerZoneIpcType::EventScene8;
|
|
||||||
data = ServerZoneIpcData::EventScene8(scene);
|
|
||||||
}
|
|
||||||
9..=16 => {
|
|
||||||
let mut scene = EventScene::<16> {
|
|
||||||
actor_id: target,
|
|
||||||
event_id,
|
|
||||||
scene,
|
|
||||||
scene_flags,
|
|
||||||
params_count: params.len() as u8,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
scene.params[..params.len()].copy_from_slice(¶ms[0..params.len()]);
|
|
||||||
|
|
||||||
op_code = ServerZoneIpcType::EventScene16;
|
|
||||||
data = ServerZoneIpcData::EventScene16(scene);
|
|
||||||
}
|
|
||||||
17..=32 => {
|
|
||||||
let mut scene = EventScene::<32> {
|
|
||||||
actor_id: target,
|
|
||||||
event_id,
|
|
||||||
scene,
|
|
||||||
scene_flags,
|
|
||||||
params_count: params.len() as u8,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
scene.params[..params.len()].copy_from_slice(¶ms[0..params.len()]);
|
|
||||||
|
|
||||||
op_code = ServerZoneIpcType::EventScene32;
|
|
||||||
data = ServerZoneIpcData::EventScene32(scene);
|
|
||||||
}
|
|
||||||
33..=64 => {
|
|
||||||
let mut scene = EventScene::<64> {
|
|
||||||
actor_id: target,
|
|
||||||
event_id,
|
|
||||||
scene,
|
|
||||||
scene_flags,
|
|
||||||
params_count: params.len() as u8,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
scene.params.copy_from_slice(¶ms[0..params.len()]);
|
|
||||||
|
|
||||||
op_code = ServerZoneIpcType::EventScene64;
|
|
||||||
data = ServerZoneIpcData::EventScene64(scene);
|
|
||||||
}
|
|
||||||
65..=128 => {
|
|
||||||
let mut scene = EventScene::<128> {
|
|
||||||
actor_id: target,
|
|
||||||
event_id,
|
|
||||||
scene,
|
|
||||||
scene_flags,
|
|
||||||
params_count: params.len() as u8,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
scene.params[..params.len()].copy_from_slice(¶ms[0..params.len()]);
|
|
||||||
|
|
||||||
op_code = ServerZoneIpcType::EventScene128;
|
|
||||||
data = ServerZoneIpcData::EventScene128(scene);
|
|
||||||
}
|
|
||||||
129..255 => {
|
|
||||||
let mut scene = EventScene::<255> {
|
|
||||||
actor_id: target,
|
|
||||||
event_id,
|
|
||||||
scene,
|
|
||||||
scene_flags,
|
|
||||||
params_count: params.len() as u8,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
scene.params[..params.len()].copy_from_slice(¶ms[0..params.len()]);
|
|
||||||
|
|
||||||
op_code = ServerZoneIpcType::EventScene255;
|
|
||||||
data = ServerZoneIpcData::EventScene255(scene);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
tracing::warn!("Unsupported amount of parameters in play_scene!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.create_segment_self(op_code, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_position(&mut self, position: Position, rotation: f32) {
|
fn set_position(&mut self, position: Position, rotation: f32) {
|
||||||
|
@ -404,7 +299,7 @@ impl UserData for LuaPlayer {
|
||||||
u32,
|
u32,
|
||||||
Vec<u32>,
|
Vec<u32>,
|
||||||
)| {
|
)| {
|
||||||
this.play_scene(target, event_id, scene, scene_flags, ¶ms);
|
this.play_scene(target, event_id, scene, scene_flags, params);
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -324,8 +324,7 @@ pub async fn server_main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ClientTriggerCommand::EventRelatedUnk { .. } = &trigger.trigger
|
if let ClientTriggerCommand::EventRelatedUnk { .. } = &trigger.trigger {
|
||||||
{
|
|
||||||
let msg = FromServer::ActorControlSelf(ActorControlSelf {
|
let msg = FromServer::ActorControlSelf(ActorControlSelf {
|
||||||
category: ActorControlCategory::EventRelatedUnk1 { unk1: 1 },
|
category: ActorControlCategory::EventRelatedUnk1 { unk1: 1 },
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue