diff --git a/data/json/bionics.json b/data/json/bionics.json index 0a5832c4b027..3c3bc76ff161 100644 --- a/data/json/bionics.json +++ b/data/json/bionics.json @@ -710,7 +710,7 @@ "description": "When active, this bionic eliminates all light within a 2 tile radius through destructive interference.", "occupied_bodyparts": [ [ "torso", 16 ] ], "flags": [ "BIONIC_TOGGLED" ], - "enchantments": [ "ENCH_INVISIBILITY" ], + "enchantments": [ "ENCH_SHADOW_CLOUD" ], "act_cost": "9 kJ", "react_cost": "9 kJ", "time": 1 diff --git a/data/json/emit.json b/data/json/emit.json index 0027fd2537b4..4c9045aef039 100644 --- a/data/json/emit.json +++ b/data/json/emit.json @@ -130,6 +130,14 @@ "intensity": 3, "chance": 50 }, + { + "id": "emit_shadow_field", + "type": "emit", + "field": "fd_shadow", + "intensity": 1, + "qty": 10, + "chance": 100 + }, { "id": "emit_shock_burst", "type": "emit", diff --git a/data/json/enchantments.json b/data/json/enchantments.json index 20f58e1bb00d..34e1b8d6ae50 100644 --- a/data/json/enchantments.json +++ b/data/json/enchantments.json @@ -4,5 +4,12 @@ "id": "ENCH_INVISIBILITY", "condition": "ACTIVE", "ench_effects": [ { "effect": "invisibility", "intensity": 1 } ] + }, + { + "type": "enchantment", + "id": "ENCH_SHADOW_CLOUD", + "condition": "ACTIVE", + "ench_effects": [ { "effect": "invisibility", "intensity": 1 } ], + "emitter": "emit_shadow_field" } ] diff --git a/data/json/field_type.json b/data/json/field_type.json index 8adc5779f08d..7d062ace36ef 100644 --- a/data/json/field_type.json +++ b/data/json/field_type.json @@ -506,6 +506,13 @@ "display_field": true, "looks_like": "fd_fire" }, + { + "id": "fd_shadow", + "type": "field_type", + "intensity_levels": [ { "name": "shadow", "light_override": 3.7 } ], + "half_life": "10 seconds", + "percent_spread": 50 + }, { "id": "fd_flame_burst", "type": "field_type", diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index 2c291f25a0f7..aa2741ece8a2 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -3275,6 +3275,10 @@ Setting of sprite sheets. Same as `tiles-new` field in `tile_config`. Sprite fil "type": "field_type", // this is a field type "id": "fd_gum_web", // id of the field "immune_mtypes": [ "mon_spider_gum" ], // list of monster immune to this field + "intensity_levels": [ + { "name": "shadow", // name of this level of intensity + "light_override": 3.7 } //light level on the tile occupied by this field will be set at 3.7 not matter the ambient light. + ], "bash": { "str_min": 1, // lower bracket of bashing damage required to bash "str_max": 3, // higher bracket diff --git a/src/bionics.cpp b/src/bionics.cpp index 8ee57ec40fa7..46f877676b53 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -154,7 +154,6 @@ static const bionic_id bio_lockpick( "bio_lockpick" ); static const bionic_id bio_magnet( "bio_magnet" ); static const bionic_id bio_meteorologist( "bio_meteorologist" ); static const bionic_id bio_nanobots( "bio_nanobots" ); -static const bionic_id bio_night( "bio_night" ); static const bionic_id bio_painkiller( "bio_painkiller" ); static const bionic_id bio_plutdump( "bio_plutdump" ); static const bionic_id bio_power_storage( "bio_power_storage" ); @@ -244,6 +243,8 @@ bionic_data::bionic_data() : name( no_translation( "bad bionic" ) ), { } +bionic_data::~bionic_data() = default; + static void force_comedown( effect &eff ) { if( eff.is_null() || eff.get_effect_type() == nullptr || eff.get_duration() <= 1_turns ) { @@ -1472,11 +1473,7 @@ void Character::process_bionic( int b ) } // Bionic effects on every turn they are active go here. - if( bio.id == bio_night ) { - if( calendar::once_every( 5_turns ) ) { - add_msg_if_player( m_neutral, _( "Artificial night generator active!" ) ); - } - } else if( bio.id == bio_remote ) { + if( bio.id == bio_remote ) { if( g->remoteveh() == nullptr && get_value( "remote_controlling" ).empty() ) { bio.powered = false; add_msg_if_player( m_warning, _( "Your %s has lost connection and is turning off." ), diff --git a/src/bionics.h b/src/bionics.h index d4ae5f2f095c..fb7e40883cac 100644 --- a/src/bionics.h +++ b/src/bionics.h @@ -29,6 +29,7 @@ using itype_id = std::string; struct bionic_data { bionic_data(); + ~bionic_data(); translation name; translation description; diff --git a/src/character.cpp b/src/character.cpp index 8bea842509c4..b4040c98f5d2 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -220,7 +220,7 @@ static const bionic_id bio_synaptic_regen( "bio_synaptic_regen" ); static const bionic_id bio_tattoo_led( "bio_tattoo_led" ); static const bionic_id bio_tools( "bio_tools" ); static const bionic_id bio_ups( "bio_ups" ); -static const bionic_id str_bio_night( "bio_night" ); + // Aftershock stuff! static const bionic_id afs_bio_linguistic_coprocessor( "afs_bio_linguistic_coprocessor" ); @@ -9975,11 +9975,7 @@ bool Character::sees( const tripoint &t, bool, int ) const if( wanted_range < MAX_CLAIRVOYANCE && wanted_range < clairvoyance() ) { return true; } - // Only check if we need to override if we already came to the opposite conclusion. - if( can_see && wanted_range < 15 && wanted_range > sight_range( 1 ) && - has_active_bionic( str_bio_night ) ) { - can_see = false; - } + if( can_see && wanted_range > unimpaired_range() ) { can_see = false; } diff --git a/src/field.cpp b/src/field.cpp index a32d1b098c4f..6a28c098a488 100644 --- a/src/field.cpp +++ b/src/field.cpp @@ -71,6 +71,11 @@ float field_entry::light_emitted() const return type.obj().get_light_emitted( intensity - 1 ); } +float field_entry::local_light_override() const +{ + return type.obj().get_local_light_override( intensity - 1 ); +} + float field_entry::translucency() const { return type.obj().get_translucency( intensity - 1 ); diff --git a/src/field.h b/src/field.h index 441fa29dd167..a0e08d033410 100644 --- a/src/field.h +++ b/src/field.h @@ -43,6 +43,7 @@ class field_entry mongroup_id monster_spawn_group() const; float light_emitted() const; + float local_light_override() const; float translucency() const; bool is_transparent() const; int convection_temperature_mod() const; diff --git a/src/field_type.cpp b/src/field_type.cpp index 8ca335520039..abcd399872f6 100644 --- a/src/field_type.cpp +++ b/src/field_type.cpp @@ -164,6 +164,8 @@ void field_type::load( const JsonObject &jo, const std::string & ) fallback_intensity_level.monster_spawn_group ); optional( jao, was_loaded, "light_emitted", intensity_level.light_emitted, fallback_intensity_level.light_emitted ); + optional( jao, was_loaded, "light_override", intensity_level.local_light_override, + fallback_intensity_level.local_light_override ); optional( jao, was_loaded, "translucency", intensity_level.translucency, fallback_intensity_level.translucency ); optional( jao, was_loaded, "convection_temperature_mod", intensity_level.convection_temperature_mod, diff --git a/src/field_type.h b/src/field_type.h index 94da194f0f0a..6cfd630c8d50 100644 --- a/src/field_type.h +++ b/src/field_type.h @@ -109,6 +109,7 @@ struct field_intensity_level { int monster_spawn_radius = 0; mongroup_id monster_spawn_group; float light_emitted = 0.0f; + float local_light_override = -1.0f; float translucency = 0.0f; int convection_temperature_mod = 0; int scent_neutralization = 0; @@ -224,6 +225,9 @@ struct field_type { float get_light_emitted( int level = 0 ) const { return get_intensity_level( level ).light_emitted; } + float get_local_light_override( int level = 0 )const { + return get_intensity_level( level ).local_light_override; + } float get_translucency( int level = 0 ) const { return get_intensity_level( level ).translucency; } diff --git a/src/lightmap.cpp b/src/lightmap.cpp index 4dc84228cd21..286e184a8fb4 100644 --- a/src/lightmap.cpp +++ b/src/lightmap.cpp @@ -40,8 +40,6 @@ #include "vpart_range.h" #include "weather.h" -static const bionic_id bio_night( "bio_night" ); - static const efftype_id effect_haslight( "haslight" ); static const efftype_id effect_onfire( "onfire" ); @@ -407,6 +405,7 @@ void map::generate_lightmap( const int zlev ) apply_character_light( guy ); } + std::vector> lm_override; // Traverse the submaps in order for( int smx = 0; smx < my_MAPSIZE; ++smx ) { for( int smy = 0; smy < my_MAPSIZE; ++smy ) { @@ -459,6 +458,10 @@ void map::generate_lightmap( const int zlev ) if( light_emitted > 0 ) { add_light_source( p, light_emitted ); } + const float light_override = cur->local_light_override(); + if( light_override >= 0.0 ) { + lm_override.push_back( std::pair( p, light_override ) ); + } } } } @@ -565,13 +568,8 @@ void map::generate_lightmap( const int zlev ) apply_light_source( p, light_source_buffer[p.x][p.y] ); } } - - if( g->u.has_active_bionic( bio_night ) ) { - for( const tripoint &p : points_in_rectangle( cache_start, cache_end ) ) { - if( rl_dist( p, g->u.pos() ) < 2 ) { - lm[p.x][p.y].fill( LIGHT_AMBIENT_MINIMAL ); - } - } + for( const std::pair &elem : lm_override ) { + lm[elem.first.x][elem.first.y].fill( elem.second ); } } diff --git a/tests/modify_morale_test.cpp b/tests/modify_morale_test.cpp index 826ad58bfa0a..9c31d32bf2fb 100644 --- a/tests/modify_morale_test.cpp +++ b/tests/modify_morale_test.cpp @@ -409,7 +409,7 @@ TEST_CASE( "ursine honey", "[food][modify_morale][ursine][honey]" ) CHECK( dummy.get_morale( MORALE_HONEY ) > 0 ); AND_THEN( "they enjoy it" ) { - CHECK( dummy.has_morale( MORALE_FOOD_GOOD ) > 0 ); + CHECK( dummy.get_morale( MORALE_FOOD_GOOD ) > 0 ); } } }