diff --git a/Adventures in Lestoria Tests/EnchantTests.cpp b/Adventures in Lestoria Tests/EnchantTests.cpp index 8caec339..29d4032c 100644 --- a/Adventures in Lestoria Tests/EnchantTests.cpp +++ b/Adventures in Lestoria Tests/EnchantTests.cpp @@ -1225,5 +1225,18 @@ namespace EnchantTests Game::Update(0.f); Assert::AreEqual(size_t(1),game->GetBackgroundEffects().size(),L"There should be a background effect (i.e. the Black Hole)."); } + TEST_METHOD(FireBoltNoEnchantCheck){ + Game::ChangeClass(player,WIZARD); + player->CheckAndPerformAbility(player->GetAbility1(),testKeyboardInput); + Game::Update(0.5f); + Assert::AreEqual(size_t(0),game->GetEffect(EffectType::TRAIL_OF_FIRE).size(),L"Trail of Fire should not be generated."); + } + TEST_METHOD(FireBoltEnchantCheck){ + Game::ChangeClass(player,WIZARD); + Game::GiveAndEquipEnchantedRing("Trail of Fire"); + player->CheckAndPerformAbility(player->GetAbility1(),testKeyboardInput); + Game::Update(0.5f); + Assert::AreEqual(size_t(1),game->GetEffect(EffectType::TRAIL_OF_FIRE).size(),L"Trail of Fire should be generated with the enchant."); + } }; } diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index dc39ea1a..3159d77b 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -1425,7 +1425,7 @@ void AiL::RenderWorld(float fElapsedTime){ auto it=backgroundEffectsLower.begin(); while(it!=backgroundEffectsLower.end()){ const Effect&e=**it; - e.Draw(); + e._Draw(); ++it; } } @@ -1566,7 +1566,7 @@ void AiL::RenderWorld(float fElapsedTime){ ++monstersBeforeLowerIt; } for(const Effect*const e:backgroundEffectsLower){ - e->Draw(); + e->_Draw(); } while(dropsBeforeLowerIt!=dropsBeforeLower.end()){ const int dropInd=*dropsBeforeLowerIt; @@ -1595,7 +1595,7 @@ void AiL::RenderWorld(float fElapsedTime){ b->_Draw(); } for(const Effect*const e:foregroundEffectsLower){ - e->Draw(); + e->_Draw(); } #pragma endregion #pragma region Permanent Foreground Rendering @@ -1718,7 +1718,7 @@ void AiL::RenderWorld(float fElapsedTime){ auto it=backgroundEffectsUpper.begin(); while(it!=backgroundEffectsUpper.end()){ const Effect&e=**it; - e.Draw(); + e._Draw(); ++it; } } @@ -1867,7 +1867,7 @@ void AiL::RenderWorld(float fElapsedTime){ ++monstersBeforeUpperIt; } for(const Effect*const e:backgroundEffectsUpper){ - e->Draw(); + e->_Draw(); } while(dropsBeforeUpperIt!=dropsBeforeUpper.end()){ const int dropInd=*dropsBeforeUpperIt; @@ -1896,7 +1896,7 @@ void AiL::RenderWorld(float fElapsedTime){ b->_Draw(); } for(const Effect*const e:foregroundEffectsUpper){ - e->Draw(); + e->_Draw(); } #pragma endregion #pragma region Permanent Upper Foreground Rendering diff --git a/Adventures in Lestoria/Effect.cpp b/Adventures in Lestoria/Effect.cpp index f7b09441..6667000f 100644 --- a/Adventures in Lestoria/Effect.cpp +++ b/Adventures in Lestoria/Effect.cpp @@ -54,7 +54,7 @@ Effect::Effect(vf2d pos,float lifetime,const std::string&imgFile,bool upperLevel :Effect(pos,lifetime,imgFile,upperLevel,fadein,fadeout,size,spd,EffectType::NONE,col,rotation,rotationSpd,additiveBlending){} Effect::Effect(vf2d pos,float lifetime,const std::string&imgFile,bool upperLevel,float fadein,float fadeout,vf2d size,vf2d spd,EffectType type,Pixel col,float rotation,float rotationSpd,bool additiveBlending) - :pos(pos),lifetime(lifetime),upperLevel(upperLevel),size(size),fadein(fadein),original_fadeInTime(fadein),fadeout(fadeout),original_fadeOutTime(fadeout),spd(spd),col(col),rotation(rotation),rotationSpd(rotationSpd),additiveBlending(additiveBlending){ + :pos(pos),lifetime(lifetime),upperLevel(upperLevel),size(size),fadein(fadein),original_fadeInTime(fadein),fadeout(fadeout),original_fadeOutTime(fadeout),spd(spd),col(col),rotation(rotation),rotationSpd(rotationSpd),additiveBlending(additiveBlending),type(type){ this->animation.AddState(imgFile,ANIMATION_DATA.at(imgFile)); this->animation.ChangeState(internal_animState,imgFile); } @@ -80,7 +80,7 @@ bool Effect::Update(float fElapsedTime){ return true; } -void Effect::Draw()const{ +void Effect::_Draw()const{ if(additiveBlending)game->SetDecalMode(DecalMode::ADDITIVE); const bool FadeInFinished{original_fadeInTime==0||fadein==original_fadeInTime}; const bool HasFadeout{fadeout>0}; @@ -90,17 +90,22 @@ void Effect::Draw()const{ game->view.DrawDecal(pos-vf2d{3,3}*shadowScale/2+vf2d{0,12*size.y},GFX["circle.png"].Decal(),shadowScale,BLACK); } + Pixel blendCol{col}; [[unlikely]]if(!FadeInFinished){ - game->view.DrawPartialRotatedDecal(pos-vf2d{0,GetZ()},GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,{col.r,col.g,col.b,uint8_t(fadein/original_fadeInTime*col.a)}); + blendCol={col.r,col.g,col.b,uint8_t(fadein/original_fadeInTime*col.a)}; }else [[likely]]if(HasFadeout){ - game->view.DrawPartialRotatedDecal(pos-vf2d{0,GetZ()},GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,{col.r,col.g,col.b,uint8_t(fadeout/original_fadeOutTime*col.a)}); - }else{ - game->view.DrawPartialRotatedDecal(pos-vf2d{0,GetZ()},GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,col); + blendCol={col.r,col.g,col.b,uint8_t(fadeout/original_fadeOutTime*col.a)}; } + Draw(blendCol); + game->SetDecalMode(DecalMode::NORMAL); } +void Effect::Draw(const Pixel blendCol)const{ + game->view.DrawPartialRotatedDecal(pos-vf2d{0,GetZ()},GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,blendCol); +} + Animate2D::Frame Effect::GetFrame()const{ return animation.GetFrame(internal_animState); } diff --git a/Adventures in Lestoria/Effect.h b/Adventures in Lestoria/Effect.h index 7448a9de..b6fdf71d 100644 --- a/Adventures in Lestoria/Effect.h +++ b/Adventures in Lestoria/Effect.h @@ -50,6 +50,7 @@ enum class EffectType{ SPELL_CIRCLE, MONSTER_SOUL, BLINK_PORTAL, + TRAIL_OF_FIRE, }; struct Effect{ @@ -76,7 +77,8 @@ public: Effect(vf2d pos,float lifetime,const std::string&imgFile,bool upperLevel,float fadein,float fadeout,vf2d size,vf2d spd,EffectType type,Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false); virtual bool Update(float fElapsedTime); Animate2D::Frame GetFrame()const; - virtual void Draw()const; + void _Draw()const; + virtual void Draw(const Pixel blendCol)const; bool OnUpperLevel(); const EffectType GetType()const; const float GetZ()const; @@ -98,7 +100,7 @@ struct Meteor:Effect{ float startLifetime=0; bool shakeField=false; bool Update(float fElapsedTime)override; - void Draw()const override; + void Draw(const Pixel blendCol)const override; }; struct PulsatingFire:Effect{ @@ -107,7 +109,7 @@ struct PulsatingFire:Effect{ float lastParticleTimer=0; float lastDamageTimer=0; bool Update(float fElapsedTime)override; - void Draw()const override; + void Draw(const Pixel blendCol)const override; }; struct SwordSlash:Effect{ @@ -123,7 +125,7 @@ private: struct ForegroundEffect:Effect{ ForegroundEffect(vf2d pos,float lifetime,std::string imgFile,bool upperLevel,float size=1.0f,float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false); ForegroundEffect(vf2d pos,float lifetime,std::string imgFile,bool upperLevel,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false); - virtual void Draw()const override final; + virtual void Draw(const Pixel blendCol)const override final; }; struct SpellCircle:Effect{ @@ -131,7 +133,7 @@ struct SpellCircle:Effect{ SpellCircle(vf2d pos,float lifetime,std::string imgFile,std::string spellInsigniaFile,bool upperLevel,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false,vf2d insigniaSize={1,1},float insigniaFadeout=0.0f,vf2d insigniaSpd={},Pixel insigniaCol=WHITE,float insigniaRotation=0,float insigniaRotationSpd=0,bool insigniaAdditiveBlending=false); Effect spellInsignia{vf2d{},0.f,"spell_insignia.png",false,{}}; virtual bool Update(float fElapsedTime)override final; - virtual void Draw()const override final; + virtual void Draw(const Pixel blendCol)const override final; }; struct RockLaunch:Effect{ @@ -156,7 +158,7 @@ private: struct MonsterSoul:Effect{ MonsterSoul(vf2d pos,float fadeoutTime,float size,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending=false); virtual bool Update(float fElapsedTime)override final; - virtual void Draw()const override final; + virtual void Draw(const Pixel blendCol)const override final; public: enum Phase{ RISING, @@ -175,7 +177,7 @@ struct FadeInOutEffect:Effect{ //A version with oscillators for position and colors, for extra animation effects! FadeInOutEffect(Oscillatorpos,const std::string&img,float lifetime,bool onUpperLevel,Oscillatorsize,vf2d spd,Oscillatorcol,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; + virtual void Draw(const Pixel blendCol)const override; std::functionparticleGenerator; const float particleSpawnFreq; OscillatorposOscillator; diff --git a/Adventures in Lestoria/FadeInOutEffect.cpp b/Adventures in Lestoria/FadeInOutEffect.cpp index 771d85d3..ddb4301f 100644 --- a/Adventures in Lestoria/FadeInOutEffect.cpp +++ b/Adventures in Lestoria/FadeInOutEffect.cpp @@ -60,6 +60,6 @@ bool FadeInOutEffect::Update(float fElapsedTime){ col=colOscillator.Update(fElapsedTime); return Effect::Update(fElapsedTime); } -void FadeInOutEffect::Draw()const{ - Effect::Draw(); +void FadeInOutEffect::Draw(const Pixel blendCol)const{ + Effect::Draw(blendCol); } \ No newline at end of file diff --git a/Adventures in Lestoria/FallingStone.cpp b/Adventures in Lestoria/FallingStone.cpp index 7910e86d..e127f713 100644 --- a/Adventures in Lestoria/FallingStone.cpp +++ b/Adventures in Lestoria/FallingStone.cpp @@ -84,7 +84,7 @@ void FallingStone::Update(float fElapsedTime){ } void FallingStone::Draw(const Pixel blendCol)const{ if(lifetime<=indicatorDisplayTime){ - indicator.Draw(); + indicator._Draw(); } Bullet::Draw(blendCol); } diff --git a/Adventures in Lestoria/FireBolt.cpp b/Adventures in Lestoria/FireBolt.cpp index 3118b059..f52e9310 100644 --- a/Adventures in Lestoria/FireBolt.cpp +++ b/Adventures in Lestoria/FireBolt.cpp @@ -41,13 +41,16 @@ All rights reserved. #include "DEFINES.h" #include "util.h" #include "SoundEffect.h" +#include "TrailEffect.h" INCLUDE_game INCLUDE_MONSTER_LIST FireBolt::FireBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) :Bullet(pos,vel,radius,damage, - "energy_bolt.png",upperLevel,false,INFINITE,true,friendly,col){} + "energy_bolt.png",upperLevel,false,INFINITE,true,friendly,col){ + if(game->GetPlayer()->HasEnchant("Trail of Fire"))flameTrail=dynamic_cast(game->AddEffect(std::make_unique(pos,"Trail of Fire"_ENC["TRAIL DURATION"],"FlamesTexture.png","Trail of Fire"_ENC["TRAIL DAMAGE"]/100.f*game->GetPlayer()->GetAttack(),"Trail of Fire"_ENC["TRAIL TICK FREQUENCY"],upperLevel,1.f,vf2d{1.f,2.f},30000.f,Oscillator{{255,0,0,128},Pixel(0xE74F30),2.f},EffectType::TRAIL_OF_FIRE,true),true)); +} void FireBolt::Update(float fElapsedTime){ lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); @@ -72,6 +75,8 @@ void FireBolt::Update(float fElapsedTime){ SoundEffect::PlaySFX("Wizard Fire Bolt Hit",pos); } + + if(flameTrail)flameTrail.value().get().SetEndPos(pos); } BulletDestroyState FireBolt::PlayerHit(Player*player) diff --git a/Adventures in Lestoria/ForegroundEffect.cpp b/Adventures in Lestoria/ForegroundEffect.cpp index 2cbe3a94..801e596e 100644 --- a/Adventures in Lestoria/ForegroundEffect.cpp +++ b/Adventures in Lestoria/ForegroundEffect.cpp @@ -47,12 +47,6 @@ ForegroundEffect::ForegroundEffect(vf2d pos,float lifetime,std::string imgFile,b :Effect(pos,lifetime,imgFile,upperLevel,size,fadeout,spd,col,rotation,rotationSpd,additiveBlending){} ForegroundEffect::ForegroundEffect(vf2d pos,float lifetime,std::string imgFile,bool upperLevel,vf2d size,float fadeout,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending) :Effect(pos,lifetime,imgFile,upperLevel,size,fadeout,spd,col,rotation,rotationSpd,additiveBlending){} -void ForegroundEffect::Draw()const{ - if(additiveBlending)game->SetDecalMode(DecalMode::ADDITIVE); - if(fadeout==0){ - game->DrawPartialRotatedDecal(pos,GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,col); - } else { - game->DrawPartialRotatedDecal(pos,GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,{col.r,col.g,col.b,uint8_t(fadeout/original_fadeOutTime*255)}); - } - game->SetDecalMode(DecalMode::NORMAL); +void ForegroundEffect::Draw(const Pixel blendCol)const{ + game->DrawPartialRotatedDecal(pos,GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,blendCol); } \ No newline at end of file diff --git a/Adventures in Lestoria/Meteor.cpp b/Adventures in Lestoria/Meteor.cpp index a3139e0a..cb9b6b24 100644 --- a/Adventures in Lestoria/Meteor.cpp +++ b/Adventures in Lestoria/Meteor.cpp @@ -70,7 +70,7 @@ bool Meteor::Update(float fElapsedTime){ return Effect::Update(fElapsedTime); } -void Meteor::Draw()const{ +void Meteor::Draw(const Pixel blendCol)const{ if(lifetime>0){ vf2d scale=vf2d{192,64}/3.f*(startLifetime+1-lifetime)*0.25*size; vf2d meteorOffset=vf2d{lifetime*"Wizard.Ability 3.MeteorXMovementMult"_I,0}*"Wizard.Ability 3.MeteorShadowStartingDist"_F; diff --git a/Adventures in Lestoria/MonsterSoul.cpp b/Adventures in Lestoria/MonsterSoul.cpp index bd3d4d46..a48da09d 100644 --- a/Adventures in Lestoria/MonsterSoul.cpp +++ b/Adventures in Lestoria/MonsterSoul.cpp @@ -84,9 +84,9 @@ bool MonsterSoul::Update(float fElapsedTime){ } return updateResult; } -void MonsterSoul::Draw()const{ +void MonsterSoul::Draw(const Pixel blendCol)const{ game->SetDecalMode(DecalMode::ADDITIVE); game->view.DrawRotatedDecal(pos-vf2d{0,GetZ()},GFX["monstersoulglow.png"].Decal(),0.f,GFX["monstersoulglow.png"].Sprite()->Size()/2,size*util::lerp(0.6f,1.4f,abs(sin(2*PI*lifetime)))); game->SetDecalMode(DecalMode::NORMAL); - Effect::Draw(); + Effect::Draw(blendCol); } \ No newline at end of file diff --git a/Adventures in Lestoria/Oscillator.h b/Adventures in Lestoria/Oscillator.h index 7f5d580e..fc6c1ba9 100644 --- a/Adventures in Lestoria/Oscillator.h +++ b/Adventures in Lestoria/Oscillator.h @@ -42,16 +42,16 @@ All rights reserved. template class Oscillator{ public: - Oscillator() + inline Oscillator() :Oscillator({},{},0.f){} - Oscillator(T val1,T val2,float cycleSpd) + inline Oscillator(T val1,T val2,float cycleSpd) :val1(val1),val2(val2),first(this->val1),second(this->val2),cycleSpd(cycleSpd),currentVal(val1){} - const T&Update(const float fElapsedTime){ + inline const T&Update(const float fElapsedTime){ currentVal=util::lerp(val1,val2,sin(PI*timer*cycleSpd)/2+0.5f); timer+=fElapsedTime; return get(); } - const T&get(){ + inline const T&get()const{ return currentVal; }; const T&first; diff --git a/Adventures in Lestoria/PulsatingFire.cpp b/Adventures in Lestoria/PulsatingFire.cpp index 942cdcdc..fb2f2bfe 100644 --- a/Adventures in Lestoria/PulsatingFire.cpp +++ b/Adventures in Lestoria/PulsatingFire.cpp @@ -75,7 +75,7 @@ bool PulsatingFire::Update(float fElapsedTime){ return Effect::Update(fElapsedTime); } -void PulsatingFire::Draw()const{ +void PulsatingFire::Draw(const Pixel blendCol)const{ for(int i=0;i<8;i++){ Animate2D::FrameSequence*effectSpr=nullptr; switch(int(pulsatingFireValues[i]*5)){ diff --git a/Adventures in Lestoria/SoundEffect.cpp b/Adventures in Lestoria/SoundEffect.cpp index 19f90ff4..44db324c 100644 --- a/Adventures in Lestoria/SoundEffect.cpp +++ b/Adventures in Lestoria/SoundEffect.cpp @@ -86,7 +86,7 @@ void SoundEffect::Initialize(){ } } -void SoundEffect::PlaySFX(const std::string_view eventName,const vf2d&pos){ +void SoundEffect::PlaySFX(const std::string&eventName,const vf2d&pos){ if(game->TestingModeEnabled()||eventName.length()==0)return; const SoundEffect&sfx=GetRandomSFXFromFile(eventName); @@ -112,7 +112,7 @@ void SoundEffect::PlaySFX(const std::string_view eventName,const vf2d&pos){ } } -size_t SoundEffect::PlayLoopingSFX(const std::string_view eventName,const vf2d&pos){ +size_t SoundEffect::PlayLoopingSFX(const std::string&eventName,const vf2d&pos){ if(game->TestingModeEnabled()||eventName.length()==0)return 0U; const SoundEffect&sfx=GetRandomSFXFromFile(eventName); const size_t id=Audio::Engine().LoadSound(operator""_SFX(sfx.filename.c_str(),sfx.filename.length())); @@ -128,8 +128,8 @@ void SoundEffect::StopLoopingSFX(const int id){ RepeatingSoundEffect::playingSoundEffects.erase(id); } -SoundEffect&SoundEffect::GetRandomSFXFromFile(const std::string_view eventName){ - auto itr=SOUND_EFFECTS.equal_range(std::string(eventName)); +SoundEffect&SoundEffect::GetRandomSFXFromFile(const std::string&eventName){ + auto itr=SOUND_EFFECTS.equal_range(eventName); size_t soundCount=std::distance(itr.first,itr.second); if(soundCount==0)ERR("WARNING! Sound Effect "<SOUND_EFFECTS; std::string filename; float vol; diff --git a/Adventures in Lestoria/SpellCircle.cpp b/Adventures in Lestoria/SpellCircle.cpp index 34338715..11c81ebb 100644 --- a/Adventures in Lestoria/SpellCircle.cpp +++ b/Adventures in Lestoria/SpellCircle.cpp @@ -45,9 +45,9 @@ SpellCircle::SpellCircle(vf2d pos,float lifetime,std::string imgFile,std::string SpellCircle::SpellCircle(vf2d pos,float lifetime,std::string imgFile,std::string spellInsigniaFile,bool upperLevel,float size,float fadeout,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending,float insigniaSize,float insigniaFadeout,vf2d insigniaSpd,Pixel insigniaCol,float insigniaRotation,float insigniaRotationSpd,bool insigniaAdditiveBlending) :SpellCircle(pos,lifetime,imgFile,spellInsigniaFile,upperLevel,vf2d{size,size},fadeout,spd,col,rotation,rotationSpd,additiveBlending,vf2d{insigniaSize,insigniaSize},insigniaFadeout,insigniaSpd,insigniaCol,insigniaRotation,insigniaRotationSpd,insigniaAdditiveBlending){} -void SpellCircle::Draw()const{ - Effect::Draw(); - spellInsignia.Draw(); +void SpellCircle::Draw(const Pixel blendCol)const{ + Effect::Draw(blendCol); + spellInsignia._Draw(); } bool SpellCircle::Update(float fElapsedTime){ diff --git a/Adventures in Lestoria/TrailEffect.h b/Adventures in Lestoria/TrailEffect.h index 7b19df11..a59eb649 100644 --- a/Adventures in Lestoria/TrailEffect.h +++ b/Adventures in Lestoria/TrailEffect.h @@ -37,21 +37,68 @@ All rights reserved. #pragma endregion #pragma once -#include "Effect.h" +#include "AdventuresInLestoria.h" +#include "SoundEffect.h" -class TrailEffect:Effect{ - inline TrailEffect(vf2d startPos,float lifetime,const std::string&imgFile,bool upperLevel,float fadeout,vf2d scale,float imgXOffsetSpd,Oscillatorcol,EffectType type=EffectType::NONE,bool additiveBlending=false) - :Effect(pos,lifetime,imgFile,upperLevel,scale,fadeout,{},col.first,0.f,0.f,additiveBlending){} +INCLUDE_game +INCLUDE_GFX +INCLUDE_MONSTER_LIST + +struct TrailEffect:Effect{ + inline TrailEffect(vf2d startPos,float lifetime,const std::string&imgFile,int damage,float damageTickFrequency,bool upperLevel,float fadeout,vf2d scale,float imgXOffsetSpd,Oscillatorcol,EffectType type=EffectType::NONE,bool additiveBlending=false) + :endPos(startPos),imageXSpd(imgXOffsetSpd),damage(damage),col(col),damageTickFrequency(damageTickFrequency),Effect(startPos,lifetime,imgFile,upperLevel,0.f,fadeout,scale,{},type,WHITE,0.f,0.f,additiveBlending){} inline void SetEndPos(const vf2d pos){ this->endPos=pos; } inline bool Update(float fElapsedTime){ col.Update(fElapsedTime); + imageXOffset+=imageXSpd*fElapsedTime; + rotation=util::angleTo(pos,endPos); + hitTimer-=fElapsedTime; + + if(hitTimer<=0.f){ + for(std::shared_ptr&monster:MONSTER_LIST){ + vf2d closestPointToFlameTrail{geom2d::closest(geom2d::line{pos,endPos},monster->GetPos())}; + float distToTrail{util::distance(monster->GetPos(),closestPointToFlameTrail)}; + if(!monster->InUndamageableState(OnUpperLevel(),GetZ())&&distToTrail<=12*size.y){ + monster->Hurt(damage,OnUpperLevel(),GetZ(),HurtFlag::DOT); + SoundEffect::PlaySFX("Burn",monster->GetPos()); + } + } + hitTimer+=damageTickFrequency; + } + + return Effect::Update(fElapsedTime); } - inline void Draw()const{ - + inline void Draw(const Pixel blendCol)const{ + geom2d::lineflameTrailLine{pos,endPos}; + geom2d::lineflameTrailLineRectLine1{pos+vf2d{GetFrame().GetSourceImage()->Sprite()->height/2.f*size.y,rotation-PI/2}.cart(),endPos+vf2d{GetFrame().GetSourceImage()->Sprite()->height/2.f*size.y,rotation-PI/2}.cart()}; + geom2d::lineflameTrailLineRectLine2{pos+vf2d{GetFrame().GetSourceImage()->Sprite()->height/2.f*size.y,rotation+PI/2}.cart(),endPos+vf2d{GetFrame().GetSourceImage()->Sprite()->height/2.f*size.y,rotation+PI/2}.cart()}; + vf2d flameTrailSize{flameTrailLine.length(),float(GetFrame().GetSourceImage()->Sprite()->height)}; + flameTrailSize*=size; + + const auto PixelToUVSpace=[this,&flameTrailSize](vf2d pixelPos){ + pixelPos.x+=imageXOffset; + return pixelPos/GetFrame().GetSourceImage()->Sprite()->Size()/size; + }; + + game->view.DrawPolygonDecal(GetFrame().GetSourceImage()->Decal(),std::vector{ + flameTrailLine.upoint(0.5f),flameTrailLineRectLine1.start,flameTrailLineRectLine1.upoint(0.5f),flameTrailLineRectLine1.end, + flameTrailLineRectLine2.end,flameTrailLineRectLine2.upoint(0.5f),flameTrailLineRectLine2.start,flameTrailLineRectLine1.start, + },std::vector{ + PixelToUVSpace(flameTrailSize/2),PixelToUVSpace({}),PixelToUVSpace({flameTrailSize.x/2.f,0}),PixelToUVSpace({flameTrailSize.x,0.f}), + PixelToUVSpace(flameTrailSize),PixelToUVSpace({flameTrailSize.x/2.f,flameTrailSize.y}),PixelToUVSpace({0.f,flameTrailSize.y}),PixelToUVSpace({}), + },std::vector{ + col.get(),{0,0,0,0},col.get(),{0,0,0,0}, + {0,0,0,0},col.get(),{0,0,0,0},{0,0,0,0}, + },blendCol); } private: Oscillatorcol; vf2d endPos{}; + float imageXSpd; + float imageXOffset{}; + int damage; + float damageTickFrequency; + float hitTimer{}; }; \ No newline at end of file diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 2ca71a36..1031e69b 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 11271 +#define VERSION_BUILD 11309 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/assets/FlamesTexture.png b/Adventures in Lestoria/assets/FlamesTexture.png index 31995652..4363a4ec 100644 Binary files a/Adventures in Lestoria/assets/FlamesTexture.png and b/Adventures in Lestoria/assets/FlamesTexture.png differ diff --git a/Adventures in Lestoria/assets/config/audio/events.txt b/Adventures in Lestoria/assets/config/audio/events.txt index df3508d8..4c0a1e63 100644 --- a/Adventures in Lestoria/assets/config/audio/events.txt +++ b/Adventures in Lestoria/assets/config/audio/events.txt @@ -56,6 +56,11 @@ Events # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) File[0] = bomb_explosion.ogg, 100% } + Burn + { + # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) + File[0] = burn.ogg, 70% + } Button Click { # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) diff --git a/Adventures in Lestoria/assets/config/items/ItemEnchants.txt b/Adventures in Lestoria/assets/config/items/ItemEnchants.txt index 7d286d73..b4cc7806 100644 --- a/Adventures in Lestoria/assets/config/items/ItemEnchants.txt +++ b/Adventures in Lestoria/assets/config/items/ItemEnchants.txt @@ -504,11 +504,12 @@ Item Enchants } Trail of Fire { - Description = "The Firebolt leaves behind a trail of fire, burning targets standing in it for {TRAIL DAMAGE}% attack every second for {TRAIL DURATION} seconds." + Description = "Firebolt leaves behind a trail of fire, burning targets standing in it for {TRAIL DAMAGE}% attack every second for {TRAIL DURATION} seconds." Affects = Ability 1 - TRAIL DAMAGE = 10% + TRAIL DAMAGE = 30% TRAIL DURATION = 10s + TRAIL TICK FREQUENCY = 1s # 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 499f4145..d60bfa9c 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/assets/sounds/burn.ogg b/Adventures in Lestoria/assets/sounds/burn.ogg new file mode 100644 index 00000000..a8b1380b Binary files /dev/null and b/Adventures in Lestoria/assets/sounds/burn.ogg differ diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 59306d32..a9e45195 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ