implement db backing for items and send them to client
This commit is contained in:
parent
f8af4ab3a1
commit
2010222c9b
src
entity
login
ship
@ -41,7 +41,7 @@ pub trait EntityGateway {
|
|||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_item(&mut self, _item: item::Item, _location: ItemLocation) -> Item {
|
fn new_item(&mut self, _item: ItemDetail, _location: ItemLocation) -> Item {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ pub struct InMemoryGateway {
|
|||||||
user_settings: Arc<Mutex<HashMap<u32, UserSettings>>>,
|
user_settings: Arc<Mutex<HashMap<u32, UserSettings>>>,
|
||||||
//guildcard: Arc<Mutex<HashMap<u32, GuildCardData>>>,
|
//guildcard: Arc<Mutex<HashMap<u32, GuildCardData>>>,
|
||||||
characters: Arc<Mutex<HashMap<u32, Character>>>,
|
characters: Arc<Mutex<HashMap<u32, Character>>>,
|
||||||
items: Arc<Mutex<HashMap<u32, Item>>>,
|
items: Arc<Mutex<HashMap<ItemEntityId, Item>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InMemoryGateway {
|
impl InMemoryGateway {
|
||||||
@ -106,18 +106,18 @@ impl EntityGateway for InMemoryGateway {
|
|||||||
GuildCardData::default()
|
GuildCardData::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_item(&mut self, item: item::Item, location: ItemLocation) -> Item {
|
fn new_item(&mut self, item: ItemDetail, location: ItemLocation) -> Item {
|
||||||
let mut items = self.items.lock().unwrap();
|
let mut items = self.items.lock().unwrap();
|
||||||
let id = items
|
let id = items
|
||||||
.iter()
|
.iter()
|
||||||
.fold(0, |sum, (i, _)| std::cmp::max(sum, *i))
|
.fold(0, |sum, (i, _)| std::cmp::max(sum, i.0))
|
||||||
+ 1;
|
+ 1;
|
||||||
let new_item = Item {
|
let new_item = Item {
|
||||||
id: id,
|
id: ItemEntityId(id),
|
||||||
location: location,
|
location: location,
|
||||||
item: item,
|
item: item,
|
||||||
};
|
};
|
||||||
items.insert(id, new_item.clone());
|
items.insert(ItemEntityId(id), new_item.clone());
|
||||||
new_item
|
new_item
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,11 +131,10 @@ impl EntityGateway for InMemoryGateway {
|
|||||||
items
|
items
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, k)| {
|
.filter(|(_, k)| {
|
||||||
if let ItemLocation::Inventory{character_id, index} = k.location {
|
match k.location {
|
||||||
character_id == character.id
|
ItemLocation::Inventory{character_id, ..} => character_id == character.id,
|
||||||
}
|
ItemLocation::Bank{character_id, ..} => character_id == character.id,
|
||||||
else {
|
_ => false
|
||||||
false
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|(_, k)| {
|
.map(|(_, k)| {
|
||||||
@ -143,5 +142,4 @@ impl EntityGateway for InMemoryGateway {
|
|||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
use libpso::item;
|
use libpso::item;
|
||||||
|
use libpso::character::character;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(PartialEq, Copy, Clone, Debug, Hash, Eq)]
|
||||||
|
pub struct ItemEntityId(pub u32);
|
||||||
|
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
|
||||||
|
pub struct ItemId(u32);
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum ItemLocation {
|
pub enum ItemLocation {
|
||||||
Inventory {
|
Inventory {
|
||||||
character_id: u32,
|
character_id: u32,
|
||||||
@ -9,7 +16,7 @@ pub enum ItemLocation {
|
|||||||
},
|
},
|
||||||
Bank {
|
Bank {
|
||||||
character_id: u32,
|
character_id: u32,
|
||||||
slot: usize
|
slot: usize,
|
||||||
},
|
},
|
||||||
Floor {
|
Floor {
|
||||||
// floor: eventually
|
// floor: eventually
|
||||||
@ -19,9 +26,67 @@ pub enum ItemLocation {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Item {
|
pub struct Weapon {
|
||||||
pub id: u32,
|
pub equipped: bool,
|
||||||
pub location: ItemLocation,
|
pub weapon: item::weapon::Weapon,
|
||||||
pub item: item::Item,
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct Armor {
|
||||||
|
pub equipped: bool,
|
||||||
|
pub armor: item::armor::Armor,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct Shield {
|
||||||
|
pub equipped: bool,
|
||||||
|
pub shield: item::shield::Shield,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct Tool {
|
||||||
|
pub tool: item::tool::ToolType,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tool {
|
||||||
|
pub fn as_bytes(&self) -> [u8; 16] {
|
||||||
|
let mut result = [0; 16];
|
||||||
|
result[0..3].copy_from_slice(&self.tool.value());
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum ItemDetail {
|
||||||
|
Weapon(Weapon),
|
||||||
|
Armor(Armor),
|
||||||
|
Shield(Shield),
|
||||||
|
Tool(Tool),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ItemDetail {
|
||||||
|
pub fn is_stackable(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
ItemDetail::Tool(tool) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_bytes(&self) -> [u8; 16] {
|
||||||
|
match self {
|
||||||
|
ItemDetail::Weapon(weapon) => weapon.weapon.as_bytes(),
|
||||||
|
ItemDetail::Armor(armor) => armor.armor.as_bytes(),
|
||||||
|
ItemDetail::Shield(shield) => shield.shield.as_bytes(),
|
||||||
|
ItemDetail::Tool(tool) => tool.as_bytes(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct Item {
|
||||||
|
pub id: ItemEntityId,
|
||||||
|
pub location: ItemLocation,
|
||||||
|
pub item: ItemDetail,
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ use crc::{crc32, Hasher32};
|
|||||||
use libpso::packet::login::*;
|
use libpso::packet::login::*;
|
||||||
use libpso::{PacketParseError, PSOPacket};
|
use libpso::{PacketParseError, PSOPacket};
|
||||||
use libpso::crypto::bb::PSOBBCipher;
|
use libpso::crypto::bb::PSOBBCipher;
|
||||||
|
use libpso::item;
|
||||||
|
|
||||||
use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY};
|
use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY};
|
||||||
use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId};
|
use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId};
|
||||||
@ -15,6 +16,7 @@ use libpso::{utf8_to_array, utf8_to_utf16_array};
|
|||||||
|
|
||||||
use crate::entity::gateway::EntityGateway;
|
use crate::entity::gateway::EntityGateway;
|
||||||
use crate::entity::account::{UserAccount, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM};
|
use crate::entity::account::{UserAccount, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM};
|
||||||
|
use crate::entity::item::{ItemDetail, ItemLocation, Weapon, Armor, Shield, Tool};
|
||||||
use crate::entity::character::Character;
|
use crate::entity::character::Character;
|
||||||
|
|
||||||
use crate::login::login::get_login_status;
|
use crate::login::login::get_login_status;
|
||||||
@ -188,6 +190,68 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccount,
|
|||||||
char.slot = preview.slot;
|
char.slot = preview.slot;
|
||||||
char.character = preview.character.as_character();
|
char.character = preview.character.as_character();
|
||||||
entity_gateway.set_character(&char);
|
entity_gateway.set_character(&char);
|
||||||
|
|
||||||
|
let new_weapon = match char.character.ch_class {
|
||||||
|
0 | 1 | 2 | 9 => item::weapon::WeaponType::Saber,
|
||||||
|
3 | 4 | 5 | 11 => item::weapon::WeaponType::Handgun,
|
||||||
|
6 | 7 | 8 | 10 => item::weapon::WeaponType::Cane,
|
||||||
|
_ => panic!()
|
||||||
|
};
|
||||||
|
|
||||||
|
entity_gateway.new_item(
|
||||||
|
ItemDetail::Weapon(
|
||||||
|
Weapon {
|
||||||
|
equipped: true,
|
||||||
|
weapon: item::weapon::Weapon {
|
||||||
|
weapon: new_weapon,
|
||||||
|
grind: 0,
|
||||||
|
special: None,
|
||||||
|
attrs: [None; 3]
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
ItemLocation::Inventory {
|
||||||
|
character_id: char.id,
|
||||||
|
index: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
entity_gateway.new_item(
|
||||||
|
ItemDetail::Armor (
|
||||||
|
Armor {
|
||||||
|
equipped: true,
|
||||||
|
armor: item::armor::Armor {
|
||||||
|
armor: item::armor::ArmorType::Frame,
|
||||||
|
dfp: 0,
|
||||||
|
evp: 0,
|
||||||
|
slots: 0,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
ItemLocation::Inventory {
|
||||||
|
character_id: char.id,
|
||||||
|
index: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
for _ in 0..4 {
|
||||||
|
entity_gateway.new_item(
|
||||||
|
ItemDetail::Tool (
|
||||||
|
Tool {
|
||||||
|
tool: item::tool::ToolType::Monomate,
|
||||||
|
}),
|
||||||
|
ItemLocation::Inventory {
|
||||||
|
character_id: char.id,
|
||||||
|
index: 2,
|
||||||
|
});
|
||||||
|
entity_gateway.new_item(
|
||||||
|
ItemDetail::Tool (
|
||||||
|
Tool {
|
||||||
|
tool: item::tool::ToolType::Monofluid,
|
||||||
|
}),
|
||||||
|
ItemLocation::Inventory {
|
||||||
|
character_id: char.id,
|
||||||
|
index: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: starter mag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::common::leveltable::CharacterStats;
|
use crate::common::leveltable::CharacterStats;
|
||||||
use libpso::character::character;
|
use libpso::character::character;
|
||||||
|
use crate::ship::items::Inventory;
|
||||||
|
|
||||||
|
|
||||||
pub struct CharacterBuilder<'a> {
|
pub struct CharacterBuilder<'a> {
|
||||||
@ -60,8 +61,7 @@ impl<'a> CharacterBuilder<'a> {
|
|||||||
|
|
||||||
pub struct FullCharacterBuilder<'a> {
|
pub struct FullCharacterBuilder<'a> {
|
||||||
character: Option<&'a character::Character>,
|
character: Option<&'a character::Character>,
|
||||||
inventory: Option<&'a [character::InventoryItem; 30]>,
|
inventory: Option<&'a Inventory>,
|
||||||
inventory_len: Option<usize>,
|
|
||||||
key_config: Option<&'a [u8; 0x16C]>,
|
key_config: Option<&'a [u8; 0x16C]>,
|
||||||
joystick_config: Option<&'a [u8; 0x38]>,
|
joystick_config: Option<&'a [u8; 0x38]>,
|
||||||
}
|
}
|
||||||
@ -72,7 +72,6 @@ impl<'a> FullCharacterBuilder<'a> {
|
|||||||
FullCharacterBuilder {
|
FullCharacterBuilder {
|
||||||
character: None,
|
character: None,
|
||||||
inventory: None,
|
inventory: None,
|
||||||
inventory_len: None,
|
|
||||||
key_config: None,
|
key_config: None,
|
||||||
joystick_config: None,
|
joystick_config: None,
|
||||||
}
|
}
|
||||||
@ -85,10 +84,9 @@ impl<'a> FullCharacterBuilder<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inventory(self, inventory: &'a [character::InventoryItem; 30], len: usize) -> FullCharacterBuilder<'a> {
|
pub fn inventory(self, inventory: &'a Inventory) -> FullCharacterBuilder<'a> {
|
||||||
FullCharacterBuilder {
|
FullCharacterBuilder {
|
||||||
inventory: Some(inventory),
|
inventory: Some(inventory),
|
||||||
inventory_len: Some(len),
|
|
||||||
..self
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,15 +108,14 @@ impl<'a> FullCharacterBuilder<'a> {
|
|||||||
pub fn build(self) -> character::FullCharacter {
|
pub fn build(self) -> character::FullCharacter {
|
||||||
let character = self.character.unwrap();
|
let character = self.character.unwrap();
|
||||||
let inventory = self.inventory.unwrap();
|
let inventory = self.inventory.unwrap();
|
||||||
let inventory_len = self.inventory_len.unwrap();
|
|
||||||
let key_config = self.key_config.unwrap();
|
let key_config = self.key_config.unwrap();
|
||||||
let joystick_config = self.joystick_config.unwrap();
|
let joystick_config = self.joystick_config.unwrap();
|
||||||
|
|
||||||
character::FullCharacter {
|
character::FullCharacter {
|
||||||
character: *character,
|
character: *character,
|
||||||
inventory: character::Inventory {
|
inventory: character::Inventory {
|
||||||
item_count: inventory_len as u8,
|
item_count: inventory.count() as u8,
|
||||||
items: *inventory,
|
items: inventory.as_client_inventory_items(),
|
||||||
..character::Inventory::default()
|
..character::Inventory::default()
|
||||||
},
|
},
|
||||||
key_team_config: character::KeyTeamConfig {
|
key_team_config: character::KeyTeamConfig {
|
||||||
|
@ -289,7 +289,7 @@ impl ClientLocation {
|
|||||||
self.rooms.iter_mut()
|
self.rooms.iter_mut()
|
||||||
.filter(|lobby| lobby.is_some())
|
.filter(|lobby| lobby.is_some())
|
||||||
.map(|lobby| lobby.as_ref().unwrap())
|
.map(|lobby| lobby.as_ref().unwrap())
|
||||||
.map(|mut lobby| lobby.write().unwrap().remove(id))
|
.map(|lobby| lobby.write().unwrap().remove(id))
|
||||||
.any(|k| k);
|
.any(|k| k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,3 +2,4 @@ pub mod ship;
|
|||||||
pub mod location;
|
pub mod location;
|
||||||
pub mod character;
|
pub mod character;
|
||||||
pub mod room;
|
pub mod room;
|
||||||
|
pub mod items;
|
||||||
|
@ -17,10 +17,11 @@ use crate::common::leveltable::CharacterLevelTable;
|
|||||||
use crate::entity::gateway::EntityGateway;
|
use crate::entity::gateway::EntityGateway;
|
||||||
use crate::entity::account::{UserAccount, UserSettings, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM};
|
use crate::entity::account::{UserAccount, UserSettings, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM};
|
||||||
use crate::entity::character::Character;
|
use crate::entity::character::Character;
|
||||||
use crate::entity::item::ItemLocation;
|
use crate::entity::item::{ItemLocation, Item};
|
||||||
use crate::login::login::get_login_status;
|
use crate::login::login::get_login_status;
|
||||||
use crate::ship::location::{ClientLocation, LobbyId, RoomId, AreaType, MAX_ROOMS};
|
use crate::ship::location::{ClientLocation, LobbyId, RoomId, AreaType, MAX_ROOMS};
|
||||||
use crate::ship::character::{CharacterBuilder, FullCharacterBuilder};
|
use crate::ship::character::{CharacterBuilder, FullCharacterBuilder};
|
||||||
|
use crate::ship::items;
|
||||||
use crate::ship::room;
|
use crate::ship::room;
|
||||||
|
|
||||||
pub const SHIP_PORT: u16 = 23423;
|
pub const SHIP_PORT: u16 = 23423;
|
||||||
@ -109,24 +110,31 @@ struct ClientState {
|
|||||||
settings: UserSettings,
|
settings: UserSettings,
|
||||||
character: Character,
|
character: Character,
|
||||||
session: Session,
|
session: Session,
|
||||||
|
inventory: items::Inventory,
|
||||||
|
//bank: Bank,
|
||||||
block: u32,
|
block: u32,
|
||||||
room_client_id: u32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClientState {
|
impl ClientState {
|
||||||
fn new(user: UserAccount, settings: UserSettings, character: Character, session: Session) -> ClientState {
|
fn new(user: UserAccount, settings: UserSettings, character: Character, inventory: items::Inventory, /*bank: Bank,*/ session: Session) -> ClientState {
|
||||||
ClientState {
|
ClientState {
|
||||||
user: user,
|
user: user,
|
||||||
settings: settings,
|
settings: settings,
|
||||||
character: character,
|
character: character,
|
||||||
session: session,
|
session: session,
|
||||||
|
inventory: inventory,
|
||||||
|
//bank: bank,
|
||||||
block: 1,
|
block: 1,
|
||||||
room_client_id: 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub struct ShipServerState<EG: EntityGateway> {
|
pub struct ShipServerState<EG: EntityGateway> {
|
||||||
entity_gateway: EG,
|
entity_gateway: EG,
|
||||||
clients: HashMap<ClientId, ClientState>,
|
clients: HashMap<ClientId, ClientState>,
|
||||||
@ -134,6 +142,7 @@ pub struct ShipServerState<EG: EntityGateway> {
|
|||||||
level_table: CharacterLevelTable,
|
level_table: CharacterLevelTable,
|
||||||
name: String,
|
name: String,
|
||||||
rooms: [Option<room::RoomState>; MAX_ROOMS],
|
rooms: [Option<room::RoomState>; MAX_ROOMS],
|
||||||
|
item_activator: items::ItemActivator,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EG: EntityGateway> ShipServerState<EG> {
|
impl<EG: EntityGateway> ShipServerState<EG> {
|
||||||
@ -145,6 +154,7 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
|||||||
level_table: CharacterLevelTable::new(),
|
level_table: CharacterLevelTable::new(),
|
||||||
name: "Sona-Nyl".into(),
|
name: "Sona-Nyl".into(),
|
||||||
rooms: [None; MAX_ROOMS],
|
rooms: [None; MAX_ROOMS],
|
||||||
|
item_activator: items::ItemActivator::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +172,13 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
|||||||
let settings = self.entity_gateway.get_user_settings_by_user(&user)
|
let settings = self.entity_gateway.get_user_settings_by_user(&user)
|
||||||
.ok_or(ShipError::ClientNotFound(id))?;
|
.ok_or(ShipError::ClientNotFound(id))?;
|
||||||
|
|
||||||
self.clients.insert(id, ClientState::new(user, settings, character, pkt.session));
|
let items = self.entity_gateway.get_items_by_character(&character);
|
||||||
|
let (inventory, bank) = items::split_items_into_inventory_and_bank(items);
|
||||||
|
let stacked_items = items::stack_items(inventory);
|
||||||
|
let activated_items = stacked_items.into_iter().map(|item| self.item_activator.activate_item(item)).collect();
|
||||||
|
let inventory = items::Inventory::new(activated_items);
|
||||||
|
|
||||||
|
self.clients.insert(id, ClientState::new(user, settings, character, inventory, pkt.session));
|
||||||
vec![SendShipPacket::LoginResponse(response), SendShipPacket::ShipBlockList(ShipBlockList::new(&self.name, 3))]
|
vec![SendShipPacket::LoginResponse(response), SendShipPacket::ShipBlockList(ShipBlockList::new(&self.name, 3))]
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -177,34 +193,15 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
|||||||
|
|
||||||
let (level, stats) = self.level_table.get_stats_from_exp(character::Class::from(client.character.character.ch_class), client.character.character.exp);
|
let (level, stats) = self.level_table.get_stats_from_exp(character::Class::from(client.character.character.ch_class), client.character.character.exp);
|
||||||
|
|
||||||
let items = self.entity_gateway.get_items_by_character(&client.character);
|
|
||||||
let (inventory, inv_len) = items
|
|
||||||
.iter()
|
|
||||||
.take(30)
|
|
||||||
.fold(([character::InventoryItem::default(); 30], 0), |(mut inv, len), item| {
|
|
||||||
let index = {
|
|
||||||
if let ItemLocation::Inventory{index, .. } = item.location {
|
|
||||||
index
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
panic!("inventory item that isnt in inventory???");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let bytes = item.item.as_bytes();
|
|
||||||
inv[index].data1.copy_from_slice(&bytes[0..12]);
|
|
||||||
inv[index].item_id = item.id;
|
|
||||||
(inv, len+1)
|
|
||||||
});
|
|
||||||
let fc = FullCharacterBuilder::new()
|
let fc = FullCharacterBuilder::new()
|
||||||
.character(&CharacterBuilder::new()
|
.character(&CharacterBuilder::new()
|
||||||
.character(&client.character.character)
|
.character(&client.character.character)
|
||||||
.stats(&stats)
|
.stats(&stats)
|
||||||
.level(level - 1)
|
.level(level - 1)
|
||||||
.build())
|
.build())
|
||||||
.inventory(&inventory, inv_len)
|
.inventory(&client.inventory)
|
||||||
.key_config(&client.settings.settings.key_config)
|
.key_config(&client.settings.settings.key_config)
|
||||||
.joystick_config(&client.settings.settings.joystick_config)
|
.joystick_config(&client.settings.settings.joystick_config)
|
||||||
//.team_config(&joystick_config)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
|
Loading…
x
Reference in New Issue
Block a user