diff --git a/src/bin/main.rs b/src/bin/main.rs index f83f88f..6db053a 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -84,6 +84,7 @@ fn main() { Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}), None,], tekked: true, + modifiers: Vec::new(), } ), location: ItemLocation::Inventory { @@ -103,6 +104,7 @@ fn main() { Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}), None,], tekked: true, + modifiers: Vec::new(), } ), location: ItemLocation::Inventory { @@ -122,6 +124,7 @@ fn main() { Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}), None,], tekked: true, + modifiers: Vec::new(), } ), location: ItemLocation::Inventory { @@ -141,6 +144,7 @@ fn main() { Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}), None,], tekked: true, + modifiers: Vec::new(), } ), location: ItemLocation::Inventory { @@ -160,6 +164,7 @@ fn main() { Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}), Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),], tekked: true, + modifiers: Vec::new(), } ), location: ItemLocation::Inventory { @@ -179,6 +184,7 @@ fn main() { Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 80}), None,], tekked: false, + modifiers: Vec::new(), } ), location: ItemLocation::Bank { diff --git a/src/entity/item/armor.rs b/src/entity/item/armor.rs index a97a508..48e41ee 100644 --- a/src/entity/item/armor.rs +++ b/src/entity/item/armor.rs @@ -1,4 +1,5 @@ use serde::{Serialize, Deserialize}; +use crate::entity::item::ItemEntityId; #[derive(Debug, Copy, Clone)] pub enum ItemParseError { @@ -288,12 +289,21 @@ impl ArmorType { } -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq)] +pub enum ArmorModifier { + AddSlot { + addslot: ItemEntityId, + } +} + + +#[derive(Debug, Clone, PartialEq)] pub struct Armor { pub armor: ArmorType, pub dfp: u8, pub evp: u8, pub slots: u8, + pub modifiers: Vec } impl Armor { @@ -314,6 +324,7 @@ impl Armor { dfp: data[6], evp: data[8], slots: data[5], + modifiers: Vec::new(), }) } else { diff --git a/src/entity/item/mag.rs b/src/entity/item/mag.rs index ac34e62..130bd2b 100644 --- a/src/entity/item/mag.rs +++ b/src/entity/item/mag.rs @@ -1,4 +1,5 @@ use serde::{Serialize, Deserialize}; +use crate::entity::item::ItemEntityId; #[derive(Debug, Copy, Clone)] pub enum ItemParseError { @@ -251,6 +252,15 @@ impl MagType { } } +#[derive(Debug, Clone, PartialEq)] +pub enum MagModifier { + FeedMag{ + food: ItemEntityId, + }, + BankMag, + MagCell(ItemEntityId), +} + #[derive(Debug, Copy, Clone, PartialEq)] pub enum PhotonBlast { Farlla, @@ -261,7 +271,7 @@ pub enum PhotonBlast { MyllaYoulla, } -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq)] pub struct Mag { pub mag: MagType, pub def: u16, @@ -272,6 +282,7 @@ pub struct Mag { pub iq: u8, pub photon_blast: [Option; 3], pub color: u8, + pub modifiers: Vec, } @@ -371,6 +382,7 @@ impl Mag { iq: iq, photon_blast: [None, None, None], // TODO: actually get PBs from bytes color: data[15] % 18, + modifiers: Vec::new(), }) } else { diff --git a/src/entity/item/weapon.rs b/src/entity/item/weapon.rs index 4421d53..48a0e4c 100644 --- a/src/entity/item/weapon.rs +++ b/src/entity/item/weapon.rs @@ -1,3 +1,4 @@ +use crate::entity::item::ItemEntityId; use serde::{Serialize, Deserialize}; #[derive(Debug, Copy, Clone)] @@ -1330,13 +1331,47 @@ impl WeaponType { } } + +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum TekSpecialModifier { + Plus, + Neutral, + Minus, +} + #[derive(Debug, Copy, Clone, PartialEq)] +pub enum TekPercentModifier { + PlusPlus, + Plus, + Neutral, + Minus, + MinusMinus, +} + +#[derive(Debug, Clone, PartialEq)] +pub enum WeaponModifier { + AddPercents { + attr: WeaponAttribute, + pds: Vec, + }, + AddGrind { + amount: u32, + grinder: ItemEntityId, + }, + Tekked { + special: TekSpecialModifier, + percents: TekPercentModifier, + }, +} + +#[derive(Debug, Clone, PartialEq)] pub struct Weapon { pub weapon: WeaponType, pub special: Option, pub grind: u8, pub attrs: [Option; 3], pub tekked: bool, + pub modifiers: Vec } @@ -1348,6 +1383,7 @@ impl Weapon { grind: 0, attrs: [None; 3], tekked: true, + modifiers: Vec::new(), } } @@ -1416,6 +1452,7 @@ impl Weapon { a[2], ], tekked: t, + modifiers: Vec::new(), }) } else { diff --git a/src/login/character.rs b/src/login/character.rs index 1d24efa..cade993 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -200,6 +200,7 @@ async fn new_character(entity_gateway: &mut EG, user: &UserAc special: None, attrs: [None; 3], tekked: true, + modifiers: Vec::new(), }), location: ItemLocation::Inventory { character_id: character.id, @@ -214,7 +215,8 @@ async fn new_character(entity_gateway: &mut EG, user: &UserAc armor: item::armor::ArmorType::Frame, dfp: 0, evp: 0, - slots: 0, + slots: 0, + modifiers: Vec::new(), }), location: ItemLocation::Inventory { character_id: character.id, @@ -235,6 +237,7 @@ async fn new_character(entity_gateway: &mut EG, user: &UserAc iq: 0, photon_blast: [None; 3], color: (character.appearance.skin % 18) as u8, + modifiers: Vec::new(), }), location: ItemLocation::Inventory { character_id: character.id, diff --git a/src/ship/drops/generic_armor.rs b/src/ship/drops/generic_armor.rs index 2bf5895..18efbab 100644 --- a/src/ship/drops/generic_armor.rs +++ b/src/ship/drops/generic_armor.rs @@ -107,6 +107,7 @@ impl GenericArmorTable { dfp: dfp_modifier as u8, evp: evp_modifier as u8, slots: slots as u8, + modifiers: Vec::new(), })) } } @@ -126,24 +127,28 @@ mod test { dfp: 0, evp: 0, slots: 1, + modifiers: Vec::new(), }))); assert!(gat.get_drop(&MapArea::Caves3, &mut rng) == Some(ItemDropType::Armor(Armor { armor: ArmorType::AbsorbArmor, dfp: 1, evp: 1, slots: 1, + modifiers: Vec::new(), }))); assert!(gat.get_drop(&MapArea::Forest2, &mut rng) == Some(ItemDropType::Armor(Armor { armor: ArmorType::HyperFrame, dfp: 0, evp: 0, slots: 0, + modifiers: Vec::new(), }))); assert!(gat.get_drop(&MapArea::DarkFalz, &mut rng) == Some(ItemDropType::Armor(Armor { armor: ArmorType::ImperialArmor, dfp: 2, evp: 1, slots: 0, + modifiers: Vec::new(), }))); } } diff --git a/src/ship/drops/generic_weapon.rs b/src/ship/drops/generic_weapon.rs index 71e578c..d00ad14 100644 --- a/src/ship/drops/generic_weapon.rs +++ b/src/ship/drops/generic_weapon.rs @@ -503,6 +503,7 @@ impl GenericWeaponTable { grind: weapon_grind as u8, attrs: weapon_attributes, tekked: weapon_special.is_none(), + modifiers: Vec::new(), })) } } @@ -524,6 +525,7 @@ mod test { grind: 0, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), }))); let gwt = GenericWeaponTable::new(Episode::One, Difficulty::Hard, SectionID::Skyly); @@ -533,6 +535,7 @@ mod test { grind: 2, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), }))); let gwt = GenericWeaponTable::new(Episode::One, Difficulty::VeryHard, SectionID::Skyly); @@ -542,6 +545,7 @@ mod test { grind: 0, attrs: [None, None, None], tekked: false, + modifiers: Vec::new(), }))); let gwt = GenericWeaponTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly); @@ -551,6 +555,7 @@ mod test { grind: 0, attrs: [Some(WeaponAttribute {attr: Attribute::ABeast, value: 30}), Some(WeaponAttribute {attr: Attribute::Dark, value: 30}), None], tekked: true, + modifiers: Vec::new(), }))); } } diff --git a/src/ship/drops/rare_drop_table.rs b/src/ship/drops/rare_drop_table.rs index 56d564c..dc3dd47 100644 --- a/src/ship/drops/rare_drop_table.rs +++ b/src/ship/drops/rare_drop_table.rs @@ -104,6 +104,7 @@ impl RareDropTable { grind: 0, attrs: self.attribute_table.generate_rare_attributes(map_area, rng), tekked: false, + modifiers: Vec::new(), }) }, @@ -113,6 +114,7 @@ impl RareDropTable { dfp: self.armor_stats.dfp_modifier(&armor, rng) as u8, evp: self.armor_stats.evp_modifier(&armor, rng) as u8, slots: self.armor_stats.slots(map_area, rng) as u8, + modifiers: Vec::new(), }) }, RareDropItem::Shield(shield) => { @@ -144,6 +146,7 @@ impl RareDropTable { synchro: 20, photon_blast: [None; 3], color: rng.gen_range(0, 18), + modifiers: Vec::new(), }) } } diff --git a/tests/test_bank.rs b/tests/test_bank.rs index 99318f6..f0328bb 100644 --- a/tests/test_bank.rs +++ b/tests/test_bank.rs @@ -26,6 +26,7 @@ async fn test_bank_items_sent_in_character_login() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Bank { @@ -62,8 +63,9 @@ async fn test_request_bank_items() { weapon: item::weapon::WeaponType::Vulcan, grind: 0, special: None, - attrs: [None, None, None], + attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Bank { @@ -156,6 +158,7 @@ async fn test_request_bank_items_sorted() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Bank { @@ -184,6 +187,7 @@ async fn test_request_bank_items_sorted() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Bank { @@ -231,6 +235,7 @@ async fn test_deposit_individual_item() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Inventory { @@ -248,6 +253,7 @@ async fn test_deposit_individual_item() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Inventory { @@ -639,6 +645,7 @@ async fn test_deposit_individual_item_in_full_bank() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Inventory { @@ -658,6 +665,7 @@ async fn test_deposit_individual_item_in_full_bank() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Bank { @@ -750,6 +758,7 @@ async fn test_deposit_stacked_item_in_full_bank() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Bank { @@ -842,6 +851,7 @@ async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Bank { @@ -1046,6 +1056,7 @@ async fn test_withdraw_individual_item() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Bank { @@ -1429,6 +1440,7 @@ async fn test_withdraw_individual_item_in_full_inventory() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Bank { @@ -1447,6 +1459,7 @@ async fn test_withdraw_individual_item_in_full_inventory() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Inventory { @@ -1539,6 +1552,7 @@ async fn test_withdraw_stacked_item_in_full_inventory() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Inventory { @@ -1631,6 +1645,7 @@ async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Inventory { diff --git a/tests/test_item_pickup.rs b/tests/test_item_pickup.rs index 2b584c4..3f83927 100644 --- a/tests/test_item_pickup.rs +++ b/tests/test_item_pickup.rs @@ -176,6 +176,7 @@ async fn test_pick_up_meseta_when_inventory_full() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Inventory { @@ -254,6 +255,7 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Inventory { @@ -352,6 +354,7 @@ async fn test_can_not_pick_up_item_when_inventory_full() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Inventory { @@ -371,6 +374,7 @@ async fn test_can_not_pick_up_item_when_inventory_full() { special: None, attrs: [None, None, None], tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Inventory {