1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-05-12 14:47:46 +00:00

Fix remaining inn warps, prevent the player from getting stuck

This means the three ARR inns are now "functional" (as in, you can enter
and exit them.) I also added some code to give you control of your
character in case you hit an unimplemented event.
This commit is contained in:
Joshua Goins 2025-05-05 23:45:22 -04:00
parent e237cbe84d
commit ca8d36e48c
5 changed files with 90 additions and 46 deletions

View file

@ -13,9 +13,12 @@ registerAction(9, "actions/FastBlade.lua")
registerAction(6221, "items/Fantasia.lua")
-- Events
registerEvent(131078, "warp/WarpInnGridania.lua")
registerEvent(131079, "warp/WarpInnLimsaLominsa.lua")
registerEvent(131080, "warp/WarpInnGridania.lua")
registerEvent(131081, "warp/WarpInnUldah.lua")
registerEvent(131082, "common/GenericWarp.lua")
registerEvent(131083, "common/GenericWarp.lua")
registerEvent(131084, "common/GenericWarp.lua")
registerEvent(131092, "common/GenericWarp.lua")
registerEvent(131093, "common/GenericWarp.lua")
registerEvent(131094, "common/GenericWarp.lua")
@ -23,3 +26,5 @@ registerEvent(720916, "custom/000/cmndefinnbed_00020.lua")
registerEvent(1245185, "opening/OpeningLimsaLominsa.lua")
registerEvent(1245186, "opening/OpeningGridania.lua")
registerEvent(1245187, "opening/OpeningUldah.lua")
-- TODO: Generic warps might be decided through ArrayEventHandler?

View file

@ -1,7 +1,18 @@
function onTalk(actorId, player)
-- TODO: maybe de-duplicare this for all inns?
function onTalk(target, player)
-- has inn access
-- player:play_scene(131079, 00001, 1, 0)
player:play_scene(target, EVENT_ID, 00001, 8192, 0)
-- doesn't have inn access
player:play_scene(actorId, EVENT_ID, 00002, 8192, 0)
--player:play_scene(actorId, EVENT_ID, 00002, 8192, 0)
end
function onReturn(scene, results, player)
player:finish_event(EVENT_ID)
if results[1] == 1 then
-- get warp
player:warp(EVENT_ID)
end
end

View file

@ -0,0 +1,16 @@
function onTalk(target, player)
-- has inn access
player:play_scene(target, EVENT_ID, 00001, 8192, 0)
-- doesn't have inn access
--player:play_scene(actorId, EVENT_ID, 00002, 8192, 0)
end
function onReturn(scene, results, player)
player:finish_event(EVENT_ID)
if results[1] == 1 then
-- get warp
player:warp(EVENT_ID)
end
end

View file

@ -727,6 +727,8 @@ async fn client_loop(
.await;
}
let mut should_cancel = false;
{
let lua = lua.lock().unwrap();
let state = lua.app_data_ref::<ExtraLuaState>().unwrap();
@ -741,6 +743,14 @@ async fn client_loop(
.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;
}
}
ClientZoneIpcData::EventHandlerReturn { handler_id, scene, error_code, num_results, results } => {

View file

@ -601,53 +601,55 @@ impl ZoneConnection {
self.warp(*warp_id).await;
}
Task::BeginLogOut => self.begin_log_out().await,
Task::FinishEvent { handler_id } => {
// sent event finish
{
let ipc = ServerZoneIpcSegment {
op_code: ServerZoneIpcType::EventFinish,
timestamp: timestamp_secs(),
data: ServerZoneIpcData::EventFinish {
handler_id: *handler_id,
event: 1,
result: 1,
arg: 0,
},
..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;
}
// give back control to the player
{
let ipc = ServerZoneIpcSegment {
op_code: ServerZoneIpcType::Unk18,
timestamp: timestamp_secs(),
data: ServerZoneIpcData::Unk18 { unk: [0; 16] },
..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;
}
}
Task::FinishEvent { handler_id } => self.event_finish(*handler_id).await,
}
}
player.queued_tasks.clear();
}
pub async fn event_finish(&mut self, handler_id: u32) {
// sent event finish
{
let ipc = ServerZoneIpcSegment {
op_code: ServerZoneIpcType::EventFinish,
timestamp: timestamp_secs(),
data: ServerZoneIpcData::EventFinish {
handler_id,
event: 1,
result: 1,
arg: 0,
},
..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;
}
// give back control to the player
{
let ipc = ServerZoneIpcSegment {
op_code: ServerZoneIpcType::Unk18,
timestamp: timestamp_secs(),
data: ServerZoneIpcData::Unk18 { unk: [0; 16] },
..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;
}
}
pub async fn begin_log_out(&mut self) {
// write the player back to the database
self.database.commit_player_data(&self.player_data);