From 349915e995de092284918386c121ad17c480bd14 Mon Sep 17 00:00:00 2001 From: dcsturman Date: Fri, 19 Dec 2025 14:20:41 -0800 Subject: [PATCH 1/4] Add Generate button Don't have prices change on each skill change. Save die rolls. --- src/components/trade_computer.rs | 106 ++++++++++----- src/trade/available_goods.rs | 218 ++++++++++++++++++++++++++++++- src/trade/ship_manifest.rs | 9 ++ 3 files changed, 296 insertions(+), 37 deletions(-) diff --git a/src/components/trade_computer.rs b/src/components/trade_computer.rs index b9f919b..39cf282 100644 --- a/src/components/trade_computer.rs +++ b/src/components/trade_computer.rs @@ -409,30 +409,35 @@ pub fn Trade() -> impl IntoView { (name, uwp) }); - // On a change to origin_world and/or dest_world updating pricing on available goods. - // Those updates are based on RNG so even with the same inputs, will change frequently. + // Recalculate prices when skills change (using saved rolls, not regenerating) Effect::new(move |_| { let buyer = buyer_broker_skill.get(); let supplier = seller_broker_skill.get(); - let distance = distance.get(); - let _illegal_goods = illegal_goods.get(); let origin_world = origin_world.get(); let dest_world = dest_world.get(); debug!( - "Updating goods pricing with origin world = {:?}", - origin_world + "Recalculating goods pricing with skills: buyer={}, supplier={}", + buyer, supplier ); - // Do not wipe the manifest; keep trade goods and sell plans across recalculations + // Recalculate buy prices using saved rolls write_available_goods.update(|ag| { - ag.price_goods_to_buy(&origin_world.get_trade_classes(), buyer, supplier); + ag.recalc_buy_prices(&origin_world.get_trade_classes(), buyer, supplier); + + // Recalculate sell prices if we have a destination + if let Some(ref world) = dest_world { + ag.recalc_sell_prices(Some(&world.get_trade_classes()), supplier, buyer); + } else { + ag.recalc_sell_prices(None, supplier, buyer); + } + ag.sort_by_discount(); }); - // Reprice the manifest. + // Reprice the manifest using saved rolls write_ship_manifest.update(|manifest| { - manifest.price_goods( + manifest.recalc_prices( &origin_world, buyer_broker_skill.get(), seller_broker_skill.get(), @@ -441,29 +446,6 @@ pub fn Trade() -> impl IntoView { let mut rng = rand::rng(); hack_ship_recompute_manifest_price_set.set(rng.random()); - - // Calculate passengers. - if let Some(world) = dest_world { - if distance > 0 { - write_available_passengers.set(Some(AvailablePassengers::generate( - origin_world.get_population(), - origin_world.port, - origin_world.travel_zone, - origin_world.tech_level, - world.get_population(), - world.port, - world.travel_zone, - world.tech_level, - distance, - i32::from(steward_skill.get()), - i32::from(buyer_broker_skill.get()), - ))); - } else { - write_available_passengers.set(None); - } - } else { - write_available_passengers.set(None); - } }); view! { @@ -487,6 +469,61 @@ pub fn Trade() -> impl IntoView { coords=dest_coords zone=dest_zone /> +
+ +
@@ -1694,6 +1731,9 @@ fn ShipManifestView( sell_price: None, sell_price_comment: String::new(), source_index: entry.index, + quantity_roll: qty / entry.quantity.multiplier as i32, + buy_price_roll: 10, // Default middle roll + sell_price_roll: None, }; write_ship_manifest .update(|manifest| { diff --git a/src/trade/available_goods.rs b/src/trade/available_goods.rs index 98f97b3..7f71f7f 100644 --- a/src/trade/available_goods.rs +++ b/src/trade/available_goods.rs @@ -104,6 +104,14 @@ use crate::trade::TradeClass; /// Each good maintains a reference to its source trade table entry, allowing /// access to trade DMs, availability restrictions, and other metadata needed /// for advanced trade calculations. +/// +/// ## Saved Rolls +/// +/// To prevent recalculation on every parameter change, the original dice rolls +/// are saved and used to recalculate prices when skills change: +/// - **quantity_roll**: Raw dice total before population modifier and multiplier +/// - **buy_price_roll**: Raw 3d6 roll for buy price calculation +/// - **sell_price_roll**: Raw 3d6 roll for sell price calculation (if applicable) #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] pub struct Good { /// Name of the good @@ -125,6 +133,12 @@ pub struct Good { pub sell_price_comment: String, /// Index into the trade table for this good. pub source_index: i16, + /// Raw dice roll for quantity (before population modifier and multiplier) + pub quantity_roll: i32, + /// Raw 3d6 roll for buy price calculation + pub buy_price_roll: i32, + /// Raw 3d6 roll for sell price calculation (if applicable) + pub sell_price_roll: Option, } impl Display for Good { @@ -312,11 +326,13 @@ impl AvailableGoodsTable { let dice_count: i32 = entry.quantity.dice as i32; let multiplier: i32 = entry.quantity.multiplier as i32; - let mut total = 0i32; + // Save the raw dice roll before modifiers + let mut raw_roll = 0i32; for _ in 0..dice_count { - total += rng.random_range(1..=6); + raw_roll += rng.random_range(1..=6); } + let mut total = raw_roll; total += if world_population <= 3 { -3 } else if world_population >= 9 { @@ -339,6 +355,7 @@ impl AvailableGoodsTable { .find(|g| g.source_index == entry.index) { existing.quantity += quantity; + // Note: we keep the original quantity_roll from the first generation return Ok(()); } @@ -353,6 +370,9 @@ impl AvailableGoodsTable { sell_price: None, sell_price_comment: String::default(), source_index: entry.index, + quantity_roll: raw_roll, + buy_price_roll: 0, // Will be set when pricing + sell_price_roll: None, }; self.goods.push(good); @@ -566,8 +586,9 @@ impl AvailableGoodsTable { ) { let mut rng = rand::rng(); for good in &mut self.goods { - // Roll 2d6 + // Roll 3d6 and save it let roll = rng.random_range(1..=6) + rng.random_range(1..=6) + rng.random_range(1..=6); + good.buy_price_roll = roll; let entry = TradeTable::global() .get(good.source_index) @@ -710,6 +731,32 @@ impl AvailableGoodsTable { } } + /// Recalculate buy prices using saved rolls + /// This allows skill changes to update prices without re-rolling + pub fn recalc_buy_prices( + &mut self, + origin_trade_classes: &[TradeClass], + buyer_broker_skill: i16, + supplier_broker_skill: i16, + ) { + for good in &mut self.goods { + good.recalc_buy_price(origin_trade_classes, buyer_broker_skill, supplier_broker_skill); + } + } + + /// Recalculate sell prices using saved rolls + /// This allows skill changes to update prices without re-rolling + pub fn recalc_sell_prices( + &mut self, + dest_trade_classes: Option<&[TradeClass]>, + seller_broker_skill: i16, + buyer_broker_skill: i16, + ) { + for good in &mut self.goods { + good.recalc_sell_price(dest_trade_classes, seller_broker_skill, buyer_broker_skill); + } + } + /// Sort goods from most discounted to least discounted pub fn sort_by_discount(&mut self) { self.goods.sort_by(|a, b| { @@ -737,8 +784,9 @@ impl Good { mut rng: impl rand::Rng, ) { if let Some(trade_classes) = trade_classes { - // Roll 3d6 + // Roll 3d6 and save it let roll = rng.random_range(1..=6) + rng.random_range(1..=6) + rng.random_range(1..=6); + self.sell_price_roll = Some(roll); let entry = TradeTable::global() .get(self.source_index) @@ -800,6 +848,156 @@ impl Good { ); self.sell_price = Some((self.base_cost as f64 * price_multiplier).round() as i32); + } else { + self.sell_price = None; + self.sell_price_roll = None; + self.sell_price_comment.clear(); + } + } + + /// Recalculate buy price using saved roll + /// This allows skill changes to update prices without re-rolling + pub fn recalc_buy_price( + &mut self, + origin_trade_classes: &[TradeClass], + buyer_broker_skill: i16, + supplier_broker_skill: i16, + ) { + let roll = self.buy_price_roll; + + let entry = TradeTable::global() + .get(self.source_index) + .unwrap_or_else(|| { + panic!( + "Failed to get trade table entry for index {}", + &self.source_index + ) + }); + let purchase_origin_dm = find_max_dm(&entry.purchase_dm, origin_trade_classes); + let sale_origin_dm = find_max_dm(&entry.sale_dm, origin_trade_classes); + + // Calculate the modified roll + let modified_roll = roll as i16 + buyer_broker_skill - supplier_broker_skill + + purchase_origin_dm + - sale_origin_dm; + + // Determine the price multiplier based on the modified roll + let price_multiplier = match modified_roll { + i16::MIN..=-3 => 3.0, // 300% + -2 => 2.5, // 250% + -1 => 2.0, // 200% + 0 => 1.75, // 175% + 1 => 1.5, // 150% + 2 => 1.35, // 135% + 3 => 1.25, // 125% + 4 => 1.2, // 120% + 5 => 1.15, // 115% + 6 => 1.1, // 110% + 7 => 1.05, // 105% + 8 => 1.0, // 100% + 9 => 0.95, // 95% + 10 => 0.9, // 90% + 11 => 0.85, // 85% + 12 => 0.8, // 80% + 13 => 0.75, // 75% + 14 => 0.7, // 70% + 15 => 0.65, // 65% + 16 => 0.6, // 60% + 17 => 0.55, // 55% + 18 => 0.5, // 50% + 19 => 0.45, // 45% + 20 => 0.4, // 40% + 21 => 0.35, // 35% + 22 => 0.3, // 30% + 23 => 0.25, // 25% + 24 => 0.2, // 20% + 25.. => 0.15, // 15% + }; + + self.buy_cost_comment = format!( + "(roll) {} + (broker) {} + (trade mod) {} = {} which gives a multiplier of {}", + roll, + buyer_broker_skill - supplier_broker_skill, + purchase_origin_dm - sale_origin_dm, + modified_roll, + price_multiplier + ); + + // Apply the multiplier to the cost + self.buy_cost = (self.base_cost as f64 * price_multiplier).round() as i32; + } + + /// Recalculate sell price using saved roll + /// This allows skill changes to update prices without re-rolling + pub fn recalc_sell_price( + &mut self, + trade_classes: Option<&[TradeClass]>, + seller_broker_skill: i16, + buyer_broker_skill: i16, + ) { + if let Some(trade_classes) = trade_classes { + if let Some(roll) = self.sell_price_roll { + let entry = TradeTable::global() + .get(self.source_index) + .unwrap_or_else(|| { + panic!( + "Failed to get trade table entry for index {}", + &self.source_index + ) + }); + + let purchase_origin_dm = find_max_dm(&entry.purchase_dm, trade_classes); + let sale_origin_dm = find_max_dm(&entry.sale_dm, trade_classes); + + // Calculate the modified roll + let modified_roll = + roll as i16 + seller_broker_skill - buyer_broker_skill - purchase_origin_dm + + sale_origin_dm; + + // Determine the price multiplier based on the modified roll + let price_multiplier = match modified_roll { + i16::MIN..=-3 => 0.1, + -2 => 0.2, + -1 => 0.3, + 0 => 0.4, + 1 => 0.45, + 2 => 0.5, + 3 => 0.55, + 4 => 0.60, + 5 => 0.65, + 6 => 0.70, + 7 => 0.75, + 8 => 0.80, + 9 => 0.85, + 10 => 0.9, + 11 => 1.0, + 12 => 1.05, + 13 => 1.10, + 14 => 1.15, + 15 => 1.20, + 16 => 1.25, + 17 => 1.30, + 18 => 1.40, + 19 => 1.50, + 20 => 1.60, + 21 => 1.75, + 22 => 2.0, + 23 => 2.5, + 24 => 3.0, + 25.. => 4.0, + }; + + self.sell_price_comment = format!( + "(roll) {} + (broker) {} + (trade mod) {} = {} which gives a multiplier of {}", + roll, + seller_broker_skill - buyer_broker_skill, + sale_origin_dm - purchase_origin_dm, + modified_roll, + price_multiplier + ); + + self.sell_price = Some((self.base_cost as f64 * price_multiplier).round() as i32); + } } else { self.sell_price = None; self.sell_price_comment.clear(); @@ -1030,6 +1228,9 @@ mod tests { sell_price_comment: String::default(), sell_price: None, source_index: 11, + quantity_roll: 10, + buy_price_roll: 10, + sell_price_roll: None, }; // Check the display output @@ -1099,6 +1300,9 @@ mod tests { sell_price_comment: String::default(), sell_price: None, source_index: 11, + quantity_roll: 10, + buy_price_roll: 10, + sell_price_roll: None, }; let good2 = Good { @@ -1111,6 +1315,9 @@ mod tests { sell_price_comment: String::default(), sell_price: None, source_index: 12, + quantity_roll: 10, + buy_price_roll: 10, + sell_price_roll: None, }; let good3 = Good { @@ -1123,6 +1330,9 @@ mod tests { sell_price_comment: String::default(), sell_price: None, source_index: 13, + quantity_roll: 10, + buy_price_roll: 10, + sell_price_roll: None, }; // Add goods in random order diff --git a/src/trade/ship_manifest.rs b/src/trade/ship_manifest.rs index 770e76e..59f4d9a 100644 --- a/src/trade/ship_manifest.rs +++ b/src/trade/ship_manifest.rs @@ -91,6 +91,15 @@ impl ShipManifest { .price_goods_to_sell(Some(trade_classes), buyer, supplier); } + /// Recalculate prices for all goods in the manifest using saved rolls. + /// + /// This allows skill changes to update prices without re-rolling. + pub fn recalc_prices(&mut self, world: &World, buyer: i16, supplier: i16) { + let trade_classes = world.get_trade_classes(); + self.trade_goods + .recalc_sell_prices(Some(&trade_classes), supplier, buyer); + } + /// /// Calculates total passenger revenue for the manifest /// From 799f3ab05b6d2fde3eea9501f5874c028fe27772 Mon Sep 17 00:00:00 2001 From: dcsturman Date: Mon, 22 Dec 2025 15:40:28 -0600 Subject: [PATCH 2/4] Changed when we reroll dice Dice used to be rerolled for everything on every change. Now they are rerolled only when they have to be so you can raise and lower e.g. broker skill and get the same result. --- src/components/system_generator.rs | 1 - src/components/trade_computer.rs | 252 ++++++++----- src/components/traveller_map.rs | 11 +- src/systems/gas_giant.rs | 2 - src/systems/system_tables.rs | 2 - src/trade/available_goods.rs | 229 ++---------- src/trade/available_passengers.rs | 572 ++++++++++++++++++++++++++--- src/trade/ship_manifest.rs | 22 +- 8 files changed, 737 insertions(+), 354 deletions(-) diff --git a/src/components/system_generator.rs b/src/components/system_generator.rs index b23df60..bd96407 100644 --- a/src/components/system_generator.rs +++ b/src/components/system_generator.rs @@ -203,7 +203,6 @@ pub fn World() -> impl IntoView { Effect::new(move |_| { let upp = upp.get(); let name = main_world_name.get(); - debug!("Building world {name} with UPP {upp}"); // Attempt to parse the UWP string into a world object let Ok(mut w) = World::from_upp(&name, upp.as_str(), false, true) else { diff --git a/src/components/trade_computer.rs b/src/components/trade_computer.rs index 39cf282..8e3bfa6 100644 --- a/src/components/trade_computer.rs +++ b/src/components/trade_computer.rs @@ -309,7 +309,6 @@ pub fn Trade() -> impl IntoView { let calculated_distance = crate::components::traveller_map::calculate_hex_distance( origin.0, origin.1, dest.0, dest.1, ); - debug!("Calculated distance = {calculated_distance}"); distance.set(calculated_distance); } }; @@ -319,8 +318,11 @@ pub fn Trade() -> impl IntoView { Effect::new(move |_| { let _ = hack_ship_recompute_manifest_price.get(); write_ship_manifest.update(|manifest| { + debug!("PRICE GOODS WITH ORIGIN A"); + // Set world_to_use to be the dest_world if it exists otherwise use the origin_world. + let world_to_use = dest_world.get().unwrap_or_else(|| origin_world.get()); manifest.price_goods( - &origin_world.get(), + &Some(world_to_use), buyer_broker_skill.get(), seller_broker_skill.get(), ); @@ -332,20 +334,12 @@ pub fn Trade() -> impl IntoView { Effect::new(move |prev: Option<(String, String)>| { if let Some((prev_name, prev_uwp)) = &prev { if *prev_name == origin_world_name.get() && *prev_uwp == origin_uwp.get() { - debug!("Origin world name and uwp haven't changed; skipping rebuild: {prev_name}, {prev_uwp}"); return (prev_name.to_string(), prev_uwp.to_string()); } } - debug!( - "Rebuilding origin world as name or uwp changed. Was {:?}; Now name = {}, uwp = {} ", - &prev, - origin_world_name.get(), - origin_uwp.get() - ); let name = origin_world_name.get(); let uwp = origin_uwp.get(); - debug!("In first Effect: name = {name}, uwp = {uwp}"); if !name.is_empty() && uwp.len() == 9 { let Ok(mut world) = World::from_upp(&name, &uwp, false, false) else { log::error!("Failed to parse UPP in hook to build origin world: {uwp}"); @@ -380,7 +374,6 @@ pub fn Trade() -> impl IntoView { Effect::new(move |prev: Option<(String, String)>| { if let Some((prev_name, prev_uwp)) = &prev { if *prev_name == dest_world_name.get() && *prev_uwp == dest_uwp.get() { - debug!("Destination world name and uwp haven't changed; skipping rebuild: {prev_name}, {prev_uwp}"); return (prev_name.to_string(), prev_uwp.to_string()); } } @@ -388,7 +381,6 @@ pub fn Trade() -> impl IntoView { let name = dest_world_name.get(); let uwp = dest_uwp.get(); - debug!("Rebuilding destination world as name or uwp changed."); if !name.is_empty() && uwp.len() == 9 { let Ok(mut world) = World::from_upp(&name, &uwp, false, false) else { log::error!("Failed to parse UPP in hook to build destination world: {uwp}"); @@ -398,8 +390,28 @@ pub fn Trade() -> impl IntoView { world.gen_trade_classes(); world.coordinates = dest_coords.get(); world.travel_zone = dest_zone.get(); - write_dest_world.set(Some(world)); + + let was_none = dest_world.get().is_none(); + write_dest_world.set(Some(world.clone())); calc_distance_closure(); + + // Generate passengers and freight when destination is added for the first time + if was_none && distance.get() > 0 { + let origin = origin_world.get(); + write_available_passengers.set(Some(AvailablePassengers::generate( + origin.get_population(), + origin.port, + origin.travel_zone, + origin.tech_level, + world.get_population(), + world.port, + world.travel_zone, + world.tech_level, + distance.get(), + i32::from(steward_skill.get()), + i32::from(buyer_broker_skill.get()), + ))); + } } else { // If we don't have a valid name, reset other UI elements to reasonable defaults. write_dest_world.set(None); @@ -409,43 +421,78 @@ pub fn Trade() -> impl IntoView { (name, uwp) }); - // Recalculate prices when skills change (using saved rolls, not regenerating) - Effect::new(move |_| { + // Recalculate prices and passengers when skills or world parameters change (using saved rolls, not regenerating) + Effect::new(move |prev_dest: Option>| { let buyer = buyer_broker_skill.get(); let supplier = seller_broker_skill.get(); + let steward = steward_skill.get(); let origin_world = origin_world.get(); let dest_world = dest_world.get(); + let dist = distance.get(); - debug!( - "Recalculating goods pricing with skills: buyer={}, supplier={}", - buyer, supplier - ); + // Check if destination world changed (not just skills) + let current_dest_name = dest_world.as_ref().map(|w| w.name.clone()); + let dest_changed = prev_dest.is_some() && prev_dest.as_ref() != Some(¤t_dest_name); // Recalculate buy prices using saved rolls write_available_goods.update(|ag| { - ag.recalc_buy_prices(&origin_world.get_trade_classes(), buyer, supplier); + ag.price_goods_to_buy(&origin_world.get_trade_classes(), buyer, supplier); // Recalculate sell prices if we have a destination if let Some(ref world) = dest_world { - ag.recalc_sell_prices(Some(&world.get_trade_classes()), supplier, buyer); + ag.price_goods_to_sell(Some(world.get_trade_classes()), supplier, buyer); } else { - ag.recalc_sell_prices(None, supplier, buyer); + ag.price_goods_to_sell(None, supplier, buyer); } ag.sort_by_discount(); }); - // Reprice the manifest using saved rolls + // Reprice the manifest + // Manifest goods are sold at the destination, so use dest_world for pricing write_ship_manifest.update(|manifest| { - manifest.recalc_prices( - &origin_world, + // Destination changed - generate new sell price rolls + debug!( + "EFFECT A: Destination changed, generating new prices for manifest on world {}.", + dest_world + .as_ref() + .map(|w| w.name.clone()) + .unwrap_or_else(|| "None".to_string()) + ); + manifest.price_goods( + &dest_world, buyer_broker_skill.get(), seller_broker_skill.get(), ); }); + // Recalculate passengers and freight using saved rolls + if let Some(ref world) = dest_world { + if dist > 0 { + write_available_passengers.update(|passengers_opt| { + if let Some(passengers) = passengers_opt { + passengers.recalculate( + origin_world.get_population(), + origin_world.port, + origin_world.travel_zone, + origin_world.tech_level, + world.get_population(), + world.port, + world.travel_zone, + world.tech_level, + dist, + i32::from(steward), + i32::from(buyer), + ); + } + }); + } + } + let mut rng = rand::rng(); hack_ship_recompute_manifest_price_set.set(rng.random()); + + current_dest_name }); view! { @@ -473,46 +520,50 @@ pub fn Trade() -> impl IntoView {
} @@ -771,37 +822,56 @@ fn GoodsToSellView( } #[component] -fn SellGoodRow(good: Good, write_ship_manifest: WriteSignal) -> impl IntoView { - let mut good_copy = good.clone(); +fn SellGoodRow( + good_index: i16, + ship_manifest: Signal, + write_ship_manifest: WriteSignal, +) -> impl IntoView { + let good = Memo::new(move |_| { + ship_manifest.with(|manifest| { + manifest + .trade_goods + .get_by_index(good_index) + .cloned() + .unwrap_or_default() + }) + }); + let update_sold = move |ev| { + let current_good = good.get_untracked(); let new_value = event_target_value(&ev) .parse::() .unwrap_or(0) - .clamp(0, good_copy.quantity); - good_copy.transacted = new_value; - debug!("Updating sold quantity to {new_value} for {good_copy:?}"); + .clamp(0, current_good.quantity); write_ship_manifest.update(|manifest| { - manifest.trade_goods.update_good(good_copy.clone()); + manifest.trade_goods.update_good(Good { + transacted: new_value, + ..current_good + }); }); }; - let sell_cost_comment = move || good.sell_price_comment.clone(); + let sell_cost_comment = move || good.get().sell_price_comment.clone(); view! { - {move || good.name.clone()} - {move || good.quantity.to_string()} - {move || good.base_cost.to_string()} - {move || good.buy_cost.to_string()} + {move || good.get().name.clone()} + {move || good.get().quantity.to_string()} + {move || good.get().base_cost.to_string()} + {move || good.get().buy_cost.to_string()} {move || { - if let Some(sp) = good.sell_price { sp.to_string() } else { "-".to_string() } + if let Some(sp) = good.get().sell_price { + sp.to_string() + } else { + "-".to_string() + } }} {move || { - if let Some(sp) = good.sell_price { - let pct = (((sp as f64 / good.buy_cost as f64) * 100.0) - 100.0).round() - as i32; + if let Some(sp) = good.get().sell_price { + let pct = (((sp as f64 / good.get().buy_cost as f64) * 100.0) - 100.0) + .round() as i32; format!("{}%", pct) } else { "-".to_string() @@ -812,11 +882,11 @@ fn SellGoodRow(good: Good, write_ship_manifest: WriteSignal) -> im 0 { + if good.get().transacted > 0 { "purchased-input purchased-input-active" } else { "purchased-input" @@ -1336,7 +1406,8 @@ fn PassengerView( #[component] fn ShipManifestView( origin_swap: impl Fn() + Clone + 'static, - origin_world: Signal, + _origin_world: Signal, + dest_world: Signal>, buyer_broker_skill: Signal, seller_broker_skill: Signal, distance: RwSignal, @@ -1574,7 +1645,7 @@ fn ShipManifestView( {move || { let manifest = ship_manifest.get(); let revenue = if let Some(passengers) = available_passengers.get() { - manifest.freight_revenue(distance.get(), &passengers) as i64 + manifest.freight_revenue(distance.get(), &passengers) as i64 } else { 0 }; @@ -1601,8 +1672,10 @@ fn ShipManifestView( let manifest = ship_manifest.get(); let passenger_revenue = manifest.passenger_revenue(distance.get()) as i64; - let freight_revenue = if let Some(passengers) = available_passengers.get() { - manifest.freight_revenue(distance.get(), &passengers) as i64 + let freight_revenue = if let Some(passengers) = available_passengers + .get() + { + manifest.freight_revenue(distance.get(), &passengers) as i64 } else { 0 }; @@ -1618,17 +1691,18 @@ fn ShipManifestView(