File: monfactions_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 (169 lines) | stat: -rw-r--r-- 7,125 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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include <vector>

#include "cata_catch.h"
#include "filesystem.h"
#include "monfaction.h"
#include "type_id.h"

static const mfaction_str_id monfaction_animal( "animal" );
static const mfaction_str_id monfaction_bear( "bear" );
static const mfaction_str_id monfaction_fish( "fish" );
static const mfaction_str_id monfaction_small_animal( "small_animal" );
static const mfaction_str_id monfaction_test_monfaction1( "test_monfaction1" );
static const mfaction_str_id monfaction_test_monfaction2( "test_monfaction2" );
static const mfaction_str_id monfaction_test_monfaction3( "test_monfaction3" );
static const mfaction_str_id monfaction_test_monfaction5( "test_monfaction5" );
static const mfaction_str_id monfaction_test_monfaction7( "test_monfaction7" );
static const mfaction_str_id monfaction_test_monfaction_extend( "test_monfaction_extend" );
static const mfaction_str_id monfaction_vermin( "vermin" );

static std::string att_enum_to_string( mf_attitude att )
{
    switch( att ) {
        case MFA_BY_MOOD:
            return "MFA_BY_MOOD";
        case MFA_NEUTRAL:
            return "MFA_NEUTRAL";
        case MFA_FRIENDLY:
            return "MFA_FRIENDLY";
        case MFA_HATE:
            return "MFA_HATE";
        case MFA_SIZE:
            return "MFA_SIZE";
        default:
            break;
    }

    printf( "Unknown monster faction attitude %d\n", static_cast<int>( att ) );
    return "?";
}

// generates a file in current directory that contains dump of all inter-faction attitude
TEST_CASE( "generate_monfactions_attitude_matrix", "[.]" )
{
    std::ofstream outfile;
    outfile.open( fs::u8path( "monfactions.txt" ) );
    for( const monfaction &f : monfactions::get_all() ) {
        for( const monfaction &f1 : monfactions::get_all() ) {
            mf_attitude att = f.attitude( f1.id );
            mf_attitude rev_att = f1.attitude( f.id );
            // NOLINTNEXTLINE(cata-text-style)
            outfile << f.id.str() << "->" << f1.id.str() << ":\t";
            outfile << att_enum_to_string( att );
            // NOLINTNEXTLINE(cata-text-style)
            outfile << "\t(Rev: ";
            outfile << att_enum_to_string( rev_att );
            outfile << ")\n";
        }
    }
}

TEST_CASE( "monfactions_reciprocate", "[monster][monfactions]" )
{
    for( const monfaction &f : monfactions::get_all() ) {
        SECTION( f.id.str() ) {
            for( const monfaction &f1 : monfactions::get_all() ) {
                mf_attitude att = f.attitude( f1.id );
                mf_attitude rev_att = f1.attitude( f.id );

                INFO( f1.id.str() );
                REQUIRE( att != MFA_SIZE );
                REQUIRE( rev_att != MFA_SIZE );

                if( att == MFA_FRIENDLY || att == MFA_NEUTRAL ) {
                    CHECK_FALSE( rev_att == MFA_BY_MOOD );
                    CHECK_FALSE( rev_att == MFA_HATE );

                    if( ( rev_att != MFA_FRIENDLY ) && ( rev_att != MFA_NEUTRAL ) ) {
                        std::string att_str = att_enum_to_string( att );
                        std::string rev_att_str = att_enum_to_string( rev_att );
                        printf( "\n%s has an attitude of %s to %s, but %s has an attitude of %s to %s."
                                "\nEither %s should not be FRIENDLY/NEUTRAL to %s, or"
                                "\n%s should be FRIENDLY/NEUTRAL to %s\n\n",
                                f.id.c_str(), att_str.c_str(), f1.id.c_str(), f1.id.c_str(), rev_att_str.c_str(), f.id.c_str(),
                                f.id.c_str(), f1.id.c_str(), f1.id.c_str(), f.id.c_str() );

                    }
                }
            }
        }
    }
}

TEST_CASE( "monfactions_attitude", "[monster][monfactions]" )
{
    // check some common cases
    const auto attitude = []( const std::string & f, const std::string & t ) {
        return mfaction_str_id( f )->attitude( mfaction_str_id( t ) );
    };

    SECTION( "faction is friendly to itself" ) {
        CHECK( attitude( "zombie", "zombie" ) == MFA_FRIENDLY );
        CHECK( attitude( "human", "human" ) == MFA_FRIENDLY );
    }

    SECTION( "inheritance" ) {
        // based on the current state of json
        REQUIRE( attitude( "animal", "small_animal" ) == MFA_NEUTRAL );
        REQUIRE( monfaction_small_animal->base_faction == monfaction_animal );
        REQUIRE( monfaction_vermin->base_faction == monfaction_small_animal );
        REQUIRE( monfaction_fish->base_faction == monfaction_animal );
        REQUIRE( monfaction_bear->base_faction == monfaction_animal );

        INFO( "fish is a child of animal, is friendly to itself" );
        CHECK( attitude( "animal", "animal" ) == MFA_BY_MOOD );

        INFO( "default attitude towards self takes precedence over inheritance from parents" );
        CHECK( attitude( "animal", "fish" ) == MFA_NEUTRAL );
        CHECK( attitude( "fish", "fish" ) == MFA_FRIENDLY );

        INFO( "fish is inherited from animal and should be neutral toward small_animal" );
        CHECK( attitude( "fish", "small_animal" ) == MFA_NEUTRAL );

        INFO( "dog is inherited from animal, but hates small animals, of which vermin is a child" );
        CHECK( attitude( "dog", "vermin" ) == MFA_HATE );
        CHECK( attitude( "dog", "fish" ) == MFA_NEUTRAL );

    }

    SECTION( "some random samples" ) {
        CHECK( attitude( "aquatic_predator", "fish" ) == MFA_HATE );
        CHECK( attitude( "robofac", "zombie" ) == MFA_HATE );

        CHECK( attitude( "dragonfly", "defense_bot" ) == MFA_NEUTRAL );
        CHECK( attitude( "dragonfly", "dermatik" ) == MFA_HATE );

        CHECK( attitude( "zombie_aquatic", "zombie" ) == MFA_FRIENDLY );
        CHECK( attitude( "zombie", "zombie_aquatic" ) == MFA_FRIENDLY );
        CHECK( attitude( "zombie", "small_animal" ) == MFA_NEUTRAL );

        CHECK( attitude( "plant", "triffid" ) == MFA_FRIENDLY );
        CHECK( attitude( "plant", "utility_bot" ) == MFA_NEUTRAL );

        CHECK( attitude( "bee", "military" ) == MFA_NEUTRAL );

        CHECK( attitude( "bear", "bee" ) == MFA_HATE );
        CHECK( attitude( "wolf", "pig" ) == MFA_HATE );
        CHECK( attitude( "small_animal", "zombie" ) == MFA_NEUTRAL );
    }
}

TEST_CASE( "monfaction_extend", "[monster][monfactions]" )
{
    const monfaction &orig = monfaction_test_monfaction1.obj();
    const monfaction &extn = monfaction_test_monfaction_extend.obj();

    // check that player was extended and ant was deleted
    CHECK( orig.attitude( monfaction_test_monfaction7 ) == MFA_BY_MOOD );
    CHECK( extn.attitude( monfaction_test_monfaction7 ) == MFA_FRIENDLY );

    CHECK( orig.attitude( monfaction_test_monfaction3 ) == MFA_NEUTRAL );
    CHECK( extn.attitude( monfaction_test_monfaction3 ) == MFA_BY_MOOD );

    // check that other attitudes are preserved
    CHECK( orig.attitude( monfaction_test_monfaction2 ) == MFA_FRIENDLY );
    CHECK( extn.attitude( monfaction_test_monfaction2 ) == MFA_FRIENDLY );

    CHECK( orig.attitude( monfaction_test_monfaction5 ) == MFA_BY_MOOD );
    CHECK( extn.attitude( monfaction_test_monfaction5 ) == MFA_BY_MOOD );
}