diff --git a/data/core/sentinels.json b/data/core/sentinels.json index 06a74c091b5f8..bf7fe5c2f855b 100644 --- a/data/core/sentinels.json +++ b/data/core/sentinels.json @@ -17,7 +17,15 @@ "base_hp": 60, "drench_capacity": 1, "legacy_id": "NUM_BP", - "sub_parts": [ "sub_limb_debug" ] + "sub_parts": [ "sub_bp_null" ] + }, + { + "id": "sub_bp_null", + "type": "sub_body_part", + "parent": "bp_null", + "side": 0, + "opposite": "sub_bp_null", + "name": { "str": "Null sub_body_part, if you see this please report it", "//~": "NO_I18N" } }, { "id": "mx_null", @@ -50,6 +58,12 @@ "name": { "str": "This is a bug" }, "description": "This fault id is a reserved sentinel." }, + { + "type": "attack_vector", + "id": "vector_null", + "//": "Fallback weapon vector, unarmed attacks always go through techs", + "weapon": true + }, { "type": "SPELL", "id": "null", diff --git a/data/json/attack_vectors.json b/data/json/attack_vectors.json index 8928cf53fd311..0b670dcd4fb90 100644 --- a/data/json/attack_vectors.json +++ b/data/json/attack_vectors.json @@ -1,10 +1,4 @@ [ - { - "type": "attack_vector", - "id": "vector_null", - "//": "Fallback weapon vector, unarmed attacks always go through techs", - "weapon": true - }, { "type": "attack_vector", "id": "test_test", diff --git a/data/json/body_parts.json b/data/json/body_parts.json index 15952c01ee610..f908cb0a4629f 100644 --- a/data/json/body_parts.json +++ b/data/json/body_parts.json @@ -900,7 +900,7 @@ "parent": "bp_null", "side": 0, "opposite": "sub_limb_debug", - "name": "debug limb should never be seen" + "name": { "str": "debug limb should never be seen", "//~": "NO_I18N" } }, { "id": "sub_limb_debug_tail", @@ -908,7 +908,7 @@ "parent": "debug_tail", "side": 0, "opposite": "sub_limb_debug_tail", - "name": "debug limb for debug tail" + "name": { "str": "debug limb for debug tail", "//~": "NO_I18N" } }, { "id": "torso_upper", diff --git a/src/armor_layers.cpp b/src/armor_layers.cpp index 502d382119b64..6c53a2bf979a5 100644 --- a/src/armor_layers.cpp +++ b/src/armor_layers.cpp @@ -251,7 +251,7 @@ std::vector clothing_properties( _( "Item provides no protection" ) ) ); return props; } - if( bp == bodypart_id( "bp_null" ) ) { + if( bp == bodypart_str_id::NULL_ID() ) { // if the armor has no protection data if( worn_item.find_armor_data()->sub_data.empty() ) { props.push_back( string_format( "%s", @@ -356,7 +356,7 @@ std::vector clothing_protection( const item &worn_item, const int w } // if bp is null its gonna be impossible to really get good info - if( bp == bodypart_id( "bp_null" ) ) { + if( bp == bodypart_str_id::NULL_ID() ) { // if we have exactly one entry for armor we can use that data if( worn_item.find_armor_data()->sub_data.size() == 1 ) { used_bp = *worn_item.get_covered_body_parts().begin(); @@ -464,7 +464,7 @@ item_penalties outfit::get_item_penalties( std::list::const_iterator worn_ std::vector> lists_of_bad_items_within; for( const bodypart_id &bp : c.get_all_body_parts() ) { - if( bp != _bp && _bp != bodypart_id( "bp_null" ) ) { + if( bp != _bp && _bp != bodypart_str_id::NULL_ID() ) { continue; } if( !worn_item_it->covers( bp ) ) { @@ -614,7 +614,7 @@ void outfit::sort_armor( Character &guy ) for( const bodypart_id &it : guy.get_all_body_parts() ) { armor_cat.insert( it ); } - armor_cat.insert( bodypart_id( "bp_null" ) ); + armor_cat.insert( bodypart_str_id::NULL_ID() ); const int num_of_parts = guy.get_all_body_parts().size(); int win_h = 0; @@ -713,7 +713,7 @@ void outfit::sort_armor( Character &guy ) // Create ptr list of items to display tmp_worn.clear(); const bodypart_id &bp = armor_cat[ tabindex ]; - if( bp == bodypart_id( "bp_null" ) ) { + if( bp == bodypart_str_id::NULL_ID() ) { // All for( auto it = worn.begin(); it != worn.end(); ++it ) { tmp_worn.push_back( it ); @@ -754,7 +754,8 @@ void outfit::sort_armor( Character &guy ) // top bar std::string header_title = _( "Sort Armor" ); wprintz( w_sort_cat, c_white, header_title ); - std::string temp = bp != bodypart_id( "bp_null" ) ? body_part_name_as_heading( bp, 1 ) : _( "All" ); + std::string temp = bp == bodypart_str_id::NULL_ID() ? _( "All" ) : body_part_name_as_heading( bp, + 1 ); temp = string_format( " << %s >>", temp ); wprintz( w_sort_cat, c_yellow, temp ); int keyhint_offset = utf8_width( header_title ) + utf8_width( temp ) + 1; @@ -864,7 +865,7 @@ void outfit::sort_armor( Character &guy ) // Right list rightListSize = 0; for( const bodypart_id &cover : armor_cat ) { - if( cover == bodypart_id( "bp_null" ) ) { + if( cover == bodypart_str_id::NULL_ID() ) { continue; } if( !combine_bp( cover ) || rl.count( cover.obj().opposite_part ) == 0 ) { @@ -882,7 +883,7 @@ void outfit::sort_armor( Character &guy ) int encumbrance_char_allowance = 4; //Enough for " 99+", will increase if necessary int item_name_offset = 2; for( const bodypart_id &cover : rl ) { - if( cover == bodypart_id( "bp_null" ) ) { + if( cover == bodypart_str_id::NULL_ID() ) { continue; } if( curr >= rightListOffset && pos <= rightListLines ) { diff --git a/src/avatar.cpp b/src/avatar.cpp index e5fea4fa2b22f..473e99f365368 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -1840,7 +1840,7 @@ void avatar::add_pain_msg( int val, const bodypart_id &bp ) const if( has_flag( json_flag_PAIN_IMMUNE ) ) { return; } - if( bp == bodypart_id( "bp_null" ) ) { + if( bp == bodypart_str_id::NULL_ID() ) { if( val > 20 ) { add_msg_if_player( _( "Your body is wracked with excruciating pain!" ) ); } else if( val > 10 ) { diff --git a/src/bodypart.cpp b/src/bodypart.cpp index c6ac999f9d3ef..fd1580505624a 100644 --- a/src/bodypart.cpp +++ b/src/bodypart.cpp @@ -23,7 +23,6 @@ const bodypart_str_id body_part_arm_l( "arm_l" ); const bodypart_str_id body_part_arm_r( "arm_r" ); -const bodypart_str_id body_part_bp_null( "bp_null" ); const bodypart_str_id body_part_eyes( "eyes" ); const bodypart_str_id body_part_foot_l( "foot_l" ); const bodypart_str_id body_part_foot_r( "foot_r" ); @@ -35,8 +34,6 @@ const bodypart_str_id body_part_leg_r( "leg_r" ); const bodypart_str_id body_part_mouth( "mouth" ); const bodypart_str_id body_part_torso( "torso" ); -const sub_bodypart_str_id sub_body_part_sub_limb_debug( "sub_limb_debug" ); - side opposite_side( side s ) { switch( s ) { @@ -641,7 +638,7 @@ std::set body_part_type::consolidate( //first try to compress sets of sub body parts together into a full limb for( size_t i = 0; i < covered.size(); i++ ) { const sub_bodypart_id &sbp = covered[i]; - if( sbp == sub_body_part_sub_limb_debug ) { + if( sbp == sub_bodypart_str_id::NULL_ID() ) { // if we have already covered this continue continue; } @@ -650,9 +647,10 @@ std::set body_part_type::consolidate( bool found_all = true; for( const sub_bodypart_str_id &searching : sbp->parent->sub_parts ) { //skip secondary locations for this - if( !searching->secondary ) { - found_all = std::find( covered.begin(), covered.end(), searching.id() ) != covered.end() && - found_all; + if( !searching->secondary && + std::find( covered.begin(), covered.end(), searching.id() ) == covered.end() ) { + found_all = false; + break; } } @@ -664,7 +662,7 @@ std::set body_part_type::consolidate( for( const sub_bodypart_str_id &searching : sbp->parent->sub_parts ) { if( !searching->secondary ) { auto sbp_it = std::find( covered.begin(), covered.end(), searching.id() ); - *sbp_it = sub_body_part_sub_limb_debug; + *sbp_it = sub_bodypart_str_id::NULL_ID(); } } } @@ -698,13 +696,13 @@ std::set body_part_type::consolidate( for( size_t i = 0; i < covered.size(); i++ ) { const sub_bodypart_id &sbp = covered[i]; - if( sbp == sub_body_part_sub_limb_debug ) { + if( sbp == sub_bodypart_str_id::NULL_ID() ) { // if we have already covered this value as a pair continue continue; } sub_bodypart_id temp; // if our sub part has an opposite - if( sbp->opposite != sub_body_part_sub_limb_debug ) { + if( sbp->opposite != sub_bodypart_str_id::NULL_ID() ) { temp = sbp->opposite; } else { // if it doesn't have an opposite add it to the return vector alone and continue @@ -720,7 +718,7 @@ std::set body_part_type::consolidate( to_return.insert( sbp->name_multiple ); found = true; // set the found part to a null value - sbp_it = sub_body_part_sub_limb_debug; + sbp_it = sub_bodypart_str_id::NULL_ID(); break; } } diff --git a/src/bodypart.h b/src/bodypart.h index c23099837c38a..51c0c2510bf25 100644 --- a/src/bodypart.h +++ b/src/bodypart.h @@ -31,7 +31,6 @@ template class generic_factory; using bodypart_str_id = string_id; using bodypart_id = int_id; -extern const bodypart_str_id body_part_bp_null; extern const bodypart_str_id body_part_head; extern const bodypart_str_id body_part_eyes; extern const bodypart_str_id body_part_mouth; @@ -45,8 +44,6 @@ extern const bodypart_str_id body_part_foot_l; extern const bodypart_str_id body_part_leg_r; extern const bodypart_str_id body_part_foot_r; -extern const sub_bodypart_str_id sub_body_part_sub_limb_debug; - // The order is important ; pldata.h has to be in the same order enum body_part : int { bp_torso = 0, diff --git a/src/character.cpp b/src/character.cpp index b6527972d4214..c01b860c4403e 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -1835,7 +1835,7 @@ void Character::forced_dismount() } const int dodge = get_dodge(); const int damage = std::max( 0, rng( 1, 20 ) - rng( dodge, dodge * 2 ) ); - bodypart_id hit( "bp_null" ); + bodypart_id hit = bodypart_str_id::NULL_ID(); switch( rng( 1, 10 ) ) { case 1: if( one_in( 2 ) ) { @@ -3710,8 +3710,7 @@ void Character::apply_skill_boost() std::pair Character::best_part_to_smash() const { - const bodypart_id bp_null( "bp_null" ); - std::pair best_part_to_smash = {bp_null, 0}; + std::pair best_part_to_smash = {bodypart_str_id::NULL_ID().id(), 0}; int tmp_bash_armor = 0; for( const bodypart_id &bp : get_all_body_parts() ) { tmp_bash_armor += worn.damage_resist( damage_bash, bp ); diff --git a/src/character.h b/src/character.h index 47f5abceec0d6..f17cf4ecac946 100644 --- a/src/character.h +++ b/src/character.h @@ -3202,7 +3202,7 @@ class Character : public Creature, public visitable void on_item_acquire( const item &it ); /** Called when effect intensity has been changed */ void on_effect_int_change( const efftype_id &eid, int intensity, - const bodypart_id &bp = bodypart_id( "bp_null" ) ) override; + const bodypart_id &bp = bodypart_str_id::NULL_ID() ) override; /** Called when a mutation is gained */ void on_mutation_gain( const trait_id &mid ); /** Called when a mutation is lost */ diff --git a/src/creature.cpp b/src/creature.cpp index 8bef92676f7d6..66fd8d0721b83 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -2348,7 +2348,7 @@ void Creature::set_body() bool Creature::has_part( const bodypart_id &id, body_part_filter filter ) const { - return get_part_id( id, filter, true ) != body_part_bp_null; + return get_part_id( id, filter, true ) != bodypart_str_id::NULL_ID(); } bodypart *Creature::get_part( const bodypart_id &id ) @@ -2423,7 +2423,7 @@ bodypart_id Creature::get_part_id( const bodypart_id &id, } } // try to find the next best thing - std::pair best = { body_part_bp_null, 0.0f }; + std::pair best = { bodypart_str_id::NULL_ID().id(), 0.0f }; if( filter >= body_part_filter::next_best ) { for( const std::pair &bp : body ) { for( const std::pair &mp : bp.first->limbtypes ) { @@ -2436,7 +2436,7 @@ bodypart_id Creature::get_part_id( const bodypart_id &id, } } } - if( best.first == body_part_bp_null && !suppress_debugmsg ) { + if( best.first == bodypart_str_id::NULL_ID() && !suppress_debugmsg ) { debugmsg( "Could not find equivalent bodypart id %s in %s's body", id.id().c_str(), get_name() ); } diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index 310a8ff382286..2ab3e468fc052 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -2062,7 +2062,7 @@ static void character_edit_hp_menu( Character &you ) hotkey++; } smenu.addentry( pos, true, hotkey, "%s: %d", _( "All" ), you.get_lowest_hp() ); - part_ids.emplace_back( body_part_bp_null ); + part_ids.emplace_back( bodypart_str_id::NULL_ID().id() ); smenu.query(); bodypart_str_id bp = body_part_no_a_real_part; bool all_select = false; @@ -2071,11 +2071,11 @@ static void character_edit_hp_menu( Character &you ) return; } bp = part_ids.at( smenu.ret ).id(); - if( bp == body_part_bp_null ) { + if( bp == bodypart_str_id::NULL_ID() ) { all_select = true; } - if( bp.is_valid() && bp != body_part_bp_null ) { + if( bp.is_valid() && bp != bodypart_str_id::NULL_ID() ) { int value; if( query_int( value, _( "Set the hitpoints to? Currently: %d" ), you.get_part_hp_cur( bp.id() ) ) && diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index 4b9e0defb108d..b1448bd89cd9e 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -407,7 +407,7 @@ class wear_inventory_preset: public armor_inventory_preset return loc->is_armor() && ( !loc.has_parent() || !is_worn_ablative( loc.parent_item(), loc ) ) && !you.is_worn( *loc ) && - ( bp != bodypart_id( "bp_null" ) ? loc->covers( bp ) : true ); + ( bp != bodypart_str_id::NULL_ID() ? loc->covers( bp ) : true ); } std::string get_denial( const item_location &loc ) const override { diff --git a/src/game_inventory.h b/src/game_inventory.h index 7b42187a67b51..36cac04f49200 100644 --- a/src/game_inventory.h +++ b/src/game_inventory.h @@ -163,7 +163,7 @@ item_location molle_attach( Character &you, item &tool ); item_location veh_tool_attach( Character &you, const std::string &vp_name, const std::set &allowed_types ); /** Choose item to wear. */ -item_location wear( Character &you, const bodypart_id &bp = bodypart_id( "bp_null" ) ); +item_location wear( Character &you, const bodypart_id &bp = bodypart_str_id::NULL_ID() ); /** Choose item to take off. */ item_location take_off(); /** Item cut up menu. */ diff --git a/src/handle_action.cpp b/src/handle_action.cpp index 23d95e1f29ff5..9f17c9a2564aa 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -1047,9 +1047,8 @@ avatar::smash_result avatar::smash( tripoint_bub_ms &smashp ) } if( !has_weapon() ) { - const bodypart_id bp_null( "bp_null" ); std::pair best_part_to_smash = this->best_part_to_smash(); - if( best_part_to_smash.first != bp_null && here.is_bashable( smashp ) ) { + if( best_part_to_smash.first != bodypart_str_id::NULL_ID() && here.is_bashable( smashp ) ) { std::string name_to_bash = _( "thing" ); if( here.is_bashable_furn( smashp ) ) { name_to_bash = here.furnname( smashp ); diff --git a/src/item.cpp b/src/item.cpp index bcf512473c5b6..7532736bf9d57 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -132,8 +132,6 @@ static const ammotype ammo_bolt( "bolt" ); static const ammotype ammo_money( "money" ); static const ammotype ammo_plutonium( "plutonium" ); -static const attack_vector_id attack_vector_vector_null( "vector_null" ); - static const bionic_id bio_digestion( "bio_digestion" ); static const bodygraph_id bodygraph_full_body_iteminfo( "full_body_iteminfo" ); @@ -2317,8 +2315,8 @@ double item::effective_dps( const Character &guy, Creature &mon ) const Creature *temp_mon = &mon; double subtotal_damage = 0; damage_instance base_damage; - guy.roll_all_damage( crit, base_damage, true, *this, attack_vector_vector_null, - sub_body_part_sub_limb_debug, &mon, bp ); + guy.roll_all_damage( crit, base_damage, true, *this, attack_vector_id::NULL_ID(), + sub_bodypart_str_id::NULL_ID(), &mon, bp ); damage_instance dealt_damage = base_damage; dealt_damage = guy.modify_damage_dealt_with_enchantments( dealt_damage ); // TODO: Modify DPS calculation to consider weakpoints. @@ -2344,8 +2342,8 @@ double item::effective_dps( const Character &guy, Creature &mon ) const if( has_technique( RAPID ) ) { Creature *temp_rs_mon = &mon; damage_instance rs_base_damage; - guy.roll_all_damage( crit, rs_base_damage, true, *this, attack_vector_vector_null, - sub_body_part_sub_limb_debug, &mon, bp ); + guy.roll_all_damage( crit, rs_base_damage, true, *this, attack_vector_id::NULL_ID(), + sub_bodypart_str_id::NULL_ID(), &mon, bp ); damage_instance dealt_rs_damage = rs_base_damage; for( damage_unit &dmg_unit : dealt_rs_damage.damage_units ) { dmg_unit.damage_multiplier *= 0.66; @@ -5621,11 +5619,11 @@ void item::melee_combat_info( std::vector &info, const iteminfo_query ( !dmg_types.empty() || type->m_to_hit > 0 ) ) || debug_mode ) { bodypart_id bp = bodypart_id( "torso" ); damage_instance non_crit; - player_character.roll_all_damage( false, non_crit, true, *this, attack_vector_vector_null, - sub_body_part_sub_limb_debug, nullptr, bp ); + player_character.roll_all_damage( false, non_crit, true, *this, attack_vector_id::NULL_ID(), + sub_bodypart_str_id::NULL_ID(), nullptr, bp ); damage_instance crit; - player_character.roll_all_damage( true, crit, true, *this, attack_vector_vector_null, - sub_body_part_sub_limb_debug, nullptr, bp ); + player_character.roll_all_damage( true, crit, true, *this, attack_vector_id::NULL_ID(), + sub_bodypart_str_id::NULL_ID(), nullptr, bp ); int attack_cost = player_character.attack_speed( *this ); insert_separation_line( info ); if( parts->test( iteminfo_parts::DESCRIPTION_MELEEDMG ) ) { diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 6d2d5d317b700..e83d90c78dd1b 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -3702,8 +3702,8 @@ static bodypart_id pick_part_to_heal( bodypart_id healed_part = patient.body_window( menu_header, force, precise, limb_power, head_bonus, torso_bonus, bleed_stop, bite_chance, infect_chance, bandage_power, disinfectant_power ); - if( healed_part == bodypart_id( "bp_null" ) ) { - return bodypart_id( "bp_null" ); + if( healed_part == bodypart_str_id::NULL_ID() ) { + return healed_part; } if( healed_part->has_flag( json_flag_BIONIC_LIMB ) ) { @@ -3738,7 +3738,7 @@ static bodypart_id pick_part_to_heal( bodypart_id heal_actor::use_healing_item( Character &healer, Character &patient, item &it, bool force ) const { - bodypart_id healed = bodypart_id( "bp_null" ); + bodypart_id healed = bodypart_str_id::NULL_ID(); const int head_bonus = get_heal_value( healer, bodypart_id( "head" ) ); const int limb_power = get_heal_value( healer, bodypart_id( "arm_l" ) ); const int torso_bonus = get_heal_value( healer, bodypart_id( "torso" ) ); @@ -3747,7 +3747,7 @@ bodypart_id heal_actor::use_healing_item( Character &healer, Character &patient, patient.add_msg_player_or_npc( m_bad, _( "Your biology is not compatible with that item." ), _( "'s biology is not compatible with that item." ) ); - return bodypart_id( "bp_null" ); // canceled + return bodypart_str_id::NULL_ID().id(); // canceled } if( healer.is_npc() ) { @@ -3779,9 +3779,9 @@ bodypart_id heal_actor::use_healing_item( Character &healer, Character &patient, healed = pick_part_to_heal( healer, patient, menu_header, limb_power, head_bonus, torso_bonus, get_stopbleed_level( healer ), bite, infect, force, get_bandaged_level( healer ), get_disinfected_level( healer ) ); - if( healed == bodypart_id( "bp_null" ) ) { + if( healed == bodypart_str_id::NULL_ID() ) { add_msg( m_info, _( "Never mind." ) ); - return bodypart_id( "bp_null" ); // canceled + return bodypart_str_id::NULL_ID().id(); // canceled } return healed; } else { diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index a67964ca83745..34580062a2d93 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -651,7 +651,7 @@ static void damage_targets( const spell &sp, Creature &caster, cr->add_damage_over_time( sp.damage_over_time( { cr->get_random_body_part() }, caster ) ); } } else { - cr->add_damage_over_time( sp.damage_over_time( { body_part_bp_null }, caster ) ); + cr->add_damage_over_time( sp.damage_over_time( { bodypart_str_id::NULL_ID().id() }, caster ) ); } } } diff --git a/src/martialarts.cpp b/src/martialarts.cpp index 87f5fa1813b3e..13421f81e6cc6 100644 --- a/src/martialarts.cpp +++ b/src/martialarts.cpp @@ -1482,7 +1482,7 @@ std::optional> // Store a dummy sublimb to show we're attacking with a weapon weight = weapon->base_damage_melee().total_damage(); list.add_or_replace( vec, weight ); - storage.emplace_back( vec, sub_body_part_sub_limb_debug ); + storage.emplace_back( vec, sub_bodypart_str_id::NULL_ID() ); add_msg_debug( debugmode::DF_MELEE, "Weapon %s eligable for attack vector %s with weight %.1f", weapon->display_name(), vec.c_str(), weight ); diff --git a/src/mattack_actors.cpp b/src/mattack_actors.cpp index b162886215759..717ef6a5f8d6c 100644 --- a/src/mattack_actors.cpp +++ b/src/mattack_actors.cpp @@ -589,7 +589,8 @@ int melee_actor::do_grab( monster &z, Creature *target, bodypart_id bp_id ) cons target->add_effect( grab_data.grab_effect, 1_days, bp_id, true, eff_grab_strength ); } else { // Monsters don't have limb scores, no need to target limbs - target->add_effect( grab_data.grab_effect, 1_days, body_part_bp_null, true, eff_grab_strength ); + target->add_effect( grab_data.grab_effect, 1_days, bodypart_str_id::NULL_ID().id(), true, + eff_grab_strength ); z.add_effect( effect_grabbing, 1_days, true, 1 ); } } diff --git a/src/melee.cpp b/src/melee.cpp index fe0c109097a24..1aa26a8433021 100644 --- a/src/melee.cpp +++ b/src/melee.cpp @@ -74,8 +74,6 @@ static const anatomy_id anatomy_human_anatomy( "human_anatomy" ); -static const attack_vector_id attack_vector_vector_null( "vector_null" ); - static const bionic_id bio_cqb( "bio_cqb" ); static const bionic_id bio_heat_absorb( "bio_heat_absorb" ); static const bionic_id bio_shock( "bio_shock" ); @@ -699,7 +697,7 @@ bool Character::melee_attack_abstract( Creature &t, bool allow_special, if( !has_active_bionic( bio_cqb ) && !t.is_hallucination() && !( t.has_flag( json_flag_CANNOT_MOVE ) && t.has_flag( json_flag_CANNOT_TAKE_DAMAGE ) ) ) { - melee_train( *this, 2, std::min( 5, skill_training_cap ), cur_weap, attack_vector_vector_null ); + melee_train( *this, 2, std::min( 5, skill_training_cap ), cur_weap, attack_vector_id::NULL_ID() ); } // Cap stumble penalty, heavy weapons are quite weak already @@ -733,12 +731,12 @@ bool Character::melee_attack_abstract( Creature &t, bool allow_special, // Pick our attack // Unarmed needs a defined technique if( has_force_technique ) { - attack = std::make_tuple( force_technique, attack_vector_vector_null, - sub_body_part_sub_limb_debug ); + attack = std::make_tuple( force_technique, attack_vector_id::NULL_ID(), + sub_bodypart_str_id::NULL_ID() ); } else if( allow_special ) { attack = pick_technique( t, cur_weapon, critical_hit, false, false ); } else { - attack = std::make_tuple( tec_none, attack_vector_vector_null, sub_body_part_sub_limb_debug ); + attack = std::make_tuple( tec_none, attack_vector_id::NULL_ID(), sub_bodypart_str_id::NULL_ID() ); } // Unpack our data matec_id attack_id; @@ -747,7 +745,7 @@ bool Character::melee_attack_abstract( Creature &t, bool allow_special, std::tie( attack_id, vector_id, contact_area ) = attack; // If no weapon is selected, use highest layer of clothing for attack vector instead. - if( contact_area != sub_body_part_sub_limb_debug ) { + if( contact_area != sub_bodypart_str_id::NULL_ID() ) { // todo: simplify this by using item_location everywhere // so only cur_weapon = worn.current_unarmed_weapon remains // Check if our vector allows armor-derived damage @@ -944,7 +942,7 @@ bool Character::melee_attack_abstract( Creature &t, bool allow_special, did_hit( t ); if( t.as_character() ) { dealt_projectile_attack dp = dealt_projectile_attack(); - t.as_character()->on_hit( this, bodypart_id( "bp_null" ), 0.0f, &dp ); + t.as_character()->on_hit( this, bodypart_str_id::NULL_ID().id(), 0.0f, &dp ); } return true; } @@ -1420,9 +1418,8 @@ std::tuple Character::pick_tech } } - return random_entry( possible, - std::make_tuple( tec_none, attack_vector_vector_null, - sub_body_part_sub_limb_debug ) ); + return random_entry( possible, std::make_tuple( tec_none, attack_vector_id::NULL_ID(), + sub_bodypart_str_id::NULL_ID() ) ); } std::optional> Character::evaluate_technique( const matec_id &tec_id, Creature const &t, const item_location &weap, diff --git a/src/monattack.cpp b/src/monattack.cpp index 18e2bdb9e664d..51e4c29666d00 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -4115,7 +4115,7 @@ bool mattack::bio_op_takedown( monster *z ) return true; } // Yes, it has the CQC bionic. - bodypart_id hit( "bp_null" ); + bodypart_id hit = bodypart_str_id::NULL_ID(); if( one_in( 2 ) ) { hit = bodypart_id( "leg_l" ); } else { diff --git a/src/monstergenerator.cpp b/src/monstergenerator.cpp index 55844d292eedd..f139b9fa84026 100644 --- a/src/monstergenerator.cpp +++ b/src/monstergenerator.cpp @@ -701,7 +701,6 @@ mon_effect_data::mon_effect_data() : chance( 100.0f ), permanent( false ), affect_hit_bp( false ), - bp( body_part_bp_null ), duration( 1, 1 ), intensity( 0, 0 ) {} @@ -711,7 +710,7 @@ void mon_effect_data::load( const JsonObject &jo ) optional( jo, false, "chance", chance, 100.f ); optional( jo, false, "permanent", permanent, false ); optional( jo, false, "affect_hit_bp", affect_hit_bp, false ); - optional( jo, false, "bp", bp, body_part_bp_null ); + optional( jo, false, "bp", bp ); optional( jo, false, "message", message ); // Support shorthand for a single value. if( jo.has_int( "duration" ) ) { diff --git a/src/morale.cpp b/src/morale.cpp index c7f0195d44e9f..038b78145b1ed 100644 --- a/src/morale.cpp +++ b/src/morale.cpp @@ -979,14 +979,13 @@ void player_morale::on_worn_item_washed( const item &it ) void player_morale::on_effect_int_change( const efftype_id &eid, int intensity, const bodypart_id &bp ) { - const bodypart_id bp_null( "bp_null" ); - if( eid == effect_took_prozac && bp == bp_null ) { + if( eid == effect_took_prozac && bp == bodypart_str_id::NULL_ID() ) { set_prozac( intensity != 0 ); - } else if( eid == effect_took_prozac_bad && bp == bp_null ) { + } else if( eid == effect_took_prozac_bad && bp == bodypart_str_id::NULL_ID() ) { set_prozac_bad( intensity != 0 ); - } else if( eid == effect_cold && bp != bp_null ) { + } else if( eid == effect_cold && bp != bodypart_str_id::NULL_ID() ) { body_parts[bp].cold = intensity; - } else if( eid == effect_hot && bp != bp_null ) { + } else if( eid == effect_hot && bp != bodypart_str_id::NULL_ID() ) { body_parts[bp].hot = intensity; } } diff --git a/src/morale.h b/src/morale.h index 0dc43461ab4ac..b6f23380d698b 100644 --- a/src/morale.h +++ b/src/morale.h @@ -66,7 +66,7 @@ class player_morale void on_worn_item_transform( const item &old_it, const item &new_it ); void on_worn_item_washed( const item &it ); void on_effect_int_change( const efftype_id &eid, int intensity, - const bodypart_id &bp = bodypart_id( "bp_null" ) ); + const bodypart_id &bp = bodypart_str_id::NULL_ID().id() ); void store( JsonOut &jsout ) const; void load( const JsonObject &jsin ); diff --git a/src/mtype.h b/src/mtype.h index 4dfac2cf25ca8..01dc8b98a31cf 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -214,7 +214,7 @@ struct mon_effect_data { // Whether the effect is permanent. bool permanent; bool affect_hit_bp; - bodypart_str_id bp; + bodypart_str_id bp = bodypart_str_id::NULL_ID(); // The range of the durations (in turns) of the effect. std::pair duration; // The range of the intensities of the effect. diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 38964125de7d8..6f5be5567f46f 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -6596,7 +6596,7 @@ talk_effect_fun_t::func f_deal_damage( const JsonObject &jo, std::string_view me } if( d.actor( is_npc )->get_monster() ) { - bp = bodypart_id( "bp_null" ); + bp = bodypart_str_id::NULL_ID(); } dmg_inst.add_damage( damage_type, dmg_amount.evaluate( d ), arpen.evaluate( d ), diff --git a/src/string_id_null_ids.cpp b/src/string_id_null_ids.cpp index acf78b515cb38..06557103d17ad 100644 --- a/src/string_id_null_ids.cpp +++ b/src/string_id_null_ids.cpp @@ -63,6 +63,7 @@ MAKE_NULL_ID( spell_type, "null" ) } //NOLINTNEXTLINE(cata-static-string_id-constants) +MAKE_NULL_ID2( attack_vector, "vector_null" ) MAKE_NULL_ID2( itype, "null" ) MAKE_NULL_ID2( mtype, "mon_null" ) MAKE_NULL_ID2( oter_t, "" ) diff --git a/src/trapfunc.cpp b/src/trapfunc.cpp index 744ea97dd32a7..c409a6a6b27de 100644 --- a/src/trapfunc.cpp +++ b/src/trapfunc.cpp @@ -474,7 +474,7 @@ bool trapfunc::crossbow( const tripoint_bub_ms &p, Creature *c, item * ) if( you != nullptr ) { ///\EFFECT_DODGE reduces chance of being hit by crossbow trap if( !one_in( 4 ) && rng( 8, 20 ) > you->get_dodge() ) { - bodypart_id hit( "bp_null" ); + bodypart_id hit = bodypart_str_id::NULL_ID(); switch( rng( 1, 10 ) ) { case 1: if( one_in( 2 ) ) { @@ -580,7 +580,7 @@ bool trapfunc::shotgun( const tripoint_bub_ms &p, Creature *c, item * ) } ///\EFFECT_DODGE reduces chance of being hit by shotgun trap if( rng( 5, 50 ) > you->get_dodge() ) { - bodypart_id hit = bodypart_id( "bp_null" ); + bodypart_id hit = bodypart_str_id::NULL_ID(); switch( rng( 1, 10 ) ) { case 1: if( one_in( 2 ) ) { @@ -1022,7 +1022,7 @@ bool trapfunc::pit_spikes( const tripoint_bub_ms &p, Creature *c, item * ) } else if( 0 == damage || rng( 5, 30 ) < dodge ) { you->add_msg_if_player( _( "You avoid the spikes within." ) ); } else { - bodypart_id hit( "bp_null" ); + bodypart_id hit = bodypart_str_id::NULL_ID(); switch( rng( 1, 10 ) ) { case 1: hit = bodypart_id( "leg_l" ); @@ -1107,7 +1107,7 @@ bool trapfunc::pit_glass( const tripoint_bub_ms &p, Creature *c, item * ) } else if( 0 == damage || rng( 5, 30 ) < dodge ) { you->add_msg_if_player( _( "You avoid the glass shards within." ) ); } else { - bodypart_id hit( "bp_null" ); + bodypart_id hit = bodypart_str_id::NULL_ID(); switch( rng( 1, 10 ) ) { case 1: hit = bodypart_id( "leg_l" ); diff --git a/tests/effect_test.cpp b/tests/effect_test.cpp index 74bb620d9e137..6543cddb8cd3b 100644 --- a/tests/effect_test.cpp +++ b/tests/effect_test.cpp @@ -92,7 +92,8 @@ TEST_CASE( "effect_initialization_test", "[effect][init]" ) TEST_CASE( "effect_duration", "[effect][duration]" ) { // "debugged" and "intensified" effects come from JSON effect data (data/mods/TEST_DATA/effects.json) - effect eff_debugged( effect_source::empty(), &effect_debugged.obj(), 1_turns, body_part_bp_null, + effect eff_debugged( effect_source::empty(), &effect_debugged.obj(), 1_turns, + bodypart_str_id::NULL_ID(), false, 1, calendar::turn ); // Current duration from effect initialization @@ -121,7 +122,8 @@ TEST_CASE( "effect_duration", "[effect][duration]" ) // 1000 rounded up, and it has "max_intensity": 3 meaning the highest its intensity will go is 3 at // a duration of 3000 or higher. SECTION( "set_duration modifies intensity if effect is duration-based" ) { - effect eff_intense( effect_source::empty(), &effect_intensified.obj(), 1_turns, body_part_bp_null, + effect eff_intense( effect_source::empty(), &effect_intensified.obj(), 1_turns, + bodypart_str_id::NULL_ID(), false, 1, calendar::turn ); REQUIRE( eff_intense.get_int_dur_factor() == 1_minutes ); @@ -165,7 +167,8 @@ TEST_CASE( "effect_duration", "[effect][duration]" ) // TEST_CASE( "effect_intensity", "[effect][intensity]" ) { - effect eff_debugged( effect_source::empty(), &effect_debugged.obj(), 3_turns, body_part_bp_null, + effect eff_debugged( effect_source::empty(), &effect_debugged.obj(), 3_turns, + bodypart_str_id::NULL_ID(), false, 1, calendar::turn ); REQUIRE( eff_debugged.get_intensity() == 1 ); @@ -192,7 +195,7 @@ TEST_CASE( "effect_intensity", "[effect][intensity]" ) TEST_CASE( "effect_intensity_removal", "[effect][intensity]" ) { effect eff_test_int_remove( effect_source::empty(), &effect_test_int_remove.obj(), 3_turns, - body_part_bp_null, + bodypart_str_id::NULL_ID(), false, 1, calendar::turn ); REQUIRE( eff_test_int_remove.get_intensity() == 1 ); @@ -207,7 +210,8 @@ TEST_CASE( "effect_intensity_removal", "[effect][intensity]" ) TEST_CASE( "max_effective_intensity", "[effect][max][intensity]" ) { - effect eff_maxed( effect_source::empty(), &effect_max_effected.obj(), 3_turns, body_part_bp_null, + effect eff_maxed( effect_source::empty(), &effect_max_effected.obj(), 3_turns, + bodypart_str_id::NULL_ID(), false, 1, calendar::turn ); REQUIRE( eff_maxed.get_intensity() == 1 ); @@ -251,7 +255,8 @@ TEST_CASE( "effect_decay", "[effect][decay]" ) std::vector rem_bps; SECTION( "decay reduces effect duration by 1 turn and triggers intensity decay" ) { - effect eff_debugged( effect_source::empty(), &effect_debugged.obj(), 2_turns, body_part_bp_null, + effect eff_debugged( effect_source::empty(), &effect_debugged.obj(), 2_turns, + bodypart_str_id::NULL_ID(), false, 5, calendar::turn ); // Ensure it will last 2 turns, and is not permanent/paused REQUIRE( to_turns( eff_debugged.get_duration() ) == 2 ); @@ -283,7 +288,8 @@ TEST_CASE( "effect_decay", "[effect][decay]" ) } SECTION( "decay does not reduce paused/permanent effect duration" ) { - effect eff_debugged( effect_source::empty(), &effect_debugged.obj(), 2_turns, body_part_bp_null, + effect eff_debugged( effect_source::empty(), &effect_debugged.obj(), 2_turns, + bodypart_str_id::NULL_ID(), true, 1, calendar::turn ); // Ensure it will last 2 turns, and is permanent/paused REQUIRE( to_turns( eff_debugged.get_duration() ) == 2 ); @@ -297,7 +303,8 @@ TEST_CASE( "effect_decay", "[effect][decay]" ) } SECTION( "intensity decay triggers on the appropriate turns" ) { - effect eff_debugged( effect_source::empty(), &effect_debugged.obj(), 1_hours, body_part_bp_null, + effect eff_debugged( effect_source::empty(), &effect_debugged.obj(), 1_hours, + bodypart_str_id::NULL_ID(), false, 10, calendar::turn ); // Ensure it has a decay tick of 2 turns and a decay step of -1, and int removal is allwed // Also check max duration @@ -361,7 +368,7 @@ TEST_CASE( "effect_decay", "[effect][decay]" ) SECTION( "int_decay_remove == false protects an effect from removal" ) { effect eff_test_int_remove( effect_source::empty(), &effect_test_int_remove.obj(), 3_turns, - body_part_bp_null, + bodypart_str_id::NULL_ID(), false, 3, calendar::turn ); // Ensure it has the -2 int decay step, is protected from removal and has a decay tick of 1 REQUIRE( eff_test_int_remove.get_int_decay_step() == -2 ); @@ -456,7 +463,7 @@ TEST_CASE( "effect_display_and_speed_name_may_vary_with_intensity", // "name": [ "Whoa", "Wut?", "Wow!" ] // "max_intensity": 3 effect eff_intense( effect_source::empty(), &effect_intensified.obj(), 1_turns, - body_part_bp_null, false, 1, calendar::turn ); + bodypart_str_id::NULL_ID(), false, 1, calendar::turn ); REQUIRE( eff_intense.get_max_intensity() == 3 ); // use_name_ints is true if there are names for each intensity @@ -489,7 +496,7 @@ TEST_CASE( "effect_display_and_speed_name_may_vary_with_intensity", // "name": [ "Debugged" ] // "speed_name": "Optimized" effect eff_debugged( effect_source::empty(), &effect_debugged.obj(), 1_minutes, - body_part_bp_null, false, 1, calendar::turn ); + bodypart_str_id::NULL_ID(), false, 1, calendar::turn ); THEN( "disp_name has the name, and current intensity if > 1" ) { eff_debugged.set_intensity( 1 ); @@ -572,7 +579,8 @@ TEST_CASE( "effect_body_part", "[effect][bodypart]" ) TEST_CASE( "effect_modifiers", "[effect][modifier]" ) { SECTION( "base_mods apply equally for any intensity" ) { - effect eff_debugged( effect_source::empty(), &effect_debugged.obj(), 1_minutes, body_part_bp_null, + effect eff_debugged( effect_source::empty(), &effect_debugged.obj(), 1_minutes, + bodypart_str_id::NULL_ID(), false, 1, calendar::turn ); CHECK( eff_debugged.get_mod( "STR" ) == 1 ); @@ -586,7 +594,8 @@ TEST_CASE( "effect_modifiers", "[effect][modifier]" ) // Scaling mods - vary based on intensity SECTION( "scaling_mods vary based on intensity" ) { - effect eff_intense( effect_source::empty(), &effect_intensified.obj(), 1_turns, body_part_bp_null, + effect eff_intense( effect_source::empty(), &effect_intensified.obj(), 1_turns, + bodypart_str_id::NULL_ID(), false, 1, calendar::turn ); REQUIRE( eff_intense.get_max_intensity() == 3 ); @@ -635,7 +644,7 @@ TEST_CASE( "bleed_effect_attribution", "[effect][bleed][monster]" ) WHEN( "when player cuts monster" ) { REQUIRE( test_monster.get_hp() == test_monster.get_hp_max() ); THEN( "bleed effect gets attributed to player" ) { - test_monster.deal_damage( player.as_character(), body_part_bp_null, cut_damage ); + test_monster.deal_damage( player.as_character(), bodypart_str_id::NULL_ID(), cut_damage ); const effect &bleed = test_monster.get_effect( effect_bleed ); CHECK( test_monster.get_hp() < test_monster.get_hp_max() ); CHECK( !bleed.is_null() ); diff --git a/tests/melee_test.cpp b/tests/melee_test.cpp index 4b0f6b1c5431d..4de0ab66388b1 100644 --- a/tests/melee_test.cpp +++ b/tests/melee_test.cpp @@ -344,7 +344,7 @@ static void check_damage_from_test_fire( const std::string &mon_id, int expected standard_npc dude( "TestCharacter", dude_pos, {}, 8, 10, 10, 10, 10 ); monster &mon = spawn_test_monster( mon_id, dude.pos_bub() + tripoint::east ); REQUIRE( mon.pos_bub() == dude.pos_bub() + tripoint::east ); - REQUIRE( mon.get_armor_type( damage_test_fire, body_part_bp_null ) == expected_resist ); + REQUIRE( mon.get_armor_type( damage_test_fire, bodypart_str_id::NULL_ID() ) == expected_resist ); REQUIRE( mon.is_immune_damage( damage_test_fire ) == is_immune ); REQUIRE( mon.get_hp() == mon.get_hp_max() ); REQUIRE( dude.get_value( "general_dmg_type_test_test_fire" ).empty() ); diff --git a/tests/stats_tracker_test.cpp b/tests/stats_tracker_test.cpp index 49a20acf8c634..0f84ec9a9f52f 100644 --- a/tests/stats_tracker_test.cpp +++ b/tests/stats_tracker_test.cpp @@ -114,16 +114,16 @@ TEST_CASE( "stats_tracker_total_events", "[stats]" ) CHECK( s.get_events( ctd ).total( "damage", damage_to_u ) == 0 ); CHECK( s.get_events( ctd ).total( "damage", damage_to_any ) == 0 ); - b.send( u_id, 10, body_part_bp_null, 0 ); + b.send( u_id, 10, bodypart_str_id::NULL_ID(), 0 ); CHECK( s.get_events( ctd ).total( "damage", damage_to_u ) == 10 ); CHECK( s.get_events( ctd ).total( "damage", damage_to_any ) == 10 ); - b.send( other_id, 10, body_part_bp_null, 0 ); + b.send( other_id, 10, bodypart_str_id::NULL_ID(), 0 ); CHECK( s.get_events( ctd ).total( "damage", damage_to_u ) == 10 ); CHECK( s.get_events( ctd ).total( "damage", damage_to_any ) == 20 ); - b.send( u_id, 10, body_part_bp_null, 0 ); + b.send( u_id, 10, bodypart_str_id::NULL_ID(), 0 ); CHECK( s.get_events( ctd ).total( "damage", damage_to_u ) == 20 ); CHECK( s.get_events( event_type::character_takes_damage ).total( "damage", damage_to_any ) == 30 ); - b.send( u_id, 5, body_part_bp_null, 0 ); + b.send( u_id, 5, bodypart_str_id::NULL_ID(), 0 ); CHECK( s.get_events( event_type::character_takes_damage ).total( "damage", damage_to_u ) == 25 ); CHECK( s.get_events( event_type::character_takes_damage ).total( "damage", damage_to_any ) == 35 ); } @@ -193,11 +193,11 @@ TEST_CASE( "stats_tracker_event_time_bounds", "[stats]" ) CHECK( !s.get_events( ctd ).first() ); CHECK( !s.get_events( ctd ).last() ); - b.send( u_id, 10, body_part_bp_null, 0 ); + b.send( u_id, 10, bodypart_str_id::NULL_ID(), 0 ); CHECK( s.get_events( ctd ).first()->second.first == start ); CHECK( s.get_events( ctd ).last()->second.last == calendar::turn ); calendar::turn += 1_minutes; - b.send( u_id, 10, body_part_bp_null, 0 ); + b.send( u_id, 10, bodypart_str_id::NULL_ID(), 0 ); CHECK( s.get_events( ctd ).first()->second.first == start ); CHECK( s.get_events( ctd ).last()->second.last == calendar::turn ); } @@ -337,7 +337,7 @@ TEST_CASE( "stats_tracker_with_event_statistics", "[stats]" ) SECTION( "damage" ) { const cata::event avatar_2_damage = - cata::event::make( u_id, 2, body_part_bp_null, 0 ); + cata::event::make( u_id, 2, bodypart_str_id::NULL_ID(), 0 ); send_game_start( b, u_id ); CHECK( score_score_damage_taken->value( s ).get() == 0 ); @@ -556,7 +556,7 @@ TEST_CASE( "stats_tracker_watchers", "[stats]" ) SECTION( "damage" ) { const cata::event avatar_2_damage = - cata::event::make( u_id, 2, body_part_bp_null, 0 ); + cata::event::make( u_id, 2, bodypart_str_id::NULL_ID(), 0 ); watch_stat damage_watcher; s.add_watcher( event_statistic_avatar_damage_taken, &damage_watcher );