diff --git a/Adventures in Lestoria Tests/EnchantTests.cpp b/Adventures in Lestoria Tests/EnchantTests.cpp index 0c65de8e..8caec339 100644 --- a/Adventures in Lestoria Tests/EnchantTests.cpp +++ b/Adventures in Lestoria Tests/EnchantTests.cpp @@ -1210,5 +1210,20 @@ namespace EnchantTests Assert::AreEqual(player->GetRightClickAbility().GetCooldownTime()-0.25f,player->GetRightClickAbility().cooldown,L"The cooldown should be normal again."); Assert::AreEqual("Wizard.Right Click Ability.Mana Cost"_I,player->GetRightClickAbility().manaCost,L"The mana cost should be normal again."); } + TEST_METHOD(BlackHoleNoEnchantCheck){ + Game::ChangeClass(player,WIZARD); + 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)."); + } + TEST_METHOD(BlackHoleEnchantCheck){ + Game::ChangeClass(player,WIZARD); + Game::GiveAndEquipEnchantedRing("Black Hole"); + 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)."); + } }; } diff --git a/Adventures in Lestoria Tests/EngineTests.cpp b/Adventures in Lestoria Tests/EngineTests.cpp index 310cf51e..c4075919 100644 --- a/Adventures in Lestoria Tests/EngineTests.cpp +++ b/Adventures in Lestoria Tests/EngineTests.cpp @@ -38,6 +38,7 @@ All rights reserved. #include "CppUnitTest.h" #include "AdventuresInLestoria.h" +#include "util.h" using namespace Microsoft::VisualStudio::CppUnitTestFramework; @@ -105,5 +106,22 @@ namespace EngineTests std::u32string u32middleColorCodeStr{middleColorCodeStr.begin(),middleColorCodeStr.end()}; Assert::AreEqual(WHITE.n,testGame->GetFinalRenderColor(WHITE,middleColorCodeStr).n,L"Should use source color since there's no leading HTML color code."); } + TEST_METHOD(UtilMapRangeTest){ + Assert::AreEqual(0.f,util::map_range(0.f,0,100,0,100),L"0 in input range 0-100 output range 0-100 maps to 0"); + Assert::AreEqual(100.f,util::map_range(100.f,0,100,0,100),L"100 in input range 0-100 output range 0-100 maps to 100"); + Assert::AreEqual(50.f,util::map_range(50.f,0,100,0,100),L"50 in input range 0-100 output range 0-100 maps to 100"); + + Assert::AreEqual(0.f,util::map_range(0.f,0,50,0,100),L"0 in input range 0-50 output range 0-100 maps to 0"); + Assert::AreEqual(200.f,util::map_range(100.f,0,50,0,100),L"100 in input range 0-50 output range 0-100 maps to 200"); + Assert::AreEqual(100.f,util::map_range(50.f,0,50,0,100),L"50 in input range 0-50 output range 0-100 maps to 100"); + + Assert::AreEqual(100.f,util::map_range(0.f,0,100,100,200),L"0 in input range 0-100 output range 100-200 maps to 100"); + Assert::AreEqual(200.f,util::map_range(100.f,0,100,100,200),L"100 in input range 0-100 output range 100-200 maps to 200"); + Assert::AreEqual(150.f,util::map_range(50.f,0,100,100,200),L"50 in input range 0-100 output range 100-200 maps to 150"); + + Assert::AreEqual(0.f,util::map_range(0.f,50,100,100,200),L"0 in input range 50-100 output range 100-200 maps to 0"); + Assert::AreEqual(200.f,util::map_range(100.f,50,100,100,200),L"100 in input range 50-100 output range 100-200 maps to 200"); + Assert::AreEqual(100.f,util::map_range(50.f,50,100,100,200),L"50 in input range 50-100 output range 100-200 maps to 100"); + } }; } \ No newline at end of file diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj b/Adventures in Lestoria/Adventures in Lestoria.vcxproj index 44243217..059b048f 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj @@ -387,6 +387,10 @@ + + + + diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters index 8bd1763c..679d796c 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters @@ -684,6 +684,9 @@ Header Files + + Source Files\Effects + diff --git a/Adventures in Lestoria/BlackHole.h b/Adventures in Lestoria/BlackHole.h new file mode 100644 index 00000000..edf487df --- /dev/null +++ b/Adventures in Lestoria/BlackHole.h @@ -0,0 +1,58 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +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 +#include "AdventuresInLestoria.h" +#include "util.h" + +INCLUDE_MONSTER_LIST + +struct BlackHole:FadeInOutEffect{ + inline BlackHole(OscillatorVf2d pos,const std::string&img,float lifetime,float cycleSpd,bool onUpperLevel,OscillatorFloat size,vf2d spd,OscillatorPixel col,float rotation,float rotationSpd,bool additiveBlending=false,float particleSpawnFreq=0.f,const std::function&particleGenerator={}) + :FadeInOutEffect(pos,img,lifetime,cycleSpd,onUpperLevel,size,spd,col,rotation,rotationSpd,additiveBlending,particleSpawnFreq,particleGenerator){} + + inline bool Update(float fElapsedTime){ + for(std::shared_ptr&m:MONSTER_LIST){ + float distToMonster{util::distance(pos,m->GetPos())}; + if(distToMonster<="Black Hole"_ENC["PULL IN RADIUS"]/100.f*24){ + float pullInForce{util::map_range(distToMonster,0,"Black Hole"_ENC["PULL IN RADIUS"]/100.f*24,"Black Hole"_ENC["PULL IN FORCE MAX"],"Black Hole"_ENC["PULL IN FORCE MIN"])}; + m->AddAddedVelocity(util::pointTo(m->GetPos(),pos)*pullInForce); + } + } + return FadeInOutEffect::Update(fElapsedTime); + } +}; \ No newline at end of file diff --git a/Adventures in Lestoria/Effect.cpp b/Adventures in Lestoria/Effect.cpp index 3244f5f7..f7b09441 100644 --- a/Adventures in Lestoria/Effect.cpp +++ b/Adventures in Lestoria/Effect.cpp @@ -119,4 +119,8 @@ const float Effect::GetZ()const{ void Effect::SetType(const EffectType type){ this->type=type; +} + +const bool&Effect::OnUpperLevel()const{ + return upperLevel; } \ No newline at end of file diff --git a/Adventures in Lestoria/Effect.h b/Adventures in Lestoria/Effect.h index 5e4ec3d6..d27f848a 100644 --- a/Adventures in Lestoria/Effect.h +++ b/Adventures in Lestoria/Effect.h @@ -45,13 +45,13 @@ class Player; using HitList=std::unordered_set>; using OscillatorVf2d=std::pair; using OscillatorPixel=std::pair; +using OscillatorFloat=std::pair; enum class EffectType{ NONE, SPELL_CIRCLE, MONSTER_SOUL, BLINK_PORTAL, - BLACK_HOLE, }; struct Effect{ @@ -82,6 +82,7 @@ public: bool OnUpperLevel(); const EffectType GetType()const; const float GetZ()const; + const bool&OnUpperLevel()const; void SetType(const EffectType type); protected: float original_fadeOutTime; @@ -172,23 +173,23 @@ public: struct FadeInOutEffect:Effect{ //cycleSpd is how long it takes to get from fully opaque to fully transparent, and back to fully opaque - - FadeInOutEffect(vf2d pos,const std::string&img,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending=false,float particleSpawnFreq=0.f,const std::function&particleGenerator={}); + FadeInOutEffect(vf2d pos,const std::string&img,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending=false,float particleSpawnFreq=0.f,const std::function&particleGenerator={}); //A version with oscillators for position and colors, for extra animation effects! - FadeInOutEffect(OscillatorVf2d pos,const std::string&img,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,OscillatorPixel col,float rotation,float rotationSpd,bool additiveBlending=false,float particleSpawnFreq=0.f,const std::function&particleGenerator={}); + FadeInOutEffect(OscillatorVf2d pos,const std::string&img,float lifetime,float cycleSpd,bool onUpperLevel,OscillatorFloat size,vf2d spd,OscillatorPixel col,float rotation,float rotationSpd,bool additiveBlending=false,float particleSpawnFreq=0.f,const std::function&particleGenerator={}); virtual bool Update(float fElapsedTime)override; virtual void Draw()const override; - std::functionparticleGenerator; + std::functionparticleGenerator; const float particleSpawnFreq; const float cycleSpd; const OscillatorVf2d posOscillator; + const OscillatorFloat sizeOscillator; const OscillatorPixel colOscillator; float particleSpawnTimer{}; const float originalParticleSpawnTimer{}; }; struct PoisonPool:FadeInOutEffect{ - PoisonPool(vf2d pos,const std::string&img,float radius,int damage,float damageFreq,const HurtType friendly,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending=false,float particleSpawnFreq=0.f,const std::function&particleGenerator={}); + PoisonPool(vf2d pos,const std::string&img,float radius,int damage,float damageFreq,const HurtType friendly,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending=false,float particleSpawnFreq=0.f,const std::function&particleGenerator={}); virtual bool Update(float fElapsedTime)override final; const int damage; float damageTimer{}; diff --git a/Adventures in Lestoria/FadeInOutEffect.cpp b/Adventures in Lestoria/FadeInOutEffect.cpp index b32fc364..b903454a 100644 --- a/Adventures in Lestoria/FadeInOutEffect.cpp +++ b/Adventures in Lestoria/FadeInOutEffect.cpp @@ -39,25 +39,27 @@ All rights reserved. #include "Effect.h" #include "AdventuresInLestoria.h" #include "DEFINES.h" +#include "util.h" INCLUDE_game -FadeInOutEffect::FadeInOutEffect(vf2d pos,const std::string&img,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending,float particleSpawnFreq,const std::function&particleGenerator) - :FadeInOutEffect({pos,pos},img,lifetime,cycleSpd,onUpperLevel,size,spd,{col,col},rotation,rotationSpd,additiveBlending,particleSpawnFreq,particleGenerator){} -FadeInOutEffect::FadeInOutEffect(OscillatorVf2d pos,const std::string&img,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,OscillatorPixel col,float rotation,float rotationSpd,bool additiveBlending,float particleSpawnFreq,const std::function&particleGenerator) - :particleSpawnFreq(particleSpawnFreq),particleGenerator(particleGenerator),cycleSpd(cycleSpd),particleSpawnTimer(particleSpawnFreq),originalParticleSpawnTimer(particleSpawnTimer),posOscillator(pos),colOscillator(col),Effect(pos.first,lifetime,img,onUpperLevel,size,0.25f,spd,col.first,rotation,rotationSpd,additiveBlending){} +FadeInOutEffect::FadeInOutEffect(vf2d pos,const std::string&img,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending,float particleSpawnFreq,const std::function&particleGenerator) + :FadeInOutEffect({pos,pos},img,lifetime,cycleSpd,onUpperLevel,{size,size},spd,{col,{col.r,col.g,col.b,0}},rotation,rotationSpd,additiveBlending,particleSpawnFreq,particleGenerator){} +FadeInOutEffect::FadeInOutEffect(OscillatorVf2d pos,const std::string&img,float lifetime,float cycleSpd,bool onUpperLevel,OscillatorFloat size,vf2d spd,OscillatorPixel col,float rotation,float rotationSpd,bool additiveBlending,float particleSpawnFreq,const std::function&particleGenerator) + :particleSpawnFreq(particleSpawnFreq),particleGenerator(particleGenerator),cycleSpd(cycleSpd),particleSpawnTimer(particleSpawnFreq),originalParticleSpawnTimer(particleSpawnTimer),posOscillator(pos),colOscillator(col),sizeOscillator(size),Effect(pos.first,lifetime,img,onUpperLevel,size.first,0.25f,spd,col.first,rotation,rotationSpd,additiveBlending){} bool FadeInOutEffect::Update(float fElapsedTime){ if(particleGenerator){ particleSpawnTimer-=fElapsedTime; if(particleSpawnTimer<=0.f){ particleSpawnTimer+=originalParticleSpawnTimer; - game->AddEffect(std::make_unique(particleGenerator())); + game->AddEffect(std::make_unique(particleGenerator(*this))); } } float t{float(abs(sin(PI*game->GetRunTime()*cycleSpd)))}; pos=posOscillator.first.lerp(posOscillator.second,t); + size={util::lerp(sizeOscillator.first,sizeOscillator.second,t),util::lerp(sizeOscillator.first,sizeOscillator.second,t)}; col=PixelLerp(colOscillator.first,colOscillator.second,t); - col.a=t*255; + col.a=util::lerp(colOscillator.first.a,colOscillator.second.a,t); return Effect::Update(fElapsedTime); } void FadeInOutEffect::Draw()const{ diff --git a/Adventures in Lestoria/ItemEnchant.h b/Adventures in Lestoria/ItemEnchant.h index 5a7f19eb..f8cdd8dc 100644 --- a/Adventures in Lestoria/ItemEnchant.h +++ b/Adventures in Lestoria/ItemEnchant.h @@ -77,7 +77,7 @@ public: const std::optional&GetAbilitySlot()const; const std::optionalGetAbility()const; //Get the ability this enchant is tied to. const float GetConfigValue(const std::string_view keyName)const; - const float operator[](const std::string& name)const; + const float operator[](const std::string&name)const; private: class ItemEnchantCategoryData{ friend class ItemEnchantInfo; diff --git a/Adventures in Lestoria/Monster.cpp b/Adventures in Lestoria/Monster.cpp index fcbfbc4f..815e6e24 100644 --- a/Adventures in Lestoria/Monster.cpp +++ b/Adventures in Lestoria/Monster.cpp @@ -314,7 +314,7 @@ bool Monster::Update(float fElapsedTime){ } } #pragma endregion - + if(vel.x>0){ vel.x=std::max(0.f,vel.x-friction*fElapsedTime); } else { @@ -325,10 +325,20 @@ bool Monster::Update(float fElapsedTime){ } else { vel.y=std::min(0.f,vel.y+friction*fElapsedTime); } + if(addedVel.x>0){ + addedVel.x=std::max(0.f,addedVel.x-friction*fElapsedTime); + } else { + addedVel.x=std::min(0.f,addedVel.x+friction*fElapsedTime); + } + if(addedVel.y>0){ + addedVel.y=std::max(0.f,addedVel.y-friction*fElapsedTime); + } else { + addedVel.y=std::min(0.f,addedVel.y+friction*fElapsedTime); + } bumpedIntoTerrain=false; - if(vel!=vf2d{0,0}){ - bumpedIntoTerrain|=SetX(pos.x+vel.x*fElapsedTime); - bumpedIntoTerrain|=SetY(pos.y+vel.y*fElapsedTime); + if(vel!=vf2d{0,0}||addedVel!=vf2d{0,0}){ + bumpedIntoTerrain|=SetX(pos.x+vf2d{vel+addedVel}.x*fElapsedTime); + bumpedIntoTerrain|=SetY(pos.y+vf2d{vel+addedVel}.y*fElapsedTime); } if(IsAlive()){ @@ -1610,4 +1620,7 @@ const bool Monster::FaceTarget()const{ } void Monster::ResetCurseOfDeathDamage(){ accumulatedCurseOfDeathDamage=0; +} +void Monster::AddAddedVelocity(vf2d vel){ + this->addedVel+=vel; } \ No newline at end of file diff --git a/Adventures in Lestoria/Monster.h b/Adventures in Lestoria/Monster.h index 41b61c05..7796a973 100644 --- a/Adventures in Lestoria/Monster.h +++ b/Adventures in Lestoria/Monster.h @@ -110,6 +110,7 @@ public: void Collision(Monster&p); void Collision(); void SetVelocity(vf2d vel); + void AddAddedVelocity(vf2d vel); //NOTE: If a monster is trying to set its velocity internally, use SetVelocity() instead. This function is for external sources affecting this monster's velocity. //Returns false if the monster could not be moved to the requested location due to collision. bool SetPos(vf2d pos); //Returns false if the monster could not be moved to the requested location due to collision. @@ -315,6 +316,7 @@ private: void LongLastingMarkEffect(float&out_markDuration); //Modifies a given duration. float stunTimer{}; int accumulatedCurseOfDeathDamage{}; + vf2d addedVel{}; struct STRATEGY{ static std::string ERR; diff --git a/Adventures in Lestoria/PoisonBottle.cpp b/Adventures in Lestoria/PoisonBottle.cpp index 9be0b0ad..26d6beb1 100644 --- a/Adventures in Lestoria/PoisonBottle.cpp +++ b/Adventures in Lestoria/PoisonBottle.cpp @@ -72,7 +72,7 @@ void PoisonBottle::Update(float fElapsedTime){ game->AddEffect(std::make_unique(pos+vf2d{util::random(16)*poisonCircleScale,util::random(2*PI)}.cart(),util::random_range(1.f,4.f),"circle.png",game->GetPlayer()->OnUpperLevel(),vf2d{size,size},util::random_range(0.2f,0.5f),vf2d{util::random_range(-6.f,6.f),util::random_range(-12.f,-4.f)},col)); } if(additionalBounceCount==0&&game->GetPlayer()->HasEnchant("Pooling Poison")){ - game->AddEffect(std::make_unique(pos,"poison_pool.png",bounceExplodeRadius,game->GetPlayer()->GetAttack()*"Pooling Poison"_ENC["POISON POOL DAMAGE PCT"]/100.f,"Pooling Poison"_ENC["POISON POOL DAMAGE FREQUENCY"],friendly?HurtType::MONSTER:HurtType::PLAYER,"Pooling Poison"_ENC["SPLASH LINGER TIME"],0.5f,OnUpperLevel(),poisonCircleScale,vf2d{},WHITE,0.f,0.f,false,0.05f,[pos=pos,col=col,poisonCircleScale](){ + game->AddEffect(std::make_unique(pos,"poison_pool.png",bounceExplodeRadius,game->GetPlayer()->GetAttack()*"Pooling Poison"_ENC["POISON POOL DAMAGE PCT"]/100.f,"Pooling Poison"_ENC["POISON POOL DAMAGE FREQUENCY"],friendly?HurtType::MONSTER:HurtType::PLAYER,"Pooling Poison"_ENC["SPLASH LINGER TIME"],0.5f,OnUpperLevel(),poisonCircleScale,vf2d{},WHITE,0.f,0.f,false,0.05f,[pos=pos,col=col,poisonCircleScale](const Effect&self){ float size{util::random_range(0.4f,0.8f)}; return Effect{pos+vf2d{util::random(16)*poisonCircleScale,util::random(2*PI)}.cart(),util::random_range(1.f,4.f),"circle.png",game->GetPlayer()->OnUpperLevel(),vf2d{size,size},util::random_range(0.2f,0.5f),vf2d{util::random_range(-6.f,6.f),util::random_range(-12.f,-4.f)},col}; }),true); diff --git a/Adventures in Lestoria/PoisonPool.cpp b/Adventures in Lestoria/PoisonPool.cpp index dd838736..841a6f1c 100644 --- a/Adventures in Lestoria/PoisonPool.cpp +++ b/Adventures in Lestoria/PoisonPool.cpp @@ -42,7 +42,7 @@ All rights reserved. INCLUDE_game -PoisonPool::PoisonPool(vf2d pos,const std::string&img,float radius,int damage,float damageFreq,const HurtType friendly,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending,float particleSpawnFreq,const std::function&particleGenerator) +PoisonPool::PoisonPool(vf2d pos,const std::string&img,float radius,int damage,float damageFreq,const HurtType friendly,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending,float particleSpawnFreq,const std::function&particleGenerator) :damage(damage),damageTimer(damageFreq),originalDamageTimer(damageTimer),radius(radius),friendly(friendly),poisonPoolSFXID(SoundEffect::PlayLoopingSFX("Poison Pool",pos)),FadeInOutEffect(pos,img,lifetime,cycleSpd,onUpperLevel,size,spd,col,rotation,rotationSpd,additiveBlending,particleSpawnFreq,particleGenerator){} bool PoisonPool::Update(float fElapsedTime){ diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 567fe8af..a41308ae 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 1 #define VERSION_MINOR 2 #define VERSION_PATCH 5 -#define VERSION_BUILD 11230 +#define VERSION_BUILD 11250 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/Wizard.cpp b/Adventures in Lestoria/Wizard.cpp index feb6f234..7ba4e2cf 100644 --- a/Adventures in Lestoria/Wizard.cpp +++ b/Adventures in Lestoria/Wizard.cpp @@ -44,6 +44,7 @@ All rights reserved. #include "config.h" #include "util.h" #include "SoundEffect.h" +#include "BlackHole.h" INCLUDE_MONSTER_LIST INCLUDE_BULLET_LIST @@ -155,11 +156,19 @@ void Wizard::InitializeClassAbilities(){ if(game->TestingModeEnabled()||dist>0&&p->CanPathfindTo(p->GetPos(),teleportPoint,float("Wizard.Right Click Ability.TilesMax"_I)) &&(NoTileCollisionExistsHere()||NoPlayerCollisionWithTile())){ if(p->HasEnchant("Blink Portal")){ - Effect&eff{game->AddEffect(std::make_unique(OscillatorVf2d{p->GetPos(),p->GetPos()+vf2d{0,-6.f}},"portal.png","Blink Portal"_ENC["REACTIVATION TIME"],0.5f,p->OnUpperLevel(),1.f,vf2d{},OscillatorPixel{WHITE,0x50196f},0.f,0.f),true)}; + Effect&eff{game->AddEffect(std::make_unique(OscillatorVf2d{p->GetPos(),p->GetPos()+vf2d{0,-6.f}},"portal.png","Blink Portal"_ENC["REACTIVATION TIME"],0.5f,p->OnUpperLevel(),OscillatorFloat{0.9f,1.1f},vf2d{},OscillatorPixel{WHITE,0x50196f},0.f,0.f),true)}; eff.SetType(EffectType::BLINK_PORTAL); } TeleportTo(teleportPoint); p->lastPathfindingCooldown=0.1f; + + if(p->HasEnchant("Black Hole")){ + Effect&blackHoleEff{game->AddEffect(std::make_unique(OscillatorVf2d{p->GetPos(),p->GetPos()+vf2d{0,-6.f}},"blackhole.png","Black Hole"_ENC["BLACK HOLE DURATION"],0.75f,p->OnUpperLevel(),OscillatorFloat{3.4f,3.7f},vf2d{},OscillatorPixel{WHITE,WHITE},util::random(2*PI),PI/3,false,0.03f,[](const Effect&self){ + vf2d particlePos{self.pos+vf2d{"Black Hole"_ENC["PULL IN RADIUS"]/100.f*24,util::random(2*PI)}.cart()}; + return Effect{particlePos,util::random_range(0.3f,0.5f),"pixel.png",self.OnUpperLevel(),util::random(2.f),0.1f,util::pointTo(particlePos,self.pos)*util::random_range(700,1000),PixelLerp(BLACK,Pixel(0x9859de),util::random(1.f)),0.f,0.f,false}; + }),true)}; + } + return true; } else { p->NotificationDisplay("Cannot Teleport to that location!",0.5f); diff --git a/Adventures in Lestoria/assets/blackhole.png b/Adventures in Lestoria/assets/blackhole.png index c51b814e..55950863 100644 Binary files a/Adventures in Lestoria/assets/blackhole.png and b/Adventures in Lestoria/assets/blackhole.png differ diff --git a/Adventures in Lestoria/assets/config/items/ItemEnchants.txt b/Adventures in Lestoria/assets/config/items/ItemEnchants.txt index 1f204782..7d286d73 100644 --- a/Adventures in Lestoria/assets/config/items/ItemEnchants.txt +++ b/Adventures in Lestoria/assets/config/items/ItemEnchants.txt @@ -495,6 +495,9 @@ Item Enchants Affects = Right Click Ability BLACK HOLE DURATION = 4s + PULL IN FORCE MIN = 1 + PULL IN FORCE MAX = 6 + PULL IN RADIUS = 350 # Stat, Lowest, Highest Value # Stat Modifier[0] = ..., 0, 0 diff --git a/Adventures in Lestoria/assets/gamepack.pak b/Adventures in Lestoria/assets/gamepack.pak index 28212d2a..499f4145 100644 Binary files a/Adventures in Lestoria/assets/gamepack.pak and b/Adventures in Lestoria/assets/gamepack.pak differ diff --git a/Adventures in Lestoria/util.cpp b/Adventures in Lestoria/util.cpp index 4d8455e5..5d6b2cf1 100644 --- a/Adventures in Lestoria/util.cpp +++ b/Adventures in Lestoria/util.cpp @@ -216,5 +216,4 @@ void util::turn_towards_direction(float&angle,float target,float rate) std::wstring util::to_wstring(const std::string&str){ return {str.begin(),str.end()}; -} - +} \ No newline at end of file diff --git a/Adventures in Lestoria/util.h b/Adventures in Lestoria/util.h index 0c6c716c..ef4038b3 100644 --- a/Adventures in Lestoria/util.h +++ b/Adventures in Lestoria/util.h @@ -73,6 +73,11 @@ namespace olc::util{ std::wstring wformat(std::string str,_Args&..._Vals){ return util::to_wstring(std::vformat(str,std::make_format_args(_Vals...))); } + + template + T map_range(T x, T in_min, T in_max, T out_min, T out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } } template diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index fb6c8629..ce5d6193 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ