1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-04-24 16:17:44 +00:00

Add support for the GM command to change the weather

You can now change the weather with `//gm weather <id>`.
This commit is contained in:
Joshua Goins 2025-03-18 23:48:00 -04:00
parent 4927fa9119
commit 788cbf114a
7 changed files with 44 additions and 11 deletions

View file

@ -500,6 +500,9 @@ async fn main() {
tracing::info!("Got a game master command!"); tracing::info!("Got a game master command!");
match &command { match &command {
GameMasterCommandType::ChangeWeather => {
connection.change_weather(*arg as u16).await
}
GameMasterCommandType::ChangeTerritory => { GameMasterCommandType::ChangeTerritory => {
connection.change_zone(*arg as u16).await connection.change_zone(*arg as u16).await
} }

View file

@ -1,4 +1,3 @@
use crate::{ use crate::{
CHAR_NAME, CUSTOMIZE_DATA, INVALID_OBJECT_ID, WORLD_ID, CHAR_NAME, CUSTOMIZE_DATA, INVALID_OBJECT_ID, WORLD_ID,
common::timestamp_secs, common::timestamp_secs,

View file

@ -12,7 +12,7 @@ use super::{
Zone, Zone,
ipc::{ ipc::{
ActorSetPos, ClientZoneIpcSegment, InitZone, Position, ServerZoneIpcData, ActorSetPos, ClientZoneIpcSegment, InitZone, Position, ServerZoneIpcData,
ServerZoneIpcSegment, ServerZoneIpcType, UpdateClassInfo, ServerZoneIpcSegment, ServerZoneIpcType, UpdateClassInfo, WeatherChange,
}, },
}; };
@ -137,6 +137,25 @@ impl ZoneConnection {
} }
} }
pub async fn change_weather(&mut self, new_weather_id: u16) {
let ipc = ServerZoneIpcSegment {
op_code: ServerZoneIpcType::WeatherChange,
timestamp: timestamp_secs(),
data: ServerZoneIpcData::WeatherChange(WeatherChange {
weather_id: new_weather_id,
transistion_time: 1.0,
}),
..Default::default()
};
self.send_segment(PacketSegment {
source_actor: self.player_id,
target_actor: self.player_id,
segment_type: SegmentType::Ipc { data: ipc },
})
.await;
}
pub fn get_free_spawn_index(&mut self) -> u8 { pub fn get_free_spawn_index(&mut self) -> u8 {
self.spawn_index += 1; self.spawn_index += 1;
self.spawn_index self.spawn_index

View file

@ -44,6 +44,9 @@ pub use common_spawn::{CharacterMode, CommonSpawn, ObjectKind};
mod status_effect_list; mod status_effect_list;
pub use status_effect_list::StatusEffectList; pub use status_effect_list::StatusEffectList;
mod weather_change;
pub use weather_change::WeatherChange;
use crate::common::read_string; use crate::common::read_string;
use crate::common::write_string; use crate::common::write_string;
use crate::packet::IpcSegment; use crate::packet::IpcSegment;
@ -87,7 +90,6 @@ impl ReadWriteIpcSegment for ServerZoneIpcSegment {
ServerZoneIpcType::Unk8 => 808, ServerZoneIpcType::Unk8 => 808,
ServerZoneIpcType::LinkShellInformation => 456, ServerZoneIpcType::LinkShellInformation => 456,
ServerZoneIpcType::Unk9 => 24, ServerZoneIpcType::Unk9 => 24,
ServerZoneIpcType::Unk10 => 8,
ServerZoneIpcType::Unk11 => 32, ServerZoneIpcType::Unk11 => 32,
ServerZoneIpcType::Unk15 => 8, ServerZoneIpcType::Unk15 => 8,
ServerZoneIpcType::Unk16 => 136, ServerZoneIpcType::Unk16 => 136,
@ -98,6 +100,7 @@ impl ReadWriteIpcSegment for ServerZoneIpcSegment {
ServerZoneIpcType::PrepareZoning => 16, ServerZoneIpcType::PrepareZoning => 16,
ServerZoneIpcType::NpcSpawn => 648, ServerZoneIpcType::NpcSpawn => 648,
ServerZoneIpcType::StatusEffectList => 384, ServerZoneIpcType::StatusEffectList => 384,
ServerZoneIpcType::WeatherChange => 8,
} }
} }
} }
@ -130,6 +133,7 @@ pub struct ActorSetPos {
#[brw(repr = u8)] #[brw(repr = u8)]
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub enum GameMasterCommandType { pub enum GameMasterCommandType {
ChangeWeather = 0x6,
ChangeTerritory = 0x58, ChangeTerritory = 0x58,
} }
@ -165,9 +169,6 @@ pub enum ServerZoneIpcType {
LinkShellInformation = 0x234, LinkShellInformation = 0x234,
// Unknown, server sends to the client before player spawn // Unknown, server sends to the client before player spawn
Unk9 = 0x189, Unk9 = 0x189,
// Unknown, server sends to the client before player spawn.
// Seems to the same across two different characters?
Unk10 = 0x110,
// Unknown, server sends this in response to Unk7 // Unknown, server sends this in response to Unk7
Unk11 = 0x156, Unk11 = 0x156,
// Sent by the server when it wants the client to... prepare to zone? // Sent by the server when it wants the client to... prepare to zone?
@ -188,6 +189,8 @@ pub enum ServerZoneIpcType {
NpcSpawn = 0x100, NpcSpawn = 0x100,
// Sent by the server to update an actor's status effect list // Sent by the server to update an actor's status effect list
StatusEffectList = 0xBB, StatusEffectList = 0xBB,
// Sent by the server when it's time to change the weather
WeatherChange = 0x110,
} }
#[binrw] #[binrw]
@ -273,9 +276,6 @@ pub enum ServerZoneIpcData {
Unk9 { Unk9 {
unk: [u8; 24], unk: [u8; 24],
}, },
Unk10 {
unk: u64,
},
Unk11 { Unk11 {
timestamp: u32, timestamp: u32,
#[brw(pad_after = 24)] // empty bytes #[brw(pad_after = 24)] // empty bytes
@ -302,6 +302,7 @@ pub enum ServerZoneIpcData {
SocialList(SocialList), SocialList(SocialList),
NpcSpawn(NpcSpawn), NpcSpawn(NpcSpawn),
StatusEffectList(StatusEffectList), StatusEffectList(StatusEffectList),
WeatherChange(WeatherChange),
} }
#[binrw] #[binrw]
@ -456,6 +457,10 @@ mod tests {
ServerZoneIpcType::StatusEffectList, ServerZoneIpcType::StatusEffectList,
ServerZoneIpcData::StatusEffectList(StatusEffectList::default()), ServerZoneIpcData::StatusEffectList(StatusEffectList::default()),
), ),
(
ServerZoneIpcType::WeatherChange,
ServerZoneIpcData::WeatherChange(WeatherChange::default()),
),
]; ];
for (opcode, data) in &ipc_types { for (opcode, data) in &ipc_types {

View file

@ -1,6 +1,5 @@
use binrw::binrw; use binrw::binrw;
use super::CommonSpawn; use super::CommonSpawn;
#[binrw] #[binrw]

View file

@ -1,6 +1,5 @@
use binrw::binrw; use binrw::binrw;
use super::CommonSpawn; use super::CommonSpawn;
#[binrw] #[binrw]

View file

@ -0,0 +1,9 @@
use binrw::binrw;
#[binrw]
#[derive(Debug, Clone, Copy, Default)]
pub struct WeatherChange {
pub weather_id: u16,
#[brw(pad_before = 3)]
pub transistion_time: f32,
}