From aad65c615917e0e9c6f8bc26f14ffec07d9981c0 Mon Sep 17 00:00:00 2001 From: juliancoffee Date: Sat, 5 Jun 2021 19:22:51 +0300 Subject: [PATCH] Move traveler loadout declaration to asset * New loadout/world/traveler.ron file to specify traveler loadout * LoadoutBuilder::with_asset_expect now can use passed rng to choose items --- assets/common/loadout/world/traveler.ron | 28 +++++++++ common/src/comp/inventory/loadout_builder.rs | 64 +++++++++++--------- server/src/rtsim/entity.rs | 59 +----------------- 3 files changed, 66 insertions(+), 85 deletions(-) create mode 100644 assets/common/loadout/world/traveler.ron diff --git a/assets/common/loadout/world/traveler.ron b/assets/common/loadout/world/traveler.ron new file mode 100644 index 0000000000..c2126e5496 --- /dev/null +++ b/assets/common/loadout/world/traveler.ron @@ -0,0 +1,28 @@ +({ + ActiveMainhand: Choice([ + (1.0, Some(Item("common.items.weapons.sword.wood-2"))), + (1.0, Some(Item("common.items.weapons.sword.starter"))), + (1.0, Some(Item("common.items.weapons.sword.wood-0"))), + (1.0, Some(Item("common.items.weapons.bow.starter"))), + (1.0, Some(Item("common.items.weapons.bow.hardwood-2"))), + ]), + + Armor(Chest): Item("common.items.npc_armor.chest.leather_blue"), + Armor(Legs): Item("common.items.npc_armor.pants.leather_blue"), + Armor(Shoulders): Item("common.items.armor.swift.shoulder"), + + Armor(Back): Choice([ + (1.0, Some(Item("common.items.armor.hide.rawhide.back"))), + (1.0, Some(Item("common.items.armor.misc.back.backpack"))), + (1.0, Some(Item("common.items.npc_armor.back.backpack_blue"))), + (1.0, Some(Item("common.items.npc_armor.back.leather_blue"))), + (1.0, None), + ]), + + Lantern: Choice([ + (1.0, Some(Item("common.items.lantern.black_0"))), + (1.0, Some(Item("common.items.lantern.blue_0"))), + (1.0, Some(Item("common.items.lantern.green_0"))), + (1.0, Some(Item("common.items.lantern.red_0"))), + ]), +}) diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index 87013950cc..5453a9b0c2 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -73,16 +73,16 @@ enum ItemSpec { } impl ItemSpec { - fn try_to_item(&self, asset_specifier: &str) -> Option { + fn try_to_item(&self, asset_specifier: &str, rng: &mut impl Rng) -> Option { match self { ItemSpec::Item(specifier) => Some(Item::new_from_asset_expect(&specifier)), ItemSpec::Choice(items) => { - choose(&items, asset_specifier) + choose(&items, asset_specifier, rng) .as_ref() .and_then(|e| match e { - entry @ ItemSpec::Item { .. } => entry.try_to_item(asset_specifier), - choice @ ItemSpec::Choice { .. } => choice.try_to_item(asset_specifier), + entry @ ItemSpec::Item { .. } => entry.try_to_item(asset_specifier, rng), + choice @ ItemSpec::Choice { .. } => choice.try_to_item(asset_specifier, rng), }) }, } @@ -108,10 +108,12 @@ impl ItemSpec { } } -fn choose<'a>(items: &'a [(f32, Option)], asset_specifier: &str) -> &'a Option { - let mut rng = rand::thread_rng(); - - items.choose_weighted(&mut rng, |item| item.0).map_or_else( +fn choose<'a>( + items: &'a [(f32, Option)], + asset_specifier: &str, + rng: &mut impl Rng, +) -> &'a Option { + items.choose_weighted(rng, |item| item.0).map_or_else( |err| match err { WeightedError::NoItem | WeightedError::AllWeightsZero => &None, WeightedError::InvalidWeight => { @@ -394,10 +396,15 @@ impl LoadoutBuilder { } #[must_use] - pub fn from_asset_expect(asset_specifier: &str) -> Self { + pub fn from_asset_expect(asset_specifier: &str, rng: Option<&mut impl Rng>) -> Self { let loadout = Self::new(); - loadout.with_asset_expect(asset_specifier) + if let Some(rng) = rng { + loadout.with_asset_expect(asset_specifier, rng) + } else { + let rng = &mut rand::thread_rng(); + loadout.with_asset_expect(asset_specifier, rng) + } } /// # Usage @@ -409,10 +416,10 @@ impl LoadoutBuilder { /// 2) Will panic if path to item specified in loadout file doesn't exist /// 3) Will panic while runs in tests and asset doesn't have "correct" form #[must_use] - pub fn with_asset_expect(mut self, asset_specifier: &str) -> Self { + pub fn with_asset_expect(mut self, asset_specifier: &str, rng: &mut impl Rng) -> Self { let spec = LoadoutSpec::load_expect(asset_specifier).read().0.clone(); for (key, entry) in spec { - let item = match entry.try_to_item(asset_specifier) { + let item = match entry.try_to_item(asset_specifier, rng) { Some(item) => item, None => continue, }; @@ -485,7 +492,10 @@ impl LoadoutBuilder { /// Set default armor items for the loadout. This may vary with game /// updates, but should be safe defaults for a new character. #[must_use] - pub fn defaults(self) -> Self { self.with_asset_expect("common.loadout.default") } + pub fn defaults(self) -> Self { + let rng = &mut rand::thread_rng(); + self.with_asset_expect("common.loadout.default", rng) + } /// Builds loadout of creature when spawned #[must_use] @@ -523,51 +533,52 @@ impl LoadoutBuilder { } }); // Creates rest of loadout + let rng = &mut rand::thread_rng(); let loadout_builder = if let Some(config) = config { let builder = Self::new().active_mainhand(active_item); // NOTE: we apply asset after active mainhand so asset has ability override it match config { LoadoutConfig::Gnarling => match active_tool_kind { Some(ToolKind::Bow | ToolKind::Staff | ToolKind::Spear) => { - builder.with_asset_expect("common.loadout.dungeon.tier-0.gnarling") + builder.with_asset_expect("common.loadout.dungeon.tier-0.gnarling", rng) }, _ => builder, }, LoadoutConfig::Adlet => match active_tool_kind { Some(ToolKind::Bow) => { - builder.with_asset_expect("common.loadout.dungeon.tier-1.adlet_bow") + builder.with_asset_expect("common.loadout.dungeon.tier-1.adlet_bow", rng) }, Some(ToolKind::Spear | ToolKind::Staff) => { - builder.with_asset_expect("common.loadout.dungeon.tier-1.adlet_spear") + builder.with_asset_expect("common.loadout.dungeon.tier-1.adlet_spear", rng) }, _ => builder, }, LoadoutConfig::Sahagin => { - builder.with_asset_expect("common.loadout.dungeon.tier-2.sahagin") + builder.with_asset_expect("common.loadout.dungeon.tier-2.sahagin", rng) }, LoadoutConfig::Haniwa => { - builder.with_asset_expect("common.loadout.dungeon.tier-3.haniwa") + builder.with_asset_expect("common.loadout.dungeon.tier-3.haniwa", rng) }, LoadoutConfig::Myrmidon => { - builder.with_asset_expect("common.loadout.dungeon.tier-4.myrmidon") + builder.with_asset_expect("common.loadout.dungeon.tier-4.myrmidon", rng) }, LoadoutConfig::Husk => { - builder.with_asset_expect("common.loadout.dungeon.tier-5.husk") + builder.with_asset_expect("common.loadout.dungeon.tier-5.husk", rng) }, LoadoutConfig::Beastmaster => { - builder.with_asset_expect("common.loadout.dungeon.tier-5.beastmaster") + builder.with_asset_expect("common.loadout.dungeon.tier-5.beastmaster", rng) }, LoadoutConfig::Warlord => { - builder.with_asset_expect("common.loadout.dungeon.tier-5.warlord") + builder.with_asset_expect("common.loadout.dungeon.tier-5.warlord", rng) }, LoadoutConfig::Warlock => { - builder.with_asset_expect("common.loadout.dungeon.tier-5.warlock") + builder.with_asset_expect("common.loadout.dungeon.tier-5.warlock", rng) }, LoadoutConfig::Villager => builder - .with_asset_expect("common.loadout.village.villager") + .with_asset_expect("common.loadout.village.villager", rng) .bag(ArmorSlot::Bag1, Some(make_potion_bag(10))), LoadoutConfig::Guard => builder - .with_asset_expect("common.loadout.village.guard") + .with_asset_expect("common.loadout.village.guard", rng) .bag(ArmorSlot::Bag1, Some(make_potion_bag(25))), LoadoutConfig::Merchant => { let mut backpack = @@ -618,7 +629,6 @@ impl LoadoutBuilder { } } } - let mut rng = rand::thread_rng(); let mut item_with_amount = |item_id: &str, amount: &mut f32| { if *amount > 0.0 { let mut item = Item::new_from_asset_expect(item_id); @@ -685,7 +695,7 @@ impl LoadoutBuilder { } } builder - .with_asset_expect("common.loadout.village.merchant") + .with_asset_expect("common.loadout.village.merchant", rng) .back(Some(backpack)) .bag(ArmorSlot::Bag1, Some(bag1)) .bag(ArmorSlot::Bag2, Some(bag2)) diff --git a/server/src/rtsim/entity.rs b/server/src/rtsim/entity.rs index 940297025d..5405f10cea 100644 --- a/server/src/rtsim/entity.rs +++ b/server/src/rtsim/entity.rs @@ -77,65 +77,8 @@ impl Entity { pub fn get_loadout(&self) -> comp::inventory::loadout::Loadout { let mut rng = self.rng(PERM_LOADOUT); - let main_tool = comp::Item::new_from_asset_expect( - (&[ - "common.items.weapons.sword.wood-2", - "common.items.weapons.sword.starter", - "common.items.weapons.sword.wood-0", - "common.items.weapons.bow.starter", - "common.items.weapons.bow.hardwood-2", - ]) - .choose(&mut rng) - .unwrap(), - ); - let back = match rng.gen_range(0..5) { - 0 => Some(comp::Item::new_from_asset_expect( - "common.items.armor.hide.rawhide.back", - )), - 1 => Some(comp::Item::new_from_asset_expect( - "common.items.armor.misc.back.backpack", - )), - 2 => Some(comp::Item::new_from_asset_expect( - "common.items.npc_armor.back.backpack_blue", - )), - 3 => Some(comp::Item::new_from_asset_expect( - "common.items.npc_armor.back.leather_blue", - )), - _ => None, - }; - - let lantern = match rng.gen_range(0..4) { - 0 => Some(comp::Item::new_from_asset_expect( - "common.items.lantern.black_0", - )), - 1 => Some(comp::Item::new_from_asset_expect( - "common.items.lantern.blue_0", - )), - 2 => Some(comp::Item::new_from_asset_expect( - "common.items.lantern.green_0", - )), - _ => Some(comp::Item::new_from_asset_expect( - "common.items.lantern.red_0", - )), - }; - - let chest = Some(comp::Item::new_from_asset_expect( - "common.items.npc_armor.chest.leather_blue", - )); - let pants = Some(comp::Item::new_from_asset_expect( - "common.items.npc_armor.pants.leather_blue", - )); - let shoulder = Some(comp::Item::new_from_asset_expect( - "common.items.armor.hide.leather.shoulder", - )); - - LoadoutBuilder::build_loadout(self.get_body(), Some(main_tool), None, None) - .back(back) - .lantern(lantern) - .chest(chest) - .pants(pants) - .shoulder(shoulder) + LoadoutBuilder::from_asset_expect("common.loadout.world.traveler", &mut rng) .bag( comp::inventory::slot::ArmorSlot::Bag1, Some(comp::inventory::loadout_builder::make_potion_bag(100)),