diff --git a/Adventures in Lestoria Tests/EnchantTests.cpp b/Adventures in Lestoria Tests/EnchantTests.cpp index 3e48d6d5..30592341 100644 --- a/Adventures in Lestoria Tests/EnchantTests.cpp +++ b/Adventures in Lestoria Tests/EnchantTests.cpp @@ -1073,5 +1073,21 @@ namespace EnchantTests player->Hurt(5,player->OnUpperLevel(),player->GetZ()); Assert::AreEqual(100,player->GetHealth(),L"Player should still be blocking at this time with Heavy Guard."); } + TEST_METHOD(AdvanceShieldNoEnchantCheck){ + testKey->bHeld=true; //Force the key to be held down for testing purposes. + player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput); + Assert::AreEqual(0U,player->GetShield(),L"Without the Advance Shield enchant, shield amount remains at 0."); + } + TEST_METHOD(AdvanceShieldEnchantCheck){ + testKey->bHeld=true; //Force the key to be held down for testing purposes. + std::weak_ptrnullRing{Inventory::AddItem("Null Ring"s)}; + Inventory::EquipItem(nullRing,EquipSlot::RING1); + nullRing.lock()->EnchantItem("Advance Shield"); + player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput); + Assert::AreEqual(int(player->GetMaxHealth()*0.2f),int(player->GetShield()),L"The Advance Shield enchant provides a 20% health player shield."); + game->SetElapsedTime(9.f); + game->OnUserUpdate(9.f); + Assert::AreEqual(0U,player->GetShield(),L"The Advance Shield enchant shield lasts 9 seconds. It should have worn off after that time."); + } }; } diff --git a/Adventures in Lestoria Tests/PlayerTests.cpp b/Adventures in Lestoria Tests/PlayerTests.cpp index 0e4d2c9e..db3fb61a 100644 --- a/Adventures in Lestoria Tests/PlayerTests.cpp +++ b/Adventures in Lestoria Tests/PlayerTests.cpp @@ -756,7 +756,7 @@ namespace PlayerTests } TEST_METHOD(PlayerAddShieldCheck){ player=testGame->GetPlayer(); - player->AddShield(60U,5.f,PlayerTimerType::ADVANCED_SHIELD_TIMER); + player->AddShield(60U,5.f,PlayerTimerType::ADVANCE_SHIELD_TIMER); Assert::AreEqual(60U,player->GetShield(),L"Player has 60 shield points."); testGame->SetElapsedTime(5.f); testGame->OnUserUpdate(5.f); @@ -764,7 +764,7 @@ namespace PlayerTests } TEST_METHOD(PlayerMultiShieldCheck){ player=testGame->GetPlayer(); - player->AddShield(60U,5.f,PlayerTimerType::ADVANCED_SHIELD_TIMER); + player->AddShield(60U,5.f,PlayerTimerType::ADVANCE_SHIELD_TIMER); player->AddShield(100U,2.f,PlayerTimerType::PLAYER_OUTLINE_TIMER); Assert::AreEqual(160U,player->GetShield(),L"Player has 160 shield points."); testGame->SetElapsedTime(2.f); @@ -776,7 +776,7 @@ namespace PlayerTests } TEST_METHOD(PlayerSubtractShieldCheck){ player=testGame->GetPlayer(); - player->AddShield(60U,5.f,PlayerTimerType::ADVANCED_SHIELD_TIMER); + player->AddShield(60U,5.f,PlayerTimerType::ADVANCE_SHIELD_TIMER); Assert::AreEqual(60U,player->GetShield(),L"Player has 60 shield points."); player->SubtractShield(40U); Assert::AreEqual(20U,player->GetShield(),L"Player has 20 shield points."); @@ -785,7 +785,7 @@ namespace PlayerTests } TEST_METHOD(PlayerDamageShieldCheck){ player=testGame->GetPlayer(); - player->AddShield(60U,5.f,PlayerTimerType::ADVANCED_SHIELD_TIMER); + player->AddShield(60U,5.f,PlayerTimerType::ADVANCE_SHIELD_TIMER); Assert::AreEqual(60U,player->GetShield(),L"Player has 60 shield points."); player->Hurt(20U,player->OnUpperLevel(),player->GetZ()); Assert::AreEqual(40U,player->GetShield(),L"Player has 40 shield points."); diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index 78a73502..03a81974 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -181,6 +181,8 @@ AiL::AiL(bool testingMode){ DEBUG_PATHFINDING="debug_pathfinding"_I; #pragma endregion + Warrior::ResetToOriginalAbilities(); + sAppName="GAME_NAME"_S; game=this; gameStarted=time(NULL); @@ -1126,7 +1128,7 @@ void AiL::RenderWorld(float fElapsedTime){ view.DrawPartialSquishedRotatedDecal(pos+vf2d{0,-player->GetZ()*(std::signbit(scale.y)?-1:1)},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale*scale,{1.f,player->ySquishFactor},playerCol); DrawAfterImage:view.DrawRotatedDecal(player->afterImagePos,player->afterImage.Decal(),0.f,player->afterImage.Sprite()->Size()/2,{player->GetSizeMult(),player->GetSizeMult()},{0xFFDCDA}); SetDecalMode(DecalMode::NORMAL); - if(player->GetState()==State::BLOCK){ + if(player->GetState()==State::BLOCK||player->GetShield()>0){ view.DrawDecal(player->GetPos()+vf2d{0,-player->GetZ()*(std::signbit(scale.y)?-1:1)}-vf2d{12,12},GFX["block.png"].Decal()); } @@ -2027,9 +2029,11 @@ void AiL::RenderHud(){ DrawDecal({2,2},GFX["heart_outline.png"].Decal(),{1.f,1.f},healthOutlineCol); const Decal*heartImg{GFX["heart.png"].Decal()}; if(player->GetShield()>0)heartImg=GFX["shield_heart.png"].Decal(); - DrawPartialDecal({2,2+(15-15*player->GetHealthRatio())},const_cast(heartImg),{},{17,15*player->GetHealthRatio()}); + float healthRatio{float(healthCounter.GetDisplayValue())/player->GetMaxHealth()}; + float manaRatio{float(manaCounter.GetDisplayValue())/player->GetMaxMana()}; + DrawPartialDecal({2,2+(15*(1-healthRatio))},const_cast(heartImg),{0.f,15*(1-healthRatio)},{17,15*healthRatio}); DrawDecal({2,20},GFX["mana_outline.png"].Decal()); - DrawPartialDecal({2,20+(15-15*player->GetManaRatio())},GFX["mana.png"].Decal(),{},{17,15*player->GetManaRatio()}); + DrawPartialDecal({2,20+(15*(1-manaRatio))},GFX["mana.png"].Decal(),{0.f,15*(1-manaRatio)},{17,15*manaRatio}); std::string text=player->GetHealth()>0?std::to_string(healthCounter.GetDisplayValue()+shieldCounter.GetDisplayValue()):"X"; std::string text_mana=std::to_string(manaCounter.GetDisplayValue()); @@ -2911,7 +2915,6 @@ const MapName&AiL::GetCurrentLevel()const{ } void AiL::ChangePlayerClass(Class cl){ - if(game->GetPlayer()->GetClass()==cl)return; Ability itemAbility1=player->useItem1; Ability itemAbility2=player->useItem2; Ability itemAbility3=player->useItem3; @@ -4515,6 +4518,12 @@ void AiL::UsingSteamAPI(const bool usingSteam){ void AiL::InitializePlayer(){ player=std::make_unique(); Player::moneyListeners.clear(); + Warrior::ability4=Ability{}; + Ranger::ability4=Ability{}; + Wizard::ability4=Ability{}; + Thief::ability4=Ability{}; + Trapper::ability4=Ability{}; + Witch::ability4=Ability{}; } void AiL::SetWorldZoom(float newZoomScale){ diff --git a/Adventures in Lestoria/DamageNumber.cpp b/Adventures in Lestoria/DamageNumber.cpp index 83d922e0..4d5a5fec 100644 --- a/Adventures in Lestoria/DamageNumber.cpp +++ b/Adventures in Lestoria/DamageNumber.cpp @@ -133,6 +133,10 @@ void DamageNumber::Draw(){ std::string text=std::to_string(damage); DrawDamageNumber(NumberScalesWithDamage,text,{0x888093,0x150035},{BLACK,{0,0,0,0}}); }break; + case SHIELD_LOSS:{ + std::string text=std::to_string(damage); + DrawDamageNumber(NumberScalesWithDamage,text,{DARK_BLUE,0x68d7ef},{BLUE,0x4141be}); + }break; default:ERR(std::format("Damage Number Type {} is not implemented! THIS SHOULD NOT BE HAPPENING!",int(type))); } } diff --git a/Adventures in Lestoria/DamageNumber.h b/Adventures in Lestoria/DamageNumber.h index 5f82b8f5..232d8404 100644 --- a/Adventures in Lestoria/DamageNumber.h +++ b/Adventures in Lestoria/DamageNumber.h @@ -47,6 +47,7 @@ namespace DamageNumberType{ CRIT, DOT, BACKSTAB, + SHIELD_LOSS, }; } diff --git a/Adventures in Lestoria/Player.cpp b/Adventures in Lestoria/Player.cpp index 3516af5d..37fdde84 100644 --- a/Adventures in Lestoria/Player.cpp +++ b/Adventures in Lestoria/Player.cpp @@ -942,9 +942,12 @@ bool Player::Hurt(int damage,bool onUpperLevel,float z,const TrueDamageFlag dama game->ShowDamageVignetteOverlay(vignetteOverlayCol); } + bool tookShieldDamage{false}; + if(tookLethalDamage&&survivedHitDueToDefiance)ApplyIframes("Death Defiance"_ENC["LETHAL DAMAGE SURVIVE IFRAME TIME"]); else{ if(GetShield()>0){ + tookShieldDamage=true; if(PlayHitSoundEffect)SoundEffect::PlaySFX("Warrior Block Hit",SoundEffect::CENTERED); SubtractShield(mod_dmg); } @@ -971,9 +974,11 @@ bool Player::Hurt(int damage,bool onUpperLevel,float z,const TrueDamageFlag dama }else{ if(lastHitTimer>0){ damageNumberPtr.get()->AddDamage(int(mod_dmg)); + if(tookShieldDamage)damageNumberPtr->SetType(DamageNumberType::SHIELD_LOSS); damageNumberPtr.get()->SetPauseTimer(0.4f); }else{ damageNumberPtr=std::make_shared(pos,int(mod_dmg),true); + if(tookShieldDamage)damageNumberPtr->SetType(DamageNumberType::SHIELD_LOSS); DAMAGENUMBER_LIST.push_back(damageNumberPtr); } lastHitTimer=0.05f; @@ -2163,13 +2168,13 @@ void Player::AddShield(const ShieldAmount shieldAmt,const float shieldTimer, con if(HasTimer(shieldType)){ auto shieldIt{std::find_if(shield.begin(),shield.end(),[&shieldType](const std::pair&shieldData){return shieldData.first==shieldType;})}; if(shieldIt!=shield.end()){ - std::pairshieldData{*shieldIt}; + std::pair&shieldData{*shieldIt}; shieldData.second=std::max(shieldData.second,shieldAmt); }else ERR(std::format("WARNING! The shield type {} does not have a corresponding entry! All shields when generated should have made one! THIS SHOULD NOT BE HAPPENING!",int(shieldType))); }else{ std::pair&newShield{shield.emplace_back(std::pair{shieldType,shieldAmt})}; if(shield.capacity()>SHIELD_CAPACITY)ERR(std::format("WARNING! Shield capacity limit has been reached! If you need more than {} shields, please expand the SHIELD_CAPACITY property of player!",SHIELD_CAPACITY)); - AddTimer(shieldType,Timer{std::format("Shield Type {}",int(shieldType)),shieldTimer,[newShield,this](){std::erase_if(shield,[&newShield](const std::pair&shieldData){return shieldData.first==newShield.first;});}}); + AddTimer(shieldType,Timer{std::format("Shield Type {}",int(shieldType)),shieldTimer,[&newShield,this](){newShield.second=0U;}}); } } Player::ShieldAmount Player::SubtractShield(const ShieldAmount shieldDamage){ diff --git a/Adventures in Lestoria/Player.h b/Adventures in Lestoria/Player.h index c7f3f557..8de37bde 100644 --- a/Adventures in Lestoria/Player.h +++ b/Adventures in Lestoria/Player.h @@ -411,7 +411,7 @@ private: const vf2d GetAimingLocation(bool useWalkDir=false,bool invert=false); std::unordered_maptimers; void RunTimers(); - float base_attack_range="Warrior.Auto Attack.Range"_F/100.f; + float base_attack_range="Warrior.Auto Attack.Range"_F; Renderable playerOutline; void UpdatePlayerOutline(); void OnBuffAdd(Buff&newBuff); diff --git a/Adventures in Lestoria/PlayerTimerType.h b/Adventures in Lestoria/PlayerTimerType.h index 9554d960..2a75a7e7 100644 --- a/Adventures in Lestoria/PlayerTimerType.h +++ b/Adventures in Lestoria/PlayerTimerType.h @@ -42,5 +42,5 @@ enum class PlayerTimerType{ ADRENALINE_STIM, PLAYER_OUTLINE_TIMER, OPPORTUNITY_SHOT_RANDOM_SPECIAL_MARK, - ADVANCED_SHIELD_TIMER, + ADVANCE_SHIELD_TIMER, }; \ No newline at end of file diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 2f45a33f..2c43ca99 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 11062 +#define VERSION_BUILD 11074 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/Warrior.cpp b/Adventures in Lestoria/Warrior.cpp index bb12c092..17eb8d4a 100644 --- a/Adventures in Lestoria/Warrior.cpp +++ b/Adventures in Lestoria/Warrior.cpp @@ -107,10 +107,15 @@ void Warrior::InitializeClassAbilities(){ [](Player*p,vf2d pos={}){ if(p->GetState()==State::NORMAL||p->GetState()==State::CASTING){ rightClickAbility.cooldown=rightClickAbility.COOLDOWN_TIME; - p->SetState(State::BLOCK); - p->blockTimer="Warrior.Right Click Ability.Duration"_F; - if(p->HasEnchant("Heavy Guard"))p->blockTimer*="Heavy Guard"_ENC["BLOCK DURATION MULT"]; - p->AddBuff(BuffType::BLOCK_SLOWDOWN,p->blockTimer,"Warrior.Right Click Ability.SlowAmt"_F); + float blockTime{"Warrior.Right Click Ability.Duration"_F}; + if(p->HasEnchant("Heavy Guard"))blockTime*="Heavy Guard"_ENC["BLOCK DURATION MULT"]; + if(p->HasEnchant("Advance Shield")){ + p->AddShield(p->GetMaxHealth()*"Advance Shield"_ENC["SHIELD AMOUNT"]/100.f,"Advance Shield"_ENC["SHIELD DURATION"],PlayerTimerType::ADVANCE_SHIELD_TIMER); + }else{ + p->blockTimer=blockTime; + p->SetState(State::BLOCK); + p->AddBuff(BuffType::BLOCK_SLOWDOWN,p->blockTimer,"Warrior.Right Click Ability.SlowAmt"_F); + } return true; } return false; diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index d6977670..2fef58eb 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ