1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
#include "calendar.h"
#include "cata_catch.h"
#include "enums.h"
#include "item.h"
#include "map.h"
#include "point.h"
#include "type_id.h"
#include "weather.h"
static const flag_id json_flag_FROZEN( "FROZEN" );
static void set_map_temperature( units::temperature new_temperature )
{
get_weather().temperature = new_temperature;
get_weather().clear_temp_cache();
}
TEST_CASE( "Rate_of_rotting", "[rot]" )
{
SECTION( "Passage of time" ) {
// Item rot is a time duration.
// At 65 F (18,3 C) item rots at rate of 1h/1h
// So the level of rot should be about same as the item age
// In preserving containers and in freezer the item should not rot at all
// Item in freezer should not be frozen.
// Items created at turn zero are handled differently, so ensure we're
// not there.
if( calendar::turn <= calendar::start_of_cataclysm ) {
calendar::turn = calendar::start_of_cataclysm + 1_minutes;
}
item normal_item( "meat_cooked" );
item freeze_item( "offal_canned" );
item sealed_item( "offal_canned" );
sealed_item = sealed_item.in_its_container();
set_map_temperature( units::from_fahrenheit( 65 ) ); // 18,3 C
normal_item.process( get_map(), nullptr, tripoint_zero, 1, temperature_flag::NORMAL );
sealed_item.process( get_map(), nullptr, tripoint_zero, 1, temperature_flag::NORMAL );
freeze_item.process( get_map(), nullptr, tripoint_zero, 1, temperature_flag::NORMAL );
// Item should exist with no rot when it is brand new
CHECK( normal_item.get_rot() == 0_turns );
CHECK( sealed_item.get_rot() == 0_turns );
CHECK( freeze_item.get_rot() == 0_turns );
INFO( "Initial turn: " << to_turn<int>( calendar::turn ) );
calendar::turn += 20_minutes;
sealed_item.process( get_map(), nullptr, tripoint_zero, 1, temperature_flag::NORMAL );
normal_item.process( get_map(), nullptr, tripoint_zero, 1, temperature_flag::NORMAL );
freeze_item.process( get_map(), nullptr, tripoint_zero, 1, temperature_flag::FREEZER );
// After 20 minutes the normal item should have 20 minutes of rot
CHECK( to_turns<int>( normal_item.get_rot() )
== Approx( to_turns<int>( 20_minutes ) ).epsilon( 0.01 ) );
// Item in freezer and in preserving container should have no rot
CHECK( sealed_item.get_rot() == 0_turns );
CHECK( freeze_item.get_rot() == 0_turns );
// Move time 110 minutes
calendar::turn += 110_minutes;
sealed_item.process( get_map(), nullptr, tripoint_zero, 1, temperature_flag::NORMAL );
freeze_item.process( get_map(), nullptr, tripoint_zero, 1, temperature_flag::FREEZER );
// In freezer and in preserving container still should be no rot
CHECK( sealed_item.get_rot() == 0_turns );
CHECK( freeze_item.get_rot() == 0_turns );
// The item in freezer should still not be frozen
CHECK( !freeze_item.has_own_flag( json_flag_FROZEN ) );
}
}
TEST_CASE( "Items_rot_away", "[rot]" )
{
SECTION( "Item in reality bubble rots away" ) {
// Item should rot away when it has 2x of its shelf life in rot.
if( calendar::turn <= calendar::start_of_cataclysm ) {
calendar::turn = calendar::start_of_cataclysm + 1_minutes;
}
item test_item( "meat_cooked" );
// Process item once to set all of its values.
test_item.process( get_map(), nullptr, tripoint_zero, 1, temperature_flag::HEATER );
// Set rot to >2 days and process again. process_temperature_rot should return true.
calendar::turn += 20_minutes;
test_item.mod_rot( 2_days );
CHECK( test_item.process_temperature_rot( 1, tripoint_zero, get_map(), nullptr,
temperature_flag::HEATER ) );
INFO( "Rot: " << to_turns<int>( test_item.get_rot() ) );
}
}
TEST_CASE( "Hourly_rotpoints", "[rot]" )
{
item normal_item( "meat_cooked" );
// No rot below 32F/0C
CHECK( normal_item.calc_hourly_rotpoints_at_temp( units::from_celsius( 0 ) ) == 0 );
// No rot above 145F/63C
CHECK( normal_item.calc_hourly_rotpoints_at_temp( units::from_celsius( 63 ) ) == 0 );
// Make sure no off by one error at the border
CHECK( normal_item.calc_hourly_rotpoints_at_temp( units::from_celsius( 62 ) ) == Approx(
20364.67 ) );
// 3200 point/h at 65F/18C
CHECK( normal_item.calc_hourly_rotpoints_at_temp( units::from_fahrenheit( 65 ) ) == Approx(
3600 ) );
// Doubles after +16F
CHECK( normal_item.calc_hourly_rotpoints_at_temp( units::from_fahrenheit( 65 + 16 ) ) == Approx(
3600.0 * 2 ) );
// Halves after -16F
CHECK( normal_item.calc_hourly_rotpoints_at_temp( units::from_fahrenheit( 65 - 16 ) ) == Approx(
3600.0 / 2 ) );
// Test the linear area. Halfway between 32F/9C (0 point/hour) and 38F/3C (1117.672 point/hour)
CHECK( normal_item.calc_hourly_rotpoints_at_temp( units::from_fahrenheit( 35 ) ) == Approx(
1117.672 / 2 ) );
// Maximum rot at above 105 F
CHECK( normal_item.calc_hourly_rotpoints_at_temp( units::from_fahrenheit( 107 ) ) == Approx(
20364.67 ) );
}
|