2024-07-08 17:12:00 -05:00
# pragma region License
/*
License ( OLC - 3 )
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
Copyright 2024 Joshua Sigona < sigonasr2 @ gmail . com >
Redistribution and use in source and binary forms , with or without modification ,
are permitted provided that the following conditions are met :
1. Redistributions or derivations of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
2. Redistributions or derivative works in binary form must reproduce the above
copyright notice . This list of conditions and the following disclaimer must be
reproduced in the documentation and / or other materials provided with the distribution .
3. Neither the name of the copyright holder nor the names of its contributors may
be used to endorse or promote products derived from this software without specific
prior written permission .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS " AND ANY
EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT ,
INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED
TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR
BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN
CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE .
Portions of this software are copyright <EFBFBD> 2024 The FreeType
Project ( www . freetype . org ) . Please see LICENSE_FT . txt for more information .
All rights reserved .
*/
# pragma endregion
# include "CppUnitTest.h"
# include "AdventuresInLestoria.h"
# include "Tutorial.h"
# include <random>
# include <format>
# include "ItemDrop.h"
2024-08-03 14:54:40 -05:00
# include <ranges>
2024-09-12 18:32:54 -05:00
# include "GameHelper.h"
2024-07-08 17:12:00 -05:00
using namespace Microsoft : : VisualStudio : : CppUnitTestFramework ;
using namespace olc : : utils ;
INCLUDE_GFX
INCLUDE_ITEM_DATA
2024-08-06 04:39:36 -05:00
INCLUDE_INITIALIZEGAMECONFIGURATIONS
2024-07-08 17:12:00 -05:00
extern std : : mt19937 rng ;
namespace ItemTests
{
TEST_CLASS ( ItemTest )
{
public :
std : : unique_ptr < AiL > testGame ;
InputGroup testKeyboardInput ;
Player * player ;
HWButton * testKey ;
TEST_METHOD_INITIALIZE ( ItemInitialize ) {
2024-08-06 04:39:36 -05:00
InitializeGameConfigurations ( ) ;
2024-07-08 17:12:00 -05:00
rng = std : : mt19937 { 57189U } ; //Establish a fixed random seed on setup so the exact same results are generated every test run.
2024-07-31 04:40:12 -05:00
testGame . reset ( new AiL ( true ) ) ;
2024-07-08 17:12:00 -05:00
ItemAttribute : : Initialize ( ) ;
ItemInfo : : InitializeItems ( ) ;
testGame - > InitializeGraphics ( ) ;
testGame - > InitializeClasses ( ) ;
sig : : Animation : : InitializeAnimations ( ) ;
testGame - > InitializeDefaultKeybinds ( ) ;
testGame - > InitializePlayer ( ) ;
sig : : Animation : : SetupPlayerAnimations ( ) ;
Menu : : InitializeMenus ( ) ;
Tutorial : : Initialize ( ) ;
Stats : : InitializeDamageReductionTable ( ) ;
GameState : : Initialize ( ) ;
GameState : : STATE = GameState : : states . at ( States : : State : : GAME_RUN ) ;
2024-08-26 12:04:38 -05:00
testGame - > ResetLevelStates ( ) ;
2024-07-08 17:12:00 -05:00
# pragma region Setup a fake test map and test monster
2024-08-04 22:49:11 -05:00
game - > MAP_DATA [ " CAMPAIGN_1_1 " ] ;
ItemDrop : : ClearDrops ( ) ;
MonsterData testMonsterData { " TestName " , " Test Monster " , 1000 , 10 , 5 , { MonsterDropData { " Health Potion " , 100.f , 1 , 1 } } , 200.f } ;
MONSTER_DATA [ " TestName " ] = testMonsterData ;
2024-07-08 17:12:00 -05:00
# pragma endregion
player = testGame - > GetPlayer ( ) ;
//Setup key "0" as a test input
testKeyboardInput . AddKeybind ( Input { InputType : : KEY , 0 } ) ;
2024-08-04 22:49:11 -05:00
testKey = testGame - > GetKeyboardState ( 0 ) ;
2024-07-08 17:12:00 -05:00
testGame - > olc_UpdateKeyFocus ( true ) ; //Force the game to be "focused" for tests. Required if we want keyboard inputs to work.
Menu : : themes . SetInitialized ( ) ;
GFX . SetInitialized ( ) ;
}
2024-09-12 15:18:57 -05:00
TEST_METHOD_CLEANUP ( ItemCleanupTests ) {
testGame - > EndGame ( ) ;
testGame - > OnUserUpdate ( 0.f ) ;
testGame . reset ( ) ;
}
2024-07-08 17:12:00 -05:00
TEST_METHOD ( ItemGiveTest ) {
Inventory : : AddItem ( " Health Potion " s , 3 ) ;
Assert : : AreEqual ( 3U , Inventory : : GetItemCount ( " Health Potion " s ) , L " Player has 3 Health Potions. " ) ;
}
TEST_METHOD ( ItemRemoveTest ) {
Inventory : : AddItem ( " Health Potion " s , 3 ) ;
for ( std : : weak_ptr < Item > & item : Inventory : : GetItem ( " Health Potion " s ) ) Inventory : : RemoveItem ( item , 3 ) ;
Assert : : AreEqual ( 0U , Inventory : : GetItemCount ( " Health Potion " s ) , L " Player has no Health Potions. " ) ;
}
TEST_METHOD ( ItemQuantityStackTest ) {
Inventory : : AddItem ( " Health Potion " s , 3 ) ;
Inventory : : AddItem ( " Health Potion " s , 3 ) ;
Assert : : AreEqual ( 6U , Inventory : : GetItemCount ( " Health Potion " s ) , L " Player has 6 Health Potions. " ) ;
}
TEST_METHOD ( EquipmentNoStackTest ) {
Inventory : : AddItem ( " Ring of the Slime King " s ) ;
Inventory : : AddItem ( " Ring of the Slime King " s ) ;
Inventory : : AddItem ( " Ring of the Slime King " s ) ;
int itemCounter { } ;
for ( std : : weak_ptr < Item > & item : Inventory : : GetItem ( " Ring of the Slime King " s ) ) itemCounter + + ;
Assert : : AreEqual ( 3 , itemCounter , L " 3 separate item entries for Ring of the Slime King. " ) ;
}
TEST_METHOD ( UsingBlankLoadoutItemDoesNothing ) {
Assert : : IsFalse ( game - > UseLoadoutItem ( 0 ) , L " Using a blank loadout item slot (0) does not produce a result. " ) ;
Assert : : IsFalse ( game - > UseLoadoutItem ( 1 ) , L " Using a blank loadout item slot (1) does not produce a result. " ) ;
Assert : : IsFalse ( game - > UseLoadoutItem ( 2 ) , L " Using a blank loadout item slot (2) does not produce a result. " ) ;
}
2024-07-09 10:49:12 -05:00
TEST_METHOD ( UsingLoadoutItemOfQuantityZeroDoesNothing ) {
Assert : : ExpectException < std : : exception > ( [ ] ( ) { game - > SetLoadoutItem ( 0 , " Minor Health Potion " ) ; } , L " Applying an item that doesn't exist to a loadout slot should not be allowed. " ) ;
}
TEST_METHOD ( UsingLoadoutItemConsumesIt ) {
player - > Hurt ( 1 , player - > OnUpperLevel ( ) , player - > GetZ ( ) ) ;
Inventory : : AddItem ( " Minor Health Potion " s , 5U ) ;
game - > SetLoadoutItem ( 0 , " Minor Health Potion " ) ;
testKey - > bHeld = true ; //Simulate key being pressed.
2024-08-06 15:08:32 -05:00
player - > CheckAndPerformAbility ( player - > GetItem1 ( ) , testKeyboardInput ) ;
2024-07-09 10:49:12 -05:00
Assert : : AreEqual ( 1 , Inventory : : loadoutItemsUsed [ 0 ] . second , L " 1 Health potion considered used in loadout inventory. " ) ;
Assert : : AreEqual ( 4U , Inventory : : GetItemCount ( " Minor Health Potion " s ) , L " 4 Health potions remain in player's inventory. " ) ;
2024-08-06 15:08:32 -05:00
Assert : : AreEqual ( player - > GetItem1 ( ) . GetCooldownTime ( ) , player - > GetItem1 ( ) . cooldown , L " Item 1 is now on cooldown. " ) ;
2024-07-09 10:49:12 -05:00
}
TEST_METHOD ( ItemScriptBuffTest ) {
player - > Hurt ( 1 , player - > OnUpperLevel ( ) , player - > GetZ ( ) ) ;
Inventory : : AddItem ( " Stat Up Everything Potion " s , 5U ) ;
game - > SetLoadoutItem ( 0 , " Stat Up Everything Potion " ) ;
testKey - > bHeld = true ; //Simulate key being pressed.
2024-08-06 15:08:32 -05:00
Assert : : ExpectException < std : : exception > ( [ & ] ( ) { player - > CheckAndPerformAbility ( player - > GetItem1 ( ) , testKeyboardInput ) ; } , L " If all buffs are properly applied, then some of these stat up buffs are illegal and will catch an exception. " ) ;
2024-07-09 10:49:12 -05:00
}
TEST_METHOD ( FlatRestoreScriptTest ) {
player - > Hurt ( 75 , player - > OnUpperLevel ( ) , player - > GetZ ( ) ) ;
2024-08-06 15:08:32 -05:00
player - > ConsumeMana ( 76 ) ;
2024-07-09 10:49:12 -05:00
Inventory : : AddItem ( " Flat Recovery Potion " s , 5U ) ;
game - > SetLoadoutItem ( 0 , " Flat Recovery Potion " ) ;
testKey - > bHeld = true ; //Simulate key being pressed.
2024-08-06 15:08:32 -05:00
player - > CheckAndPerformAbility ( player - > GetItem1 ( ) , testKeyboardInput ) ;
2024-08-30 22:25:49 -05:00
game - > OnUserUpdate ( 0.f ) ; //Wait an extra tick for the buff to begin going down.
2024-07-23 04:41:24 -05:00
game - > SetElapsedTime ( 0.05f ) ;
game - > OnUserUpdate ( 0.05f ) ; //Wait some time as the item applies a buff that heals us. We're also going to gain one mana during this tick.
2024-07-09 10:49:12 -05:00
Assert : : AreEqual ( 75 , player - > GetHealth ( ) , L " Player Health is 75 after using Flat Recovery Potion. " ) ;
Assert : : AreEqual ( 75 , player - > GetMana ( ) , L " Player Mana is 75 after using Flat Recovery Potion. " ) ;
}
TEST_METHOD ( PctRestoreScriptTest ) {
player - > Hurt ( 75 , player - > OnUpperLevel ( ) , player - > GetZ ( ) ) ;
2024-08-06 15:08:32 -05:00
player - > ConsumeMana ( 76 ) ;
2024-07-09 10:49:12 -05:00
Inventory : : AddItem ( " Pct Recovery Potion " s , 5U ) ;
game - > SetLoadoutItem ( 1 , " Pct Recovery Potion " ) ;
testKey - > bHeld = true ; //Simulate key being pressed.
2024-08-06 15:08:32 -05:00
player - > CheckAndPerformAbility ( player - > GetItem2 ( ) , testKeyboardInput ) ;
2024-08-30 22:25:49 -05:00
game - > OnUserUpdate ( 0.f ) ; //Wait an extra tick for the buff to begin going down.
2024-07-23 04:41:24 -05:00
game - > SetElapsedTime ( 0.05f ) ;
game - > OnUserUpdate ( 0.05f ) ; //Wait some time as the item applies a buff that heals us.
2024-07-09 10:49:12 -05:00
Assert : : AreEqual ( 75 , player - > GetHealth ( ) , L " Player Health is 75 after using Pct Recovery Potion. " ) ;
Assert : : AreEqual ( 75 , player - > GetMana ( ) , L " Player Mana is 75 after using Pct Recovery Potion. " ) ;
}
TEST_METHOD ( HealOverTimeTest ) {
player - > Hurt ( 75 , player - > OnUpperLevel ( ) , player - > GetZ ( ) ) ;
Inventory : : AddItem ( " Bandages " s , 5U ) ;
game - > SetLoadoutItem ( 2 , " Bandages " ) ;
testKey - > bHeld = true ; //Simulate key being pressed.
2024-08-06 15:08:32 -05:00
player - > CheckAndPerformAbility ( player - > GetItem3 ( ) , testKeyboardInput ) ;
2024-08-30 22:25:49 -05:00
game - > OnUserUpdate ( 0.f ) ; //Wait an extra tick for the buff to begin going down.
2024-07-23 04:41:24 -05:00
game - > SetElapsedTime ( 0.05f ) ;
game - > OnUserUpdate ( 0.05f ) ; //Wait some time as the item applies a buff that heals us.
2024-07-09 10:49:12 -05:00
Assert : : AreEqual ( 30 , player - > GetHealth ( ) , L " Player is immediately healed for 5 health points on Bandages use. " ) ;
game - > SetElapsedTime ( 1.f ) ;
game - > OnUserUpdate ( 1.f ) ;
for ( int seconds { 1 } ; seconds < = 6 ; seconds + + ) {
Assert : : AreEqual ( 30 + seconds * 5 , player - > GetHealth ( ) , L " Player is healed again for 5 health points. " ) ;
game - > OnUserUpdate ( 1.f ) ;
}
Assert : : AreEqual ( 60 , player - > GetHealth ( ) , L " Player should not be healed now that the Bandages effect is over. " ) ;
}
2024-07-31 04:40:12 -05:00
TEST_METHOD ( DisassembleAccessoryTest ) {
Inventory : : AddItem ( " Ring of the Slime King " s ) ;
std : : weak_ptr < Item > disassembleRingTest { Inventory : : AddItem ( " Ring of the Slime King " s ) } ;
Inventory : : AddItem ( " Ring of the Slime King " s ) ;
Inventory : : Disassemble ( disassembleRingTest ) ;
Assert : : AreEqual ( 2U , Inventory : : GetItemCount ( " Ring of the Slime King " s ) , L " Disassembly has removed one of the Slime King rings from our inventory. " ) ;
Assert : : IsTrue ( disassembleRingTest . expired ( ) , L " Original reference to disassembled ring should now be invalid. " ) ;
Assert : : AreEqual ( 1U , Inventory : : GetItemCount ( ITEM_DATA [ " Ring of the Slime King " ] . FragmentName ( ) ) , L " Disassembly has given us a Slime King Ring Fragment. " ) ;
}
2024-07-31 04:48:35 -05:00
TEST_METHOD ( DisassembleNonAccessoryTest ) {
2024-07-31 11:21:05 -05:00
Inventory : : AddItem ( " Ring of the Slime King " s ) ;
2024-07-31 04:48:35 -05:00
try {
Inventory : : Disassemble ( Inventory : : AddItem ( " Test Armor " s ) ) ;
Assert : : Fail ( L " Disassembling Test Armor succeeded! This should NOT be allowed! " ) ;
} catch ( std : : runtime_error & e ) { }
try {
Inventory : : Disassemble ( Inventory : : AddItem ( " Green Slime Remains " s ) ) ;
Assert : : Fail ( L " Disassembling Green Slime Remains succeeded! This should NOT be allowed! " ) ;
} catch ( std : : runtime_error & e ) { }
try {
Inventory : : Disassemble ( Inventory : : AddItem ( " Health Potion " s ) ) ;
Assert : : Fail ( L " Disassembling a Health Potion succeeded! This should NOT be allowed! " ) ;
} catch ( std : : runtime_error & e ) { }
}
2024-07-31 11:21:05 -05:00
TEST_METHOD ( RefiningTest ) {
std : : weak_ptr < Item > slimeKingRing { Inventory : : AddItem ( " Ring of the Slime King " s ) } ;
Assert : : IsFalse ( slimeKingRing . lock ( ) - > CanBeRefined ( ) , L " Ring of the Slime King should not be allowed to be refined since we have no fragments. " ) ;
std : : weak_ptr < Item > testArmor { Inventory : : AddItem ( " Test Armor " s ) } ;
Assert : : IsFalse ( testArmor . lock ( ) - > CanBeRefined ( ) , L " Test Armor should not be allowed to be refined since it's not an accessory. " ) ;
Inventory : : AddItem ( slimeKingRing . lock ( ) - > FragmentName ( ) , 50U ) ;
2024-09-12 15:18:57 -05:00
Inventory : : EquipItem ( slimeKingRing , EquipSlot : : RING1 ) ;
2024-07-31 11:21:05 -05:00
Assert : : IsTrue ( slimeKingRing . lock ( ) - > CanBeRefined ( ) , L " Ring of the Slime King should now be allowed to be refined since we meet all requirements. " ) ;
player - > SetMoney ( 0 ) ;
Assert : : IsFalse ( slimeKingRing . lock ( ) - > CanBeRefined ( ) , L " Ring of the Slime King should not be allowed to be refined since we do not have enough money. " ) ;
player - > SetMoney ( 10000 ) ;
while ( slimeKingRing . lock ( ) - > CanBeRefined ( ) ) {
RefineResult result { slimeKingRing . lock ( ) - > Refine ( ) } ;
LOG ( std : : format ( " Enhanced {} by {} " , result . first . Name ( ) , result . second ) ) ;
}
for ( const auto & [ attr , val ] : slimeKingRing . lock ( ) - > RandomStats ( ) ) {
Assert : : AreEqual ( ITEM_DATA [ slimeKingRing . lock ( ) - > ActualName ( ) ] . GetMaxStats ( ) . A_Read ( attr ) , val , L " The current stats should be equal to the maximum stats when refinement is done. " ) ;
}
2024-09-12 15:18:57 -05:00
/*Ring of the Slime King has the following refining stats:
* StatValues = Health , Mana , Move Spd %
MinStats = 5 , 1 , 1
MaxStats = 20 , 4 , 3
*
Therefore , after this process is done the player should have 20 more health , 4 more mana , and 3 % more move speed than normal .
*/
//These checks make sure that the refining call actually modifies already equipped items!
Assert : : AreEqual ( 120 , player - > GetMaxHealth ( ) , L " Player should now have 120 max health. " ) ;
Assert : : AreEqual ( 104 , player - > GetMaxMana ( ) , L " Player should now have 104 max mana. " ) ;
Assert : : AreEqual ( 1.03f , player - > GetMoveSpdMult ( ) , L " Player should now have 103% move speed. " ) ;
2024-07-31 11:21:05 -05:00
}
2024-08-03 14:54:40 -05:00
TEST_METHOD ( EnchantTestCheck ) {
std : : weak_ptr < Item > slimeKingRing { Inventory : : AddItem ( " Ring of the Slime King " s ) } ;
Assert : : IsFalse ( slimeKingRing . lock ( ) - > HasEnchant ( ) ) ;
2024-09-18 15:03:40 -05:00
bool obtainedDuplicate { false } ;
2024-08-03 14:54:40 -05:00
for ( int i : std : : ranges : : iota_view ( 0 , 1000 ) ) {
2024-09-18 15:03:40 -05:00
std : : optional < ItemEnchant > previousEnchant { slimeKingRing . lock ( ) - > GetEnchant ( ) } ;
2024-09-16 03:16:40 -05:00
std : : string previousEnchantName { } ;
if ( slimeKingRing . lock ( ) - > HasEnchant ( ) ) previousEnchantName = slimeKingRing . lock ( ) - > GetEnchant ( ) . value ( ) . Name ( ) ;
2024-09-18 15:03:40 -05:00
slimeKingRing . lock ( ) - > _EnchantItem ( ItemEnchant : : RollRandomEnchant ( previousEnchant ) ) ;
2024-08-03 14:54:40 -05:00
Assert : : IsTrue ( slimeKingRing . lock ( ) - > HasEnchant ( ) ) ;
2024-09-18 15:03:40 -05:00
if ( previousEnchantName = = slimeKingRing . lock ( ) - > GetEnchant ( ) . value ( ) . Name ( ) ) {
bool improvementExists { false } ;
std : : string statDowngrades { } ;
if ( previousEnchant . value ( ) . HasAttributes ( ) ) {
for ( const auto & [ attr , val ] : previousEnchant . value ( ) ) {
if ( slimeKingRing . lock ( ) - > GetEnchant ( ) . value ( ) . GetAttribute ( attr . ActualName ( ) ) > val ) {
improvementExists = true ;
break ;
} else statDowngrades + = std : : format ( " {} - Previous:{}, New:{} \n " , attr . Name ( ) , val , slimeKingRing . lock ( ) - > GetEnchant ( ) . value ( ) . GetAttribute ( attr . ActualName ( ) ) ) ;
}
} else improvementExists = true ;
Assert : : IsTrue ( improvementExists , util : : wformat ( " Could not find a stat improvement for same name stat! {} THIS SHOULD NOT BE ALLOWED! " , statDowngrades ) . c_str ( ) ) ;
obtainedDuplicate = true ;
}
2024-08-03 14:54:40 -05:00
if ( ItemEnchantInfo : : ENCHANT_LIST . at ( slimeKingRing . lock ( ) - > GetEnchant ( ) . value ( ) . Name ( ) ) . GetClass ( ) . has_value ( ) ) Assert : : AreEqual ( int ( player - > GetClass ( ) ) , int ( ItemEnchantInfo : : ENCHANT_LIST . at ( slimeKingRing . lock ( ) - > GetEnchant ( ) . value ( ) . Name ( ) ) . GetClass ( ) . value ( ) ) ) ; //Validate enchant is only for this class if it's a class-based ability.
}
testGame - > ChangePlayerClass ( WIZARD ) ;
player = testGame - > GetPlayer ( ) ; //The player pointer has been reassigned...
for ( int i : std : : ranges : : iota_view ( 0 , 1000 ) ) {
2024-09-18 15:03:40 -05:00
std : : optional < ItemEnchant > previousEnchant { slimeKingRing . lock ( ) - > GetEnchant ( ) } ;
2024-09-16 03:16:40 -05:00
std : : string previousEnchantName { } ;
if ( slimeKingRing . lock ( ) - > HasEnchant ( ) ) previousEnchantName = slimeKingRing . lock ( ) - > GetEnchant ( ) . value ( ) . Name ( ) ;
2024-09-18 15:03:40 -05:00
slimeKingRing . lock ( ) - > _EnchantItem ( ItemEnchant : : RollRandomEnchant ( previousEnchant ) ) ;
2024-08-03 14:54:40 -05:00
Assert : : IsTrue ( slimeKingRing . lock ( ) - > HasEnchant ( ) ) ;
2024-09-18 15:03:40 -05:00
if ( previousEnchantName = = slimeKingRing . lock ( ) - > GetEnchant ( ) . value ( ) . Name ( ) ) {
bool improvementExists { false } ;
std : : string statDowngrades { } ;
if ( previousEnchant . value ( ) . HasAttributes ( ) ) {
for ( const auto & [ attr , val ] : previousEnchant . value ( ) ) {
if ( slimeKingRing . lock ( ) - > GetEnchant ( ) . value ( ) . GetAttribute ( attr . ActualName ( ) ) > val ) {
improvementExists = true ;
break ;
} else statDowngrades + = std : : format ( " {} - Previous:{}, New:{} \n " , attr . Name ( ) , val , slimeKingRing . lock ( ) - > GetEnchant ( ) . value ( ) . GetAttribute ( attr . ActualName ( ) ) ) ;
}
} else improvementExists = true ;
Assert : : IsTrue ( improvementExists , util : : wformat ( " Could not find a stat improvement for same name stat! {} THIS SHOULD NOT BE ALLOWED! " , statDowngrades ) . c_str ( ) ) ;
obtainedDuplicate = true ;
}
2024-08-03 14:54:40 -05:00
if ( ItemEnchantInfo : : ENCHANT_LIST . at ( slimeKingRing . lock ( ) - > GetEnchant ( ) . value ( ) . Name ( ) ) . GetClass ( ) . has_value ( ) ) Assert : : AreEqual ( int ( player - > GetClass ( ) ) , int ( ItemEnchantInfo : : ENCHANT_LIST . at ( slimeKingRing . lock ( ) - > GetEnchant ( ) . value ( ) . Name ( ) ) . GetClass ( ) . value ( ) ) ) ; //Validate enchant is only for this class if it's a class-based ability.
}
2024-09-18 15:03:40 -05:00
Assert : : IsTrue ( obtainedDuplicate , L " During this test a duplicate enchant was never obtained! THIS SHOULD BE ALLOWED! " ) ;
2024-08-03 14:54:40 -05:00
}
2024-09-06 16:10:37 -05:00
TEST_METHOD ( AccessoryAntiCompatibilityCheck ) {
std : : weak_ptr < Item > extraRing { Inventory : : AddItem ( " Ring of the Slime King " s ) } ;
std : : weak_ptr < Item > extraRing2 { Inventory : : AddItem ( " Ring of the Slime King " s ) } ;
Inventory : : EquipItem ( extraRing , EquipSlot : : RING2 ) ;
Assert : : AreEqual ( true , Item : : SelectedEquipIsDifferent ( extraRing2 , EquipSlot : : RING1 ) , L " The game should allow equipping of any two normal rings that are not the same ring. " ) ;
Assert : : AreEqual ( false , Item : : SelectedEquipIsDifferent ( extraRing , EquipSlot : : RING1 ) , L " The game should not allow equipping the same ring if it's already equipped. " ) ;
Inventory : : UnequipItem ( EquipSlot : : RING2 ) ;
Assert : : AreEqual ( true , Item : : SelectedEquipIsDifferent ( extraRing , EquipSlot : : RING1 ) , L " The game should allow equipping a ring to either blank slot if they're open. " ) ;
}
2024-09-12 18:32:54 -05:00
TEST_METHOD ( AccessoryRandomEnchantTest ) {
std : : weak_ptr < Item > extraRing { Inventory : : AddItem ( " Ring of the Slime King " s ) } ;
std : : unordered_map < ItemEnchantInfo : : ItemEnchantCategory , uint32_t > enchantCounts ;
for ( int i : std : : ranges : : iota_view ( 0 , 1000 ) ) {
2024-09-15 21:24:48 -05:00
Inventory : : AddItem ( extraRing . lock ( ) - > FragmentName ( ) , " Fragment Enchant Cost " _i [ 0 ] ) ;
player - > AddMoney ( " Fragment Enchant Cost " _i [ 1 ] ) ;
2024-09-18 15:03:40 -05:00
const ItemEnchant & resultEnchant { extraRing . lock ( ) - > ApplyRandomEnchant ( ) } ;
2024-09-12 18:32:54 -05:00
if ( resultEnchant . GetClass ( ) . has_value ( ) ) Assert : : AreEqual ( int ( resultEnchant . GetClass ( ) . value ( ) ) , int ( player - > GetClass ( ) ) , L " Player's class matches the class of the enchant. " ) ;
enchantCounts [ resultEnchant . Category ( ) ] + + ;
Assert : : AreEqual ( true , extraRing . lock ( ) - > GetEnchant ( ) . has_value ( ) , L " Ring is expected to be enchanted. " ) ;
Assert : : AreEqual ( resultEnchant . Name ( ) , extraRing . lock ( ) - > GetEnchant ( ) . value ( ) . Name ( ) , L " Ring is expected to be enchanted with the same enchant that was selected. " ) ;
Assert : : AreEqual ( false , player - > HasEnchant ( resultEnchant . Name ( ) ) , L " Player is not expected to have the same enchant that was selected while the ring is unequipped. " ) ;
Inventory : : EquipItem ( extraRing , EquipSlot : : RING1 ) ;
Assert : : AreEqual ( true , player - > HasEnchant ( resultEnchant . Name ( ) ) , L " Player is expected to have the same enchant that was selected. " ) ;
Inventory : : UnequipItem ( EquipSlot : : RING1 ) ;
}
Test : : InRange ( enchantCounts [ ItemEnchantInfo : : ItemEnchantCategory : : GENERAL ] , { 450U , 550U } , util : : wformat ( " General enchants % is approx 50%. " ) ) ;
Test : : InRange ( enchantCounts [ ItemEnchantInfo : : ItemEnchantCategory : : CLASS ] , { 350U , 450U } , util : : wformat ( " Class enchants % is approx 40%. " ) ) ;
Test : : InRange ( enchantCounts [ ItemEnchantInfo : : ItemEnchantCategory : : UNIQUE ] , { 50U , 150U } , util : : wformat ( " Unique enchants % is approx 40%. " ) ) ;
}
2024-09-12 19:25:43 -05:00
TEST_METHOD ( EnchantColorTest ) {
Assert : : AreEqual ( " Item Enchants.General Enchants.Enchant Display Color " _Pixel . n , ItemEnchantInfo : : GetEnchant ( " Health Boost " ) . DisplayCol ( ) . n , L " Expecting a general enchant to have the general enchant pixel display color. " ) ;
Assert : : AreEqual ( " Item Enchants.Class Enchants.Enchant Display Color " _Pixel . n , ItemEnchantInfo : : GetEnchant ( " Quickdraw " ) . DisplayCol ( ) . n , L " Expecting a class enchant to have the class enchant pixel display color. " ) ;
Assert : : AreEqual ( " Item Enchants.Unique Enchants.Enchant Display Color " _Pixel . n , ItemEnchantInfo : : GetEnchant ( " Magical Protection " ) . DisplayCol ( ) . n , L " Expecting a unique enchant to have the unique enchant pixel display color. " ) ;
}
2024-09-15 21:24:48 -05:00
TEST_METHOD ( CanBeEnchantedTest ) {
std : : weak_ptr < Item > extraRing { Inventory : : AddItem ( " Ring of the Slime King " s ) } ;
std : : weak_ptr < Item > testArmor { Inventory : : AddItem ( " Test Armor " s ) } ;
Assert : : AreEqual ( false , extraRing . lock ( ) - > CanBeEnchanted ( ) , L " We don't have the money nor required fragments to enchant this item. " ) ;
Assert : : AreEqual ( false , testArmor . lock ( ) - > CanBeEnchanted ( ) , L " We can't enchant armor. " ) ;
player - > SetMoney ( 2000U ) ;
Assert : : AreEqual ( false , extraRing . lock ( ) - > CanBeEnchanted ( ) , L " We don't have the required fragments to enchant this item. " ) ;
player - > SetMoney ( 0U ) ;
Inventory : : AddItem ( extraRing . lock ( ) - > FragmentName ( ) , " Fragment Enchant Cost " _i [ 0 ] ) ;
Assert : : AreEqual ( false , extraRing . lock ( ) - > CanBeEnchanted ( ) , L " We don't have the required money to enchant this item. " ) ;
player - > SetMoney ( 2000U ) ;
Assert : : AreEqual ( true , extraRing . lock ( ) - > CanBeEnchanted ( ) , L " We don't have the required money to enchant this item. " ) ;
extraRing . lock ( ) - > ApplyRandomEnchant ( ) ;
Assert : : AreEqual ( false , extraRing . lock ( ) - > CanBeEnchanted ( ) , L " Ring cannot be enchanted again due to consumption of fragments. " ) ;
Inventory : : AddItem ( extraRing . lock ( ) - > FragmentName ( ) , " Fragment Enchant Cost " _i [ 0 ] ) ;
Assert : : AreEqual ( true , extraRing . lock ( ) - > CanBeEnchanted ( ) , L " Ring can be enchanted again with the right amount of fragments. " ) ;
Assert : : AreEqual ( uint32_t ( 2000 - " Fragment Enchant Cost " _i [ 1 ] ) , player - > GetMoney ( ) , util : : wformat ( " Lost {} money due to enchanting ring. " , " Fragment Enchant Cost " _i [ 1 ] ) . c_str ( ) ) ;
}
2024-07-08 17:12:00 -05:00
} ;
}