mirror of
https://github.com/redstrate/Kawari.git
synced 2025-04-26 16:37:46 +00:00
Add basic Event scripting capaibilities
This implements the first event script, going from the first Ul'dah opening cutscene to the next.
This commit is contained in:
parent
bcbe62af06
commit
c4b9ad060b
8 changed files with 142 additions and 38 deletions
21
resources/scripts/opening/OpeningUldah.lua
Normal file
21
resources/scripts/opening/OpeningUldah.lua
Normal file
|
@ -0,0 +1,21 @@
|
|||
--- TODO: find a way to hardcode it this way
|
||||
EVENT_ID = 1245187
|
||||
|
||||
function Scene00000(player)
|
||||
player:play_scene(EVENT_ID, 00000, 4959237, 1)
|
||||
end
|
||||
|
||||
function Scene00001(player)
|
||||
--- todo put player in correct position
|
||||
player:play_scene(EVENT_ID, 00001, 4959237, 1)
|
||||
end
|
||||
|
||||
function onEnterTerritory(player)
|
||||
Scene00000(player);
|
||||
end
|
||||
|
||||
function onSceneFinished(player, scene)
|
||||
if scene == 0 then
|
||||
Scene00001(player)
|
||||
end
|
||||
end
|
|
@ -76,6 +76,7 @@ async fn main() {
|
|||
position: Position::default(),
|
||||
inventory: Inventory::new(),
|
||||
status_effects: StatusEffects::default(),
|
||||
event: None,
|
||||
};
|
||||
|
||||
let mut lua_player = LuaPlayer::default();
|
||||
|
@ -570,6 +571,7 @@ async fn main() {
|
|||
ClientZoneIpcData::ChatMessage(chat_message) => {
|
||||
ChatHandler::handle_chat_message(
|
||||
&mut connection,
|
||||
&mut lua_player,
|
||||
chat_message,
|
||||
)
|
||||
.await
|
||||
|
@ -754,6 +756,10 @@ async fn main() {
|
|||
tracing::info!(
|
||||
"Recieved EventRelatedUnk! {unk1} {unk2} {unk3} {unk4}"
|
||||
);
|
||||
|
||||
if let Some(event) = connection.event.as_mut() {
|
||||
event.scene_finished(&mut lua_player, *unk2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,17 @@ use crate::{
|
|||
config::get_config,
|
||||
opcodes::ServerZoneIpcType,
|
||||
packet::{PacketSegment, SegmentType},
|
||||
world::ipc::{
|
||||
ActorControl, ActorControlCategory, BattleNpcSubKind, CommonSpawn, DisplayFlag, EventPlay,
|
||||
EventStart, NpcSpawn, ObjectKind, OnlineStatus, PlayerSpawn, PlayerSubKind,
|
||||
world::{
|
||||
Event,
|
||||
ipc::{
|
||||
ActorControl, ActorControlCategory, BattleNpcSubKind, CommonSpawn, DisplayFlag,
|
||||
EventPlay, EventStart, NpcSpawn, ObjectKind, OnlineStatus, PlayerSpawn, PlayerSubKind,
|
||||
ServerZoneIpcData, ServerZoneIpcSegment,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
use super::{ZoneConnection, ipc::ChatMessage};
|
||||
use super::{LuaPlayer, ZoneConnection, ipc::ChatMessage};
|
||||
|
||||
pub const CUSTOMIZE_DATA: CustomizeData = CustomizeData {
|
||||
race: 4,
|
||||
|
@ -44,7 +47,11 @@ pub const CUSTOMIZE_DATA: CustomizeData = CustomizeData {
|
|||
pub struct ChatHandler {}
|
||||
|
||||
impl ChatHandler {
|
||||
pub async fn handle_chat_message(connection: &mut ZoneConnection, chat_message: &ChatMessage) {
|
||||
pub async fn handle_chat_message(
|
||||
connection: &mut ZoneConnection,
|
||||
lua_player: &mut LuaPlayer,
|
||||
chat_message: &ChatMessage,
|
||||
) {
|
||||
tracing::info!("Client sent chat message: {}!", chat_message.message);
|
||||
|
||||
let parts: Vec<&str> = chat_message.message.split(' ').collect();
|
||||
|
@ -322,34 +329,12 @@ impl ChatHandler {
|
|||
.await;
|
||||
}
|
||||
|
||||
// play the scene, bart
|
||||
{
|
||||
let ipc = ServerZoneIpcSegment {
|
||||
unk1: 20,
|
||||
unk2: 0,
|
||||
op_code: ServerZoneIpcType::EventPlay,
|
||||
server_id: 0,
|
||||
timestamp: timestamp_secs(),
|
||||
data: ServerZoneIpcData::EventPlay(EventPlay {
|
||||
actor_id: ObjectTypeId {
|
||||
object_id: ObjectId(connection.player_data.actor_id),
|
||||
object_type: 0,
|
||||
},
|
||||
event_id: 0x130003,
|
||||
scene: 1,
|
||||
scene_flags: 4959237,
|
||||
..Default::default()
|
||||
}),
|
||||
};
|
||||
|
||||
connection.event = Some(Event::new("opening/OpeningUldah.lua"));
|
||||
connection
|
||||
.send_segment(PacketSegment {
|
||||
source_actor: connection.player_data.actor_id,
|
||||
target_actor: connection.player_data.actor_id,
|
||||
segment_type: SegmentType::Ipc { data: ipc },
|
||||
})
|
||||
.await;
|
||||
}
|
||||
.event
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.enter_territory(lua_player);
|
||||
}
|
||||
_ => tracing::info!("Unrecognized debug command!"),
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::{
|
|||
};
|
||||
|
||||
use super::{
|
||||
Inventory, Item, LuaPlayer, Zone,
|
||||
Event, Inventory, Item, LuaPlayer, Zone,
|
||||
ipc::{
|
||||
ActorSetPos, ClientZoneIpcSegment, ContainerInfo, ContainerType, InitZone, ItemInfo,
|
||||
ServerZoneIpcData, ServerZoneIpcSegment, StatusEffect, StatusEffectList, UpdateClassInfo,
|
||||
|
@ -69,6 +69,8 @@ pub struct ZoneConnection {
|
|||
pub position: Position,
|
||||
pub inventory: Inventory,
|
||||
pub status_effects: StatusEffects,
|
||||
|
||||
pub event: Option<Event>,
|
||||
}
|
||||
|
||||
impl ZoneConnection {
|
||||
|
|
52
src/world/event.rs
Normal file
52
src/world/event.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use mlua::{Function, Lua};
|
||||
|
||||
use crate::config::get_config;
|
||||
|
||||
use super::LuaPlayer;
|
||||
|
||||
pub struct Event {
|
||||
lua: Lua,
|
||||
}
|
||||
|
||||
impl Event {
|
||||
pub fn new(path: &str) -> Self {
|
||||
let lua = Lua::new();
|
||||
|
||||
let config = get_config();
|
||||
let file_name = format!("{}/{}", &config.world.scripts_location, path);
|
||||
lua.load(std::fs::read(&file_name).expect("Failed to locate scripts directory!"))
|
||||
.set_name("@".to_string() + &file_name)
|
||||
.exec()
|
||||
.unwrap();
|
||||
|
||||
Self { lua }
|
||||
}
|
||||
|
||||
pub fn enter_territory(&mut self, player: &mut LuaPlayer) {
|
||||
self.lua
|
||||
.scope(|scope| {
|
||||
let player = scope.create_userdata_ref_mut(player).unwrap();
|
||||
|
||||
let func: Function = self.lua.globals().get("onEnterTerritory").unwrap();
|
||||
|
||||
func.call::<()>(player).unwrap();
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn scene_finished(&mut self, player: &mut LuaPlayer, scene: u16) {
|
||||
self.lua
|
||||
.scope(|scope| {
|
||||
let player = scope.create_userdata_ref_mut(player).unwrap();
|
||||
|
||||
let func: Function = self.lua.globals().get("onSceneFinished").unwrap();
|
||||
|
||||
func.call::<()>((player, scene)).unwrap();
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
}
|
|
@ -337,7 +337,8 @@ pub enum ClientZoneIpcData {
|
|||
#[br(pre_assert(*magic == ClientZoneIpcType::EventRelatedUnk))]
|
||||
EventRelatedUnk {
|
||||
unk1: u32,
|
||||
unk2: u32,
|
||||
unk2: u16,
|
||||
#[brw(pad_before = 2)]
|
||||
unk3: u32,
|
||||
unk4: u32,
|
||||
},
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
use mlua::{UserData, UserDataMethods};
|
||||
|
||||
use crate::{
|
||||
common::timestamp_secs,
|
||||
common::{ObjectId, ObjectTypeId, timestamp_secs},
|
||||
opcodes::ServerZoneIpcType,
|
||||
packet::{PacketSegment, SegmentType},
|
||||
};
|
||||
|
||||
use super::{
|
||||
PlayerData, StatusEffects,
|
||||
ipc::{ServerZoneIpcData, ServerZoneIpcSegment},
|
||||
ipc::{EventPlay, ServerZoneIpcData, ServerZoneIpcSegment},
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -44,6 +44,33 @@ impl LuaPlayer {
|
|||
fn give_status_effect(&mut self, effect_id: u16, duration: f32) {
|
||||
self.status_effects.add(effect_id, duration);
|
||||
}
|
||||
|
||||
fn play_scene(&mut self, event_id: u32, scene: u16, scene_flags: u32, param: u8) {
|
||||
let ipc = ServerZoneIpcSegment {
|
||||
unk1: 20,
|
||||
unk2: 0,
|
||||
op_code: ServerZoneIpcType::EventPlay,
|
||||
server_id: 0,
|
||||
timestamp: timestamp_secs(),
|
||||
data: ServerZoneIpcData::EventPlay(EventPlay {
|
||||
actor_id: ObjectTypeId {
|
||||
object_id: ObjectId(self.player_data.actor_id),
|
||||
object_type: 0,
|
||||
},
|
||||
event_id,
|
||||
scene,
|
||||
scene_flags,
|
||||
unk2: param,
|
||||
..Default::default()
|
||||
}),
|
||||
};
|
||||
|
||||
self.queue_segment(PacketSegment {
|
||||
source_actor: self.player_data.actor_id,
|
||||
target_actor: self.player_data.actor_id,
|
||||
segment_type: SegmentType::Ipc { data: ipc },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for LuaPlayer {
|
||||
|
@ -59,5 +86,12 @@ impl UserData for LuaPlayer {
|
|||
Ok(())
|
||||
},
|
||||
);
|
||||
methods.add_method_mut(
|
||||
"play_scene",
|
||||
|_, this, (event_id, scene, scene_flags, param): (u32, u16, u32, u8)| {
|
||||
this.play_scene(event_id, scene, scene_flags, param);
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,3 +17,6 @@ pub use inventory::{EquippedContainer, Inventory, Item};
|
|||
|
||||
mod lua;
|
||||
pub use lua::LuaPlayer;
|
||||
|
||||
mod event;
|
||||
pub use event::Event;
|
||||
|
|
Loading…
Add table
Reference in a new issue