From af4a7b3d354b4e854588c1a518f153e8cce2cb7e Mon Sep 17 00:00:00 2001 From: Anton Simakov <67688115+GuardianDll@users.noreply.github.com> Date: Fri, 21 Apr 2023 21:24:02 +0200 Subject: [PATCH] Fog and mist weather (#64954) * initial commit * no message * improve calculations, currently uses test values * oops * no message * no message * fixing the wrong values, remove debug message * tests: override weather in tests that need clear vision * Andrei's fix of vision test * vision_junction_reciprocity fix * weather realism test fix --------- Co-authored-by: andrei --- data/json/weather_type.json | 70 +++++++++++++++++++++++++++++++++++++ tests/bionics_test.cpp | 2 ++ tests/char_sight_test.cpp | 4 +++ tests/vision_test.cpp | 31 ++++++++++------ 4 files changed, 97 insertions(+), 10 deletions(-) diff --git a/data/json/weather_type.json b/data/json/weather_type.json index fab07ba2ff1b3..df4aea49bde8b 100644 --- a/data/json/weather_type.json +++ b/data/json/weather_type.json @@ -269,6 +269,76 @@ ] } }, + { + "id": "mist", + "type": "weather_type", + "name": "Mist", + "color": "light_gray", + "map_color": "dark_gray_white", + "sym": "~", + "ranged_penalty": 3, + "sight_penalty": 1.3, + "light_modifier": -20, + "sun_multiplier": 0.3, + "sound_attn": 0, + "dangerous": false, + "precip": "none", + "rains": false, + "sound_category": "silent", + "priority": 20, + "required_weathers": [ "clear", "sunny" ], + "condition": { + "and": [ + { "math": [ "u_val( 'weather:windpower' )", "<", "12" ] }, + { "math": [ "u_val( 'weather:windpower' )", ">", "0" ] }, + { "math": [ "dew_point_factor", "<", "5" ] } + ] + } + }, + { + "id": "fog", + "type": "weather_type", + "name": "Fog", + "color": "light_gray", + "map_color": "dark_gray_white", + "sym": "~", + "ranged_penalty": 7, + "sight_penalty": 1.7, + "light_modifier": -40, + "sun_multiplier": 0.3, + "sound_attn": 0, + "dangerous": false, + "precip": "none", + "rains": false, + "sound_category": "silent", + "priority": 20, + "required_weathers": [ "mist" ], + "condition": { + "and": [ + { "math": [ "u_val( 'weather:windpower' )", "<", "12" ] }, + { "math": [ "u_val( 'weather:windpower' )", ">", "0" ] }, + { "math": [ "dew_point_factor", "<=", "2.5" ] } + ] + } + }, + { + "type": "effect_on_condition", + "id": "EOC_DEW_POINT_FACTOR", + "recurrence": [ "15 minutes", "30 minutes" ], + "//": "First and second math calculate the dew point, the third calculate how close the weather to the point it can form a fog", + "//2": "dew_point_factor is a difference between actual temperature and the dew point. the closer it gets to zero, the bigger probability to cause a mist or dew, starting somewhere from 2,5 centigrade or 5 fahrenheit, to zero", + "effect": [ + { + "math": [ + "dprhx", + "=", + "log ( u_val( 'weather:humidity' ) / 100 ) + 17.625 * u_val( 'weather:temperature' ) / ( 469.5 + u_val( 'weather:temperature' ) )" + ] + }, + { "math": [ "dew_point", "=", "469.5 * dprhx / ( 17.625 - dprhx )" ] }, + { "math": [ "dew_point_factor", "=", "u_val('weather: temperature') - ( dew_point )" ] } + ] + }, { "id": "early_portal_storm", "type": "weather_type", diff --git a/tests/bionics_test.cpp b/tests/bionics_test.cpp index 23026a3f1bc06..b8dae5fcc40d0 100644 --- a/tests/bionics_test.cpp +++ b/tests/bionics_test.cpp @@ -13,6 +13,7 @@ #include "item_pocket.h" #include "map_helpers.h" #include "npc.h" +#include "options_helpers.h" #include "pimpl.h" #include "player_helpers.h" #include "ret_val.h" @@ -537,6 +538,7 @@ TEST_CASE( "fueled bionics", "[bionics] [item]" ) // Midday for solar test clear_map(); g->reset_light_level(); + scoped_weather_override weather_clear( WEATHER_CLEAR ); calendar::turn = calendar::turn_zero + 12_hours; REQUIRE( g->is_in_sunlight( dummy.pos() ) ); diff --git a/tests/char_sight_test.cpp b/tests/char_sight_test.cpp index c6055f95c09be..42d923201495c 100644 --- a/tests/char_sight_test.cpp +++ b/tests/char_sight_test.cpp @@ -10,6 +10,7 @@ #include "lightmap.h" #include "map.h" #include "map_helpers.h" +#include "options_helpers.h" #include "player_helpers.h" #include "type_id.h" @@ -55,6 +56,7 @@ TEST_CASE( "light and fine_detail_vision_mod", "[character][sight][light][vision clear_avatar(); clear_map(); g->reset_light_level(); + scoped_weather_override weather_clear( WEATHER_CLEAR ); SECTION( "full daylight" ) { // Set clock to noon @@ -117,6 +119,7 @@ TEST_CASE( "character sight limits", "[character][sight][vision]" ) clear_avatar(); clear_map(); g->reset_light_level(); + scoped_weather_override weather_clear( WEATHER_CLEAR ); GIVEN( "it is midnight with a new moon" ) { calendar::turn = calendar::turn_zero; @@ -212,6 +215,7 @@ TEST_CASE( "ursine vision", "[character][ursine][vision]" ) clear_avatar(); clear_map(); g->reset_light_level(); + scoped_weather_override weather_clear( WEATHER_CLEAR ); float light_here = 0.0f; diff --git a/tests/vision_test.cpp b/tests/vision_test.cpp index 2d63da3cdc441..f7caaceec17c5 100644 --- a/tests/vision_test.cpp +++ b/tests/vision_test.cpp @@ -19,6 +19,7 @@ #include "map_test_case.h" #include "mapdata.h" #include "mtype.h" +#include "options_helpers.h" #include "point.h" #include "type_id.h" #include "units.h" @@ -157,6 +158,7 @@ struct vision_test_case { player_character.clear_moncams(); clear_map( -2, OVERMAP_HEIGHT ); g->reset_light_level(); + scoped_weather_override weather_clear( WEATHER_CLEAR ); REQUIRE( !player_character.is_blind() ); REQUIRE( !player_character.in_sleep_state() ); @@ -534,25 +536,34 @@ TEST_CASE( "vision_single_tile_skylight", "[shadowcasting][vision]" ) TEST_CASE( "vision_junction_reciprocity", "[vision][reciprocity]" ) { bool player_in_junction = GENERATE( true, false ); + CAPTURE( player_in_junction ); vision_test_case t { player_in_junction ? std::vector{ - "u# ", - "-- Z", + "### ", + "#u####", + "#---z#", + "######", }: std::vector{ - "z# ", - "-- u", + "### ", + "#z####", + "#---u#", + "######", }, player_in_junction ? std::vector{ - "4466", - "4446", + "444666", + "444666", + "444466", + "444466", }: std::vector{ - "4444", - "4444", + "666666", + "444444", + "444444", + "444444", }, day_time }; @@ -560,14 +571,14 @@ TEST_CASE( "vision_junction_reciprocity", "[vision][reciprocity]" ) monster *zombie = nullptr; tile_predicate spawn_zombie = [&]( map_test_case::tile tile ) { zombie = g->place_critter_at( mon_zombie, tile.p ); + get_map().ter_set( tile.p + tripoint_above, ter_t_flat_roof ); return true; }; t.set_up_tiles = - ifchar( 'C', spawn_moncam ) || - ifchar( 'Z', spawn_zombie ) || ifchar( 'z', spawn_zombie ) || t.set_up_tiles; + t.flags.headlamp = true; t.test_all(); if( player_in_junction ) {