mirror of
https://github.com/redstrate/Kawari.git
synced 2025-07-23 21:17:45 +00:00
Play the inn bed wakeup animation on login
Currently this is hardcoded to The Roost because I ran out of time, but it's easy to add support for other inn rooms. I had to extend the Lua scene API quite a bit, hence a bunch of unrelated changes so it doesn't break every other event script.
This commit is contained in:
parent
bfbd4ff8bc
commit
743e2b9b65
26 changed files with 185 additions and 97 deletions
|
@ -7,12 +7,28 @@ dofile(BASE_DIR.."events/Events.lua")
|
|||
dofile(BASE_DIR.."items/Items.lua")
|
||||
dofile(BASE_DIR.."Global.lua")
|
||||
|
||||
BED_EVENT_HANDLER = 720916
|
||||
BED_CUTSCENE_FLAGS = 4165480179 -- TODO: remove this hardcode
|
||||
BED_SCENE_WAKEUP_ANIM = 00100
|
||||
|
||||
-- Lua error handlers, and other server events like player login
|
||||
function onBeginLogin(player)
|
||||
-- send a welcome message
|
||||
player:send_message(getLoginMessage())
|
||||
end
|
||||
|
||||
function onFinishZoning(player)
|
||||
local zone_id = player.zone.id;
|
||||
|
||||
-- play the wakeup animation
|
||||
-- the roost
|
||||
-- TODO: check for other inns
|
||||
if zone_id == 179 then
|
||||
player:start_event(player.id, BED_EVENT_HANDLER, 15, zone_id)
|
||||
player:play_scene(player.id, BED_EVENT_HANDLER, BED_SCENE_WAKEUP_ANIM, BED_CUTSCENE_FLAGS, {})
|
||||
end
|
||||
end
|
||||
|
||||
function onCommandRequiredRankInsufficientError(player)
|
||||
player:send_message("You do not have permission to run this command.")
|
||||
end
|
||||
|
|
|
@ -20,7 +20,7 @@ function onReturn(scene, results, player)
|
|||
|
||||
if scene == SCENE_SHOW_MENU then
|
||||
if destination ~= AETHERNET_MENU_CANCEL then
|
||||
player:finish_event(EVENT_ID) -- Need to finish the event here, because warping does not return to this callback (the game will crash or softlock otherwise)
|
||||
player:finish_event(EVENT_ID, 0) -- Need to finish the event here, because warping does not return to this callback (the game will crash or softlock otherwise)
|
||||
player:warp_aetheryte(destination)
|
||||
return
|
||||
end
|
||||
|
@ -28,5 +28,5 @@ function onReturn(scene, results, player)
|
|||
-- TODO: attunement logic
|
||||
end
|
||||
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -36,7 +36,7 @@ function onReturn(scene, results, player)
|
|||
end ]]
|
||||
elseif menu_option == AETHERNET_SUBMENU then
|
||||
if decision ~= AETHERNET_SUBMENU_CANCEL then
|
||||
player:finish_event(EVENT_ID) -- Need to finish the event here, because warping does not return to this callback (the game will crash or softlock otherwise)
|
||||
player:finish_event(EVENT_ID, 0) -- Need to finish the event here, because warping does not return to this callback (the game will crash or softlock otherwise)
|
||||
player:warp_aetheryte(decision)
|
||||
return
|
||||
end
|
||||
|
@ -47,5 +47,5 @@ function onReturn(scene, results, player)
|
|||
end
|
||||
end
|
||||
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -11,5 +11,5 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -5,5 +5,5 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -5,5 +5,5 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -5,5 +5,5 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
|
||||
if results[1] == 1 then
|
||||
-- get warp
|
||||
|
|
|
@ -38,6 +38,6 @@ function onReturn(scene, results, player)
|
|||
player:play_scene(player.id, EVENT_ID, SCENE_SHOP_END, 1 | 0x2000, {})
|
||||
end
|
||||
else
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,7 +31,7 @@ function onReturn(scene, results, player)
|
|||
|
||||
if scene == SCENE_SHOW_MENU then
|
||||
if decision == NOTHING or decision == CANCEL_SCENE then
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
else
|
||||
if decision == LOG_OUT or decision == EXIT_GAME then
|
||||
player:begin_log_out()
|
||||
|
@ -47,7 +47,9 @@ function onReturn(scene, results, player)
|
|||
end
|
||||
elseif scene == SCENE_DREAMFITTING then
|
||||
player:play_scene(player.id, EVENT_ID, SCENE_AWAKEN_ANIM, CUTSCENE_FLAGS, {0})
|
||||
elseif scene == SCENE_AWAKEN_ANIM then
|
||||
player:finish_event(EVENT_ID, player.zone.id)
|
||||
else
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,5 +33,5 @@ function onReturn(scene, results, player)
|
|||
player:play_scene(player.id, EVENT_ID, 00003, FADE_OUT + HIDE_UI + CONDITION_CUTSCENE, {0})
|
||||
return
|
||||
end
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -7,5 +7,5 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -6,5 +6,5 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -3,5 +3,5 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -9,5 +9,5 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -9,5 +9,5 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -5,5 +5,5 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -8,5 +8,5 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -16,5 +16,5 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -8,5 +8,5 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
|
|
|
@ -21,6 +21,6 @@ function onReturn(scene, results, player)
|
|||
elseif scene == SCENE_PLAY_CUTSCENE then
|
||||
player:play_scene(player.id, EVENT_ID, SCENE_SHOW_MENU, 8192, {1})
|
||||
else
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ function onTalk(target, player)
|
|||
end
|
||||
|
||||
function onReturn(scene, results, player)
|
||||
player:finish_event(EVENT_ID)
|
||||
player:finish_event(EVENT_ID, 0)
|
||||
|
||||
if results[1] == 1 then
|
||||
-- get warp
|
||||
|
|
|
@ -15,8 +15,8 @@ use kawari::ipc::zone::{
|
|||
};
|
||||
|
||||
use kawari::ipc::zone::{
|
||||
ClientTriggerCommand, ClientZoneIpcData, EventStart, GameMasterRank, OnlineStatus,
|
||||
ServerZoneIpcData, ServerZoneIpcSegment, SocialListRequestType,
|
||||
ClientTriggerCommand, ClientZoneIpcData, GameMasterRank, OnlineStatus, ServerZoneIpcData,
|
||||
ServerZoneIpcSegment, SocialListRequestType,
|
||||
};
|
||||
use kawari::opcodes::{ServerChatIpcType, ServerZoneIpcType};
|
||||
use kawari::packet::oodle::OodleNetwork;
|
||||
|
@ -27,7 +27,7 @@ use kawari::world::{
|
|||
ChatHandler, ExtraLuaState, LuaZone, ObsfucationData, Zone, ZoneConnection, load_init_script,
|
||||
};
|
||||
use kawari::world::{
|
||||
ClientHandle, Event, FromServer, LuaPlayer, PlayerData, ServerHandle, StatusEffects, ToServer,
|
||||
ClientHandle, FromServer, LuaPlayer, PlayerData, ServerHandle, StatusEffects, ToServer,
|
||||
WorldDatabase, handle_custom_ipc, server_main_loop,
|
||||
};
|
||||
use kawari::{
|
||||
|
@ -443,6 +443,20 @@ async fn client_loop(
|
|||
})
|
||||
.await;
|
||||
},
|
||||
ClientTriggerCommand::FinishZoning {} => {
|
||||
let lua = lua.lock().unwrap();
|
||||
lua.scope(|scope| {
|
||||
let connection_data =
|
||||
scope.create_userdata_ref_mut(&mut lua_player).unwrap();
|
||||
|
||||
let func: Function = lua.globals().get("onFinishZoning").unwrap();
|
||||
|
||||
func.call::<()>(connection_data).unwrap();
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
_ => {
|
||||
// inform the server of our trigger, it will handle sending it to other clients
|
||||
connection.handle.send(ToServer::ClientTrigger(connection.id, connection.player_data.actor_id, trigger.clone())).await;
|
||||
|
@ -902,15 +916,15 @@ async fn client_loop(
|
|||
} else {
|
||||
tracing::error!(ERR_INVENTORY_ADD_FAILED);
|
||||
connection.send_message(ERR_INVENTORY_ADD_FAILED).await;
|
||||
connection.event_finish(*event_id).await;
|
||||
connection.event_finish(*event_id, 0).await;
|
||||
}
|
||||
} else {
|
||||
connection.send_message("Insufficient gil to buy item. Nice try bypassing the client-side check!").await;
|
||||
connection.event_finish(*event_id).await;
|
||||
connection.event_finish(*event_id, 0).await;
|
||||
}
|
||||
} else {
|
||||
connection.send_message("Unable to find shop item, this is a bug in Kawari!").await;
|
||||
connection.event_finish(*event_id).await;
|
||||
connection.event_finish(*event_id, 0).await;
|
||||
}
|
||||
} else if *buy_sell_mode == SELL {
|
||||
let storage = get_container_type(*item_index).unwrap();
|
||||
|
@ -1019,69 +1033,24 @@ async fn client_loop(
|
|||
connection.event_scene(&target_id, *event_id, 10, 8193, params).await;
|
||||
} else {
|
||||
connection.send_message("Unable to find shop item, this is a bug in Kawari!").await;
|
||||
connection.event_finish(*event_id).await;
|
||||
connection.event_finish(*event_id, 0).await;
|
||||
}
|
||||
} else {
|
||||
tracing::error!("Received unknown transaction mode {buy_sell_mode}!");
|
||||
connection.event_finish(*event_id).await;
|
||||
connection.event_finish(*event_id, 0).await;
|
||||
}
|
||||
}
|
||||
ClientZoneIpcData::StartTalkEvent { actor_id, event_id } => {
|
||||
connection.player_data.target_actorid = *actor_id;
|
||||
// load event
|
||||
{
|
||||
let ipc = ServerZoneIpcSegment {
|
||||
op_code: ServerZoneIpcType::EventStart,
|
||||
timestamp: timestamp_secs(),
|
||||
data: ServerZoneIpcData::EventStart(EventStart {
|
||||
target_id: *actor_id,
|
||||
event_id: *event_id,
|
||||
event_type: 1, // talk?
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
connection
|
||||
.send_segment(PacketSegment {
|
||||
source_actor: connection.player_data.actor_id,
|
||||
target_actor: connection.player_data.actor_id,
|
||||
segment_type: SegmentType::Ipc,
|
||||
data: SegmentData::Ipc { data: ipc },
|
||||
})
|
||||
.await;
|
||||
}
|
||||
connection.start_event(*actor_id, *event_id, 1, 0).await;
|
||||
|
||||
/* TODO: ServerZoneIpcType::Unk18 with data [64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
||||
* was observed to always be sent by the server upon interacting with shops. They open and function fine without
|
||||
* it, but should we send it anyway, for the sake of accuracy? It's also still unclear if this
|
||||
* happens for -every- NPC/actor. */
|
||||
* was observed to always be sent by the server upon interacting with shops. They open and function fine without
|
||||
* it, but should we send it anyway, for the sake of accuracy? It's also still unclear if this
|
||||
* happens for -every- NPC/actor. */
|
||||
|
||||
let mut should_cancel = false;
|
||||
{
|
||||
let lua = lua.lock().unwrap();
|
||||
let state = lua.app_data_ref::<ExtraLuaState>().unwrap();
|
||||
|
||||
if let Some(event_script) =
|
||||
state.event_scripts.get(event_id)
|
||||
{
|
||||
connection.event = Some(Event::new(*event_id, event_script));
|
||||
connection
|
||||
.event
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.talk(*actor_id, &mut lua_player);
|
||||
} else {
|
||||
tracing::warn!("Event {event_id} isn't scripted yet! Ignoring...");
|
||||
|
||||
should_cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
if should_cancel {
|
||||
// give control back to the player so they aren't stuck
|
||||
connection.event_finish(*event_id).await;
|
||||
connection.send_message(&format!("Event {event_id} tried to start, but it doesn't have a script associated with it!")).await;
|
||||
// begin talk function if it exists
|
||||
if let Some(event) = connection.event.as_mut() {
|
||||
event.talk(*actor_id, &mut lua_player);
|
||||
}
|
||||
}
|
||||
ClientZoneIpcData::EventYieldHandler(handler) => {
|
||||
|
@ -1517,6 +1486,7 @@ async fn main() {
|
|||
weather_id: 0,
|
||||
obsfucation_data: ObsfucationData::default(),
|
||||
queued_content: None,
|
||||
event_type: 0,
|
||||
});
|
||||
}
|
||||
Some((mut socket, _)) = handle_rcon(&rcon_listener) => {
|
||||
|
|
|
@ -110,7 +110,7 @@ impl ChatHandler {
|
|||
}
|
||||
"!finishevent" => {
|
||||
if let Some(event) = &connection.event {
|
||||
connection.event_finish(event.id).await;
|
||||
connection.event_finish(event.id, 0).await;
|
||||
connection
|
||||
.send_message("Current event forcefully finished.")
|
||||
.await;
|
||||
|
|
|
@ -26,7 +26,7 @@ use crate::{
|
|||
ActionEffect, ActionRequest, ActionResult, ActorControl, ActorControlCategory,
|
||||
ActorControlSelf, ActorControlTarget, ClientZoneIpcSegment, CommonSpawn, Config,
|
||||
ContainerInfo, CurrencyInfo, DisplayFlag, EffectEntry, EffectKind, EffectResult, Equip,
|
||||
EventScene, GameMasterRank, InitZone, ItemInfo, Move, NpcSpawn, ObjectKind,
|
||||
EventScene, EventStart, GameMasterRank, InitZone, ItemInfo, Move, NpcSpawn, ObjectKind,
|
||||
PlayerStats, PlayerSubKind, QuestActiveList, ServerZoneIpcData, ServerZoneIpcSegment,
|
||||
StatusEffect, StatusEffectList, UpdateClassInfo, Warp, WeatherChange,
|
||||
},
|
||||
|
@ -155,6 +155,7 @@ pub struct ZoneConnection {
|
|||
pub status_effects: StatusEffects,
|
||||
|
||||
pub event: Option<Event>,
|
||||
pub event_type: u8,
|
||||
pub actors: Vec<Actor>,
|
||||
|
||||
pub ip: SocketAddr,
|
||||
|
@ -847,7 +848,8 @@ impl ZoneConnection {
|
|||
}
|
||||
player.queued_segments.clear();
|
||||
|
||||
for task in &player.queued_tasks {
|
||||
let tasks = player.queued_tasks.clone();
|
||||
for task in &tasks {
|
||||
match task {
|
||||
Task::ChangeTerritory { zone_id } => self.change_zone(*zone_id).await,
|
||||
Task::SetRemakeMode(remake_mode) => self
|
||||
|
@ -857,7 +859,7 @@ impl ZoneConnection {
|
|||
self.warp(*warp_id).await;
|
||||
}
|
||||
Task::BeginLogOut => self.begin_log_out().await,
|
||||
Task::FinishEvent { handler_id } => self.event_finish(*handler_id).await,
|
||||
Task::FinishEvent { handler_id, arg } => self.event_finish(*handler_id, *arg).await,
|
||||
Task::SetClassJob { classjob_id } => {
|
||||
self.player_data.classjob_id = *classjob_id;
|
||||
self.update_class_info().await;
|
||||
|
@ -1016,6 +1018,15 @@ impl ZoneConnection {
|
|||
self.set_current_exp(current_exp + amount);
|
||||
self.update_class_info().await;
|
||||
}
|
||||
Task::StartEvent {
|
||||
actor_id,
|
||||
event_id,
|
||||
event_type,
|
||||
event_arg,
|
||||
} => {
|
||||
self.start_event(*actor_id, *event_id, *event_type, *event_arg)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
player.queued_tasks.clear();
|
||||
|
@ -1066,11 +1077,11 @@ impl ZoneConnection {
|
|||
"Unable to play event {event_id}, scene {:?}, scene_flags {scene_flags}!",
|
||||
scene
|
||||
);
|
||||
self.event_finish(event_id).await;
|
||||
self.event_finish(event_id, 0).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn event_finish(&mut self, handler_id: u32) {
|
||||
pub async fn event_finish(&mut self, handler_id: u32, arg: u32) {
|
||||
self.player_data.target_actorid = ObjectTypeId::default();
|
||||
// sent event finish
|
||||
{
|
||||
|
@ -1079,9 +1090,9 @@ impl ZoneConnection {
|
|||
timestamp: timestamp_secs(),
|
||||
data: ServerZoneIpcData::EventFinish {
|
||||
handler_id,
|
||||
event: 1,
|
||||
event: self.event_type,
|
||||
result: 1,
|
||||
arg: 0,
|
||||
arg,
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
@ -1777,4 +1788,62 @@ impl ZoneConnection {
|
|||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn start_event(
|
||||
&mut self,
|
||||
actor_id: ObjectTypeId,
|
||||
event_id: u32,
|
||||
event_type: u8,
|
||||
event_arg: u32,
|
||||
) {
|
||||
self.player_data.target_actorid = actor_id;
|
||||
self.event_type = event_type;
|
||||
|
||||
// tell the client the event has started
|
||||
{
|
||||
let ipc = ServerZoneIpcSegment {
|
||||
op_code: ServerZoneIpcType::EventStart,
|
||||
timestamp: timestamp_secs(),
|
||||
data: ServerZoneIpcData::EventStart(EventStart {
|
||||
target_id: actor_id,
|
||||
event_id,
|
||||
event_type,
|
||||
event_arg,
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
self.send_segment(PacketSegment {
|
||||
source_actor: self.player_data.actor_id,
|
||||
target_actor: self.player_data.actor_id,
|
||||
segment_type: SegmentType::Ipc,
|
||||
data: SegmentData::Ipc { data: ipc },
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
// load event script if needed
|
||||
let mut should_cancel = false;
|
||||
{
|
||||
let lua = self.lua.lock().unwrap();
|
||||
let state = lua.app_data_ref::<ExtraLuaState>().unwrap();
|
||||
if let Some(event_script) = state.event_scripts.get(&event_id) {
|
||||
self.event = Some(Event::new(event_id, event_script));
|
||||
} else {
|
||||
tracing::warn!("Event {event_id} isn't scripted yet! Ignoring...");
|
||||
|
||||
should_cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
if should_cancel {
|
||||
// give control back to the player so they aren't stuck
|
||||
self.event_finish(event_id, 0).await;
|
||||
self.send_message(&format!(
|
||||
"Event {event_id} tried to start, but it doesn't have a script associated with it!"
|
||||
))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ use mlua::{FromLua, Lua, LuaSerdeExt, UserData, UserDataFields, UserDataMethods,
|
|||
|
||||
use super::{PlayerData, StatusEffects, Zone, connection::TeleportQuery};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Task {
|
||||
ChangeTerritory {
|
||||
zone_id: u16,
|
||||
|
@ -33,6 +34,7 @@ pub enum Task {
|
|||
BeginLogOut,
|
||||
FinishEvent {
|
||||
handler_id: u32,
|
||||
arg: u32,
|
||||
},
|
||||
SetClassJob {
|
||||
classjob_id: u8,
|
||||
|
@ -83,6 +85,12 @@ pub enum Task {
|
|||
AddExp {
|
||||
amount: u32,
|
||||
},
|
||||
StartEvent {
|
||||
actor_id: ObjectTypeId,
|
||||
event_id: u32,
|
||||
event_type: u8,
|
||||
event_arg: u32,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
|
@ -199,7 +207,7 @@ impl LuaPlayer {
|
|||
let error_message = "Unsupported amount of parameters in play_scene! This is likely a bug in your script! Cancelling event...".to_string();
|
||||
tracing::warn!(error_message);
|
||||
self.send_message(&error_message, 0);
|
||||
self.finish_event(event_id);
|
||||
self.finish_event(event_id, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,8 +281,9 @@ impl LuaPlayer {
|
|||
self.queued_tasks.push(Task::BeginLogOut);
|
||||
}
|
||||
|
||||
fn finish_event(&mut self, handler_id: u32) {
|
||||
self.queued_tasks.push(Task::FinishEvent { handler_id });
|
||||
fn finish_event(&mut self, handler_id: u32, arg: u32) {
|
||||
self.queued_tasks
|
||||
.push(Task::FinishEvent { handler_id, arg });
|
||||
}
|
||||
|
||||
fn set_classjob(&mut self, classjob_id: u8) {
|
||||
|
@ -446,6 +455,21 @@ impl LuaPlayer {
|
|||
fn add_exp(&mut self, amount: u32) {
|
||||
self.queued_tasks.push(Task::AddExp { amount });
|
||||
}
|
||||
|
||||
fn start_event(
|
||||
&mut self,
|
||||
actor_id: ObjectTypeId,
|
||||
event_id: u32,
|
||||
event_type: u8,
|
||||
event_arg: u32,
|
||||
) {
|
||||
self.queued_tasks.push(Task::StartEvent {
|
||||
actor_id,
|
||||
event_id,
|
||||
event_type,
|
||||
event_arg,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for LuaPlayer {
|
||||
|
@ -533,8 +557,8 @@ impl UserData for LuaPlayer {
|
|||
this.begin_log_out();
|
||||
Ok(())
|
||||
});
|
||||
methods.add_method_mut("finish_event", |_, this, handler_id: u32| {
|
||||
this.finish_event(handler_id);
|
||||
methods.add_method_mut("finish_event", |_, this, (handler_id, arg): (u32, u32)| {
|
||||
this.finish_event(handler_id, arg);
|
||||
Ok(())
|
||||
});
|
||||
methods.add_method_mut("set_classjob", |_, this, classjob_id: u8| {
|
||||
|
@ -600,6 +624,13 @@ impl UserData for LuaPlayer {
|
|||
this.add_exp(amount);
|
||||
Ok(())
|
||||
});
|
||||
methods.add_method_mut(
|
||||
"start_event",
|
||||
|_, this, (target, event_id, event_type, event_arg): (ObjectTypeId, u32, u8, u32)| {
|
||||
this.start_event(target, event_id, event_type, event_arg);
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
|
|
Loading…
Add table
Reference in a new issue