Add public Getters for loadout item functions. Implement Wizard's Soul Enchant. Release Build 10708.

mac-build
sigonasr2 7 months ago
parent 4ca3cf4426
commit 5dc46664eb
  1. 74
      Adventures in Lestoria Tests/EnchantTests.cpp
  2. 16
      Adventures in Lestoria Tests/ItemTests.cpp
  3. 29
      Adventures in Lestoria/Player.cpp
  4. 9
      Adventures in Lestoria/Player.h
  5. 2
      Adventures in Lestoria/Version.h
  6. BIN
      x64/Release/Adventures in Lestoria.exe

@ -70,7 +70,7 @@ namespace EnchantTests
std::unique_ptr<AiL>testGame; std::unique_ptr<AiL>testGame;
InputGroup testKeyboardInput; InputGroup testKeyboardInput;
Player*player; Player*player;
const HWButton*testKey; HWButton*testKey;
TEST_METHOD_INITIALIZE(PlayerInitialize){ TEST_METHOD_INITIALIZE(PlayerInitialize){
InitializeGameConfigurations(); InitializeGameConfigurations();
rng=std::mt19937{57189U};//Establish a fixed random seed on setup so the exact same results are generated every test run. 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."); 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_ptr<Item>nullRing{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.");
}
}; };
} }

@ -132,25 +132,25 @@ namespace ItemTests
Inventory::AddItem("Minor Health Potion"s,5U); Inventory::AddItem("Minor Health Potion"s,5U);
game->SetLoadoutItem(0,"Minor Health Potion"); game->SetLoadoutItem(0,"Minor Health Potion");
testKey->bHeld=true; //Simulate key being pressed. 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(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(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){ TEST_METHOD(ItemScriptBuffTest){
player->Hurt(1,player->OnUpperLevel(),player->GetZ()); player->Hurt(1,player->OnUpperLevel(),player->GetZ());
Inventory::AddItem("Stat Up Everything Potion"s,5U); Inventory::AddItem("Stat Up Everything Potion"s,5U);
game->SetLoadoutItem(0,"Stat Up Everything Potion"); game->SetLoadoutItem(0,"Stat Up Everything Potion");
testKey->bHeld=true; //Simulate key being pressed. testKey->bHeld=true; //Simulate key being pressed.
Assert::ExpectException<std::exception>([&](){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<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.");
} }
TEST_METHOD(FlatRestoreScriptTest){ TEST_METHOD(FlatRestoreScriptTest){
player->Hurt(75,player->OnUpperLevel(),player->GetZ()); player->Hurt(75,player->OnUpperLevel(),player->GetZ());
player->mana=24; player->ConsumeMana(76);
Inventory::AddItem("Flat Recovery Potion"s,5U); Inventory::AddItem("Flat Recovery Potion"s,5U);
game->SetLoadoutItem(0,"Flat Recovery Potion"); game->SetLoadoutItem(0,"Flat Recovery Potion");
testKey->bHeld=true; //Simulate key being pressed. testKey->bHeld=true; //Simulate key being pressed.
player->CheckAndPerformAbility(player->useItem1,testKeyboardInput); player->CheckAndPerformAbility(player->GetItem1(),testKeyboardInput);
game->SetElapsedTime(0.05f); 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. 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."); Assert::AreEqual(75,player->GetHealth(),L"Player Health is 75 after using Flat Recovery Potion.");
@ -158,11 +158,11 @@ namespace ItemTests
} }
TEST_METHOD(PctRestoreScriptTest){ TEST_METHOD(PctRestoreScriptTest){
player->Hurt(75,player->OnUpperLevel(),player->GetZ()); player->Hurt(75,player->OnUpperLevel(),player->GetZ());
player->mana=24; player->ConsumeMana(76);
Inventory::AddItem("Pct Recovery Potion"s,5U); Inventory::AddItem("Pct Recovery Potion"s,5U);
game->SetLoadoutItem(1,"Pct Recovery Potion"); game->SetLoadoutItem(1,"Pct Recovery Potion");
testKey->bHeld=true; //Simulate key being pressed. testKey->bHeld=true; //Simulate key being pressed.
player->CheckAndPerformAbility(player->useItem2,testKeyboardInput); player->CheckAndPerformAbility(player->GetItem2(),testKeyboardInput);
game->SetElapsedTime(0.05f); game->SetElapsedTime(0.05f);
game->OnUserUpdate(0.05f);//Wait some time as the item applies a buff that heals us. 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."); 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); Inventory::AddItem("Bandages"s,5U);
game->SetLoadoutItem(2,"Bandages"); game->SetLoadoutItem(2,"Bandages");
testKey->bHeld=true; //Simulate key being pressed. testKey->bHeld=true; //Simulate key being pressed.
player->CheckAndPerformAbility(player->useItem3,testKeyboardInput); player->CheckAndPerformAbility(player->GetItem3(),testKeyboardInput);
game->SetElapsedTime(0.05f); game->SetElapsedTime(0.05f);
game->OnUserUpdate(0.05f);//Wait some time as the item applies a buff that heals us. 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."); Assert::AreEqual(30,player->GetHealth(),L"Player is immediately healed for 5 health points on Bandages use.");

@ -376,6 +376,7 @@ void Player::Update(float fElapsedTime){
if(allowed){ if(allowed){
castPrepAbility->cooldown=castPrepAbility->GetCooldownTime(); castPrepAbility->cooldown=castPrepAbility->GetCooldownTime();
ConsumeMana(castPrepAbility->manaCost); ConsumeMana(castPrepAbility->manaCost);
OnAbilityUse(ability);
} }
castInfo.castTimer=0; castInfo.castTimer=0;
} }
@ -1149,7 +1150,7 @@ void Player::CastSpell(Ability&ability){
castPosition=GetPos()+pointToCursor; castPosition=GetPos()+pointToCursor;
} }
castInfo={ability.name,ability.precastInfo.castTime,ability.precastInfo.castTime,castPosition}; 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); SetState(State::CASTING);
} }
@ -1812,6 +1813,7 @@ void Player::CheckAndPerformAbility(Ability&ability,InputGroup key){
ability.cooldown=ability.GetCooldownTime(); ability.cooldown=ability.GetCooldownTime();
CancelCast(); CancelCast();
ConsumeMana(ability.manaCost); ConsumeMana(ability.manaCost);
OnAbilityUse(ability);
}else }else
if(ability.precastInfo.precastTargetingRequired&&GetState()==State::NORMAL&&HasEnoughOfItem){ if(ability.precastInfo.precastTargetingRequired&&GetState()==State::NORMAL&&HasEnoughOfItem){
PrepareCast(ability); PrepareCast(ability);
@ -1916,3 +1918,28 @@ 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)); 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)); 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;
}

@ -105,8 +105,6 @@ class Player{
friend class Inventory; friend class Inventory;
friend class ItemInfo; friend class ItemInfo;
friend void ItemOverlay::Draw(); friend void ItemOverlay::Draw();
friend class PlayerTests::PlayerTest;
friend class ItemTests::ItemTest;
public: public:
Player(); 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 //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 SetAnimationBasedOnTargetingDirection(const std::string_view animation_name,float targetDirection);
void SetAnimationBasedOnTarget(const std::string_view animation_name,const vf2d&target); void SetAnimationBasedOnTarget(const std::string_view animation_name,const vf2d&target);
Ability&GetItem1();
Ability&GetItem2();
Ability&GetItem3();
void SetItem1UseFunc(Ability a); void SetItem1UseFunc(Ability a);
void SetItem2UseFunc(Ability a); void SetItem2UseFunc(Ability a);
void SetItem3UseFunc(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){}); void ApplyDot(float duration,int damage,float timeBetweenTicks,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc=[](Player*p,Buff&b){});
const float GetDamageAmplificationMult()const; const float GetDamageAmplificationMult()const;
const bool HasEnchant(const std::string_view enchantName)const; const bool HasEnchant(const std::string_view enchantName)const;
void CheckAndPerformAbility(Ability&ability,InputGroup key);
private: private:
int hp="Warrior.BaseHealth"_I; int hp="Warrior.BaseHealth"_I;
int mana="Player.BaseMana"_I; int mana="Player.BaseMana"_I;
@ -369,7 +372,6 @@ private:
float lowHealthSoundPlayedTimer=0.f; float lowHealthSoundPlayedTimer=0.f;
float rangerShootAnimationTimer=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. 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 deadlyDashWaitTimer{};
float deadlyDashAfterDashTimer{}; float deadlyDashAfterDashTimer{};
vf2d deadlyDashEndingPos{}; vf2d deadlyDashEndingPos{};
@ -378,6 +380,7 @@ private:
std::unordered_set<std::string>myClass{}; std::unordered_set<std::string>myClass{};
float daggerThrowWaitTimer{INFINITY}; float daggerThrowWaitTimer{INFINITY};
std::unordered_set<std::string>enchantList; std::unordered_set<std::string>enchantList;
void OnAbilityUse(const Ability&ability); //Callback when an ability successfully is used and has gone on cooldown.
protected: protected:
const float ATTACK_COOLDOWN="Warrior.Auto Attack.Cooldown"_F; const float ATTACK_COOLDOWN="Warrior.Auto Attack.Cooldown"_F;
const float MAGIC_ATTACK_COOLDOWN="Wizard.Auto Attack.Cooldown"_F; const float MAGIC_ATTACK_COOLDOWN="Wizard.Auto Attack.Cooldown"_F;

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1 #define VERSION_MAJOR 1
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 3 #define VERSION_PATCH 3
#define VERSION_BUILD 10703 #define VERSION_BUILD 10708
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

Loading…
Cancel
Save