diff --git a/Adventures in Lestoria Tests/EnchantTests.cpp b/Adventures in Lestoria Tests/EnchantTests.cpp index 22e0b79e..f18c6f69 100644 --- a/Adventures in Lestoria Tests/EnchantTests.cpp +++ b/Adventures in Lestoria Tests/EnchantTests.cpp @@ -70,7 +70,7 @@ namespace EnchantTests std::unique_ptrtestGame; InputGroup testKeyboardInput; Player*player; - const HWButton*testKey; + HWButton*testKey; TEST_METHOD_INITIALIZE(PlayerInitialize){ InitializeGameConfigurations(); rng=std::mt19937{57189U};//Establish a fixed random seed on setup so the exact same results are generated every test run. @@ -405,5 +405,77 @@ namespace EnchantTests Assert::Fail(L"A Monster Soul has not disappeared after colliding with a player."); } } + TEST_METHOD(WizardsSoulCheck){ + testKey->bHeld=true; //Force the key to be held down for testing purposes. + player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput); + player->SetState(State::NORMAL); + player->RestoreMana(100); + player->CheckAndPerformAbility(player->GetAbility1(),testKeyboardInput); + player->SetState(State::NORMAL); + player->RestoreMana(100); + player->CheckAndPerformAbility(player->GetAbility2(),testKeyboardInput); + player->SetState(State::NORMAL); + player->RestoreMana(100); + player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput); + player->SetState(State::NORMAL); + player->RestoreMana(100); + player->CheckAndPerformAbility(player->GetAbility4(),testKeyboardInput); + Assert::AreEqual(player->GetRightClickAbility().GetCooldownTime(),player->GetRightClickAbility().cooldown,L"By default the player cooldowns are unaffected without the Wizard's Soul enchant."); + Assert::AreEqual(player->GetAbility1().GetCooldownTime(),player->GetAbility1().cooldown,L"By default the player cooldowns are unaffected without the Wizard's Soul enchant."); + Assert::AreEqual(player->GetAbility2().GetCooldownTime(),player->GetAbility2().cooldown,L"By default the player cooldowns are unaffected without the Wizard's Soul enchant."); + Assert::AreEqual(player->GetAbility3().GetCooldownTime(),player->GetAbility3().cooldown,L"By default the player cooldowns are unaffected without the Wizard's Soul enchant."); + Assert::AreEqual(player->GetAbility4().GetCooldownTime(),player->GetAbility4().cooldown,L"By default the player cooldowns are unaffected without the Wizard's Soul enchant."); + std::weak_ptrnullRing{Inventory::AddItem("Null Ring"s)}; + Inventory::EquipItem(nullRing,EquipSlot::RING1); + nullRing.lock()->EnchantItem("Wizard's Soul"); + player->SetState(State::NORMAL); + player->RestoreMana(100); + player->GetRightClickAbility().cooldown=0.f; //Reset the cooldown so it can be used. + player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput); + Assert::AreEqual(player->GetRightClickAbility().GetCooldownTime(),player->GetRightClickAbility().cooldown,L"Right-click ability goes on cooldown like normal."); + Assert::AreEqual(player->GetAbility1().GetCooldownTime(),player->GetAbility1().cooldown,L"All other abilities are unaffected by Right-click ability being used."); + Assert::AreEqual(player->GetAbility2().GetCooldownTime(),player->GetAbility2().cooldown,L"All other abilities are unaffected by Right-click ability being used."); + Assert::AreEqual(player->GetAbility3().GetCooldownTime(),player->GetAbility3().cooldown,L"All other abilities are unaffected by Right-click ability being used."); + Assert::AreEqual(player->GetAbility4().GetCooldownTime(),player->GetAbility4().cooldown,L"All other abilities are unaffected by Right-click ability being used."); + player->SetState(State::NORMAL); + player->RestoreMana(100); + player->GetAbility1().cooldown=0.f; //Reset the cooldown so it can be used. + player->CheckAndPerformAbility(player->GetAbility1(),testKeyboardInput); + Assert::AreEqual(player->GetRightClickAbility().GetCooldownTime(),player->GetRightClickAbility().cooldown,L"Right-click ability remains unaffected by other abilities."); + Assert::AreEqual(player->GetAbility1().GetCooldownTime(),player->GetAbility1().cooldown,L"Same ability used should not be affected."); + Assert::AreEqual(player->GetAbility2().GetCooldownTime()-1.5f,player->GetAbility2().cooldown,L"All other abilities have cooldowns reduced by 1.5 seconds."); + Assert::AreEqual(player->GetAbility3().GetCooldownTime()-1.5f,player->GetAbility3().cooldown,L"All other abilities have cooldowns reduced by 1.5 seconds."); + Assert::AreEqual(player->GetAbility4().GetCooldownTime()-1.5f,player->GetAbility4().cooldown,L"All other abilities have cooldowns reduced by 1.5 seconds."); + player->SetState(State::NORMAL); + player->RestoreMana(100); + player->GetAbility2().cooldown=0.f; //Reset the cooldown so it can be used. + player->CheckAndPerformAbility(player->GetAbility2(),testKeyboardInput); + Assert::AreEqual(player->GetRightClickAbility().GetCooldownTime(),player->GetRightClickAbility().cooldown,L"Right-click ability remains unaffected by other abilities."); + Assert::AreEqual(player->GetAbility1().GetCooldownTime()-1.5f,player->GetAbility1().cooldown,L"All other abilities have cooldowns reduced by 1.5 seconds."); + Assert::AreEqual(player->GetAbility2().GetCooldownTime(),player->GetAbility2().cooldown,L"Same ability used should not be affected."); + Assert::AreEqual(player->GetAbility3().GetCooldownTime()-3.f,player->GetAbility3().cooldown,L"All other abilities have cooldowns reduced by 1.5 seconds."); + Assert::AreEqual(player->GetAbility4().GetCooldownTime()-3.f,player->GetAbility4().cooldown,L"All other abilities have cooldowns reduced by 1.5 seconds."); + player->SetState(State::NORMAL); + player->RestoreMana(100); + player->GetAbility3().cooldown=0.f; //Reset the cooldown so it can be used. + player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput); + game->SetElapsedTime(1.f); + game->OnUserUpdate(1.f); //It's a cast, so wait one second as the ability gets used. This also reduces cooldowns by a second... + Assert::AreEqual(player->GetRightClickAbility().GetCooldownTime()-1.f,player->GetRightClickAbility().cooldown,L"Right-click ability remains unaffected by other abilities."); + Assert::AreEqual(player->GetAbility1().GetCooldownTime()-4.f,player->GetAbility1().cooldown,L"All other abilities have cooldowns reduced by 1.5 seconds."); + Assert::AreEqual(player->GetAbility2().GetCooldownTime()-2.5f,player->GetAbility2().cooldown,L"All other abilities have cooldowns reduced by 1.5 seconds."); + Assert::AreEqual(player->GetAbility3().GetCooldownTime()-1.f,player->GetAbility3().cooldown,L"Same ability used should not be affected."); + Assert::AreEqual(player->GetAbility4().GetCooldownTime(),player->GetAbility4().cooldown,L"All other abilities have cooldowns reduced by 1.5 seconds."); + player->SetState(State::NORMAL); + player->RestoreMana(100); + player->GetAbility4().cooldown=0.f; //Reset the cooldown so it can be used. + player->CheckAndPerformAbility(player->GetAbility4(),testKeyboardInput); + Assert::AreEqual(player->GetRightClickAbility().GetCooldownTime()-1.f,player->GetRightClickAbility().cooldown,L"Right-click ability remains unaffected by other abilities."); + Assert::AreEqual(player->GetAbility1().GetCooldownTime()-4.f,player->GetAbility1().cooldown,L"Ability 4 isn't setup for anything and returns as unused, causing cooldowns to remain the same."); + Assert::AreEqual(player->GetAbility2().GetCooldownTime()-2.5f,player->GetAbility2().cooldown,L"Ability 4 isn't setup for anything and returns as unused, causing cooldowns to remain the same."); + Assert::AreEqual(player->GetAbility3().GetCooldownTime()-1.f,player->GetAbility3().cooldown,L"Ability 4 isn't setup for anything and returns as unused, causing cooldowns to remain the same."); + Assert::AreEqual(player->GetAbility4().GetCooldownTime(),player->GetAbility4().cooldown,L"Ability 4 isn't setup for anything and returns as unused, causing cooldowns to remain the same."); + + } }; } \ No newline at end of file diff --git a/Adventures in Lestoria Tests/ItemTests.cpp b/Adventures in Lestoria Tests/ItemTests.cpp index 8bfec848..7885422f 100644 --- a/Adventures in Lestoria Tests/ItemTests.cpp +++ b/Adventures in Lestoria Tests/ItemTests.cpp @@ -132,25 +132,25 @@ namespace ItemTests Inventory::AddItem("Minor Health Potion"s,5U); game->SetLoadoutItem(0,"Minor Health Potion"); testKey->bHeld=true; //Simulate key being pressed. - player->CheckAndPerformAbility(player->useItem1,testKeyboardInput); + player->CheckAndPerformAbility(player->GetItem1(),testKeyboardInput); 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."); - Assert::AreEqual(player->useItem1.GetCooldownTime(),player->useItem1.cooldown,L"Item 1 is now on cooldown."); + Assert::AreEqual(player->GetItem1().GetCooldownTime(),player->GetItem1().cooldown,L"Item 1 is now on cooldown."); } 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. - Assert::ExpectException([&](){player->CheckAndPerformAbility(player->useItem1,testKeyboardInput);},L"If all buffs are properly applied, then some of these stat up buffs are illegal and will catch an exception."); + Assert::ExpectException([&](){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."); } TEST_METHOD(FlatRestoreScriptTest){ player->Hurt(75,player->OnUpperLevel(),player->GetZ()); - player->mana=24; + player->ConsumeMana(76); Inventory::AddItem("Flat Recovery Potion"s,5U); game->SetLoadoutItem(0,"Flat Recovery Potion"); testKey->bHeld=true; //Simulate key being pressed. - player->CheckAndPerformAbility(player->useItem1,testKeyboardInput); + player->CheckAndPerformAbility(player->GetItem1(),testKeyboardInput); 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. Assert::AreEqual(75,player->GetHealth(),L"Player Health is 75 after using Flat Recovery Potion."); @@ -158,11 +158,11 @@ namespace ItemTests } TEST_METHOD(PctRestoreScriptTest){ player->Hurt(75,player->OnUpperLevel(),player->GetZ()); - player->mana=24; + player->ConsumeMana(76); Inventory::AddItem("Pct Recovery Potion"s,5U); game->SetLoadoutItem(1,"Pct Recovery Potion"); testKey->bHeld=true; //Simulate key being pressed. - player->CheckAndPerformAbility(player->useItem2,testKeyboardInput); + player->CheckAndPerformAbility(player->GetItem2(),testKeyboardInput); game->SetElapsedTime(0.05f); game->OnUserUpdate(0.05f);//Wait some time as the item applies a buff that heals us. Assert::AreEqual(75,player->GetHealth(),L"Player Health is 75 after using Pct Recovery Potion."); @@ -173,7 +173,7 @@ namespace ItemTests Inventory::AddItem("Bandages"s,5U); game->SetLoadoutItem(2,"Bandages"); testKey->bHeld=true; //Simulate key being pressed. - player->CheckAndPerformAbility(player->useItem3,testKeyboardInput); + player->CheckAndPerformAbility(player->GetItem3(),testKeyboardInput); game->SetElapsedTime(0.05f); game->OnUserUpdate(0.05f);//Wait some time as the item applies a buff that heals us. Assert::AreEqual(30,player->GetHealth(),L"Player is immediately healed for 5 health points on Bandages use."); diff --git a/Adventures in Lestoria/Player.cpp b/Adventures in Lestoria/Player.cpp index 31255538..11406080 100644 --- a/Adventures in Lestoria/Player.cpp +++ b/Adventures in Lestoria/Player.cpp @@ -376,6 +376,7 @@ void Player::Update(float fElapsedTime){ if(allowed){ castPrepAbility->cooldown=castPrepAbility->GetCooldownTime(); ConsumeMana(castPrepAbility->manaCost); + OnAbilityUse(ability); } castInfo.castTimer=0; } @@ -1149,7 +1150,7 @@ void Player::CastSpell(Ability&ability){ castPosition=GetPos()+pointToCursor; } castInfo={ability.name,ability.precastInfo.castTime,ability.precastInfo.castTime,castPosition}; - if(ability.actionPerformedDuringCast){ability.action(this,castPosition);} + if(ability.actionPerformedDuringCast){ability.action(this,castPosition);OnAbilityUse(ability);} SetState(State::CASTING); } @@ -1812,6 +1813,7 @@ void Player::CheckAndPerformAbility(Ability&ability,InputGroup key){ ability.cooldown=ability.GetCooldownTime(); CancelCast(); ConsumeMana(ability.manaCost); + OnAbilityUse(ability); }else if(ability.precastInfo.precastTargetingRequired&&GetState()==State::NORMAL&&HasEnoughOfItem){ PrepareCast(ability); @@ -1915,4 +1917,29 @@ const float Player::GetDamageAmplificationMult()const{ const bool Player::HasEnchant(const std::string_view enchantName)const{ if(!ItemEnchantInfo::GetEnchants().count(std::string(enchantName)))ERR(std::format("WARNING! Enchantment {} does not exist in enchantment database!",enchantName)); return enchantList.count(std::string(enchantName)); +} + +void Player::OnAbilityUse(const Ability&ability){ + if(ability.itemAbility)ERR(std::format("WARNING! Somehow triggered an item ability called {} in OnAbilityUse Callback function. THIS SHOULD NOT BE HAPPENING!",ability.name)); + if(ability.name==GetRightClickAbility().name)return; + if(HasEnchant("Wizard's Soul")){ + const auto ReduceCooldown=[this,&ability](Ability&a){ + if(ability.name==a.name)return; + a.cooldown-="Wizard's Soul"_ENC["ABILITY COOLDOWN AMOUNT"]; + }; + ReduceCooldown(GetAbility1()); + ReduceCooldown(GetAbility2()); + ReduceCooldown(GetAbility3()); + ReduceCooldown(GetAbility4()); + } +} + +Ability&Player::GetItem1(){ + return useItem1; +} +Ability&Player::GetItem2(){ + return useItem2; +} +Ability&Player::GetItem3(){ + return useItem3; } \ No newline at end of file diff --git a/Adventures in Lestoria/Player.h b/Adventures in Lestoria/Player.h index f2aaa961..0dfaa25c 100644 --- a/Adventures in Lestoria/Player.h +++ b/Adventures in Lestoria/Player.h @@ -105,8 +105,6 @@ class Player{ friend class Inventory; friend class ItemInfo; friend void ItemOverlay::Draw(); - friend class PlayerTests::PlayerTest; - friend class ItemTests::ItemTest; public: Player(); //So this is rather fascinating and only exists because we have the ability to change classes which means we need to initialize a class @@ -245,6 +243,10 @@ public: void SetAnimationBasedOnTargetingDirection(const std::string_view animation_name,float targetDirection); void SetAnimationBasedOnTarget(const std::string_view animation_name,const vf2d&target); + Ability&GetItem1(); + Ability&GetItem2(); + Ability&GetItem3(); + void SetItem1UseFunc(Ability a); void SetItem2UseFunc(Ability a); void SetItem3UseFunc(Ability a); @@ -300,6 +302,7 @@ public: void ApplyDot(float duration,int damage,float timeBetweenTicks,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc=[](Player*p,Buff&b){}); const float GetDamageAmplificationMult()const; const bool HasEnchant(const std::string_view enchantName)const; + void CheckAndPerformAbility(Ability&ability,InputGroup key); private: int hp="Warrior.BaseHealth"_I; int mana="Player.BaseMana"_I; @@ -369,7 +372,6 @@ private: float lowHealthSoundPlayedTimer=0.f; float rangerShootAnimationTimer=0.f; Renderable minimapImg; //An image of the character represented on a minimap. Should be 12x12 and generally be a circle. - void CheckAndPerformAbility(Ability&ability,InputGroup key); float deadlyDashWaitTimer{}; float deadlyDashAfterDashTimer{}; vf2d deadlyDashEndingPos{}; @@ -378,6 +380,7 @@ private: std::unordered_setmyClass{}; float daggerThrowWaitTimer{INFINITY}; std::unordered_setenchantList; + void OnAbilityUse(const Ability&ability); //Callback when an ability successfully is used and has gone on cooldown. protected: const float ATTACK_COOLDOWN="Warrior.Auto Attack.Cooldown"_F; const float MAGIC_ATTACK_COOLDOWN="Wizard.Auto Attack.Cooldown"_F; diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 600f2934..f69ab94f 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 1 #define VERSION_MINOR 2 #define VERSION_PATCH 3 -#define VERSION_BUILD 10703 +#define VERSION_BUILD 10708 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 2cab8396..bff2cba1 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ