wow i should have pushed much smaller chunks more often oops. shop selling added, shop buying quantity bug fixed(?) added lots of todos
This commit is contained in:
parent
9131dc0e51
commit
10aca8c7ec
@ -350,6 +350,23 @@ fn main() {
|
||||
}
|
||||
}
|
||||
).await.unwrap();
|
||||
let item14 = entity_gateway.create_item(
|
||||
NewItemEntity {
|
||||
item: ItemDetail::Weapon(
|
||||
item::weapon::Weapon {
|
||||
weapon: item::weapon::WeaponType::Vulcan,
|
||||
grind: 5,
|
||||
special: Some(item::weapon::WeaponSpecial::Charge),
|
||||
attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}),
|
||||
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
|
||||
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),],
|
||||
tekked: true,
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: character.id,
|
||||
}
|
||||
}).await.unwrap();
|
||||
|
||||
let equipped = item::EquippedEntity {
|
||||
weapon: Some(item2_w.id),
|
||||
@ -360,7 +377,7 @@ fn main() {
|
||||
};
|
||||
entity_gateway.set_character_equips(&character.id, &equipped).await.unwrap();
|
||||
|
||||
let inventory = item::InventoryEntity::new(vec![item0, item1, item2_w, item3, item4, item5_m, item6, item7_a, item8_s, item9_u0, item10_u1, item11_u2, item12_u3, item13]);
|
||||
let inventory = item::InventoryEntity::new(vec![item0, item1, item2_w, item3, item4, item5_m, item6, item7_a, item8_s, item9_u0, item10_u1, item11_u2, item12_u3, item13, item14]);
|
||||
entity_gateway.set_character_inventory(&character.id, &inventory).await.unwrap();
|
||||
entity_gateway.set_character_bank(&character.id, &item::BankEntity::default(), item::BankName("".into())).await.unwrap();
|
||||
}
|
||||
|
@ -597,6 +597,7 @@ pub enum PgItemLocationDetail {
|
||||
mag: u32,
|
||||
},
|
||||
Shop,
|
||||
SoldToShop,
|
||||
}
|
||||
|
||||
impl From<ItemLocation> for PgItemLocationDetail {
|
||||
@ -609,6 +610,7 @@ impl From<ItemLocation> for PgItemLocationDetail {
|
||||
ItemLocation::Consumed => PgItemLocationDetail::Consumed,
|
||||
ItemLocation::FedToMag{mag} => PgItemLocationDetail::FedToMag{mag: mag.0},
|
||||
ItemLocation::Shop => PgItemLocationDetail::Shop,
|
||||
ItemLocation::SoldToShop => PgItemLocationDetail::SoldToShop,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -623,6 +625,7 @@ impl From<PgItemLocationDetail> for ItemLocation {
|
||||
PgItemLocationDetail::Consumed => ItemLocation::Consumed,
|
||||
PgItemLocationDetail::FedToMag{mag} => ItemLocation::FedToMag{mag: ItemEntityId(mag)},
|
||||
PgItemLocationDetail::Shop => ItemLocation::Shop,
|
||||
PgItemLocationDetail::SoldToShop => ItemLocation::SoldToShop,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ pub enum ArmorModifier {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Armor {
|
||||
pub armor: ArmorType,
|
||||
pub dfp: u8,
|
||||
@ -329,4 +329,74 @@ impl Armor {
|
||||
Err(ItemParseError::InvalidArmorBytes) // TODO: error handling if wrong bytes are given
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_rare_item(self) -> bool {
|
||||
match self.armor {
|
||||
ArmorType::HunterField => true,
|
||||
ArmorType::RangerField => true,
|
||||
ArmorType::ForceField => true,
|
||||
ArmorType::RevivalGarment => true,
|
||||
ArmorType::SpiritGarment => true,
|
||||
ArmorType::StinkFrame => true,
|
||||
ArmorType::DPartsVer101 => true,
|
||||
ArmorType::DPartsVer210 => true,
|
||||
ArmorType::ParasiteWearDeRol => true,
|
||||
ArmorType::ParasiteWearNelgal => true,
|
||||
ArmorType::ParasiteWearVajulla => true,
|
||||
ArmorType::SensePlate => true,
|
||||
ArmorType::GravitonPlate => true,
|
||||
ArmorType::AttributePlate => true,
|
||||
ArmorType::FlowensFrame => true,
|
||||
ArmorType::CustomFrameVerOo => true,
|
||||
ArmorType::DbsArmor => true,
|
||||
ArmorType::GuardWave => true,
|
||||
ArmorType::DfField => true,
|
||||
ArmorType::LuminousField => true,
|
||||
ArmorType::ChuChuFever => true,
|
||||
ArmorType::LoveHeart => true,
|
||||
ArmorType::FlameGarment => true,
|
||||
ArmorType::VirusArmorLafuteria => true,
|
||||
ArmorType::BrightnessCircle => true,
|
||||
ArmorType::AuraField => true,
|
||||
ArmorType::ElectroFrame => true,
|
||||
ArmorType::SacredCloth => true,
|
||||
ArmorType::SmokingPlate => true,
|
||||
ArmorType::StarCuirass => true,
|
||||
ArmorType::BlackHoundCuirass => true,
|
||||
ArmorType::MorningPrayer => true,
|
||||
ArmorType::BlackOdoshiDomaru => true,
|
||||
ArmorType::RedOdoshiDomaru => true,
|
||||
ArmorType::BlackOdoshiRedNimaidou => true,
|
||||
ArmorType::BlueOdoshiVioletNimaidou => true,
|
||||
ArmorType::DirtyLifejacket => true,
|
||||
ArmorType::KroesSweater => true,
|
||||
ArmorType::WeddingDress => true,
|
||||
ArmorType::SonicteamArmor => true,
|
||||
ArmorType::RedCoat => true,
|
||||
ArmorType::Thirteen => true,
|
||||
ArmorType::MotherGarb => true,
|
||||
ArmorType::MotherGarbPlus => true,
|
||||
ArmorType::DressPlate => true,
|
||||
ArmorType::Sweetheart => true,
|
||||
ArmorType::IgnitionCloak => true,
|
||||
ArmorType::CongealCloak => true,
|
||||
ArmorType::TempestCloak => true,
|
||||
ArmorType::CursedCloak => true,
|
||||
ArmorType::SelectCloak => true,
|
||||
ArmorType::SpiritCuirass => true,
|
||||
ArmorType::RevivalCuriass => true,
|
||||
ArmorType::AllianceUniform => true,
|
||||
ArmorType::OfficerUniform => true,
|
||||
ArmorType::CommanderUniform => true,
|
||||
ArmorType::CrimsonCoat => true,
|
||||
ArmorType::InfantryGear => true,
|
||||
ArmorType::LieutenantGear => true,
|
||||
ArmorType::InfantryMantle => true,
|
||||
ArmorType::LieutenantMantle => true,
|
||||
ArmorType::UnionField => true,
|
||||
ArmorType::SamuraiArmor => true,
|
||||
ArmorType::StealthSuit => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -253,6 +253,11 @@ impl ESWeapon {
|
||||
name,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this isn't even needed. all sranks are rare and only sell for 10? meseta in the shop
|
||||
pub fn is_rare_item(self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1098,6 +1098,53 @@ impl Mag {
|
||||
MagCell::LibertaKit => MagType::Agastya,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: is this even needed? mags are not shop sellable...yet
|
||||
pub fn is_rare_item(self) -> bool {
|
||||
match self.mag {
|
||||
MagType::Pitri => true,
|
||||
MagType::Soniti => true,
|
||||
MagType::Preta => true,
|
||||
MagType::Churel => true,
|
||||
MagType::Robochao => true,
|
||||
MagType::OpaOpa => true,
|
||||
MagType::Pian => true,
|
||||
MagType::Chao => true,
|
||||
MagType::ChuChu => true,
|
||||
MagType::KapuKapu => true,
|
||||
MagType::AngelsWing => true,
|
||||
MagType::DevilsWing => true,
|
||||
MagType::Elenor => true,
|
||||
MagType::MarkIII => true,
|
||||
MagType::MasterSystem => true,
|
||||
MagType::Genesis => true,
|
||||
MagType::SegaSaturn => true,
|
||||
MagType::Dreamcast => true,
|
||||
MagType::Hamburger => true,
|
||||
MagType::PanzersTail => true,
|
||||
MagType::DevilsTail => true,
|
||||
MagType::Deva => true,
|
||||
MagType::Rati => true,
|
||||
MagType::Savitri => true,
|
||||
MagType::Rukmin => true,
|
||||
MagType::Pushan => true,
|
||||
MagType::Diwari => true,
|
||||
MagType::Sato => true,
|
||||
MagType::Bhima => true,
|
||||
MagType::Nidra => true,
|
||||
MagType::GeungSi => true,
|
||||
MagType::Tellusis => true,
|
||||
MagType::StrikerUnit => true,
|
||||
MagType::Pioneer => true,
|
||||
MagType::Puyo => true,
|
||||
MagType::Moro => true,
|
||||
MagType::Rappy => true,
|
||||
MagType::Yahoo => true,
|
||||
MagType::GaelGiel => true,
|
||||
MagType::Agastya => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,6 +12,7 @@ use serde::{Serialize, Deserialize};
|
||||
use crate::entity::character::CharacterEntityId;
|
||||
use crate::ship::map::MapArea;
|
||||
use crate::ship::drops::ItemDropType;
|
||||
use crate::ship::shops::{ShopItem, ArmorShopItem, ToolShopItem, WeaponShopItem};
|
||||
|
||||
#[derive(PartialEq, Copy, Clone, Debug, Hash, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct ItemEntityId(pub u32);
|
||||
@ -47,6 +48,7 @@ pub enum ItemLocation {
|
||||
mag: ItemEntityId,
|
||||
},
|
||||
Shop,
|
||||
SoldToShop,
|
||||
/*Destroyed {
|
||||
// marks an item that has been consumed in some way
|
||||
},
|
||||
|
@ -548,4 +548,154 @@ impl Shield {
|
||||
Err(ItemParseError::InvalidShieldBytes) // TODO: error handling if wrong bytes are given
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_rare_item(self) -> bool {
|
||||
match self.shield {
|
||||
ShieldType::InvisibleGuard => true,
|
||||
ShieldType::SacredGuard => true,
|
||||
ShieldType::SPartsVer116 => true,
|
||||
ShieldType::SPartsVer201 => true,
|
||||
ShieldType::LightRelief => true,
|
||||
ShieldType::ShieldOfDelsaber => true,
|
||||
ShieldType::ForceWall => true,
|
||||
ShieldType::RangerWall => true,
|
||||
ShieldType::HunterWall => true,
|
||||
ShieldType::AttributeWall => true,
|
||||
ShieldType::SecretGear => true,
|
||||
ShieldType::CombatGear => true,
|
||||
ShieldType::ProtoRegeneGear => true,
|
||||
ShieldType::RegenerateGear => true,
|
||||
ShieldType::RegeneGearAdv => true,
|
||||
ShieldType::FlowensShield => true,
|
||||
ShieldType::CustomBarrierVerOo => true,
|
||||
ShieldType::DbsShield => true,
|
||||
ShieldType::RedRing => true,
|
||||
ShieldType::TripolicShield => true,
|
||||
ShieldType::StandstillShield => true,
|
||||
ShieldType::SafetyHeart => true,
|
||||
ShieldType::KasamiBracer => true,
|
||||
ShieldType::GodsShieldSuzaku => true,
|
||||
ShieldType::GodsShieldGenbu => true,
|
||||
ShieldType::GodsShieldByakko => true,
|
||||
ShieldType::GodsShieldSeiryu => true,
|
||||
ShieldType::HuntersShell => true,
|
||||
ShieldType::RicosGlasses => true,
|
||||
ShieldType::RicosEarring => true,
|
||||
ShieldType::BlueRing => true,
|
||||
ShieldType::Barrier2 => true,
|
||||
ShieldType::SecureFeet => true,
|
||||
ShieldType::Barrier3 => true,
|
||||
ShieldType::Barrier4 => true,
|
||||
ShieldType::Barrier5 => true,
|
||||
ShieldType::Barrier6 => true,
|
||||
ShieldType::RestaMerge => true,
|
||||
ShieldType::AntiMerge => true,
|
||||
ShieldType::ShiftaMerge => true,
|
||||
ShieldType::DebandMerge => true,
|
||||
ShieldType::FoieMerge => true,
|
||||
ShieldType::GifoieMerge => true,
|
||||
ShieldType::RafoieMerge => true,
|
||||
ShieldType::RedMerge => true,
|
||||
ShieldType::BartaMerge => true,
|
||||
ShieldType::GibartaMerge => true,
|
||||
ShieldType::RabartaMerge => true,
|
||||
ShieldType::BlueMerge => true,
|
||||
ShieldType::ZondeMerge => true,
|
||||
ShieldType::GizondeMerge => true,
|
||||
ShieldType::RazondeMerge => true,
|
||||
ShieldType::YellowMerge => true,
|
||||
ShieldType::RecoveryBarrier => true,
|
||||
ShieldType::AssistBarrier => true,
|
||||
ShieldType::RedBarrier => true,
|
||||
ShieldType::BlueBarrier => true,
|
||||
ShieldType::YellowBarrier => true,
|
||||
ShieldType::WeaponsGoldShield => true,
|
||||
ShieldType::BlackGear => true,
|
||||
ShieldType::WorksGuard => true,
|
||||
ShieldType::RagolRing => true,
|
||||
ShieldType::BlueRing2 => true,
|
||||
ShieldType::BlueRing3 => true,
|
||||
ShieldType::BlueRing4 => true,
|
||||
ShieldType::BlueRing5 => true,
|
||||
ShieldType::BlueRing6 => true,
|
||||
ShieldType::BlueRing7 => true,
|
||||
ShieldType::BlueRing8 => true,
|
||||
ShieldType::BlueRing9 => true,
|
||||
ShieldType::GreenRing => true,
|
||||
ShieldType::GreenRing2 => true,
|
||||
ShieldType::GreenRing3 => true,
|
||||
ShieldType::GreenRing4 => true,
|
||||
ShieldType::GreenRing5 => true,
|
||||
ShieldType::GreenRing6 => true,
|
||||
ShieldType::GreenRing7 => true,
|
||||
ShieldType::GreenRing8 => true,
|
||||
ShieldType::YellowRing => true,
|
||||
ShieldType::YellowRing2 => true,
|
||||
ShieldType::YellowRing3 => true,
|
||||
ShieldType::YellowRing4 => true,
|
||||
ShieldType::YellowRing5 => true,
|
||||
ShieldType::YellowRing6 => true,
|
||||
ShieldType::YellowRing7 => true,
|
||||
ShieldType::YellowRing8 => true,
|
||||
ShieldType::PurpleRing => true,
|
||||
ShieldType::PurpleRing2 => true,
|
||||
ShieldType::PurpleRing3 => true,
|
||||
ShieldType::PurpleRing4 => true,
|
||||
ShieldType::PurpleRing5 => true,
|
||||
ShieldType::PurpleRing6 => true,
|
||||
ShieldType::PurpleRing7 => true,
|
||||
ShieldType::PurpleRing8 => true,
|
||||
ShieldType::WhiteRing => true,
|
||||
ShieldType::WhiteRing2 => true,
|
||||
ShieldType::WhiteRing3 => true,
|
||||
ShieldType::WhiteRing4 => true,
|
||||
ShieldType::WhiteRing5 => true,
|
||||
ShieldType::WhiteRing6 => true,
|
||||
ShieldType::WhiteRing7 => true,
|
||||
ShieldType::WhiteRing8 => true,
|
||||
ShieldType::BlackRing => true,
|
||||
ShieldType::BlackRing2 => true,
|
||||
ShieldType::BlackRing3 => true,
|
||||
ShieldType::BlackRing4 => true,
|
||||
ShieldType::BlackRing5 => true,
|
||||
ShieldType::BlackRing6 => true,
|
||||
ShieldType::BlackRing7 => true,
|
||||
ShieldType::BlackRing8 => true,
|
||||
ShieldType::WeaponsSilverShield => true,
|
||||
ShieldType::WeaponsCopperShield => true,
|
||||
ShieldType::Gratia => true,
|
||||
ShieldType::TripolicReflector => true,
|
||||
ShieldType::StrikerPlus => true,
|
||||
ShieldType::RegenerateGearBP => true,
|
||||
ShieldType::Rupika => true,
|
||||
ShieldType::YataMirror => true,
|
||||
ShieldType::BunnyEars => true,
|
||||
ShieldType::CatEars => true,
|
||||
ShieldType::ThreeSeals => true,
|
||||
ShieldType::GodsShieldKouryu => true,
|
||||
ShieldType::DfShield => true,
|
||||
ShieldType::FromTheDepths => true,
|
||||
ShieldType::DeRolLeShield => true,
|
||||
ShieldType::HoneycombReflector => true,
|
||||
ShieldType::Epsiguard => true,
|
||||
ShieldType::AngelRing => true,
|
||||
ShieldType::UnionGuard => true,
|
||||
ShieldType::UnionGuard2 => true,
|
||||
ShieldType::UnionGuard3 => true,
|
||||
ShieldType::UnionGuard4 => true,
|
||||
ShieldType::StinkShield => true,
|
||||
ShieldType::Unknownb => true,
|
||||
ShieldType::Genpei => true,
|
||||
ShieldType::Genpei2 => true,
|
||||
ShieldType::Genpei3 => true,
|
||||
ShieldType::Genpei4 => true,
|
||||
ShieldType::Genpei5 => true,
|
||||
ShieldType::Genpei6 => true,
|
||||
ShieldType::Genpei7 => true,
|
||||
ShieldType::Genpei8 => true,
|
||||
ShieldType::Genpei9 => true,
|
||||
ShieldType::Genpei10 => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -680,4 +680,174 @@ impl Tool {
|
||||
pub fn max_stack(&self) -> usize {
|
||||
self.tool.max_stack()
|
||||
}
|
||||
|
||||
pub fn is_rare_item(self) -> bool {
|
||||
match self.tool {
|
||||
ToolType::CellOfMag502 => true,
|
||||
ToolType::CellOfMag213 => true,
|
||||
ToolType::PartsOfRobochao => true,
|
||||
ToolType::HeartOfOpaOpa => true,
|
||||
ToolType::HeartOfPian => true,
|
||||
ToolType::HeartOfChao => true,
|
||||
ToolType::SorcerersRightArm => true,
|
||||
ToolType::SBeatsArms => true,
|
||||
ToolType::PArmsArms => true,
|
||||
ToolType::DelsabersRightArm => true,
|
||||
ToolType::BringersRightArm => true,
|
||||
ToolType::DelsabersLeftArm => true,
|
||||
ToolType::SRedsArms => true,
|
||||
ToolType::DragonsClaw => true,
|
||||
ToolType::HildebearsHead => true,
|
||||
ToolType::HildebluesHead => true,
|
||||
ToolType::PartsOfBaranz => true,
|
||||
ToolType::BelrasRightArm => true,
|
||||
ToolType::GiGuesBody => true,
|
||||
ToolType::SinowBerillsArms => true,
|
||||
ToolType::GrassAssassinsArms => true,
|
||||
ToolType::BoomasRightArm => true,
|
||||
ToolType::GoboomasRightArm => true,
|
||||
ToolType::GigoboomasRightArm => true,
|
||||
ToolType::GalGryphonsWing => true,
|
||||
ToolType::RappysWing => true,
|
||||
ToolType::CladdingOfEpsilon => true,
|
||||
ToolType::DeRolLeShell => true,
|
||||
ToolType::BerillPhoton => true,
|
||||
ToolType::ParasiticGeneFlow => true,
|
||||
ToolType::MagicStoneIritista => true,
|
||||
ToolType::BlueBlackStone => true,
|
||||
ToolType::Syncesta => true,
|
||||
ToolType::MagicWater => true,
|
||||
ToolType::ParasiticCellTypeD => true,
|
||||
ToolType::MagicRockHeartKey => true,
|
||||
ToolType::MagicRockMoola => true,
|
||||
ToolType::StarAmplifier => true,
|
||||
ToolType::BookOfHitogata => true,
|
||||
ToolType::HeartOfChuChu => true,
|
||||
ToolType::PartsOfEggBlaster => true,
|
||||
ToolType::HeartOfAngel => true,
|
||||
ToolType::HeartOfDevil => true,
|
||||
ToolType::KitOfHamburger => true,
|
||||
ToolType::PanthersSpirit => true,
|
||||
ToolType::KitOfMark3 => true,
|
||||
ToolType::KitOfMasterSystem => true,
|
||||
ToolType::KitOfGenesis => true,
|
||||
ToolType::KitOfSegaSaturn => true,
|
||||
ToolType::KitOfDreamcast => true,
|
||||
ToolType::AmplifierOfResta => true,
|
||||
ToolType::AmplifierOfAnti => true,
|
||||
ToolType::AmplifierOfShifta => true,
|
||||
ToolType::AmplifierOfDeband => true,
|
||||
ToolType::AmplifierOfFoie => true,
|
||||
ToolType::AmplifierOfGifoie => true,
|
||||
ToolType::AmplifierOfRafoie => true,
|
||||
ToolType::AmplifierOfBarta => true,
|
||||
ToolType::AmplifierOfGibarta => true,
|
||||
ToolType::AmplifierOfRabarta => true,
|
||||
ToolType::AmplifierOfZonde => true,
|
||||
ToolType::AmplifierOfGizonde => true,
|
||||
ToolType::AmplifierOfRazonde => true,
|
||||
ToolType::AmplifierOfRed => true,
|
||||
ToolType::AmplifierOfBlue => true,
|
||||
ToolType::AmplifierOfYellow => true,
|
||||
ToolType::HeartOfKapuKapu => true,
|
||||
ToolType::PhotonBooster => true,
|
||||
ToolType::Addslot => true,
|
||||
ToolType::PhotonDrop => true,
|
||||
ToolType::PhotonSphere => true,
|
||||
ToolType::PhotonCrystal => true,
|
||||
ToolType::SecretTicket => true,
|
||||
ToolType::PhotonTicket => true,
|
||||
ToolType::BookOfKatana1 => true,
|
||||
ToolType::BookOfKatana2 => true,
|
||||
ToolType::BookOfKatana3 => true,
|
||||
ToolType::WeaponsBronzeBadge => true,
|
||||
ToolType::WeaponsSilverBadge => true,
|
||||
ToolType::WeaponsGoldBadge => true,
|
||||
ToolType::WeaponsCrystalBadge => true,
|
||||
ToolType::WeaponsSteelBadge => true,
|
||||
ToolType::WeaponsAluminumBadge => true,
|
||||
ToolType::WeaponsLeatherBadge => true,
|
||||
ToolType::WeaponsBoneBadge => true,
|
||||
ToolType::LetterOfAppreciation => true,
|
||||
ToolType::ItemTicket => true,
|
||||
ToolType::ValentinesChocolate => true,
|
||||
ToolType::NewYearsCard => true,
|
||||
ToolType::ChristmasCard => true,
|
||||
ToolType::BirthdayCard => true,
|
||||
ToolType::ProofOfSonicTeam => true,
|
||||
ToolType::SpecialEventTicket => true,
|
||||
ToolType::FlowerBouquet => true,
|
||||
ToolType::Cake => true,
|
||||
ToolType::Accessories => true,
|
||||
ToolType::MrNakasBusinessCard => true,
|
||||
ToolType::Present => true,
|
||||
ToolType::Chocolate => true,
|
||||
ToolType::Candy => true,
|
||||
ToolType::Cake2 => true,
|
||||
ToolType::WeaponsSilverBadge2 => true,
|
||||
ToolType::WeaponsGoldBadge2 => true,
|
||||
ToolType::WeaponsCrystalBadge2 => true,
|
||||
ToolType::WeaponsSteelBadge2 => true,
|
||||
ToolType::WeaponsAluminumBadge2 => true,
|
||||
ToolType::WeaponsLeatherBadge2 => true,
|
||||
ToolType::WeaponsBoneBadge2 => true,
|
||||
ToolType::Bouquet => true,
|
||||
ToolType::Decoction => true,
|
||||
ToolType::ChristmasPresent => true,
|
||||
ToolType::EasterEgg => true,
|
||||
ToolType::JackOLantern => true,
|
||||
ToolType::DiskVol1WeddingMarch => true,
|
||||
ToolType::DiskVol2DayLight => true,
|
||||
ToolType::DiskVol3BurningRangers => true,
|
||||
ToolType::DiskVol4OpenYourHeart => true,
|
||||
ToolType::DiskVol5LiveLearn => true,
|
||||
ToolType::DiskVol6Nights => true,
|
||||
ToolType::DiskVol7EndingThemePianoVer => true,
|
||||
ToolType::DiskVol8HeartToHeart => true,
|
||||
ToolType::DiskVol9StrangeBlue => true,
|
||||
ToolType::DiskVol10ReunionSystem => true,
|
||||
ToolType::DiskVol11Pinnacles => true,
|
||||
ToolType::DiskVol12FightInsideTheSpaceship => true,
|
||||
ToolType::HuntersReport => true,
|
||||
ToolType::HuntersReport2 => true,
|
||||
ToolType::HuntersReport3 => true,
|
||||
ToolType::HuntersReport4 => true,
|
||||
ToolType::HuntersReport5 => true,
|
||||
ToolType::Tablet => true,
|
||||
ToolType::Unknown2 => true,
|
||||
ToolType::DragonScale => true,
|
||||
ToolType::HeavenStrikerCoat => true,
|
||||
ToolType::PioneerParts => true,
|
||||
ToolType::AmitiesMemo => true,
|
||||
ToolType::HeartOfMorolian => true,
|
||||
ToolType::RappysBeak => true,
|
||||
ToolType::YahoosEngine => true,
|
||||
ToolType::DPhotonCore => true,
|
||||
ToolType::LibertaKit => true,
|
||||
ToolType::CellOfMag0503 => true,
|
||||
ToolType::CellOfMag0504 => true,
|
||||
ToolType::CellOfMag0505 => true,
|
||||
ToolType::CellOfMag0506 => true,
|
||||
ToolType::CellOfMag0507 => true,
|
||||
ToolType::TeamPoints500 => true,
|
||||
ToolType::TeamPoints1000 => true,
|
||||
ToolType::TeamPoints5000 => true,
|
||||
ToolType::TeamPoints10000 => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: do we actually need this function?
|
||||
pub fn is_material(self) -> bool {
|
||||
match self.tool {
|
||||
ToolType::PowerMaterial => true,
|
||||
ToolType::MindMaterial => true,
|
||||
ToolType::EvadeMaterial => true,
|
||||
ToolType::HpMaterial => true,
|
||||
ToolType::TpMaterial => true,
|
||||
ToolType::DefMaterial => true,
|
||||
ToolType::LuckMaterial => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -384,4 +384,66 @@ impl Unit {
|
||||
Err(ItemParseError::InvalidUnitBytes) // TODO: error handling if wrong bytes are given
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_rare_item(self) -> bool {
|
||||
match self.unit {
|
||||
UnitType::GodPower => true,
|
||||
UnitType::GodMind => true,
|
||||
UnitType::GodArm => true,
|
||||
UnitType::GodLegs => true,
|
||||
UnitType::GodHp => true,
|
||||
UnitType::GodTp => true,
|
||||
UnitType::GodBody => true,
|
||||
UnitType::GodLuck => true,
|
||||
UnitType::HeroAbility => true,
|
||||
UnitType::GodAbility => true,
|
||||
UnitType::AllResist => true,
|
||||
UnitType::SuperResist => true,
|
||||
UnitType::PerfectResist => true,
|
||||
UnitType::HpRevival => true,
|
||||
UnitType::TpRevival => true,
|
||||
UnitType::PbAmplifier => true,
|
||||
UnitType::PbGenerate => true,
|
||||
UnitType::PbCreate => true,
|
||||
UnitType::DevilTechnique => true,
|
||||
UnitType::GodTechnique => true,
|
||||
UnitType::DevilBattle => true,
|
||||
UnitType::GodBattle => true,
|
||||
UnitType::CurePoison => true,
|
||||
UnitType::CureParalysis => true,
|
||||
UnitType::CureSlow => true,
|
||||
UnitType::CureConfuse => true,
|
||||
UnitType::CureFreeze => true,
|
||||
UnitType::CureShock => true,
|
||||
UnitType::YasakaniMagatama => true,
|
||||
UnitType::V101 => true,
|
||||
UnitType::V501 => true,
|
||||
UnitType::V502 => true,
|
||||
UnitType::V801 => true,
|
||||
UnitType::Limiter => true,
|
||||
UnitType::Adept => true,
|
||||
UnitType::SwordsmanLore => true,
|
||||
UnitType::ProofOfSwordSaint => true,
|
||||
UnitType::Smartlink => true,
|
||||
UnitType::DivineProtection => true,
|
||||
UnitType::HeavenlyBattle => true,
|
||||
UnitType::HeavenlyPower => true,
|
||||
UnitType::HeavenlyMind => true,
|
||||
UnitType::HeavenlyArms => true,
|
||||
UnitType::HeavenlyLegs => true,
|
||||
UnitType::HeavenlyBody => true,
|
||||
UnitType::HeavenlyLuck => true,
|
||||
UnitType::HeavenlyAbility => true,
|
||||
UnitType::CenturionAbility => true,
|
||||
UnitType::FriendRing => true,
|
||||
UnitType::HeavenlyHp => true,
|
||||
UnitType::HeavenlyTp => true,
|
||||
UnitType::HeavenlyResist => true,
|
||||
UnitType::HeavenlyTechnique => true,
|
||||
UnitType::HpRessurection => true,
|
||||
UnitType::TpRessurection => true,
|
||||
UnitType::PbIncrease => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1454,7 +1454,7 @@ pub enum WeaponModifier {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Weapon {
|
||||
pub weapon: WeaponType,
|
||||
pub special: Option<WeaponSpecial>,
|
||||
@ -1584,6 +1584,70 @@ impl Weapon {
|
||||
Err(ItemParseError::InvalidWeaponBytes) // TODO: error handling if wrong bytes are given
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: invert this? ie: handgun, saber, dagger etc. => false, _ => true?
|
||||
pub fn is_rare_item(self) -> bool {
|
||||
match self.weapon {
|
||||
WeaponType::Saber => false,
|
||||
WeaponType::Brand => false,
|
||||
WeaponType::Buster => false,
|
||||
WeaponType::Pallasch => false,
|
||||
WeaponType::Gladius => false,
|
||||
WeaponType::Sword => false,
|
||||
WeaponType::Gigush => false,
|
||||
WeaponType::Breaker => false,
|
||||
WeaponType::Claymore => false,
|
||||
WeaponType::Calibur => false,
|
||||
WeaponType::Dagger => false,
|
||||
WeaponType::Knife => false,
|
||||
WeaponType::Blade => false,
|
||||
WeaponType::Edge => false,
|
||||
WeaponType::Ripper => false,
|
||||
WeaponType::Partisan => false,
|
||||
WeaponType::Halbert => false,
|
||||
WeaponType::Glaive => false,
|
||||
WeaponType::Berdys => false,
|
||||
WeaponType::Gungnir => false,
|
||||
WeaponType::Slicer => false,
|
||||
WeaponType::Spinner => false,
|
||||
WeaponType::Cutter => false,
|
||||
WeaponType::Sawcer => false,
|
||||
WeaponType::Diska => false,
|
||||
WeaponType::Handgun => false,
|
||||
WeaponType::Autogun => false,
|
||||
WeaponType::Lockgun => false,
|
||||
WeaponType::Railgun => false,
|
||||
WeaponType::Raygun => false,
|
||||
WeaponType::Rifle => false,
|
||||
WeaponType::Sniper => false,
|
||||
WeaponType::Blaster => false,
|
||||
WeaponType::Beam => false,
|
||||
WeaponType::Laser => false,
|
||||
WeaponType::Mechgun => false,
|
||||
WeaponType::Assault => false,
|
||||
WeaponType::Repeater => false,
|
||||
WeaponType::Gatling => false,
|
||||
WeaponType::Vulcan => false,
|
||||
WeaponType::Shot => false,
|
||||
WeaponType::Spread => false,
|
||||
WeaponType::Cannon => false,
|
||||
WeaponType::Launcher => false,
|
||||
WeaponType::Arms => false,
|
||||
WeaponType::Cane => false,
|
||||
WeaponType::Stick => false,
|
||||
WeaponType::Mace => false,
|
||||
WeaponType::Club => false,
|
||||
WeaponType::Rod => false,
|
||||
WeaponType::Pole => false,
|
||||
WeaponType::Pillar => false,
|
||||
WeaponType::Striker => false,
|
||||
WeaponType::Wand => false,
|
||||
WeaponType::Staff => false,
|
||||
WeaponType::Baton => false,
|
||||
WeaponType::Scepter => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,11 +3,12 @@ use thiserror::Error;
|
||||
use libpso::character::character;//::InventoryItem;
|
||||
use crate::entity::character::CharacterEntityId;
|
||||
use crate::entity::item::{ItemEntityId, ItemDetail, ItemEntity, ItemType, ItemLocation, InventoryEntity, InventoryItemEntity, EquippedEntity};
|
||||
use crate::entity::item::tool::Tool;
|
||||
use crate::entity::item::tool::{Tool, ToolType};
|
||||
use crate::entity::item::mag::Mag;
|
||||
use crate::entity::item::weapon::Weapon;
|
||||
use crate::ship::items::{ClientItemId, BankItem, BankItemHandle};
|
||||
use crate::ship::items::floor::{IndividualFloorItem, StackedFloorItem};
|
||||
use crate::ship::shops::{ShopItem, ArmorShopItem, ToolShopItem, WeaponShopItem};
|
||||
|
||||
const INVENTORY_CAPACITY: usize = 30;
|
||||
|
||||
@ -220,6 +221,63 @@ impl InventoryItem {
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_sell_price(&self) -> Option<u32> {
|
||||
match self {
|
||||
InventoryItem::Individual(individual_item) => {
|
||||
match &individual_item.item {
|
||||
// TODO: can wrapped items be sold?
|
||||
ItemDetail::Weapon(w) => {
|
||||
if !w.tekked {
|
||||
return Some(1u32)
|
||||
}
|
||||
if w.is_rare_item() {
|
||||
return Some(10u32)
|
||||
}
|
||||
// other item factors?
|
||||
return Some((WeaponShopItem::weapon_from_item(w).price() / 8) as u32)
|
||||
},
|
||||
ItemDetail::Armor(a) => {
|
||||
if a.is_rare_item() {
|
||||
return Some(10u32)
|
||||
}
|
||||
return Some((ArmorShopItem::armor_from_item(a).price() / 8) as u32)
|
||||
},
|
||||
ItemDetail::Shield(s) => {
|
||||
if s.is_rare_item() {
|
||||
return Some(10u32)
|
||||
}
|
||||
return Some((ArmorShopItem::shield_from_item(s).price() / 8) as u32)
|
||||
},
|
||||
ItemDetail::Unit(u) => {
|
||||
if u.is_rare_item() {
|
||||
return Some(10u32)
|
||||
}
|
||||
return Some((ArmorShopItem::unit_from_item(u).price() / 8) as u32)
|
||||
},
|
||||
ItemDetail::Tool(t) => {
|
||||
if t.is_rare_item() { // TODO: photon drop/sphere etc
|
||||
return Some(10u32)
|
||||
}
|
||||
return Some((ToolShopItem::tool_from_item(t).price() / 8) as u32)
|
||||
},
|
||||
ItemDetail::TechniqueDisk(d) => { // TODO: are all techs the same?
|
||||
return Some((ToolShopItem::tech_from_item(d).price() / 8) as u32)
|
||||
},
|
||||
ItemDetail::Mag(_m) => { //TODO: error. mags are not sellable
|
||||
return None
|
||||
},
|
||||
ItemDetail::ESWeapon(_e) => {
|
||||
return Some(10u32) // TODO: check price
|
||||
},
|
||||
}
|
||||
},
|
||||
// the number of stacked items sold is handled by the caller. this is just the price of 1
|
||||
InventoryItem::Stacked(stacked_item) => {
|
||||
return Some((ToolShopItem::tool_from_item(&stacked_item.tool).price() / 8) as u32)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::ship::items::ClientItemId;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, BTreeMap};
|
||||
use std::cmp::Ordering;
|
||||
use thiserror::Error;
|
||||
use crate::entity::gateway::EntityGateway;
|
||||
use crate::entity::character::{CharacterEntity, CharacterEntityId, TechLevel};
|
||||
@ -55,6 +56,8 @@ pub enum ItemManagerError {
|
||||
NoArmorEquipped,
|
||||
GatewayError(#[from] crate::entity::gateway::GatewayError),
|
||||
StackedItemError(Vec<ItemEntity>),
|
||||
ItemNotSellable, // TODO: capture what item was attempted to be sold
|
||||
WalletFull,
|
||||
}
|
||||
|
||||
pub struct ItemManager {
|
||||
@ -844,6 +847,49 @@ impl ItemManager {
|
||||
Ok(inventory_item)
|
||||
}
|
||||
|
||||
pub async fn player_sells_item<EG: EntityGateway>(&mut self,
|
||||
entity_gateway: &mut EG,
|
||||
character: &mut CharacterEntity,
|
||||
item_id: ClientItemId,
|
||||
amount: usize)
|
||||
-> Result<(), anyhow::Error> {
|
||||
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
|
||||
let sold_item_handle = inventory.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?;
|
||||
if let Some(item_sold) = sold_item_handle.item() {
|
||||
if let Some(unit_price) = item_sold.get_sell_price() { // -> Option<u32> u32 = meseta, or None if error
|
||||
let total_sale = unit_price * amount as u32;
|
||||
if character.meseta + total_sale <= 999999 {
|
||||
character.meseta += total_sale;
|
||||
match item_sold {
|
||||
InventoryItem::Individual(i) => {
|
||||
entity_gateway.change_item_location(&i.entity_id, ItemLocation::SoldToShop).await?;
|
||||
inventory.remove_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?;
|
||||
},
|
||||
InventoryItem::Stacked(s) => {
|
||||
match amount.cmp(&s.count()) {
|
||||
Ordering::Less | Ordering::Equal => {
|
||||
sold_item_handle.consume(amount)?;
|
||||
},
|
||||
// TODO: put a real error here
|
||||
Ordering::Greater => {println!("i can't believe you've done this.");},
|
||||
};
|
||||
},
|
||||
}
|
||||
entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?;
|
||||
entity_gateway.save_character(&character).await?;
|
||||
} else {
|
||||
return Err(ItemManagerError::WalletFull.into());
|
||||
}
|
||||
} else {
|
||||
return Err(ItemManagerError::ItemNotSellable.into());
|
||||
}
|
||||
} else {
|
||||
return Err(ItemManagerError::ItemIdNotInInventory(item_id).into())
|
||||
}
|
||||
// TODO: why did i put this
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: check if slot exists before putting units into it
|
||||
pub async fn player_equips_item<EG: EntityGateway>(&mut self,
|
||||
entity_gateway: &mut EG,
|
||||
|
@ -370,11 +370,12 @@ where
|
||||
}
|
||||
};
|
||||
|
||||
if client.character.meseta < item.price() as u32 {
|
||||
// TODO: stop giving away wares for free
|
||||
if client.character.meseta < (item.price() * buy_item.amount as usize) as u32 {
|
||||
return Err(ShipError::ShopError.into())
|
||||
}
|
||||
|
||||
client.character.meseta -= item.price() as u32;
|
||||
client.character.meseta -= (item.price() * buy_item.amount as usize) as u32;
|
||||
entity_gateway.save_character(&client.character).await?;
|
||||
|
||||
let inventory_item = item_manager.player_buys_item(entity_gateway, &client.character, item, ClientItemId(buy_item.item_id), buy_item.amount as usize).await?;
|
||||
|
@ -110,7 +110,7 @@ pub fn drop_coordinates(id: ClientId,
|
||||
item_id: ClientItemId(drop_coordinates.item_id),
|
||||
});
|
||||
|
||||
Ok(Box::new(None.into_iter()))
|
||||
Ok(Box::new(None.into_iter())) // TODO: do we need to send a packet here?
|
||||
}
|
||||
|
||||
pub async fn no_longer_has_item<EG>(id: ClientId,
|
||||
@ -254,7 +254,7 @@ where
|
||||
if client.character.meseta >= charge.meseta {
|
||||
client.character.meseta -= charge.meseta;
|
||||
entity_gateway.save_character(&client.character).await?;
|
||||
Ok(Box::new(None.into_iter()))
|
||||
Ok(Box::new(None.into_iter())) // TODO: should probably tell other players we used charge and lost money?
|
||||
} else {
|
||||
Err(ShipError::NotEnoughMeseta(id, client.character.meseta).into())
|
||||
}
|
||||
@ -274,7 +274,7 @@ where
|
||||
let item_used_type = item_manager.player_consumes_tool(entity_gateway, &mut client.character, ClientItemId(player_use_tool.item_id), 1).await?;
|
||||
|
||||
item_manager.use_item(item_used_type, entity_gateway, &mut client.character).await?;
|
||||
Ok(Box::new(None.into_iter()))
|
||||
Ok(Box::new(None.into_iter())) // TODO: should probably tell other players we used an item
|
||||
}
|
||||
|
||||
pub async fn player_used_medical_center<EG>(id: ClientId,
|
||||
@ -333,7 +333,7 @@ where
|
||||
0
|
||||
};
|
||||
item_manager.player_equips_item(entity_gateway, &client.character, ClientItemId(pkt.item_id), equip_slot).await?;
|
||||
Ok(Box::new(None.into_iter()))
|
||||
Ok(Box::new(None.into_iter())) // TODO: tell other players you equipped an item
|
||||
}
|
||||
|
||||
pub async fn player_unequips_item<EG>(id: ClientId,
|
||||
@ -347,7 +347,7 @@ where
|
||||
{
|
||||
let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?;
|
||||
item_manager.player_unequips_item(entity_gateway, &client.character, ClientItemId(pkt.item_id)).await?;
|
||||
Ok(Box::new(None.into_iter()))
|
||||
Ok(Box::new(None.into_iter())) // TODO: tell other players if you unequip an item
|
||||
}
|
||||
|
||||
pub async fn player_sorts_items<EG>(id: ClientId,
|
||||
@ -361,5 +361,21 @@ where
|
||||
{
|
||||
let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?;
|
||||
item_manager.player_sorts_items(entity_gateway, &client.character, pkt.item_ids).await?;
|
||||
Ok(Box::new(None.into_iter())) // Do clients care about the order of other clients items?
|
||||
Ok(Box::new(None.into_iter())) // TODO: clients probably care about each others item orders
|
||||
}
|
||||
|
||||
pub async fn player_sells_item<EG> (id: ClientId,
|
||||
sold_item: &PlayerSoldItem,
|
||||
entity_gateway: &mut EG,
|
||||
// client_location: &ClientLocation,
|
||||
clients: &mut Clients,
|
||||
item_manager: &mut ItemManager)
|
||||
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
||||
where
|
||||
EG: EntityGateway
|
||||
{
|
||||
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
|
||||
item_manager.player_sells_item(entity_gateway, &mut client.character, ClientItemId(sold_item.item_id), sold_item.amount as usize).await?;
|
||||
// TODO: send the packet to other clients
|
||||
Ok(Box::new(None.into_iter()))
|
||||
}
|
||||
|
@ -485,6 +485,9 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
||||
GameMessage::SortItems(sort_items) => {
|
||||
handler::message::player_sorts_items(id, sort_items, &mut self.entity_gateway, &self.clients, &mut self.item_manager).await?
|
||||
},
|
||||
GameMessage::PlayerSoldItem(player_sold_item) => {
|
||||
handler::message::player_sells_item(id, player_sold_item, &mut self.entity_gateway, &mut self.clients, &mut self.item_manager).await?
|
||||
},
|
||||
_ => {
|
||||
let cmsg = msg.clone();
|
||||
let block = self.blocks.with_client(id, &self.clients)?;
|
||||
|
@ -90,6 +90,20 @@ impl ShopItem for ArmorShopItem {
|
||||
}
|
||||
}
|
||||
|
||||
impl ArmorShopItem {
|
||||
pub fn armor_from_item(a: &Armor) -> ArmorShopItem {
|
||||
ArmorShopItem::Frame(a.armor, a.slots as usize)
|
||||
}
|
||||
|
||||
pub fn shield_from_item(s: &Shield) -> ArmorShopItem {
|
||||
ArmorShopItem::Barrier(s.shield)
|
||||
}
|
||||
|
||||
pub fn unit_from_item(u: &Unit) -> ArmorShopItem {
|
||||
ArmorShopItem::Unit(u.unit)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
struct FrameTierItem {
|
||||
|
@ -96,6 +96,16 @@ impl ShopItem for ToolShopItem {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToolShopItem {
|
||||
pub fn tool_from_item(t: &Tool) -> ToolShopItem {
|
||||
ToolShopItem::Tool(t.tool)
|
||||
}
|
||||
|
||||
pub fn tech_from_item(d: &TechniqueDisk) -> ToolShopItem {
|
||||
ToolShopItem::Tech(*d)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct ToolTable(Vec<ToolType>);
|
||||
|
@ -27,7 +27,7 @@ pub struct WeaponShopItem {
|
||||
weapon: WeaponType,
|
||||
special: Option<WeaponSpecial>,
|
||||
grind: usize,
|
||||
attributes: [Option<WeaponAttribute>; 2],
|
||||
attributes: [Option<WeaponAttribute>; 3],
|
||||
}
|
||||
|
||||
impl PartialEq for WeaponShopItem {
|
||||
@ -120,7 +120,6 @@ impl ShopItem for WeaponShopItem {
|
||||
}).unwrap_or(0.0);
|
||||
|
||||
price += special * special * 1000.0;
|
||||
|
||||
price as usize
|
||||
})
|
||||
.unwrap_or(0xFFFF)
|
||||
@ -143,6 +142,17 @@ impl ShopItem for WeaponShopItem {
|
||||
}
|
||||
}
|
||||
|
||||
impl WeaponShopItem {
|
||||
pub fn weapon_from_item(w: &Weapon) -> WeaponShopItem {
|
||||
WeaponShopItem {
|
||||
weapon: w.weapon,
|
||||
special: w.special,
|
||||
grind: w.grind as usize,
|
||||
attributes: w.attrs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct WeaponTableTierEntry {
|
||||
@ -512,10 +522,10 @@ impl<R: Rng + SeedableRng> WeaponShop<R> {
|
||||
};
|
||||
|
||||
WeaponShopItem {
|
||||
weapon,
|
||||
grind,
|
||||
special,
|
||||
attributes: [attr1, attr2],
|
||||
weapon: weapon,
|
||||
grind: grind,
|
||||
special: special,
|
||||
attributes: [attr1, attr2, None],
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user