Skip to content

Commit

Permalink
Adjust crafting catastrophic failure chances
Browse files Browse the repository at this point in the history
Fudge the numbers to make catastrophic (item-destroying) failures much
less likely than setback failures.
Also display the chance of a catastrophic failure in the UI.
  • Loading branch information
anothersimulacrum committed Oct 6, 2022
1 parent f06f1a4 commit 7d8e043
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -3116,8 +3116,10 @@ class Character : public Creature, public visitable
* @return a value >= 0.0 with >= 1.0 representing unequivocal success
*/
float crafting_success_roll( const recipe &making ) const;
float crafting_failure_roll( const recipe &making ) const;
float get_recipe_weighted_skill_average( const recipe &making ) const;
float recipe_success_chance( const recipe &making ) const;
float item_destruction_chance( const recipe &making ) const;
craft_roll_data recipe_success_roll_data( const recipe &making ) const;
craft_roll_data recipe_failure_roll_data( const recipe &making ) const;
void complete_craft( item &craft, const cata::optional<tripoint> &loc );
Expand Down
34 changes: 32 additions & 2 deletions src/crafting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1158,6 +1158,16 @@ Character::craft_roll_data Character::recipe_success_roll_data( const recipe &ma
return ret;
}

Character::craft_roll_data Character::recipe_failure_roll_data( const recipe &making ) const
{
craft_roll_data data = recipe_success_roll_data( making );
// Fund the numbers for the outcomes we want
data.final_difficulty -= 1;
data.final_difficulty *= 0.25;
data.stddev *= 0.5;
return data;
}

float Character::crafting_success_roll( const recipe &making ) const
{
craft_roll_data data = recipe_success_roll_data( making );
Expand All @@ -1169,6 +1179,17 @@ float Character::crafting_success_roll( const recipe &making ) const
return std::max( craft_roll - data.final_difficulty, 0.0f );
}

float Character::crafting_failure_roll( const recipe &making ) const
{
craft_roll_data data = recipe_failure_roll_data( making );
float craft_roll = std::max( normal_roll( data.center, data.stddev ), 0.0 );

add_msg_debug( debugmode::DF_CHARACTER, "Crafting skill roll: %f, final difficulty %g", craft_roll,
data.final_difficulty );

return std::max( craft_roll, 0.0f );
}

// Returns the area under a curve with provided standard deviation and center
// from difficulty to positive to infinity. That is, the chance that a normal roll on
// said curve will return a value of difficulty or greater.
Expand Down Expand Up @@ -1209,10 +1230,19 @@ float Character::recipe_success_chance( const recipe &making ) const
// If that result is above 1, there is no chance of failure.
craft_roll_data data = recipe_success_roll_data( making );


return normal_roll_chance( data.center, data.stddev, 1.f + data.final_difficulty );
}

float Character::item_destruction_chance( const recipe &making ) const
{
// If a normal roll with these parameters rolls over 1, we will not have a catastrophic failure
// If we roll under one, we will
craft_roll_data data = recipe_failure_roll_data( making );

// normal_roll_chance returns the chance that we roll over, we want the chance we roll under
return 1.f - normal_roll_chance( data.center, data.stddev, 1.f + data.final_difficulty );
}

int item::get_next_failure_point() const
{
if( !is_craft() ) {
Expand Down Expand Up @@ -1263,7 +1293,7 @@ bool item::handle_craft_failure( Character &crafter )
return false;
}

const double success_roll = crafter.crafting_success_roll( get_making() );
const double success_roll = crafter.crafting_failure_roll( get_making() );
const int starting_components = this->components.size();
// Destroy at most 75% of the components, always a chance of losing 1 though
const size_t max_destroyed = std::max<size_t>( 1, components.size() * 3 / 4 );
Expand Down
18 changes: 18 additions & 0 deletions src/crafting_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,23 @@ static std::string craft_success_chance_string( const recipe &recp, const Charac
return string_format( _( "Minor Failure Chance: <color_%s>%2.2f</color>" ), color, chance );
}

static std::string cata_fail_chance_string( const recipe &recp, const Character &guy )
{
float chance = 100.f * guy.item_destruction_chance( recp );
std::string color;
if( chance > 50 ) {
color = "i_red";
} else if( chance > 20 ) {
color = "red";
} else if( chance > 5 ) {
color = "yellow";
} else {
color = "light_gray";
}

return string_format( _( "Catastrophic Failure Chance: <color_%s>%2.2f</color>" ), color, chance );
}


static std::vector<std::string> recipe_info(
const recipe &recp,
Expand Down Expand Up @@ -330,6 +347,7 @@ static std::vector<std::string> recipe_info(
}

oss << craft_success_chance_string( recp, guy ) << "\n";
oss << cata_fail_chance_string( recp, guy ) << "\n";

if( !recp.is_nested() ) {
const int expected_turns = guy.expected_time_to_craft( recp, batch_size )
Expand Down

0 comments on commit 7d8e043

Please sign in to comment.