Make kit generate all possible modulars

This commit is contained in:
juliancoffee 2022-09-05 00:10:30 +03:00
parent 0c5a33b031
commit 421aa44d5f
2 changed files with 61 additions and 37 deletions

View File

@ -479,9 +479,7 @@ pub fn generate_weapons(
let primaries = generate_weapon_primary_components(tool, material, hand_restriction)?;
let mut weapons = Vec::new();
// TODO: should we always ignore handness?
// We seems to do so in `random_weapon`
for (comp, _hand) in primaries {
for (comp, comp_hand) in primaries {
let secondaries = SECONDARY_COMPONENT_POOL
.get(&tool)
.into_iter()
@ -490,7 +488,12 @@ pub fn generate_weapons(
hand_restriction == *hand || hand_restriction.is_none() || hand.is_none()
});
for (def, _hand) in secondaries {
for (def, hand) in secondaries {
if comp_hand.is_some() && hand.is_some() && comp_hand != *hand {
// if handedness of components incompatible, skip
continue;
}
let secondary = Item::new_from_item_base(
ItemBase::Simple(Arc::clone(def)),
Vec::new(),

View File

@ -1944,49 +1944,70 @@ where
if target_inventory.free_slots() < count {
return Err("Inventory doesn't have enough slots".to_owned());
}
let mut rng = thread_rng();
for (item_id, quantity) in kit {
let mut item = match &item_id {
KitSpec::Item(item_id) => Item::new_from_asset(item_id)
.map_err(|_| format!("Unknown item: {:#?}", item_id))?,
push_item(item_id, quantity, server, &mut |item| {
let res = target_inventory.push(item);
let _ = target_inv_update.insert(
target,
comp::InventoryUpdate::new(comp::InventoryUpdateEvent::Debug),
);
res
})?;
}
Ok(())
} else {
Err("Could not get inventory".to_string())
}
}
fn push_item(
item_id: KitSpec,
quantity: u32,
server: &Server,
push: &mut dyn FnMut(Item) -> Result<(), Item>,
) -> CmdResult<()> {
let items = match &item_id {
KitSpec::Item(item_id) => vec![
Item::new_from_asset(item_id).map_err(|_| format!("Unknown item: {:#?}", item_id))?,
],
KitSpec::ModularWeapon { tool, material } => {
comp::item::modular::random_weapon(*tool, *material, None, &mut rng)
comp::item::modular::generate_weapons(*tool, *material, None)
.map_err(|err| format!("{:#?}", err))?
},
};
let mut res = Ok(());
let mut res = Ok(());
for mut item in items {
// Either push stack or push one by one.
if item.is_stackable() {
// FIXME: in theory, this can fail,
// but we don't have stack sizes yet.
let _ = item.set_amount(quantity);
res = target_inventory.push(item);
let _ = target_inv_update.insert(
target,
comp::InventoryUpdate::new(comp::InventoryUpdateEvent::Debug),
);
res = push(item);
} else {
let ability_map = server.state.ecs().read_resource::<AbilityMap>();
let msm = server.state.ecs().read_resource::<MaterialStatManifest>();
for _ in 0..quantity {
res = target_inventory.push(item.duplicate(&ability_map, &msm));
let _ = target_inv_update.insert(
target,
comp::InventoryUpdate::new(comp::InventoryUpdateEvent::Debug),
);
res = push(item.duplicate(&ability_map, &msm));
if res.is_err() {
break;
}
}
}
// I think it's possible to pick-up item during this loop
// and fail into case where you had space but now you don't?
if res.is_err() {
return Err("Can't fit item to inventory".to_owned());
}
}
Ok(())
} else {
Err("Could not get inventory".to_string())
}
}
fn handle_object(