Add dynamic cast up for EffectRef .get(). Add EffectTests.cpp to Unit Testing Suite. Down to 6 failing tests.
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 8m39s

This commit is contained in:
AMay 2026-03-30 16:11:44 -05:00
parent 6d15c427a5
commit c891600d29
10 changed files with 37 additions and 24 deletions

1
.gitignore vendored
View File

@ -430,3 +430,4 @@ desktop.ini
tools
/dotnet-tools.json
/Adventures in Lestoria Tests/EffectTests.cpp

View File

@ -107,6 +107,7 @@
<ClCompile Include="BuffTests.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Unit Testing|x64'">$(ProjectDir)..\Adventures in Lestoria\discord-files;$(ProjectDir)..\Adventures in Lestoria\steam;C:\Users\niconiconii\source\repos\AdventuresInLestoria\Adventures in Lestoria\steam;C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\steam;C:\Users\niconiconii\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\niconiconii\OneDrive\Documents\include;C:\Users\sigon\OneDrive\Documents\include;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<ClCompile Include="EffectTests.cpp" />
<ClCompile Include="EnchantTests.cpp">
<SubType>
</SubType>

View File

@ -81,6 +81,9 @@
<ClCompile Include="MonsterTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="EffectTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="GameHelper.h">

View File

@ -39,12 +39,11 @@ All rights reserved.
#include "AdventuresInLestoria.h"
#include "Tutorial.h"
#include <random>
#include <format>
#include "ItemDrop.h"
#include "DamageNumber.h"
#include <ranges>
#include "BulletTypes.h"
#include "GameHelper.h"
#include"SoundEffect.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace olc::utils;
@ -392,17 +391,23 @@ namespace EnchantTests
Monster testMonster2{{},MONSTER_DATA["TestName"]};
testMonster.Hurt(1000,testMonster.OnUpperLevel(),testMonster.GetZ());
Game::Update(0.5f);
for(std::shared_ptr<Effect>&eff:game->GetAllEffects()|std::views::filter([](std::shared_ptr<Effect>&eff){return eff->GetType()==EffectType::MONSTER_SOUL;})){
Assert::Fail(L"A Monster Soul should not be generated");
}
for(EffectData&eff:game->GetAllEffects().first.get()|std::views::filter([](EffectData&eff){return eff.effect&&EFF(*eff.effect).GetType()==EffectType::MONSTER_SOUL;}))Assert::Fail(L"A Monster Soul should not be generated");
for(EffectData&eff:game->GetAllEffects().second.get()|std::views::filter([](EffectData&eff){return eff.effect&&EFF(*eff.effect).GetType()==EffectType::MONSTER_SOUL;}))Assert::Fail(L"A Monster Soul should not be generated");
Game::GiveAndEquipEnchantedRing("Reaper of Souls");
testMonster2.Hurt(1000,testMonster2.OnUpperLevel(),testMonster2.GetZ());
Game::Update(0.5f);
bool foundSoul{false};
for(const std::shared_ptr<Effect>&eff:game->GetAllEffects()|std::views::filter([](const std::shared_ptr<Effect>&eff){return eff->GetType()==EffectType::MONSTER_SOUL;})){
for(const EffectData&eff:game->GetAllEffects().first.get()|std::views::filter([](const EffectData&eff){return eff.effect&&EFF(*eff.effect).GetType()==EffectType::MONSTER_SOUL;})|std::views::take(1)){
foundSoul=true;
break;
}
if(!foundSoul){
for(const EffectData&eff:game->GetAllEffects().second.get()|std::views::filter([](const EffectData&eff){return eff.effect&&EFF(*eff.effect).GetType()==EffectType::MONSTER_SOUL;})|std::views::take(1)){
foundSoul=true;
break;
}
}
if(!foundSoul)Assert::Fail(L"A soul was not generated from a kill with the Reaper of Souls enchant.");
Game::Update(3.5f);
player->Hurt(5,player->OnUpperLevel(),player->GetZ());
@ -420,7 +425,10 @@ namespace EnchantTests
Assert::AreEqual(0.f,player->GetAbility4().cooldown,L"Player's ability cooldowns should reduce from contacting the soul.");
//This should be the moment the wisp is fading out.
Game::Update(0.5f);
for(std::shared_ptr<Effect>&eff:game->GetAllEffects()|std::views::filter([](std::shared_ptr<Effect>&eff){return eff->GetType()==EffectType::MONSTER_SOUL;})){
for(EffectData&eff:game->GetAllEffects().first.get()|std::views::filter([](EffectData&eff){return eff.effect&&EFF(*eff.effect).GetType()==EffectType::MONSTER_SOUL;})){
Assert::Fail(L"A Monster Soul has not disappeared after colliding with a player.");
}
for(EffectData&eff:game->GetAllEffects().second.get()|std::views::filter([](EffectData&eff){return eff.effect&&EFF(*eff.effect).GetType()==EffectType::MONSTER_SOUL;})){
Assert::Fail(L"A Monster Soul has not disappeared after colliding with a player.");
}
}
@ -1268,7 +1276,7 @@ namespace EnchantTests
player->SetTestScreenAimingLocation(player->GetPos()+vf2d{16.f,0.f});
player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput);
Game::Update(0.f);
Assert::AreEqual(size_t(0),game->GetBackgroundEffects().size(),L"There should be no background effects (i.e. Black Holes).");
Assert::AreEqual(size_t(0),EffectManager::GetBackgroundEffectCount(),L"There should be no background effects (i.e. Black Holes).");
}
TEST_METHOD(BlackHoleEnchantCheck){
Game::ChangeClass(player,WIZARD);
@ -1276,7 +1284,7 @@ namespace EnchantTests
player->SetTestScreenAimingLocation(player->GetPos()+vf2d{16.f,0.f});
player->CheckAndPerformAbility(player->GetRightClickAbility(),testKeyboardInput);
Game::Update(0.f);
Assert::AreEqual(size_t(1),game->GetBackgroundEffects().size(),L"There should be a background effect (i.e. the Black Hole).");
Assert::AreEqual(size_t(1),EffectManager::GetBackgroundEffectCount(),L"There should be a background effect (i.e. the Black Hole).");
}
TEST_METHOD(TrailOfFireNoEnchantCheck){
Game::ChangeClass(player,WIZARD);

View File

@ -257,7 +257,7 @@
<AdditionalIncludeDirectories>$(ProjectDir)steam;$(ProjectDir)discord-files;C:\Users\LabUser\source\repos\AdventuresInLestoria\Adventures in Lestoria\steam;C:\Users\LabUser\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\LabUser\Documents\include;C:\Users\niconiconii\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\niconiconii\OneDrive\Documents\include;C:\Users\niconiconii\source\repos\AdventuresInLestoria\Adventures in Lestoria\steam;C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\steam;C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\sigon\OneDrive\Documents\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatSpecificWarningsAsErrors>4099;5030;4715;4172;4834</TreatSpecificWarningsAsErrors>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalOptions>/w14099 /w15030 /w14715 /w14172 /w14834 /D "UNITTESTING" %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/w14099 /w15030 /w14715 /w14172 /w14834 /D "UNITTESTING" /bigobj %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

View File

@ -818,7 +818,7 @@ void AiL::UpdateEffects(float fElapsedTime){
size_t effectSlot{};
std::ranges::for_each(arr,[&fElapsedTime,&effectSlot,&effCount](EffectData&effect){
enum class AliveState:bool{ALIVE,DEAD};
AliveState previousAliveState{!effect.effect?AliveState::DEAD:AliveState::ALIVE};\
AliveState previousAliveState{!effect.effect?AliveState::DEAD:AliveState::ALIVE};
if(previousAliveState==AliveState::DEAD)return;
if(!std::visit(EffectOverloads{},*effect.effect,std::variant<float>{fElapsedTime})){effect.effect.reset();}
AliveState newAliveState{!effect.effect?AliveState::DEAD:AliveState::ALIVE};
@ -4532,7 +4532,7 @@ void AiL::AddToSpecialMarkedTargetList(std::tuple<std::weak_ptr<Monster>,StackCo
lockOnSpecialTargets.emplace_back(markData);
}
[[nodiscard]]std::pair<ForegroundEffectsArr,BackgroundEffectsArr>AiL::GetAllEffects()const{
[[nodiscard]]std::pair<ForegroundEffectsArrRef,BackgroundEffectsArrRef>AiL::GetAllEffects(){
return {EffectManager::GetForegroundEffects(),EffectManager::GetBackgroundEffects()};
}
@ -4621,8 +4621,8 @@ AiL::Notification::Notification(const std::string_view message,const float time,
const std::vector<std::reference_wrapper<EffectData>>AiL::GetEffect(EffectType type){
std::vector<std::reference_wrapper<EffectData>>foundEffects;
std::ranges::copy(GetAllEffects().first|std::views::filter([&type](const EffectData&effect){return EFF(*effect.effect).GetType()==type;})|std::ranges::to<std::vector>(),std::back_inserter(foundEffects));
std::ranges::copy(GetAllEffects().second|std::views::filter([&type](const EffectData&effect){return EFF(*effect.effect).GetType()==type;})|std::ranges::to<std::vector>(),std::back_inserter(foundEffects));
std::ranges::copy(GetAllEffects().first.get()|std::views::filter([&type](const EffectData&effect){return effect.effect&&EFF(*effect.effect).GetType()==type;})|std::ranges::to<std::vector<std::reference_wrapper<EffectData>>>(),std::back_inserter(foundEffects));
std::ranges::copy(GetAllEffects().second.get()|std::views::filter([&type](const EffectData&effect){return effect.effect&&EFF(*effect.effect).GetType()==type;})|std::ranges::to<std::vector<std::reference_wrapper<EffectData>>>(),std::back_inserter(foundEffects));
return foundEffects;
}

View File

@ -83,8 +83,8 @@ using HurtList=std::vector<HurtListItem>;
using StackCount=uint8_t;
using MarkTime=float;
using ForegroundEffectsArr=std::array<EffectData,EFFECT_LIMIT>;
using BackgroundEffectsArr=std::array<EffectData,EFFECT_LIMIT>;
using ForegroundEffectsArrRef=std::reference_wrapper<std::array<EffectData,EFFECT_LIMIT>>;
using BackgroundEffectsArrRef=std::reference_wrapper<std::array<EffectData,EFFECT_LIMIT>>;
enum class KnockbackCondition{
KNOCKBACK_HURT_TARGETS, //Knockback only targets that took damage.
@ -338,7 +338,7 @@ public:
void ResetLevelStates();
std::pair<ForegroundEffectsArr,BackgroundEffectsArr>GetAllEffects()const; //Foreground and background effects in one vector. (Foreground,Background)
std::pair<ForegroundEffectsArrRef,BackgroundEffectsArrRef>GetAllEffects(); //Foreground and background effects in one vector. (Foreground,Background)
struct TileGroupData{
vi2d tilePos;
@ -360,9 +360,9 @@ public:
inline EffectRef<T>AddEffect(const T&effect,bool back=false){
std::array<EffectData,EFFECT_LIMIT>&effectList{back?EffectManager::backgroundEffectList:EffectManager::foregroundEffectList};
for(size_t index{};const EffectData&data:effectList|std::views::drop_while([&index=index](const EffectData&data){
if(!data.effect)return true;
if(!data.effect)return false;
index++;
return false;
return true;
})|std::views::take(1)){
int newEffectId{EffectManager::GLOBAL_EFFECT_ID++};
effectList[index]=EffectData{newEffectId,effect};

View File

@ -144,7 +144,6 @@ const bool Effect::IsDead()const{
}
EffectData::EffectData(){}
EffectData::EffectData(int effectId,const Effect&effect):effectId(effectId),effect(effect){}
void EffectManager::Reset(){
foregroundEffectList.fill({});

View File

@ -38,7 +38,8 @@ struct EffectManager{
friend class AiL;
struct EffectData{
EffectData();
EffectData(int effectId,const Effect&effect);
template<typename T>
EffectData(int effectId,const T&effect):effectId(effectId),effect(effect){}
int effectId{};
std::optional<EffectT>effect{};
};
@ -74,7 +75,7 @@ public:
inline bool expired()const{
const std::array<EffectManager::EffectData,EFFECT_LIMIT>&effectList{foregroundEffect?EffectManager::GetForegroundEffects():EffectManager::GetBackgroundEffects()};
return effectList.at(slotId).effectId!=effectId||effectList.at(slotId).effect;
return !effectList.at(slotId).effect||effectList.at(slotId).effectId!=effectId;
};
inline bool operator==(const EffectRef&ref){
@ -84,7 +85,7 @@ public:
T&get(){
std::array<EffectManager::EffectData,1000>&effectList{foregroundEffect?EffectManager::GetForegroundEffects():EffectManager::GetBackgroundEffects()};
if(expired())ERR("WARNING! This effect was not properly checked for expiration! THIS IS NOT ALLOWED!");
return std::get<T>(*effectList.at(slotId).effect);
return dynamic_cast<T&>(EFF(*effectList.at(slotId).effect));
};
private:
int slotId;

View File

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_PATCH 0
#define VERSION_BUILD 13190
#define VERSION_BUILD 13200
#define stringify(a) stringify_(a)
#define stringify_(a) #a