diff --git a/data/json/body_parts.json b/data/json/body_parts.json index afd773b27e6f..8814df467454 100644 --- a/data/json/body_parts.json +++ b/data/json/body_parts.json @@ -1,113 +1,87 @@ [ { "id": "num_bp", + "legacy_id": "NUM_BP", "type": "body_part", "name": "appendix", "accusative": { "ctxt": "bodypart_accusative", "str": "appendix" }, "heading": "appendix", "heading_multiple": "Appendices", - "encumbrance_text": "It's inflamed.", - "main_part": "num_bp", - "opposite_part": "num_bp", - "hit_size": 0, - "hit_size_relative": [ 0, 0, 0 ], - "hit_difficulty": 0, - "side": "both", - "base_hp": 60, - "legacy_id": "NUM_BP" + "encumbrance_text": "It's inflamed." }, { "id": "torso", + "legacy_id": "TORSO", "type": "body_part", "name": "torso", "accusative": { "ctxt": "bodypart_accusative", "str": "torso" }, "heading": "Torso", - "heading_multiple": "Torso", "hp_bar_ui_text": "TORSO", "encumbrance_text": "Dodging and melee is hampered.", - "main_part": "torso", - "opposite_part": "torso", "essential": true, "hit_size": 45, "hit_size_relative": [ 20, 33.33, 36.57 ], "hit_difficulty": 1, - "side": "both", - "legacy_id": "TORSO", "stylish_bonus": 6, "hot_morale_mod": 2, "cold_morale_mod": 2, "squeamish_penalty": 6, - "base_hp": 60, "bionic_slots": 80 }, { "id": "head", + "legacy_id": "HEAD", "type": "body_part", "name": "head", "accusative": { "ctxt": "bodypart_accusative", "str": "head" }, "heading": "Head", - "heading_multiple": "Head", "hp_bar_ui_text": "HEAD", - "encumbrance_text": "", - "main_part": "head", - "opposite_part": "head", "essential": true, "hit_size": 6, "hit_size_relative": [ 0, 2.33, 5.71 ], "hit_difficulty": 1.35, - "side": "both", - "legacy_id": "HEAD", "stylish_bonus": 3, "hot_morale_mod": 2, "cold_morale_mod": 2, "squeamish_penalty": 7, - "base_hp": 60, "bionic_slots": 18 }, { "id": "eyes", + "legacy_id": "EYES", "type": "body_part", "name": "eyes", "accusative": { "ctxt": "bodypart_accusative", "str": "eyes" }, "heading": "Eyes", - "heading_multiple": "Eyes", "encumbrance_text": "Ranged combat is hampered.", "main_part": "head", - "opposite_part": "eyes", "hit_size": 1, "hit_size_relative": [ 0, 0.33, 0.57 ], "hit_difficulty": 1.15, - "side": "both", - "legacy_id": "EYES", "stylish_bonus": 2, "squeamish_penalty": 8, - "base_hp": 60, "bionic_slots": 4 }, { "id": "mouth", + "legacy_id": "MOUTH", "type": "body_part", "name": "mouth", "accusative": { "ctxt": "bodypart_accusative", "str": "mouth" }, "heading": "Mouth", - "heading_multiple": "Mouth", "encumbrance_text": "Running is slowed.", "main_part": "head", - "opposite_part": "mouth", "hit_size": 1, - "hit_size_relative": [ 0, 0, 0 ], "hit_difficulty": 1.15, - "side": "both", - "legacy_id": "MOUTH", "stylish_bonus": 2, "hot_morale_mod": 2, "cold_morale_mod": 2, "squeamish_penalty": 9, - "base_hp": 60, "bionic_slots": 4 }, { "id": "arm_l", + "legacy_id": "ARM_L", "type": "body_part", "//": "See comments in `body_part_struct::load` of bodypart.cpp about why xxx and xxx_multiple are not inside a single translation object.", "name": "left arm", @@ -118,21 +92,19 @@ "heading_multiple": "Arms", "encumbrance_text": "Melee and ranged combat is hampered.", "hp_bar_ui_text": "L ARM", - "main_part": "arm_l", "opposite_part": "arm_r", "hit_size": 9, "hit_size_relative": [ 15, 20, 22.86 ], "hit_difficulty": 0.95, "side": "left", - "legacy_id": "ARM_L", "hot_morale_mod": 0.5, "cold_morale_mod": 0.5, "squeamish_penalty": 5, - "base_hp": 60, "bionic_slots": 20 }, { "id": "arm_r", + "legacy_id": "ARM_R", "type": "body_part", "name": "right arm", "name_multiple": "arms", @@ -142,21 +114,19 @@ "heading_multiple": "Arms", "hp_bar_ui_text": "R ARM", "encumbrance_text": "Melee and ranged combat is hampered.", - "main_part": "arm_r", "opposite_part": "arm_l", "hit_size": 9, "hit_size_relative": [ 15, 20, 22.86 ], "hit_difficulty": 0.95, "side": "right", - "legacy_id": "ARM_R", "hot_morale_mod": 0.5, "cold_morale_mod": 0.5, "squeamish_penalty": 5, - "base_hp": 60, "bionic_slots": 20 }, { "id": "hand_l", + "legacy_id": "HAND_L", "type": "body_part", "name": "left hand", "name_multiple": "hands", @@ -168,19 +138,17 @@ "main_part": "arm_l", "opposite_part": "hand_r", "hit_size": 3, - "hit_size_relative": [ 0, 0, 0 ], "hit_difficulty": 1.1, "side": "left", - "legacy_id": "HAND_L", "stylish_bonus": 0.5, "hot_morale_mod": 0.5, "cold_morale_mod": 0.5, "squeamish_penalty": 3, - "base_hp": 60, "bionic_slots": 5 }, { "id": "hand_r", + "legacy_id": "HAND_R", "type": "body_part", "name": "right hand", "name_multiple": "hands", @@ -192,19 +160,17 @@ "main_part": "arm_r", "opposite_part": "hand_l", "hit_size": 3, - "hit_size_relative": [ 0, 0, 0 ], "hit_difficulty": 1.1, "side": "right", - "legacy_id": "HAND_R", "stylish_bonus": 0.5, "hot_morale_mod": 0.5, "cold_morale_mod": 0.5, "squeamish_penalty": 3, - "base_hp": 60, "bionic_slots": 5 }, { "id": "leg_l", + "legacy_id": "LEG_L", "type": "body_part", "name": "left leg", "name_multiple": "legs", @@ -214,22 +180,20 @@ "heading_multiple": "Legs", "hp_bar_ui_text": "L LEG", "encumbrance_text": "Running and swimming are slowed.", - "main_part": "leg_l", "opposite_part": "leg_r", "hit_size": 9, "hit_size_relative": [ 25, 12, 5.71 ], "hit_difficulty": 0.975, "side": "left", - "legacy_id": "LEG_L", "stylish_bonus": 1, "hot_morale_mod": 0.5, "cold_morale_mod": 0.5, "squeamish_penalty": 5, - "base_hp": 60, "bionic_slots": 30 }, { "id": "leg_r", + "legacy_id": "LEG_R", "type": "body_part", "name": "right leg", "name_multiple": "legs", @@ -239,22 +203,20 @@ "heading_multiple": "Legs", "hp_bar_ui_text": "R LEG", "encumbrance_text": "Running and swimming are slowed.", - "main_part": "leg_r", "opposite_part": "leg_l", "hit_size": 9, "hit_size_relative": [ 25, 12, 5.71 ], "hit_difficulty": 0.975, "side": "right", - "legacy_id": "LEG_R", "stylish_bonus": 1, "hot_morale_mod": 0.5, "cold_morale_mod": 0.5, "squeamish_penalty": 5, - "base_hp": 60, "bionic_slots": 30 }, { "id": "foot_l", + "legacy_id": "FOOT_L", "type": "body_part", "name": "left foot", "name_multiple": "feet", @@ -266,19 +228,17 @@ "main_part": "leg_l", "opposite_part": "foot_r", "hit_size": 3, - "hit_size_relative": [ 0, 0, 0 ], "hit_difficulty": 0.8, "side": "left", - "legacy_id": "FOOT_L", "stylish_bonus": 0.5, "hot_morale_mod": 0.5, "cold_morale_mod": 0.5, "squeamish_penalty": 3, - "base_hp": 60, "bionic_slots": 7 }, { "id": "foot_r", + "legacy_id": "FOOT_R", "type": "body_part", "name": "right foot", "name_multiple": "feet", @@ -290,15 +250,12 @@ "main_part": "leg_r", "opposite_part": "foot_l", "hit_size": 3, - "hit_size_relative": [ 0, 0, 0 ], "hit_difficulty": 0.8, "side": "right", - "legacy_id": "FOOT_R", "stylish_bonus": 0.5, "hot_morale_mod": 0.5, "cold_morale_mod": 0.5, "squeamish_penalty": 3, - "base_hp": 60, "bionic_slots": 7 } ] diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index 01d74a8c296b..fdf2b0f6493b 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -438,15 +438,17 @@ This section describes each json file and their contents. Each json has their ow | name | (_mandatory_) In-game name displayed. | accusative | (_mandatory_) Accusative form for this bodypart. | heading | (_mandatory_) How it's displayed in headings. -| heading_multiple | (_mandatory_) Plural form of heading. -| hp_bar_ui_text | (_mandatory_) How it's displayed next to the hp bar in the panel. -| main_part | (_mandatory_) What is the main part this one is attached to. (If this is a main part it's attached to itself) -| base_hp | (_mandatory_) The amount of hp this part has before any modification. -| opposite_part | (_mandatory_) What is the opposite part ot this one in case of a pair. -| essential | (_optional_) Whether the character dies if this part drops to 0 HP. -| hit_size | (_mandatory_) Size of the body part when doing an unweighted selection. -| hit_size_relative | (_mandatory_) Hit sizes for attackers who are smaller, equal in size, and bigger. -| hit_difficulty | (_mandatory_) How hard is it to hit a given body part, assuming "owner" is hit. Higher number means good hits will veer towards this part, lower means this part is unlikely to be hit by inaccurate attacks. Formula is `chance *= pow(hit_roll, hit_difficulty)` +| heading_multiple | (_optional_) Plural form of heading. (default: heading value) +| hp_bar_ui_text | (_optional_) How it's displayed next to the hp bar in the panel. (default: empty string) +| encumbrance_text | (_optional_) Description of effect when encumbered. (default: empty string) +| main_part | (_optional_) What is the main part this one is attached to. (default: self) +| base_hp | (_optional_) The amount of hp this part has before any modification. (default: `60`) +| opposite_part | (_optional_) What is the opposite part ot this one in case of a pair. (default: self) +| essential | (_optional_) Whether the character dies if this part drops to `0` HP. +| hit_size | (_optional_) Float. Size of the body part when doing an unweighted selection. (default: `0.`) +| hit_size_relative | (_optional_) Float. Hit sizes for attackers who are smaller, equal in size, and bigger. (default: `[ 0, 0, 0 ]` +| hit_difficulty | (_optional_) Float. How hard is it to hit a given body part, assuming "owner" is hit. Higher number means good hits will veer towards this part, lower means this part is unlikely to be hit by inaccurate attacks. Formula is `chance *= pow(hit_roll, hit_difficulty)` (default: `0`) +| side | (_optional_) Which side this body part is on. Default both. | stylish_bonus | (_optional_) Mood bonus associated with wearing fancy clothing on this part. (default: `0`) | hot_morale_mod | (_optional_) Mood effect of being too hot on this part. (default: `0`) | cold_morale_mod | (_optional_) Mood effect of being too cold on this part. (default: `0`) diff --git a/src/bodypart.cpp b/src/bodypart.cpp index e0f8f02c3386..3d8a21b5bc5c 100644 --- a/src/bodypart.cpp +++ b/src/bodypart.cpp @@ -235,22 +235,23 @@ void body_part_type::load( const JsonObject &jo, const std::string & ) mandatory( jo, was_loaded, "heading", name_as_heading ); // Same as the above comment - mandatory( jo, was_loaded, "heading_multiple", name_as_heading_multiple ); + optional( jo, was_loaded, "heading_multiple", name_as_heading_multiple, name_as_heading ); optional( jo, was_loaded, "hp_bar_ui_text", hp_bar_ui_text ); - mandatory( jo, was_loaded, "encumbrance_text", encumb_text ); - mandatory( jo, was_loaded, "hit_size", hit_size ); - mandatory( jo, was_loaded, "hit_difficulty", hit_difficulty ); - mandatory( jo, was_loaded, "hit_size_relative", hit_size_relative ); + optional( jo, was_loaded, "encumbrance_text", encumb_text ); - mandatory( jo, was_loaded, "base_hp", base_hp ); + assign( jo, "hit_size", hit_size, true ); + assign( jo, "hit_difficulty", hit_difficulty, true ); + assign( jo, "hit_size_relative", hit_size_relative, true ); - mandatory( jo, was_loaded, "legacy_id", legacy_id ); + assign( jo, "base_hp", base_hp, true ); + + assign( jo, "legacy_id", legacy_id ); token = legacy_id_to_enum( legacy_id ); - mandatory( jo, was_loaded, "main_part", main_part ); - mandatory( jo, was_loaded, "opposite_part", opposite_part ); + optional( jo, was_loaded, "main_part", main_part, id ); + optional( jo, was_loaded, "opposite_part", opposite_part, id ); - optional( jo, was_loaded, "essential", essential ); + optional( jo, was_loaded, "essential", essential, false ); optional( jo, was_loaded, "hot_morale_mod", hot_morale_mod, 0.0 ); optional( jo, was_loaded, "cold_morale_mod", cold_morale_mod, 0.0 ); @@ -258,11 +259,12 @@ void body_part_type::load( const JsonObject &jo, const std::string & ) optional( jo, was_loaded, "stylish_bonus", stylish_bonus, 0 ); optional( jo, was_loaded, "squeamish_penalty", squeamish_penalty, 0 ); - - optional( jo, was_loaded, "bionic_slots", bionic_slots_, 0 ); - part_side = jo.get_enum_value( "side" ); + const auto side_reader = enum_flags_reader { "side" }; + optional( jo, was_loaded, "side", part_side, side_reader, side::BOTH ); + + debugmsg( "Part id %s has side %s", id.c_str(), io::enum_to_string( part_side ) ); } void body_part_type::reset()