44#include < cstddef>
55
66#include " openvic-simulation/country/CountryInstance.hpp"
7+ #include " openvic-simulation/defines/EconomyDefines.hpp"
78#include " openvic-simulation/economy/GoodDefinition.hpp"
89#include " openvic-simulation/economy/GoodInstance.hpp"
910#include " openvic-simulation/economy/production/ProductionType.hpp"
@@ -24,7 +25,8 @@ ArtisanalProducer::ArtisanalProducer(
2425 fixed_point_map_t <GoodDefinition const *>&& new_stockpile,
2526 ProductionType const * const new_production_type,
2627 fixed_point_t new_current_production
27- ) : modifier_effect_cache { artisanal_producer_deps.modifier_effect_cache },
28+ ) : economy_defines { artisanal_producer_deps.economy_defines },
29+ modifier_effect_cache { artisanal_producer_deps.modifier_effect_cache },
2830 stockpile { std::move (new_stockpile) },
2931 production_type_nullable { nullptr },
3032 current_production { new_current_production }
@@ -374,9 +376,10 @@ ProductionType const* ArtisanalProducer::pick_production_type(
374376
375377 const fixed_point_t revenue = pop.get_artisanal_revenue ();
376378 const fixed_point_t costs = costs_of_production;
379+ const fixed_point_t base_chance_to_switch_while_profitable = economy_defines.get_goods_focus_swap_chance ();
377380 if (production_type_nullable == nullptr || (revenue <= costs)) {
378381 should_pick_new_production_type = true ;
379- } else {
382+ } else if (base_chance_to_switch_while_profitable > 0 ) {
380383 const fixed_point_t current_score = calculate_production_type_score (
381384 revenue,
382385 costs,
@@ -406,8 +409,26 @@ ProductionType const* ArtisanalProducer::pick_production_type(
406409 }
407410 }
408411
409- // TODO decide based on score and randomness and defines.economy.GOODS_FOCUS_SWAP_CHANCE
410- should_pick_new_production_type = relative_score < fixed_point_t ::_0_50;
412+ // picked so the line hits 0 at relative_score = 2/3 and the area under the curve equals 1
413+ // 2/3 was picked as being in the top 1/3 of production types makes it very unlikely you'll profit from switching.
414+ constexpr fixed_point_t slope = fixed_point_t {-9 } / 2 ;
415+ constexpr fixed_point_t offset = 3 ;
416+
417+ const fixed_point_t change_modifier_from_relative_score = std::max (fixed_point_t ::_0, slope * relative_score + offset);
418+ const fixed_point_t switch_chance = base_chance_to_switch_while_profitable * change_modifier_from_relative_score;
419+ if (switch_chance >= 1 ) {
420+ should_pick_new_production_type = true ;
421+ } else {
422+ constexpr fixed_point_t weights_sum = 1 ;
423+ const fixed_point_t keep_current_chance = weights_sum - switch_chance;
424+ const std::array<fixed_point_t , 2 > weights { keep_current_chance, switch_chance };
425+ const size_t should_switch = sample_weighted_index (
426+ random_number_generator (),
427+ weights,
428+ weights_sum
429+ );
430+ should_pick_new_production_type = should_switch == 1 ;
431+ }
411432 }
412433
413434 if (!should_pick_new_production_type) {
0 commit comments