239 lines
7.7 KiB
Rust
239 lines
7.7 KiB
Rust
use libpso::character::character;
|
|
use stats::leveltable::CharacterStats;
|
|
use entity::character::CharacterEntity;
|
|
//use crate::ship::items::{CharacterInventory, CharacterBank};
|
|
use crate::ship::items::bank::BankState;
|
|
use crate::ship::items::inventory::InventoryState;
|
|
use entity::item::Meseta;
|
|
|
|
|
|
#[derive(Default)]
|
|
pub struct CharacterBytesBuilder<'a> {
|
|
character: Option<&'a CharacterEntity>,
|
|
stats: Option<&'a CharacterStats>,
|
|
level: Option<u32>,
|
|
meseta: Option<Meseta>,
|
|
}
|
|
|
|
impl<'a> CharacterBytesBuilder<'a> {
|
|
#[must_use]
|
|
pub fn character(self, character: &'a CharacterEntity) -> CharacterBytesBuilder<'a> {
|
|
CharacterBytesBuilder {
|
|
character: Some(character),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn stats(self, stats: &'a CharacterStats) -> CharacterBytesBuilder<'a> {
|
|
CharacterBytesBuilder {
|
|
stats: Some(stats),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn level(self, level: u32) -> CharacterBytesBuilder<'a> {
|
|
CharacterBytesBuilder {
|
|
level: Some(level),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn meseta(self, meseta: Meseta) -> CharacterBytesBuilder<'a> {
|
|
CharacterBytesBuilder {
|
|
meseta: Some(meseta),
|
|
..self
|
|
}
|
|
}
|
|
|
|
pub fn build(self) -> character::Character {
|
|
let character = self.character.unwrap();
|
|
let stats = self.stats.unwrap();
|
|
let level = self.level.unwrap();
|
|
let meseta = self.meseta.unwrap();
|
|
character::Character {
|
|
name: libpso::utf8_to_utf16_array!(character.name, 16),
|
|
hp: stats.hp,
|
|
atp: stats.atp + character.materials.power as u16 * 2,
|
|
mst: stats.mst + character.materials.mind as u16 * 2,
|
|
evp: stats.evp + character.materials.evade as u16 * 2,
|
|
dfp: stats.dfp + character.materials.def as u16 * 2,
|
|
ata: stats.ata,
|
|
lck: stats.lck + character.materials.luck as u16 * 2,
|
|
level,
|
|
section_id: character.section_id.into(),
|
|
ch_class: character.char_class.into(),
|
|
costume: character.appearance.costume,
|
|
skin: character.appearance.skin,
|
|
face: character.appearance.face,
|
|
head: character.appearance.head,
|
|
hair: character.appearance.hair,
|
|
hair_r: character.appearance.hair_r,
|
|
hair_g: character.appearance.hair_g,
|
|
hair_b: character.appearance.hair_b,
|
|
prop_x: character.appearance.prop_x,
|
|
prop_y: character.appearance.prop_y,
|
|
config: character.config.as_bytes(),
|
|
techniques: character.techs.as_bytes(),
|
|
meseta: meseta.0,
|
|
exp: character.exp,
|
|
..character::Character::default()
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct FullCharacterBytesBuilder<'a> {
|
|
character: Option<&'a CharacterEntity>,
|
|
stats: Option<&'a CharacterStats>,
|
|
level: Option<u32>,
|
|
meseta: Option<Meseta>,
|
|
inventory: Option<&'a InventoryState>,
|
|
bank: Option<&'a BankState>,
|
|
keyboard_config: Option<&'a [u8; 0x16C]>,
|
|
gamepad_config: Option<&'a [u8; 0x38]>,
|
|
symbol_chat: Option<&'a [u8; 1248]>,
|
|
tech_menu: Option<&'a [u8; 40]>,
|
|
option_flags: Option<u32>,
|
|
}
|
|
|
|
impl<'a> FullCharacterBytesBuilder<'a> {
|
|
#[must_use]
|
|
pub fn character(self, character: &'a CharacterEntity) -> FullCharacterBytesBuilder<'a> {
|
|
FullCharacterBytesBuilder {
|
|
character: Some(character),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn stats(self, stats: &'a CharacterStats) -> FullCharacterBytesBuilder<'a> {
|
|
FullCharacterBytesBuilder {
|
|
stats: Some(stats),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn level(self, level: u32) -> FullCharacterBytesBuilder<'a> {
|
|
FullCharacterBytesBuilder {
|
|
level: Some(level),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn meseta(self, meseta: Meseta) -> FullCharacterBytesBuilder<'a> {
|
|
FullCharacterBytesBuilder {
|
|
meseta: Some(meseta),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn inventory(self, inventory: &'a InventoryState) -> FullCharacterBytesBuilder<'a> {
|
|
FullCharacterBytesBuilder {
|
|
inventory: Some(inventory),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn bank(self, bank: &'a BankState) -> FullCharacterBytesBuilder<'a> {
|
|
FullCharacterBytesBuilder {
|
|
bank: Some(bank),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn keyboard_config(self, keyboard_config: &'a [u8; 0x16C]) -> FullCharacterBytesBuilder<'a> {
|
|
FullCharacterBytesBuilder {
|
|
keyboard_config: Some(keyboard_config),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn gamepad_config(self, gamepad_config: &'a [u8; 0x38]) -> FullCharacterBytesBuilder<'a> {
|
|
FullCharacterBytesBuilder {
|
|
gamepad_config: Some(gamepad_config),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn symbol_chat(self, symbol_chat: &'a [u8; 1248]) -> FullCharacterBytesBuilder<'a> {
|
|
FullCharacterBytesBuilder {
|
|
symbol_chat: Some(symbol_chat),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn tech_menu(self, tech_menu: &'a [u8; 40]) -> FullCharacterBytesBuilder<'a> {
|
|
FullCharacterBytesBuilder {
|
|
tech_menu: Some(tech_menu),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn option_flags(self, option_flags: u32) -> FullCharacterBytesBuilder<'a> {
|
|
FullCharacterBytesBuilder {
|
|
option_flags: Some(option_flags),
|
|
..self
|
|
}
|
|
}
|
|
|
|
pub fn build(self) -> character::FullCharacter {
|
|
let character = self.character.unwrap();
|
|
let stats = self.stats.unwrap();
|
|
let level = self.level.unwrap();
|
|
let meseta = self.meseta.unwrap();
|
|
let inventory = self.inventory.unwrap();
|
|
let bank = self.bank.unwrap();
|
|
let keyboard_config = self.keyboard_config.unwrap();
|
|
let gamepad_config = self.gamepad_config.unwrap();
|
|
let symbol_chat = self.symbol_chat.unwrap();
|
|
let tech_menu = self.tech_menu.unwrap();
|
|
let option_flags = self.option_flags.unwrap();
|
|
|
|
let mut inventory_items = inventory.as_client_inventory_items();
|
|
inventory_items[7].material_count = character.materials.power as u8;
|
|
inventory_items[8].material_count = character.materials.mind as u8;
|
|
inventory_items[9].material_count = character.materials.evade as u8;
|
|
inventory_items[10].material_count = character.materials.def as u8;
|
|
inventory_items[11].material_count = character.materials.luck as u8;
|
|
|
|
character::FullCharacter {
|
|
character: CharacterBytesBuilder::default()
|
|
.character(character)
|
|
.stats(stats)
|
|
.level(level - 1)
|
|
.meseta(meseta)
|
|
.build(),
|
|
inventory: character::Inventory {
|
|
item_count: inventory.count() as u8,
|
|
items: inventory_items,
|
|
hp_mats_used: character.materials.hp as u8 * 2,
|
|
tp_mats_used: character.materials.tp as u8 * 2,
|
|
..character::Inventory::default()
|
|
},
|
|
key_team_config: character::KeyTeamConfig {
|
|
keyboard_config: *keyboard_config,
|
|
gamepad_config: *gamepad_config,
|
|
..character::KeyTeamConfig::default()
|
|
},
|
|
info_board: character.info_board.as_bytes(),
|
|
symbol_chats: *symbol_chat,
|
|
tech_menu: *tech_menu,
|
|
bank: bank.as_client_bank_items(),
|
|
option_flags,
|
|
..character::FullCharacter::default()
|
|
}
|
|
}
|
|
}
|