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.

416 lines
11 KiB

5 years ago
5 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
  1. use std::convert::{From, Into};
  2. use std::collections::HashMap;
  3. use serde::{Serialize, Deserialize};
  4. use libpso::packet::ship::{UpdateConfig, WriteInfoboard, KeyboardConfig, GamepadConfig};
  5. use libpso::character::settings::{DEFAULT_PALETTE_CONFIG, DEFAULT_TECH_MENU, DEFAULT_KEYBOARD_CONFIG1, DEFAULT_KEYBOARD_CONFIG2, DEFAULT_KEYBOARD_CONFIG3, DEFAULT_KEYBOARD_CONFIG4, DEFAULT_GAMEPAD_CONFIG};
  6. use crate::entity::item::tech::Technique;
  7. use crate::entity::account::UserAccountId;
  8. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, enum_utils::FromStr, derive_more::Display, Serialize, Deserialize, Default)]
  9. pub enum CharacterClass {
  10. #[default]
  11. HUmar,
  12. HUnewearl,
  13. HUcast,
  14. HUcaseal,
  15. RAmar,
  16. RAmarl,
  17. RAcast,
  18. RAcaseal,
  19. FOmar,
  20. FOmarl,
  21. FOnewm,
  22. FOnewearl,
  23. }
  24. // TODO: TryFrom
  25. impl From<u8> for CharacterClass {
  26. fn from(f: u8) -> CharacterClass {
  27. match f {
  28. 0 => CharacterClass::HUmar,
  29. 1 => CharacterClass::HUnewearl,
  30. 2 => CharacterClass::HUcast,
  31. 3 => CharacterClass::RAmar,
  32. 4 => CharacterClass::RAcast,
  33. 5 => CharacterClass::RAcaseal,
  34. 6 => CharacterClass::FOmarl,
  35. 7 => CharacterClass::FOnewm,
  36. 8 => CharacterClass::FOnewearl,
  37. 9 => CharacterClass::HUcaseal,
  38. 10 => CharacterClass::FOmar,
  39. 11 => CharacterClass::RAmarl,
  40. _ => panic!("unknown class")
  41. }
  42. }
  43. }
  44. impl From<CharacterClass> for u8 {
  45. fn from(other: CharacterClass) -> u8 {
  46. match other {
  47. CharacterClass::HUmar => 0,
  48. CharacterClass::HUnewearl => 1,
  49. CharacterClass::HUcast => 2,
  50. CharacterClass::RAmar => 3,
  51. CharacterClass::RAcast => 4,
  52. CharacterClass::RAcaseal => 5,
  53. CharacterClass::FOmarl => 6,
  54. CharacterClass::FOnewm => 7,
  55. CharacterClass::FOnewearl => 8,
  56. CharacterClass::HUcaseal => 9,
  57. CharacterClass::FOmar => 10,
  58. CharacterClass::RAmarl => 11,
  59. }
  60. }
  61. }
  62. impl CharacterClass {
  63. pub fn is_human(&self) -> bool {
  64. matches!(self,
  65. CharacterClass::HUmar |
  66. CharacterClass::RAmar |
  67. CharacterClass::RAmarl |
  68. CharacterClass::FOmar |
  69. CharacterClass::FOmarl)
  70. }
  71. pub fn is_newman(&self) -> bool {
  72. matches!(self,
  73. CharacterClass::HUnewearl |
  74. CharacterClass::FOnewm |
  75. CharacterClass::FOnewearl)
  76. }
  77. pub fn is_android(&self) -> bool {
  78. matches!(self,
  79. CharacterClass::HUcast |
  80. CharacterClass::HUcaseal |
  81. CharacterClass::RAcast |
  82. CharacterClass::RAcaseal)
  83. }
  84. }
  85. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, enum_utils::FromStr, derive_more::Display, Serialize, Deserialize, Default)]
  86. pub enum SectionID {
  87. #[default]
  88. Viridia,
  89. Greenill,
  90. Skyly,
  91. Bluefull,
  92. Purplenum,
  93. Pinkal,
  94. Redria,
  95. Oran,
  96. Yellowboze,
  97. Whitill,
  98. }
  99. impl From<u8> for SectionID {
  100. fn from(id: u8) -> SectionID {
  101. match id {
  102. 0 => SectionID::Viridia,
  103. 1 => SectionID::Greenill,
  104. 2 => SectionID::Skyly,
  105. 3 => SectionID::Bluefull,
  106. 4 => SectionID::Purplenum,
  107. 5 => SectionID::Pinkal,
  108. 6 => SectionID::Redria,
  109. 7 => SectionID::Oran,
  110. 8 => SectionID::Yellowboze,
  111. 9 => SectionID::Whitill,
  112. _ => panic!(),
  113. }
  114. }
  115. }
  116. impl From<SectionID> for u8 {
  117. fn from(other: SectionID) -> u8 {
  118. match other {
  119. SectionID::Viridia => 0,
  120. SectionID::Greenill => 1,
  121. SectionID::Skyly => 2,
  122. SectionID::Bluefull => 3,
  123. SectionID::Purplenum => 4,
  124. SectionID::Pinkal => 5,
  125. SectionID::Redria => 6,
  126. SectionID::Oran => 7,
  127. SectionID::Yellowboze => 8,
  128. SectionID::Whitill => 9,
  129. }
  130. }
  131. }
  132. #[derive(Clone, Debug, Default)]
  133. pub struct CharacterAppearance {
  134. pub costume: u16,
  135. pub skin: u16,
  136. pub face: u16,
  137. pub head: u16,
  138. pub hair: u16,
  139. pub hair_r: u16,
  140. pub hair_g: u16,
  141. pub hair_b: u16,
  142. pub prop_x: f32,
  143. pub prop_y: f32,
  144. }
  145. #[derive(Clone, Debug)]
  146. pub struct TechLevel(pub u8);
  147. #[derive(Clone, Debug, Default)]
  148. pub struct CharacterTechniques {
  149. pub techs: HashMap<Technique, TechLevel>
  150. }
  151. impl CharacterTechniques {
  152. pub fn set_tech(&mut self, tech: Technique, level: TechLevel) {
  153. self.techs.insert(tech, TechLevel(level.0 - 1));
  154. }
  155. // from_bytes
  156. pub fn as_bytes(&self) -> [u8; 20] {
  157. self.techs.iter()
  158. .fold([0xFF; 20], |mut techlist, (tech, level)| {
  159. let index = tech.as_value();
  160. techlist[index as usize] = level.0;
  161. techlist
  162. })
  163. }
  164. }
  165. #[derive(Debug, Clone)]
  166. pub struct CharacterConfig {
  167. pub raw_data: [u8; 0xE8],
  168. }
  169. impl Default for CharacterConfig {
  170. fn default() -> CharacterConfig {
  171. CharacterConfig {
  172. raw_data: DEFAULT_PALETTE_CONFIG,
  173. }
  174. }
  175. }
  176. impl CharacterConfig {
  177. pub fn update(&mut self, new_config: &UpdateConfig) {
  178. self.raw_data = new_config.config;
  179. }
  180. pub fn as_bytes(&self) -> [u8; 0xE8] {
  181. self.raw_data
  182. }
  183. }
  184. #[derive(Debug, Clone)]
  185. pub struct CharacterInfoboard {
  186. pub board: [u16; 172],
  187. }
  188. impl Default for CharacterInfoboard {
  189. fn default() -> CharacterInfoboard {
  190. CharacterInfoboard {
  191. board: [0; 172]
  192. }
  193. }
  194. }
  195. impl CharacterInfoboard {
  196. pub fn as_bytes(&self) -> [u16; 172] {
  197. self.board
  198. }
  199. pub fn update_infoboard(&mut self, new_board: &WriteInfoboard) {
  200. self.board = libpso::utf8_to_utf16_array!(new_board.message, 172);
  201. }
  202. }
  203. #[derive(Debug, Clone, Default)]
  204. pub struct CharacterGuildCard {
  205. pub description: String,
  206. }
  207. #[derive(Debug, Clone)]
  208. pub struct CharacterTechMenu {
  209. pub tech_menu: [u8; 40],
  210. }
  211. impl Default for CharacterTechMenu {
  212. fn default() -> CharacterTechMenu {
  213. CharacterTechMenu {
  214. tech_menu: DEFAULT_TECH_MENU,
  215. }
  216. }
  217. }
  218. impl CharacterTechMenu {
  219. pub fn as_bytes(&self) -> [u8; 40] {
  220. self.tech_menu
  221. }
  222. }
  223. #[derive(Clone, Default, Debug)]
  224. pub struct CharacterMaterials {
  225. pub power: u32,
  226. pub mind: u32,
  227. pub def: u32,
  228. pub evade: u32,
  229. pub luck: u32,
  230. pub hp: u32,
  231. pub tp: u32,
  232. }
  233. #[derive(Clone, Debug)]
  234. pub struct CharacterKeyboardConfig {
  235. pub keyboard_config: [u8; 0x16C],
  236. }
  237. impl Default for CharacterKeyboardConfig {
  238. fn default() -> CharacterKeyboardConfig {
  239. CharacterKeyboardConfig {
  240. keyboard_config: DEFAULT_KEYBOARD_CONFIG1,
  241. }
  242. }
  243. }
  244. impl CharacterKeyboardConfig {
  245. fn new(preset: usize) -> CharacterKeyboardConfig {
  246. match preset {
  247. 1 => {
  248. CharacterKeyboardConfig {
  249. keyboard_config: DEFAULT_KEYBOARD_CONFIG1,
  250. }
  251. },
  252. 2 => {
  253. CharacterKeyboardConfig {
  254. keyboard_config: DEFAULT_KEYBOARD_CONFIG2,
  255. }
  256. },
  257. 3 => {
  258. CharacterKeyboardConfig {
  259. keyboard_config: DEFAULT_KEYBOARD_CONFIG3,
  260. }
  261. },
  262. 4 => {
  263. CharacterKeyboardConfig {
  264. keyboard_config: DEFAULT_KEYBOARD_CONFIG4,
  265. }
  266. },
  267. _ => {
  268. CharacterKeyboardConfig {
  269. keyboard_config: DEFAULT_KEYBOARD_CONFIG1,
  270. }
  271. },
  272. }
  273. }
  274. pub fn update(&mut self, new_config: &KeyboardConfig) {
  275. self.keyboard_config = new_config.keyboard_config;
  276. }
  277. pub fn as_bytes(&self) -> [u8; 0x16C] {
  278. self.keyboard_config
  279. }
  280. }
  281. #[derive(Clone, Debug)]
  282. pub struct CharacterGamepadConfig {
  283. pub gamepad_config: [u8; 0x38],
  284. }
  285. impl Default for CharacterGamepadConfig {
  286. fn default() -> CharacterGamepadConfig {
  287. CharacterGamepadConfig {
  288. gamepad_config: DEFAULT_GAMEPAD_CONFIG,
  289. }
  290. }
  291. }
  292. impl CharacterGamepadConfig {
  293. pub fn update(&mut self, new_config: &GamepadConfig) {
  294. self.gamepad_config = new_config.gamepad_config;
  295. }
  296. pub fn as_bytes(&self) -> [u8; 0x38] {
  297. self.gamepad_config
  298. }
  299. }
  300. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Default, derive_more::Display)]
  301. pub struct CharacterEntityId(pub u32);
  302. #[derive(Clone)]
  303. pub struct NewCharacterEntity {
  304. pub user_id: UserAccountId,
  305. pub slot: u32,
  306. pub name: String,
  307. pub exp: u32,
  308. pub char_class: CharacterClass,
  309. pub section_id: SectionID,
  310. pub appearance: CharacterAppearance,
  311. pub techs: CharacterTechniques,
  312. pub config: CharacterConfig,
  313. pub info_board: CharacterInfoboard,
  314. pub guildcard: CharacterGuildCard,
  315. pub materials: CharacterMaterials,
  316. pub tech_menu: CharacterTechMenu,
  317. pub option_flags: u32,
  318. pub keyboard_config: CharacterKeyboardConfig,
  319. pub gamepad_config: CharacterGamepadConfig,
  320. }
  321. impl NewCharacterEntity {
  322. pub fn new(user: UserAccountId, keyboard_config_preset: usize,) -> NewCharacterEntity {
  323. NewCharacterEntity {
  324. user_id: user,
  325. slot: 0,
  326. name: "".into(),
  327. exp: 0,
  328. char_class: CharacterClass::HUmar,
  329. section_id: SectionID::Viridia,
  330. appearance: CharacterAppearance::default(),
  331. techs: CharacterTechniques::default(),
  332. config: CharacterConfig::default(),
  333. info_board: CharacterInfoboard::default(),
  334. guildcard: CharacterGuildCard::default(),
  335. materials: CharacterMaterials::default(),
  336. tech_menu: CharacterTechMenu::default(),
  337. option_flags: 0,
  338. keyboard_config: CharacterKeyboardConfig::new(keyboard_config_preset),
  339. gamepad_config: CharacterGamepadConfig::default(),
  340. }
  341. }
  342. }
  343. #[derive(Clone, Default, Debug)]
  344. pub struct CharacterEntity {
  345. pub id: CharacterEntityId,
  346. pub user_id: UserAccountId,
  347. pub slot: u32,
  348. pub name: String,
  349. pub exp: u32,
  350. pub char_class: CharacterClass,
  351. pub section_id: SectionID,
  352. pub appearance: CharacterAppearance,
  353. pub techs: CharacterTechniques,
  354. pub config: CharacterConfig,
  355. pub info_board: CharacterInfoboard,
  356. pub guildcard: CharacterGuildCard,
  357. pub materials: CharacterMaterials,
  358. pub tech_menu: CharacterTechMenu,
  359. pub option_flags: u32,
  360. pub keyboard_config: CharacterKeyboardConfig,
  361. pub gamepad_config: CharacterGamepadConfig,
  362. }