Added the FriendlyType enum and modified all bullet constructors to handle the new enum. Release Build 12458.
Some checks failed
Emscripten Build / Build_and_Deploy_Web_Build (push) Failing after 1m9s
Some checks failed
Emscripten Build / Build_and_Deploy_Web_Build (push) Failing after 1m9s
This commit is contained in:
parent
fa3161af35
commit
66a10cee9f
@ -414,6 +414,7 @@
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FriendlyType.h" />
|
||||
<ClInclude Include="HurtDamageInfo.h">
|
||||
<SubType>
|
||||
</SubType>
|
||||
|
||||
@ -726,6 +726,9 @@
|
||||
<ClInclude Include="MonsterAbility.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FriendlyType.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Player.cpp">
|
||||
|
||||
@ -45,12 +45,12 @@ All rights reserved.
|
||||
INCLUDE_game
|
||||
INCLUDE_GFX
|
||||
|
||||
Arrow::Arrow(vf2d pos,vf2d targetPos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
|
||||
Arrow::Arrow(vf2d pos,vf2d targetPos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col)
|
||||
:finalDistance(geom2d::line(pos,targetPos).length()*1.2f),acc(PI/2*250),targetPos(targetPos),
|
||||
Bullet(pos,vel,radius,damage,
|
||||
"arrow.png",upperLevel,false,INFINITE,true,friendly,col){}
|
||||
|
||||
Arrow::Arrow(vf2d pos,vf2d targetPos,vf2d vel,const std::string_view gfx,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
|
||||
Arrow::Arrow(vf2d pos,vf2d targetPos,vf2d vel,const std::string_view gfx,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col)
|
||||
:finalDistance(geom2d::line(pos,targetPos).length()*1.2f),acc(PI/2*250),targetPos(targetPos),
|
||||
Bullet(pos,vel,radius,damage,std::string(gfx),upperLevel,false,INFINITE,true,friendly,col){}
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ All rights reserved.
|
||||
INCLUDE_ANIMATION_DATA
|
||||
INCLUDE_game
|
||||
|
||||
BearTrap::BearTrap(vf2d pos,float radius,int damage,float fadeinTime,float fadeoutTime,bool upperLevel,bool hitsMultiple,float lifetime,bool friendly,Pixel col,vf2d scale)
|
||||
BearTrap::BearTrap(vf2d pos,float radius,int damage,float fadeinTime,float fadeoutTime,bool upperLevel,bool hitsMultiple,float lifetime,FriendlyType friendly,Pixel col,vf2d scale)
|
||||
:Bullet(pos,{},radius,damage,"Ability Icons/bear_trap.png",upperLevel,hitsMultiple,lifetime,false,friendly,col,scale,0.f,"Trap Hit"){
|
||||
fadeInTime=fadeinTime;
|
||||
animation.AddState("bear_trap.png",ANIMATION_DATA["bear_trap.png"]);
|
||||
|
||||
@ -47,7 +47,7 @@ INCLUDE_ANIMATION_DATA
|
||||
INCLUDE_MONSTER_LIST
|
||||
INCLUDE_game
|
||||
|
||||
Bomb::Bomb(const vf2d pos,const float z,const float gravity,const float detonationTime,const float bombFadeoutTime,const float bombKnockbackFactor,const vf2d targetPos,const float explosionRadius,const int damage,const bool upperLevel,const bool friendly,const Pixel col,const vf2d scale)
|
||||
Bomb::Bomb(const vf2d pos,const float z,const float gravity,const float detonationTime,const float bombFadeoutTime,const float bombKnockbackFactor,const vf2d targetPos,const float explosionRadius,const int damage,const bool upperLevel,const FriendlyType friendly,const Pixel col,const vf2d scale)
|
||||
:Bullet(pos,{},0.f,damage,"goblin_bomb.png",upperLevel,true,INFINITY,false,friendly,col,scale)
|
||||
,explosionRadius(explosionRadius),gravity(gravity),detonationTime(detonationTime),bombFadeoutTime(bombFadeoutTime),bombKnockbackFactor(bombKnockbackFactor),targetPos(targetPos){
|
||||
this->z=z;
|
||||
|
||||
@ -68,7 +68,7 @@ void Monster::STRATEGY::BREAKING_PILLAR(Monster&m,float fElapsedTime,std::string
|
||||
const float bulletAngRandomOffset{util::random(PI/2)};
|
||||
for(int i=0;i<ConfigInt("Death Ring Bullet Count");i++){
|
||||
const float bulletAngle=((2*PI)/ConfigInt("Death Ring Bullet Count"))*i+bulletAngRandomOffset;
|
||||
CreateBullet(Bullet)(m.GetPos(),vf2d{ConfigFloat("Death Ring Bullet Speed"),bulletAngle}.cart(),ConfigFloat("Death Ring Bullet Size"),ConfigInt("Death Ring Bullet Damage"),m.OnUpperLevel(),false,ConfigPixel("Death Ring Bullet Color"),vf2d{ConfigFloat("Death Ring Bullet Size")/3,ConfigFloat("Death Ring Bullet Size")/3})EndBullet;
|
||||
CreateBullet(Bullet)(m.GetPos(),vf2d{ConfigFloat("Death Ring Bullet Speed"),bulletAngle}.cart(),ConfigFloat("Death Ring Bullet Size"),ConfigInt("Death Ring Bullet Damage"),m.OnUpperLevel(),NON_FRIENDLY,ConfigPixel("Death Ring Bullet Color"),vf2d{ConfigFloat("Death Ring Bullet Size")/3,ConfigFloat("Death Ring Bullet Size")/3})EndBullet;
|
||||
BULLET_LIST.back()->SetIframeTimeOnHit(0.15f);
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -38,9 +38,9 @@ All rights reserved.
|
||||
|
||||
#include "Bullet.h"
|
||||
|
||||
Bullet::Bullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col,vf2d scale,float image_angle)
|
||||
Bullet::Bullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col,vf2d scale,float image_angle)
|
||||
:IBullet(pos,vel,radius,damage,upperLevel,friendly,col,scale,image_angle){}
|
||||
//Initializes a bullet with an animation.
|
||||
Bullet::Bullet(vf2d pos,vf2d vel,float radius,int damage,const std::string&animation,bool upperLevel,bool hitsMultiple,float lifetime,bool rotatesWithAngle,bool friendly,Pixel col,vf2d scale,float image_angle,std::string_view hitSound)
|
||||
Bullet::Bullet(vf2d pos,vf2d vel,float radius,int damage,const std::string&animation,bool upperLevel,bool hitsMultiple,float lifetime,bool rotatesWithAngle,FriendlyType friendly,Pixel col,vf2d scale,float image_angle,std::string_view hitSound)
|
||||
:IBullet(pos,vel,radius,damage,animation,upperLevel,hitsMultiple,lifetime,rotatesWithAngle,friendly,col,scale,image_angle,hitSound){}
|
||||
void Bullet::ModifyOutgoingDamageData(HurtDamageInfo&data){}
|
||||
@ -41,9 +41,9 @@ All rights reserved.
|
||||
|
||||
class Bullet:public IBullet{
|
||||
public:
|
||||
Bullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f);
|
||||
Bullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f);
|
||||
//Initializes a bullet with an animation.
|
||||
Bullet(vf2d pos,vf2d vel,float radius,int damage,const std::string&animation,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,bool rotatesWithAngle=false,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f,std::string_view hitSound="");
|
||||
Bullet(vf2d pos,vf2d vel,float radius,int damage,const std::string&animation,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,bool rotatesWithAngle=false,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f,std::string_view hitSound="");
|
||||
protected:
|
||||
virtual void ModifyOutgoingDamageData(HurtDamageInfo&data)override;
|
||||
};
|
||||
@ -46,7 +46,7 @@ All rights reserved.
|
||||
|
||||
struct EnergyBolt:public Bullet{
|
||||
float lastParticleSpawn=0;
|
||||
EnergyBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE);
|
||||
EnergyBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE);
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -55,7 +55,7 @@ struct EnergyBolt:public Bullet{
|
||||
|
||||
struct FireBolt:public Bullet{
|
||||
float lastParticleSpawn=0;
|
||||
FireBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE);
|
||||
FireBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE);
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -70,7 +70,7 @@ struct LightningBolt:public Bullet{
|
||||
NO_MORE_HITS=0,
|
||||
};
|
||||
float lastParticleSpawn=0;
|
||||
LightningBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE);
|
||||
LightningBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE);
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -86,8 +86,8 @@ struct Arrow:public Bullet{
|
||||
float acc=PI/2*250;
|
||||
vf2d targetPos;
|
||||
bool poisonArrow{false};
|
||||
Arrow(vf2d pos,vf2d targetPos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE);
|
||||
Arrow(vf2d pos,vf2d targetPos,vf2d vel,const std::string_view gfx,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE);
|
||||
Arrow(vf2d pos,vf2d targetPos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE);
|
||||
Arrow(vf2d pos,vf2d targetPos,vf2d vel,const std::string_view gfx,float radius,int damage,bool upperLevel,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE);
|
||||
void Update(float fElapsedTime)override;
|
||||
// Change the arrow's heading by predicting a path somewhere in the future and aiming at the closest possible spot to its targetPos.
|
||||
// The perception level can be a value from 0-90 indicating the sweep angle to check beyond the initial aiming angle.
|
||||
@ -100,8 +100,8 @@ struct Arrow:public Bullet{
|
||||
|
||||
struct ChargedArrow:public Bullet{
|
||||
vf2d lastLaserPos;
|
||||
ChargedArrow(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE);
|
||||
ChargedArrow(const std::string&shotArrowGraphic,const std::string&laserGraphic,vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE);
|
||||
ChargedArrow(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE);
|
||||
ChargedArrow(const std::string&shotArrowGraphic,const std::string&laserGraphic,vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE);
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -116,7 +116,7 @@ struct FrogTongue:public Bullet{
|
||||
float duration;
|
||||
float knockbackStrength;
|
||||
Monster&sourceMonster;
|
||||
FrogTongue(Monster&sourceMonster,vf2d targetPos,float lifetime,int damage,bool upperLevel,float knockbackStrength=1.0f,bool friendly=false,Pixel col=WHITE);
|
||||
FrogTongue(Monster&sourceMonster,vf2d targetPos,float lifetime,int damage,bool upperLevel,float knockbackStrength=1.0f,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE);
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -125,7 +125,7 @@ struct FrogTongue:public Bullet{
|
||||
};
|
||||
|
||||
struct Wisp:public Bullet{
|
||||
Wisp(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE);
|
||||
Wisp(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE);
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -154,7 +154,7 @@ struct DaggerStab:public Bullet{
|
||||
float daggerStabDistance;
|
||||
float knockbackAmt;
|
||||
DirectionOffsets daggerPositionOffsets;
|
||||
DaggerStab(Monster&sourceMonster,const std::string&image,float radius,int damage,const float knockbackAmt,bool upperLevel,const Direction facingDir,const float daggerFrameDuration,const float daggerStabDistance,const DirectionOffsets offsets,bool friendly=false,Pixel col=WHITE);
|
||||
DaggerStab(Monster&sourceMonster,const std::string&image,float radius,int damage,const float knockbackAmt,bool upperLevel,const Direction facingDir,const float daggerFrameDuration,const float daggerStabDistance,const DirectionOffsets offsets,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE);
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -167,7 +167,7 @@ struct DaggerSlash:public Bullet{
|
||||
float frameDuration;
|
||||
float daggerSlashDistance;
|
||||
float knockbackAmt;
|
||||
DaggerSlash(Monster&sourceMonster,const std::string&image,float radius,int damage,const float knockbackAmt,bool upperLevel,const Direction facingDir,const float daggerFrameDuration,const float daggerSlashDistance,bool friendly=false,Pixel col=WHITE);
|
||||
DaggerSlash(Monster&sourceMonster,const std::string&image,float radius,int damage,const float knockbackAmt,bool upperLevel,const Direction facingDir,const float daggerFrameDuration,const float daggerSlashDistance,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE);
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -184,7 +184,7 @@ struct Bomb:public Bullet{
|
||||
Animate2D::AnimationState animation;
|
||||
Animate2D::Animation<std::string>bomb_animation;
|
||||
float bombKnockbackFactor{0.f};
|
||||
Bomb(const vf2d pos,const float z,const float gravity,const float detonationTime,const float bombFadeoutTime,float bombKnockbackFactor,const vf2d targetPos,const float explosionRadius,const int damage,const bool upperLevel,const bool friendly=false,const Pixel col=WHITE,const vf2d scale={1,1});
|
||||
Bomb(const vf2d pos,const float z,const float gravity,const float detonationTime,const float bombFadeoutTime,float bombKnockbackFactor,const vf2d targetPos,const float explosionRadius,const int damage,const bool upperLevel,const FriendlyType friendly=NON_FRIENDLY,const Pixel col=WHITE,const vf2d scale={1,1});
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -207,7 +207,7 @@ struct LevitatingRock:public Bullet{
|
||||
std::vector<LevitatingRock*>slaveRocks;
|
||||
//The rock will rotate around the attachedTarget towards the attackingTarget. The facingRotOffset determines the angle relative to the direction pointed towards this rock will be positioned at. Once the wait time expires, the rock is fired at target speed in that given direction.
|
||||
//The lock on time is how long the rocks will follow the player. The wait time is how long to wait until firing.
|
||||
LevitatingRock(const Monster&attachedTarget,const vf2d&attackingTarget,const float fadeInTime,const float facingRotOffset,const float distance,const float lockOnTime,const float waitTime,const float targetSpd,const float radius,const int damage,const bool upperLevel,const bool friendly=false,const Pixel col=WHITE,const vf2d scale={1,1});
|
||||
LevitatingRock(const Monster&attachedTarget,const vf2d&attackingTarget,const float fadeInTime,const float facingRotOffset,const float distance,const float lockOnTime,const float waitTime,const float targetSpd,const float radius,const int damage,const bool upperLevel,const FriendlyType friendly=NON_FRIENDLY,const Pixel col=WHITE,const vf2d scale={1,1});
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -225,7 +225,7 @@ struct Tornado:public Bullet{
|
||||
float knockbackAmt{};
|
||||
float fadeInDuration{};
|
||||
float rot{0.f};
|
||||
Tornado(vf2d centerPoint,float distance,float initialRot,float rotSpd,int damage,const float knockupAmt,const float knockbackAmt,const float lifetime,bool upperLevel,bool friendly=false,Pixel col=WHITE,const vf2d scale={1,1});
|
||||
Tornado(vf2d centerPoint,float distance,float initialRot,float rotSpd,int damage,const float knockupAmt,const float knockbackAmt,const float lifetime,bool upperLevel,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,const vf2d scale={1,1});
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -236,7 +236,7 @@ struct Debris:public Bullet{
|
||||
const int randomFrame{};
|
||||
const float rotatingSpd{};
|
||||
float knockbackAmt{};
|
||||
Debris(const vf2d pos,const vf2d vel,const int damage,const float radius,const float knockbackAmt,const float rotSpd,const float lifetime,bool upperLevel,bool friendly=false,Pixel col=WHITE,const vf2d scale={1,1});
|
||||
Debris(const vf2d pos,const vf2d vel,const int damage,const float radius,const float knockbackAmt,const float rotSpd,const float lifetime,bool upperLevel,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,const vf2d scale={1,1});
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -249,7 +249,7 @@ struct LargeTornado:public Bullet{
|
||||
float knockupDuration{};
|
||||
float knockbackAmt{};
|
||||
//Suction amount in pixels/sec
|
||||
LargeTornado(vf2d pos,const float suctionAmt,const float knockupAmt,const float knockbackAmt,const int damage,const float radius,const float lifetime,bool upperLevel,bool friendly=false,Pixel col=WHITE,const vf2d scale={1,1});
|
||||
LargeTornado(vf2d pos,const float suctionAmt,const float knockupAmt,const float knockbackAmt,const int damage,const float radius,const float lifetime,bool upperLevel,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,const vf2d scale={1,1});
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -257,13 +257,13 @@ struct LargeTornado:public Bullet{
|
||||
};
|
||||
|
||||
struct Feather:public Bullet{
|
||||
Feather(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f);
|
||||
Feather(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f);
|
||||
void ModifyOutgoingDamageData(HurtDamageInfo&data)override;
|
||||
};
|
||||
|
||||
struct LargeStone:public Bullet{
|
||||
public:
|
||||
LargeStone(vf2d pos,const float stoneThrowTime,const vf2d landingPos,float moveVelWaitTimer,float radius,float z,float gravity,int damage,const float knockbackAmt,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f);
|
||||
LargeStone(vf2d pos,const float stoneThrowTime,const vf2d landingPos,float moveVelWaitTimer,float radius,float z,float gravity,int damage,const float knockbackAmt,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f);
|
||||
protected:
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
@ -284,7 +284,7 @@ private:
|
||||
|
||||
struct FallingBullet:public Bullet{
|
||||
//The position for this bullet represents where the falling bullet should land.
|
||||
FallingBullet(const std::string&imgName,vf2d targetPos,vf2d vel,float zVel,float indicatorDisplayTime,float radius,int damage,bool upperLevel,bool hitsMultiple=false,float knockbackAmt=0.f,float lifetime=INFINITE,bool friendly=false,Pixel spellCircleCol=WHITE,vf2d scale={1,1},float image_angle=0.f,float spellCircleRotation=0.f,float spellCircleRotationSpd=0.f,Pixel insigniaCol=WHITE,float insigniaRotation=0.f,float insigniaRotationSpd=0.f);
|
||||
FallingBullet(const std::string&imgName,vf2d targetPos,vf2d vel,float zVel,float indicatorDisplayTime,float radius,int damage,bool upperLevel,bool hitsMultiple=false,float knockbackAmt=0.f,float lifetime=INFINITE,FriendlyType friendly=NON_FRIENDLY,Pixel spellCircleCol=WHITE,vf2d scale={1,1},float image_angle=0.f,float spellCircleRotation=0.f,float spellCircleRotationSpd=0.f,Pixel insigniaCol=WHITE,float insigniaRotation=0.f,float insigniaRotationSpd=0.f);
|
||||
protected:
|
||||
void Update(float fElapsedTime)override;
|
||||
void Draw(const Pixel blendCol)const override;
|
||||
@ -301,7 +301,7 @@ private:
|
||||
|
||||
//While not a bullet directly, the DeadlyDash class generates a bunch of afterimages and collision checks.
|
||||
struct DeadlyDash:public Bullet{
|
||||
DeadlyDash(vf2d startPos,vf2d endPos,float radius,float afterImagesLingeringTime,int damage,float knockbackAmt,bool upperLevel,bool friendly,float afterImagesSpreadDist,const std::string&animation,Pixel col);
|
||||
DeadlyDash(vf2d startPos,vf2d endPos,float radius,float afterImagesLingeringTime,int damage,float knockbackAmt,bool upperLevel,FriendlyType friendly,float afterImagesSpreadDist,const std::string&animation,Pixel col);
|
||||
protected:
|
||||
void Draw(const Pixel blendCol)const override;
|
||||
void ModifyOutgoingDamageData(HurtDamageInfo&data)override;
|
||||
@ -316,14 +316,14 @@ private:
|
||||
};
|
||||
|
||||
struct BearTrap:public Bullet{
|
||||
BearTrap(vf2d pos,float radius,int damage,float fadeinTime,float fadeoutTime,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1});
|
||||
BearTrap(vf2d pos,float radius,int damage,float fadeinTime,float fadeoutTime,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,vf2d scale={1,1});
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
void ModifyOutgoingDamageData(HurtDamageInfo&data)override;
|
||||
};
|
||||
|
||||
struct ExplosiveTrap:public Bullet{
|
||||
ExplosiveTrap(vf2d pos,float radius,float explosionRadius,float automaticDetonationTime,int damage,float fadeinTime,float fadeoutTime,float activationWaitTime,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1});
|
||||
ExplosiveTrap(vf2d pos,float radius,float explosionRadius,float automaticDetonationTime,int damage,float fadeinTime,float fadeoutTime,float activationWaitTime,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,vf2d scale={1,1});
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -341,7 +341,7 @@ private:
|
||||
};
|
||||
|
||||
struct PurpleEnergyBall:public Bullet{
|
||||
PurpleEnergyBall(vf2d pos,float radius,float homingRadius,int damage,bool upperLevel,vf2d speed,float lifetime=INFINITE,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1});
|
||||
PurpleEnergyBall(vf2d pos,float radius,float homingRadius,int damage,bool upperLevel,vf2d speed,float lifetime=INFINITE,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,vf2d scale={1,1});
|
||||
void Update(float fElapsedTime)override;
|
||||
void Draw(const Pixel blendCol)const override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
@ -356,7 +356,7 @@ private:
|
||||
};
|
||||
|
||||
struct ThrownProjectile:public Bullet{
|
||||
ThrownProjectile(vf2d pos,vf2d targetPos,const std::string&img,float explodeRadius,float z,float totalFallTime,float totalRiseZAmt,int damage,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1},float image_angle={0.f},const std::optional<Effect>explodeEffect={},const std::optional<std::string>explodeSoundEffect={},const std::optional<LingeringEffect>lingeringEffect={});
|
||||
ThrownProjectile(vf2d pos,vf2d targetPos,const std::string&img,float explodeRadius,float z,float totalFallTime,float totalRiseZAmt,int damage,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,vf2d scale={1,1},float image_angle={0.f},const std::optional<Effect>explodeEffect={},const std::optional<std::string>explodeSoundEffect={},const std::optional<LingeringEffect>lingeringEffect={});
|
||||
void Update(float fElapsedTime)override;
|
||||
void ModifyOutgoingDamageData(HurtDamageInfo&data)override;
|
||||
void _OnGroundLand();
|
||||
@ -378,7 +378,7 @@ protected:
|
||||
};
|
||||
|
||||
struct PoisonBottle:public ThrownProjectile{
|
||||
PoisonBottle(vf2d pos,vf2d targetPos,const std::string&img,float explodeRadius,float bounceExplodeRadius,float z,float totalFallTime,float totalRiseZAmt,int damage,int additionalBounceCount,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1},float image_angle={0.f});
|
||||
PoisonBottle(vf2d pos,vf2d targetPos,const std::string&img,float explodeRadius,float bounceExplodeRadius,float z,float totalFallTime,float totalRiseZAmt,int damage,int additionalBounceCount,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,vf2d scale={1,1},float image_angle={0.f});
|
||||
void ModifyOutgoingDamageData(HurtDamageInfo&data)override;
|
||||
virtual void OnGroundLand()override final; //This is called when the projectile lands, damage is not dealt yet, default behavior just deals damage in the area.
|
||||
private:
|
||||
@ -387,7 +387,7 @@ private:
|
||||
};
|
||||
|
||||
struct BurstBullet:public Bullet{
|
||||
BurstBullet(vf2d pos,vf2d vel,const Entity target,const float explodeDist,const int extraBulletCount,const float extraBulletHeadingAngleChange,const float extraBulletRadius,const vf2d extraBulletScale,const float extraBulletStartSpeed,const float extraBulletAcc,float radius,int damage,bool upperLevel,bool friendly,Pixel col,vf2d scale);
|
||||
BurstBullet(vf2d pos,vf2d vel,const Entity target,const float explodeDist,const int extraBulletCount,const float extraBulletHeadingAngleChange,const float extraBulletRadius,const vf2d extraBulletScale,const float extraBulletStartSpeed,const float extraBulletAcc,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col,vf2d scale);
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -409,7 +409,7 @@ private:
|
||||
|
||||
struct RotateBullet:public Bullet{
|
||||
//headingAngleChange determines how the startingAngle adjusts over time (in radians).
|
||||
RotateBullet(vf2d pos,float startingAng,float startSpeed,float acc,float headingAngleChange,float radius,int damage,bool upperLevel,bool friendly,Pixel col);
|
||||
RotateBullet(vf2d pos,float startingAng,float startSpeed,float acc,float headingAngleChange,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col);
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -419,7 +419,7 @@ private:
|
||||
};
|
||||
|
||||
struct InkBullet:public Bullet{
|
||||
InkBullet(const vf2d pos,const vf2d targetPos,const vf2d vel,const float inkExplosionRadius,const float inkPuddleLifetime,const float inkSlowdownDuration,const float inkSlowdownPct,const float inkPuddleRadius,const bool upperLevel,const bool friendly);
|
||||
InkBullet(const vf2d pos,const vf2d targetPos,const vf2d vel,const float inkExplosionRadius,const float inkPuddleLifetime,const float inkSlowdownDuration,const float inkSlowdownPct,const float inkPuddleRadius,const bool upperLevel,const FriendlyType friendly);
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
@ -435,7 +435,7 @@ private:
|
||||
};
|
||||
|
||||
struct HomingBullet:public Bullet{
|
||||
HomingBullet(const vf2d pos,const Entity target,const float rotateTowardsSpeed,const float rotateTowardsSpeedCoveredInInk,const float lifetime,const float speed,const float radius,const int damage,const bool upperLevel,const bool friendly=false,const Pixel col=WHITE,const vf2d scale={1,1},const float image_angle=0.f);
|
||||
HomingBullet(const vf2d pos,const Entity target,const float rotateTowardsSpeed,const float rotateTowardsSpeedCoveredInInk,const float lifetime,const float speed,const float radius,const int damage,const bool upperLevel,const FriendlyType friendly=NON_FRIENDLY,const Pixel col=WHITE,const vf2d scale={1,1},const float image_angle=0.f);
|
||||
void Update(float fElapsedTime)override;
|
||||
void ModifyOutgoingDamageData(HurtDamageInfo&data)override;
|
||||
private:
|
||||
@ -445,7 +445,7 @@ private:
|
||||
};
|
||||
|
||||
struct GhostSaber:public Bullet{
|
||||
GhostSaber(const vf2d pos,const std::weak_ptr<Monster>target,const float lifetime,const float distFromTarget,const float knockbackAmt,const float initialRot,const float radius,const float expandSpd,const int damage,const bool upperLevel,const float rotSpd,const bool friendly=false,const Pixel col=WHITE,const vf2d scale={1,1},const float image_angle=0.f);
|
||||
GhostSaber(const vf2d pos,const std::weak_ptr<Monster>target,const float lifetime,const float distFromTarget,const float knockbackAmt,const float initialRot,const float radius,const float expandSpd,const int damage,const bool upperLevel,const float rotSpd,const FriendlyType friendly=NON_FRIENDLY,const Pixel col=WHITE,const vf2d scale={1,1},const float image_angle=0.f);
|
||||
void Update(float fElapsedTime)override;
|
||||
BulletDestroyState PlayerHit(Player*player)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _PlayerHit()!!
|
||||
BulletDestroyState MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit)override;//DO NOT CALL THIS DIRECTLY! INSTEAD USE _MonsterHit()!!
|
||||
|
||||
@ -48,7 +48,7 @@ INCLUDE_game
|
||||
INCLUDE_MONSTER_LIST
|
||||
INCLUDE_ANIMATION_DATA
|
||||
|
||||
BurstBullet::BurstBullet(vf2d pos,vf2d vel,const Entity target,const float explodeDist,const int extraBulletCount,const float extraBulletHeadingAngleChange,const float extraBulletRadius,const vf2d extraBulletScale,const float extraBulletStartSpeed,const float extraBulletAcc,float radius,int damage,bool upperLevel,bool friendly,Pixel col,vf2d scale)
|
||||
BurstBullet::BurstBullet(vf2d pos,vf2d vel,const Entity target,const float explodeDist,const int extraBulletCount,const float extraBulletHeadingAngleChange,const float extraBulletRadius,const vf2d extraBulletScale,const float extraBulletStartSpeed,const float extraBulletAcc,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col,vf2d scale)
|
||||
:Bullet(pos,vel,radius,damage,"burstrotatebullet.png",upperLevel,false,INFINITE,true,friendly,col,scale),extraBulletStartSpeed(extraBulletStartSpeed),extraBulletAcc(extraBulletAcc),extraBulletRadius(extraBulletRadius),extraBulletScale(extraBulletScale),extraBulletHeadingAngleChange(extraBulletHeadingAngleChange),extraBulletCount(extraBulletCount),target(target),explodeDist(explodeDist),scaleOscillator({0.85f,0.85f},{1.f,1.f},0.3f){
|
||||
animation.mult=0.f; //Prevent animating.
|
||||
}
|
||||
|
||||
@ -44,11 +44,11 @@ All rights reserved.
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
ChargedArrow::ChargedArrow(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
|
||||
ChargedArrow::ChargedArrow(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col)
|
||||
:lastLaserPos(pos),laserGraphic("laser.png"),
|
||||
Bullet(pos,vel,radius,damage,"charged_shot_arrow.png",upperLevel,true,INFINITE,true,friendly,col){}
|
||||
|
||||
ChargedArrow::ChargedArrow(const std::string&shotArrowGraphic,const std::string&laserGraphic,vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
|
||||
ChargedArrow::ChargedArrow(const std::string&shotArrowGraphic,const std::string&laserGraphic,vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col)
|
||||
:lastLaserPos(pos),laserGraphic(laserGraphic),
|
||||
Bullet(pos,vel,radius,damage,shotArrowGraphic,upperLevel,true,INFINITE,true,friendly,col){}
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ All rights reserved.
|
||||
INCLUDE_game
|
||||
INCLUDE_ANIMATION_DATA
|
||||
|
||||
DaggerSlash::DaggerSlash(Monster&sourceMonster,const std::string&image,float radius,int damage,const float knockbackAmt,bool upperLevel,const Direction facingDir,const float daggerFrameDuration,const float daggerSlashDistance,bool friendly,Pixel col)
|
||||
DaggerSlash::DaggerSlash(Monster&sourceMonster,const std::string&image,float radius,int damage,const float knockbackAmt,bool upperLevel,const Direction facingDir,const float daggerFrameDuration,const float daggerSlashDistance,FriendlyType friendly,Pixel col)
|
||||
:Bullet(sourceMonster.GetPos(),{},radius,damage,image,upperLevel,false,daggerFrameDuration*ANIMATION_DATA["goblin_sword_slash.png"].GetFrameCountBasedOnAnimationStyle(),true,friendly,col),
|
||||
sourceMonster(sourceMonster),frameDuration(daggerFrameDuration),daggerSlashDistance(daggerSlashDistance),facingDir(facingDir),knockbackAmt(knockbackAmt){}
|
||||
void DaggerSlash::Update(float fElapsedTime){
|
||||
|
||||
@ -45,7 +45,7 @@ All rights reserved.
|
||||
INCLUDE_game
|
||||
INCLUDE_ANIMATION_DATA
|
||||
|
||||
DaggerStab::DaggerStab(Monster&sourceMonster,const std::string&image,float radius,int damage,const float knockbackAmt,bool upperLevel,const Direction facingDir,const float daggerFrameDuration,const float daggerStabDistance,const DirectionOffsets offsets,bool friendly,Pixel col)
|
||||
DaggerStab::DaggerStab(Monster&sourceMonster,const std::string&image,float radius,int damage,const float knockbackAmt,bool upperLevel,const Direction facingDir,const float daggerFrameDuration,const float daggerStabDistance,const DirectionOffsets offsets,FriendlyType friendly,Pixel col)
|
||||
:Bullet(sourceMonster.GetPos(),{},radius,damage,image,upperLevel,false,daggerFrameDuration*ANIMATION_DATA["dagger_stab.png"].GetFrameCountBasedOnAnimationStyle(),true,friendly,col),
|
||||
sourceMonster(sourceMonster),frameDuration(daggerFrameDuration),daggerStabDistance(daggerStabDistance),facingDir(facingDir),daggerPositionOffsets(offsets),knockbackAmt(knockbackAmt){}
|
||||
void DaggerStab::Update(float fElapsedTime){
|
||||
|
||||
@ -45,12 +45,12 @@ const float DamageNumber::MOVE_UP_TIME=0.4f;
|
||||
|
||||
using enum DamageNumberType::DamageNumberType;
|
||||
|
||||
DamageNumber::DamageNumber(vf2d pos,int damage,bool friendly,DamageNumberType::DamageNumberType type):
|
||||
DamageNumber::DamageNumber(vf2d pos,int damage,FriendlyType friendly,DamageNumberType::DamageNumberType type):
|
||||
pos(pos),damage(damage),friendly(friendly),type(type),invertedDirection(type==INTERRUPT),riseSpd(GetOriginalRiseSpd()){
|
||||
RecalculateSize();
|
||||
}
|
||||
|
||||
std::shared_ptr<DamageNumber>DamageNumber::AddDamageNumber(vf2d pos,int damage,bool friendly,DamageNumberType::DamageNumberType type){
|
||||
std::shared_ptr<DamageNumber>DamageNumber::AddDamageNumber(vf2d pos,int damage,FriendlyType friendly,DamageNumberType::DamageNumberType type){
|
||||
return DAMAGENUMBER_LIST.emplace_back(std::make_shared<DamageNumber>(pos,damage,friendly,type));
|
||||
}
|
||||
|
||||
|
||||
@ -37,6 +37,7 @@ All rights reserved.
|
||||
#pragma endregion
|
||||
#pragma once
|
||||
#include "olcUTIL_Geometry2D.h"
|
||||
#include"FriendlyTag.h"
|
||||
|
||||
namespace DamageNumberType{
|
||||
enum DamageNumberType{
|
||||
@ -53,7 +54,7 @@ namespace DamageNumberType{
|
||||
|
||||
struct DamageNumber{
|
||||
//The friendly flag indicates if the number was for a friendly/player target or if it's for a monster target (set to false)
|
||||
DamageNumber(vf2d pos,int damage,bool friendly=false,DamageNumberType::DamageNumberType type=DamageNumberType::HEALTH_LOSS);
|
||||
DamageNumber(vf2d pos,int damage,FriendlyType friendly=NON_FRIENDLY,DamageNumberType::DamageNumberType type=DamageNumberType::HEALTH_LOSS);
|
||||
void Update();
|
||||
void Draw();
|
||||
void AddDamage(int damageAmt);
|
||||
@ -61,7 +62,7 @@ struct DamageNumber{
|
||||
void SetPauseTimer(const float pauseTime);
|
||||
void SetType(const DamageNumberType::DamageNumberType type);
|
||||
const DamageNumberType::DamageNumberType GetType()const;
|
||||
static std::shared_ptr<DamageNumber>AddDamageNumber(vf2d pos,int damage,bool friendly=false,DamageNumberType::DamageNumberType type=DamageNumberType::HEALTH_LOSS);
|
||||
static std::shared_ptr<DamageNumber>AddDamageNumber(vf2d pos,int damage,FriendlyType FriendlyType=NON_FRIENDLY,DamageNumberType::DamageNumberType type=DamageNumberType::HEALTH_LOSS);
|
||||
private:
|
||||
vf2d pos;
|
||||
int damage;
|
||||
@ -70,7 +71,7 @@ private:
|
||||
DamageNumberType::DamageNumberType type=DamageNumberType::HEALTH_LOSS;
|
||||
float riseSpd=0.f;
|
||||
vf2d size{1.f,1.f};
|
||||
bool friendly=false;
|
||||
FriendlyType friendly=NON_FRIENDLY;
|
||||
bool invertedDirection=false;
|
||||
const static float MOVE_UP_TIME;
|
||||
float GetOriginalRiseSpd();
|
||||
|
||||
@ -44,7 +44,7 @@ All rights reserved.
|
||||
INCLUDE_ANIMATION_DATA
|
||||
INCLUDE_game
|
||||
|
||||
DeadlyDash::DeadlyDash(vf2d startPos,vf2d endPos,float radius,float afterImagesLingeringTime,int damage,float knockbackAmt,bool upperLevel,bool friendly,float afterImagesSpreadDist,const std::string&animation,Pixel col)
|
||||
DeadlyDash::DeadlyDash(vf2d startPos,vf2d endPos,float radius,float afterImagesLingeringTime,int damage,float knockbackAmt,bool upperLevel,FriendlyType friendly,float afterImagesSpreadDist,const std::string&animation,Pixel col)
|
||||
:animation(animation),startPos(startPos),endPos(endPos),checkRadius(radius),afterImagesSpreadDist(afterImagesSpreadDist),afterImagesLingeringTime(afterImagesLingeringTime),knockbackAmt(knockbackAmt),Bullet({},{},0.f,damage,"circle.png",upperLevel,true,INFINITE,false,friendly,col,{1.f,1.f},0.f){
|
||||
const geom2d::line<float>afterImageLine{startPos,endPos};
|
||||
const int afterImageCount{int(afterImageLine.length()/afterImagesSpreadDist)+1};
|
||||
|
||||
@ -43,7 +43,7 @@ All rights reserved.
|
||||
INCLUDE_GFX
|
||||
INCLUDE_game
|
||||
|
||||
Debris::Debris(const vf2d pos,const vf2d vel,const int damage,const float radius,const float knockbackAmt,const float rotSpd,const float lifetime,bool upperLevel,bool friendly,Pixel col,const vf2d scale)
|
||||
Debris::Debris(const vf2d pos,const vf2d vel,const int damage,const float radius,const float knockbackAmt,const float rotSpd,const float lifetime,bool upperLevel,FriendlyType friendly,Pixel col,const vf2d scale)
|
||||
:Bullet(pos,vel,radius,damage,"commercial_assets/wind_solid_objects.png",upperLevel,false,lifetime,false,friendly,col,scale),knockbackAmt(knockbackAmt),rotatingSpd(rotSpd),randomFrame(util::random(GFX["commercial_assets/wind_solid_objects.png"].Sprite()->Size().x/24)){}
|
||||
void Debris::Update(float fElapsedTime){
|
||||
image_angle+=rotatingSpd*fElapsedTime;
|
||||
|
||||
@ -42,6 +42,7 @@ All rights reserved.
|
||||
#include <variant>
|
||||
#include "Oscillator.h"
|
||||
#include "Entity.h"
|
||||
#include"FriendlyTag.h"
|
||||
class Monster;
|
||||
class Player;
|
||||
using HitList=std::unordered_set<std::variant<Monster*,Player*>>;
|
||||
|
||||
@ -43,7 +43,7 @@ All rights reserved.
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
EnergyBolt::EnergyBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
|
||||
EnergyBolt::EnergyBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col)
|
||||
:Bullet(pos,vel,radius,damage,
|
||||
"energy_bolt.png",upperLevel,game->GetPlayer()->HasEnchant("Piercing Bolt")?true:false,INFINITE,true,friendly,col){}
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ All rights reserved.
|
||||
INCLUDE_ANIMATION_DATA
|
||||
INCLUDE_game
|
||||
|
||||
ExplosiveTrap::ExplosiveTrap(vf2d pos,float radius,float explosionRadius,float automaticDetonationTime,int damage,float fadeinTime,float fadeoutTime,float activationWaitTime,bool upperLevel,bool hitsMultiple,float lifetime,bool friendly,Pixel col,vf2d scale)
|
||||
ExplosiveTrap::ExplosiveTrap(vf2d pos,float radius,float explosionRadius,float automaticDetonationTime,int damage,float fadeinTime,float fadeoutTime,float activationWaitTime,bool upperLevel,bool hitsMultiple,float lifetime,FriendlyType friendly,Pixel col,vf2d scale)
|
||||
:activationWaitTime(activationWaitTime),automaticDetonationTime(automaticDetonationTime),activationRadius(radius),explosionRadius(explosionRadius),explosionCount(game->GetPlayer()->HasEnchant("Concussive Trap")?"Concussive Trap"_ENC["TRAP EXPLODE COUNT"]:1),Bullet(pos,{},0.f,damage,"Ability Icons/explosive_trap.png",upperLevel,hitsMultiple,INFINITE,false,friendly,col,scale,0.f,"Trap Hit"){
|
||||
fadeInTime=fadeinTime;
|
||||
animation.AddState("explosive_trap.png",ANIMATION_DATA["explosive_trap.png"]);
|
||||
|
||||
@ -45,7 +45,7 @@ All rights reserved.
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
FallingBullet::FallingBullet(const std::string&imgName,vf2d targetPos,vf2d vel,float zVel,float indicatorDisplayTime,float radius,int damage,bool upperLevel,bool hitsMultiple,float knockbackAmt,float lifetime,bool friendly,Pixel spellCircleCol,vf2d scale,float image_angle,float spellCircleRotation,float spellCircleRotationSpd,Pixel insigniaCol,float insigniaRotation,float insigniaRotationSpd)
|
||||
FallingBullet::FallingBullet(const std::string&imgName,vf2d targetPos,vf2d vel,float zVel,float indicatorDisplayTime,float radius,int damage,bool upperLevel,bool hitsMultiple,float knockbackAmt,float lifetime,FriendlyType friendly,Pixel spellCircleCol,vf2d scale,float image_angle,float spellCircleRotation,float spellCircleRotationSpd,Pixel insigniaCol,float insigniaRotation,float insigniaRotationSpd)
|
||||
:Bullet(targetPos,vel,0.f,damage,imgName,upperLevel,false,lifetime+0.1f,false,friendly,WHITE,scale,image_angle),targetPos(targetPos),zVel(zVel),indicatorDisplayTime(indicatorDisplayTime),knockbackAmt(knockbackAmt),collisionRadius(radius),
|
||||
indicator(targetPos,lifetime+0.1f,"range_indicator.png","spell_insignia.png",upperLevel,radius/12.f,0.5f,{},spellCircleCol,spellCircleRotation,spellCircleRotationSpd,false,radius/12.f,0.f,{},insigniaCol,insigniaRotation,insigniaRotationSpd,false){
|
||||
pos+=-vel*lifetime;
|
||||
|
||||
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#include "BulletTypes.h"
|
||||
#include "Player.h"
|
||||
|
||||
Feather::Feather(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool hitsMultiple,float lifetime,bool friendly,Pixel col,vf2d scale,float image_angle)
|
||||
Feather::Feather(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool hitsMultiple,float lifetime,FriendlyType friendly,Pixel col,vf2d scale,float image_angle)
|
||||
:Bullet(pos,vel,radius,damage,"feather.png",upperLevel,hitsMultiple,lifetime,true,friendly,col){
|
||||
SetBulletType(BulletType::FEATHER);
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ All rights reserved.
|
||||
INCLUDE_game
|
||||
INCLUDE_MONSTER_LIST
|
||||
|
||||
FireBolt::FireBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
|
||||
FireBolt::FireBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col)
|
||||
:Bullet(pos,vel,radius,damage,
|
||||
"energy_bolt.png",upperLevel,false,INFINITE,true,friendly,col){
|
||||
if(game->GetPlayer()->HasEnchant("Trail of Fire")&&friendly)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));
|
||||
|
||||
42
Adventures in Lestoria/FriendlyType.h
Normal file
42
Adventures in Lestoria/FriendlyType.h
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma region License
|
||||
/*
|
||||
License (OLC-3)
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Copyright 2026 Amy 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
|
||||
#pragma once
|
||||
enum FriendlyType:bool{
|
||||
NON_FRIENDLY=false,
|
||||
FRIENDLY=true,
|
||||
};
|
||||
@ -70,7 +70,7 @@ void Monster::STRATEGY::FROG(Monster&m,float fElapsedTime,std::string strategy){
|
||||
m.F(A::LOCKON_WAITTIME)=ConfigFloat("Attack Duration");
|
||||
vf2d tongueMaxRangePos=geom2d::line<float>(m.GetPos(),m.V(A::LOCKON_POS)).upoint(ConfigFloat("Tongue Max Range")/ConfigFloat("Range"));
|
||||
SoundEffect::PlaySFX("Slime Shoot",m.pos);
|
||||
CreateBullet(FrogTongue)(m,tongueMaxRangePos,ConfigFloat("Attack Duration"),m.GetAttack(),m.OnUpperLevel(),ConfigFloat("Tongue Knockback Strength"),false,ConfigPixel("Tongue Color"))EndBullet;
|
||||
CreateBullet(FrogTongue)(m,tongueMaxRangePos,ConfigFloat("Attack Duration"),m.GetAttack(),m.OnUpperLevel(),ConfigFloat("Tongue Knockback Strength"),NON_FRIENDLY,ConfigPixel("Tongue Color"))EndBullet;
|
||||
m.PerformShootAnimation();
|
||||
SETPHASE(2);
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ INCLUDE_game
|
||||
INCLUDE_MONSTER_LIST
|
||||
INCLUDE_GFX
|
||||
|
||||
FrogTongue::FrogTongue(Monster&sourceMonster,vf2d targetPos,float lifetime,int damage,bool upperLevel,float knockbackStrength,bool friendly,Pixel col)
|
||||
FrogTongue::FrogTongue(Monster&sourceMonster,vf2d targetPos,float lifetime,int damage,bool upperLevel,float knockbackStrength,FriendlyType friendly,Pixel col)
|
||||
:Bullet(sourceMonster.GetPos(),{},0,damage,upperLevel,friendly,col),targetPos(targetPos),tongueLength(0.f),knockbackStrength(knockbackStrength),sourceMonster(sourceMonster){
|
||||
this->lifetime=lifetime;
|
||||
duration=lifetime;
|
||||
|
||||
@ -98,7 +98,7 @@ void Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std
|
||||
const float range{util::random_range(0,ConfigPixels("Bombardment Max Distance"))};
|
||||
const vf2d targetPos{game->GetPlayer()->GetPos()+vf2d{range,randomAng}.cart()};
|
||||
m.F(A::SHRAPNEL_SHOT_FALL_TIMER)+=ConfigFloat("Shrapnel Shot Bullet Separation");
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Shrapnel Shot Bullet Radius"),ConfigInt("Shrapnel Shot Damage"),m.OnUpperLevel(),false,ConfigFloat("Shrapnel Knockback Amt"),ConfigFloat("Shrapnel Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Shrapnel Shot Bullet Radius")/100.f*1.75f,ConfigFloat("Shrapnel Shot Bullet Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Shrapnel Shot Bullet Radius"),ConfigInt("Shrapnel Shot Damage"),m.OnUpperLevel(),false,ConfigFloat("Shrapnel Knockback Amt"),ConfigFloat("Shrapnel Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Shrapnel Shot Bullet Radius")/100.f*1.75f,ConfigFloat("Shrapnel Shot Bullet Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
m.I(A::SHRAPNEL_SHOT_COUNT)--;
|
||||
}
|
||||
}
|
||||
@ -139,28 +139,28 @@ void Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std
|
||||
const float randomAng{util::random_range(0,2*PI)};
|
||||
const float range{util::random_range(0,ConfigPixels("Bombardment Max Distance"))};
|
||||
const vf2d targetPos{game->GetPlayer()->GetPos()+vf2d{range,randomAng}.cart()};
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
case PRECISE_BOMBARDMENT:{
|
||||
const float randomAng{util::random_range(0,2*PI)};
|
||||
const float range{util::random_range(0,ConfigPixels("Precise Bombardment Max Distance"))};
|
||||
const vf2d targetPos{game->GetPlayer()->GetPos()+vf2d{range,randomAng}.cart()};
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
case LINE:{
|
||||
//Draw a line from one side of the screen to the other, drawing through the middle.
|
||||
if(m.I(A::CANNON_SHOT_COUNT)==0)m.F(A::LINE_SHOT_ANG)=util::random_range(0,2*PI);
|
||||
const vf2d targetPos{geom2d::line{game->GetPlayer()->GetPos()+vf2d{float(game->ScreenHeight()),m.F(A::LINE_SHOT_ANG)}.cart(),game->GetPlayer()->GetPos()+vf2d{float(game->ScreenHeight()),m.F(A::LINE_SHOT_ANG)+PI}.cart()}.upoint(float(m.I(A::CANNON_SHOT_COUNT))/TOTAL_CANNON_SHOTS)};
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
case SHARPSHOOTER:{
|
||||
if(m.I(A::CANNON_SHOT_COUNT)%2==0)CreateBullet(FallingBullet)("cannonball.png",game->GetPlayer()->GetPos(),ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
if(m.I(A::CANNON_SHOT_COUNT)%2==0)CreateBullet(FallingBullet)("cannonball.png",game->GetPlayer()->GetPos(),ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
case PREDICTION:{
|
||||
const float angle{util::angleTo(game->GetPlayer()->GetPreviousPos(),game->GetPlayer()->GetPos())};
|
||||
const float range{util::random_range(0,100.f*game->GetPlayer()->GetMoveSpdMult())*ConfigFloat("Cannon Shot Impact Time")};
|
||||
const vf2d targetPos{game->GetPlayer()->GetPos()+vf2d{range,angle}.cart()};
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
}
|
||||
AdvanceCannonPhase();
|
||||
@ -278,28 +278,28 @@ void Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std
|
||||
const float randomAng{util::random_range(0,2*PI)};
|
||||
const float range{util::random_range(0,ConfigPixels("Bombardment Max Distance"))};
|
||||
const vf2d targetPos{game->GetPlayer()->GetPos()+vf2d{range,randomAng}.cart()};
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
case PRECISE_BOMBARDMENT:{
|
||||
const float randomAng{util::random_range(0,2*PI)};
|
||||
const float range{util::random_range(0,ConfigPixels("Precise Bombardment Max Distance"))};
|
||||
const vf2d targetPos{game->GetPlayer()->GetPos()+vf2d{range,randomAng}.cart()};
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
case LINE:{
|
||||
//Draw a line from one side of the screen to the other, drawing through the middle.
|
||||
if(m.I(A::CANNON_SHOT_COUNT)==0)m.F(A::LINE_SHOT_ANG)=util::random_range(0,2*PI);
|
||||
const vf2d targetPos{geom2d::line{game->GetPlayer()->GetPos()+vf2d{float(game->ScreenHeight()),m.F(A::LINE_SHOT_ANG)}.cart(),game->GetPlayer()->GetPos()+vf2d{float(game->ScreenHeight()),m.F(A::LINE_SHOT_ANG)+PI}.cart()}.upoint(float(m.I(A::CANNON_SHOT_COUNT))/TOTAL_CANNON_SHOTS)};
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
case SHARPSHOOTER:{
|
||||
if(m.I(A::CANNON_SHOT_COUNT)%2==0)CreateBullet(FallingBullet)("cannonball.png",game->GetPlayer()->GetPos(),ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
if(m.I(A::CANNON_SHOT_COUNT)%2==0)CreateBullet(FallingBullet)("cannonball.png",game->GetPlayer()->GetPos(),ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
case PREDICTION:{
|
||||
const float angle{util::angleTo(game->GetPlayer()->GetPreviousPos(),game->GetPlayer()->GetPos())};
|
||||
const float range{util::random_range(0,100.f*game->GetPlayer()->GetMoveSpdMult())*ConfigFloat("Cannon Shot Impact Time")};
|
||||
const vf2d targetPos{game->GetPlayer()->GetPos()+vf2d{range,angle}.cart()};
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
}
|
||||
AdvanceCannonPhase();
|
||||
@ -337,28 +337,28 @@ void Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std
|
||||
const float randomAng{util::random_range(0,2*PI)};
|
||||
const float range{util::random_range(0,ConfigPixels("Bombardment Max Distance"))};
|
||||
const vf2d targetPos{game->GetPlayer()->GetPos()+vf2d{range,randomAng}.cart()};
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
case PRECISE_BOMBARDMENT:{
|
||||
const float randomAng{util::random_range(0,2*PI)};
|
||||
const float range{util::random_range(0,ConfigPixels("Precise Bombardment Max Distance"))};
|
||||
const vf2d targetPos{game->GetPlayer()->GetPos()+vf2d{range,randomAng}.cart()};
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
case LINE:{
|
||||
//Draw a line from one side of the screen to the other, drawing through the middle.
|
||||
if(m.I(A::CANNON_SHOT_COUNT)==0)m.F(A::LINE_SHOT_ANG)=util::random_range(0,2*PI);
|
||||
const vf2d targetPos{geom2d::line{game->GetPlayer()->GetPos()+vf2d{float(game->ScreenHeight()),m.F(A::LINE_SHOT_ANG)}.cart(),game->GetPlayer()->GetPos()+vf2d{float(game->ScreenHeight()),m.F(A::LINE_SHOT_ANG)+PI}.cart()}.upoint(float(m.I(A::CANNON_SHOT_COUNT))/TOTAL_CANNON_SHOTS)};
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
case SHARPSHOOTER:{
|
||||
if(m.I(A::CANNON_SHOT_COUNT)%2==0)CreateBullet(FallingBullet)("cannonball.png",game->GetPlayer()->GetPos(),ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
if(m.I(A::CANNON_SHOT_COUNT)%2==0)CreateBullet(FallingBullet)("cannonball.png",game->GetPlayer()->GetPos(),ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
case PREDICTION:{
|
||||
const float angle{util::angleTo(game->GetPlayer()->GetPreviousPos(),game->GetPlayer()->GetPos())};
|
||||
const float range{util::random_range(0,100.f*game->GetPlayer()->GetMoveSpdMult())*ConfigFloat("Cannon Shot Impact Time")};
|
||||
const vf2d targetPos{game->GetPlayer()->GetPos()+vf2d{range,angle}.cart()};
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("cannonball.png",targetPos,ConfigVec("Cannon Vel"),ConfigFloatArr("Cannon Vel",2),ConfigFloat("Indicator Time"),ConfigPixels("Cannon Radius"),ConfigInt("Cannon Damage"),m.OnUpperLevel(),false,ConfigFloat("Cannon Knockback Amt"),ConfigFloat("Cannon Shot Impact Time"),NON_FRIENDLY,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*1.75f,ConfigFloat("Cannon Radius")/100.f*1.75f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Circle Rotation Spd")),ConfigPixel("Cannon Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Cannon Spell Insignia Rotation Spd")))EndBullet;
|
||||
}break;
|
||||
}
|
||||
AdvanceCannonPhase();
|
||||
|
||||
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#include "BulletTypes.h"
|
||||
#include "Attributable.h"
|
||||
|
||||
GhostSaber::GhostSaber(const vf2d pos,const std::weak_ptr<Monster>target,const float lifetime,const float distFromTarget,const float knockbackAmt,const float initialRot,const float radius,const float expandSpd,const int damage,const bool upperLevel,const float rotSpd,const bool friendly,const Pixel col,const vf2d scale,const float image_angle)
|
||||
GhostSaber::GhostSaber(const vf2d pos,const std::weak_ptr<Monster>target,const float lifetime,const float distFromTarget,const float knockbackAmt,const float initialRot,const float radius,const float expandSpd,const int damage,const bool upperLevel,const float rotSpd,const FriendlyType friendly,const Pixel col,const vf2d scale,const float image_angle)
|
||||
:Bullet(target.lock()->GetPos()+vf2d{distFromTarget,initialRot}.cart(),{},radius,damage,"ghost_dagger.png",upperLevel,true,INFINITE,false,friendly,col,scale,image_angle),attachedMonster(target),rotSpd(rotSpd),distFromTarget(distFromTarget),rot(initialRot),aliveTime(lifetime),knockbackAmt(knockbackAmt),expandSpd(expandSpd){}
|
||||
void GhostSaber::Update(float fElapsedTime){
|
||||
alphaOscillator.Update(fElapsedTime);
|
||||
|
||||
@ -137,21 +137,21 @@ void Monster::STRATEGY::GIANT_OCTOPUS(Monster&m,float fElapsedTime,std::string s
|
||||
}
|
||||
if(m.F(A::SHOOT_TIMER)<=0.f){
|
||||
const auto CreateBurstBullet=[&](){
|
||||
CreateBullet(BurstBullet)(m.GetPos(),util::pointTo(m.GetPos(),game->GetPlayer()->GetPos())*ConfigFloat("Big Bullet Speed"),game->GetPlayer(),ConfigPixels("Big Bullet Detection Radius"),ConfigInt("Big Bullet Extra Bullet Count"),util::degToRad(ConfigFloat("Big Bullet Extra Bullet Rotate Speed")),ConfigFloat("Big Bullet Extra Bullet Radius"),vf2d{ConfigFloatArr("Big Bullet Extra Bullet Image Scale",0),ConfigFloatArr("Big Bullet Extra Bullet Image Scale",1)},ConfigFloat("Big Bullet Extra Bullet Speed"),ConfigFloat("Big Bullet Extra Bullet Acceleration"),ConfigFloat("Big Bullet Radius"),ConfigInt("Big Bullet Damage"),m.OnUpperLevel(),false,ConfigPixel("Big Bullet Color"),vf2d{ConfigFloat("Big Bullet Image Scale"),ConfigFloat("Big Bullet Image Scale")})EndBullet;
|
||||
CreateBullet(BurstBullet)(m.GetPos(),util::pointTo(m.GetPos(),game->GetPlayer()->GetPos())*ConfigFloat("Big Bullet Speed"),game->GetPlayer(),ConfigPixels("Big Bullet Detection Radius"),ConfigInt("Big Bullet Extra Bullet Count"),util::degToRad(ConfigFloat("Big Bullet Extra Bullet Rotate Speed")),ConfigFloat("Big Bullet Extra Bullet Radius"),vf2d{ConfigFloatArr("Big Bullet Extra Bullet Image Scale",0),ConfigFloatArr("Big Bullet Extra Bullet Image Scale",1)},ConfigFloat("Big Bullet Extra Bullet Speed"),ConfigFloat("Big Bullet Extra Bullet Acceleration"),ConfigFloat("Big Bullet Radius"),ConfigInt("Big Bullet Damage"),m.OnUpperLevel(),NON_FRIENDLY,ConfigPixel("Big Bullet Color"),vf2d{ConfigFloat("Big Bullet Image Scale"),ConfigFloat("Big Bullet Image Scale")})EndBullet;
|
||||
m.F(A::SHOOT_TIMER)=ConfigFloat("Big Bullet Boss Rest Time");
|
||||
m.I(A::ATTACK_COUNT)=-1;
|
||||
};
|
||||
if(InSecondPhase){
|
||||
if(m.F(A::LAST_INK_SHOOT_TIMER)<=0.f){
|
||||
CreateBullet(InkBullet)(m.GetPos(),game->GetPlayer()->GetPos(),vf2d{ConfigFloat("Phase 2.Ink Bullet Speed"),0.f},ConfigFloat("Phase 2.Ink Explosion Radius"),ConfigFloat("Phase 2.Ink Puddle Lifetime"),ConfigFloat("Phase 2.Ink Slowdown Time"),ConfigFloat("Phase 2.Ink Slowdown Amount")/100.f,ConfigFloat("Phase 2.Ink Puddle Collision Radius"),m.OnUpperLevel(),false)EndBullet;
|
||||
CreateBullet(InkBullet)(m.GetPos(),game->GetPlayer()->GetPos(),vf2d{ConfigFloat("Phase 2.Ink Bullet Speed"),0.f},ConfigFloat("Phase 2.Ink Explosion Radius"),ConfigFloat("Phase 2.Ink Puddle Lifetime"),ConfigFloat("Phase 2.Ink Slowdown Time"),ConfigFloat("Phase 2.Ink Slowdown Amount")/100.f,ConfigFloat("Phase 2.Ink Puddle Collision Radius"),m.OnUpperLevel(),NON_FRIENDLY)EndBullet;
|
||||
m.F(A::LAST_INK_SHOOT_TIMER)=ConfigFloat("Phase 2.Ink Bullet Frequency");
|
||||
goto BulletShot;
|
||||
}else
|
||||
if(m.I(A::BULLET_COUNT_AFTER_INK_ATTACK)>ConfigInt("Phase 2.Homing Bullet Starts After")){
|
||||
if(m.I(A::ATTACK_COUNT)%ConfigInt("Phase 2.Homing Bullet Frequency")==0)CreateBullet(HomingBullet)(m.GetPos(),Entity{game->GetPlayer()},util::degToRad(ConfigFloat("Phase 2.Homing Bullet Rotation Speed")),util::degToRad(ConfigFloat("Phase 2.Homing Bullet Rotation Speed Player Covered In Ink")),ConfigFloat("Phase 2.Homing Bullet Lifetime"),ConfigFloat("Bullet Speed"),ConfigFloat("Bullet Radius"),ConfigFloat("Bullet Damage"),m.OnUpperLevel(),false,ConfigPixel("Phase 2.Homing Bullet Color"),{ConfigFloat("Bullet Radius"),ConfigFloat("Bullet Radius")})EndBullet;
|
||||
if(m.I(A::ATTACK_COUNT)%ConfigInt("Phase 2.Homing Bullet Frequency")==0)CreateBullet(HomingBullet)(m.GetPos(),Entity{game->GetPlayer()},util::degToRad(ConfigFloat("Phase 2.Homing Bullet Rotation Speed")),util::degToRad(ConfigFloat("Phase 2.Homing Bullet Rotation Speed Player Covered In Ink")),ConfigFloat("Phase 2.Homing Bullet Lifetime"),ConfigFloat("Bullet Speed"),ConfigFloat("Bullet Radius"),ConfigFloat("Bullet Damage"),m.OnUpperLevel(),NON_FRIENDLY,ConfigPixel("Phase 2.Homing Bullet Color"),{ConfigFloat("Bullet Radius"),ConfigFloat("Bullet Radius")})EndBullet;
|
||||
else
|
||||
if(m.I(A::ATTACK_COUNT)>=ConfigInt("Big Bullet Frequency")-1)CreateBurstBullet();
|
||||
else CreateBullet(Bullet)(m.GetPos(),util::pointTo(m.GetPos(),game->GetPlayer()->GetPos())*ConfigFloat("Bullet Speed"),ConfigFloat("Bullet Radius"),ConfigFloat("Bullet Damage"),m.OnUpperLevel(),false,ConfigPixel("Bullet Color"),{ConfigFloat("Bullet Radius"),ConfigFloat("Bullet Radius")})EndBullet;
|
||||
else CreateBullet(Bullet)(m.GetPos(),util::pointTo(m.GetPos(),game->GetPlayer()->GetPos())*ConfigFloat("Bullet Speed"),ConfigFloat("Bullet Radius"),ConfigFloat("Bullet Damage"),m.OnUpperLevel(),NON_FRIENDLY,ConfigPixel("Bullet Color"),{ConfigFloat("Bullet Radius"),ConfigFloat("Bullet Radius")})EndBullet;
|
||||
m.F(A::SHOOT_TIMER)=ConfigFloat("Shoot Frequency");
|
||||
goto BulletShot;
|
||||
}
|
||||
@ -160,7 +160,7 @@ void Monster::STRATEGY::GIANT_OCTOPUS(Monster&m,float fElapsedTime,std::string s
|
||||
if(m.I(A::ATTACK_COUNT)>=ConfigInt("Big Bullet Frequency")-1)CreateBurstBullet();
|
||||
else{
|
||||
m.F(A::SHOOT_TIMER)=ConfigFloat("Shoot Frequency");
|
||||
CreateBullet(Bullet)(m.GetPos(),util::pointTo(m.GetPos(),game->GetPlayer()->GetPos())*ConfigFloat("Bullet Speed"),ConfigFloat("Bullet Radius"),ConfigFloat("Bullet Damage"),m.OnUpperLevel(),false,ConfigPixel("Bullet Color"),{ConfigFloat("Bullet Radius"),ConfigFloat("Bullet Radius")})EndBullet;
|
||||
CreateBullet(Bullet)(m.GetPos(),util::pointTo(m.GetPos(),game->GetPlayer()->GetPos())*ConfigFloat("Bullet Speed"),ConfigFloat("Bullet Radius"),ConfigFloat("Bullet Damage"),m.OnUpperLevel(),NON_FRIENDLY,ConfigPixel("Bullet Color"),{ConfigFloat("Bullet Radius"),ConfigFloat("Bullet Radius")})EndBullet;
|
||||
}
|
||||
BulletShot:
|
||||
m.F(A::LAST_SHOOT_TIMER)=1.f;
|
||||
|
||||
@ -38,7 +38,7 @@ All rights reserved.
|
||||
|
||||
#include "BulletTypes.h"
|
||||
|
||||
HomingBullet::HomingBullet(const vf2d pos,const Entity target,const float rotateTowardsSpeed,const float rotateTowardsSpeedCoveredInInk,const float lifetime,const float speed,const float radius,const int damage,const bool upperLevel,const bool friendly,const Pixel col,const vf2d scale,const float image_angle)
|
||||
HomingBullet::HomingBullet(const vf2d pos,const Entity target,const float rotateTowardsSpeed,const float rotateTowardsSpeedCoveredInInk,const float lifetime,const float speed,const float radius,const int damage,const bool upperLevel,const FriendlyType friendly,const Pixel col,const vf2d scale,const float image_angle)
|
||||
:Bullet(pos,util::pointTo(pos,target.GetPos())*speed,radius,damage,upperLevel,friendly,col,scale,image_angle),target(target),rotateTowardsSpeed(rotateTowardsSpeed),rotateTowardsSpeedCoveredInInk(rotateTowardsSpeedCoveredInInk){
|
||||
this->lifetime=lifetime;
|
||||
}
|
||||
|
||||
@ -48,10 +48,10 @@ INCLUDE_GFX
|
||||
INCLUDE_MONSTER_LIST
|
||||
INCLUDE_WINDOW_SIZE
|
||||
|
||||
IBullet::IBullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col,vf2d scale,float image_angle)
|
||||
IBullet::IBullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col,vf2d scale,float image_angle)
|
||||
:pos(pos),vel(vel),radius(radius),damage(damage),col(col),friendly(friendly),upperLevel(upperLevel),scale(scale),image_angle(image_angle){};
|
||||
|
||||
IBullet::IBullet(vf2d pos,vf2d vel,float radius,int damage,const std::string&animation,bool upperLevel,bool hitsMultiple,float lifetime,bool rotatesWithAngle,bool friendly,Pixel col,vf2d scale,float image_angle,std::string_view hitSound)
|
||||
IBullet::IBullet(vf2d pos,vf2d vel,float radius,int damage,const std::string&animation,bool upperLevel,bool hitsMultiple,float lifetime,bool rotatesWithAngle,FriendlyType friendly,Pixel col,vf2d scale,float image_angle,std::string_view hitSound)
|
||||
:pos(pos),vel(vel),radius(radius),damage(damage),col(col),animated(true),rotates(rotatesWithAngle),lifetime(lifetime),hitsMultiple(hitsMultiple),friendly(friendly),upperLevel(upperLevel),scale(scale),image_angle(image_angle),hitSound(std::string(hitSound)){
|
||||
this->animation.AddState(animation,ANIMATION_DATA.at(animation));
|
||||
this->animation.ChangeState(internal_animState,animation);
|
||||
|
||||
@ -40,6 +40,7 @@ All rights reserved.
|
||||
#include "olcUTIL_Animate2D.h"
|
||||
#include "Monster.h"
|
||||
#include "DEFINES.h"
|
||||
#include"FriendlyTag.h"
|
||||
using HitList=std::unordered_set<std::variant<Monster*,Player*>>;
|
||||
|
||||
enum class HurtType{
|
||||
@ -71,7 +72,7 @@ struct IBullet{
|
||||
bool rotates=false;
|
||||
bool animated=false;
|
||||
float fadeOutTime=0.f; //Setting the fade out time causes the bullet's lifetime to be set to the fadeout time as well, as that's when the bullet's alpha will reach 0, so it dies.
|
||||
bool friendly=false; //Whether or not it's a player bullet or enemy bullet.
|
||||
FriendlyType friendly=NON_FRIENDLY; //Whether or not it's a player bullet or enemy bullet.
|
||||
bool upperLevel=false;
|
||||
bool alwaysOnTop=false;
|
||||
float z=0.f;
|
||||
@ -110,9 +111,9 @@ public:
|
||||
Animate2D::AnimationState internal_animState;
|
||||
HitList hitList;
|
||||
virtual ~IBullet()=default;
|
||||
IBullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f);
|
||||
IBullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f);
|
||||
//Initializes a bullet with an animation.
|
||||
IBullet(vf2d pos,vf2d vel,float radius,int damage,const std::string&animation,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,bool rotatesWithAngle=false,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f,std::string_view hitSound="");
|
||||
IBullet(vf2d pos,vf2d vel,float radius,int damage,const std::string&animation,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,bool rotatesWithAngle=false,FriendlyType friendly=NON_FRIENDLY,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f,std::string_view hitSound="");
|
||||
public:
|
||||
|
||||
void SimulateUpdate(const float fElapsedTime);
|
||||
|
||||
@ -40,7 +40,7 @@ All rights reserved.
|
||||
|
||||
INCLUDE_ANIMATION_DATA
|
||||
|
||||
InkBullet::InkBullet(const vf2d pos,const vf2d targetPos,const vf2d vel,const float inkExplosionRadius,const float inkPuddleLifetime,const float inkSlowdownDuration,const float inkSlowdownPct,const float inkPuddleRadius,const bool upperLevel,const bool friendly)
|
||||
InkBullet::InkBullet(const vf2d pos,const vf2d targetPos,const vf2d vel,const float inkExplosionRadius,const float inkPuddleLifetime,const float inkSlowdownDuration,const float inkSlowdownPct,const float inkPuddleRadius,const bool upperLevel,const FriendlyType friendly)
|
||||
:Bullet(pos,vel,inkExplosionRadius,0,"inkbullet.png",upperLevel,friendly),targetPos(targetPos),inkExplosionRadius(inkExplosionRadius),inkSlowdownPct(inkSlowdownPct),inkSlowdownDuration(inkSlowdownDuration),inkPuddleLifetime(inkPuddleLifetime),inkPuddleRadius(inkPuddleRadius){
|
||||
additiveBlending=true;
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ void ItemInfo::InitializeScripts(){
|
||||
return Effect{self.pos,0.5f,"fire_ring.png",self.OnUpperLevel(),util::random_range(0.7f,1.f),0.1f,{},PixelLerp(Pixel(0xF7B752),Pixel(0xE74F30),util::random(1.f)),util::random(2*PI),0.f,true};
|
||||
});
|
||||
}
|
||||
CreateBullet(ThrownProjectile)(game->GetPlayer()->GetPos(),targetingPos.value(),props.GetString("Image"),props.GetFloat("Cast Size")/100.f*24,game->GetPlayer()->GetZ(),0.3f,8.f,projectileDamage,game->GetPlayer()->OnUpperLevel(),false,INFINITE,true,WHITE,props.GetFloat("Cast Size")/100.f*vf2d{1.f,1.f},0.f,
|
||||
CreateBullet(ThrownProjectile)(game->GetPlayer()->GetPos(),targetingPos.value(),props.GetString("Image"),props.GetFloat("Cast Size")/100.f*24,game->GetPlayer()->GetZ(),0.3f,8.f,projectileDamage,game->GetPlayer()->OnUpperLevel(),false,INFINITE,FRIENDLY,WHITE,props.GetFloat("Cast Size")/100.f*vf2d{1.f,1.f},0.f,
|
||||
Effect{vf2d{},ANIMATION_DATA.at("explosionframes.png").GetTotalAnimationDuration(),"explosionframes.png",game->GetPlayer()->OnUpperLevel(),props.GetFloat("Cast Size")/100.f*vf2d{1.f,1.f}},props.GetString("Explode Sound Effect"),lingeringEffect)EndBullet;
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -45,7 +45,7 @@ All rights reserved.
|
||||
INCLUDE_game
|
||||
INCLUDE_MONSTER_LIST
|
||||
|
||||
LargeStone::LargeStone(vf2d pos,const float stoneThrowTime,const vf2d landingPos,float moveVelWaitTimer,float radius,float z,float gravity,int damage,const float knockbackAmt,bool upperLevel,bool hitsMultiple,float lifetime,bool friendly,Pixel col,vf2d scale,float image_angle)
|
||||
LargeStone::LargeStone(vf2d pos,const float stoneThrowTime,const vf2d landingPos,float moveVelWaitTimer,float radius,float z,float gravity,int damage,const float knockbackAmt,bool upperLevel,bool hitsMultiple,float lifetime,FriendlyType friendly,Pixel col,vf2d scale,float image_angle)
|
||||
:knockbackAmt(knockbackAmt),stoneThrowTime(stoneThrowTime),startingPos(pos),landingPos(landingPos),gravity(gravity),initialMoveWaitTime(moveVelWaitTimer),moveTimer(moveVelWaitTimer),Bullet(pos,{},radius,damage,"large_rock.png",upperLevel,false,INFINITE,false,friendly,col,scale,image_angle){
|
||||
this->z=z;
|
||||
Deactivate();
|
||||
|
||||
@ -44,7 +44,7 @@ All rights reserved.
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
LargeTornado::LargeTornado(vf2d pos,const float suctionAmt,const float knockupAmt,const float knockbackAmt,const int damage,const float radius,const float lifetime,bool upperLevel,bool friendly,Pixel col,const vf2d scale)
|
||||
LargeTornado::LargeTornado(vf2d pos,const float suctionAmt,const float knockupAmt,const float knockbackAmt,const int damage,const float radius,const float lifetime,bool upperLevel,FriendlyType friendly,Pixel col,const vf2d scale)
|
||||
:suctionAmt(suctionAmt),knockupDuration(knockupAmt),knockbackAmt(knockbackAmt),Bullet(pos,vf2d{},radius,damage,"large_tornado.png",upperLevel,true,lifetime+0.5f,false,friendly,col,scale){
|
||||
SetBulletType(BulletType::LARGE_TORNADO);
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ All rights reserved.
|
||||
INCLUDE_game
|
||||
INCLUDE_GFX
|
||||
|
||||
LevitatingRock::LevitatingRock(const Monster&attachedTarget,const vf2d&attackingTarget,const float fadeInTime,const float facingRotOffset,const float distance,const float lockOnTime,const float waitTime,const float targetSpd,const float radius,const int damage,const bool upperLevel,const bool friendly,const Pixel col,const vf2d scale)
|
||||
LevitatingRock::LevitatingRock(const Monster&attachedTarget,const vf2d&attackingTarget,const float fadeInTime,const float facingRotOffset,const float distance,const float lockOnTime,const float waitTime,const float targetSpd,const float radius,const int damage,const bool upperLevel,const FriendlyType friendly,const Pixel col,const vf2d scale)
|
||||
:attachedTarget(attachedTarget),attackingTarget(attackingTarget),fadeInTime(fadeInTime),fadeInOriginalTime(fadeInTime),facingRotOffset(facingRotOffset),dist(distance),lockOnTime(lockOnTime),initialWaitTime(waitTime),flyingSpd(targetSpd),collisionRadius(radius),
|
||||
Bullet(attachedTarget.GetPos(),{},0.f,damage,"rock.png",upperLevel,false,INFINITE,false,friendly,col){}
|
||||
void LevitatingRock::Update(float fElapsedTime){
|
||||
|
||||
@ -47,7 +47,7 @@ INCLUDE_game
|
||||
INCLUDE_MONSTER_LIST
|
||||
INCLUDE_EMITTER_LIST
|
||||
|
||||
LightningBolt::LightningBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
|
||||
LightningBolt::LightningBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col)
|
||||
:Bullet(pos,vel,radius,damage,"lightning_bolt.png",upperLevel,false,INFINITE,true,friendly,col){}
|
||||
|
||||
void LightningBolt::Update(float fElapsedTime){
|
||||
|
||||
@ -776,7 +776,7 @@ void Monster::Moved(){
|
||||
}
|
||||
if(currentCast){
|
||||
currentCast.reset();
|
||||
DamageNumber::AddDamageNumber(GetPos(),0,false,DamageNumberType::INTERRUPT);
|
||||
DamageNumber::AddDamageNumber(GetPos(),0,NON_FRIENDLY,DamageNumberType::INTERRUPT);
|
||||
PerformIdleAnimation();
|
||||
}
|
||||
}
|
||||
@ -864,8 +864,7 @@ bool Monster::_Hurt(int damage,bool onUpperLevel,float z,const TrueDamageFlag da
|
||||
if(lastDotTimer>0){
|
||||
dotNumberPtr.get()->AddDamage(int(mod_dmg));
|
||||
}else{
|
||||
dotNumberPtr=DamageNumber::AddDamageNumber(pos+vf2d{0,8.f},int(mod_dmg),false,DamageNumberType::DOT);
|
||||
DAMAGENUMBER_LIST.push_back(dotNumberPtr);
|
||||
dotNumberPtr=DamageNumber::AddDamageNumber(pos+vf2d{0,8.f},int(mod_dmg),NON_FRIENDLY,DamageNumberType::DOT);
|
||||
}
|
||||
lastDotTimer=0.05f;
|
||||
}else{
|
||||
@ -874,7 +873,6 @@ bool Monster::_Hurt(int damage,bool onUpperLevel,float z,const TrueDamageFlag da
|
||||
damageNumberPtr.get()->SetPauseTimer(0.4f);
|
||||
}else{
|
||||
damageNumberPtr=DamageNumber::AddDamageNumber(pos,int(mod_dmg));
|
||||
DAMAGENUMBER_LIST.push_back(damageNumberPtr);
|
||||
}
|
||||
#pragma region Change Label based on bonus conditions (Crit/Backstab)
|
||||
if(crit){
|
||||
@ -1498,7 +1496,7 @@ const bool Monster::_DealTrueDamage(const uint32_t damageAmt,HurtFlag::HurtFlag
|
||||
|
||||
void Monster::Heal(const int healAmt,const bool displayDamageNumber){
|
||||
hp=std::clamp(hp+healAmt,0,int(GetMaxHealth()));
|
||||
if(displayDamageNumber)DamageNumber::AddDamageNumber(GetPos(),healAmt,false,DamageNumberType::HEALTH_GAIN);
|
||||
if(displayDamageNumber)DamageNumber::AddDamageNumber(GetPos(),healAmt,NON_FRIENDLY,DamageNumberType::HEALTH_GAIN);
|
||||
}
|
||||
|
||||
const float Monster::GetModdedStatBonuses(std::string_view stat)const{
|
||||
|
||||
@ -131,7 +131,7 @@ void Monster::STRATEGY::PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std::string
|
||||
case PREPARE_SHOOT:{
|
||||
m.F(A::SHOOT_TIMER)-=fElapsedTime;
|
||||
if(m.F(A::SHOOT_TIMER)<=0.f){
|
||||
CreateBullet(Bullet)(m.GetPos(),util::pointTo(m.GetPos(),m.V(A::LOCKON_POS))*ConfigFloat("Bullet Speed"),ConfigFloat("Bullet Radius"),m.GetAttack(),m.OnUpperLevel(),false,ConfigPixel("Bullet Color"),vf2d{1.f,1.f}*ConfigFloat("Bullet Radius")/3.f)EndBullet;
|
||||
CreateBullet(Bullet)(m.GetPos(),util::pointTo(m.GetPos(),m.V(A::LOCKON_POS))*ConfigFloat("Bullet Speed"),ConfigFloat("Bullet Radius"),m.GetAttack(),m.OnUpperLevel(),NON_FRIENDLY,ConfigPixel("Bullet Color"),vf2d{1.f,1.f}*ConfigFloat("Bullet Radius")/3.f)EndBullet;
|
||||
m.PerformAnimation("SHOOTING");
|
||||
m.F(A::SHOOT_ANIMATION_TIME)=m.GetCurrentAnimation().GetTotalAnimationDuration();
|
||||
SETPHASE(SHOOT_RELOAD);
|
||||
|
||||
@ -579,7 +579,7 @@ void Player::Update(float fElapsedTime){
|
||||
SoundEffect::PlaySFX("Deadly Dash",GetPos());
|
||||
SetPos(MoveUsingPathfinding(deadlyDashEndingPos));
|
||||
SetAnimationBasedOnTargetingDirection("DEADLYDASH",util::angleTo(originalPos,GetPos()));
|
||||
CreateBullet(DeadlyDash)(originalPos,GetPos(),"Thief.Ability 2.Hit Radius"_F,"Thief.Ability 2.Deadly Dash After Images Lingering Time"_F,GetAttack()*"Thief.Ability 2.Damage"_F,"Thief.Ability 2.Knockback Amount"_F,OnUpperLevel(),true,5.f,animation.currentStateName,WHITE)EndBullet;
|
||||
CreateBullet(DeadlyDash)(originalPos,GetPos(),"Thief.Ability 2.Hit Radius"_F,"Thief.Ability 2.Deadly Dash After Images Lingering Time"_F,GetAttack()*"Thief.Ability 2.Damage"_F,"Thief.Ability 2.Knockback Amount"_F,OnUpperLevel(),FRIENDLY,5.f,animation.currentStateName,WHITE)EndBullet;
|
||||
SetState(State::NORMAL);
|
||||
SetAdditiveBlending(false);
|
||||
game->SetupWorldShake(0.3f);
|
||||
@ -800,7 +800,7 @@ void Player::Update(float fElapsedTime){
|
||||
vf2d extendedLine=pointTowardsCursor.upoint(1.1f);
|
||||
float angleToCursor=atan2(extendedLine.y-GetPos().y,extendedLine.x-GetPos().x);
|
||||
attack_cooldown_timer=ARROW_ATTACK_COOLDOWN;
|
||||
BULLET_LIST.push_back(std::make_unique<Arrow>(Arrow(GetPos(),extendedLine,vf2d{cos(angleToCursor)*"Ranger.Ability 1.ArrowSpd"_F,float(sin(angleToCursor)*"Ranger.Ability 1.ArrowSpd"_F-PI/8*"Ranger.Ability 1.ArrowSpd"_F)}+movementVelocity/1.5f,12*"Ranger.Ability 1.ArrowRadius"_F/100,int(GetAttack()*"Ranger.Ability 1.DamageMult"_F),OnUpperLevel(),true)));
|
||||
BULLET_LIST.push_back(std::make_unique<Arrow>(Arrow(GetPos(),extendedLine,vf2d{cos(angleToCursor)*"Ranger.Ability 1.ArrowSpd"_F,float(sin(angleToCursor)*"Ranger.Ability 1.ArrowSpd"_F-PI/8*"Ranger.Ability 1.ArrowSpd"_F)}+movementVelocity/1.5f,12*"Ranger.Ability 1.ArrowRadius"_F/100,int(GetAttack()*"Ranger.Ability 1.DamageMult"_F),OnUpperLevel(),FRIENDLY)));
|
||||
if(GetClass()&(RANGER|TRAPPER))SetAnimationBasedOnTargetingDirection("SHOOT",angleToCursor);
|
||||
rapidFireTimer=RAPID_FIRE_SHOOT_DELAY;
|
||||
}else{
|
||||
@ -818,10 +818,10 @@ void Player::Update(float fElapsedTime){
|
||||
const float daggerLifetime{"Thief.Ability 1.Dagger Range"_F/"Thief.Ability 1.Dagger Speed"_F};
|
||||
|
||||
if(HasEnchant("Triple Toss")){
|
||||
CreateBullet(Bullet)(GetPos(),vf2d{"Thief.Ability 1.Dagger Speed"_F,angleToCursor+util::degToRad("Triple Toss"_ENC["SPREAD ANGLE"])}.cart(),"Thief.Ability 1.Dagger Radius"_F,GetAttack()*"Thief.Ability 1.Damage"_I,"dagger.png",OnUpperLevel(),false,daggerLifetime,true,true,WHITE,{1.f,1.f},0.f,"Dagger Hit")EndBullet;
|
||||
CreateBullet(Bullet)(GetPos(),vf2d{"Thief.Ability 1.Dagger Speed"_F,angleToCursor-util::degToRad("Triple Toss"_ENC["SPREAD ANGLE"])}.cart(),"Thief.Ability 1.Dagger Radius"_F,GetAttack()*"Thief.Ability 1.Damage"_I,"dagger.png",OnUpperLevel(),false,daggerLifetime,true,true,WHITE,{1.f,1.f},0.f,"Dagger Hit")EndBullet;
|
||||
CreateBullet(Bullet)(GetPos(),vf2d{"Thief.Ability 1.Dagger Speed"_F,angleToCursor+util::degToRad("Triple Toss"_ENC["SPREAD ANGLE"])}.cart(),"Thief.Ability 1.Dagger Radius"_F,GetAttack()*"Thief.Ability 1.Damage"_I,"dagger.png",OnUpperLevel(),false,daggerLifetime,true,FRIENDLY,WHITE,{1.f,1.f},0.f,"Dagger Hit")EndBullet;
|
||||
CreateBullet(Bullet)(GetPos(),vf2d{"Thief.Ability 1.Dagger Speed"_F,angleToCursor-util::degToRad("Triple Toss"_ENC["SPREAD ANGLE"])}.cart(),"Thief.Ability 1.Dagger Radius"_F,GetAttack()*"Thief.Ability 1.Damage"_I,"dagger.png",OnUpperLevel(),false,daggerLifetime,true,FRIENDLY,WHITE,{1.f,1.f},0.f,"Dagger Hit")EndBullet;
|
||||
}
|
||||
CreateBullet(Bullet)(GetPos(),vf2d{"Thief.Ability 1.Dagger Speed"_F,angleToCursor}.cart(),"Thief.Ability 1.Dagger Radius"_F,GetAttack()*"Thief.Ability 1.Damage"_I,"dagger.png",OnUpperLevel(),false,daggerLifetime,true,true,WHITE,{1.f,1.f},0.f,"Dagger Hit")EndBullet;
|
||||
CreateBullet(Bullet)(GetPos(),vf2d{"Thief.Ability 1.Dagger Speed"_F,angleToCursor}.cart(),"Thief.Ability 1.Dagger Radius"_F,GetAttack()*"Thief.Ability 1.Damage"_I,"dagger.png",OnUpperLevel(),false,daggerLifetime,true,FRIENDLY,WHITE,{1.f,1.f},0.f,"Dagger Hit")EndBullet;
|
||||
}
|
||||
daggerThrowWaitTimer-=fElapsedTime;
|
||||
#pragma endregion
|
||||
@ -990,8 +990,7 @@ bool Player::Hurt(int damage,bool onUpperLevel,float z,const TrueDamageFlag dama
|
||||
if(lastDotTimer>0){
|
||||
dotNumberPtr.get()->AddDamage(int(mod_dmg));
|
||||
}else{
|
||||
dotNumberPtr==DamageNumber::AddDamageNumber(pos+vf2d{0,8.f},int(mod_dmg),false,DamageNumberType::DOT);
|
||||
DAMAGENUMBER_LIST.push_back(dotNumberPtr);
|
||||
dotNumberPtr=DamageNumber::AddDamageNumber(pos+vf2d{0,8.f},int(mod_dmg),NON_FRIENDLY,DamageNumberType::DOT);
|
||||
}
|
||||
lastDotTimer=0.05f;
|
||||
}else{
|
||||
@ -1000,7 +999,7 @@ bool Player::Hurt(int damage,bool onUpperLevel,float z,const TrueDamageFlag dama
|
||||
if(tookShieldDamage)damageNumberPtr->SetType(DamageNumberType::SHIELD_LOSS);
|
||||
damageNumberPtr.get()->SetPauseTimer(0.4f);
|
||||
}else{
|
||||
damageNumberPtr=DamageNumber::AddDamageNumber(pos,int(mod_dmg),true);
|
||||
damageNumberPtr=DamageNumber::AddDamageNumber(pos,int(mod_dmg),FRIENDLY);
|
||||
if(tookShieldDamage)damageNumberPtr->SetType(DamageNumberType::SHIELD_LOSS);
|
||||
DAMAGENUMBER_LIST.push_back(damageNumberPtr);
|
||||
}
|
||||
@ -1055,7 +1054,7 @@ void Player::CancelCast(){
|
||||
bool wasCasting=castInfo.castTimer>0;
|
||||
castInfo={"",0};
|
||||
std::erase_if(buffList,[](Buff&b){return b.type==OVER_TIME_DURING_CAST;}); //Remove all buffs that would be applied during a cast, as we got interrupted.
|
||||
if(wasCasting)DamageNumber::AddDamageNumber(GetPos(),0,true,DamageNumberType::INTERRUPT);
|
||||
if(wasCasting)DamageNumber::AddDamageNumber(GetPos(),0,FRIENDLY,DamageNumberType::INTERRUPT);
|
||||
if(state==State::CASTING){
|
||||
state=State::NORMAL;
|
||||
castPrepAbility->waitForRelease=true;
|
||||
@ -1306,14 +1305,14 @@ void Player::_SetIframes(float duration){
|
||||
|
||||
bool Player::Heal(int damage,bool suppressDamageNumber){
|
||||
hp=std::clamp(hp+damage,0,int(GetMaxHealth()));
|
||||
if(!suppressDamageNumber&&damage>0)DamageNumber::AddDamageNumber(GetPos(),damage,true,DamageNumberType::HEALTH_GAIN);
|
||||
if(!suppressDamageNumber&&damage>0)DamageNumber::AddDamageNumber(GetPos(),damage,FRIENDLY,DamageNumberType::HEALTH_GAIN);
|
||||
Input::SetLightbar(PixelLerp(DARK_RED,GREEN,GetHealthRatio()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void Player::RestoreMana(int amt,bool suppressDamageNumber){
|
||||
mana=std::clamp(mana+amt,0,GetMaxMana());
|
||||
if(amt>0&&!suppressDamageNumber)DamageNumber::AddDamageNumber(GetPos(),amt,true,DamageNumberType::MANA_GAIN);
|
||||
if(amt>0&&!suppressDamageNumber)DamageNumber::AddDamageNumber(GetPos(),amt,FRIENDLY,DamageNumberType::MANA_GAIN);
|
||||
}
|
||||
|
||||
void Player::ConsumeMana(int amt){
|
||||
|
||||
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#include "BulletTypes.h"
|
||||
#include <ranges>
|
||||
|
||||
PoisonBottle::PoisonBottle(vf2d pos,vf2d targetPos,const std::string&img,float explodeRadius,float bounceExplodeRadius,float z,float totalFallTime,float totalRiseZAmt,int damage,int additionalBounceCount,bool upperLevel,bool hitsMultiple,float lifetime,bool friendly,Pixel col,vf2d scale,float image_angle)
|
||||
PoisonBottle::PoisonBottle(vf2d pos,vf2d targetPos,const std::string&img,float explodeRadius,float bounceExplodeRadius,float z,float totalFallTime,float totalRiseZAmt,int damage,int additionalBounceCount,bool upperLevel,bool hitsMultiple,float lifetime,FriendlyType friendly,Pixel col,vf2d scale,float image_angle)
|
||||
:ThrownProjectile(pos,targetPos,img,explodeRadius,z,totalFallTime,totalRiseZAmt,damage,upperLevel,hitsMultiple,lifetime,friendly,col,scale,image_angle),bounceExplodeRadius(bounceExplodeRadius),additionalBounceCount(additionalBounceCount){
|
||||
this->z=z;
|
||||
this->risingTime=this->originalRisingTime=totalFallTime*0.25f/(additionalBounceCount+1);
|
||||
|
||||
@ -42,7 +42,7 @@ All rights reserved.
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
PurpleEnergyBall::PurpleEnergyBall(vf2d pos,float radius,float homingRadius,int damage,bool upperLevel,vf2d speed,float lifetime,bool friendly,Pixel col,vf2d scale)
|
||||
PurpleEnergyBall::PurpleEnergyBall(vf2d pos,float radius,float homingRadius,int damage,bool upperLevel,vf2d speed,float lifetime,FriendlyType friendly,Pixel col,vf2d scale)
|
||||
:initialScale(scale),homingRadius(homingRadius),bounceCount(game->GetPlayer()->HasEnchant("Bouncing Orb")?"Bouncing Orb"_ENC["BOUNCE COUNT"]:1),Bullet(pos,speed,radius,damage,"mark_trail.png",upperLevel,true,INFINITE,false,friendly,col,scale/2.f,0.f){}
|
||||
|
||||
void PurpleEnergyBall::Update(float fElapsedTime){
|
||||
|
||||
@ -72,7 +72,7 @@ bool Ranger::AutoAttack(){
|
||||
vf2d extendedLine=pointTowardsCursor.upoint(1.1f);
|
||||
float angleToCursor=atan2(extendedLine.y-GetPos().y,extendedLine.x-GetPos().x);
|
||||
attack_cooldown_timer=ARROW_ATTACK_COOLDOWN-GetAttackRecoveryRateReduction();
|
||||
Arrow&arrow{CreateBullet(Arrow)(GetPos(),extendedLine,vf2d{cos(angleToCursor)*"Ranger.Auto Attack.ArrowSpd"_F,float(sin(angleToCursor)*"Ranger.Auto Attack.ArrowSpd"_F-PI/8*"Ranger.Auto Attack.ArrowSpd"_F)}+movementVelocity/1.5f,"Ranger.Auto Attack.Radius"_F,int(GetAttack()*"Ranger.Auto Attack.DamageMult"_F),OnUpperLevel(),true)EndBullet};
|
||||
Arrow&arrow{CreateBullet(Arrow)(GetPos(),extendedLine,vf2d{cos(angleToCursor)*"Ranger.Auto Attack.ArrowSpd"_F,float(sin(angleToCursor)*"Ranger.Auto Attack.ArrowSpd"_F-PI/8*"Ranger.Auto Attack.ArrowSpd"_F)}+movementVelocity/1.5f,"Ranger.Auto Attack.Radius"_F,int(GetAttack()*"Ranger.Auto Attack.DamageMult"_F),OnUpperLevel(),FRIENDLY)EndBullet};
|
||||
if(PoisonArrowAutoAttackReady()){
|
||||
arrow.poisonArrow=true;
|
||||
poisonArrowReadyTimer="Poisonous Arrow"_ENC["POISON ARROW RESET FREQUENCY"];
|
||||
@ -134,7 +134,7 @@ void Ranger::InitializeClassAbilities(){
|
||||
float damageMult{"Ranger.Ability 2.DamageMult"_F};
|
||||
if(p->HasEnchant("Mega Charged Shot"))damageMult*="Mega Charged Shot"_ENC["DAMAGE INCREASE MULT"];
|
||||
|
||||
BULLET_LIST.push_back(std::make_unique<ChargedArrow>(p->GetPos(),arrowVelocity*"Ranger.Ability 2.Speed"_F,beamRadius,p->GetAttack()*damageMult,p->OnUpperLevel(),true));
|
||||
BULLET_LIST.push_back(std::make_unique<ChargedArrow>(p->GetPos(),arrowVelocity*"Ranger.Ability 2.Speed"_F,beamRadius,p->GetAttack()*damageMult,p->OnUpperLevel(),FRIENDLY));
|
||||
p->SetState(State::SHOOT_ARROW);
|
||||
p->rangerShootAnimationTimer=0.3f;
|
||||
p->SetAnimationBasedOnTargetingDirection("SHOOT",atan2(arrowVelocity.y,arrowVelocity.x));
|
||||
@ -170,7 +170,7 @@ void Ranger::InitializeClassAbilities(){
|
||||
vf2d extendedLine=pointTowardsCursor.upoint(1.1f);
|
||||
int finalArrowDamage{perArrowDamage};
|
||||
if(i==algorithmArrowCount-1)finalArrowDamage+=leftoverArrowDamage;
|
||||
BULLET_LIST.emplace_back(std::make_unique<Arrow>(Arrow(p->GetPos(),extendedLine,vf2d{cos(newAngle)*"Ranger.Ability 3.ArrowSpd"_F,float(sin(newAngle)*"Ranger.Ability 3.ArrowSpd"_F-PI/8*"Ranger.Ability 3.ArrowSpd"_F)}+p->movementVelocity,12*"Ranger.Ability 3.ArrowRadius"_F/100,finalArrowDamage,p->OnUpperLevel(),true)));
|
||||
BULLET_LIST.emplace_back(std::make_unique<Arrow>(Arrow(p->GetPos(),extendedLine,vf2d{cos(newAngle)*"Ranger.Ability 3.ArrowSpd"_F,float(sin(newAngle)*"Ranger.Ability 3.ArrowSpd"_F-PI/8*"Ranger.Ability 3.ArrowSpd"_F)}+p->movementVelocity,12*"Ranger.Ability 3.ArrowRadius"_F/100,finalArrowDamage,p->OnUpperLevel(),FRIENDLY)));
|
||||
totalDamageCalculated+=finalArrowDamage;
|
||||
}
|
||||
if(totalDamageCalculated!=intendedTotalDamage)ERR(std::format("WARNING! Multi-shot expected a total damage calculation of {} but added up to {} instead!",intendedTotalDamage,totalDamageCalculated));
|
||||
|
||||
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#include "BulletTypes.h"
|
||||
|
||||
|
||||
RotateBullet::RotateBullet(vf2d pos,float startingAng,float startSpeed,float acc,float headingAngleChange,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
|
||||
RotateBullet::RotateBullet(vf2d pos,float startingAng,float startSpeed,float acc,float headingAngleChange,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col)
|
||||
:Bullet(pos,vf2d{startSpeed,startingAng}.cart(),radius,damage,"burstrotatebullet.png",upperLevel,false,INFINITE,true,friendly,col),headingAngleChange(headingAngleChange){
|
||||
this->acc=acc;
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ void Monster::STRATEGY::SANDWORM(Monster&m,float fElapsedTime,std::string strate
|
||||
const auto ShootBullet=[&](){
|
||||
m.B(A::BULLET_HAS_BEEN_SHOT)=true;
|
||||
m.I(A::ATTACK_COUNT)--;
|
||||
CreateBullet(Bullet)(m.GetPos(),vf2d{ConfigPixels("Bullet Speed"),util::angleTo(m.GetPos(),game->GetPlayer()->GetPos())}.cart(),ConfigFloat("Bullet Radius"),m.GetAttack(),m.OnUpperLevel(),false,ConfigPixel("Bullet Color"),ConfigFloat("Bullet Radius")*vf2d{1.f,1.f}/2.f)EndBullet;
|
||||
CreateBullet(Bullet)(m.GetPos(),vf2d{ConfigPixels("Bullet Speed"),util::angleTo(m.GetPos(),game->GetPlayer()->GetPos())}.cart(),ConfigFloat("Bullet Radius"),m.GetAttack(),m.OnUpperLevel(),NON_FRIENDLY,ConfigPixel("Bullet Color"),ConfigFloat("Bullet Radius")*vf2d{1.f,1.f}/2.f)EndBullet;
|
||||
};
|
||||
|
||||
m.F(A::CASTING_TIMER)-=fElapsedTime;
|
||||
|
||||
@ -54,7 +54,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,std::string stra
|
||||
m.queueShotTimer=0;
|
||||
{
|
||||
SoundEffect::PlaySFX("Slime Shoot",m.pos + vf2d{ 0,-4 });
|
||||
BULLET_LIST.push_back(std::make_unique<Bullet>(Bullet(m.pos + vf2d{ 0,-4 }, geom2d::line(m.pos + vf2d{ 0,-4 }, game->GetPlayer()->GetPos()).vector().norm() * 24.f * float(ConfigInt("BulletSpeed"))/100.f, 12.f*ConfigInt("BulletSize")/100.f, m.GetAttack(),m.upperLevel,false, { uint8_t(ConfigIntArr("BulletColor",0)),uint8_t(ConfigIntArr("BulletColor",1)),uint8_t(ConfigIntArr("BulletColor",2)),uint8_t(ConfigIntArr("BulletColor",3) )},{ConfigInt("BulletSize")/100.f*8,ConfigInt("BulletSize")/100.f*8})));
|
||||
BULLET_LIST.push_back(std::make_unique<Bullet>(Bullet(m.pos + vf2d{ 0,-4 }, geom2d::line(m.pos + vf2d{ 0,-4 }, game->GetPlayer()->GetPos()).vector().norm() * 24.f * float(ConfigInt("BulletSpeed"))/100.f, 12.f*ConfigInt("BulletSize")/100.f, m.GetAttack(),m.upperLevel,NON_FRIENDLY, { uint8_t(ConfigIntArr("BulletColor",0)),uint8_t(ConfigIntArr("BulletColor",1)),uint8_t(ConfigIntArr("BulletColor",2)),uint8_t(ConfigIntArr("BulletColor",3) )},{ConfigInt("BulletSize")/100.f*8,ConfigInt("BulletSize")/100.f*8})));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
|
||||
int bulletCount=ConfigInt("Phase1.RingBulletCount");
|
||||
for(int i=0;i<bulletCount;i++){
|
||||
float angle=((2*PI)/bulletCount)*i+angleOffset;
|
||||
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),false,YELLOW,vf2d{6,6}));
|
||||
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),NON_FRIENDLY,YELLOW,vf2d{6,6}));
|
||||
}
|
||||
SoundEffect::PlaySFX("Slime King Shoot",m.GetPos());
|
||||
};
|
||||
@ -302,7 +302,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
|
||||
for(int i=0;i<bulletCount;i++){
|
||||
float initialAngle=util::angleTo(m.GetPos(),game->GetPlayer()->GetPos());
|
||||
float angle=(i-(bulletCount/2))*util::degToRad(ConfigFloat("Phase2.ShootAngleSpread"))+initialAngle;
|
||||
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),false,YELLOW,vf2d{6,6}));
|
||||
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),NON_FRIENDLY,YELLOW,vf2d{6,6}));
|
||||
}
|
||||
SoundEffect::PlaySFX("Slime King Shoot",m.GetPos());
|
||||
}
|
||||
@ -332,7 +332,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
|
||||
for(int i=0;i<bulletCount;i++){
|
||||
float initialAngle=util::angleTo(m.GetPos(),game->GetPlayer()->GetPos());
|
||||
float angle=(i-(bulletCount/2))*util::degToRad(ConfigFloat("Phase3.ShootAngleSpread"))+initialAngle;
|
||||
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),false,YELLOW,vf2d{6,6}));
|
||||
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),NON_FRIENDLY,YELLOW,vf2d{6,6}));
|
||||
}
|
||||
SoundEffect::PlaySFX("Slime King Shoot",m.GetPos());
|
||||
}else
|
||||
@ -364,7 +364,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
|
||||
float bulletAngle=util::angleTo(m.GetPos(),game->GetPlayer()->GetPos());
|
||||
float spreadAngle=util::degToRad(ConfigFloat("Phase4.RandomOffsetAngle"));
|
||||
bulletAngle+=util::random(spreadAngle*2)-spreadAngle;
|
||||
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(bulletAngle),sin(bulletAngle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),false,YELLOW,vf2d{6,6}));
|
||||
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(bulletAngle),sin(bulletAngle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),NON_FRIENDLY,YELLOW,vf2d{6,6}));
|
||||
SoundEffect::PlaySFX("Slime King Shoot",m.GetPos());
|
||||
}else
|
||||
if(m.I(A::PATTERN_REPEAT_COUNT)==5){
|
||||
|
||||
@ -231,7 +231,7 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str
|
||||
|
||||
m.SIZET(A::LOOPING_SOUND_ID)=SoundEffect::PlayLoopingSFX("Rock Toss Cast",m.GetPos());
|
||||
|
||||
CreateBullet(LargeStone)(m.GetPos()+vf2d{0,ConfigFloat("Standard Attack.Stone Throw Height Offset")/2.f},ConfigFloat("Standard Attack.Stone Throw Time"),m.V(A::LOCKON_POS),m.F(A::CASTING_TIMER),ConfigPixels("Standard Attack.Stone Radius"),ConfigFloat("Standard Attack.Stone Throw Height Offset"),acc,ConfigInt("Standard Attack.Stone Damage"),ConfigFloat("Standard Attack.Stone Throw Knockback Factor"),m.OnUpperLevel(),false,INFINITY,false,WHITE,vf2d{1,1}*m.GetSizeMult(),util::random(2*PI))EndBullet;
|
||||
CreateBullet(LargeStone)(m.GetPos()+vf2d{0,ConfigFloat("Standard Attack.Stone Throw Height Offset")/2.f},ConfigFloat("Standard Attack.Stone Throw Time"),m.V(A::LOCKON_POS),m.F(A::CASTING_TIMER),ConfigPixels("Standard Attack.Stone Radius"),ConfigFloat("Standard Attack.Stone Throw Height Offset"),acc,ConfigInt("Standard Attack.Stone Damage"),ConfigFloat("Standard Attack.Stone Throw Knockback Factor"),m.OnUpperLevel(),false,INFINITY,NON_FRIENDLY,WHITE,vf2d{1,1}*m.GetSizeMult(),util::random(2*PI))EndBullet;
|
||||
}else{
|
||||
SETPHASE(BEAR_ATTACK);
|
||||
m.F(A::CHASE_TIMER)=0.f;
|
||||
@ -330,7 +330,7 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str
|
||||
m.PerformAnimation("CAST");
|
||||
|
||||
for(int i:std::ranges::iota_view(0,ConfigInt("Stone Rain.Stone Count"))){
|
||||
CreateBullet(FallingBullet)("rock.png",game->camera.GetViewPosition()+vf2d{util::random(game->ScreenWidth()),util::random(game->ScreenHeight())},ConfigVec("Stone Rain.Stone Vel"),ConfigFloatArr("Stone Rain.Stone Vel",2),ConfigFloat("Stone Rain.Indicator Time"),ConfigPixels("Stone Rain.Stone Radius"),ConfigInt("Stone Rain.Stone Damage"),m.OnUpperLevel(),false,ConfigFloat("Stone Rain.Stone Knockback Amt"),util::random_range(ConfigFloatArr("Stone Rain.Stone Fall Delay",0),ConfigFloatArr("Stone Rain.Stone Fall Delay",1)),false,ConfigPixel("Stone Rain.Stone Spell Circle Color"),vf2d{ConfigFloat("Stone Rain.Stone Radius")/100.f*2.f,ConfigFloat("Stone Rain.Stone Radius")/100.f*2.f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Stone Rain.Stone Spell Circle Rotation Spd")),ConfigPixel("Stone Rain.Stone Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Stone Rain.Stone Spell Insignia Rotation Spd")))EndBullet;
|
||||
CreateBullet(FallingBullet)("rock.png",game->camera.GetViewPosition()+vf2d{util::random(game->ScreenWidth()),util::random(game->ScreenHeight())},ConfigVec("Stone Rain.Stone Vel"),ConfigFloatArr("Stone Rain.Stone Vel",2),ConfigFloat("Stone Rain.Indicator Time"),ConfigPixels("Stone Rain.Stone Radius"),ConfigInt("Stone Rain.Stone Damage"),m.OnUpperLevel(),false,ConfigFloat("Stone Rain.Stone Knockback Amt"),util::random_range(ConfigFloatArr("Stone Rain.Stone Fall Delay",0),ConfigFloatArr("Stone Rain.Stone Fall Delay",1)),NON_FRIENDLY,ConfigPixel("Stone Rain.Stone Spell Circle Color"),vf2d{ConfigFloat("Stone Rain.Stone Radius")/100.f*2.f,ConfigFloat("Stone Rain.Stone Radius")/100.f*2.f},util::random(2*PI),util::random(2*PI),util::degToRad(ConfigFloat("Stone Rain.Stone Spell Circle Rotation Spd")),ConfigPixel("Stone Rain.Stone Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Stone Rain.Stone Spell Insignia Rotation Spd")))EndBullet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,12 +106,12 @@ void Monster::STRATEGY::STONE_ELEMENTAL(Monster&m,float fElapsedTime,std::string
|
||||
SETPHASE(SHOOT_STONE_CAST);
|
||||
m.B(A::PLAYED_FLAG)=false;
|
||||
m.F(A::CASTING_TIMER)=ConfigFloat("Rock Toss Track Time")+ConfigFloat("Rock Toss Wait Time");
|
||||
CreateBullet(LevitatingRock)(m,game->GetPlayer()->GetPos(),1.f,0.f,ConfigPixels("Rock Toss Max Spawn Distance"),ConfigFloat("Rock Toss Track Time"),ConfigFloat("Rock Toss Wait Time"),ConfigFloat("Rock Toss Bullet Speed"),ConfigFloat("Rock Radius"),std::max(1,ConfigInt("Rock Toss Damage")/5),m.OnUpperLevel(),false,WHITE,vf2d{1,1})EndBullet;
|
||||
CreateBullet(LevitatingRock)(m,game->GetPlayer()->GetPos(),1.f,0.f,ConfigPixels("Rock Toss Max Spawn Distance"),ConfigFloat("Rock Toss Track Time"),ConfigFloat("Rock Toss Wait Time"),ConfigFloat("Rock Toss Bullet Speed"),ConfigFloat("Rock Radius"),std::max(1,ConfigInt("Rock Toss Damage")/5),m.OnUpperLevel(),NON_FRIENDLY,WHITE,vf2d{1,1})EndBullet;
|
||||
const int masterRockInd=BULLET_LIST.size()-1;
|
||||
CreateBullet(LevitatingRock)(m,game->GetPlayer()->GetPos(),1.f,util::degToRad(-20.f),ConfigPixels("Rock Toss Max Spawn Distance")*0.75f,ConfigFloat("Rock Toss Track Time"),ConfigFloat("Rock Toss Wait Time"),ConfigFloat("Rock Toss Bullet Speed"),ConfigFloat("Rock Radius")*0.6f,std::max(1,ConfigInt("Rock Toss Damage")/5),m.OnUpperLevel(),false,WHITE,vf2d{0.6f,0.6f})EndBullet;
|
||||
CreateBullet(LevitatingRock)(m,game->GetPlayer()->GetPos(),1.f,util::degToRad(-40.f),ConfigPixels("Rock Toss Max Spawn Distance")*0.5f,ConfigFloat("Rock Toss Track Time"),ConfigFloat("Rock Toss Wait Time"),ConfigFloat("Rock Toss Bullet Speed"),ConfigFloat("Rock Radius")*0.6f,std::max(1,ConfigInt("Rock Toss Damage")/5),m.OnUpperLevel(),false,WHITE,vf2d{0.6f,0.6f})EndBullet;
|
||||
CreateBullet(LevitatingRock)(m,game->GetPlayer()->GetPos(),1.f,util::degToRad(20.f),ConfigPixels("Rock Toss Max Spawn Distance")*0.75f,ConfigFloat("Rock Toss Track Time"),ConfigFloat("Rock Toss Wait Time"),ConfigFloat("Rock Toss Bullet Speed"),ConfigFloat("Rock Radius")*0.6f,std::max(1,ConfigInt("Rock Toss Damage")/5),m.OnUpperLevel(),false,WHITE,vf2d{0.6f,0.6f})EndBullet;
|
||||
CreateBullet(LevitatingRock)(m,game->GetPlayer()->GetPos(),1.f,util::degToRad(40.f),ConfigPixels("Rock Toss Max Spawn Distance")*0.5f,ConfigFloat("Rock Toss Track Time"),ConfigFloat("Rock Toss Wait Time"),ConfigFloat("Rock Toss Bullet Speed"),ConfigFloat("Rock Radius")*0.6f,std::max(1,ConfigInt("Rock Toss Damage")/5),m.OnUpperLevel(),false,WHITE,vf2d{0.6f,0.6f})EndBullet;
|
||||
CreateBullet(LevitatingRock)(m,game->GetPlayer()->GetPos(),1.f,util::degToRad(-20.f),ConfigPixels("Rock Toss Max Spawn Distance")*0.75f,ConfigFloat("Rock Toss Track Time"),ConfigFloat("Rock Toss Wait Time"),ConfigFloat("Rock Toss Bullet Speed"),ConfigFloat("Rock Radius")*0.6f,std::max(1,ConfigInt("Rock Toss Damage")/5),m.OnUpperLevel(),NON_FRIENDLY,WHITE,vf2d{0.6f,0.6f})EndBullet;
|
||||
CreateBullet(LevitatingRock)(m,game->GetPlayer()->GetPos(),1.f,util::degToRad(-40.f),ConfigPixels("Rock Toss Max Spawn Distance")*0.5f,ConfigFloat("Rock Toss Track Time"),ConfigFloat("Rock Toss Wait Time"),ConfigFloat("Rock Toss Bullet Speed"),ConfigFloat("Rock Radius")*0.6f,std::max(1,ConfigInt("Rock Toss Damage")/5),m.OnUpperLevel(),NON_FRIENDLY,WHITE,vf2d{0.6f,0.6f})EndBullet;
|
||||
CreateBullet(LevitatingRock)(m,game->GetPlayer()->GetPos(),1.f,util::degToRad(20.f),ConfigPixels("Rock Toss Max Spawn Distance")*0.75f,ConfigFloat("Rock Toss Track Time"),ConfigFloat("Rock Toss Wait Time"),ConfigFloat("Rock Toss Bullet Speed"),ConfigFloat("Rock Radius")*0.6f,std::max(1,ConfigInt("Rock Toss Damage")/5),m.OnUpperLevel(),NON_FRIENDLY,WHITE,vf2d{0.6f,0.6f})EndBullet;
|
||||
CreateBullet(LevitatingRock)(m,game->GetPlayer()->GetPos(),1.f,util::degToRad(40.f),ConfigPixels("Rock Toss Max Spawn Distance")*0.5f,ConfigFloat("Rock Toss Track Time"),ConfigFloat("Rock Toss Wait Time"),ConfigFloat("Rock Toss Bullet Speed"),ConfigFloat("Rock Radius")*0.6f,std::max(1,ConfigInt("Rock Toss Damage")/5),m.OnUpperLevel(),NON_FRIENDLY,WHITE,vf2d{0.6f,0.6f})EndBullet;
|
||||
auto bulletListEndIter{BULLET_LIST.end()};
|
||||
for(int i=0;i<4;i++){ //This is going to assign the last four stones we created as slaves to the first rock so that their directions can all be changed together.
|
||||
bulletListEndIter--;
|
||||
@ -205,7 +205,7 @@ void Monster::STRATEGY::STONE_ELEMENTAL(Monster&m,float fElapsedTime,std::string
|
||||
const float bulletAngRandomOffset{util::random(PI/2)};
|
||||
for(int i=0;i<ConfigInt("Burrow Ring Bullet Count");i++){
|
||||
const float bulletAngle=((2*PI)/ConfigInt("Burrow Ring Bullet Count"))*i+bulletAngRandomOffset;
|
||||
CreateBullet(Bullet)(m.GetPos()+vf2d{0,4*m.GetSizeMult()},vf2d{ConfigFloat("Burrow Ring Bullet Speed"),bulletAngle}.cart(),ConfigFloat("Burrow Ring Bullet Size"),ConfigInt("Burrow Ring Bullet Damage"),m.OnUpperLevel(),false,ConfigPixel("Burrow Ring Bullet Color"),vf2d{ConfigFloat("Burrow Ring Bullet Size")/3,ConfigFloat("Burrow Ring Bullet Size")/3})EndBullet;
|
||||
CreateBullet(Bullet)(m.GetPos()+vf2d{0,4*m.GetSizeMult()},vf2d{ConfigFloat("Burrow Ring Bullet Speed"),bulletAngle}.cart(),ConfigFloat("Burrow Ring Bullet Size"),ConfigInt("Burrow Ring Bullet Damage"),m.OnUpperLevel(),NON_FRIENDLY,ConfigPixel("Burrow Ring Bullet Color"),vf2d{ConfigFloat("Burrow Ring Bullet Size")/3,ConfigFloat("Burrow Ring Bullet Size")/3})EndBullet;
|
||||
BULLET_LIST.back()->SetIframeTimeOnHit(0.15f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ All rights reserved.
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
ThrownProjectile::ThrownProjectile(vf2d pos,vf2d targetPos,const std::string&img,float explodeRadius,float z,float totalFallTime,float totalRiseZAmt,int damage,bool upperLevel,bool hitsMultiple,float lifetime,bool friendly,Pixel col,vf2d scale,float image_angle,const std::optional<Effect>explodeEffect,const std::optional<std::string>explodeSoundEffect,const std::optional<LingeringEffect>lingeringEffect)
|
||||
ThrownProjectile::ThrownProjectile(vf2d pos,vf2d targetPos,const std::string&img,float explodeRadius,float z,float totalFallTime,float totalRiseZAmt,int damage,bool upperLevel,bool hitsMultiple,float lifetime,FriendlyType friendly,Pixel col,vf2d scale,float image_angle,const std::optional<Effect>explodeEffect,const std::optional<std::string>explodeSoundEffect,const std::optional<LingeringEffect>lingeringEffect)
|
||||
:Bullet(pos,util::pointTo(pos,targetPos)*util::distance(pos,targetPos)/totalFallTime,0.f,damage,img,upperLevel,hitsMultiple,lifetime,false,friendly,col,scale,image_angle),initialZ(z),explodeRadius(explodeRadius),totalRiseZAmt(totalRiseZAmt),totalFallTime(totalFallTime),startingPos(pos),targetPos(targetPos),originalRisingTime(totalFallTime*0.25f),risingTime(originalRisingTime),originalFallingTime(totalFallTime*0.75f),fallingTime(originalFallingTime),explodeEffect(explodeEffect),img(img),explodeSoundEffect(explodeSoundEffect),lingeringEffect(lingeringEffect){
|
||||
this->z=z;
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ All rights reserved.
|
||||
#include "Player.h"
|
||||
#include "util.h"
|
||||
|
||||
Tornado::Tornado(vf2d centerPoint,float distance,float initialRot,float rotSpd,int damage,const float knockupDuration,const float knockbackAmt,const float lifetime,bool upperLevel,bool friendly,Pixel col,const vf2d scale)
|
||||
Tornado::Tornado(vf2d centerPoint,float distance,float initialRot,float rotSpd,int damage,const float knockupDuration,const float knockbackAmt,const float lifetime,bool upperLevel,FriendlyType friendly,Pixel col,const vf2d scale)
|
||||
:polarAngle({distance,initialRot}),rot(initialRot),rotatingSpd(rotSpd),knockupDuration(knockupDuration),knockbackAmt(knockbackAmt),centerPoint(centerPoint),Bullet(centerPoint+polarAngle.cart(),vf2d{},6.f,damage,"tornado2.png",upperLevel,true,lifetime+0.5f,false,friendly,col,scale){}
|
||||
|
||||
void Tornado::Update(float fElapsedTime){
|
||||
|
||||
@ -74,7 +74,7 @@ bool Trapper::AutoAttack(){
|
||||
vf2d extendedLine=pointTowardsCursor.upoint(1.1f);
|
||||
float angleToCursor=atan2(extendedLine.y-GetPos().y,extendedLine.x-GetPos().x);
|
||||
attack_cooldown_timer=ARROW_ATTACK_COOLDOWN-GetAttackRecoveryRateReduction();
|
||||
CreateBullet(Arrow)(GetPos(),extendedLine,vf2d{cos(angleToCursor)*"Ranger.Auto Attack.ArrowSpd"_F,float(sin(angleToCursor)*"Ranger.Auto Attack.ArrowSpd"_F-PI/8*"Ranger.Auto Attack.ArrowSpd"_F)}+movementVelocity/1.5f,"Ranger.Auto Attack.Radius"_F,int(GetAttack()*"Ranger.Auto Attack.DamageMult"_F),OnUpperLevel(),true)EndBullet;
|
||||
CreateBullet(Arrow)(GetPos(),extendedLine,vf2d{cos(angleToCursor)*"Ranger.Auto Attack.ArrowSpd"_F,float(sin(angleToCursor)*"Ranger.Auto Attack.ArrowSpd"_F-PI/8*"Ranger.Auto Attack.ArrowSpd"_F)}+movementVelocity/1.5f,"Ranger.Auto Attack.Radius"_F,int(GetAttack()*"Ranger.Auto Attack.DamageMult"_F),OnUpperLevel(),FRIENDLY)EndBullet;
|
||||
BULLET_LIST.back()->SetIsPlayerAutoAttackProjectile();
|
||||
SetState(State::SHOOT_ARROW);
|
||||
SetAnimationBasedOnTargetingDirection("SHOOT",angleToCursor);
|
||||
@ -117,7 +117,7 @@ void Trapper::InitializeClassAbilities(){
|
||||
#pragma region Trapper Ability 2 (Bear Trap)
|
||||
Trapper::ability2.action=
|
||||
[](Player*p,vf2d pos={}){
|
||||
CreateBullet(BearTrap)(p->GetPos(),"Trapper.Ability 2.Trap Radius"_I,"Trapper.Ability 2.DamageMult"_F*p->GetAttack(),0.2f,0.5f,p->OnUpperLevel(),false,INFINITE,true,WHITE,{1.f,1.f})EndBullet;
|
||||
CreateBullet(BearTrap)(p->GetPos(),"Trapper.Ability 2.Trap Radius"_I,"Trapper.Ability 2.DamageMult"_F*p->GetAttack(),0.2f,0.5f,p->OnUpperLevel(),false,INFINITE,FRIENDLY,WHITE,{1.f,1.f})EndBullet;
|
||||
SoundEffect::PlaySFX("Place Down Trap",p->GetPos());
|
||||
p->SetAnimationBasedOnTargetingDirection("SETTRAP",p->GetFacingDirection());
|
||||
return true;
|
||||
@ -128,7 +128,7 @@ void Trapper::InitializeClassAbilities(){
|
||||
[](Player*p,vf2d pos={}){
|
||||
float trapDamage{"Trapper.Ability 3.DamageMult"_F*p->GetAttack()};
|
||||
if(p->HasEnchant("Concussive Trap"))trapDamage+=p->GetAttack()*"Concussive Trap"_ENC["ADDITIONAL EXPLOSION DAMAGE"]/100.f;
|
||||
CreateBullet(ExplosiveTrap)(p->GetPos(),"Trapper.Ability 3.Trap Radius"_I,"Trapper.Ability 3.Explosion Radius"_F/100.f*24,"Trapper.Ability 3.Trap Auto Detonate Time"_F,trapDamage,0.2f,0.5f,"Trapper.Ability 3.Trap Activation Time"_F,p->OnUpperLevel(),false,INFINITE,true,WHITE,{1.f,1.f})EndBullet;
|
||||
CreateBullet(ExplosiveTrap)(p->GetPos(),"Trapper.Ability 3.Trap Radius"_I,"Trapper.Ability 3.Explosion Radius"_F/100.f*24,"Trapper.Ability 3.Trap Auto Detonate Time"_F,trapDamage,0.2f,0.5f,"Trapper.Ability 3.Trap Activation Time"_F,p->OnUpperLevel(),false,INFINITE,FRIENDLY,WHITE,{1.f,1.f})EndBullet;
|
||||
SoundEffect::PlaySFX("Place Down Trap",p->GetPos());
|
||||
p->SetAnimationBasedOnTargetingDirection("SETTRAP",p->GetFacingDirection());
|
||||
return true;
|
||||
|
||||
@ -60,7 +60,7 @@ void Monster::STRATEGY::TURRET(Monster&m,float fElapsedTime,std::string strategy
|
||||
m.queueShotTimer-=fElapsedTime;
|
||||
if(m.queueShotTimer<0){
|
||||
m.queueShotTimer=0;
|
||||
BULLET_LIST.push_back(std::make_unique<Bullet>(Bullet(m.pos + vf2d{ 0,-4 }, geom2d::line(m.pos + vf2d{ 0,-4 }, game->GetPlayer()->GetPos()).vector().norm() * 24.f * float(ConfigInt("BulletSpeed"))/100.f, 12.f*ConfigInt("BulletSize")/100.f, m.GetAttack(),m.upperLevel,false, { uint8_t(ConfigIntArr("BulletColor",0)),uint8_t(ConfigIntArr("BulletColor",1)),uint8_t(ConfigIntArr("BulletColor",2)),uint8_t(ConfigIntArr("BulletColor",3) )},{ConfigInt("BulletSize")/100.f*8,ConfigInt("BulletSize")/100.f*8})));
|
||||
BULLET_LIST.push_back(std::make_unique<Bullet>(Bullet(m.pos + vf2d{ 0,-4 }, geom2d::line(m.pos + vf2d{ 0,-4 }, game->GetPlayer()->GetPos()).vector().norm() * 24.f * float(ConfigInt("BulletSpeed"))/100.f, 12.f*ConfigInt("BulletSize")/100.f, m.GetAttack(),m.upperLevel,NON_FRIENDLY, { uint8_t(ConfigIntArr("BulletColor",0)),uint8_t(ConfigIntArr("BulletColor",1)),uint8_t(ConfigIntArr("BulletColor",2)),uint8_t(ConfigIntArr("BulletColor",3) )},{ConfigInt("BulletSize")/100.f*8,ConfigInt("BulletSize")/100.f*8})));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -210,7 +210,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy
|
||||
std::string_view row=ConfigString(std::format("Wisp Pattern {}.Row[{}]",wispPattern,y));
|
||||
if(row[int(x/wispSize.x)%row.length()]!='.'){
|
||||
float ySpawn=ConfigInt("Phase 2.Wisp Pattern Spawn Y")+y*wispSize.y;
|
||||
BULLET_LIST.push_back(std::make_unique<Wisp>(vf2d{x,ySpawn},vf2d{0,ConfigFloat("Phase 2.Wisp Speed")},ConfigFloat("Phase 2.Wisp Hitbox Radius"),m.GetAttack(),m.OnUpperLevel(),false,ConfigPixel("Phase 2.Wisp Color")));
|
||||
BULLET_LIST.push_back(std::make_unique<Wisp>(vf2d{x,ySpawn},vf2d{0,ConfigFloat("Phase 2.Wisp Speed")},ConfigFloat("Phase 2.Wisp Hitbox Radius"),m.GetAttack(),m.OnUpperLevel(),NON_FRIENDLY,ConfigPixel("Phase 2.Wisp Color")));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -415,7 +415,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy
|
||||
std::string_view row=ConfigString(std::format("Wisp Pattern {}.Row[{}]",wispPattern,y));
|
||||
if(row[int(x/wispSize.x)%row.length()]!='.'){
|
||||
float ySpawn=ConfigInt("Phase 4.Wisp Pattern Spawn Y")+y*wispSize.y;
|
||||
BULLET_LIST.push_back(std::make_unique<Wisp>(vf2d{x,ySpawn},vf2d{0,ConfigFloat("Phase 4.Wisp Speed")},ConfigFloat("Phase 4.Wisp Hitbox Radius"),m.GetAttack(),m.OnUpperLevel(),false,ConfigPixel("Phase 4.Wisp Color")));
|
||||
BULLET_LIST.push_back(std::make_unique<Wisp>(vf2d{x,ySpawn},vf2d{0,ConfigFloat("Phase 4.Wisp Speed")},ConfigFloat("Phase 4.Wisp Hitbox Radius"),m.GetAttack(),m.OnUpperLevel(),NON_FRIENDLY,ConfigPixel("Phase 4.Wisp Color")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_PATCH 0
|
||||
#define VERSION_BUILD 12426
|
||||
#define VERSION_BUILD 12458
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
||||
@ -175,7 +175,7 @@ void Warrior::InitializeClassAbilities(){
|
||||
}
|
||||
int sonicSlashDamage{int(p->GetAttack()*"Warrior.Ability 3.DamageMult"_F)};
|
||||
if(p->HasEnchant("Sonic Upgrade"))sonicSlashDamage+=p->GetMaxHealth()*"Sonic Upgrade"_ENC["ADDITIONAL DMG PCT"]/100.f;
|
||||
BULLET_LIST.emplace_back(std::make_unique<Bullet>(p->GetPos(),bulletVel,"Warrior.Ability 3.Radius"_F,sonicSlashDamage,"sonicslash.png",p->upperLevel,true,"Warrior.Ability 3.Lifetime"_F,true,true,WHITE,vf2d{"Warrior.Ability 3.Radius"_F/30,"Warrior.Ability 3.Radius"_F/30}));
|
||||
BULLET_LIST.emplace_back(std::make_unique<Bullet>(p->GetPos(),bulletVel,"Warrior.Ability 3.Radius"_F,sonicSlashDamage,"sonicslash.png",p->upperLevel,true,"Warrior.Ability 3.Lifetime"_F,true,FRIENDLY,WHITE,vf2d{"Warrior.Ability 3.Radius"_F/30,"Warrior.Ability 3.Radius"_F/30}));
|
||||
game->SetupWorldShake("Warrior.Ability 3.ShakeTime"_F);
|
||||
if(p->HasEnchant("Sword Enchantment"))p->AddBuff(BuffType::SWORD_ENCHANTMENT,"Sword Enchantment"_ENC["INCREASE DURATION"],1);
|
||||
SoundEffect::PlaySFX("Warrior Sonic Slash",SoundEffect::CENTERED);
|
||||
|
||||
@ -43,7 +43,7 @@ All rights reserved.
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
Wisp::Wisp(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
|
||||
Wisp::Wisp(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,FriendlyType friendly,Pixel col)
|
||||
:Bullet(pos,vel,radius,damage,"wisp.png",upperLevel,false,INFINITE,false,friendly,col){}
|
||||
void Wisp::Update(float fElapsedTime){
|
||||
|
||||
|
||||
@ -108,7 +108,7 @@ bool Witch::AutoAttack(){
|
||||
float angleToCursor=atan2(GetWorldAimingLocation().y-GetPos().y,GetWorldAimingLocation().x-GetPos().x);
|
||||
int damage{int(GetAttack()*"Witch.Auto Attack.DamageMult"_F)};
|
||||
if(HasEnchant("Bouncing Orb"))damage*="Bouncing Orb"_ENC["ORB DAMAGE"]/100.f;
|
||||
CreateBullet(PurpleEnergyBall)(GetPos(),"Witch.Auto Attack.Radius"_F/100*12,"Witch.Auto Attack.Homing Range"_F/100*24,damage,upperLevel,{cos(angleToCursor)*"Witch.Auto Attack.Speed"_F,sin(angleToCursor)*"Witch.Auto Attack.Speed"_F},INFINITE,true)EndBullet;
|
||||
CreateBullet(PurpleEnergyBall)(GetPos(),"Witch.Auto Attack.Radius"_F/100*12,"Witch.Auto Attack.Homing Range"_F/100*24,damage,upperLevel,{cos(angleToCursor)*"Witch.Auto Attack.Speed"_F,sin(angleToCursor)*"Witch.Auto Attack.Speed"_F},INFINITE,FRIENDLY)EndBullet;
|
||||
BULLET_LIST.back()->SetIsPlayerAutoAttackProjectile();
|
||||
SoundEffect::PlaySFX("Witch Attack",SoundEffect::CENTERED);
|
||||
return true;
|
||||
@ -169,7 +169,7 @@ void Witch::InitializeClassAbilities(){
|
||||
int additionalBounceCount{0};
|
||||
if(p->HasEnchant("Poison Bounce"))additionalBounceCount+="Poison Bounce"_ENC["BOUNCE COUNT"];
|
||||
const float totalFallTime{util::lerp(1/30.f*(additionalBounceCount+1),0.3f,util::distance(p->GetPos(),pos)/("Witch.Ability 2.Casting Range"_F/100.f*24))};
|
||||
CreateBullet(PoisonBottle)(p->GetPos(),pos,"poison_bottle.png","Witch.Ability 2.Casting Size"_F/100.f*24,"Poison Bounce"_ENC["BOUNCE EXPLODE RADIUS"]/100.f*24,12.f,totalFallTime,"Witch.Ability 2.Toss Max Z"_F,p->GetAttack()*"Witch.Ability 2.Damage Mult"_F,additionalBounceCount,p->OnUpperLevel(),false,INFINITE,true,WHITE,vf2d{1.f,1.f},util::random(2*PI))EndBullet;
|
||||
CreateBullet(PoisonBottle)(p->GetPos(),pos,"poison_bottle.png","Witch.Ability 2.Casting Size"_F/100.f*24,"Poison Bounce"_ENC["BOUNCE EXPLODE RADIUS"]/100.f*24,12.f,totalFallTime,"Witch.Ability 2.Toss Max Z"_F,p->GetAttack()*"Witch.Ability 2.Damage Mult"_F,additionalBounceCount,p->OnUpperLevel(),false,INFINITE,FRIENDLY,WHITE,vf2d{1.f,1.f},util::random(2*PI))EndBullet;
|
||||
return true;
|
||||
};
|
||||
#pragma endregion
|
||||
|
||||
@ -106,7 +106,7 @@ void Wizard::OnUpdate(float fElapsedTime){
|
||||
bool Wizard::AutoAttack(){
|
||||
attack_cooldown_timer=MAGIC_ATTACK_COOLDOWN-GetAttackRecoveryRateReduction();
|
||||
float angleToCursor=atan2(GetWorldAimingLocation().y-GetPos().y,GetWorldAimingLocation().x-GetPos().x);
|
||||
CreateBullet(EnergyBolt)(GetPos(),{cos(angleToCursor)*"Wizard.Auto Attack.Speed"_F,sin(angleToCursor)*"Wizard.Auto Attack.Speed"_F},"Wizard.Auto Attack.Radius"_F/100*12,int(GetAttack()*"Wizard.Auto Attack.DamageMult"_F),upperLevel,true,WHITE)EndBullet;
|
||||
CreateBullet(EnergyBolt)(GetPos(),{cos(angleToCursor)*"Wizard.Auto Attack.Speed"_F,sin(angleToCursor)*"Wizard.Auto Attack.Speed"_F},"Wizard.Auto Attack.Radius"_F/100*12,int(GetAttack()*"Wizard.Auto Attack.DamageMult"_F),upperLevel,FRIENDLY,WHITE)EndBullet;
|
||||
BULLET_LIST.back()->SetIsPlayerAutoAttackProjectile();
|
||||
SoundEffect::PlaySFX("Wizard Auto Attack",SoundEffect::CENTERED);
|
||||
return true;
|
||||
@ -183,7 +183,7 @@ void Wizard::InitializeClassAbilities(){
|
||||
Wizard::ability1.action=
|
||||
[](Player*p,vf2d pos={}){
|
||||
float angleToCursor=atan2(p->GetWorldAimingLocation().y-p->GetPos().y,p->GetWorldAimingLocation().x-p->GetPos().x);
|
||||
CreateBullet(FireBolt)(p->GetPos(),{cos(angleToCursor)*"Wizard.Ability 1.BulletSpeed"_F,sin(angleToCursor)*"Wizard.Ability 1.BulletSpeed"_F},"Wizard.Ability 1.Radius"_F/100*12,int(p->GetAttack()*"Wizard.Ability 1.InitialDamageMult"_F),p->upperLevel,true,"Wizard.Ability 1.BulletColor"_Pixel)EndBullet;
|
||||
CreateBullet(FireBolt)(p->GetPos(),{cos(angleToCursor)*"Wizard.Ability 1.BulletSpeed"_F,sin(angleToCursor)*"Wizard.Ability 1.BulletSpeed"_F},"Wizard.Ability 1.Radius"_F/100*12,int(p->GetAttack()*"Wizard.Ability 1.InitialDamageMult"_F),p->upperLevel,FRIENDLY,"Wizard.Ability 1.BulletColor"_Pixel)EndBullet;
|
||||
SoundEffect::PlaySFX("Wizard Fire Bolt Shoot",SoundEffect::CENTERED);
|
||||
return true;
|
||||
};
|
||||
@ -192,7 +192,7 @@ void Wizard::InitializeClassAbilities(){
|
||||
Wizard::ability2.action=
|
||||
[](Player*p,vf2d pos={}){
|
||||
float angleToCursor=atan2(p->GetWorldAimingLocation().y-p->GetPos().y,p->GetWorldAimingLocation().x-p->GetPos().x);
|
||||
CreateBullet(LightningBolt)(p->GetPos(),{cos(angleToCursor)*"Wizard.Ability 2.BulletSpeed"_F,sin(angleToCursor)*"Wizard.Ability 2.BulletSpeed"_F},"Wizard.Ability 2.Radius"_F/100*12,int(p->GetAttack()*"Wizard.Ability 2.DamageMult"_F),p->upperLevel,true,"Wizard.Ability 2.BulletColor"_Pixel)EndBullet;
|
||||
CreateBullet(LightningBolt)(p->GetPos(),{cos(angleToCursor)*"Wizard.Ability 2.BulletSpeed"_F,sin(angleToCursor)*"Wizard.Ability 2.BulletSpeed"_F},"Wizard.Ability 2.Radius"_F/100*12,int(p->GetAttack()*"Wizard.Ability 2.DamageMult"_F),p->upperLevel,FRIENDLY,"Wizard.Ability 2.BulletColor"_Pixel)EndBullet;
|
||||
SoundEffect::PlaySFX("Wizard Lightning Bolt Shoot",SoundEffect::CENTERED);
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -184,7 +184,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy)
|
||||
RUN_TOWARDS(m,fElapsedTime,"Run Towards");
|
||||
m.F(A::SHOOT_TIMER)-=fElapsedTime;
|
||||
if(m.F(A::SHOOT_TIMER)<=0.f){
|
||||
CreateBullet(Bullet)(m.GetPos(),vf2d{0.f,ConfigFloat("Fly Across Attack.Attack Y Speed")},4,ConfigInt("Fly Across Attack.Poop Damage"),"birdpoop.png",m.OnUpperLevel(),false,INFINITY,false,false,WHITE,vf2d{1.f,1.25f})EndBullet;
|
||||
CreateBullet(Bullet)(m.GetPos(),vf2d{0.f,ConfigFloat("Fly Across Attack.Attack Y Speed")},4,ConfigInt("Fly Across Attack.Poop Damage"),"birdpoop.png",m.OnUpperLevel(),false,INFINITY,false,NON_FRIENDLY,WHITE,vf2d{1.f,1.25f})EndBullet;
|
||||
BULLET_LIST.back()->SetIframeTimeOnHit(0.25f);
|
||||
const int extraPoopBitsCount=util::random()%6;
|
||||
for(int i=0;i<extraPoopBitsCount;i++){
|
||||
@ -193,7 +193,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy)
|
||||
if(RightDirection)xOffset=1.f;
|
||||
else xOffset=-1.f;
|
||||
xOffset*=9.f;
|
||||
CreateBullet(Bullet)(m.GetPos()+vf2d{xOffset+util::random_range(-3.f,3.f),-util::random(10.f)-4.f},vf2d{0.f,ConfigFloat("Fly Across Attack.Attack Y Speed")},1,ConfigInt("Fly Across Attack.Poop Damage"),"birdpoop.png",m.OnUpperLevel(),false,INFINITY,false,false,WHITE,vf2d{util::random_range(0.2f,0.3f),util::random_range(0.2f,0.3f)},util::random(2*PI))EndBullet;
|
||||
CreateBullet(Bullet)(m.GetPos()+vf2d{xOffset+util::random_range(-3.f,3.f),-util::random(10.f)-4.f},vf2d{0.f,ConfigFloat("Fly Across Attack.Attack Y Speed")},1,ConfigInt("Fly Across Attack.Poop Damage"),"birdpoop.png",m.OnUpperLevel(),false,INFINITY,false,NON_FRIENDLY,WHITE,vf2d{util::random_range(0.2f,0.3f),util::random_range(0.2f,0.3f)},util::random(2*PI))EndBullet;
|
||||
BULLET_LIST.back()->SetIframeTimeOnHit(0.25f);
|
||||
}
|
||||
m.F(A::SHOOT_TIMER)=ConfigFloat("Fly Across Attack.Attack Frequency");
|
||||
@ -227,7 +227,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy)
|
||||
for(int tornadoCounter=0;tornadoCounter<tornadoCount;tornadoCounter++){
|
||||
const float startAngle=randomRotDir+tornadoCounter*((2*PI)/tornadoCount);
|
||||
|
||||
CreateBullet(Tornado)(m.GetPos(),tornadoDistance,startAngle,tornadoRotSpd,m.GetAttack(),ConfigFloat("Tornado Attack.Knockup Duration"),ConfigFloat("Tornado Attack.Knockback Amount"),ConfigFloat("Tornado Attack.Attack Duration"),m.OnUpperLevel(),false,WHITE)EndBullet;
|
||||
CreateBullet(Tornado)(m.GetPos(),tornadoDistance,startAngle,tornadoRotSpd,m.GetAttack(),ConfigFloat("Tornado Attack.Knockup Duration"),ConfigFloat("Tornado Attack.Knockback Amount"),ConfigFloat("Tornado Attack.Attack Duration"),m.OnUpperLevel(),NON_FRIENDLY,WHITE)EndBullet;
|
||||
BULLET_LIST.back()->SetFadeinTime(ConfigFloat("Tornado Attack.Tornado Fade-In Time"));
|
||||
}
|
||||
}
|
||||
@ -323,7 +323,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy)
|
||||
|
||||
const float sizeMultiplier=util::random_range(0.75f,1.25f);
|
||||
|
||||
CreateBullet(Debris)(m.GetPos()+debrisSpawningOffset,debrisSpd,ConfigInt("Wind Attack.Debris Damage"),ConfigFloat("Wind Attack.Debris Radius")*sizeMultiplier,ConfigFloat("Wind Attack.Debris Knockback Multiplier"),util::random_range(util::degToRad(-180.f),util::degToRad(180.f)),INFINITE,m.OnUpperLevel(),false,WHITE,vf2d{1.f,1.f}*sizeMultiplier)EndBullet;
|
||||
CreateBullet(Debris)(m.GetPos()+debrisSpawningOffset,debrisSpd,ConfigInt("Wind Attack.Debris Damage"),ConfigFloat("Wind Attack.Debris Radius")*sizeMultiplier,ConfigFloat("Wind Attack.Debris Knockback Multiplier"),util::random_range(util::degToRad(-180.f),util::degToRad(180.f)),INFINITE,m.OnUpperLevel(),NON_FRIENDLY,WHITE,vf2d{1.f,1.f}*sizeMultiplier)EndBullet;
|
||||
|
||||
m.F(A::SHOOT_TIMER)=ConfigFloat("Wind Attack.Wind Projectile Spawn Rate");
|
||||
}
|
||||
@ -376,7 +376,7 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy)
|
||||
return featherRate;
|
||||
};
|
||||
|
||||
CreateBullet(Feather)(ConfigVec("Mid Phase.Large Tornado Position"),vf2d{ConfigPixels("Mid Phase.Feather Speed"),util::random(2*PI)}.cart(),ConfigFloat("Mid Phase.Feather Radius"),ConfigInt("Mid Phase.Feather Damage"),m.OnUpperLevel(),false,INFINITE,false,WHITE)EndBullet;
|
||||
CreateBullet(Feather)(ConfigVec("Mid Phase.Large Tornado Position"),vf2d{ConfigPixels("Mid Phase.Feather Speed"),util::random(2*PI)}.cart(),ConfigFloat("Mid Phase.Feather Radius"),ConfigInt("Mid Phase.Feather Damage"),m.OnUpperLevel(),false,INFINITE,NON_FRIENDLY,WHITE)EndBullet;
|
||||
|
||||
m.F(A::SHOOT_TIMER)=GetHighestFeatherRateFromConfig(game->BossEncounterMobCount()-1); //Subtract one because we aren't counting the boss as part of this.
|
||||
}
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user