void start_location::handle_heli_crash( player &u ) const { for( int i = 2; i < num_hp_parts; i++ ) { // Skip head + torso for balance reasons. auto part = hp_part( i ); auto bp_part = u.hp_to_bp( part ); int roll = int( rng( 1, 8 ) ); switch( roll ) { case 1: case 2:// Damage + Bleed u.add_effect( effect_bleed, 60, bp_part ); /* fallthrough */ case 3: case 4: case 5: { // Just damage auto maxHp = u.get_hp_max( part ); // Body part health will range from 33% to 66% with occasional bleed int dmg = int( rng( maxHp / 3, maxHp * 2 / 3 ) ); u.apply_damage( nullptr, bp_part, dmg ); break; } default: // No damage break; } } }
void talk_function::give_aid( npc &p ) { p.add_effect( effect_currently_busy, 30_minutes ); for( int i = 0; i < num_hp_parts; i++ ) { const body_part bp_healed = player::hp_to_bp( hp_part( i ) ); g->u.heal( hp_part( i ), 5 * rng( 2, 5 ) ); if( g->u.has_effect( effect_bite, bp_healed ) ) { g->u.remove_effect( effect_bite, bp_healed ); } if( g->u.has_effect( effect_bleed, bp_healed ) ) { g->u.remove_effect( effect_bleed, bp_healed ); } if( g->u.has_effect( effect_infected, bp_healed ) ) { g->u.remove_effect( effect_infected, bp_healed ); } } g->u.assign_activity( activity_id( "ACT_WAIT_NPC" ), 10000 ); g->u.activity.str_values.push_back( p.name ); }
void talk_function::give_all_aid( npc &p ) { p.add_effect( effect_currently_busy, 30_minutes ); give_aid( p ); for( npc &guy : g->all_npcs() ) { if( rl_dist( guy.pos(), g->u.pos() ) < PICKUP_RANGE && guy.is_friend() ) { for( int i = 0; i < num_hp_parts; i++ ) { const body_part bp_healed = player::hp_to_bp( hp_part( i ) ); guy.heal( hp_part( i ), 5 * rng( 2, 5 ) ); if( guy.has_effect( effect_bite, bp_healed ) ) { guy.remove_effect( effect_bite, bp_healed ); } if( guy.has_effect( effect_bleed, bp_healed ) ) { guy.remove_effect( effect_bleed, bp_healed ); } if( guy.has_effect( effect_infected, bp_healed ) ) { guy.remove_effect( effect_infected, bp_healed ); } } } } }
void iuse::bandage(game *g, player *p, item *it, bool t) { int bonus = p->sklevel[sk_firstaid]; hp_part healed; if (p->is_npc()) { // NPCs heal whichever has sustained the most damage int highest_damage = 0; for (int i = 0; i < num_hp_parts; i++) { int damage = p->hp_max[i] - p->hp_cur[i]; if (i == hp_head) damage *= 1.5; if (i == hp_torso) damage *= 1.2; if (damage > highest_damage) { highest_damage = damage; healed = hp_part(i); } } } else { // Player--present a menu WINDOW* w = newwin(10, 20, 8, 1); wborder(w, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX ); mvwprintz(w, 1, 1, c_ltred, "Bandage where?"); mvwprintz(w, 2, 1, c_ltgray, "1: Head"); mvwprintz(w, 3, 1, c_ltgray, "2: Torso"); mvwprintz(w, 4, 1, c_ltgray, "3: Left Arm"); mvwprintz(w, 5, 1, c_ltgray, "4: Right Arm"); mvwprintz(w, 6, 1, c_ltgray, "5: Left Leg"); mvwprintz(w, 7, 1, c_ltgray, "6: Right Leg"); mvwprintz(w, 8, 1, c_ltgray, "7: Exit"); nc_color col; int curhp; for (int i = 0; i < num_hp_parts; i++) { curhp = p->hp_cur[i]; int tmpbonus = bonus; if (curhp != 0) { switch (hp_part(i)) { case hp_head: curhp += 1; tmpbonus *= .8; break; case hp_torso: curhp += 4; tmpbonus *= 1.5; break; default: curhp += 3; break; } curhp += tmpbonus; if (curhp > p->hp_max[i]) curhp = p->hp_max[i]; if (curhp == p->hp_max[i]) col = c_green; else if (curhp > p->hp_max[i] * .8) col = c_ltgreen; else if (curhp > p->hp_max[i] * .5) col = c_yellow; else if (curhp > p->hp_max[i] * .3) col = c_ltred; else col = c_red; if (p->has_trait(PF_HPIGNORANT)) mvwprintz(w, i + 2, 15, col, "***"); else { if (curhp >= 100) mvwprintz(w, i + 2, 15, col, "%d", curhp); else if (curhp >= 10) mvwprintz(w, i + 2, 16, col, "%d", curhp); else mvwprintz(w, i + 2, 17, col, "%d", curhp); } } else // curhp is 0; requires surgical attention mvwprintz(w, i + 2, 15, c_dkgray, "---"); } wrefresh(w); char ch; do { ch = getch(); if (ch == '1') healed = hp_head; else if (ch == '2') healed = hp_torso; else if (ch == '3') { if (p->hp_cur[hp_arm_l] == 0) { g->add_msg("That arm is broken. It needs surgical attention."); it->charges++; return; } else healed = hp_arm_l; } else if (ch == '4') { if (p->hp_cur[hp_arm_r] == 0) { g->add_msg("That arm is broken. It needs surgical attention."); it->charges++; return; } else healed = hp_arm_r; } else if (ch == '5') { if (p->hp_cur[hp_leg_l] == 0) { g->add_msg("That leg is broken. It needs surgical attention."); it->charges++; return; } else healed = hp_leg_l; } else if (ch == '6') { if (p->hp_cur[hp_leg_r] == 0) { g->add_msg("That leg is broken. It needs surgical attention."); it->charges++; return; } else healed = hp_leg_r; } else if (ch == '7') { g->add_msg("Never mind."); it->charges++; return; } } while (ch < '1' || ch > '7'); werase(w); wrefresh(w); delwin(w); refresh(); } p->practice(sk_firstaid, 8); int dam = 0; if (healed == hp_head) dam = 1 + bonus * .8; else if (healed == hp_torso) dam = 4 + bonus * 1.5; else dam = 3 + bonus; p->heal(healed, dam); }
hp_part Character::body_window( const std::string &menu_header, bool show_all, bool precise, int normal_bonus, int head_bonus, int torso_bonus, int bleed, int bite, int infect ) const { WINDOW *hp_window = newwin(10, 31, (TERMY - 10) / 2, (TERMX - 31) / 2); draw_border(hp_window); trim_and_print( hp_window, 1, 1, getmaxx(hp_window) - 2, c_ltred, menu_header.c_str() ); nc_color color = c_ltgray; bool allowed_result[num_hp_parts] = { false }; const auto check_part = [&]( hp_part part, std::string part_name, int heal_val, int line_num ) { body_part bp = player::hp_to_bp( part ); if( show_all || hp_cur[part] < hp_max[part] || has_effect("infected", bp) || has_effect("bite", bp) || has_effect("bleed", bp) ) { nc_color color = show_all ? c_green : limb_color( bp, bleed, bite, infect ); if( color != c_ltgray || heal_val != 0 ) { mvwprintz( hp_window, line_num, 1, color, part_name.c_str() ); allowed_result[part] = true; } } }; check_part( hp_head, _("1: Head"), head_bonus, 2 ); check_part( hp_torso, _("2: Torso"), torso_bonus, 3 ); check_part( hp_arm_l, _("3: Left Arm"), normal_bonus, 4 ); check_part( hp_arm_r, _("4: Right Arm"), normal_bonus, 5 ); check_part( hp_leg_l, _("5: Left Leg"), normal_bonus, 6 ); check_part( hp_leg_r, _("6: Right Leg"), normal_bonus, 7 ); mvwprintz( hp_window, 8, 1, c_ltgray, _("7: Exit") ); std::string health_bar; for( int i = 0; i < num_hp_parts; i++ ) { if( !allowed_result[i] ) { continue; } body_part bp = body_part( i ); // Have printed the name of the body part, can select it int current_hp = hp_cur[i]; if( current_hp != 0 ) { std::tie( health_bar, color ) = get_hp_bar(current_hp, hp_max[i], false); // Drop the bar color, use the state color instead const nc_color state_col = limb_color( bp, true, true, true ); color = state_col != c_ltgray ? state_col : c_green; if( precise ) { mvwprintz(hp_window, i + 2, 15, color, "%5d", current_hp); } else { mvwprintz(hp_window, i + 2, 15, color, health_bar.c_str()); } } else { // curhp is 0; requires surgical attention // But still could be infected or bleeding const nc_color state_col = limb_color( bp, true, true, true ); color = state_col != c_ltgray ? state_col : c_dkgray; mvwprintz(hp_window, i + 2, 15, color, "-----"); } if( current_hp != 0 ) { switch( hp_part( i ) ) { case hp_head: current_hp += head_bonus; break; case hp_torso: current_hp += torso_bonus; break; default: current_hp += normal_bonus; break; } if( current_hp > hp_max[i] ) { current_hp = hp_max[i]; } else if (current_hp < 0) { current_hp = 0; } if( current_hp == hp_cur[i] && ( infect <= 0 || !has_effect( "infected", bp ) ) && ( bite <= 0 || !has_effect( "bite", bp ) ) && ( bleed <= 0 || !has_effect( "bleed", bp ) ) ) { // Nothing would change continue; } mvwprintz( hp_window, i + 2, 20, c_dkgray, " -> " ); std::tie( health_bar, color ) = get_hp_bar( current_hp, hp_max[i], false ); const nc_color state_col = limb_color( bp, bleed > 0, bite > 0, infect > 0 ); color = state_col != c_ltgray ? state_col : c_green; if( precise ) { mvwprintz( hp_window, i + 2, 24, color, "%5d", current_hp ); } else { mvwprintz( hp_window, i + 2, 24, color, health_bar.c_str() ); } } else { // curhp is 0; requires surgical attention const nc_color state_col = limb_color( bp, bleed > 0, bite > 0, infect > 0 ); color = state_col != c_ltgray ? state_col : c_dkgray; mvwprintz(hp_window, i + 2, 24, color, "-----"); } } wrefresh(hp_window); char ch; hp_part healed_part = num_hp_parts; do { ch = getch(); if (ch == '1') { healed_part = hp_head; } else if (ch == '2') { healed_part = hp_torso; } else if (ch == '3') { healed_part = hp_arm_l; } else if (ch == '4') { healed_part = hp_arm_r; } else if (ch == '5') { healed_part = hp_leg_l; } else if (ch == '6') { healed_part = hp_leg_r; } else if (ch == '7' || ch == KEY_ESCAPE) { healed_part = num_hp_parts; break; } } while (ch < '1' || ch > '7'); werase(hp_window); wrefresh(hp_window); delwin(hp_window); refresh(); return healed_part; }