Implemented Evasive Movement enchant. Added a player outline decal on a repeating timer. Release Build 10989.
This commit is contained in:
parent
012f5de2a1
commit
9df7016f2d
@ -682,13 +682,13 @@ namespace EnchantTests
|
|||||||
Assert::AreEqual(uint8_t(1),Thief::ability2.charges,L"Deadly Dash should be available to use again.");
|
Assert::AreEqual(uint8_t(1),Thief::ability2.charges,L"Deadly Dash should be available to use again.");
|
||||||
Assert::AreEqual(0.f,Thief::ability2.cooldown,L"Deadly Dash should no longer be on cooldown.");
|
Assert::AreEqual(0.f,Thief::ability2.cooldown,L"Deadly Dash should no longer be on cooldown.");
|
||||||
Assert::AreEqual(0,Thief::ability2.manaCost,L"Deadly Dash's mana cost should be zero.");
|
Assert::AreEqual(0,Thief::ability2.manaCost,L"Deadly Dash's mana cost should be zero.");
|
||||||
Assert::AreEqual("Deadly Mirage"_ENC["REACTIVATE TIMING WINDOW"],player->GetTimer(Player::TimerType::DEADLY_MIRAGE_SECOND_CAST).RemainingTime(),L"Deadly Mirage's second cast timer should have started.");
|
Assert::AreEqual("Deadly Mirage"_ENC["REACTIVATE TIMING WINDOW"],player->GetTimer(PlayerTimerType::DEADLY_MIRAGE_SECOND_CAST).RemainingTime(),L"Deadly Mirage's second cast timer should have started.");
|
||||||
player->SetState(State::NORMAL);
|
player->SetState(State::NORMAL);
|
||||||
player->CheckAndPerformAbility(player->GetAbility2(),testKeyboardInput);
|
player->CheckAndPerformAbility(player->GetAbility2(),testKeyboardInput);
|
||||||
Assert::AreEqual(uint8_t(0),Thief::ability2.charges,L"Deadly Dash should have been used up.");
|
Assert::AreEqual(uint8_t(0),Thief::ability2.charges,L"Deadly Dash should have been used up.");
|
||||||
Assert::AreEqual("Thief.Ability 2.Cooldown"_F,Thief::ability2.cooldown,L"Deadly Dash should now be on cooldown");
|
Assert::AreEqual("Thief.Ability 2.Cooldown"_F,Thief::ability2.cooldown,L"Deadly Dash should now be on cooldown");
|
||||||
Assert::AreEqual("Thief.Ability 2.Mana Cost"_I,Thief::ability2.manaCost,L"Deadly Dash's mana cost is back to normal.");
|
Assert::AreEqual("Thief.Ability 2.Mana Cost"_I,Thief::ability2.manaCost,L"Deadly Dash's mana cost is back to normal.");
|
||||||
Assert::AreEqual(true,player->GetTimer(Player::TimerType::DEADLY_MIRAGE_SECOND_CAST).IsDone(),L"Deadly Mirage's second cast timer should have been cancelled.");
|
Assert::AreEqual(true,player->GetTimer(PlayerTimerType::DEADLY_MIRAGE_SECOND_CAST).IsDone(),L"Deadly Mirage's second cast timer should have been cancelled.");
|
||||||
Thief::ability2.charges=1;
|
Thief::ability2.charges=1;
|
||||||
Thief::ability2.cooldown=0.f;
|
Thief::ability2.cooldown=0.f;
|
||||||
player->RestoreMana(100);
|
player->RestoreMana(100);
|
||||||
@ -750,5 +750,19 @@ namespace EnchantTests
|
|||||||
Assert::AreEqual(110,player->GetAttack(),L"Bloodlust's bonus attacks stack only to 10.");
|
Assert::AreEqual(110,player->GetAttack(),L"Bloodlust's bonus attacks stack only to 10.");
|
||||||
Assert::AreEqual("Thief.Ability 3.Duration"_F+"Bloodlust"_ENC["BUFF TIMER INCREASE"]*30,player->GetBuffs(BuffType::ADRENALINE_RUSH)[0].duration,L"Bloodlust's duration increases per kill.");
|
Assert::AreEqual("Thief.Ability 3.Duration"_F+"Bloodlust"_ENC["BUFF TIMER INCREASE"]*30,player->GetBuffs(BuffType::ADRENALINE_RUSH)[0].duration,L"Bloodlust's duration increases per kill.");
|
||||||
}
|
}
|
||||||
|
TEST_METHOD(EvasiveMovementCheck){
|
||||||
|
testKey->bHeld=true; //Force the key to be held down for testing purposes.
|
||||||
|
game->ChangePlayerClass(THIEF);
|
||||||
|
player=game->GetPlayer();
|
||||||
|
player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput);
|
||||||
|
Assert::AreEqual(size_t(0),player->GetBuffs(BuffType::DAMAGE_REDUCTION).size(),L"Roll doesn't give a damage reduction buff.");
|
||||||
|
player->GetRightClickAbility().charges=1;
|
||||||
|
std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)};
|
||||||
|
Inventory::EquipItem(nullRing,EquipSlot::RING1);
|
||||||
|
nullRing.lock()->EnchantItem("Evasive Movement");
|
||||||
|
player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput);
|
||||||
|
Assert::AreEqual(size_t(1),player->GetBuffs(BuffType::DAMAGE_REDUCTION).size(),L"Roll gives a damage reduction buff.");
|
||||||
|
Assert::AreEqual("Evasive Movement"_ENC["DAMAGE REDUCTION PCT"]/100.f,player->GetDamageReductionFromBuffs(),L"Evasive Movement provides 50% damage reduction.");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -582,6 +582,10 @@
|
|||||||
<ClInclude Include="olcUTIL_Geometry2D.h" />
|
<ClInclude Include="olcUTIL_Geometry2D.h" />
|
||||||
<ClInclude Include="Pathfinding.h" />
|
<ClInclude Include="Pathfinding.h" />
|
||||||
<ClInclude Include="Player.h" />
|
<ClInclude Include="Player.h" />
|
||||||
|
<ClInclude Include="PlayerTimerType.h">
|
||||||
|
<SubType>
|
||||||
|
</SubType>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="PopupMenuLabel.h">
|
<ClInclude Include="PopupMenuLabel.h">
|
||||||
<SubType>
|
<SubType>
|
||||||
</SubType>
|
</SubType>
|
||||||
|
@ -231,9 +231,6 @@
|
|||||||
<ClInclude Include="MenuAnimatedIconToggleButton.h">
|
<ClInclude Include="MenuAnimatedIconToggleButton.h">
|
||||||
<Filter>Header Files\Interface</Filter>
|
<Filter>Header Files\Interface</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Toggleable.h">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ConnectionPoint.h">
|
<ClInclude Include="ConnectionPoint.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -678,8 +675,14 @@
|
|||||||
<ClInclude Include="ItemEnchant.h">
|
<ClInclude Include="ItemEnchant.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="PlayerTimerType.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Toggleable.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="Timer.h">
|
<ClInclude Include="Timer.h">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1118,11 +1118,14 @@ void AiL::RenderWorld(float fElapsedTime){
|
|||||||
const std::vector<Buff>attackBuffs{player->GetStatBuffs({"Attack","Attack %"})};
|
const std::vector<Buff>attackBuffs{player->GetStatBuffs({"Attack","Attack %"})};
|
||||||
const std::vector<Buff>movespeedBuffs{player->GetBuffs(BuffType::SPEEDBOOST)};
|
const std::vector<Buff>movespeedBuffs{player->GetBuffs(BuffType::SPEEDBOOST)};
|
||||||
const std::vector<Buff>adrenalineRushBuffs{player->GetBuffs(BuffType::ADRENALINE_RUSH)};
|
const std::vector<Buff>adrenalineRushBuffs{player->GetBuffs(BuffType::ADRENALINE_RUSH)};
|
||||||
|
const std::vector<Buff>damageReductionBuffs{player->GetBuffs(BuffType::DAMAGE_REDUCTION)};
|
||||||
|
|
||||||
Pixel playerCol{WHITE};
|
Pixel playerCol{WHITE};
|
||||||
if(attackBuffs.size()>0)playerCol={255,uint8_t(255*abs(sin(1.4f*attackBuffs[0].duration))),uint8_t(255*abs(sin(1.4f*attackBuffs[0].duration)))};
|
if(attackBuffs.size()>0)playerCol={255,uint8_t(255*abs(sin(1.4f*attackBuffs[0].duration))),uint8_t(255*abs(sin(1.4f*attackBuffs[0].duration)))};
|
||||||
else if(adrenalineRushBuffs.size()>0)playerCol={uint8_t(255*abs(sin(6.f*adrenalineRushBuffs[0].duration))),255,uint8_t(255*abs(sin(6.f*adrenalineRushBuffs[0].duration)))};
|
else if(adrenalineRushBuffs.size()>0)playerCol={uint8_t(255*abs(sin(6.f*adrenalineRushBuffs[0].duration))),255,uint8_t(255*abs(sin(6.f*adrenalineRushBuffs[0].duration)))};
|
||||||
else if(movespeedBuffs.size()>0)playerCol={uint8_t(255*abs(sin(2.f*movespeedBuffs[0].duration))),255,uint8_t(255*abs(sin(2.f*movespeedBuffs[0].duration)))};
|
else if(movespeedBuffs.size()>0)playerCol={uint8_t(255*abs(sin(2.f*movespeedBuffs[0].duration))),255,uint8_t(255*abs(sin(2.f*movespeedBuffs[0].duration)))};
|
||||||
|
|
||||||
|
if(damageReductionBuffs.size()>0)view.DrawPartialSquishedRotatedDecal(pos+vf2d{0,-player->GetZ()*(std::signbit(scale.y)?-1:1)},player->playerOutline.Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale*scale+0.1f,{1.f,player->ySquishFactor},{210,210,210,uint8_t(util::lerp(0,255,abs(sin((PI*GetRunTime())/1.25f))))});
|
||||||
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);
|
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});
|
DrawAfterImage:view.DrawRotatedDecal(player->afterImagePos,player->afterImage.Decal(),0.f,player->afterImage.Sprite()->Size()/2,{player->GetSizeMult(),player->GetSizeMult()},{0xFFDCDA});
|
||||||
SetDecalMode(DecalMode::NORMAL);
|
SetDecalMode(DecalMode::NORMAL);
|
||||||
|
@ -120,6 +120,9 @@ void Player::Initialize(){
|
|||||||
p.a=0;
|
p.a=0;
|
||||||
}
|
}
|
||||||
afterImage.Decal()->Update();
|
afterImage.Decal()->Update();
|
||||||
|
playerOutline.Create(24,24);
|
||||||
|
|
||||||
|
AddTimer(PlayerTimerType::PLAYER_OUTLINE_TIMER,Timer{"Player Outline Update Timer",0.05f,[&](){UpdatePlayerOutline();},Timer::REPEAT});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::InitializeMinimapImage(){
|
void Player::InitializeMinimapImage(){
|
||||||
@ -1083,21 +1086,26 @@ void Player::UpdateIdleAnimation(Key direction){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Player::AddBuff(BuffType type,float duration,float intensity){
|
void Player::AddBuff(BuffType type,float duration,float intensity){
|
||||||
buffList.push_back(Buff{this,type,duration,intensity});
|
Buff&newBuff{buffList.emplace_back(Buff{this,type,duration,intensity})};
|
||||||
|
OnBuffAdd(newBuff);
|
||||||
}
|
}
|
||||||
void Player::AddBuff(BuffType type,float duration,float intensity,std::set<ItemAttribute>attr){
|
void Player::AddBuff(BuffType type,float duration,float intensity,std::set<ItemAttribute>attr){
|
||||||
if(type==STAT_UP)std::for_each(attr.begin(),attr.end(),[](const ItemAttribute&attr){if(attr.ActualName()!="Health"&&attr.ActualName()!="Health %"&&attr.ActualName()!="Attack"&&attr.ActualName()!="Attack %"&&attr.ActualName()!="Defense"&&attr.ActualName()!="Defense %"&&attr.ActualName()!="CDR"&&attr.ActualName()!="Move Spd %")ERR(std::format("WARNING! Stat Up Attribute type {} is NOT IMPLEMENTED!",attr.ActualName()));});
|
if(type==STAT_UP)std::for_each(attr.begin(),attr.end(),[](const ItemAttribute&attr){if(attr.ActualName()!="Health"&&attr.ActualName()!="Health %"&&attr.ActualName()!="Attack"&&attr.ActualName()!="Attack %"&&attr.ActualName()!="Defense"&&attr.ActualName()!="Defense %"&&attr.ActualName()!="CDR"&&attr.ActualName()!="Move Spd %")ERR(std::format("WARNING! Stat Up Attribute type {} is NOT IMPLEMENTED!",attr.ActualName()));});
|
||||||
buffList.push_back(Buff{this,type,duration,intensity,attr});
|
Buff&newBuff{buffList.emplace_back(Buff{this,type,duration,intensity,attr})};
|
||||||
|
OnBuffAdd(newBuff);
|
||||||
}
|
}
|
||||||
void Player::AddBuff(BuffType type,float duration,float intensity,std::set<std::string>attr){
|
void Player::AddBuff(BuffType type,float duration,float intensity,std::set<std::string>attr){
|
||||||
if(type==STAT_UP)std::for_each(attr.begin(),attr.end(),[](const std::string&attr){if(attr!="Health"&&attr!="Health %"&&attr!="Attack"&&attr!="Attack %"&&attr!="Defense"&&attr!="Defense %"&&attr!="CDR"&&attr!="Move Spd %")ERR(std::format("WARNING! Stat Up Attribute type {} is NOT IMPLEMENTED!",attr));});
|
if(type==STAT_UP)std::for_each(attr.begin(),attr.end(),[](const std::string&attr){if(attr!="Health"&&attr!="Health %"&&attr!="Attack"&&attr!="Attack %"&&attr!="Defense"&&attr!="Defense %"&&attr!="CDR"&&attr!="Move Spd %")ERR(std::format("WARNING! Stat Up Attribute type {} is NOT IMPLEMENTED!",attr));});
|
||||||
buffList.push_back(Buff{this,type,duration,intensity,attr});
|
Buff&newBuff{buffList.emplace_back(Buff{this,type,duration,intensity,attr})};
|
||||||
|
OnBuffAdd(newBuff);
|
||||||
}
|
}
|
||||||
void Player::AddBuff(BuffRestorationType type,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks){
|
void Player::AddBuff(BuffRestorationType type,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks){
|
||||||
buffList.push_back(Buff{this,type,overTimeType,duration,intensity,timeBetweenTicks});
|
Buff&newBuff{buffList.emplace_back(Buff{this,type,overTimeType,duration,intensity,timeBetweenTicks})};
|
||||||
|
OnBuffAdd(newBuff);
|
||||||
}
|
}
|
||||||
void Player::AddBuff(BuffRestorationType type,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc){
|
void Player::AddBuff(BuffRestorationType type,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc){
|
||||||
buffList.push_back(Buff{this,type,overTimeType,duration,intensity,timeBetweenTicks,expireCallbackFunc});
|
Buff&newBuff{buffList.emplace_back(Buff{this,type,overTimeType,duration,intensity,timeBetweenTicks,expireCallbackFunc})};
|
||||||
|
OnBuffAdd(newBuff);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::OnUpperLevel(){
|
bool Player::OnUpperLevel(){
|
||||||
@ -1408,7 +1416,8 @@ const float Player::GetDamageReductionFromBuffs()const{
|
|||||||
for(const Buff&b:GetBuffs(BuffType::DAMAGE_REDUCTION)){
|
for(const Buff&b:GetBuffs(BuffType::DAMAGE_REDUCTION)){
|
||||||
dmgReduction+=b.intensity;
|
dmgReduction+=b.intensity;
|
||||||
}
|
}
|
||||||
dmgReduction+=GetDamageReductionPct();
|
dmgReduction+=GetEquipStat("Damage Reduction")/100.f;
|
||||||
|
if(LastReserveEnchantConditionsMet())dmgReduction+="Last Reserve"_ENC["DAMAGE REDUCTION PCT"]/100.f;
|
||||||
return std::min(0.75f,dmgReduction);
|
return std::min(0.75f,dmgReduction);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1575,13 +1584,6 @@ void Player::PerformHPRecovery(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const float Player::GetDamageReductionPct()const{
|
|
||||||
float modDmgReductionPct=0;
|
|
||||||
modDmgReductionPct+=GetEquipStat("Damage Reduction")/100.f;
|
|
||||||
if(LastReserveEnchantConditionsMet())modDmgReductionPct+="Last Reserve"_ENC["DAMAGE REDUCTION PCT"]/100.f;
|
|
||||||
return modDmgReductionPct;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::AddXP(const uint64_t xpGain){
|
void Player::AddXP(const uint64_t xpGain){
|
||||||
currentLevelXP+=xpGain;
|
currentLevelXP+=xpGain;
|
||||||
totalXPEarned+=xpGain;
|
totalXPEarned+=xpGain;
|
||||||
@ -1982,7 +1984,7 @@ void Player::OnAbilityUse(const Ability&ability){
|
|||||||
Thief::ability2.charges++;
|
Thief::ability2.charges++;
|
||||||
Thief::ability2.manaCost=0;
|
Thief::ability2.manaCost=0;
|
||||||
Thief::ability2.cooldown=0.f;
|
Thief::ability2.cooldown=0.f;
|
||||||
AddTimer(TimerType::DEADLY_MIRAGE_SECOND_CAST,Timer{"Deadly Mirage Second Cast","Deadly Mirage"_ENC["REACTIVATE TIMING WINDOW"],[](){
|
AddTimer(PlayerTimerType::DEADLY_MIRAGE_SECOND_CAST,Timer{"Deadly Mirage Second Cast","Deadly Mirage"_ENC["REACTIVATE TIMING WINDOW"],[](){
|
||||||
Thief::ability2.manaCost="Thief.Ability 2.Mana Cost"_I;
|
Thief::ability2.manaCost="Thief.Ability 2.Mana Cost"_I;
|
||||||
Thief::ability2.cooldown="Thief.Ability 2.Cooldown"_F;
|
Thief::ability2.cooldown="Thief.Ability 2.Cooldown"_F;
|
||||||
Thief::ability2.charges--;
|
Thief::ability2.charges--;
|
||||||
@ -1991,7 +1993,7 @@ void Player::OnAbilityUse(const Ability&ability){
|
|||||||
if(!IsFirstDash){
|
if(!IsFirstDash){
|
||||||
Thief::ability2.manaCost="Thief.Ability 2.Mana Cost"_I;
|
Thief::ability2.manaCost="Thief.Ability 2.Mana Cost"_I;
|
||||||
Thief::ability2.cooldown="Thief.Ability 2.Cooldown"_F;
|
Thief::ability2.cooldown="Thief.Ability 2.Cooldown"_F;
|
||||||
CancelTimer(TimerType::DEADLY_MIRAGE_SECOND_CAST);
|
CancelTimer(PlayerTimerType::DEADLY_MIRAGE_SECOND_CAST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2056,18 +2058,18 @@ const bool Player::HasEnchantWithAbilityAffected(const std::string_view abilityN
|
|||||||
return enchantAbilityList.count(std::string(abilityName));
|
return enchantAbilityList.count(std::string(abilityName));
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer&Player::AddTimer(const TimerType type,const Timer&timer){
|
Timer&Player::AddTimer(const PlayerTimerType type,const Timer&timer){
|
||||||
auto timerReturnResult{timers.insert({type,timer})};
|
auto timerReturnResult{timers.insert({type,timer})};
|
||||||
Timer&newTimer{(*(timerReturnResult.first)).second};
|
Timer&newTimer{(*(timerReturnResult.first)).second};
|
||||||
newTimer=timer;
|
newTimer=timer;
|
||||||
return newTimer;
|
return newTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer&Player::GetTimer(const TimerType type){
|
Timer&Player::GetTimer(const PlayerTimerType type){
|
||||||
return timers.at(type);
|
return timers.at(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::CancelTimer(const TimerType type){
|
void Player::CancelTimer(const PlayerTimerType type){
|
||||||
GetTimer(type).Cancel();
|
GetTimer(type).Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2080,3 +2082,21 @@ void Player::RunTimers(){
|
|||||||
void Player::ResetTimers(){
|
void Player::ResetTimers(){
|
||||||
timers.clear();
|
timers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::UpdatePlayerOutline(){
|
||||||
|
if(GetBuffs(BuffType::DAMAGE_REDUCTION).size()>0){
|
||||||
|
game->SetDrawTarget(playerOutline.Sprite());
|
||||||
|
game->Clear(BLANK);
|
||||||
|
for(int32_t y:std::ranges::iota_view(0,game->GetDrawTargetHeight())){
|
||||||
|
for(int32_t x:std::ranges::iota_view(0,game->GetDrawTargetWidth())){
|
||||||
|
if(animation.GetFrame(internal_animState).GetSourceImage()->Sprite()->GetPixel(x,y)!=BLANK)game->GetDrawTarget()->SetPixel(x,y,WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
playerOutline.Decal()->Update();
|
||||||
|
game->SetDrawTarget(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::OnBuffAdd(Buff&newBuff){
|
||||||
|
if(newBuff.type==DAMAGE_REDUCTION)UpdatePlayerOutline();
|
||||||
|
}
|
@ -49,6 +49,7 @@ All rights reserved.
|
|||||||
#include "Item.h"
|
#include "Item.h"
|
||||||
#include "AttributableStat.h"
|
#include "AttributableStat.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
#include "PlayerTimerType.h"
|
||||||
|
|
||||||
|
|
||||||
#undef GetClassName
|
#undef GetClassName
|
||||||
@ -107,10 +108,6 @@ class Player{
|
|||||||
friend class ItemInfo;
|
friend class ItemInfo;
|
||||||
friend void ItemOverlay::Draw();
|
friend void ItemOverlay::Draw();
|
||||||
public:
|
public:
|
||||||
enum class TimerType{
|
|
||||||
DEADLY_MIRAGE_SECOND_CAST,
|
|
||||||
ADRENALINE_STIM,
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
||||||
@ -144,7 +141,6 @@ public:
|
|||||||
const float GetHPRecoveryPct()const;
|
const float GetHPRecoveryPct()const;
|
||||||
const float GetHP6RecoveryPct()const;
|
const float GetHP6RecoveryPct()const;
|
||||||
const float GetHP4RecoveryPct()const;
|
const float GetHP4RecoveryPct()const;
|
||||||
const float GetDamageReductionPct()const;
|
|
||||||
const float GetAttackRecoveryRateReduction()const;
|
const float GetAttackRecoveryRateReduction()const;
|
||||||
void SetSizeMult(float size);
|
void SetSizeMult(float size);
|
||||||
float GetAttackRange(); //Returns the player's attack range in units. Divide by 100 for number of tiles.
|
float GetAttackRange(); //Returns the player's attack range in units. Divide by 100 for number of tiles.
|
||||||
@ -315,9 +311,9 @@ public:
|
|||||||
const int RemainingRapidFireShots()const;
|
const int RemainingRapidFireShots()const;
|
||||||
const std::vector<std::reference_wrapper<Ability>>GetAbilities();//Returns player defensive, core abilities (1-4) and item abilities.
|
const std::vector<std::reference_wrapper<Ability>>GetAbilities();//Returns player defensive, core abilities (1-4) and item abilities.
|
||||||
const bool HasEnchantWithAbilityAffected(const std::string_view abilityName)const; //Returns whether or not the player has an enchant that affects the provided name.
|
const bool HasEnchantWithAbilityAffected(const std::string_view abilityName)const; //Returns whether or not the player has an enchant that affects the provided name.
|
||||||
Timer&AddTimer(const TimerType type,const Timer&timer);
|
Timer&AddTimer(const PlayerTimerType type,const Timer&timer);
|
||||||
Timer&GetTimer(const TimerType type);
|
Timer&GetTimer(const PlayerTimerType type);
|
||||||
void CancelTimer(const TimerType type);
|
void CancelTimer(const PlayerTimerType type);
|
||||||
void ResetTimers();
|
void ResetTimers();
|
||||||
private:
|
private:
|
||||||
int hp="Warrior.BaseHealth"_I;
|
int hp="Warrior.BaseHealth"_I;
|
||||||
@ -401,9 +397,12 @@ private:
|
|||||||
const bool LastReserveEnchantConditionsMet()const;
|
const bool LastReserveEnchantConditionsMet()const;
|
||||||
float poisonArrowLastParticleTimer{};
|
float poisonArrowLastParticleTimer{};
|
||||||
const vf2d GetAimingLocation(bool useWalkDir=false,bool invert=false);
|
const vf2d GetAimingLocation(bool useWalkDir=false,bool invert=false);
|
||||||
std::unordered_map<TimerType,Timer>timers;
|
std::unordered_map<PlayerTimerType,Timer>timers;
|
||||||
void RunTimers();
|
void RunTimers();
|
||||||
float base_attack_range="Warrior.Auto Attack.Range"_F/100.f;
|
float base_attack_range="Warrior.Auto Attack.Range"_F/100.f;
|
||||||
|
Renderable playerOutline;
|
||||||
|
void UpdatePlayerOutline();
|
||||||
|
void OnBuffAdd(Buff&newBuff);
|
||||||
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;
|
||||||
|
44
Adventures in Lestoria/PlayerTimerType.h
Normal file
44
Adventures in Lestoria/PlayerTimerType.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#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 © 2024 The FreeType
|
||||||
|
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||||
|
All rights reserved.
|
||||||
|
*/
|
||||||
|
#pragma endregion
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum class PlayerTimerType{
|
||||||
|
DEADLY_MIRAGE_SECOND_CAST,
|
||||||
|
ADRENALINE_STIM,
|
||||||
|
PLAYER_OUTLINE_TIMER,
|
||||||
|
};
|
@ -128,6 +128,8 @@ void Thief::InitializeClassAbilities(){
|
|||||||
float iframeTime{originalIframeTime};
|
float iframeTime{originalIframeTime};
|
||||||
if(p->HasEnchant("Tumble"))iframeTime+=originalIframeTime*"Tumble"_ENC["BOOST PERCENTAGE"]/100.f;
|
if(p->HasEnchant("Tumble"))iframeTime+=originalIframeTime*"Tumble"_ENC["BOOST PERCENTAGE"]/100.f;
|
||||||
|
|
||||||
|
if(p->HasEnchant("Evasive Movement"))p->AddBuff(BuffType::DAMAGE_REDUCTION,"Evasive Movement"_ENC["DAMAGE REDUCTION DURATION"],"Evasive Movement"_ENC["DAMAGE REDUCTION PCT"]/100.f);
|
||||||
|
|
||||||
p->ApplyIframes(iframeTime);
|
p->ApplyIframes(iframeTime);
|
||||||
p->footstepTimer=0.f;
|
p->footstepTimer=0.f;
|
||||||
return true;
|
return true;
|
||||||
@ -175,7 +177,7 @@ void Thief::InitializeClassAbilities(){
|
|||||||
if(p->HasEnchant("Adrenaline Stim"))adrenalineRushDuration="Adrenaline Stim"_ENC["NEW ADRENALINE RUSH DURATION"];
|
if(p->HasEnchant("Adrenaline Stim"))adrenalineRushDuration="Adrenaline Stim"_ENC["NEW ADRENALINE RUSH DURATION"];
|
||||||
|
|
||||||
p->AddBuff(BuffType::ADRENALINE_RUSH,adrenalineRushDuration,0.f);
|
p->AddBuff(BuffType::ADRENALINE_RUSH,adrenalineRushDuration,0.f);
|
||||||
p->AddTimer(TimerType::ADRENALINE_STIM,Timer{"Adrenaline Stim Extra Sound Timer",0.3f,[](){SoundEffect::PlaySFX("Adrenaline Rush High Pitch",SoundEffect::CENTERED);},Timer::MANUAL});
|
p->AddTimer(PlayerTimerType::ADRENALINE_STIM,Timer{"Adrenaline Stim Extra Sound Timer",0.3f,[](){SoundEffect::PlaySFX("Adrenaline Rush High Pitch",SoundEffect::CENTERED);},Timer::MANUAL});
|
||||||
|
|
||||||
int healthCost{};
|
int healthCost{};
|
||||||
if(p->HasEnchant("Adrenaline Stim"))healthCost=p->GetMaxHealth()*("Adrenaline Stim"_ENC["HEALTH PCT COST"]/100.f);
|
if(p->HasEnchant("Adrenaline Stim"))healthCost=p->GetMaxHealth()*("Adrenaline Stim"_ENC["HEALTH PCT COST"]/100.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 10981
|
#define VERSION_BUILD 10989
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user