You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
7.6 KiB

2 years ago
3 years ago
2 years ago
2 years ago
4 years ago
4 years ago
2 years ago
3 years ago
2 years ago
2 years ago
2 years ago
4 years ago
3 years ago
2 years ago
4 years ago
4 years ago
  1. use libpso::character::character;
  2. use stats::leveltable::CharacterStats;
  3. use entity::character::CharacterEntity;
  4. use items::bank::BankState;
  5. use items::inventory::InventoryState;
  6. use entity::item::Meseta;
  7. #[derive(Default)]
  8. pub struct CharacterBytesBuilder<'a> {
  9. character: Option<&'a CharacterEntity>,
  10. stats: Option<&'a CharacterStats>,
  11. level: Option<u32>,
  12. meseta: Option<Meseta>,
  13. }
  14. impl<'a> CharacterBytesBuilder<'a> {
  15. #[must_use]
  16. pub fn character(self, character: &'a CharacterEntity) -> CharacterBytesBuilder<'a> {
  17. CharacterBytesBuilder {
  18. character: Some(character),
  19. ..self
  20. }
  21. }
  22. #[must_use]
  23. pub fn stats(self, stats: &'a CharacterStats) -> CharacterBytesBuilder<'a> {
  24. CharacterBytesBuilder {
  25. stats: Some(stats),
  26. ..self
  27. }
  28. }
  29. #[must_use]
  30. pub fn level(self, level: u32) -> CharacterBytesBuilder<'a> {
  31. CharacterBytesBuilder {
  32. level: Some(level),
  33. ..self
  34. }
  35. }
  36. #[must_use]
  37. pub fn meseta(self, meseta: Meseta) -> CharacterBytesBuilder<'a> {
  38. CharacterBytesBuilder {
  39. meseta: Some(meseta),
  40. ..self
  41. }
  42. }
  43. pub fn build(self) -> character::Character {
  44. let character = self.character.unwrap();
  45. let stats = self.stats.unwrap();
  46. let level = self.level.unwrap();
  47. let meseta = self.meseta.unwrap();
  48. character::Character {
  49. name: libpso::utf8_to_utf16_array!(character.name, 16),
  50. hp: stats.hp,
  51. atp: stats.atp + character.materials.power as u16 * 2,
  52. mst: stats.mst + character.materials.mind as u16 * 2,
  53. evp: stats.evp + character.materials.evade as u16 * 2,
  54. dfp: stats.dfp + character.materials.def as u16 * 2,
  55. ata: stats.ata,
  56. lck: stats.lck + character.materials.luck as u16 * 2,
  57. level,
  58. section_id: character.section_id.into(),
  59. ch_class: character.char_class.into(),
  60. costume: character.appearance.costume,
  61. skin: character.appearance.skin,
  62. face: character.appearance.face,
  63. head: character.appearance.head,
  64. hair: character.appearance.hair,
  65. hair_r: character.appearance.hair_r,
  66. hair_g: character.appearance.hair_g,
  67. hair_b: character.appearance.hair_b,
  68. prop_x: character.appearance.prop_x,
  69. prop_y: character.appearance.prop_y,
  70. config: character.config.as_bytes(),
  71. techniques: character.techs.as_bytes(),
  72. meseta: meseta.0,
  73. exp: character.exp,
  74. ..character::Character::default()
  75. }
  76. }
  77. }
  78. #[derive(Default)]
  79. pub struct FullCharacterBytesBuilder<'a> {
  80. character: Option<&'a CharacterEntity>,
  81. stats: Option<&'a CharacterStats>,
  82. level: Option<u32>,
  83. meseta: Option<Meseta>,
  84. inventory: Option<&'a InventoryState>,
  85. bank: Option<&'a BankState>,
  86. keyboard_config: Option<&'a [u8; 0x16C]>,
  87. gamepad_config: Option<&'a [u8; 0x38]>,
  88. symbol_chat: Option<&'a [u8; 1248]>,
  89. tech_menu: Option<&'a [u8; 40]>,
  90. option_flags: Option<u32>,
  91. }
  92. impl<'a> FullCharacterBytesBuilder<'a> {
  93. #[must_use]
  94. pub fn character(self, character: &'a CharacterEntity) -> FullCharacterBytesBuilder<'a> {
  95. FullCharacterBytesBuilder {
  96. character: Some(character),
  97. ..self
  98. }
  99. }
  100. #[must_use]
  101. pub fn stats(self, stats: &'a CharacterStats) -> FullCharacterBytesBuilder<'a> {
  102. FullCharacterBytesBuilder {
  103. stats: Some(stats),
  104. ..self
  105. }
  106. }
  107. #[must_use]
  108. pub fn level(self, level: u32) -> FullCharacterBytesBuilder<'a> {
  109. FullCharacterBytesBuilder {
  110. level: Some(level),
  111. ..self
  112. }
  113. }
  114. #[must_use]
  115. pub fn meseta(self, meseta: Meseta) -> FullCharacterBytesBuilder<'a> {
  116. FullCharacterBytesBuilder {
  117. meseta: Some(meseta),
  118. ..self
  119. }
  120. }
  121. #[must_use]
  122. pub fn inventory(self, inventory: &'a InventoryState) -> FullCharacterBytesBuilder<'a> {
  123. FullCharacterBytesBuilder {
  124. inventory: Some(inventory),
  125. ..self
  126. }
  127. }
  128. #[must_use]
  129. pub fn bank(self, bank: &'a BankState) -> FullCharacterBytesBuilder<'a> {
  130. FullCharacterBytesBuilder {
  131. bank: Some(bank),
  132. ..self
  133. }
  134. }
  135. #[must_use]
  136. pub fn keyboard_config(self, keyboard_config: &'a [u8; 0x16C]) -> FullCharacterBytesBuilder<'a> {
  137. FullCharacterBytesBuilder {
  138. keyboard_config: Some(keyboard_config),
  139. ..self
  140. }
  141. }
  142. #[must_use]
  143. pub fn gamepad_config(self, gamepad_config: &'a [u8; 0x38]) -> FullCharacterBytesBuilder<'a> {
  144. FullCharacterBytesBuilder {
  145. gamepad_config: Some(gamepad_config),
  146. ..self
  147. }
  148. }
  149. #[must_use]
  150. pub fn symbol_chat(self, symbol_chat: &'a [u8; 1248]) -> FullCharacterBytesBuilder<'a> {
  151. FullCharacterBytesBuilder {
  152. symbol_chat: Some(symbol_chat),
  153. ..self
  154. }
  155. }
  156. #[must_use]
  157. pub fn tech_menu(self, tech_menu: &'a [u8; 40]) -> FullCharacterBytesBuilder<'a> {
  158. FullCharacterBytesBuilder {
  159. tech_menu: Some(tech_menu),
  160. ..self
  161. }
  162. }
  163. #[must_use]
  164. pub fn option_flags(self, option_flags: u32) -> FullCharacterBytesBuilder<'a> {
  165. FullCharacterBytesBuilder {
  166. option_flags: Some(option_flags),
  167. ..self
  168. }
  169. }
  170. pub fn build(self) -> character::FullCharacter {
  171. let character = self.character.unwrap();
  172. let stats = self.stats.unwrap();
  173. let level = self.level.unwrap();
  174. let meseta = self.meseta.unwrap();
  175. let inventory = self.inventory.unwrap();
  176. let bank = self.bank.unwrap();
  177. let keyboard_config = self.keyboard_config.unwrap();
  178. let gamepad_config = self.gamepad_config.unwrap();
  179. let symbol_chat = self.symbol_chat.unwrap();
  180. let tech_menu = self.tech_menu.unwrap();
  181. let option_flags = self.option_flags.unwrap();
  182. let mut inventory_items = inventory.as_client_inventory_items();
  183. inventory_items[7].material_count = character.materials.power as u8;
  184. inventory_items[8].material_count = character.materials.mind as u8;
  185. inventory_items[9].material_count = character.materials.evade as u8;
  186. inventory_items[10].material_count = character.materials.def as u8;
  187. inventory_items[11].material_count = character.materials.luck as u8;
  188. character::FullCharacter {
  189. character: CharacterBytesBuilder::default()
  190. .character(character)
  191. .stats(stats)
  192. .level(level - 1)
  193. .meseta(meseta)
  194. .build(),
  195. inventory: character::Inventory {
  196. item_count: inventory.count() as u8,
  197. items: inventory_items,
  198. hp_mats_used: character.materials.hp as u8 * 2,
  199. tp_mats_used: character.materials.tp as u8 * 2,
  200. ..character::Inventory::default()
  201. },
  202. key_team_config: character::KeyTeamConfig {
  203. keyboard_config: *keyboard_config,
  204. gamepad_config: *gamepad_config,
  205. ..character::KeyTeamConfig::default()
  206. },
  207. info_board: character.info_board.as_bytes(),
  208. symbol_chats: *symbol_chat,
  209. tech_menu: *tech_menu,
  210. bank: bank.as_client_bank_items(),
  211. option_flags,
  212. ..character::FullCharacter::default()
  213. }
  214. }
  215. }