scraps

Abandon all hope, ye who enter here.
git clone https://git.neptards.moe/neptards/scraps.git
Log | Files | Refs | Submodules | README | LICENSE

if_character.cpp (9096B)


      1 #include "scraps/game/action_eval/if.hpp" // IWYU pragma: associated
      2 
      3 #include "scraps/game/action_eval/test_helper.hpp"
      4 #include "scraps/game/character_state.hpp"
      5 #include "scraps/game/room_state.hpp"
      6 #include "scraps/uuid.hpp"
      7 
      8 #include <libshit/except.hpp>
      9 #include <libshit/nonowning_string.hpp>
     10 
     11 // IWYU pragma: no_include <type_traits>
     12 // IWYU pragma: no_forward_declare Scraps::Game::IdKey
     13 // IWYU pragma: no_forward_declare Scraps::Game::NameKey
     14 
     15 namespace Scraps::Game::ActionEvalPrivate
     16 {
     17   TEST_SUITE_BEGIN("Scraps::Game::ActionEval");
     18 
     19   std::optional<bool> IfCharacterCustomProperty(IfParam p)
     20   {
     21     RAGS_IF_CUSTOM_PROPERTY_GET_PARTS;
     22     auto c = p.gc->GetCharacterColl().Get<NameKey>(parts[0]); if (!c) return {};
     23     return IfCustomPropertyCommon(p, c->GetProperties(), parts[1]);
     24   }
     25 
     26   TEST_CASE_FIXTURE(Fixture, "IfCharacterCustomProperty")
     27   {
     28     SetCk("chars_0", "Equals", "Value 0");
     29     CHECK(IfCharacterCustomProperty(p) == std::nullopt); // no colon
     30     SetCk("chara_0:key_0:foo", "Equals", "Value 0");
     31     CHECK(IfCharacterCustomProperty(p) == std::nullopt); // too many colon
     32     SetCk("chara_0:nosuch", "Equals", "Value 0");
     33     CHECK(IfCharacterCustomProperty(p) == std::nullopt); // no prop
     34     SetCk("nosuch:key_0", "Equals", "Value 0");
     35     CHECK(IfCharacterCustomProperty(p) == std::nullopt); // no chara
     36     SetCk("chara_0:key_0", "Equals", "Value 0");
     37     CHECK(IfCharacterCustomProperty(p) == true); // OK
     38   }
     39 
     40   std::optional<bool> IfPlayerCustomProperty(IfParam p)
     41   {
     42     return IfCustomPropertyCommon(
     43       p, p.gc->GetPlayer().GetProperties(), p.check.GetParam0());
     44   }
     45 
     46   // ---------------------------------------------------------------------------
     47 
     48   static bool GenderCommon(
     49     IfParam p, ConstCharacterProxy c, Libshit::NonowningString param)
     50   {
     51     auto gender = Format::Proto::Gender::OTHER;
     52     param = p.Replace(p.eval.tmp_str0, param);
     53     if (param == "Male") gender = Format::Proto::Gender::MALE;
     54     else if (param == "Female") gender = Format::Proto::Gender::FEMALE;
     55 
     56     return c.GetGender() == gender;
     57   }
     58 
     59   std::optional<bool> IfCharacterGender(IfParam p)
     60   {
     61     auto name = p.Replace(p.eval.tmp_str0, p.check.GetParam0());
     62     auto c = p.gc->GetCharacterColl().Get<NameKey>(name);
     63     if (!c) return {};
     64 
     65     return GenderCommon(p, *c, p.check.GetParam1());
     66   }
     67 
     68   TEST_CASE_FIXTURE(Fixture, "IfCharacterGender")
     69   {
     70     SetCk("nochar", "Male", "");
     71     CHECK(IfCharacterGender(p) == std::nullopt);
     72 
     73     SetCk("chara_0", "Male", "");
     74     CHECK(IfCharacterGender(p) == true);
     75     SetCk("chara_0", "male", ""); // case sensitive
     76     CHECK(IfCharacterGender(p) == false);
     77 
     78     SetCk("chara_1", "Female", "");
     79     CHECK(IfCharacterGender(p) == true);
     80 
     81     SetCk("chara_2", "whatever... I mean Other", "");
     82     CHECK(IfCharacterGender(p) == true);
     83   }
     84 
     85   std::optional<bool> IfPlayerGender(IfParam p)
     86   { return GenderCommon(p, p.gc->GetPlayer(), p.check.GetParam0()); }
     87 
     88   TEST_CASE_FIXTURE(Fixture, "IfPlayerGender")
     89   {
     90     SetCk("Male", "", "");
     91     CHECK(IfPlayerGender(p) == true);
     92     SetCk("Anything", "", "");
     93     CHECK(IfPlayerGender(p) == false);
     94   }
     95 
     96   // ---------------------------------------------------------------------------
     97 
     98   static bool InRoomCommon(
     99     IfParam p, RoomId rid, Libshit::NonowningString uuid, bool check_player)
    100   {
    101     uuid = p.Replace(p.eval.tmp_str0, uuid);
    102 
    103     // fast track for player's current room
    104     if (check_player && uuid == Uuid::PLAYER_ROOM_STR)
    105       return rid == p.gc->GetPlayer().GetRoomId();
    106 
    107     auto r = p.gc->GetRoomColl().StateGet<IdKey>(rid);
    108     // if not in any room -> check void uuid
    109     if (!r) return uuid == Uuid::VOID_ROOM_STR;
    110 
    111     auto uuid_p = Uuid::TryParse(uuid);
    112     return uuid_p && r->uuid == *uuid_p;
    113   }
    114 
    115   std::optional<bool> IfCharacterInRoom(IfParam p)
    116   {
    117     auto name = p.Replace(p.eval.tmp_str0, p.check.GetParam0());
    118     auto rid = p.gc->GetCharacterColl().At<NameKey>(name).GetRoomId();
    119 
    120     return InRoomCommon(p, rid, p.check.GetParam1(), true);
    121   }
    122 
    123   TEST_CASE_FIXTURE(Fixture, "IfCharacterInRoom")
    124   {
    125     SetCk("nosuch", "00000000-0000-4004-0000-000000000000", "");
    126     CHECK_THROWS(IfCharacterInRoom(p));
    127 
    128     SetCk("chara_0", "nosuch", "");
    129     CHECK(IfCharacterInRoom(p) == false);
    130 
    131     SetCk("chara_0", "00000000-0000-4004-0000-ffffffffffff", "");
    132     CHECK(IfCharacterInRoom(p) == false);
    133 
    134     SetCk("chara_0", "00000000-0000-4004-0000-000000000000", "");
    135     CHECK(IfCharacterInRoom(p) == true);
    136 
    137     // the player is in the same room as player. wow!
    138     SetCk("chara_0", Uuid::PLAYER_ROOM_STR, "");
    139     CHECK(IfCharacterInRoom(p) == true);
    140     SetCk("chara_0", "00000000000000000000000000000001", "");
    141     CHECK(IfCharacterInRoom(p) == false); // UUID not parsed
    142     SetCk("chara_0", Uuid::VOID_ROOM_STR, "");
    143     CHECK(IfCharacterInRoom(p) == false); // but not in void
    144 
    145     st.GetCharacterColl().At(1).SetRoomId(RoomId{});
    146     SetCk("chara_1", Uuid::VOID_ROOM_STR, "");
    147     CHECK(IfCharacterInRoom(p) == true); // chara 1 is in void
    148     SetCk("chara_1", Uuid::PLAYER_ROOM_STR, "");
    149     CHECK(IfCharacterInRoom(p) == false); // not same as player
    150     SetCk("chara_1", "00000000-0000-4004-0000-000000000000", "");
    151     CHECK(IfCharacterInRoom(p) == false); // not room 0...
    152   }
    153 
    154   std::optional<bool> IfPlayerInRoom(IfParam p)
    155   {
    156     return InRoomCommon(
    157       p, p.gc->GetPlayer().GetRoomId(), p.check.GetParam0(), false);
    158   }
    159 
    160   TEST_CASE_FIXTURE(Fixture, "IfPlayerInRoom")
    161   {
    162     SetCk("00000000-0000-4004-0000-000000000000", "", "");
    163     CHECK(IfPlayerInRoom(p) == true);
    164     // same room as player not handled
    165     SetCk(Uuid::PLAYER_ROOM_STR, "", "");
    166     CHECK(IfPlayerInRoom(p) == false);
    167     SetCk(Uuid::VOID_ROOM_STR, "", "");
    168     CHECK(IfPlayerInRoom(p) == false);
    169 
    170     st.GetPlayer().SetRoomId(RoomId{}); // don't try this at home
    171     CHECK(IfPlayerInRoom(p) == true);
    172   }
    173 
    174   // ---------------------------------------------------------------------------
    175 
    176   std::optional<bool> IfCharacterInRoomGroup(IfParam p)
    177   {
    178     auto name = p.Replace(p.eval.tmp_str0, p.check.GetParam0());
    179     auto c = p.gc->GetCharacterColl().At<NameKey>(name);
    180     auto r = p.gc->GetRoomColl().Get<IdKey>(c.GetRoomId());
    181     if (!r) return false;
    182 
    183     return IfInGroupCommon(p, p.gc->GetRoomGroupColl(), r->GetGroupId(),
    184                            p.check.GetParam1(), "None");
    185   }
    186 
    187   TEST_CASE_FIXTURE(Fixture, "IfCharacterInRoomGroup")
    188   {
    189     SetCk("nosuch", "None", "");
    190     CHECK_THROWS(IfCharacterInRoomGroup(p));
    191 
    192     st.GetCharacterColl().At(1).SetRoomId({});
    193     SetCk("chara_1", "None", "");
    194     CHECK(IfCharacterInRoomGroup(p) == false);
    195     SetCk("chara_1", "foobar", "");
    196     CHECK(IfCharacterInRoomGroup(p) == false);
    197     SetCk("chara_1", "room_group_0", "");
    198     CHECK(IfCharacterInRoomGroup(p) == false);
    199 
    200     SetCk("chara_0", "room_group_0", "");
    201     CHECK(IfCharacterInRoomGroup(p) == true);
    202     SetCk("chara_0", "room_group_1", "");
    203     CHECK(IfCharacterInRoomGroup(p) == false);
    204     SetCk("chara_0", "None", "");
    205     CHECK(IfCharacterInRoomGroup(p) == false);
    206   }
    207 
    208   std::optional<bool> IfPlayerInRoomGroup(IfParam p)
    209   {
    210     auto r = p.gc->GetPlayerRoom();
    211     return IfInGroupCommon(p, p.gc->GetRoomGroupColl(), r.GetGroupId(),
    212                            p.check.GetParam0(), "None");
    213   }
    214 
    215   TEST_CASE_FIXTURE(Fixture, "IfCharacterInRoomGroup")
    216   {
    217     SetCk("None", "", "");
    218     CHECK(IfPlayerInRoomGroup(p) == false);
    219     SetCk("room_group_0", "", "");
    220     CHECK(IfPlayerInRoomGroup(p) == true);
    221 
    222     dummy.game.GetRooms()[0].SetGroupId(0);
    223     SetCk("None", "", "");
    224     CHECK(IfPlayerInRoomGroup(p) == true);
    225     SetCk("room_group_0", "", "");
    226     CHECK(IfPlayerInRoomGroup(p) == false);
    227   }
    228 
    229   // ---------------------------------------------------------------------------
    230 
    231   std::optional<bool> IfPlayerInSameRoomAs(IfParam p)
    232   {
    233     auto name = p.Replace(p.eval.tmp_str0, p.check.GetParam0());
    234     return p.gc->GetPlayer().GetRoomId() ==
    235       p.gc->GetCharacterColl().At<NameKey>(name).GetRoomId();
    236   }
    237 
    238   TEST_CASE_FIXTURE(Fixture, "IfPlayerInSameRoomAs")
    239   {
    240     SetCk("nosuch", "", "");
    241     CHECK_THROWS(IfPlayerInSameRoomAs(p));
    242 
    243     SetCk("chara_1", "", "");
    244     CHECK(IfPlayerInSameRoomAs(p) == false);
    245     st.GetCharacterColl().At(1).SetRoomId(st.GetPlayerRoom().GetId());
    246     CHECK(IfPlayerInSameRoomAs(p) == true);
    247   }
    248 
    249   // ---------------------------------------------------------------------------
    250 
    251   std::optional<bool> IfPlayerMoving(IfParam p)
    252   {
    253     auto dir = RagsStr2Dir(p.Replace(p.eval.tmp_str0, p.check.GetParam0()));
    254     if (!dir.has_value())
    255       LIBSHIT_THROW(ActionEvalError, "Invalid direction",
    256                     "Direction", p.eval.tmp_str0);
    257     return dir == p.gc.GetActionEval().GetMovingDirection();
    258   }
    259 
    260   TEST_CASE_FIXTURE(Fixture, "IfPlayerMoving")
    261   {
    262     SetCk("nosuch", "", "");
    263     CHECK_THROWS(IfPlayerMoving(p));
    264 
    265     SetCk("Empty", "", "");
    266     CHECK(IfPlayerMoving(p) == true);
    267     SetCk("South", "", "");
    268     CHECK(IfPlayerMoving(p) == false);
    269 
    270     eval.moving_direction = ExitState::Dir::SOUTH;
    271     CHECK(IfPlayerMoving(p) == true);
    272   }
    273 
    274   TEST_SUITE_END();
    275 }