Add in Curse and coin debuffs. Add in Pirate's Treasure spawn and collision check for placing and removing the curse. Adding buffs to the player will not immediately apply them but put them in a buff list to be applied on the next tick. AddBuff now returns the buff. GetOrAddBuff now properly uses the AddBuff function to add a buff to avoid any behavior discrepancies. Added a new test to check for buffs to be added. Fixed unit tests that broke due to waiting an extra game tick to apply buffs. 222/222 Tests Passing. Release Build 12049.
This commit is contained in:
parent
ded7e53fd7
commit
e1575081ce
@ -120,6 +120,7 @@ namespace BuffTests
|
|||||||
TEST_METHOD(AddBuffPlayerCallbackExpireFunctionTest){
|
TEST_METHOD(AddBuffPlayerCallbackExpireFunctionTest){
|
||||||
Assert::AreEqual(size_t(0),game->GetPlayer()->GetBuffs(BuffType::AFFECTED_BY_LIGHTNING_BOLT).size(),L"Player does not have any lightning bolt affected buffs when spawning.");
|
Assert::AreEqual(size_t(0),game->GetPlayer()->GetBuffs(BuffType::AFFECTED_BY_LIGHTNING_BOLT).size(),L"Player does not have any lightning bolt affected buffs when spawning.");
|
||||||
game->GetPlayer()->AddBuff(BuffType::AFFECTED_BY_LIGHTNING_BOLT,3.f,1,[](Player*attachedTarget,Buff&b){attachedTarget->Hurt(5,attachedTarget->OnUpperLevel(),attachedTarget->GetZ());});
|
game->GetPlayer()->AddBuff(BuffType::AFFECTED_BY_LIGHTNING_BOLT,3.f,1,[](Player*attachedTarget,Buff&b){attachedTarget->Hurt(5,attachedTarget->OnUpperLevel(),attachedTarget->GetZ());});
|
||||||
|
Game::Update(0.f);
|
||||||
Assert::AreEqual(size_t(1),game->GetPlayer()->GetBuffs(BuffType::AFFECTED_BY_LIGHTNING_BOLT).size(),L"Player is now affected By Lightning Bolt buff. Should get hurt for 5 damage in 3 seconds...");
|
Assert::AreEqual(size_t(1),game->GetPlayer()->GetBuffs(BuffType::AFFECTED_BY_LIGHTNING_BOLT).size(),L"Player is now affected By Lightning Bolt buff. Should get hurt for 5 damage in 3 seconds...");
|
||||||
Game::Update(0.f);
|
Game::Update(0.f);
|
||||||
Game::Update(3.f);
|
Game::Update(3.f);
|
||||||
@ -146,20 +147,27 @@ namespace BuffTests
|
|||||||
}
|
}
|
||||||
TEST_METHOD(PlayerHasBuffFunctionTest){
|
TEST_METHOD(PlayerHasBuffFunctionTest){
|
||||||
Assert::AreEqual(false,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should not have a speedboost buff before being given one.");
|
Assert::AreEqual(false,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should not have a speedboost buff before being given one.");
|
||||||
game->GetPlayer()->AddBuff(BuffType::ADRENALINE_RUSH,1.f,1.f);
|
Game::AddBuffToPlayer(BuffType::ADRENALINE_RUSH,1.f,1.f);
|
||||||
Assert::AreEqual(false,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should not have a speedboost buff when given an unrelated buff.");
|
Assert::AreEqual(false,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should not have a speedboost buff when given an unrelated buff.");
|
||||||
game->GetPlayer()->AddBuff(BuffType::SPEEDBOOST,1.f,1.f);
|
Game::AddBuffToPlayer(BuffType::SPEEDBOOST,1.f,1.f);
|
||||||
Assert::AreEqual(true,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should now have a speedboost buff.");
|
Assert::AreEqual(true,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should now have a speedboost buff.");
|
||||||
game->GetPlayer()->AddBuff(BuffType::SPEEDBOOST,2.f,1.f);
|
Game::AddBuffToPlayer(BuffType::SPEEDBOOST,2.f,1.f);
|
||||||
Assert::AreEqual(true,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should still report having a speedboost buff.");
|
Assert::AreEqual(true,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should still report having a speedboost buff.");
|
||||||
Game::Update(0.f);
|
Game::Update(0.f);
|
||||||
Game::Update(1.f);
|
Game::Update(1.f);
|
||||||
Assert::AreEqual(true,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should still have one speedboost buff.");
|
Assert::AreEqual(true,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should still have one speedboost buff.");
|
||||||
Game::Update(1.f);
|
Game::Update(1.f);
|
||||||
Assert::AreEqual(false,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should no longer have a speedboost buff.");
|
Assert::AreEqual(false,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should no longer have a speedboost buff.");
|
||||||
game->GetPlayer()->AddBuff(BuffType::SPEEDBOOST,1.f,1.f);
|
Game::AddBuffToPlayer(BuffType::SPEEDBOOST,1.f,1.f);
|
||||||
game->GetPlayer()->RemoveBuff(BuffType::SPEEDBOOST);
|
game->GetPlayer()->RemoveBuff(BuffType::SPEEDBOOST);
|
||||||
Assert::AreEqual(false,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should no longer have a speedboost buff.");
|
Assert::AreEqual(false,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should no longer have a speedboost buff.");
|
||||||
}
|
}
|
||||||
|
TEST_METHOD(PlayerDoesNotImmediatelyReceiveBuffTest){
|
||||||
|
Assert::AreEqual(false,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should not have a speedboost buff before being given one.");
|
||||||
|
game->GetPlayer()->AddBuff(BuffType::SPEEDBOOST,1.f,1.f);
|
||||||
|
Assert::AreEqual(false,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should still not have a speedboost buff since it is in the add queue.");
|
||||||
|
Game::Update(0.f);
|
||||||
|
Assert::AreEqual(true,game->GetPlayer()->HasBuff(BuffType::SPEEDBOOST),L"Player should now have a speedboost buff.");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -275,6 +275,7 @@ namespace EnchantTests
|
|||||||
Assert::AreEqual(size_t(0),player->GetBuffs(BuffType::LETHAL_TEMPO).size(),L"Lethal Tempo does not stack up without the enchant.");
|
Assert::AreEqual(size_t(0),player->GetBuffs(BuffType::LETHAL_TEMPO).size(),L"Lethal Tempo does not stack up without the enchant.");
|
||||||
Game::GiveAndEquipEnchantedRing("Lethal Tempo");
|
Game::GiveAndEquipEnchantedRing("Lethal Tempo");
|
||||||
testMonster.Hurt(0,testMonster.OnUpperLevel(),testMonster.GetZ(),HurtFlag::PLAYER_ABILITY);
|
testMonster.Hurt(0,testMonster.OnUpperLevel(),testMonster.GetZ(),HurtFlag::PLAYER_ABILITY);
|
||||||
|
Game::Update(0.f);
|
||||||
Assert::AreEqual(size_t(1),player->GetBuffs(BuffType::LETHAL_TEMPO).size(),L"Lethal Tempo buff is active after attacking with the enchant..");
|
Assert::AreEqual(size_t(1),player->GetBuffs(BuffType::LETHAL_TEMPO).size(),L"Lethal Tempo buff is active after attacking with the enchant..");
|
||||||
Assert::AreEqual(0.0175f,player->GetAttackRecoveryRateReduction(),L"Lethal Tempo buff reduced attack Recovery Rate by 0.0175 (5% of 0.35).");
|
Assert::AreEqual(0.0175f,player->GetAttackRecoveryRateReduction(),L"Lethal Tempo buff reduced attack Recovery Rate by 0.0175 (5% of 0.35).");
|
||||||
for(int i:std::ranges::iota_view(0,10)){
|
for(int i:std::ranges::iota_view(0,10)){
|
||||||
@ -561,6 +562,7 @@ namespace EnchantTests
|
|||||||
TEST_METHOD(TumbleCheck){
|
TEST_METHOD(TumbleCheck){
|
||||||
Game::ChangeClass(player,THIEF);
|
Game::ChangeClass(player,THIEF);
|
||||||
player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput);
|
player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput);
|
||||||
|
Game::Update(0.f);
|
||||||
const float originalIframeTime{"Thief.Right Click Ability.Iframe Time"_F};
|
const float originalIframeTime{"Thief.Right Click Ability.Iframe Time"_F};
|
||||||
Assert::AreEqual(originalIframeTime,player->GetIframeTime(),L"Iframe time should be normal.");
|
Assert::AreEqual(originalIframeTime,player->GetIframeTime(),L"Iframe time should be normal.");
|
||||||
const float originalMovespdIntensity{"Thief.Right Click Ability.Movespeed Buff"_f[0]/100.f};
|
const float originalMovespdIntensity{"Thief.Right Click Ability.Movespeed Buff"_f[0]/100.f};
|
||||||
@ -569,6 +571,7 @@ namespace EnchantTests
|
|||||||
player->GetRightClickAbility().charges=1;
|
player->GetRightClickAbility().charges=1;
|
||||||
Game::GiveAndEquipEnchantedRing("Tumble");
|
Game::GiveAndEquipEnchantedRing("Tumble");
|
||||||
player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput);
|
player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput);
|
||||||
|
Game::Update(0.f);
|
||||||
Assert::AreEqual(originalIframeTime+"Thief.Right Click Ability.Iframe Time"_F*"Tumble"_ENC["BOOST PERCENTAGE"]/100.f,player->GetIframeTime(),L"Iframe time should be longer.");
|
Assert::AreEqual(originalIframeTime+"Thief.Right Click Ability.Iframe Time"_F*"Tumble"_ENC["BOOST PERCENTAGE"]/100.f,player->GetIframeTime(),L"Iframe time should be longer.");
|
||||||
Assert::AreEqual(originalMovespdIntensity+originalMovespdIntensity*"Tumble"_ENC["BOOST PERCENTAGE"]/100.f,player->GetBuffs(BuffType::SPEEDBOOST)[0].intensity,L"Player should have a movespeed buff with greater intensity.");
|
Assert::AreEqual(originalMovespdIntensity+originalMovespdIntensity*"Tumble"_ENC["BOOST PERCENTAGE"]/100.f,player->GetBuffs(BuffType::SPEEDBOOST)[0].intensity,L"Player should have a movespeed buff with greater intensity.");
|
||||||
}
|
}
|
||||||
@ -618,6 +621,7 @@ namespace EnchantTests
|
|||||||
TEST_METHOD(AdrenalineStimCheck){
|
TEST_METHOD(AdrenalineStimCheck){
|
||||||
Game::ChangeClass(player,THIEF);
|
Game::ChangeClass(player,THIEF);
|
||||||
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
||||||
|
Game::Update(0.f);
|
||||||
Assert::AreEqual("Thief.Ability 3.Duration"_F,player->GetBuffs(BuffType::ADRENALINE_RUSH)[0].duration,L"Adrenaline Rush buff duration is normal.");
|
Assert::AreEqual("Thief.Ability 3.Duration"_F,player->GetBuffs(BuffType::ADRENALINE_RUSH)[0].duration,L"Adrenaline Rush buff duration is normal.");
|
||||||
Assert::AreEqual(100,player->GetHealth(),L"Adrenaline Rush does not reduce health.");
|
Assert::AreEqual(100,player->GetHealth(),L"Adrenaline Rush does not reduce health.");
|
||||||
Assert::AreEqual("Thief.Auto Attack.Cooldown"_F*"Thief.Ability 3.Attack Speed Increase"_F/100.f,player->GetAttackRecoveryRateReduction(),L"Adrenaline Rush boosts attack rate normally.");
|
Assert::AreEqual("Thief.Auto Attack.Cooldown"_F*"Thief.Ability 3.Attack Speed Increase"_F/100.f,player->GetAttackRecoveryRateReduction(),L"Adrenaline Rush boosts attack rate normally.");
|
||||||
@ -627,6 +631,7 @@ namespace EnchantTests
|
|||||||
player->RemoveAllBuffs();
|
player->RemoveAllBuffs();
|
||||||
Game::GiveAndEquipEnchantedRing("Adrenaline Stim");
|
Game::GiveAndEquipEnchantedRing("Adrenaline Stim");
|
||||||
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
||||||
|
Game::Update(0.f);
|
||||||
Assert::AreEqual("Adrenaline Stim"_ENC["NEW ADRENALINE RUSH DURATION"],player->GetBuffs(BuffType::ADRENALINE_RUSH)[0].duration,L"Adrenaline Stim enchant boosts the duration of Adrenaline Rush.");
|
Assert::AreEqual("Adrenaline Stim"_ENC["NEW ADRENALINE RUSH DURATION"],player->GetBuffs(BuffType::ADRENALINE_RUSH)[0].duration,L"Adrenaline Stim enchant boosts the duration of Adrenaline Rush.");
|
||||||
Assert::AreEqual(80,player->GetHealth(),L"Adrenaline Stim reduces health.");
|
Assert::AreEqual(80,player->GetHealth(),L"Adrenaline Stim reduces health.");
|
||||||
Assert::AreEqual("Thief.Auto Attack.Cooldown"_F*"Thief.Ability 3.Attack Speed Increase"_F/100.f,player->GetAttackRecoveryRateReduction(),L"Adrenaline Stim still boosts attack rate normally.");
|
Assert::AreEqual("Thief.Auto Attack.Cooldown"_F*"Thief.Ability 3.Attack Speed Increase"_F/100.f,player->GetAttackRecoveryRateReduction(),L"Adrenaline Stim still boosts attack rate normally.");
|
||||||
@ -636,6 +641,7 @@ namespace EnchantTests
|
|||||||
Game::ChangeClass(player,THIEF);
|
Game::ChangeClass(player,THIEF);
|
||||||
player->SetBaseStat("Attack",100);
|
player->SetBaseStat("Attack",100);
|
||||||
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
||||||
|
Game::Update(0.f);
|
||||||
MonsterData testMonsterData{"TestName","Test Monster",30,10,5,{MonsterDropData{"Health Potion",100.f,1,1}},200.f};
|
MonsterData testMonsterData{"TestName","Test Monster",30,10,5,{MonsterDropData{"Health Potion",100.f,1,1}},200.f};
|
||||||
MONSTER_DATA["TestName"]=testMonsterData;
|
MONSTER_DATA["TestName"]=testMonsterData;
|
||||||
for(int i:std::ranges::iota_view(0,10)){
|
for(int i:std::ranges::iota_view(0,10)){
|
||||||
@ -649,6 +655,7 @@ namespace EnchantTests
|
|||||||
Thief::ability3.charges=1;
|
Thief::ability3.charges=1;
|
||||||
Game::GiveAndEquipEnchantedRing("Bloodlust");
|
Game::GiveAndEquipEnchantedRing("Bloodlust");
|
||||||
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
||||||
|
Game::Update(0.f);
|
||||||
for(int i:std::ranges::iota_view(0,30)){
|
for(int i:std::ranges::iota_view(0,30)){
|
||||||
Monster testMonster{{},MONSTER_DATA["TestName"]};
|
Monster testMonster{{},MONSTER_DATA["TestName"]};
|
||||||
testMonster.Hurt(1000,testMonster.OnUpperLevel(),testMonster.GetZ());
|
testMonster.Hurt(1000,testMonster.OnUpperLevel(),testMonster.GetZ());
|
||||||
@ -663,6 +670,7 @@ namespace EnchantTests
|
|||||||
player->GetRightClickAbility().charges=1;
|
player->GetRightClickAbility().charges=1;
|
||||||
Game::GiveAndEquipEnchantedRing("Evasive Movement");
|
Game::GiveAndEquipEnchantedRing("Evasive Movement");
|
||||||
player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput);
|
player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput);
|
||||||
|
Game::Update(0.f);
|
||||||
Assert::AreEqual(size_t(1),player->GetBuffs(BuffType::DAMAGE_REDUCTION).size(),L"Roll gives a damage reduction buff.");
|
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.");
|
Assert::AreEqual("Evasive Movement"_ENC["DAMAGE REDUCTION PCT"]/100.f,player->GetDamageReductionFromBuffs(),L"Evasive Movement provides 50% damage reduction.");
|
||||||
}
|
}
|
||||||
@ -848,6 +856,7 @@ namespace EnchantTests
|
|||||||
TEST_METHOD(SwordEnchantmentEnchantCheck){
|
TEST_METHOD(SwordEnchantmentEnchantCheck){
|
||||||
Game::GiveAndEquipEnchantedRing("Sword Enchantment");
|
Game::GiveAndEquipEnchantedRing("Sword Enchantment");
|
||||||
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
||||||
|
Game::Update(0.f);
|
||||||
Assert::AreEqual(300.f,player->GetAttackRange(),L"Attack range of Warrior doubled.");
|
Assert::AreEqual(300.f,player->GetAttackRange(),L"Attack range of Warrior doubled.");
|
||||||
Game::Update(0.f); //Wait an extra tick for the buff to begin going down.
|
Game::Update(0.f); //Wait an extra tick for the buff to begin going down.
|
||||||
Game::Update(8.f);
|
Game::Update(8.f);
|
||||||
|
@ -69,6 +69,21 @@ namespace Game{
|
|||||||
nullRing.lock()->_EnchantItem(enchantName);
|
nullRing.lock()->_EnchantItem(enchantName);
|
||||||
return nullRing;
|
return nullRing;
|
||||||
}
|
}
|
||||||
|
//Adds the buff directly to the player instead of the buffs added list. (By calling an update tick.)
|
||||||
|
inline void AddBuffToPlayer(BuffType type,float duration,float intensity){
|
||||||
|
game->GetPlayer()->AddBuff(type,duration,intensity);
|
||||||
|
Update(0.f);
|
||||||
|
}
|
||||||
|
//NOTE: If adding a % increase stat, please use the percentage version! 100% = 1!!
|
||||||
|
inline void AddBuffToPlayer(BuffType type,float duration,float intensity,std::set<ItemAttribute>attr){
|
||||||
|
game->GetPlayer()->AddBuff(type,duration,intensity,attr);
|
||||||
|
Update(0.f);
|
||||||
|
}
|
||||||
|
//NOTE: If adding a % increase stat, please use the percentage version! 100% = 1!!
|
||||||
|
inline void AddBuffToPlayer(BuffType type,float duration,float intensity,std::set<std::string>attr){
|
||||||
|
game->GetPlayer()->AddBuff(type,duration,intensity,attr);
|
||||||
|
Update(0.f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Test
|
namespace Test
|
||||||
|
@ -43,6 +43,7 @@ All rights reserved.
|
|||||||
#include "ItemDrop.h"
|
#include "ItemDrop.h"
|
||||||
#include "DamageNumber.h"
|
#include "DamageNumber.h"
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
#include "GameHelper.h"
|
||||||
|
|
||||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||||
using namespace olc::utils;
|
using namespace olc::utils;
|
||||||
@ -321,11 +322,11 @@ namespace PlayerTests
|
|||||||
Assert::AreEqual(1000+player->GetBaseStat("Health"),float(player->GetMaxHealth()),L"Max Health stat should be increased from 100 to 1100.");
|
Assert::AreEqual(1000+player->GetBaseStat("Health"),float(player->GetMaxHealth()),L"Max Health stat should be increased from 100 to 1100.");
|
||||||
}
|
}
|
||||||
TEST_METHOD(HealthStatUpBuffCheck){
|
TEST_METHOD(HealthStatUpBuffCheck){
|
||||||
player->AddBuff(BuffType::STAT_UP,5.f,1000.f,{"Health"});
|
Game::AddBuffToPlayer(BuffType::STAT_UP,5.f,1000.f,{"Health"});
|
||||||
Assert::AreEqual(1000+player->GetBaseStat("Health"),float(player->GetMaxHealth()),L"Max Health stat should be increased from 100 to 1100.");
|
Assert::AreEqual(1000+player->GetBaseStat("Health"),float(player->GetMaxHealth()),L"Max Health stat should be increased from 100 to 1100.");
|
||||||
}
|
}
|
||||||
TEST_METHOD(HealthPctStatUpBuffCheck){
|
TEST_METHOD(HealthPctStatUpBuffCheck){
|
||||||
player->AddBuff(BuffType::STAT_UP,5.f,1000.0_Pct,{"Health %"});
|
Game::AddBuffToPlayer(BuffType::STAT_UP,5.f,1000.0_Pct,{"Health %"});
|
||||||
Assert::AreEqual(1000+player->GetBaseStat("Health"),float(player->GetMaxHealth()),L"Max Health stat should be increased from 100 to 1100.");
|
Assert::AreEqual(1000+player->GetBaseStat("Health"),float(player->GetMaxHealth()),L"Max Health stat should be increased from 100 to 1100.");
|
||||||
}
|
}
|
||||||
TEST_METHOD(IllegalCritRateStatUpBuffCheck){
|
TEST_METHOD(IllegalCritRateStatUpBuffCheck){
|
||||||
@ -593,6 +594,7 @@ namespace PlayerTests
|
|||||||
Assert::AreEqual(0.f,player->GetAttackRecoveryRateReduction(),L"Attack rate cooldown starts with being reduced by 0 seconds.");
|
Assert::AreEqual(0.f,player->GetAttackRecoveryRateReduction(),L"Attack rate cooldown starts with being reduced by 0 seconds.");
|
||||||
testKey->bHeld=true; //Force the key to be held down for testing purposes.
|
testKey->bHeld=true; //Force the key to be held down for testing purposes.
|
||||||
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
||||||
|
Game::Update(0.f);
|
||||||
Assert::IsTrue(player->GetBuffs(BuffType::ADRENALINE_RUSH).size()>0,L"After using Adrenaline Rush, player has the Adrenaline Rush buff.");
|
Assert::IsTrue(player->GetBuffs(BuffType::ADRENALINE_RUSH).size()>0,L"After using Adrenaline Rush, player has the Adrenaline Rush buff.");
|
||||||
Assert::AreEqual(1.1f,player->GetMoveSpdMult(),L"Move Speed Multiplier increased by 10% to x1.1");
|
Assert::AreEqual(1.1f,player->GetMoveSpdMult(),L"Move Speed Multiplier increased by 10% to x1.1");
|
||||||
Assert::AreEqual(0.105f,player->GetAttackRecoveryRateReduction(),L"Attack Recovery Rate reduced by 30%, or 0.105s");
|
Assert::AreEqual(0.105f,player->GetAttackRecoveryRateReduction(),L"Attack Recovery Rate reduced by 30%, or 0.105s");
|
||||||
|
@ -1114,6 +1114,10 @@
|
|||||||
<SubType>
|
<SubType>
|
||||||
</SubType>
|
</SubType>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="PiratesTreasure.cpp">
|
||||||
|
<SubType>
|
||||||
|
</SubType>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="Pirate_Buccaneer.cpp" />
|
<ClCompile Include="Pirate_Buccaneer.cpp" />
|
||||||
<ClCompile Include="Pirate_Captain.cpp" />
|
<ClCompile Include="Pirate_Captain.cpp" />
|
||||||
<ClCompile Include="Pirate_Marauder.cpp" />
|
<ClCompile Include="Pirate_Marauder.cpp" />
|
||||||
|
@ -1304,6 +1304,9 @@
|
|||||||
<ClCompile Include="GhostSaber.cpp">
|
<ClCompile Include="GhostSaber.cpp">
|
||||||
<Filter>Source Files\Bullet Types</Filter>
|
<Filter>Source Files\Bullet Types</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="PiratesTreasure.cpp">
|
||||||
|
<Filter>Source Files\Monster Strategies</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="cpp.hint" />
|
<None Include="cpp.hint" />
|
||||||
|
@ -1068,12 +1068,15 @@ void AiL::RenderWorld(float fElapsedTime){
|
|||||||
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)};
|
const std::vector<Buff>damageReductionBuffs{player->GetBuffs(BuffType::DAMAGE_REDUCTION)};
|
||||||
const std::vector<Buff>inkSlowdownDebuff{player->GetBuffs(BuffType::INK_SLOWDOWN)};
|
const std::vector<Buff>inkSlowdownDebuff{player->GetBuffs(BuffType::INK_SLOWDOWN)};
|
||||||
|
const std::vector<Buff>curseDebuff{player->GetBuffs(BuffType::PIRATE_GHOST_CAPTAIN_CURSE_DOT)};
|
||||||
|
const bool displayCoinSymbol{player->GetBuffs(BuffType::PIRATE_GHOST_CAPTAIN_CURSE).size()>0};
|
||||||
|
|
||||||
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)))};
|
||||||
else if(inkSlowdownDebuff.size()>0)playerCol={uint8_t(255*abs(sin(2.f*inkSlowdownDebuff[0].duration))),uint8_t(255*abs(sin(2.f*inkSlowdownDebuff[0].duration))),uint8_t(255*abs(sin(2.f*inkSlowdownDebuff[0].duration)))};
|
else if(inkSlowdownDebuff.size()>0)playerCol={uint8_t(255*abs(sin(2.f*inkSlowdownDebuff[0].duration))),uint8_t(255*abs(sin(2.f*inkSlowdownDebuff[0].duration))),uint8_t(255*abs(sin(2.f*inkSlowdownDebuff[0].duration)))};
|
||||||
|
else if(curseDebuff.size()>0)playerCol={uint8_t(128*abs(sin(2.f*GetRunTime()))+127),uint8_t(128*abs(sin(2.f*GetRunTime()))),uint8_t(128*abs(sin(2.f*GetRunTime()))+127)};
|
||||||
|
|
||||||
if(player->HasIframes())playerCol.a*=0.62f;
|
if(player->HasIframes())playerCol.a*=0.62f;
|
||||||
|
|
||||||
@ -1093,6 +1096,10 @@ void AiL::RenderWorld(float fElapsedTime){
|
|||||||
game->AddEffect(std::make_unique<Effect>(player->GetPos()-vf2d{0,4.f}-player->GetFacingDirVector()*6.f,0.2f,"energy_particle.png",player->OnUpperLevel(),vf2d{particleSize,particleSize},0.05f,vf2d{},DARK_GREEN,util::random(2*PI)));
|
game->AddEffect(std::make_unique<Effect>(player->GetPos()-vf2d{0,4.f}-player->GetFacingDirVector()*6.f,0.2f,"energy_particle.png",player->OnUpperLevel(),vf2d{particleSize,particleSize},0.05f,vf2d{},DARK_GREEN,util::random(2*PI)));
|
||||||
player->poisonArrowLastParticleTimer=0.15f;
|
player->poisonArrowLastParticleTimer=0.15f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(displayCoinSymbol){
|
||||||
|
view.DrawRotatedDecal(pos+vf2d{0,(-player->GetZ()-24.f-sinf(PI*GetRunTime())*4.f)*(std::signbit(scale.y)?-1:1)},GFX["coin.png"].Decal(),0.f,GFX["coin.png"].Sprite()->Size()/2,{0.5f,0.5f});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto RenderZone=[&](geom2d::rect<int>&zone){
|
auto RenderZone=[&](geom2d::rect<int>&zone){
|
||||||
|
@ -66,6 +66,8 @@ enum BuffType{
|
|||||||
CURSE_OF_DEATH,
|
CURSE_OF_DEATH,
|
||||||
AFFECTED_BY_LIGHTNING_BOLT, //Intensity indicates number of repeats remaining.
|
AFFECTED_BY_LIGHTNING_BOLT, //Intensity indicates number of repeats remaining.
|
||||||
INK_SLOWDOWN, //Intensity indicates % movespd slowdown.
|
INK_SLOWDOWN, //Intensity indicates % movespd slowdown.
|
||||||
|
PIRATE_GHOST_CAPTAIN_CURSE, //A coin icon appears above the player's head.
|
||||||
|
PIRATE_GHOST_CAPTAIN_CURSE_DOT, //The same as above, but now is a damage over time as well.
|
||||||
};
|
};
|
||||||
enum class BuffRestorationType{
|
enum class BuffRestorationType{
|
||||||
ONE_OFF, //This is used as a hack fix for the RestoreDuringCast Item script since they require us to restore 1 tick immediately. Over time buffs do not apply a tick immediately.
|
ONE_OFF, //This is used as a hack fix for the RestoreDuringCast Item script since they require us to restore 1 tick immediately. Over time buffs do not apply a tick immediately.
|
||||||
@ -75,11 +77,11 @@ enum class BuffRestorationType{
|
|||||||
namespace BuffOverTimeType{
|
namespace BuffOverTimeType{
|
||||||
enum BuffOverTimeType{
|
enum BuffOverTimeType{
|
||||||
HP_RESTORATION,
|
HP_RESTORATION,
|
||||||
HP_PCT_RESTORATION,
|
HP_PCT_RESTORATION, //Percentage should be the raw percentage, NOT % form! (So 1 for 1%, not 0.01)
|
||||||
MP_RESTORATION,
|
MP_RESTORATION,
|
||||||
MP_PCT_RESTORATION,
|
MP_PCT_RESTORATION, //Percentage should be the raw percentage, NOT % form! (So 1 for 1%, not 0.01)
|
||||||
HP_DAMAGE_OVER_TIME,
|
HP_DAMAGE_OVER_TIME,
|
||||||
HP_PCT_DAMAGE_OVER_TIME,
|
HP_PCT_DAMAGE_OVER_TIME, //Percentage should be the raw percentage, NOT % form! (So 1 for 1%, not 0.01)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ void Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std
|
|||||||
NORMAL,
|
NORMAL,
|
||||||
AFTERIMAGE_FADEIN,
|
AFTERIMAGE_FADEIN,
|
||||||
GHOSTSABER_SLASH=999,
|
GHOSTSABER_SLASH=999,
|
||||||
|
TOSS_COIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CannonShotType{
|
enum CannonShotType{
|
||||||
@ -180,6 +181,12 @@ void Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std
|
|||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Config("Curse Thresholds").GetValueCount()>m.I(A::CURSE_THRESHOLD_ARRAY_IND)&&
|
||||||
|
m.GetHealthRatio()<=ConfigFloatArr("Curse Thresholds",m.I(A::CURSE_THRESHOLD_ARRAY_IND))){
|
||||||
|
m.I(A::CURSE_THRESHOLD_ARRAY_IND)++;
|
||||||
|
SETPHASE(TOSS_COIN);
|
||||||
|
}
|
||||||
}break;
|
}break;
|
||||||
case AFTERIMAGE_FADEIN:{
|
case AFTERIMAGE_FADEIN:{
|
||||||
m.F(A::CASTING_TIMER)-=fElapsedTime;
|
m.F(A::CASTING_TIMER)-=fElapsedTime;
|
||||||
@ -195,5 +202,10 @@ void Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std
|
|||||||
SETPHASE(m.I(A::PREVIOUS_PHASE));
|
SETPHASE(m.I(A::PREVIOUS_PHASE));
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
case TOSS_COIN:{
|
||||||
|
const float curseDmgPctOverTime{ConfigFloat("Curse Damage")};
|
||||||
|
game->GetPlayer()->AddBuff(BuffType::PIRATE_GHOST_CAPTAIN_CURSE,ConfigFloat("Curse Damage Wait Time"),ceil(game->GetPlayer()->GetMaxHealth()*ConfigFloat("Curse Damage")/100.f)+1,[curseDmgPctOverTime](Player*attachedTarget,Buff&b){attachedTarget->AddBuff(BuffType::PIRATE_GHOST_CAPTAIN_CURSE_DOT,BuffRestorationType::OVER_TIME,BuffOverTimeType::HP_PCT_DAMAGE_OVER_TIME,INFINITY,curseDmgPctOverTime,1.f);});
|
||||||
|
SETPHASE(NORMAL);
|
||||||
|
}break;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -82,8 +82,10 @@ Monster::Monster(vf2d pos,MonsterData data,bool upperLevel,bool bossMob):
|
|||||||
monsterWalkSoundTimer=util::random(1.f);
|
monsterWalkSoundTimer=util::random(1.f);
|
||||||
UpdateFacingDirection(game->GetPlayer()->GetPos());
|
UpdateFacingDirection(game->GetPlayer()->GetPos());
|
||||||
animation.UpdateState(internal_animState,randomFrameOffset);
|
animation.UpdateState(internal_animState,randomFrameOffset);
|
||||||
const vf2d¤tRect{GetFrame().GetSourceRect().size};
|
[[likely]]if(!game->TestingModeEnabled()){
|
||||||
afterImage.Create(currentRect.x,currentRect.y);
|
const vf2d¤tRect{GetFrame().GetSourceRect().size};
|
||||||
|
afterImage.Create(currentRect.x,currentRect.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const vf2d&Monster::GetPos()const{
|
const vf2d&Monster::GetPos()const{
|
||||||
return pos;
|
return pos;
|
||||||
@ -411,23 +413,25 @@ void Monster::Update(const float fElapsedTime){
|
|||||||
attackedByPlayer=false;
|
attackedByPlayer=false;
|
||||||
|
|
||||||
#pragma region Afterimage Handling
|
#pragma region Afterimage Handling
|
||||||
const auto RemoveScanLine=[&](uint8_t scanLine){
|
[[likely]]if(!game->TestingModeEnabled()){
|
||||||
for(int x:std::ranges::iota_view(0,afterImage.Sprite()->width)){
|
const auto RemoveScanLine=[&](uint8_t scanLine){
|
||||||
afterImage.Sprite()->SetPixel({x,scanLine},BLANK);
|
for(int x:std::ranges::iota_view(0,afterImage.Sprite()->width)){
|
||||||
}
|
afterImage.Sprite()->SetPixel({x,scanLine},BLANK);
|
||||||
afterImage.Decal()->Update();
|
}
|
||||||
};
|
afterImage.Decal()->Update();
|
||||||
|
};
|
||||||
|
|
||||||
//Scan Line goes through 1-(height-1) (odd numbers) first, then 0-22.
|
//Scan Line goes through 1-(height-1) (odd numbers) first, then 0-22.
|
||||||
const bool ScanLineFinished{scanLine==afterImage.Sprite()->height};
|
const bool ScanLineFinished{scanLine==afterImage.Sprite()->height};
|
||||||
if(!ScanLineFinished){
|
if(!ScanLineFinished){
|
||||||
removeLineTimer-=fElapsedTime;
|
removeLineTimer-=fElapsedTime;
|
||||||
if(removeLineTimer<=0.f){
|
if(removeLineTimer<=0.f){
|
||||||
removeLineTimer=TIME_BETWEEN_LINE_REMOVALS;
|
removeLineTimer=TIME_BETWEEN_LINE_REMOVALS;
|
||||||
RemoveScanLine(scanLine);
|
RemoveScanLine(scanLine);
|
||||||
scanLine+=2;
|
scanLine+=2;
|
||||||
if(scanLine>afterImage.Sprite()->height-1&&scanLine%2==1){
|
if(scanLine>afterImage.Sprite()->height-1&&scanLine%2==1){
|
||||||
scanLine=0;
|
scanLine=0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -392,6 +392,7 @@ private:
|
|||||||
static void GIANT_OCTOPUS(Monster&m,float fElapsedTime,std::string strategy);
|
static void GIANT_OCTOPUS(Monster&m,float fElapsedTime,std::string strategy);
|
||||||
static void OCTOPUS_ARM(Monster&m,float fElapsedTime,std::string strategy);
|
static void OCTOPUS_ARM(Monster&m,float fElapsedTime,std::string strategy);
|
||||||
static void GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std::string strategy);
|
static void GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std::string strategy);
|
||||||
|
static void PIRATES_TREASURE(Monster&m,float fElapsedTime,std::string strategy);
|
||||||
};
|
};
|
||||||
bool bumpedIntoTerrain=false; //Gets set to true before a strategy executes if the monster runs into some terrain on this frame.
|
bool bumpedIntoTerrain=false; //Gets set to true before a strategy executes if the monster runs into some terrain on this frame.
|
||||||
bool attackedByPlayer=false; //Gets set to true before a strategy executes if the monster has been attacked by the player.
|
bool attackedByPlayer=false; //Gets set to true before a strategy executes if the monster has been attacked by the player.
|
||||||
|
@ -175,4 +175,5 @@ enum class Attribute{
|
|||||||
FIRST_WAVE_COMPLETE,
|
FIRST_WAVE_COMPLETE,
|
||||||
GHOST_SABER_TIMER,
|
GHOST_SABER_TIMER,
|
||||||
GHOST_SABER_SLASH_ANIMATION_TIMER,
|
GHOST_SABER_SLASH_ANIMATION_TIMER,
|
||||||
|
CURSE_THRESHOLD_ARRAY_IND, //Which array index in the curse threshold strategy property we are currently at?
|
||||||
};
|
};
|
52
Adventures in Lestoria/PiratesTreasure.cpp
Normal file
52
Adventures in Lestoria/PiratesTreasure.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#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
|
||||||
|
|
||||||
|
#include "AdventuresInLestoria.h"
|
||||||
|
#include "MonsterStrategyHelpers.h"
|
||||||
|
|
||||||
|
INCLUDE_game
|
||||||
|
|
||||||
|
void Monster::STRATEGY::PIRATES_TREASURE(Monster&m,float fElapsedTime,std::string strategy){
|
||||||
|
const float distToPlayer{util::distance(game->GetPlayer()->GetPos(),m.GetPos())};
|
||||||
|
if(distToPlayer<=ConfigFloat("Open Distance"))m.PerformAnimation("OPEN");
|
||||||
|
else m.PerformIdleAnimation();
|
||||||
|
if(m.B(Attribute::COLLIDED_WITH_PLAYER)){
|
||||||
|
game->GetPlayer()->RemoveBuff(BuffType::PIRATE_GHOST_CAPTAIN_CURSE);
|
||||||
|
game->GetPlayer()->RemoveBuff(BuffType::PIRATE_GHOST_CAPTAIN_CURSE_DOT);
|
||||||
|
}
|
||||||
|
}
|
@ -441,6 +441,9 @@ void Player::Update(float fElapsedTime){
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
std::for_each(buffsToBeAdded.begin(),buffsToBeAdded.end(),[&](Buff&b){b.Update(game,fElapsedTime);});
|
||||||
|
std::move(buffsToBeAdded.begin(),buffsToBeAdded.end(),std::back_inserter(buffList));
|
||||||
|
buffsToBeAdded.clear();
|
||||||
//Class-specific update events.
|
//Class-specific update events.
|
||||||
OnUpdate(fElapsedTime);
|
OnUpdate(fElapsedTime);
|
||||||
switch(state){
|
switch(state){
|
||||||
@ -1143,39 +1146,31 @@ void Player::UpdateIdleAnimation(Key direction){
|
|||||||
animation.ChangeState(internal_catAnimState,std::format("WITCH_CAT_WALK_{}",anim[anim.length()-1]),0.f);
|
animation.ChangeState(internal_catAnimState,std::format("WITCH_CAT_WALK_{}",anim[anim.length()-1]),0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::AddBuff(BuffType type,float duration,float intensity){
|
Buff&Player::AddBuff(BuffType type,float duration,float intensity){
|
||||||
Buff&newBuff{buffList.emplace_back(this,type,duration,intensity)};
|
return buffsToBeAdded.emplace_back(this,type,duration,intensity);
|
||||||
OnBuffAdd(newBuff);
|
|
||||||
}
|
}
|
||||||
void Player::AddBuff(BuffType type,float duration,float intensity,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc){
|
Buff&Player::AddBuff(BuffType type,float duration,float intensity,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc){
|
||||||
Buff&newBuff{buffList.emplace_back(this,type,duration,intensity,expireCallbackFunc)};
|
return buffsToBeAdded.emplace_back(this,type,duration,intensity,expireCallbackFunc);
|
||||||
OnBuffAdd(newBuff);
|
|
||||||
}
|
}
|
||||||
void Player::AddBuff(BuffType type,float duration,float intensity,std::set<ItemAttribute>attr){
|
Buff&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()));});
|
||||||
Buff&newBuff{buffList.emplace_back(this,type,duration,intensity,attr)};
|
return buffsToBeAdded.emplace_back(this,type,duration,intensity,attr);
|
||||||
OnBuffAdd(newBuff);
|
|
||||||
}
|
}
|
||||||
void Player::AddBuff(BuffType type,float duration,float intensity,std::set<std::string>attr){
|
Buff&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));});
|
||||||
Buff&newBuff{buffList.emplace_back(this,type,duration,intensity,attr)};
|
return buffsToBeAdded.emplace_back(this,type,duration,intensity,attr);
|
||||||
OnBuffAdd(newBuff);
|
|
||||||
}
|
}
|
||||||
void Player::AddBuff(BuffRestorationType type,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks){
|
Buff&Player::AddBuff(BuffRestorationType type,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks){
|
||||||
Buff&newBuff{buffList.emplace_back(this,type,overTimeType,duration,intensity,timeBetweenTicks)};
|
return buffsToBeAdded.emplace_back(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){
|
Buff&Player::AddBuff(BuffRestorationType type,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc){
|
||||||
Buff&newBuff{buffList.emplace_back(this,type,overTimeType,duration,intensity,timeBetweenTicks,expireCallbackFunc)};
|
return buffsToBeAdded.emplace_back(this,type,overTimeType,duration,intensity,timeBetweenTicks,expireCallbackFunc);
|
||||||
OnBuffAdd(newBuff);
|
|
||||||
}
|
}
|
||||||
void Player::AddBuff(BuffType type,BuffRestorationType restorationType,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks){
|
Buff&Player::AddBuff(BuffType type,BuffRestorationType restorationType,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks){
|
||||||
Buff&newBuff{buffList.emplace_back(this,type,restorationType,overTimeType,duration,intensity,timeBetweenTicks)};
|
return buffsToBeAdded.emplace_back(this,type,restorationType,overTimeType,duration,intensity,timeBetweenTicks);
|
||||||
OnBuffAdd(newBuff);
|
|
||||||
}
|
}
|
||||||
void Player::AddBuff(BuffType type,BuffRestorationType restorationType,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc){
|
Buff&Player::AddBuff(BuffType type,BuffRestorationType restorationType,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc){
|
||||||
Buff&newBuff{buffList.emplace_back(this,type,restorationType,overTimeType,duration,intensity,timeBetweenTicks,expireCallbackFunc)};
|
return buffsToBeAdded.emplace_back(this,type,restorationType,overTimeType,duration,intensity,timeBetweenTicks,expireCallbackFunc);
|
||||||
OnBuffAdd(newBuff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::OnUpperLevel(){
|
bool Player::OnUpperLevel(){
|
||||||
@ -1200,7 +1195,7 @@ void Player::RemoveBuff(BuffType buff){
|
|||||||
|
|
||||||
Buff&Player::GetOrAddBuff(BuffType buff,std::pair<BuffDuration,BuffIntensity>newBuff){
|
Buff&Player::GetOrAddBuff(BuffType buff,std::pair<BuffDuration,BuffIntensity>newBuff){
|
||||||
if(GetBuffs(buff).size()>0)return EditBuff(buff,0);
|
if(GetBuffs(buff).size()>0)return EditBuff(buff,0);
|
||||||
else return buffList.emplace_back(this,buff,newBuff.first,newBuff.second);
|
else return AddBuff(buff,newBuff.first,newBuff.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
Buff&Player::EditBuff(BuffType buff,size_t buffInd){
|
Buff&Player::EditBuff(BuffType buff,size_t buffInd){
|
||||||
|
@ -174,16 +174,16 @@ public:
|
|||||||
void ForceSetPos(vf2d pos);
|
void ForceSetPos(vf2d pos);
|
||||||
void SetState(State::State newState);
|
void SetState(State::State newState);
|
||||||
|
|
||||||
void AddBuff(BuffType type,float duration,float intensity);
|
Buff&AddBuff(BuffType type,float duration,float intensity);
|
||||||
//NOTE: If adding a % increase stat, please use the percentage version! 100% = 1!!
|
//NOTE: If adding a % increase stat, please use the percentage version! 100% = 1!!
|
||||||
void AddBuff(BuffType type,float duration,float intensity,std::set<ItemAttribute>attr);
|
Buff&AddBuff(BuffType type,float duration,float intensity,std::set<ItemAttribute>attr);
|
||||||
//NOTE: If adding a % increase stat, please use the percentage version! 100% = 1!!
|
//NOTE: If adding a % increase stat, please use the percentage version! 100% = 1!!
|
||||||
void AddBuff(BuffType type,float duration,float intensity,std::set<std::string>attr);
|
Buff&AddBuff(BuffType type,float duration,float intensity,std::set<std::string>attr);
|
||||||
void AddBuff(BuffType type,float duration,float intensity,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc);
|
Buff&AddBuff(BuffType type,float duration,float intensity,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc);
|
||||||
void AddBuff(BuffRestorationType type,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks);
|
Buff&AddBuff(BuffRestorationType type,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks);
|
||||||
void AddBuff(BuffRestorationType type,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc);
|
Buff&AddBuff(BuffRestorationType type,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc);
|
||||||
void AddBuff(BuffType type,BuffRestorationType restorationType,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks);
|
Buff&AddBuff(BuffType type,BuffRestorationType restorationType,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks);
|
||||||
void AddBuff(BuffType type,BuffRestorationType restorationType,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc);
|
Buff&AddBuff(BuffType type,BuffRestorationType restorationType,BuffOverTimeType::BuffOverTimeType overTimeType,float duration,float intensity,float timeBetweenTicks,Buff::PlayerBuffExpireCallbackFunction expireCallbackFunc);
|
||||||
const bool HasBuff(BuffType buff)const;
|
const bool HasBuff(BuffType buff)const;
|
||||||
const std::vector<Buff>GetBuffs(BuffType buff)const;
|
const std::vector<Buff>GetBuffs(BuffType buff)const;
|
||||||
const std::vector<Buff>GetStatBuffs(const std::vector<std::string>&attr)const;
|
const std::vector<Buff>GetStatBuffs(const std::vector<std::string>&attr)const;
|
||||||
@ -435,6 +435,7 @@ private:
|
|||||||
std::optional<vf2d>testAimingLoc{};
|
std::optional<vf2d>testAimingLoc{};
|
||||||
vf2d addedVel{};
|
vf2d addedVel{};
|
||||||
vf2d previousPos{pos};
|
vf2d previousPos{pos};
|
||||||
|
std::vector<Buff>buffsToBeAdded{};
|
||||||
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;
|
||||||
|
@ -78,6 +78,7 @@ void Monster::InitializeStrategies(){
|
|||||||
STRATEGY_DATA.insert("Giant Octopus",Monster::STRATEGY::GIANT_OCTOPUS);
|
STRATEGY_DATA.insert("Giant Octopus",Monster::STRATEGY::GIANT_OCTOPUS);
|
||||||
STRATEGY_DATA.insert("Octopus Arm",Monster::STRATEGY::OCTOPUS_ARM);
|
STRATEGY_DATA.insert("Octopus Arm",Monster::STRATEGY::OCTOPUS_ARM);
|
||||||
STRATEGY_DATA.insert("Ghost of Pirate Captain",Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN);
|
STRATEGY_DATA.insert("Ghost of Pirate Captain",Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN);
|
||||||
|
STRATEGY_DATA.insert("Pirate's Treasure",Monster::STRATEGY::PIRATES_TREASURE);
|
||||||
|
|
||||||
STRATEGY_DATA.SetInitialized();
|
STRATEGY_DATA.SetInitialized();
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
|||||||
#define VERSION_MAJOR 1
|
#define VERSION_MAJOR 1
|
||||||
#define VERSION_MINOR 3
|
#define VERSION_MINOR 3
|
||||||
#define VERSION_PATCH 0
|
#define VERSION_PATCH 0
|
||||||
#define VERSION_BUILD 12036
|
#define VERSION_BUILD 12049
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="76" height="85" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="32">
|
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="76" height="85" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="33">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Background Music" propertytype="BGM" value="beach_boss"/>
|
<property name="Background Music" propertytype="BGM" value="beach_boss"/>
|
||||||
<property name="Level Type" type="int" propertytype="LevelType" value="1"/>
|
<property name="Level Type" type="int" propertytype="LevelType" value="1"/>
|
||||||
@ -575,5 +575,10 @@
|
|||||||
<property name="spawner" type="object" value="30"/>
|
<property name="spawner" type="object" value="30"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
|
<object id="32" template="../maps/Monsters/Pirate's Treasure.tx" x="834" y="1506">
|
||||||
|
<properties>
|
||||||
|
<property name="spawner" type="object" value="30"/>
|
||||||
|
</properties>
|
||||||
|
</object>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
BIN
Adventures in Lestoria/assets/coin.png
Normal file
BIN
Adventures in Lestoria/assets/coin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 806 B |
@ -1344,5 +1344,16 @@ MonsterStrategy
|
|||||||
Ghost Saber Knockback Amt = 100
|
Ghost Saber Knockback Amt = 100
|
||||||
# Amount of pixels/sec the ghost saber circle expands outwards.
|
# Amount of pixels/sec the ghost saber circle expands outwards.
|
||||||
Ghost Saber Expand Spd = 14px
|
Ghost Saber Expand Spd = 14px
|
||||||
|
|
||||||
|
# What HP % the boss throws a coin at the player, applying a curse, and hiding from the player.
|
||||||
|
Curse Thresholds = 70%, 40%, 10%
|
||||||
|
# How much time before the curse starts dealing damage to the player
|
||||||
|
Curse Damage Wait Time = 10s
|
||||||
|
# How much % damage the curse does to the player every second.
|
||||||
|
Curse Damage = 1%/sec
|
||||||
|
}
|
||||||
|
Pirate's Treasure
|
||||||
|
{
|
||||||
|
Open Distance = 64px
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1861,6 +1861,51 @@ Monsters
|
|||||||
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
|
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
|
||||||
# DROP[0] = Octopus Ring,100%,1,1
|
# DROP[0] = Octopus Ring,100%,1,1
|
||||||
|
|
||||||
|
Hurt Sound = Monster Hurt
|
||||||
|
Death Sound = Slime Dead
|
||||||
|
Walk Sound = Slime Walk
|
||||||
|
}
|
||||||
|
Pirate's Treasure
|
||||||
|
{
|
||||||
|
Health = 1
|
||||||
|
Attack = 80
|
||||||
|
|
||||||
|
CollisionDmg = 0
|
||||||
|
|
||||||
|
Immovable = True
|
||||||
|
Invulnerable = True
|
||||||
|
|
||||||
|
Fadeout = False
|
||||||
|
|
||||||
|
Collision Radius = 64
|
||||||
|
|
||||||
|
MoveSpd = 0%
|
||||||
|
Size = 300%
|
||||||
|
|
||||||
|
XP = 0
|
||||||
|
|
||||||
|
Strategy = Pirate's Treasure
|
||||||
|
|
||||||
|
#Size of each animation frame
|
||||||
|
SheetFrameSize = 24,24
|
||||||
|
|
||||||
|
# Setting this to true means every four rows indicates one animation, the ordering of the directions is: NORTH, EAST, SOUTH, WEST
|
||||||
|
4-Way Spritesheet = False
|
||||||
|
|
||||||
|
Animations
|
||||||
|
{
|
||||||
|
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse,ReverseOneShot)
|
||||||
|
# Animations must be defined in the same order as they are in their sprite sheets
|
||||||
|
# The First Four animations must represent a standing, walking, attack, and death animation. Their names are up to the creator.
|
||||||
|
IDLE = 1, 1.0, OneShot
|
||||||
|
WALK = 1, 1.0, OneShot
|
||||||
|
SLASHING = 1, 1.0, OneShot
|
||||||
|
OPEN = 1, 1.0, OneShot
|
||||||
|
}
|
||||||
|
|
||||||
|
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
|
||||||
|
# DROP[0] = Octopus Ring,100%,1,1
|
||||||
|
|
||||||
Hurt Sound = Monster Hurt
|
Hurt Sound = Monster Hurt
|
||||||
Death Sound = Slime Dead
|
Death Sound = Slime Dead
|
||||||
Walk Sound = Slime Walk
|
Walk Sound = Slime Walk
|
||||||
|
@ -148,6 +148,7 @@ Images
|
|||||||
GFX_Ink = ink.png
|
GFX_Ink = ink.png
|
||||||
GFX_Cannonball = cannonball.png
|
GFX_Cannonball = cannonball.png
|
||||||
GFX_GhostDagger = ghost_dagger.png
|
GFX_GhostDagger = ghost_dagger.png
|
||||||
|
GFX_Coin = coin.png
|
||||||
|
|
||||||
GFX_Thief_Sheet = nico-thief.png
|
GFX_Thief_Sheet = nico-thief.png
|
||||||
GFX_Trapper_Sheet = nico-trapper.png
|
GFX_Trapper_Sheet = nico-trapper.png
|
||||||
|
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.2" orientation="orthogonal" renderorder="right-down" width="30" height="20" tilewidth="24" tileheight="24" infinite="1" nextlayerid="3" nextobjectid="46">
|
<map version="1.10" tiledversion="1.10.2" orientation="orthogonal" renderorder="right-down" width="30" height="20" tilewidth="24" tileheight="24" infinite="1" nextlayerid="3" nextobjectid="48">
|
||||||
<tileset firstgid="1" source="Monsters.tsx"/>
|
<tileset firstgid="1" source="Monsters.tsx"/>
|
||||||
<layer id="1" name="Tile Layer 1" width="30" height="20">
|
<layer id="1" name="Tile Layer 1" width="30" height="20">
|
||||||
<data encoding="csv"/>
|
<data encoding="csv"/>
|
||||||
@ -40,5 +40,6 @@
|
|||||||
<object id="43" template="Monsters/Octopus Arm.tx" type="Monster" x="-48" y="744"/>
|
<object id="43" template="Monsters/Octopus Arm.tx" type="Monster" x="-48" y="744"/>
|
||||||
<object id="44" template="Monsters/Giant Octopus.tx" type="Monster" x="120" y="744"/>
|
<object id="44" template="Monsters/Giant Octopus.tx" type="Monster" x="120" y="744"/>
|
||||||
<object id="45" template="Monsters/Ghost of Pirate Captain.tx" type="Monster" x="-306" y="732"/>
|
<object id="45" template="Monsters/Ghost of Pirate Captain.tx" type="Monster" x="-306" y="732"/>
|
||||||
|
<object id="46" template="Monsters/Pirate's Treasure.tx" type="Monster" x="324" y="174" width="144" height="144"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<template>
|
||||||
|
<tileset firstgid="1" source="../Monsters.tsx"/>
|
||||||
|
<object name="Pirate's Treasure" type="Monster" gid="34" width="144" height="144"/>
|
||||||
|
</template>
|
Binary file not shown.
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user