Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(UI): make empty-handed unarmed damage bonus more visible #4241

Merged
merged 9 commits into from
Feb 22, 2024
Merged
2 changes: 1 addition & 1 deletion data/json/skills.json
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@
"type": "skill",
"id": "unarmed",
"name": { "str": "unarmed combat" },
"description": "Your skill in hand-to-hand fighting. For the unskilled, it's a good way to get hurt, but those with enough practice can perform special blows and techniques to quickly dispatch enemies.",
"description": "Your skill in hand-to-hand fighting, with unarmed weapons or empty-handed. Skill increases attack accuracy and unlocks techniques in many martial arts, while also providing a bonus to bare-handed damage.",
"tags": [ "combat_skill", "weapon_skill" ],
"companion_combat_rank_factor": 1,
"companion_survival_rank_factor": 1,
Expand Down
60 changes: 60 additions & 0 deletions src/character_display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "weather.h"

static const skill_id skill_swimming( "swimming" );
static const skill_id skill_unarmed( "unarmed" );

static const std::string title_STATS = translate_marker( "STATS" );
static const std::string title_ENCUMB = translate_marker( "ENCUMBRANCE AND WARMTH" );
Expand All @@ -45,6 +46,9 @@ static const std::string title_SKILLS = translate_marker( "SKILLS" );
static const std::string title_BIONICS = translate_marker( "BIONICS" );
static const std::string title_TRAITS = translate_marker( "TRAITS" );

static const trait_flag_str_id trait_flag_NEED_ACTIVE_TO_MELEE( "NEED_ACTIVE_TO_MELEE" );
static const trait_flag_str_id trait_flag_UNARMED_BONUS( "UNARMED_BONUS" );

// use this instead of having to type out 26 spaces like before
static const std::string header_spaces( 26, ' ' );

Expand Down Expand Up @@ -642,6 +646,57 @@ struct HeaderSkill {
}
};

int character_display::display_empty_handed_base_damage( const Character &you )
{
int empty_hand_base_damage = you.get_skill_level( skill_unarmed ) * 2;
const bool left_empty = !you.natural_attack_restricted_on( bodypart_id( "hand_l" ) );
const bool right_empty = !you.natural_attack_restricted_on( bodypart_id( "hand_r" ) );

if( !left_empty && !right_empty ) {
// Mutation and bionic bonuses don't matter so just print unarmed bonus
return empty_hand_base_damage;
} else {

// Mutation and bionic bonuses double if both hands are free
int per_hand = 0;
if( you.has_bionic( bionic_id( "bio_razors" ) ) ) {
per_hand += 4;
}
for( const trait_id &mut : you.get_mutations() ) {
if( mut->flags.count( trait_flag_NEED_ACTIVE_TO_MELEE ) > 0 &&
!you.has_active_mutation( mut ) ) {
continue;
}
// Fixed bonuses are nice and simple
per_hand += mut->bash_dmg_bonus + mut->cut_dmg_bonus + mut->pierce_dmg_bonus;

// Random bonuses are more fiddly, since we want baseline numbers let's just report the minimum
const std::pair<int, int> rand_bash = mut->rand_bash_bonus;
const std::pair<int, int> rand_cut = mut->rand_cut_bonus;
per_hand += rand_bash.first + rand_cut.first;

// Extra skill bonus is also fairly simple, but each type of fixed bonus can trigger it separately
if( mut->flags.count( trait_flag_UNARMED_BONUS ) > 0 ) {
if( mut->bash_dmg_bonus > 0 ) {
per_hand += std::min( you.get_skill_level( skill_unarmed ) / 2, 4 );
}
if( mut->cut_dmg_bonus > 0 ) {
per_hand += std::min( you.get_skill_level( skill_unarmed ) / 2, 4 );
}
if( mut->pierce_dmg_bonus > 0 ) {
per_hand += std::min( you.get_skill_level( skill_unarmed ) / 2, 4 );
}
}
}
empty_hand_base_damage += per_hand; // First hand
if( left_empty && right_empty ) {
// Second hand
empty_hand_base_damage += per_hand;
}
return empty_hand_base_damage;
}
}

static void draw_skills_tab( const catacurses::window &w_skills,
Character &you, unsigned int line, const player_display_tab curtab,
std::vector<HeaderSkill> &skillslist,
Expand Down Expand Up @@ -723,6 +778,11 @@ static void draw_skills_tab( const catacurses::window &w_skills,
if( aSkill->ident() == skill_id( "dodge" ) ) {
mvwprintz( w_skills, point( 14, y_pos ), cstatus, "%4.1f/%-2d(%2d%%)",
you.get_dodge(), level_num, exercise < 0 ? 0 : exercise );
}
if( aSkill->ident() == skill_id( "unarmed" ) ) {
mvwprintz( w_skills, point( 15, y_pos ), cstatus, "%3d/%-2d(%2d%%)",
character_display::display_empty_handed_base_damage( you ), level_num,
exercise < 0 ? 0 : exercise );
} else {
mvwprintz( w_skills, point( 19, y_pos ), cstatus, "%-2d(%2d%%)",
level_num,
Expand Down
4 changes: 4 additions & 0 deletions src/character_display.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ void disp_info( Character &ch );
*/
void upgrade_stat_prompt( avatar &you, const character_stat &stat );

/** Gets the minimum combined bare-handed damage from skill, bionics, and mutations for display functions */
int display_empty_handed_base_damage( const Character &you );

} // namespace character_display


#endif // CATA_SRC_CHARACTER_DISPLAY_H
4 changes: 4 additions & 0 deletions src/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "bionics.h"
#include "cata_utility.h"
#include "catacharset.h"
#include "character_display.h"
#include "character_functions.h"
#include "character_effects.h"
#include "character_martial_arts.h"
Expand Down Expand Up @@ -222,8 +223,11 @@ bool character_martial_arts::pick_style( const avatar &you ) // Style selecti
"\n"
"STR: <color_white>%d</color>, DEX: <color_white>%d</color>, "
"PER: <color_white>%d</color>, INT: <color_white>%d</color>\n"
"Base empty-handed damage: %3d\n"
"Effective dodge rating: %4.1f\n"
"Press [<color_yellow>%s</color>] for more info.\n" ),
you.get_str(), you.get_dex(), you.get_per(), you.get_int(),
character_display::display_empty_handed_base_damage( you ), you.get_dodge(),
ctxt.get_desc( "SHOW_DESCRIPTION" ) );
ma_style_callback callback( static_cast<size_t>( STYLE_OFFSET ), selectable_styles );
kmenu.callback = &callback;
Expand Down
Loading