From 8edc15649670201a0473b42052d454ac6706e728 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Thu, 29 Sep 2016 22:23:17 -0400 Subject: [PATCH] Finish tests for converting legacy special nodes --- doc/editor/appendix/Specials.html | 5 +- src/classes/party.cpp | 2 +- src/classes/party.hpp | 3 + test/spec_legacy.cpp | 389 +++++++++++++++++++++++++++++- 4 files changed, 392 insertions(+), 7 deletions(-) diff --git a/doc/editor/appendix/Specials.html b/doc/editor/appendix/Specials.html index 1d2493ed..ea33fbcc 100644 --- a/doc/editor/appendix/Specials.html +++ b/doc/editor/appendix/Specials.html @@ -169,9 +169,8 @@ to if the monsters had fled.
Mess1, Mess2:
Standard usage. If the party is not moving, no messages are displayed.
-
Extra 1a:
If this is set to 1, the party is kept from entering the space. If -not 1, the party is allowed to enter the space (this undoes any Can't Enter nodes already -called).
+
Extra 1a:
If this is set to 1, the action is prevented. If not 1, the action +is allowed (this undoes any Prevent Action nodes already called).
Extra 2a:
Sometimes, this can be set to 1 to allow the party to enter even an impassable space. This works under any of the following conditions:
    diff --git a/src/classes/party.cpp b/src/classes/party.cpp index 649a4468..ba7293e9 100644 --- a/src/classes/party.cpp +++ b/src/classes/party.cpp @@ -1235,7 +1235,7 @@ iLiving& cParty::pc_present() const { // stuff done legit, i.e. flags are within proper ranges for stuff done flag bool cParty::sd_legit(short a, short b) { - if((minmax(0,349,a) == a) && (minmax(0,49,b) == b)) + if((minmax(0,sdx_max,a) == a) && (minmax(0,sdy_max,b) == b)) return true; return false; } diff --git a/src/classes/party.hpp b/src/classes/party.hpp index 1bd5b20b..9ec058d2 100644 --- a/src/classes/party.hpp +++ b/src/classes/party.hpp @@ -129,7 +129,10 @@ public: std::map campaign_flags; private: std::map> pointers; + using sd_array = decltype(stuff_done); public: + static const int sdx_max = std::extent::value - 1; + static const int sdy_max = std::extent::value - 1; void set_ptr(unsigned short p, unsigned short sdfx, unsigned short sdfy); void force_ptr(unsigned short p, unsigned short val); diff --git a/test/spec_legacy.cpp b/test/spec_legacy.cpp index 6a466241..0553a38d 100644 --- a/test/spec_legacy.cpp +++ b/test/spec_legacy.cpp @@ -16,6 +16,8 @@ using namespace std; ostream& operator<< (ostream& out, eSpecType spec); +// TODO: Replace these with behavioral tests - ie, actually run the node and verify correct results. + TEST_CASE("When converting legacy special nodes (general)") { cSpecial newSpec; legacy::special_node_type oldSpec = {0,-1,-1,0,-1,-1,-1,-1,-1,-1,-1}; @@ -275,7 +277,7 @@ TEST_CASE("When converting legacy special nodes (general)") { oldSpec.ex1a = 1; newSpec.import_legacy(oldSpec); CHECK(newSpec.type == eSpecType::CANT_ENTER); - CHECK(newSpec.ex1a == 1); + CHECK(newSpec.ex1a == 0); CHECK(newSpec.ex2a == 0); CHECK(newSpec.jumpto == 12); } @@ -1313,6 +1315,8 @@ TEST_CASE("When converting legacy special nodes (rect)") { // Here we fetch them from the rsrc dir, rather than the data dir ResMgr::pushPath("../rsrc/strings"); + oldSpec.m1 = 4; oldSpec.m2 = 5; + oldSpec.pic = 1; oldSpec.ex1a = 2; oldSpec.ex1b = 10; oldSpec.ex2a = 4; @@ -1320,8 +1324,6 @@ TEST_CASE("When converting legacy special nodes (rect)") { oldSpec.jumpto = 12; SECTION("Place Fire Wall") { oldSpec.type = 200; - oldSpec.m1 = 4; oldSpec.m2 = 5; - oldSpec.pic = 1; oldSpec.sd1 = 75; newSpec.import_legacy(oldSpec); CHECK(newSpec.type == eSpecType::RECT_PLACE_FIELD); @@ -1335,6 +1337,269 @@ TEST_CASE("When converting legacy special nodes (rect)") { CHECK(newSpec.ex2b == 20); CHECK(newSpec.jumpto == 12); } + SECTION("Place Force Wall") { + oldSpec.type = 201; + oldSpec.sd1 = 75; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_PLACE_FIELD); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 75); + CHECK(newSpec.sd2 == WALL_FORCE); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Place Ice Wall") { + oldSpec.type = 202; + oldSpec.sd1 = 75; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_PLACE_FIELD); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 75); + CHECK(newSpec.sd2 == WALL_ICE); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Place Blade Wall") { + oldSpec.type = 203; + oldSpec.sd1 = 75; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_PLACE_FIELD); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 75); + CHECK(newSpec.sd2 == WALL_BLADES); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Place Stinking Cloud") { + oldSpec.type = 204; + oldSpec.sd1 = 75; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_PLACE_FIELD); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 75); + CHECK(newSpec.sd2 == CLOUD_STINK); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Place Sleep Cloud") { + oldSpec.type = 205; + oldSpec.sd1 = 75; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_PLACE_FIELD); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 75); + CHECK(newSpec.sd2 == CLOUD_SLEEP); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Place Quickfire") { + oldSpec.type = 206; + oldSpec.sd1 = 75; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_PLACE_FIELD); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 75); + CHECK(newSpec.sd2 == FIELD_QUICKFIRE); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Place Fire Barrier") { + oldSpec.type = 207; + oldSpec.sd1 = 75; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_PLACE_FIELD); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 75); + CHECK(newSpec.sd2 == BARRIER_FIRE); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Place Force Barrier") { + oldSpec.type = 208; + oldSpec.sd1 = 75; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_PLACE_FIELD); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 75); + CHECK(newSpec.sd2 == BARRIER_FORCE); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Cleanse") { + oldSpec.type = 209; + oldSpec.sd1 = 1; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_PLACE_FIELD); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 1); + CHECK(newSpec.sd2 == FIELD_DISPEL); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Place Special Effects") { + oldSpec.type = 210; + oldSpec.sd1 = 75; + oldSpec.sd2 = 4; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_PLACE_FIELD); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 75); + CHECK(newSpec.sd2 == SFX_LARGE_SLIME); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Place Permanent Effects") { + oldSpec.type = 211; + oldSpec.sd1 = 75; + oldSpec.sd2 = 1; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_PLACE_FIELD); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 75); + CHECK(newSpec.sd2 == OBJECT_BARREL); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Move Items") { + oldSpec.type = 212; + oldSpec.sd1 = 25; + oldSpec.sd2 = 26; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_MOVE_ITEMS); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 25); + CHECK(newSpec.sd2 == 26); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Destroy Items") { + oldSpec.type = 213; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_DESTROY_ITEMS); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Change Terrain") { + oldSpec.type = 214; + oldSpec.sd1 = 75; + oldSpec.sd2 = 80; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_CHANGE_TER); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 75); + CHECK(newSpec.sd2 == 80); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Swap Terrain") { + oldSpec.type = 215; + oldSpec.sd1 = 75; + oldSpec.sd2 = 80; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_SWAP_TER); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.sd1 == 75); + CHECK(newSpec.sd2 == 80); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Transform Terrain") { + oldSpec.type = 216; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_TRANS_TER); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Lock Terrain") { + oldSpec.type = 217; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_LOCK); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } + SECTION("Unlock Terrain") { + oldSpec.type = 218; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::RECT_UNLOCK); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.pic == 1); + CHECK(newSpec.ex1a == 2); + CHECK(newSpec.ex1b == 10); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 20); + CHECK(newSpec.jumpto == 12); + } // Clean up after ourselves ResMgr::popPath(); } @@ -1353,6 +1618,124 @@ TEST_CASE("When converting legacy special nodes (outdoors)") { CHECK(newSpec.type == eSpecType::OUT_MAKE_WANDER); CHECK(newSpec.jumpto == 12); } + SECTION("Change Terrain") { + oldSpec.type = 226; + oldSpec.m1 = 4; oldSpec.m2 = 5; + oldSpec.ex1a = 7; oldSpec.ex1b = 8; + oldSpec.ex2a = 9; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::CHANGE_TER); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.ex1a == 7); CHECK(newSpec.ex1b == 8); + CHECK(newSpec.ex2a == 9); + CHECK(newSpec.jumpto == 12); + } + SECTION("Place Outdoor Encounter") { + oldSpec.type = 227; + oldSpec.m1 = 4; oldSpec.m2 = 5; + oldSpec.ex1a = 3; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::OUT_PLACE_ENCOUNTER); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.ex1a == 3); + CHECK(newSpec.jumpto == 12); + } + SECTION("Move Party") { + oldSpec.type = 228; + oldSpec.m1 = 4; oldSpec.m2 = 5; + oldSpec.ex1a = 25; oldSpec.ex1b = 26; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::OUT_MOVE_PARTY); + CHECK(newSpec.m1 == 4); CHECK(newSpec.m2 == 5); + CHECK(newSpec.ex1a == 25); CHECK(newSpec.ex1b == 26); + CHECK(newSpec.jumpto == 12); + } + SECTION("Outdoor Store") { + oldSpec.type = 229; + oldSpec.m1 = 8; + oldSpec.ex1a = 1; oldSpec.ex1b = 2; + oldSpec.ex2a = 5; oldSpec.ex2b = 4; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::ENTER_SHOP); + CHECK(newSpec.m1 == 8); + CHECK(newSpec.ex1a == 31); + CHECK(newSpec.ex1b == 2); + CHECK(newSpec.ex2a == 5); + CHECK(newSpec.ex2b == 4); + } + // Clean up after ourselves + ResMgr::popPath(); +} + +TEST_CASE("When converting classic special nodes") { + cSpecial newSpec; + legacy::special_node_type oldSpec = {0,-1,-1,0,-1,-1,-1,-1,-1,-1,-1}; + // Fetching opcodes requires strings to be available + // Here we fetch them from the rsrc dir, rather than the data dir + ResMgr::pushPath("../rsrc/strings"); + + oldSpec.jumpto = 12; + SECTION("If Statistic") { + oldSpec.type = 153; + oldSpec.ex1a = 20; + oldSpec.ex1b = 20; + oldSpec.ex2a = 20; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::IF_STATISTIC); + CHECK(newSpec.ex1a == 20); + CHECK(newSpec.ex1b == 20); + CHECK(newSpec.ex2a == int(eSkill::MAX_HP)); + CHECK(newSpec.ex2b == 0); // cumulative check + CHECK(newSpec.jumpto == 12); + } + /* Disabled for now since it shows a dialog + SECTION("Display Picture") { + oldSpec.type = 28; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::DISPLAY_PICTURE); + CHECK(newSpec.ex1a == 0); + CHECK(newSpec.jumpto == 12); + } + */ + SECTION("Random") { + oldSpec.type = 29; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::SDF_RANDOM); + CHECK(newSpec.jumpto == 12); + } + SECTION("If Species") { + oldSpec.type = 156; + oldSpec.ex1a = 2; oldSpec.ex1b = 50; + oldSpec.ex2a = 4; oldSpec.ex2b = 0; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::IF_SPECIES); + CHECK(newSpec.ex1a == int(eRace::SLITH)); + CHECK(newSpec.ex1b == 50); + CHECK(newSpec.ex2a == 4); + CHECK(newSpec.ex2b == 0); + CHECK(newSpec.jumpto == 12); + } + SECTION("Town Change Lighting") { + oldSpec.type = 196; + oldSpec.ex1a = 2; + oldSpec.ex2a = 15; + oldSpec.ex2b = 1; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::TOWN_CHANGE_LIGHTING); + CHECK(newSpec.ex1a == LIGHT_DRAINS); + CHECK(newSpec.ex2a == 15); + CHECK(newSpec.ex2b == 1); + CHECK(newSpec.jumpto == 12); + } + SECTION("Town Set Attitude") { + oldSpec.type = 197; + oldSpec.ex1a = 20; oldSpec.ex1b = 2; + newSpec.import_legacy(oldSpec); + CHECK(newSpec.type == eSpecType::TOWN_SET_ATTITUDE); + CHECK(newSpec.ex1a == 20); + CHECK(newSpec.ex1b == int(eAttitude::FRIENDLY)); + CHECK(newSpec.jumpto == 12); + } // Clean up after ourselves ResMgr::popPath(); }