1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-06-07 17:07:46 +00:00

Add UpdateHpMpTp packet, make sprint take away debug monster health

This is just for debugging, I want to make attack actions do this
instead.
This commit is contained in:
Joshua Goins 2025-03-29 12:25:22 -04:00
parent 31c000b823
commit ff3313a0f9
9 changed files with 105 additions and 10 deletions

View file

@ -139,6 +139,11 @@
"name": "EventStart",
"opcode": 955,
"size": 24
},
{
"name": "UpdateHpMpTp",
"opcode": 325,
"size": 8
}
],
"ClientZoneIpcType": [

View file

@ -1,7 +1,10 @@
use std::sync::{Arc, Mutex};
use kawari::common::custom_ipc::{CustomIpcData, CustomIpcSegment, CustomIpcType};
use kawari::common::{Position, determine_initial_starting_zone, get_citystate, get_world_name};
use kawari::common::{
INVALID_OBJECT_ID, ObjectId, Position, determine_initial_starting_zone, get_citystate,
get_world_name,
};
use kawari::common::{get_racial_base_attributes, timestamp_secs};
use kawari::config::get_config;
use kawari::lobby::CharaMake;
@ -77,6 +80,7 @@ async fn main() {
inventory: Inventory::new(),
status_effects: StatusEffects::default(),
event: None,
actors: Vec::new(),
};
let mut lua_player = LuaPlayer::default();
@ -425,8 +429,18 @@ async fn main() {
exit_position = None;
exit_rotation = None;
}
ClientZoneIpcData::Unk1 { .. } => {
tracing::info!("Recieved Unk1!");
ClientZoneIpcData::Unk1 {
category, param1, ..
} => {
tracing::info!("Recieved Unk1! {category:#?}");
match category {
3 => {
// set target
tracing::info!("Targeting actor {param1}");
}
_ => {}
}
}
ClientZoneIpcData::Unk2 { .. } => {
tracing::info!("Recieved Unk2!");
@ -768,6 +782,18 @@ async fn main() {
println!("Found action: {:#?}", action_row);
//if request.target.object_id == INVALID_OBJECT_ID {
if let Some(actor) =
connection.get_actor(ObjectId(0x106ad804))
{
actor.hp -= 50;
let actor = actor.clone();
connection
.update_hp_mp(actor.id, actor.hp, 10000)
.await;
}
//} else {
let lua = lua.lock().unwrap();
lua.scope(|scope| {
let connection_data = scope
@ -782,6 +808,7 @@ async fn main() {
Ok(())
})
.unwrap();
//}
}
ClientZoneIpcData::Unk16 { .. } => {
tracing::info!("Recieved Unk16!");

View file

@ -20,7 +20,7 @@ pub use position::Position;
#[binrw]
#[brw(little)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ObjectId(pub u32);
impl Default for ObjectId {

7
src/world/actor.rs Normal file
View file

@ -0,0 +1,7 @@
use crate::common::ObjectId;
#[derive(Clone, Copy, Debug)]
pub struct Actor {
pub id: ObjectId,
pub hp: u32,
}

View file

@ -4,7 +4,7 @@ use crate::{
opcodes::ServerZoneIpcType,
packet::{PacketSegment, SegmentType},
world::{
Event,
Actor, Event,
ipc::{
ActorControl, ActorControlCategory, BattleNpcSubKind, CommonSpawn, DisplayFlag,
EventStart, NpcSpawn, ObjectKind, OnlineStatus, PlayerSpawn, PlayerSubKind,
@ -235,6 +235,13 @@ impl ChatHandler {
}
}
"!spawnmonster" => {
let actor = Actor {
id: ObjectId(0x106ad804),
hp: 100,
};
connection.add_actor(actor);
// spawn a tiny mandragora
{
let ipc = ServerZoneIpcSegment {

View file

@ -1,7 +1,7 @@
use tokio::net::TcpStream;
use crate::{
common::{Position, timestamp_secs},
common::{ObjectId, Position, timestamp_secs},
opcodes::ServerZoneIpcType,
packet::{
CompressionType, ConnectionType, PacketSegment, PacketState, SegmentType, parse_packet,
@ -10,7 +10,7 @@ use crate::{
};
use super::{
Event, Inventory, Item, LuaPlayer, Zone,
Actor, Event, Inventory, Item, LuaPlayer, Zone,
ipc::{
ActorSetPos, ClientZoneIpcSegment, ContainerInfo, ContainerType, InitZone, ItemInfo,
ServerZoneIpcData, ServerZoneIpcSegment, StatusEffect, StatusEffectList, UpdateClassInfo,
@ -77,6 +77,7 @@ pub struct ZoneConnection {
pub status_effects: StatusEffects,
pub event: Option<Event>,
pub actors: Vec<Actor>,
}
impl ZoneConnection {
@ -337,4 +338,34 @@ impl ZoneConnection {
self.status_effects.dirty = false;
}
}
pub async fn update_hp_mp(&mut self, actor_id: ObjectId, hp: u32, mp: u16) {
let ipc = ServerZoneIpcSegment {
op_code: ServerZoneIpcType::UpdateHpMpTp,
timestamp: timestamp_secs(),
data: ServerZoneIpcData::UpdateHpMpTp { hp, mp, unk: 0 },
..Default::default()
};
self.send_segment(PacketSegment {
source_actor: actor_id.0,
target_actor: actor_id.0,
segment_type: SegmentType::Ipc { data: ipc },
})
.await;
}
pub fn add_actor(&mut self, actor: Actor) {
self.actors.push(actor);
}
pub fn get_actor(&mut self, id: ObjectId) -> Option<&mut Actor> {
for actor in &mut self.actors {
if actor.id == id {
return Some(actor);
}
}
return None;
}
}

View file

@ -1,5 +1,7 @@
use binrw::binrw;
use crate::common::ObjectTypeId;
#[binrw]
#[derive(Debug, Eq, PartialEq, Clone, Default)]
#[brw(repr = u8)]
@ -19,7 +21,7 @@ pub struct ActionRequest {
pub request_id: u32,
pub dir: u16,
pub dir_target: u16,
pub target: u64,
pub target: ObjectTypeId,
pub arg: u32,
pub padding_prob: u32,
}

View file

@ -216,6 +216,12 @@ pub enum ServerZoneIpcData {
EventPlay(EventPlay),
/// Sent to tell the client to load a scene, but not play it
EventStart(EventStart),
/// Sent to update an actor's hp & mp values
UpdateHpMpTp {
hp: u32,
mp: u16,
unk: u16, // it's filled with... something
},
}
#[binrw]
@ -237,8 +243,15 @@ pub enum ClientZoneIpcData {
/// FIXME: 32 bytes of something from the client, not sure what yet
#[br(pre_assert(*magic == ClientZoneIpcType::Unk1))]
Unk1 {
// TODO: full of possibly interesting information
unk: [u8; 32],
// 3 = target
category: u32,
param1: u32,
param2: u32,
param3: u32,
param4: u32,
param5: u32,
param6: u32,
param7: u32,
},
/// FIXME: 16 bytes of something from the client, not sure what yet
#[br(pre_assert(*magic == ClientZoneIpcType::Unk2))]

View file

@ -20,3 +20,6 @@ pub use lua::LuaPlayer;
mod event;
pub use event::Event;
mod actor;
pub use actor::Actor;