Skip to content

Commit

Permalink
feat(balance): allow reading at penalty with full night vision, other…
Browse files Browse the repository at this point in the history
… visual/detection improvements (#4172)

* feat(balance): allow reading in the dark with full night vision trait, other visual/detection improvements

* Update mutations.json

* Fix per Jove's feedback

Co-Authored-By: joveeater <[email protected]>

* Update json_info.md

---------

Co-authored-by: joveeater <[email protected]>
  • Loading branch information
chaosvolt and joveeater authored Feb 7, 2024
1 parent 49f46f9 commit 19099e8
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 9 deletions.
2 changes: 1 addition & 1 deletion data/json/mutations/mutations.json
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,7 @@
"id": "NIGHTVISION3",
"name": { "str": "Full Night Vision" },
"points": 6,
"description": "You can see in pitch blackness as if you were wearing night-vision goggles. Activate to toggle NV-visible areas on or off.",
"description": "You can see in pitch blackness as if you were wearing night-vision goggles, and read in darkness as one can in dim lighting. Activate to toggle NV-visible areas on or off.",
"prereqs": [ "NIGHTVISION2" ],
"leads_to": [ "INFRARED" ],
"cancels": [ "ELFA_NV", "ELFA_FNV", "FEL_NV", "URSINE_EYE" ],
Expand Down
2 changes: 1 addition & 1 deletion doc/src/content/docs/en/mod/json/reference/json_info.md
Original file line number Diff line number Diff line change
Expand Up @@ -1245,7 +1245,7 @@ wake up for the first time after 24 hours into the game.
]
],
"stealth_modifier" : 0, // Percentage to be subtracted from player's visibility range, capped to 60. Negative values work, but are not very effective due to the way vision ranges are capped
"night_vision_range" : 0.0, // Night range vision. Only the best and the worst value out of all mutations are added. (default: 0.0)
"night_vision_range" : 0.0, // Night range vision. Only the best and the worst value out of all mutations are added. A value of 8 or higher will allow reading in complete darkness as though the player were in dim lighting. (default: 0.0)
"active" : true, //When set the mutation is an active mutation that the player needs to activate (default: false)
"starts_active" : true, //When true, this 'active' mutation starts active (default: false, requires 'active')
"cost" : 8, // Cost to activate this mutation. Needs one of the hunger, thirst, or fatigue values set to true. (default: 0)
Expand Down
3 changes: 2 additions & 1 deletion src/avatar_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,8 @@ bool avatar_action::move( avatar &you, map &m, const tripoint &d )
}

// Invalid move
const bool waste_moves = you.is_blind() || you.has_effect( effect_stunned );
const bool waste_moves = ( you.is_blind() && you.clairvoyance() < 1 ) ||
you.has_effect( effect_stunned );
if( waste_moves || dest_loc.z != you.posz() ) {
add_msg( _( "You bump into the %s!" ), m.obstacle_name( dest_loc ) );
// Only lose movement if we're blind
Expand Down
7 changes: 5 additions & 2 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6869,7 +6869,9 @@ bool Character::sees_with_specials( const Creature &critter ) const
return true;
}

return false;
const int dist = rl_dist( pos(), critter.pos() );
return ( dist <= 5 && ( has_active_mutation( trait_ANTENNAE ) ||
( has_active_bionic( bio_ground_sonar ) && !critter.has_flag( MF_FLIES ) ) ) );
}

detached_ptr<item> Character::pour_into( item &container, detached_ptr<item> &&liquid, int limit )
Expand Down Expand Up @@ -11015,7 +11017,8 @@ bool Character::sees( const Creature &critter ) const
{
// This handles only the player/npc specific stuff (monsters don't have traits or bionics).
const int dist = rl_dist( pos(), critter.pos() );
if( dist <= 3 && has_active_mutation( trait_ANTENNAE ) ) {
if( dist <= 5 && ( has_active_mutation( trait_ANTENNAE ) ||
( has_active_bionic( bio_ground_sonar ) && !critter.has_flag( MF_FLIES ) ) ) ) {
return true;
}

Expand Down
7 changes: 5 additions & 2 deletions src/character_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,16 @@ float fine_detail_vision_mod( const Character &who, const tripoint &p )
!who.has_trait( trait_PER_SLIME_OK ) ) ) {
return 11.0;
}
// Regular NV trait isn't enough to help at all, while Full Night Vision allows reading at a penalty
float nvbonus = who.mutation_value( "night_vision_range" ) >= 8 ? 4 : 0;
// Scale linearly as light level approaches LIGHT_AMBIENT_LIT.
// If we're actually a source of light, assume we can direct it where we need it.
// Therefore give a hefty bonus relative to ambient light.
float own_light = std::max( 1.0f, LIGHT_AMBIENT_LIT - who.active_light() - 2.0f );

// Same calculation as above, but with a result 3 lower.
float ambient_light = std::max( 1.0f, LIGHT_AMBIENT_LIT - get_map().ambient_light_at( p ) + 1.0f );
// Same calculation as above, but with a result 3 lower, and night vision is allowed to affect it.
float ambient_light = std::max( 1.0f,
LIGHT_AMBIENT_LIT - get_map().ambient_light_at( p ) - nvbonus + 1.0f );

return std::min( own_light, ambient_light );
}
Expand Down
5 changes: 3 additions & 2 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6005,7 +6005,8 @@ void game::print_items_info( const tripoint &lp, const catacurses::window &w_loo
return;
} else if( m.has_flag( "CONTAINER", lp ) && !m.could_see_items( lp, u ) ) {
mvwprintw( w_look, point( column, ++line ), _( "You cannot see what is inside of it." ) );
} else if( u.has_effect( effect_blind ) || u.worn_with_flag( flag_BLIND ) ) {
} else if( ( u.has_effect( effect_blind ) || u.worn_with_flag( flag_BLIND ) ) &&
u.clairvoyance() < 1 ) {
mvwprintz( w_look, point( column, ++line ), c_yellow,
_( "There's something there, but you can't see what it is." ) );
return;
Expand Down Expand Up @@ -9369,7 +9370,7 @@ point game::place_player( const tripoint &dest_loc )
if( !m.has_flag( "SEALED", u.pos() ) ) {
if( get_option<bool>( "NO_AUTO_PICKUP_ZONES_LIST_ITEMS" ) ||
!check_zone( zone_type_id( "NO_AUTO_PICKUP" ), u.pos() ) ) {
if( u.is_blind() && !m.i_at( u.pos() ).empty() ) {
if( u.is_blind() && !m.i_at( u.pos() ).empty() && u.clairvoyance() < 1 ) {
add_msg( _( "There's something here, but you can't see what it is." ) );
} else if( m.has_items( u.pos() ) ) {
std::vector<std::string> names;
Expand Down

0 comments on commit 19099e8

Please sign in to comment.