Add stone rain attack to second chapter boss. Second Chapter boss AI routine completed. Release Build 10015.
This commit is contained in:
parent
001d5e1c79
commit
7bb265e82a
@ -993,6 +993,10 @@
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FallingStone.cpp">
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SpellCircle.cpp">
|
||||
<SubType>
|
||||
</SubType>
|
||||
|
@ -1121,6 +1121,9 @@
|
||||
<ClCompile Include="RockLaunch.cpp">
|
||||
<Filter>Source Files\Effects</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FallingStone.cpp">
|
||||
<Filter>Source Files\Bullet Types</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
|
@ -38,6 +38,7 @@ All rights reserved.
|
||||
#pragma once
|
||||
#include "Bullet.h"
|
||||
#include "Direction.h"
|
||||
#include "Effect.h"
|
||||
|
||||
struct EnergyBolt:public Bullet{
|
||||
float lastParticleSpawn=0;
|
||||
@ -245,4 +246,19 @@ private:
|
||||
float moveTimer; //Counts down to 0, when it hits zero sets the velocity to futurevel.
|
||||
const float initialMoveWaitTime;
|
||||
const float knockbackAmt;
|
||||
};
|
||||
|
||||
struct FallingStone:public Bullet{
|
||||
//The position for this bullet represents where the falling stone should land.
|
||||
FallingStone(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;
|
||||
void Draw(const Pixel blendCol)const override;
|
||||
private:
|
||||
const vf2d targetPos;
|
||||
const float zVel{};
|
||||
const float indicatorDisplayTime;
|
||||
SpellCircle indicator;
|
||||
const float knockbackAmt;
|
||||
float lastTrailEffect{};
|
||||
};
|
@ -40,7 +40,7 @@ Size: 800%
|
||||
|
||||
>Like previously every pillar appears with 2,5 seconds delay from each other. (2 sec with an indicator, 0,5 seconds delay after a pillar got created)
|
||||
|
||||
The Boss continues with its normal behaviour while the pillars are getting casted.
|
||||
>The Boss continues with its normal behaviour while the pillars are getting casted.
|
||||
|
||||
|
||||
|
||||
|
@ -50,6 +50,7 @@ enum class EffectType{
|
||||
|
||||
struct Effect{
|
||||
friend class AiL;
|
||||
friend class FallingStone;
|
||||
vf2d pos={0,0};
|
||||
float lifetime=0;
|
||||
float fadeout=0;
|
||||
@ -110,8 +111,8 @@ struct ForegroundEffect:Effect{
|
||||
};
|
||||
|
||||
struct SpellCircle:Effect{
|
||||
SpellCircle(vf2d pos,float lifetime,std::string imgFile,std::string spellInsigniaFile,bool upperLevel,float size=1.0f,float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false,float insigniaSize=1.0f,float insigniaFadeout=0.0f,vf2d insigniaSpd={},Pixel insigniaCol=WHITE,float insigniaSotation=0,float insigniaRotationSpd=0,bool insigniaAdditiveBlending=false);
|
||||
SpellCircle(vf2d pos,float lifetime,std::string imgFile,std::string spellInsigniaFile,bool upperLevel,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false,vf2d insigniaSize={1,1},float insigniaFadeout=0.0f,vf2d insigniaSpd={},Pixel insigniaCol=WHITE,float insigniaSotation=0,float insigniaRotationSpd=0,bool insigniaAdditiveBlending=false);
|
||||
SpellCircle(vf2d pos,float lifetime,std::string imgFile,std::string spellInsigniaFile,bool upperLevel,float size=1.0f,float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false,float insigniaSize=1.0f,float insigniaFadeout=0.0f,vf2d insigniaSpd={},Pixel insigniaCol=WHITE,float insigniaRotation=0,float insigniaRotationSpd=0,bool insigniaAdditiveBlending=false);
|
||||
SpellCircle(vf2d pos,float lifetime,std::string imgFile,std::string spellInsigniaFile,bool upperLevel,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false,vf2d insigniaSize={1,1},float insigniaFadeout=0.0f,vf2d insigniaSpd={},Pixel insigniaCol=WHITE,float insigniaRotation=0,float insigniaRotationSpd=0,bool insigniaAdditiveBlending=false);
|
||||
Effect spellInsignia{vf2d{},0.f,"spell_insignia.png",false,{}};
|
||||
virtual bool Update(float fElapsedTime)override final;
|
||||
virtual void Draw()const override final;
|
||||
|
90
Adventures in Lestoria/FallingStone.cpp
Normal file
90
Adventures in Lestoria/FallingStone.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#pragma region License
|
||||
/*
|
||||
License (OLC-3)
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions or derivations of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions or derivative works in binary form must reproduce the above
|
||||
copyright notice. This list of conditions and the following disclaimer must be
|
||||
reproduced in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
Portions of this software are copyright © 2024 The FreeType
|
||||
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||
All rights reserved.
|
||||
*/
|
||||
#pragma endregion
|
||||
|
||||
#include "BulletTypes.h"
|
||||
#include "DEFINES.h"
|
||||
#include "AdventuresInLestoria.h"
|
||||
#include "util.h"
|
||||
#include <ranges>
|
||||
#include "SoundEffect.h"
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
FallingStone::FallingStone(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)
|
||||
:Bullet(targetPos,vel,radius,damage,"rock.png",upperLevel,false,lifetime+0.1f,false,friendly,col,scale,image_angle),targetPos(targetPos),zVel(zVel),indicatorDisplayTime(indicatorDisplayTime),knockbackAmt(knockbackAmt),
|
||||
indicator(targetPos,lifetime+0.1f,"range_indicator.png","spell_insignia.png",upperLevel,radius/12.f,0.5f,{},col,spellCircleRotation,spellCircleRotationSpd,false,radius/12.f,0.f,{},insigniaCol,insigniaRotation,insigniaRotationSpd,false){
|
||||
pos+=-vel*lifetime;
|
||||
z=-zVel*lifetime;
|
||||
}
|
||||
|
||||
void FallingStone::Update(float fElapsedTime){
|
||||
z+=zVel*fElapsedTime;
|
||||
lastTrailEffect-=fElapsedTime;
|
||||
if(z<=0.f){
|
||||
z=0.f;
|
||||
vel={};
|
||||
if(IsActivated()){
|
||||
fadeOutTime=0.5f;
|
||||
SoundEffect::PlaySFX("Stone Land",pos);
|
||||
if(friendly){
|
||||
for(auto&[monsterPtr,hurt]:game->Hurt(targetPos,radius,damage,OnUpperLevel(),z,HurtType::MONSTER)){
|
||||
if(hurt)std::get<Monster*>(monsterPtr)->ApplyIframes(0.1f);
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(auto&[playerPtr,hurt]:game->Hurt(targetPos,radius,damage,OnUpperLevel(),z,HurtType::PLAYER)){
|
||||
if(hurt)std::get<Player*>(playerPtr)->ApplyIframes(0.1f);
|
||||
}
|
||||
}
|
||||
game->ProximityKnockback(targetPos,radius,knockbackAmt,HurtType::PLAYER|HurtType::MONSTER);
|
||||
for(int i:std::ranges::iota_view(0,30))game->AddEffect(std::make_unique<Effect>(pos-vf2d{0.f,GetZ()},util::random_range(0.05f,0.2f),"circle_outline.png",OnUpperLevel(),util::random_range(0.5f,1.f),0.2f,vf2d{util::random_range(-10.f,10.f),util::random_range(-3.f,0.f)},PixelLerp(BLACK,col,util::random(1.f)),0.f,0.f,true));
|
||||
Deactivate();
|
||||
}
|
||||
}else{
|
||||
if(lastTrailEffect<=0.f){
|
||||
game->AddEffect(std::make_unique<Effect>(pos-vf2d{0.f,GetZ()},util::random_range(0.05f,0.2f),"circle_outline.png",OnUpperLevel(),util::random_range(0.5f,1.f),0.2f,vf2d{util::random_range(-3.f,3.f),util::random_range(-3.f,3.f)},PixelLerp(BLACK,col,util::random(1.f)),0.f,0.f,true));
|
||||
}
|
||||
}
|
||||
indicator.Update(fElapsedTime);
|
||||
}
|
||||
void FallingStone::Draw(const Pixel blendCol)const{
|
||||
if(lifetime<=indicatorDisplayTime){
|
||||
indicator.Draw();
|
||||
}
|
||||
Bullet::Draw(blendCol);
|
||||
}
|
@ -140,7 +140,6 @@ enum class Attribute{
|
||||
SAFE_AREA_WAIT_TIMER,
|
||||
PREVIOUS_MONSTER_COUNT,
|
||||
CHASE_TIMER,
|
||||
STONE_RAIN_COUNT,
|
||||
STONE_TOSS_COUNT,
|
||||
STONE_TOSS_TIMER,
|
||||
};
|
@ -45,6 +45,7 @@ All rights reserved.
|
||||
#include "SoundEffect.h"
|
||||
#include "StageMaskPolygon.h"
|
||||
#include "ExpandingRing.h"
|
||||
#include <ranges>
|
||||
|
||||
INCLUDE_game
|
||||
INCLUDE_MONSTER_LIST
|
||||
@ -323,11 +324,21 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str
|
||||
game->AddEffect(std::make_unique<RockLaunch>(m.GetPos()+vf2d{util::random_range(throwPos.GetReal(0),throwPos.GetReal(2)),util::random_range(throwPos.GetReal(1),throwPos.GetReal(3))},10.f,"rock.png",ConfigFloat("Stone Rain.Stone Toss Delay"),ConfigFloat("Stone Rain.Stone Toss Rock Size Mult"),0.1f,vf2d{0.f,-ConfigFloat("Stone Rain.Stone Toss Throw Speed")},WHITE,util::random(2*PI),0.f));
|
||||
|
||||
if(m.I(A::STONE_TOSS_COUNT)<=0){
|
||||
m.I(A::STONE_RAIN_COUNT)=ConfigInt("Stone Rain.Stone Count");
|
||||
m.phase=STONE_RAIN;
|
||||
m.F(A::BREAK_TIME)=ConfigFloat("Stone Rain.Stone Golem Wait Time");
|
||||
m.PerformAnimation("CAST");
|
||||
|
||||
for(int i:std::ranges::iota_view(0,ConfigInt("Stone Rain.Stone Count"))){
|
||||
CreateBullet(FallingStone)(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}break;
|
||||
case STONE_RAIN:{
|
||||
m.F(A::BREAK_TIME)-=fElapsedTime;
|
||||
if(m.F(A::BREAK_TIME)<=0.f){
|
||||
m.phase=STANDARD;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 3
|
||||
#define VERSION_BUILD 9994
|
||||
#define VERSION_BUILD 10015
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
@ -970,6 +970,9 @@ MonsterStrategy
|
||||
}
|
||||
Stone Rain
|
||||
{
|
||||
# How long to wait upon launching the stone rain attack before resuming normal AI.
|
||||
Stone Golem Wait Time = 4.0s
|
||||
|
||||
# How many stones the boss throws in the air.
|
||||
Initial Stone Toss Count = 2
|
||||
# Provide a Min X, Min Y, Max X, Max Y relative to the boss' position for where the stones appear prior to being tossed.
|
||||
@ -986,8 +989,18 @@ MonsterStrategy
|
||||
Stone Fall Delay = 2.5s, 4.0s
|
||||
# How long the indicator will appear before the rock drops down.
|
||||
Indicator Time = 1s
|
||||
# Provide an X,Y,Z falling velocity
|
||||
Stone Vel = -40.0, 0.0, -250.0
|
||||
Stone Damage = 30
|
||||
Stone Radius = 50
|
||||
Stone Knockback Amt = 150
|
||||
|
||||
Stone Spell Circle Color = 255, 40, 40, 160
|
||||
Stone Spell Insignia Color = 72, 66, 80, 255
|
||||
# Degrees/sec. Positive is CW, Negative is CCW.
|
||||
Stone Spell Circle Rotation Spd = -30
|
||||
# Degrees/sec. Positive is CW, Negative is CCW.
|
||||
Stone Spell Insignia Rotation Spd = 50
|
||||
}
|
||||
}
|
||||
Breaking Pillar
|
||||
|
@ -270,6 +270,12 @@ Events
|
||||
File[1] = slime_walk2.ogg, 10%
|
||||
File[2] = slime_walk3.ogg, 10%
|
||||
}
|
||||
Stone Land
|
||||
{
|
||||
CombatSound = True
|
||||
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||
File[0] = rockland.ogg, 40%
|
||||
}
|
||||
Toggle On
|
||||
{
|
||||
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||
|
BIN
Adventures in Lestoria/assets/sounds/rockland.ogg
Normal file
BIN
Adventures in Lestoria/assets/sounds/rockland.ogg
Normal file
Binary file not shown.
@ -147,14 +147,17 @@ namespace olc::utils::Animate2D
|
||||
{
|
||||
case Style::Repeat:
|
||||
case Style::OneShot:
|
||||
case Style::ReverseOneShot:
|
||||
case Style::ReverseOneShot:{
|
||||
return m_vFrames.size()*m_fFrameDuration;
|
||||
}break;
|
||||
case Style::PingPong:
|
||||
case Style::Reverse: //These two require twice as much time (minus one frame) to complete a full animation cycle.
|
||||
case Style::Reverse:{ //These two require twice as much time (minus one frame) to complete a full animation cycle.
|
||||
return m_vFrames.size()*m_fFrameDuration*2.f-m_fFrameDuration;
|
||||
default:
|
||||
}break;
|
||||
default:{
|
||||
ERR(std::format("WARNING! Animation style {} was not found! THIS SHOULD NOT BE HAPPENING!",int(m_nStyle)));
|
||||
return 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,14 +166,17 @@ namespace olc::utils::Animate2D
|
||||
{
|
||||
case Style::Repeat:
|
||||
case Style::OneShot:
|
||||
case Style::ReverseOneShot:
|
||||
case Style::ReverseOneShot:{
|
||||
return m_vFrames.size();
|
||||
}break;
|
||||
case Style::PingPong:
|
||||
case Style::Reverse: //These two require twice as much time (minus one frame) to complete a full animation cycle.
|
||||
case Style::Reverse:{ //These two require twice as much time (minus one frame) to complete a full animation cycle.
|
||||
return m_vFrames.size()*2.f-1;
|
||||
default:
|
||||
}break;
|
||||
default:{
|
||||
ERR(std::format("WARNING! Animation style {} was not found! THIS SHOULD NOT BE HAPPENING!",int(m_nStyle)));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,18 +186,22 @@ namespace olc::utils::Animate2D
|
||||
{
|
||||
switch (m_nStyle)
|
||||
{
|
||||
case Style::Repeat:
|
||||
case Style::Repeat:{
|
||||
return size_t(fTime * m_fFrameRate) % m_vFrames.size();
|
||||
case Style::OneShot:
|
||||
}break;
|
||||
case Style::OneShot:{
|
||||
return std::clamp(size_t(fTime * m_fFrameRate), size_t(0), m_vFrames.size() - 1);
|
||||
}break;
|
||||
case Style::PingPong:{
|
||||
size_t frame=size_t(m_fFrameRate*fTime) % (m_vFrames.size()*size_t(2)-size_t(1));
|
||||
return frame>=m_vFrames.size()?m_vFrames.size()-frame%m_vFrames.size()-1:frame;
|
||||
}break;
|
||||
case Style::ReverseOneShot:
|
||||
case Style::ReverseOneShot:{
|
||||
return std::clamp((m_vFrames.size() - 1) - size_t(fTime * m_fFrameRate), size_t(0), m_vFrames.size() - 1);
|
||||
case Style::Reverse:
|
||||
}break;
|
||||
case Style::Reverse:{
|
||||
return (m_vFrames.size() - 1) - (size_t(fTime * m_fFrameRate) % m_vFrames.size());
|
||||
}break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user