diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj b/Adventures in Lestoria/Adventures in Lestoria.vcxproj
index bdd98353..cd62f091 100644
--- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj
+++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj
@@ -1181,7 +1181,7 @@
-
+
diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters
index 744660cd..2f30ab42 100644
--- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters
+++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters
@@ -1172,7 +1172,7 @@
Source Files\Effects
-
+ Source Files\Bullet Types
diff --git a/Adventures in Lestoria/BulletTypes.h b/Adventures in Lestoria/BulletTypes.h
index cf11ef86..d29b373e 100644
--- a/Adventures in Lestoria/BulletTypes.h
+++ b/Adventures in Lestoria/BulletTypes.h
@@ -282,8 +282,7 @@ private:
};
struct FallingBullet:public Bullet{
- //The position for this bullet represents where the falling stone should land.
- FallingBullet(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 col=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);
+ //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 col=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;
diff --git a/Adventures in Lestoria/FallingStone.cpp b/Adventures in Lestoria/FallingBullet.cpp
similarity index 87%
rename from Adventures in Lestoria/FallingStone.cpp
rename to Adventures in Lestoria/FallingBullet.cpp
index e07e634a..95b0168f 100644
--- a/Adventures in Lestoria/FallingStone.cpp
+++ b/Adventures in Lestoria/FallingBullet.cpp
@@ -52,9 +52,6 @@ indicator(targetPos,lifetime+0.1f,"range_indicator.png","spell_insignia.png",upp
z=-zVel*lifetime;
}
-FallingBullet::FallingBullet(vf2d targetPos,vf2d vel,float zVel,float indicatorDisplayTime,float radius,int damage,bool upperLevel,bool hitsMultiple,float knockbackAmt,float lifetime,bool friendly,Pixel col,vf2d scale,float image_angle,float spellCircleRotation,float spellCircleRotationSpd,Pixel insigniaCol,float insigniaRotation,float insigniaRotationSpd)
-:FallingBullet("rock.png",targetPos,vel,zVel,indicatorDisplayTime,radius,damage,upperLevel,hitsMultiple,knockbackAmt,lifetime,friendly,col,scale,image_angle,spellCircleRotation,spellCircleRotationSpd,insigniaCol,insigniaRotation,insigniaRotationSpd){}
-
void FallingBullet::Update(float fElapsedTime){
z+=zVel*fElapsedTime;
lastTrailEffect-=fElapsedTime;
diff --git a/Adventures in Lestoria/GhostOfPirateCaptain.cpp b/Adventures in Lestoria/GhostOfPirateCaptain.cpp
index e5e1e565..d1fb0ac7 100644
--- a/Adventures in Lestoria/GhostOfPirateCaptain.cpp
+++ b/Adventures in Lestoria/GhostOfPirateCaptain.cpp
@@ -53,8 +53,15 @@ void Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std
NORMAL,
};
- static const uint8_t PHASE_COUNT{DATA.GetProperty("MonsterStrategy.Ghost of Pirate Captain").GetValueCount()};
- static std::vectorPHASES{};
+ enum CannonShotType{
+ BOMBARDMENT,//every shot is at a random location within 900 Range of the player. (This is also the move during hide and seek.)
+ PRECISE_BOMBARDMENT,//same as before but within 700 range of the player.
+ LINE,//the 4th or 5th hit would hit the player if the player doesnt move at all.
+ SHARPSHOOTER,//aiming directly at the player, skipping every 2nd shot. (only 4 instead of 8 shots)
+ PREDICTION,//shoots in the direction of the current or last players movement and predicts where the player would be in 2.8 seconds. (slightly further then where the player would be at impact. thats why 2.8 instead of 2.5 seconds)
+ };
+
+ static const uint8_t PHASE_COUNT{uint8_t(DATA.GetProperty("MonsterStrategy.Ghost of Pirate Captain.Cannon Cycle").GetValueCount())};
const auto AdvanceCannonPhase{[&m,&strategy](){
m.GetFloat(A::CANNON_TIMER)=0.f;
@@ -64,45 +71,45 @@ void Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std
switch(PHASE()){
case INIT:{
- for(int i:std::ranges::iota_view(PHASE_COUNT)){
- PHASES.emplace_back(DATA.GetProperty("MonsterStrategy.Ghost of Pirate Captain").GetInt(i));
+ for(int i:std::ranges::iota_view(0U,PHASE_COUNT)){
+ m.VEC(A::CANNON_PHASES).emplace_back(DATA.GetProperty("MonsterStrategy.Ghost of Pirate Captain.Cannon Cycle").GetInt(i));
}
- m.I(A::CANNON_SHOT_TYPE)=util::random()%5;
+ m.I(A::CANNON_SHOT_TYPE)=BOMBARDMENT;
+ SETPHASE(NORMAL);
}break;
case NORMAL:{
m.F(A::CANNON_TIMER)+=fElapsedTime;
- switch(PHASES[m.I(A::CANNON_PHASE)]){
+ const int phase{std::any_cast(m.VEC(A::CANNON_PHASES)[m.I(A::CANNON_PHASE)])};
+ switch(phase){
enum CannonPhaseType{
CANNON_SHOT,
SILENCE,
SHRAPNEL_SHOT,
};
case CANNON_SHOT:{//Normal Cannon Shot. Takes on one of five varieties.
- enum CannonShotType{
- BOMBARDMENT,//every shot is at a random location within 900 Range of the player. (This is also the move during hide and seek.)
- PRECISE_BOMBARDMENT,//same as before but within 700 range of the player.
- LINE,//the 4th or 5th hit would hit the player if the player doesnt move at all.
- SHARPSHOOTER,//aiming directly at the player, skipping every 2nd shot. (only 4 instead of 8 shots)
- PREDICTION,//shoots in the direction of the current or last players movement and predicts where the player would be in 2.8 seconds. (slightly further then where the player would be at impact. thats why 2.8 instead of 2.5 seconds)
- };
- switch(m.I(A::CANNON_SHOT_TYPE)){
- case BOMBARDMENT:{
-
- }break;
- case PRECISE_BOMBARDMENT:{
-
- }break;
- case LINE:{
-
- }break;
- case SHARPSHOOTER:{
-
- }break;
- case PREDICTION:{
-
- }break;
+ if(m.F(A::CANNON_TIMER)>=ConfigFloat("Cannon Shot Delay")){
+ switch(m.I(A::CANNON_SHOT_TYPE)){
+ case BOMBARDMENT:{
+ const float randomAng{util::random_range(0,2*PI)};
+ const float range{util::random_range(0,ConfigPixels("Bombardment Max Distance"))};
+ const vf2d targetPos{game->camera.GetTarget()-ConfigPixels("Bombardment Max Distance")/2.f+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"),0.4f,false,ConfigPixel("Cannon Spell Circle Color"),vf2d{ConfigFloat("Cannon Radius")/100.f*2.f,ConfigFloat("Cannon Radius")/100.f*2.f},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:{
+
+ }break;
+ case LINE:{
+
+ }break;
+ case SHARPSHOOTER:{
+
+ }break;
+ case PREDICTION:{
+
+ }break;
+ }
+ AdvanceCannonPhase();
}
- if(m.F(A::CANNON_TIMER)>=ConfigFloat("Cannon Shot Delay"))AdvanceCannonPhase();
}break;
case SILENCE:{
if(m.F(A::CANNON_TIMER)>=ConfigFloat("Silence Time"))AdvanceCannonPhase();
diff --git a/Adventures in Lestoria/MonsterAttribute.h b/Adventures in Lestoria/MonsterAttribute.h
index d580bf85..68030cd5 100644
--- a/Adventures in Lestoria/MonsterAttribute.h
+++ b/Adventures in Lestoria/MonsterAttribute.h
@@ -166,4 +166,5 @@ enum class Attribute{
CANNON_TIMER,
CANNON_PHASE,
CANNON_SHOT_TYPE,
+ CANNON_PHASES,
};
\ No newline at end of file
diff --git a/Adventures in Lestoria/StoneGolem.cpp b/Adventures in Lestoria/StoneGolem.cpp
index 535e43b8..35fe0e46 100644
--- a/Adventures in Lestoria/StoneGolem.cpp
+++ b/Adventures in Lestoria/StoneGolem.cpp
@@ -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)(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)),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;
}
}
}
diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h
index b0812ade..259e3c11 100644
--- a/Adventures in Lestoria/Version.h
+++ b/Adventures in Lestoria/Version.h
@@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_PATCH 0
-#define VERSION_BUILD 11936
+#define VERSION_BUILD 11946
#define stringify(a) stringify_(a)
#define stringify_(a) #a
diff --git a/Adventures in Lestoria/assets/Campaigns/Boss_3.tmx b/Adventures in Lestoria/assets/Campaigns/Boss_3.tmx
index a9af8880..e95eb140 100644
--- a/Adventures in Lestoria/assets/Campaigns/Boss_3.tmx
+++ b/Adventures in Lestoria/assets/Campaigns/Boss_3.tmx
@@ -1,5 +1,5 @@
-