elseware/src/ship/character.rs

223 lines
7.4 KiB
Rust
Raw Normal View History

2019-12-15 23:18:21 -08:00
use libpso::character::character;
use crate::common::leveltable::CharacterStats;
2020-03-29 12:43:20 -07:00
use crate::entity::character::CharacterEntity;
use crate::ship::items::{CharacterInventory, CharacterBank};
2021-12-26 23:31:12 -07:00
use crate::entity::item::Meseta;
2019-12-15 23:18:21 -08:00
2021-12-28 01:37:24 -07:00
#[derive(Default)]
pub struct CharacterBytesBuilder<'a> {
2020-03-29 12:43:20 -07:00
character: Option<&'a CharacterEntity>,
2019-12-15 23:18:21 -08:00
stats: Option<&'a CharacterStats>,
level: Option<u32>,
2021-12-26 23:31:12 -07:00
meseta: Option<Meseta>,
2019-12-15 23:18:21 -08:00
}
2021-06-18 17:38:36 -06:00
impl<'a> CharacterBytesBuilder<'a> {
2020-03-29 12:43:20 -07:00
pub fn character(self, character: &'a CharacterEntity) -> CharacterBytesBuilder<'a> {
CharacterBytesBuilder {
2019-12-15 23:18:21 -08:00
character: Some(character),
..self
}
}
pub fn stats(self, stats: &'a CharacterStats) -> CharacterBytesBuilder<'a> {
CharacterBytesBuilder {
2019-12-15 23:18:21 -08:00
stats: Some(stats),
..self
}
}
pub fn level(self, level: u32) -> CharacterBytesBuilder<'a> {
CharacterBytesBuilder {
2019-12-15 23:18:21 -08:00
level: Some(level),
..self
}
}
2021-12-26 23:31:12 -07:00
pub fn meseta(self, meseta: Meseta) -> CharacterBytesBuilder<'a> {
CharacterBytesBuilder {
meseta: Some(meseta),
..self
}
}
2019-12-15 23:18:21 -08:00
pub fn build(self) -> character::Character {
let character = self.character.unwrap();
let stats = self.stats.unwrap();
let level = self.level.unwrap();
2021-12-26 23:31:12 -07:00
let meseta = self.meseta.unwrap();
2019-12-15 23:18:21 -08:00
character::Character {
name: libpso::utf8_to_utf16_array!(character.name, 16),
hp: stats.hp,
2020-06-10 21:23:10 -06:00
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,
2019-12-15 23:18:21 -08:00
ata: stats.ata,
2020-06-10 21:23:10 -06:00
lck: stats.lck + character.materials.luck as u16 * 2,
2021-06-18 20:38:29 -06:00
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(),
2021-12-26 23:31:12 -07:00
meseta: meseta.0 as u32,
2020-06-03 18:17:17 -06:00
exp: character.exp,
..character::Character::default()
2019-12-15 23:18:21 -08:00
}
}
}
2021-12-28 01:37:24 -07:00
#[derive(Default)]
pub struct FullCharacterBytesBuilder<'a> {
2020-03-29 12:43:20 -07:00
character: Option<&'a CharacterEntity>,
stats: Option<&'a CharacterStats>,
level: Option<u32>,
2021-12-26 23:31:12 -07:00
meseta: Option<Meseta>,
inventory: Option<&'a CharacterInventory>,
bank: Option<&'a CharacterBank>,
2019-12-15 23:18:21 -08:00
key_config: Option<&'a [u8; 0x16C]>,
joystick_config: Option<&'a [u8; 0x38]>,
2020-04-19 23:16:44 -03:00
symbol_chat: Option<&'a [u8; 1248]>,
2020-04-20 00:29:23 -03:00
tech_menu: Option<&'a [u8; 40]>,
2020-10-02 21:24:32 -03:00
option_flags: Option<u32>,
2019-12-15 23:18:21 -08:00
}
2021-06-18 17:38:36 -06:00
impl<'a> FullCharacterBytesBuilder<'a> {
2020-03-29 12:43:20 -07:00
pub fn character(self, character: &'a CharacterEntity) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
2019-12-15 23:18:21 -08:00
character: Some(character),
..self
}
}
pub fn stats(self, stats: &'a CharacterStats) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
stats: Some(stats),
..self
}
}
pub fn level(self, level: u32) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
level: Some(level),
..self
}
}
2021-12-26 23:31:12 -07:00
pub fn meseta(self, meseta: Meseta) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
meseta: Some(meseta),
..self
}
}
pub fn inventory(self, inventory: &'a CharacterInventory) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
2019-12-15 23:18:21 -08:00
inventory: Some(inventory),
..self
}
}
pub fn bank(self, bank: &'a CharacterBank) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
bank: Some(bank),
..self
}
}
pub fn key_config(self, key_config: &'a [u8; 0x16C]) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
2019-12-15 23:18:21 -08:00
key_config: Some(key_config),
..self
}
}
pub fn joystick_config(self, joystick_config: &'a [u8; 0x38]) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
2019-12-15 23:18:21 -08:00
joystick_config: Some(joystick_config),
..self
}
}
2020-04-19 23:16:44 -03:00
pub fn symbol_chat(self, symbol_chat: &'a [u8; 1248]) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
symbol_chat: Some(symbol_chat),
..self
}
}
2020-04-20 00:29:23 -03:00
pub fn tech_menu(self, tech_menu: &'a [u8; 40]) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
tech_menu: Some(tech_menu),
..self
}
}
2020-10-02 21:24:32 -03:00
pub fn option_flags(self, option_flags: u32) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
option_flags: Some(option_flags),
..self
}
}
2019-12-15 23:18:21 -08:00
pub fn build(self) -> character::FullCharacter {
let character = self.character.unwrap();
let stats = self.stats.unwrap();
let level = self.level.unwrap();
2021-12-26 23:31:12 -07:00
let meseta = self.meseta.unwrap();
2019-12-15 23:18:21 -08:00
let inventory = self.inventory.unwrap();
let bank = self.bank.unwrap();
2019-12-15 23:18:21 -08:00
let key_config = self.key_config.unwrap();
let joystick_config = self.joystick_config.unwrap();
2020-04-19 23:16:44 -03:00
let symbol_chat = self.symbol_chat.unwrap();
2020-04-20 00:29:23 -03:00
let tech_menu = self.tech_menu.unwrap();
2020-10-02 21:24:32 -03:00
let option_flags = self.option_flags.unwrap();
2020-06-10 21:23:10 -06:00
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;
2019-12-15 23:18:21 -08:00
character::FullCharacter {
2021-06-18 17:38:36 -06:00
character: CharacterBytesBuilder::default()
.character(character)
.stats(stats)
.level(level - 1)
2021-12-26 23:31:12 -07:00
.meseta(meseta)
.build(),
2019-12-15 23:18:21 -08:00
inventory: character::Inventory {
item_count: inventory.count() as u8,
2020-06-10 21:23:10 -06:00
items: inventory_items,
hp_mats_used: character.materials.hp as u8 * 2,
tp_mats_used: character.materials.tp as u8 * 2,
2019-12-15 23:18:21 -08:00
..character::Inventory::default()
},
key_team_config: character::KeyTeamConfig {
key_config: *key_config,
joystick_config: *joystick_config,
..character::KeyTeamConfig::default()
},
2020-03-01 02:57:18 -04:00
info_board: character.info_board.as_bytes(),
2020-04-19 23:16:44 -03:00
symbol_chats: *symbol_chat,
2020-04-20 00:29:23 -03:00
tech_menu: *tech_menu,
bank: bank.as_client_bank_items(),
2021-06-18 20:38:29 -06:00
option_flags,
2019-12-15 23:18:21 -08:00
..character::FullCharacter::default()
}
}
}