File: rot_test.cpp

package info (click to toggle)
cataclysm-dda 0.H-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 710,808 kB
  • sloc: cpp: 524,019; python: 11,580; sh: 1,228; makefile: 1,169; xml: 507; javascript: 150; sql: 56; exp: 41; perl: 37
file content (135 lines) | stat: -rw-r--r-- 5,336 bytes parent folder | download
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 ) );
}