Skip to content

Commit

Permalink
Limbify/flagify field immunity (#60852)
Browse files Browse the repository at this point in the history
* Field immunity changes

* Update doc/JSON_INFO.md

Co-authored-by: Fris0uman <[email protected]>

Co-authored-by: Venera3 <[email protected]>
Co-authored-by: Fris0uman <[email protected]>
  • Loading branch information
3 people authored Sep 12, 2022
1 parent 2924a24 commit 4840ee2
Show file tree
Hide file tree
Showing 14 changed files with 68 additions and 30 deletions.
9 changes: 5 additions & 4 deletions data/json/field_type.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
}
],
"description_affix": "covered_in",
"immunity_data": { "traits": [ "WEB_WALKER" ] },
"immunity_data": { "flags": [ "WEBWALK" ] },
"immune_mtypes": [ "mon_spider_web", "mon_spider_web_s", "mon_mutant_arthropod" ],
"decrease_intensity_on_contact": true,
"priority": 2,
Expand Down Expand Up @@ -158,7 +158,7 @@
{ "name": "pool of acid", "color": "green" }
],
"description_affix": "covered_in",
"immunity_data": { "traits": [ "ACIDPROOF" ] },
"immunity_data": { "flags": [ "ACID_IMMUNE" ] },
"underwater_age_speedup": "2 minutes",
"has_acid": true,
"priority": 2,
Expand Down Expand Up @@ -262,7 +262,7 @@
"half_life": "30 minutes",
"phase": "liquid",
"display_field": true,
"immunity_data": { "traits": [ "GASTROPOD_FOOT" ] },
"immunity_data": { "flags": [ "SLUDGE_IMMUNE" ] },
"looks_like": "fd_sap"
},
{
Expand Down Expand Up @@ -940,6 +940,7 @@
{ "//": "repeat last entry" }
],
"description_affix": "illuminated_by",
"immunity_data": { "immunity_flags_worn": [ [ "sensor", "FLASH_PROTECTION" ] ] },
"priority": 4,
"half_life": "1 turns",
"phase": "plasma",
Expand Down Expand Up @@ -1305,7 +1306,7 @@
"outdoor_age_speedup": "5 turns",
"dirty_transparency_cache": true,
"has_fume": true,
"immunity_data": { "traits": [ "M_IMMUNE" ], "body_part_env_resistance": [ [ "mouth", 15 ], [ "eyes", 15 ] ] },
"immunity_data": { "flags": [ "MYCUS_IMMUNE" ], "body_part_env_resistance": [ [ "mouth", 15 ], [ "sensor", 15 ] ] },
"priority": 8,
"half_life": "4 minutes",
"phase": "gas",
Expand Down
6 changes: 4 additions & 2 deletions data/json/monster_special_attacks/monster_deaths.json
Original file line number Diff line number Diff line change
Expand Up @@ -534,9 +534,11 @@
"valid_targets": [ "hostile", "ally", "ground" ],
"effect": "attack",
"shape": "blast",
"flags": [ "NO_EXPLOSION_SFX" ],
"flags": [ "NO_EXPLOSION_SFX", "RANDOM_AOE" ],
"field_id": "fd_dazzling",
"field_chance": 1,
"min_aoe": 1,
"max_aoe": 2,
"field_chance": 2,
"min_field_intensity": 2,
"max_field_intensity": 2,
"min_range": 2,
Expand Down
2 changes: 1 addition & 1 deletion data/json/monsters/turrets.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"special_attacks": [ [ "SEARCHLIGHT", 1 ] ],
"death_drops": { "groups": [ [ "robots", 1 ], [ "turret_searchlight", 1 ] ] },
"death_function": {
"effect": { "id": "death_focused_beam" },
"effect": { "id": "death_focused_beam", "hit_self": true },
"message": "As the final light is destroyed, it erupts in a blinding flare!",
"corpse_type": "NO_CORPSE"
},
Expand Down
5 changes: 4 additions & 1 deletion data/json/mutations/mutations.json
Original file line number Diff line number Diff line change
Expand Up @@ -3369,7 +3369,8 @@
"valid": false,
"purifiable": false,
"threshreq": [ "THRESH_MYCUS" ],
"category": [ "MYCUS" ]
"category": [ "MYCUS" ],
"flags": [ "MYCUS_IMMUNE" ]
},
{
"type": "mutation",
Expand Down Expand Up @@ -4567,6 +4568,7 @@
"prereqs": [ "SLIMY" ],
"threshreq": [ "THRESH_GASTROPOD" ],
"leads_to": [ "GASTROPOD_BALANCE" ],
"flags": [ "SLUDGE_IMMUNE" ],
"visibility": 8,
"ugliness": 9,
"encumbrance_always": [ [ "leg_l", 10 ], [ "leg_r", 10 ], [ "foot_l", 10 ], [ "foot_r", 10 ] ],
Expand Down Expand Up @@ -4711,6 +4713,7 @@
"points": 1,
"description": "Your body excretes very fine amounts of a chemical which prevents you from sticking to webs. Walking through webs does not affect you at all.",
"leads_to": [ "WEB_WEAVER" ],
"flags": [ "WEBWALK" ],
"category": [ "SPIDER" ]
},
{
Expand Down
2 changes: 1 addition & 1 deletion data/mods/Aftershock/effects.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"outdoor_age_speedup": "3 minutes",
"dirty_transparency_cache": true,
"has_fume": true,
"immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ], "traits": [ "MIGO_BREATHE" ] },
"immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ], "flags": [ "MIGO_IMMUNE" ] },
"priority": 8,
"half_life": "10 minutes",
"phase": "gas"
Expand Down
3 changes: 2 additions & 1 deletion data/mods/Aftershock/mutations/mutations.json
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,8 @@
"points": 4,
"description": "You can now breathe the gasses the mi-go thrive in.",
"starting_trait": false,
"category": [ "MIGO" ]
"category": [ "MIGO" ],
"flags": [ "MIGO_IMMUNE" ]
},
{
"type": "mutation",
Expand Down
4 changes: 2 additions & 2 deletions data/mods/Magiclysm/field.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
}
],
"description_affix": "covered_in",
"immunity_data": { "traits": [ "SHAPESHIFTER" ] },
"immunity_data": { "flags": [ "ALKAHEST_IMMUNE" ] },
"underwater_age_speedup": "8 h",
"priority": 2,
"half_life": "8 h",
Expand Down Expand Up @@ -114,7 +114,7 @@
"effects": [ { "effect_id": "ice_energy", "intensity": 3, "immune_in_vehicle": true, "is_environmental": false } ]
}
],
"immunity_data": { "traits": [ "PERMAFROST_MAGE" ] },
"immunity_data": { "flags": [ "COLD_ENERGY_IMMUNE" ] },
"half_life": "3 seconds"
},
{
Expand Down
2 changes: 1 addition & 1 deletion data/mods/Magiclysm/monsters/dragon.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"dirty_transparency_cache": true,
"percent_spread": 40,
"outdoor_age_speedup": "0 turns",
"immunity_data": { "body_part_env_resistance": [ [ "eyes", 12 ] ] },
"immunity_data": { "body_part_env_resistance": [ [ "sensor", 12 ] ] },
"priority": 8,
"half_life": "2 minutes",
"phase": "gas",
Expand Down
4 changes: 2 additions & 2 deletions data/mods/Magiclysm/traits/attunements.json
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@
"SOULFIRE",
"WITHER_MAGE"
],
"flags": [ "ATTUNEMENT" ]
"flags": [ "ATTUNEMENT", "COLD_ENERGY_IMMUNE" ]
},
{
"id": "RADIATION_MAGE",
Expand Down Expand Up @@ -879,7 +879,7 @@
"SOULFIRE",
"WITHER_MAGE"
],
"flags": [ "ATTUNEMENT" ]
"flags": [ "ATTUNEMENT", "ALKAHEST_IMMUNE" ]
},
{
"id": "SOULFIRE",
Expand Down
2 changes: 1 addition & 1 deletion data/mods/desert_region/weather/fd_dust.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
"gas_absorption_factor": 12,
"outdoor_age_speedup": "20 seconds",
"dirty_transparency_cache": true,
"immunity_data": { "body_part_env_resistance": [ [ "mouth", 3 ], [ "eyes", 1 ] ] },
"immunity_data": { "body_part_env_resistance": [ [ "mouth", 3 ], [ "sensor", 1 ] ] },
"priority": 8,
"half_life": "20 seconds",
"phase": "gas",
Expand Down
7 changes: 4 additions & 3 deletions doc/JSON_INFO.md
Original file line number Diff line number Diff line change
Expand Up @@ -5317,9 +5317,10 @@ Fields can exist on top of terrain/furniture, and support different intensity le
],
"npc_complain": { "chance": 20, "issue": "weed_smoke", "duration": "10 minutes", "speech": "<weed_smoke>" }, // NPCs in this field will complain about being in it once per <duration> if a 1-in-<chance> roll succeeds, giving off a <speech> bark that supports snippets
"immunity_data": {
{ "traits": [ "WEB_WALKER" ] },
{ "body_part_env_resistance": [ [ "mouth", 15 ] ] }
}, // If the character in the field has the defined traits or env resistance on the bodypart they will be considered immune to the field
{ "flags": [ "WEBWALK" ] },
{ "body_part_env_resistance": [ [ "mouth", 15 ], [ "sensor", 10 ] ] },
"immunity_flags_worn": [ [ "sensor", "FLASH_PROTECTION" ] ]
}, // If the character in the field has the defined character flags (see Character Flags), necessary env resistance or worn item flags on ALL bodyparts of the defined type they will be considered immune to the field's effects -- in this example a player is immune if they have the WEBWALK flag, wear flash protection on their eyes or have both their eyes and mouth covered
"decay_amount_factor": 2, // The field's rain decay amount is divided by this when processing the field, the rain decay is a function of the weather type's precipitation class: very_light = 5s, light = 15s, heavy = 45 s
"half_life": "3 minutes", // If above 0 the field will disappear after two half-lifes on average
"underwater_age_speedup": "25 minutes", // Increase the field's age by this time every tick if it's on a terrain with the SWIMMABLE flag
Expand Down
34 changes: 29 additions & 5 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5278,19 +5278,43 @@ bool Character::is_immune_field( const field_type_id &fid ) const
}
// Check to see if we are immune
const field_type &ft = fid.obj();
for( const trait_id &t : ft.immunity_data_traits ) {
if( has_trait( t ) ) {
for( const json_character_flag &flag : ft.immunity_data_flags ) {
if( has_flag( flag ) ) {
return true;
}
}
bool immune_by_body_part_resistance = !ft.immunity_data_body_part_env_resistance.empty();
for( const std::pair<bodypart_str_id, int> &fide : ft.immunity_data_body_part_env_resistance ) {
immune_by_body_part_resistance = immune_by_body_part_resistance &&
get_env_resist( fide.first.id() ) >= fide.second;
for( const std::pair<body_part_type::type, int> &fide :
ft.immunity_data_body_part_env_resistance ) {
for( const bodypart_id &bp : get_all_body_parts_of_type( fide.first ) ) {
if( get_env_resist( bp ) < fide.second ) {
// If any one of a bodypart type is unprotected disregard this immunity type
// TODO: mitigate effect strength based on protected:unprotected ratio?
immune_by_body_part_resistance = false;
break;
}
}
}
if( immune_by_body_part_resistance ) {
return true;
}

bool immune_by_worn_flags = !ft.immunity_data_part_item_flags.empty();
for( const std::pair<body_part_type::type, flag_id> &fide :
ft.immunity_data_part_item_flags ) {
for( const bodypart_id &bp : get_all_body_parts_of_type( fide.first ) ) {
if( !worn_with_flag( fide.second, bp ) ) {
// If any one of a bodypart type is unprotected disregard this immunity type
// TODO: mitigate effect strength based on protected:unprotected ratio?
immune_by_worn_flags = false;
break;
}
}
}
if( immune_by_worn_flags ) {
return true;
}

if( ft.has_elec ) {
return is_elec_immune();
}
Expand Down
12 changes: 8 additions & 4 deletions src/field_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,16 @@ void field_type::load( const JsonObject &jo, const std::string & )
}

JsonObject jid = jo.get_object( "immunity_data" );
for( const std::string id : jid.get_array( "traits" ) ) {
immunity_data_traits.emplace_back( id );
for( const std::string id : jid.get_array( "flags" ) ) {
immunity_data_flags.emplace_back( id );
}
for( JsonArray jao : jid.get_array( "body_part_env_resistance" ) ) {
immunity_data_body_part_env_resistance.emplace_back( std::make_pair( bodypart_str_id(
jao.get_string( 0 ) ), jao.get_int( 1 ) ) );
immunity_data_body_part_env_resistance.emplace_back( std::make_pair(
io::string_to_enum<body_part_type::type>( jao.get_string( 0 ) ), jao.get_int( 1 ) ) );
}
for( JsonArray jao : jid.get_array( "immunity_flags_worn" ) ) {
immunity_data_part_item_flags.emplace_back( std::make_pair(
io::string_to_enum<body_part_type::type>( jao.get_string( 0 ) ), jao.get_string( 1 ) ) );
}

optional( jo, was_loaded, "immune_mtypes", immune_mtypes );
Expand Down
6 changes: 4 additions & 2 deletions src/field_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <utility>
#include <vector>

#include "bodypart.h"
#include "calendar.h"
#include "catacharset.h"
#include "color.h"
Expand Down Expand Up @@ -200,8 +201,9 @@ struct field_type {
// chance, issue, duration, speech
std::tuple<int, std::string, time_duration, std::string> npc_complain_data;

std::vector<trait_id> immunity_data_traits;
std::vector<std::pair<bodypart_str_id, int>> immunity_data_body_part_env_resistance;
std::vector<json_character_flag> immunity_data_flags;
std::vector<std::pair<body_part_type::type, int>> immunity_data_body_part_env_resistance;
std::vector < std::pair<body_part_type::type, flag_id>> immunity_data_part_item_flags;
std::set<mtype_id> immune_mtypes;

int priority = 0;
Expand Down

0 comments on commit 4840ee2

Please sign in to comment.