# 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 "BulletTypes.h"
# include "Effect.h"
# include "AdventuresInLestoria.h"
# 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 ) {
if ( game - > GetPlayer ( ) - > HasEnchant ( " Trail of Fire " ) ) flameTrail = dynamic_cast < TrailEffect & > ( game - > AddEffect ( std : : make_unique < TrailEffect > ( 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 < Pixel > { { 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 ) ;
if ( lastParticleSpawn = = 0 ) {
lastParticleSpawn = " Wizard.Ability 1.ParticleFrequency " _F ;
game - > AddEffect ( std : : make_unique < Effect > ( pos , " Wizard.Ability 1.ParticleLifetimeRange " _FRange , " energy_particle.png " , upperLevel , " Wizard.Ability 1.ParticleSizeRange " _FRange , " Wizard.Ability 1.ParticleFadeoutTime " _F , vf2d { " Wizard.Ability 1.ParticleXSpeedRange " _FRange , " Wizard.Ability 1.ParticleYSpeedRange " _FRange } , Pixel { uint8_t ( " Wizard.Ability 1.ParticleRedRange " _FRange ) , uint8_t ( " Wizard.Ability 1.ParticleGreenRange " _FRange ) , uint8_t ( " Wizard.Ability 1.ParticleBlueRange " _FRange ) , uint8_t ( " Wizard.Ability 1.ParticleAlphaRange " _FRange ) } ) ) ;
}
if ( distanceTraveled > " Wizard.Ability 1.Max Range " _F & & IsActivated ( ) ) {
fadeOutTime = " Wizard.Ability 1.BulletHitFadeoutTime " _F ;
for ( int i = 0 ; i < " Wizard.Ability 1.BulletHitExplosionParticleCount " _I ; i + + ) {
game - > AddEffect ( std : : make_unique < Effect > ( pos , " Wizard.Ability 1.BulletHitExplosionParticleLifetimeRange " _FRange , " circle.png " , upperLevel , " Wizard.Ability 1.BulletHitExplosionParticleSizeRange " _FRange , " Wizard.Ability 1.BulletHitExplosionParticleFadeoutTimeRange " _FRange , vf2d { " Wizard.Ability 1.BulletHitExplosionParticleSpeedRange " _FRange , " Wizard.Ability 1.BulletHitExplosionParticleSpeedRange " _FRange } , Pixel { uint8_t ( " Wizard.Ability 1.BulletHitExplosionParticleRedRange " _FRange ) , uint8_t ( " Wizard.Ability 1.BulletHitExplosionParticleGreenRange " _FRange ) , uint8_t ( " Wizard.Ability 1.BulletHitExplosionParticleBlueRange " _FRange ) , uint8_t ( " Wizard.Ability 1.BulletHitExplosionParticleAlphaRange " _FRange ) } ) ) ;
}
game - > SetupWorldShake ( " Wizard.Ability 1.WorldShakeTime " _F ) ;
if ( friendly ) {
game - > Hurt ( pos , " Wizard.Ability 1.BulletHitExplosionRange " _F / 100 * 12 , int ( " Wizard.Ability 1.BulletHitExplosionDamageMult " _F * game - > GetPlayer ( ) - > GetAttack ( ) ) , OnUpperLevel ( ) , 0 , HurtType : : MONSTER , HurtFlag : : PLAYER_ABILITY ) ;
} else {
if ( geom2d : : overlaps ( geom2d : : circle < float > { pos , " Wizard.Ability 1.BulletHitExplosionRange " _F / 100 * 12 } , geom2d : : circle < float > { game - > GetPlayer ( ) - > GetPos ( ) , 12.f } ) ) {
game - > GetPlayer ( ) - > Hurt ( damage , OnUpperLevel ( ) , 0.f ) ;
}
}
game - > AddEffect ( std : : make_unique < Effect > ( pos , 0 , " splash_effect.png " , upperLevel , " Wizard.Ability 1.BulletHitExplosionRange " _F / 100 * 2 , " Wizard.Ability 1.BulletHitExplosionFadeoutTime " _F , vf2d { } , " Wizard.Ability 1.BulletHitExplosionColor " _Pixel ) ) ;
SoundEffect : : PlaySFX ( " Wizard Fire Bolt Hit " , pos ) ;
}
if ( flameTrail ) flameTrail . value ( ) . get ( ) . SetEndPos ( pos ) ;
}
BulletDestroyState FireBolt : : PlayerHit ( Player * player )
{
fadeOutTime = " Wizard.Ability 1.BulletHitFadeoutTime " _F ;
for ( int i = 0 ; i < " Wizard.Ability 1.BulletHitExplosionParticleCount " _I ; i + + ) {
game - > AddEffect ( std : : make_unique < Effect > ( player - > GetPos ( ) , " Wizard.Ability 1.BulletHitExplosionParticleLifetimeRange " _FRange , " circle.png " , upperLevel , " Wizard.Ability 1.BulletHitExplosionParticleSizeRange " _FRange , " Wizard.Ability 1.BulletHitExplosionParticleFadeoutTimeRange " _FRange , vf2d { " Wizard.Ability 1.BulletHitExplosionParticleSpeedRange " _FRange , " Wizard.Ability 1.BulletHitExplosionParticleSpeedRange " _FRange } , Pixel { uint8_t ( " Wizard.Ability 1.BulletHitExplosionParticleRedRange " _FRange ) , uint8_t ( " Wizard.Ability 1.BulletHitExplosionParticleGreenRange " _FRange ) , uint8_t ( " Wizard.Ability 1.BulletHitExplosionParticleBlueRange " _FRange ) , uint8_t ( " Wizard.Ability 1.BulletHitExplosionParticleAlphaRange " _FRange ) } ) ) ;
game - > SetupWorldShake ( " Wizard.Ability 1.WorldShakeTime " _F ) ; }
game - > AddEffect ( std : : make_unique < Effect > ( player - > GetPos ( ) , 0 , " splash_effect.png " , upperLevel , 5 , 0.25 , vf2d { } , Pixel { 240 , 120 , 60 } ) ) ;
SoundEffect : : PlaySFX ( " Wizard Fire Bolt Hit " , pos ) ;
return BulletDestroyState : : KEEP_ALIVE ;
}
BulletDestroyState FireBolt : : MonsterHit ( Monster & monster , const uint8_t markStacksBeforeHit )
{
fadeOutTime = " Wizard.Ability 1.BulletHitFadeoutTime " _F ;
for ( int i = 0 ; i < " Wizard.Ability 1.BulletHitExplosionParticleCount " _I ; i + + ) {
game - > AddEffect ( std : : make_unique < Effect > ( monster . GetPos ( ) , " Wizard.Ability 1.BulletHitExplosionParticleLifetimeRange " _FRange , " circle.png " , upperLevel , " Wizard.Ability 1.BulletHitExplosionParticleSizeRange " _FRange , " Wizard.Ability 1.BulletHitExplosionParticleFadeoutTimeRange " _FRange , vf2d { " Wizard.Ability 1.BulletHitExplosionParticleSpeedRange " _FRange , " Wizard.Ability 1.BulletHitExplosionParticleSpeedRange " _FRange } , Pixel { uint8_t ( " Wizard.Ability 1.BulletHitExplosionParticleRedRange " _FRange ) , uint8_t ( " Wizard.Ability 1.BulletHitExplosionParticleGreenRange " _FRange ) , uint8_t ( " Wizard.Ability 1.BulletHitExplosionParticleBlueRange " _FRange ) , uint8_t ( " Wizard.Ability 1.BulletHitExplosionParticleAlphaRange " _FRange ) } ) ) ;
}
game - > SetupWorldShake ( " Wizard.Ability 1.WorldShakeTime " _F ) ;
game - > Hurt ( monster . GetPos ( ) , " Wizard.Ability 1.BulletHitExplosionRange " _F / 100 * 12 , int ( " Wizard.Ability 1.BulletHitExplosionDamageMult " _F * game - > GetPlayer ( ) - > GetAttack ( ) ) , OnUpperLevel ( ) , 0 , HurtType : : MONSTER , HurtFlag : : PLAYER_ABILITY ) ;
game - > AddEffect ( std : : make_unique < Effect > ( monster . GetPos ( ) , 0 , " splash_effect.png " , upperLevel , " Wizard.Ability 1.BulletHitExplosionRange " _F / 100 * 2 , " Wizard.Ability 1.BulletHitExplosionFadeoutTime " _F , vf2d { } , " Wizard.Ability 1.BulletHitExplosionColor " _Pixel ) ) ;
SoundEffect : : PlaySFX ( " Wizard Fire Bolt Hit " , pos ) ;
return BulletDestroyState : : KEEP_ALIVE ;
}
void FireBolt : : ModifyOutgoingDamageData ( HurtDamageInfo & data ) {
if ( friendly ) data . hurtFlags | = HurtFlag : : PLAYER_ABILITY ;
}