mirror of
https://github.com/redstrate/Kawari.git
synced 2025-05-03 11:37: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,
|
||||
};
|
||||
use kawari::world::{
|
||||
ChatHandler, Zone, ZoneConnection,
|
||||
ChatHandler, Inventory, Zone, ZoneConnection,
|
||||
ipc::{
|
||||
ActorControl, ActorControlCategory, ActorControlSelf, PlayerEntry, PlayerSetup,
|
||||
PlayerSpawn, PlayerStats, SocialList,
|
||||
|
@ -63,6 +63,7 @@ async fn main() {
|
|||
spawn_index: 0,
|
||||
zone: None,
|
||||
position: Position::default(),
|
||||
inventory: Inventory::new(),
|
||||
};
|
||||
|
||||
tokio::spawn(async move {
|
||||
|
@ -85,8 +86,6 @@ async fn main() {
|
|||
connection.player_data =
|
||||
database.find_player_data(actor_id.parse::<u32>().unwrap());
|
||||
|
||||
println!("player data: {:#?}", connection.player_data);
|
||||
|
||||
// We have send THEM a keep alive
|
||||
{
|
||||
connection
|
||||
|
@ -189,75 +188,16 @@ async fn main() {
|
|||
.await;
|
||||
}
|
||||
|
||||
let item_ids = [
|
||||
(12, 0x00003b1d),
|
||||
(11, 0x0000114a),
|
||||
(10, 0x00003b1c),
|
||||
(9, 0x00003b1a),
|
||||
(8, 0x00003b1b),
|
||||
(7, 0x00000ea7),
|
||||
(6, 0x00000ce1),
|
||||
(4, 0x00000dc1),
|
||||
(3, 0x00000ba8),
|
||||
(0, 0x00000641),
|
||||
];
|
||||
let chara_details = database
|
||||
.find_chara_make(connection.player_data.content_id);
|
||||
|
||||
// send inventory
|
||||
{
|
||||
for (slot, id) in &item_ids {
|
||||
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()
|
||||
};
|
||||
// fill inventory
|
||||
connection.inventory.equip_racial_items(
|
||||
chara_details.chara_make.customize.race,
|
||||
);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
// Send inventory
|
||||
connection.send_inventory().await;
|
||||
|
||||
// Control Data
|
||||
{
|
||||
|
@ -308,11 +248,7 @@ async fn main() {
|
|||
.await;
|
||||
}
|
||||
|
||||
let chara_details = database
|
||||
.find_chara_make(connection.player_data.content_id);
|
||||
|
||||
let zone_id = chara_details.zone_id;
|
||||
|
||||
connection.zone = Some(Zone::load(zone_id));
|
||||
|
||||
// Player Setup
|
||||
|
|
|
@ -9,10 +9,10 @@ use crate::{
|
|||
};
|
||||
|
||||
use super::{
|
||||
Zone,
|
||||
Inventory, Item, Zone,
|
||||
ipc::{
|
||||
ActorSetPos, ClientZoneIpcSegment, InitZone, ServerZoneIpcData, ServerZoneIpcSegment,
|
||||
ServerZoneIpcType, UpdateClassInfo, WeatherChange,
|
||||
ActorSetPos, ClientZoneIpcSegment, ContainerInfo, ContainerType, InitZone, ItemInfo,
|
||||
ServerZoneIpcData, ServerZoneIpcSegment, ServerZoneIpcType, UpdateClassInfo, WeatherChange,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -34,6 +34,7 @@ pub struct ZoneConnection {
|
|||
pub spawn_index: u8,
|
||||
|
||||
pub position: Position,
|
||||
pub inventory: Inventory,
|
||||
}
|
||||
|
||||
impl ZoneConnection {
|
||||
|
@ -169,4 +170,69 @@ impl ZoneConnection {
|
|||
self.spawn_index += 1;
|
||||
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;
|
||||
pub use database::{CharacterData, WorldDatabase};
|
||||
|
||||
mod inventory;
|
||||
pub use inventory::{EquippedContainer, Inventory, Item};
|
||||
|
|
Loading…
Add table
Reference in a new issue