mirror of
https://github.com/redstrate/Kawari.git
synced 2025-05-04 03:57:45 +00:00
Create Inventory struct, move inventory filling logic to ZoneConnection
This still uses hardcoded item ids, but this should much more extensible.
This commit is contained in:
parent
a36c6dff90
commit
8a03c82480
4 changed files with 155 additions and 77 deletions
|
@ -17,7 +17,7 @@ use kawari::world::ipc::{
|
||||||
StatusEffect,
|
StatusEffect,
|
||||||
};
|
};
|
||||||
use kawari::world::{
|
use kawari::world::{
|
||||||
ChatHandler, Zone, ZoneConnection,
|
ChatHandler, Inventory, Zone, ZoneConnection,
|
||||||
ipc::{
|
ipc::{
|
||||||
ActorControl, ActorControlCategory, ActorControlSelf, PlayerEntry, PlayerSetup,
|
ActorControl, ActorControlCategory, ActorControlSelf, PlayerEntry, PlayerSetup,
|
||||||
PlayerSpawn, PlayerStats, SocialList,
|
PlayerSpawn, PlayerStats, SocialList,
|
||||||
|
@ -63,6 +63,7 @@ async fn main() {
|
||||||
spawn_index: 0,
|
spawn_index: 0,
|
||||||
zone: None,
|
zone: None,
|
||||||
position: Position::default(),
|
position: Position::default(),
|
||||||
|
inventory: Inventory::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
@ -85,8 +86,6 @@ async fn main() {
|
||||||
connection.player_data =
|
connection.player_data =
|
||||||
database.find_player_data(actor_id.parse::<u32>().unwrap());
|
database.find_player_data(actor_id.parse::<u32>().unwrap());
|
||||||
|
|
||||||
println!("player data: {:#?}", connection.player_data);
|
|
||||||
|
|
||||||
// We have send THEM a keep alive
|
// We have send THEM a keep alive
|
||||||
{
|
{
|
||||||
connection
|
connection
|
||||||
|
@ -189,75 +188,16 @@ async fn main() {
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
let item_ids = [
|
let chara_details = database
|
||||||
(12, 0x00003b1d),
|
.find_chara_make(connection.player_data.content_id);
|
||||||
(11, 0x0000114a),
|
|
||||||
(10, 0x00003b1c),
|
|
||||||
(9, 0x00003b1a),
|
|
||||||
(8, 0x00003b1b),
|
|
||||||
(7, 0x00000ea7),
|
|
||||||
(6, 0x00000ce1),
|
|
||||||
(4, 0x00000dc1),
|
|
||||||
(3, 0x00000ba8),
|
|
||||||
(0, 0x00000641),
|
|
||||||
];
|
|
||||||
|
|
||||||
// send inventory
|
// fill inventory
|
||||||
{
|
connection.inventory.equip_racial_items(
|
||||||
for (slot, id) in &item_ids {
|
chara_details.chara_make.customize.race,
|
||||||
let ipc = ServerZoneIpcSegment {
|
);
|
||||||
op_code: ServerZoneIpcType::ItemInfo,
|
|
||||||
timestamp: timestamp_secs(),
|
|
||||||
data: ServerZoneIpcData::ItemInfo(ItemInfo {
|
|
||||||
container: ContainerType::Equipped,
|
|
||||||
slot: *slot,
|
|
||||||
quantity: 1,
|
|
||||||
catalog_id: *id,
|
|
||||||
condition: 30000,
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
connection
|
// Send inventory
|
||||||
.send_segment(PacketSegment {
|
connection.send_inventory().await;
|
||||||
source_actor: connection
|
|
||||||
.player_data
|
|
||||||
.actor_id,
|
|
||||||
target_actor: connection
|
|
||||||
.player_data
|
|
||||||
.actor_id,
|
|
||||||
segment_type: SegmentType::Ipc {
|
|
||||||
data: ipc,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// inform the client they have 10 items equipped
|
|
||||||
{
|
|
||||||
let ipc = ServerZoneIpcSegment {
|
|
||||||
op_code: ServerZoneIpcType::ContainerInfo,
|
|
||||||
timestamp: timestamp_secs(),
|
|
||||||
data: ServerZoneIpcData::ContainerInfo(
|
|
||||||
ContainerInfo {
|
|
||||||
container: ContainerType::Equipped,
|
|
||||||
num_items: item_ids.len() as u32,
|
|
||||||
..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: ipc },
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Control Data
|
// Control Data
|
||||||
{
|
{
|
||||||
|
@ -308,11 +248,7 @@ async fn main() {
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
let chara_details = database
|
|
||||||
.find_chara_make(connection.player_data.content_id);
|
|
||||||
|
|
||||||
let zone_id = chara_details.zone_id;
|
let zone_id = chara_details.zone_id;
|
||||||
|
|
||||||
connection.zone = Some(Zone::load(zone_id));
|
connection.zone = Some(Zone::load(zone_id));
|
||||||
|
|
||||||
// Player Setup
|
// Player Setup
|
||||||
|
|
|
@ -9,10 +9,10 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Zone,
|
Inventory, Item, Zone,
|
||||||
ipc::{
|
ipc::{
|
||||||
ActorSetPos, ClientZoneIpcSegment, InitZone, ServerZoneIpcData, ServerZoneIpcSegment,
|
ActorSetPos, ClientZoneIpcSegment, ContainerInfo, ContainerType, InitZone, ItemInfo,
|
||||||
ServerZoneIpcType, UpdateClassInfo, WeatherChange,
|
ServerZoneIpcData, ServerZoneIpcSegment, ServerZoneIpcType, UpdateClassInfo, WeatherChange,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ pub struct ZoneConnection {
|
||||||
pub spawn_index: u8,
|
pub spawn_index: u8,
|
||||||
|
|
||||||
pub position: Position,
|
pub position: Position,
|
||||||
|
pub inventory: Inventory,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ZoneConnection {
|
impl ZoneConnection {
|
||||||
|
@ -169,4 +170,69 @@ impl ZoneConnection {
|
||||||
self.spawn_index += 1;
|
self.spawn_index += 1;
|
||||||
self.spawn_index
|
self.spawn_index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn send_inventory(&mut self) {
|
||||||
|
// item list
|
||||||
|
{
|
||||||
|
let equipped = self.inventory.equipped.clone();
|
||||||
|
|
||||||
|
let mut send_slot = async |slot_index: u16, item: &Item| {
|
||||||
|
let ipc = ServerZoneIpcSegment {
|
||||||
|
op_code: ServerZoneIpcType::ItemInfo,
|
||||||
|
timestamp: timestamp_secs(),
|
||||||
|
data: ServerZoneIpcData::ItemInfo(ItemInfo {
|
||||||
|
container: ContainerType::Equipped,
|
||||||
|
slot: slot_index,
|
||||||
|
quantity: item.quantity,
|
||||||
|
catalog_id: item.id,
|
||||||
|
condition: 30000,
|
||||||
|
..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: ipc },
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
};
|
||||||
|
|
||||||
|
send_slot(0, &equipped.main_hand).await;
|
||||||
|
send_slot(1, &equipped.off_hand).await;
|
||||||
|
send_slot(2, &equipped.head).await;
|
||||||
|
send_slot(3, &equipped.body).await;
|
||||||
|
send_slot(4, &equipped.hands).await;
|
||||||
|
send_slot(6, &equipped.legs).await;
|
||||||
|
send_slot(7, &equipped.feet).await;
|
||||||
|
send_slot(8, &equipped.ears).await;
|
||||||
|
send_slot(9, &equipped.neck).await;
|
||||||
|
send_slot(10, &equipped.wrists).await;
|
||||||
|
send_slot(11, &equipped.right_ring).await;
|
||||||
|
send_slot(12, &equipped.left_ring).await;
|
||||||
|
send_slot(13, &equipped.soul_crystal).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
// inform the client they have items equipped
|
||||||
|
{
|
||||||
|
let ipc = ServerZoneIpcSegment {
|
||||||
|
op_code: ServerZoneIpcType::ContainerInfo,
|
||||||
|
timestamp: timestamp_secs(),
|
||||||
|
data: ServerZoneIpcData::ContainerInfo(ContainerInfo {
|
||||||
|
container: ContainerType::Equipped,
|
||||||
|
num_items: self.inventory.equipped.num_items(),
|
||||||
|
..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: ipc },
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
73
src/world/inventory.rs
Normal file
73
src/world/inventory.rs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#[derive(Default, Copy, Clone)]
|
||||||
|
pub struct Item {
|
||||||
|
pub quantity: u32,
|
||||||
|
pub id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Item {
|
||||||
|
pub fn new(quantity: u32, id: u32) -> Self {
|
||||||
|
Self { quantity, id }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone, Copy)]
|
||||||
|
pub struct EquippedContainer {
|
||||||
|
pub main_hand: Item,
|
||||||
|
pub off_hand: Item,
|
||||||
|
pub head: Item,
|
||||||
|
pub body: Item,
|
||||||
|
pub hands: Item,
|
||||||
|
pub legs: Item,
|
||||||
|
pub feet: Item,
|
||||||
|
pub ears: Item,
|
||||||
|
pub neck: Item,
|
||||||
|
pub wrists: Item,
|
||||||
|
pub right_ring: Item,
|
||||||
|
pub left_ring: Item,
|
||||||
|
pub soul_crystal: Item,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EquippedContainer {
|
||||||
|
pub fn num_items(&self) -> u32 {
|
||||||
|
self.main_hand.quantity
|
||||||
|
+ self.off_hand.quantity
|
||||||
|
+ self.head.quantity
|
||||||
|
+ self.body.quantity
|
||||||
|
+ self.hands.quantity
|
||||||
|
+ self.legs.quantity
|
||||||
|
+ self.feet.quantity
|
||||||
|
+ self.ears.quantity
|
||||||
|
+ self.neck.quantity
|
||||||
|
+ self.wrists.quantity
|
||||||
|
+ self.right_ring.quantity
|
||||||
|
+ self.left_ring.quantity
|
||||||
|
+ self.soul_crystal.quantity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Inventory {
|
||||||
|
pub equipped: EquippedContainer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Inventory {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
equipped: EquippedContainer::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Equip the starting items for a given race
|
||||||
|
pub fn equip_racial_items(&mut self, race_id: u8) {
|
||||||
|
// TODO: don't hardcode
|
||||||
|
self.equipped.main_hand = Item::new(1, 0x00000641);
|
||||||
|
self.equipped.body = Item::new(1, 0x00000ba8);
|
||||||
|
self.equipped.hands = Item::new(1, 0x00000dc1);
|
||||||
|
self.equipped.legs = Item::new(1, 0x00000ce1);
|
||||||
|
self.equipped.feet = Item::new(1, 0x00000ea7);
|
||||||
|
self.equipped.ears = Item::new(1, 0x00003b1b);
|
||||||
|
self.equipped.neck = Item::new(1, 0x00003b1a);
|
||||||
|
self.equipped.wrists = Item::new(1, 0x00003b1c);
|
||||||
|
self.equipped.right_ring = Item::new(1, 0x0000114a);
|
||||||
|
self.equipped.left_ring = Item::new(1, 0x00003b1d);
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,3 +11,6 @@ pub use connection::{PlayerData, ZoneConnection};
|
||||||
|
|
||||||
mod database;
|
mod database;
|
||||||
pub use database::{CharacterData, WorldDatabase};
|
pub use database::{CharacterData, WorldDatabase};
|
||||||
|
|
||||||
|
mod inventory;
|
||||||
|
pub use inventory::{EquippedContainer, Inventory, Item};
|
||||||
|
|
Loading…
Add table
Reference in a new issue