mirror of
https://github.com/redstrate/Kawari.git
synced 2025-05-12 14:47:46 +00:00
Make Limsa Inn warp functional
This was surprisingly easy, so now this works. You can't exit the inn yet, though!
This commit is contained in:
parent
afbadf85c4
commit
fec6665d8d
6 changed files with 96 additions and 9 deletions
|
@ -8,3 +8,10 @@ function onTalk(target, player)
|
|||
-- doesn't have inn access
|
||||
--player:play_scene(actorId, EVENT_ID, 00002, 8192, 0)
|
||||
end
|
||||
|
||||
function onReturn(results, player)
|
||||
if results[1] == 1 then
|
||||
-- get warp
|
||||
player:warp(EVENT_ID)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -135,9 +135,6 @@ async fn client_loop(
|
|||
let lua = connection.lua.clone();
|
||||
let config = get_config();
|
||||
|
||||
let mut exit_position = None;
|
||||
let mut exit_rotation = None;
|
||||
|
||||
let mut lua_player = LuaPlayer::default();
|
||||
|
||||
let mut buf = vec![0; RECEIVE_BUFFER_SIZE];
|
||||
|
@ -162,8 +159,8 @@ async fn client_loop(
|
|||
// collect actor data
|
||||
connection.initialize(actor_id).await;
|
||||
|
||||
exit_position = Some(connection.player_data.position);
|
||||
exit_rotation = Some(connection.player_data.rotation);
|
||||
connection.exit_position = Some(connection.player_data.position);
|
||||
connection.exit_rotation = Some(connection.player_data.rotation);
|
||||
|
||||
// tell the server we exist, now that we confirmed we are a legitimate connection
|
||||
connection.handle.send(ToServer::NewClient(client_handle.clone())).await;
|
||||
|
@ -318,7 +315,7 @@ async fn client_loop(
|
|||
// tell the server we loaded into the zone, so it can start sending us acors
|
||||
connection.handle.send(ToServer::ZoneLoaded(connection.id)).await;
|
||||
|
||||
let common = connection.get_player_common_spawn(exit_position, exit_rotation);
|
||||
let common = connection.get_player_common_spawn(connection.exit_position, connection.exit_rotation);
|
||||
|
||||
// send player spawn
|
||||
{
|
||||
|
@ -370,8 +367,8 @@ async fn client_loop(
|
|||
}
|
||||
|
||||
// wipe any exit position so it isn't accidentally reused
|
||||
exit_position = None;
|
||||
exit_rotation = None;
|
||||
connection.exit_position = None;
|
||||
connection.exit_rotation = None;
|
||||
|
||||
// tell the other players we're here
|
||||
connection.handle.send(ToServer::ActorSpawned(connection.id, Actor { id: ObjectId(connection.player_data.actor_id), hp: 100, spawn_index: 0 }, common)).await;
|
||||
|
@ -571,7 +568,7 @@ async fn client_loop(
|
|||
.unwrap();
|
||||
|
||||
// set the exit position
|
||||
exit_position = Some(Position {
|
||||
connection.exit_position = Some(Position {
|
||||
x: destination_object.transform.translation[0],
|
||||
y: destination_object.transform.translation[1],
|
||||
z: destination_object.transform.translation[2],
|
||||
|
@ -769,6 +766,12 @@ async fn client_loop(
|
|||
ClientZoneIpcData::EventHandlerReturn { handler_id, scene, error_code, num_results, results } => {
|
||||
tracing::info!("Finishing this event... {handler_id} {scene} {error_code} {num_results} {results:#?}");
|
||||
|
||||
connection
|
||||
.event
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.finish(results, &mut lua_player);
|
||||
|
||||
{
|
||||
// TODO: handle in lua script
|
||||
let ipc = ServerZoneIpcSegment {
|
||||
|
@ -969,6 +972,8 @@ async fn main() {
|
|||
database: database.clone(),
|
||||
lua: lua.clone(),
|
||||
gamedata: game_data.clone(),
|
||||
exit_position: None,
|
||||
exit_rotation: None,
|
||||
});
|
||||
}
|
||||
Some((mut socket, _)) = handle_rcon(&rcon_listener) => {
|
||||
|
|
|
@ -122,4 +122,25 @@ impl GameData {
|
|||
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the pop range object id that's associated with the warp id
|
||||
pub fn get_warp(&mut self, warp_id: u32) -> (u32, u16) {
|
||||
let exh = self.game_data.read_excel_sheet_header("Warp").unwrap();
|
||||
let exd = self
|
||||
.game_data
|
||||
.read_excel_sheet("Warp", &exh, Language::English, 0)
|
||||
.unwrap();
|
||||
|
||||
let row = &exd.read_row(&exh, warp_id).unwrap()[0];
|
||||
|
||||
let physis::exd::ColumnData::UInt32(pop_range_id) = &row.data[0] else {
|
||||
panic!("Unexpected type!");
|
||||
};
|
||||
|
||||
let physis::exd::ColumnData::UInt16(zone_id) = &row.data[1] else {
|
||||
panic!("Unexpected type!");
|
||||
};
|
||||
|
||||
(*pop_range_id, *zone_id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,6 +152,9 @@ pub struct ZoneConnection {
|
|||
pub database: Arc<WorldDatabase>,
|
||||
pub lua: Arc<Mutex<mlua::Lua>>,
|
||||
pub gamedata: Arc<Mutex<GameData>>,
|
||||
|
||||
pub exit_position: Option<Position>,
|
||||
pub exit_rotation: Option<f32>,
|
||||
}
|
||||
|
||||
impl ZoneConnection {
|
||||
|
@ -422,6 +425,31 @@ impl ZoneConnection {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn warp(&mut self, warp_id: u32) {
|
||||
let territory_type;
|
||||
// find the pop range on the other side
|
||||
{
|
||||
let mut game_data = self.gamedata.lock().unwrap();
|
||||
let (pop_range_id, zone_id) = game_data.get_warp(warp_id);
|
||||
|
||||
let new_zone = Zone::load(&mut game_data.game_data, zone_id);
|
||||
|
||||
// find it on the other side
|
||||
let (object, _) = new_zone.find_pop_range(pop_range_id).unwrap();
|
||||
|
||||
// set the exit position
|
||||
self.exit_position = Some(Position {
|
||||
x: object.transform.translation[0],
|
||||
y: object.transform.translation[1],
|
||||
z: object.transform.translation[2],
|
||||
});
|
||||
|
||||
territory_type = zone_id;
|
||||
}
|
||||
|
||||
self.change_zone(territory_type as u16).await;
|
||||
}
|
||||
|
||||
pub async fn change_weather(&mut self, new_weather_id: u16) {
|
||||
let ipc = ServerZoneIpcSegment {
|
||||
op_code: ServerZoneIpcType::WeatherId,
|
||||
|
@ -569,6 +597,9 @@ impl ZoneConnection {
|
|||
Task::SetRemakeMode(remake_mode) => self
|
||||
.database
|
||||
.set_remake_mode(player.player_data.content_id, *remake_mode),
|
||||
Task::Warp { warp_id } => {
|
||||
self.warp(*warp_id).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
player.queued_tasks.clear();
|
||||
|
|
|
@ -64,4 +64,18 @@ impl Event {
|
|||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn finish(&mut self, results: &[u32], player: &mut LuaPlayer) {
|
||||
self.lua
|
||||
.scope(|scope| {
|
||||
let player = scope.create_userdata_ref_mut(player).unwrap();
|
||||
|
||||
let func: Function = self.lua.globals().get("onReturn").unwrap();
|
||||
|
||||
func.call::<()>((results, player)).unwrap();
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ use super::{PlayerData, StatusEffects, Zone};
|
|||
pub enum Task {
|
||||
ChangeTerritory { zone_id: u16 },
|
||||
SetRemakeMode(RemakeMode),
|
||||
Warp { warp_id: u32 },
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -109,6 +110,10 @@ impl LuaPlayer {
|
|||
fn set_remake_mode(&mut self, mode: RemakeMode) {
|
||||
self.queued_tasks.push(Task::SetRemakeMode(mode));
|
||||
}
|
||||
|
||||
fn warp(&mut self, warp_id: u32) {
|
||||
self.queued_tasks.push(Task::Warp { warp_id });
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for LuaPlayer {
|
||||
|
@ -144,6 +149,10 @@ impl UserData for LuaPlayer {
|
|||
this.set_remake_mode(mode);
|
||||
Ok(())
|
||||
});
|
||||
methods.add_method_mut("warp", |_, this, warp_id: u32| {
|
||||
this.warp(warp_id);
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue