Blizzard Particle Effects+Spell casting preparation and implementation. Added Skeleton Frost Mage. Release Build 12481.
Some checks failed
Emscripten Build / Build_and_Deploy_Web_Build (push) Failing after 5m17s
Some checks failed
Emscripten Build / Build_and_Deploy_Web_Build (push) Failing after 5m17s
This commit is contained in:
parent
68b9330569
commit
d384478792
@ -396,7 +396,7 @@
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Blizzard.h" />
|
||||
<ClInclude Include="BlizzardSnowEmitter.h" />
|
||||
<ClInclude Include="BombBoom.h">
|
||||
<SubType>
|
||||
</SubType>
|
||||
@ -415,7 +415,8 @@
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FriendlyTag.h" />
|
||||
<ClInclude Include="FallEffect.h" />
|
||||
<ClInclude Include="FriendlyType.h" />
|
||||
<ClInclude Include="HurtDamageInfo.h">
|
||||
<SubType>
|
||||
</SubType>
|
||||
@ -824,6 +825,11 @@
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Blizzard.cpp">
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BlizzardSnowEmitter.cpp" />
|
||||
<ClCompile Include="Boar.cpp">
|
||||
<SubType>
|
||||
</SubType>
|
||||
|
||||
@ -726,12 +726,15 @@
|
||||
<ClInclude Include="MonsterAbility.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Blizzard.h">
|
||||
<Filter>Source Files\Effects</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FriendlyTag.h">
|
||||
<ClInclude Include="FriendlyType.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BlizzardSnowEmitter.h">
|
||||
<Filter>Source Files\Emitters</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FallEffect.h">
|
||||
<Filter>Source Files\Effects</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Player.cpp">
|
||||
@ -1355,6 +1358,12 @@
|
||||
<ClCompile Include="SkeletonFireMage.cpp">
|
||||
<Filter>Source Files\Monster Strategies</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BlizzardSnowEmitter.cpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Blizzard.cpp">
|
||||
<Filter>Source Files\Effects</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
|
||||
@ -811,7 +811,7 @@ void AiL::UpdateEffects(float fElapsedTime){
|
||||
e->Update(fElapsedTime);
|
||||
}
|
||||
|
||||
std::erase_if(EMITTER_LIST,[](std::unique_ptr<Emitter>&e){return e->dead;});
|
||||
std::erase_if(EMITTER_LIST,[](std::unique_ptr<IEmitter>&e){return e->dead;});
|
||||
std::erase_if(backgroundEffects,[](std::unique_ptr<Effect>&e){return e->dead;});
|
||||
std::erase_if(foregroundEffects,[](std::unique_ptr<Effect>&e){return e->dead;});
|
||||
std::erase_if(DAMAGENUMBER_LIST,[](std::shared_ptr<DamageNumber>&n){return n->IsDead();});
|
||||
|
||||
59
Adventures in Lestoria/Blizzard.cpp
Normal file
59
Adventures in Lestoria/Blizzard.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#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
|
||||
#include"Effect.h"
|
||||
#include"AdventuresInLestoria.h"
|
||||
#include<ranges>
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
Blizzard::Blizzard(const vf2d pos,const float radius, const float lifetime,const int damage,const float tickRate,const Range snowSizeRange,const float emitterFreq,const bool upperLevel,const FriendlyType friendly)
|
||||
:damage(damage),tickRate(tickRate),tickTimer(tickRate),radius(radius),friendly(friendly),Effect(pos,lifetime,"aiming_target.png",upperLevel,(radius*2/100)*vf2d{1.f,1.f},0.5f,{},{199,247,239,128},0.f,0.f,true)
|
||||
,snow(std::make_unique<BlizzardSnowEmitter>(pos,"circle.png",radius,snowSizeRange,emitterFreq,lifetime,upperLevel)){
|
||||
for(int i:std::ranges::iota_view(0,100))snow->Emit();
|
||||
}
|
||||
bool Blizzard::Update(float fElapsedTime){
|
||||
tickTimer-=fElapsedTime;
|
||||
if(tickTimer<=0.f){
|
||||
tickTimer+=tickRate;
|
||||
game->Hurt(pos,radius,damage,OnUpperLevel(),z,friendly?HurtType::MONSTER:HurtType::PLAYER);
|
||||
}
|
||||
snow->Update(fElapsedTime);
|
||||
}
|
||||
void Blizzard::Draw(const Pixel blendCol)const{
|
||||
|
||||
}
|
||||
60
Adventures in Lestoria/BlizzardSnowEmitter.cpp
Normal file
60
Adventures in Lestoria/BlizzardSnowEmitter.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#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
|
||||
|
||||
#include"BlizzardSnowEmitter.h"
|
||||
#include"AdventuresInLestoria.h"
|
||||
#include"FallEffect.h"
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
BlizzardSnowEmitter::BlizzardSnowEmitter(const vf2d pos,const std::string&img_filename,const float radius,Range scaleRange,float frequency,float timer,const bool upperLevel)
|
||||
:pos(pos),img_filename(img_filename),radius(radius),scaleRange(scaleRange),upperLevel(upperLevel),IEmitter(frequency,timer){}
|
||||
|
||||
void BlizzardSnowEmitter::Emit(){
|
||||
const float dist{util::random_range(0,radius)};
|
||||
const float startingZ{util::random_range(0,100)};
|
||||
const float gravity{util::random_range(10,40)};
|
||||
const float scale{util::random_range(scaleRange.first,scaleRange.second)};
|
||||
const float xSpd{-5.f};
|
||||
const float timeToFall{startingZ/gravity};
|
||||
const float colorInterpolation{util::random(1)};
|
||||
const Pixel baseCol{104,215,239};
|
||||
const uint8_t alpha{uint8_t(util::random_range(96,255))};
|
||||
game->AddEffect(std::make_unique<FallEffect>(pos+vf2d{xSpd*timeToFall,0.f},startingZ,gravity,img_filename,upperLevel,scale*vf2d{1.f,1.f},0.5f,vf2d{xSpd,0.f},Pixel{uint8_t(util::lerp(float(baseCol.r),255.f,colorInterpolation)),uint8_t(util::lerp(float(baseCol.g),255.f,colorInterpolation)),uint8_t(util::lerp(float(baseCol.b),255.f,colorInterpolation)),alpha},util::degToRad(util::random_range(0,360)),util::degToRad(util::random_range(-1.f,1.f)),true,EffectType::BLIZZARD_SNOW));
|
||||
}
|
||||
@ -36,9 +36,22 @@ All rights reserved.
|
||||
*/
|
||||
#pragma endregion
|
||||
#pragma once
|
||||
namespace Friendly{
|
||||
enum FriendlyType{
|
||||
FRIENDLY,
|
||||
NON_FRIENDLY,
|
||||
};
|
||||
}
|
||||
|
||||
#include"Emitter.h"
|
||||
#include"olcUTIL_Geometry2D.h"
|
||||
|
||||
using MinScale=float;
|
||||
using MaxScale=float;
|
||||
using Range=std::pair<MinScale,MaxScale>;
|
||||
|
||||
class BlizzardSnowEmitter:public IEmitter{
|
||||
public:
|
||||
BlizzardSnowEmitter(const olc::vf2d pos,const std::string&img_filename,const float radius,Range scaleRange,float frequency,float timer,const bool upperLevel);
|
||||
virtual void Emit()override final;
|
||||
private:
|
||||
const olc::vf2d pos;
|
||||
const float radius;
|
||||
const Range scaleRange;
|
||||
const std::string img_filename;
|
||||
const bool upperLevel;
|
||||
};
|
||||
@ -51,7 +51,7 @@ using MonsterSpawnerID=int;
|
||||
#define INCLUDE_game extern AiL*game;
|
||||
#define INCLUDE_MONSTER_DATA extern std::map<std::string,MonsterData>MONSTER_DATA;
|
||||
#define INCLUDE_BULLET_LIST extern std::vector<std::unique_ptr<IBullet>>BULLET_LIST;
|
||||
#define INCLUDE_EMITTER_LIST extern std::vector<std::unique_ptr<Emitter>>EMITTER_LIST;
|
||||
#define INCLUDE_EMITTER_LIST extern std::vector<std::unique_ptr<IEmitter>>EMITTER_LIST;
|
||||
#define INCLUDE_DATA extern utils::datafile DATA;
|
||||
#define INCLUDE_STRATEGY_DATA extern safemap<std::string,std::function<void(Monster&,float,std::string)>>STRATEGY_DATA;
|
||||
#define INCLUDE_TILE_ANIMATION_DATA extern std::map<int,std::vector<std::pair<int,float>>>TILE_ANIMATION_DATA;
|
||||
|
||||
@ -37,7 +37,7 @@ All rights reserved.
|
||||
#pragma endregion
|
||||
#pragma once
|
||||
#include "olcUTIL_Geometry2D.h"
|
||||
#include"FriendlyTag.h"
|
||||
#include"FriendlyType.h"
|
||||
|
||||
namespace DamageNumberType{
|
||||
enum DamageNumberType{
|
||||
|
||||
@ -42,7 +42,8 @@ All rights reserved.
|
||||
#include <variant>
|
||||
#include "Oscillator.h"
|
||||
#include "Entity.h"
|
||||
#include"FriendlyTag.h"
|
||||
#include"FriendlyType.h"
|
||||
#include"BlizzardSnowEmitter.h"
|
||||
class Monster;
|
||||
class Player;
|
||||
using HitList=std::unordered_set<std::variant<Monster*,Player*>>;
|
||||
@ -53,6 +54,7 @@ enum class EffectType{
|
||||
MONSTER_SOUL,
|
||||
BLINK_PORTAL,
|
||||
TRAIL_OF_FIRE,
|
||||
BLIZZARD_SNOW,
|
||||
};
|
||||
|
||||
struct Effect{
|
||||
@ -258,4 +260,18 @@ struct CollectCoinEffect:Effect{
|
||||
const Entity attachedTarget;
|
||||
Oscillator<float>sizeFlipper;
|
||||
Oscillator<float>zRiser;
|
||||
};
|
||||
|
||||
struct Blizzard:Effect{
|
||||
public:
|
||||
Blizzard(const vf2d pos,const float radius,const float lifetime,const int damage,const float tickRate,const Range snowSizeRange,const float emitterFreq,const bool upperLevel,const FriendlyType friendly);
|
||||
bool Update(float fElapsedTime)override;
|
||||
void Draw(const Pixel blendCol)const override;
|
||||
private:
|
||||
const int damage;
|
||||
const int tickRate;
|
||||
int tickTimer;
|
||||
const float radius;
|
||||
const FriendlyType friendly;
|
||||
const std::unique_ptr<BlizzardSnowEmitter>snow;
|
||||
};
|
||||
@ -38,12 +38,12 @@ All rights reserved.
|
||||
#include "Emitter.h"
|
||||
#include <memory>
|
||||
|
||||
std::vector<std::unique_ptr<Emitter>>EMITTER_LIST;
|
||||
std::vector<std::unique_ptr<IEmitter>>EMITTER_LIST;
|
||||
|
||||
Emitter::Emitter(float frequency,float timer)
|
||||
IEmitter::IEmitter(float frequency,float timer)
|
||||
:frequency(frequency),timer(timer){}
|
||||
|
||||
bool Emitter::Update(float fElapsedTime){
|
||||
bool IEmitter::Update(float fElapsedTime){
|
||||
lastEmit=std::max(lastEmit-fElapsedTime,0.f);
|
||||
if(lastEmit==0){
|
||||
lastEmit=frequency;
|
||||
|
||||
@ -38,7 +38,7 @@ All rights reserved.
|
||||
#pragma once
|
||||
#include "olcUTIL_Geometry2D.h"
|
||||
|
||||
struct Emitter{
|
||||
struct IEmitter{
|
||||
friend class AiL;
|
||||
float frequency;
|
||||
float timer;
|
||||
@ -46,13 +46,13 @@ struct Emitter{
|
||||
private:
|
||||
bool dead=false;
|
||||
public:
|
||||
virtual ~Emitter()=default;
|
||||
Emitter(float frequency,float timer);
|
||||
virtual ~IEmitter()=default;
|
||||
IEmitter(float frequency,float timer);
|
||||
bool Update(float fElapsedTime);
|
||||
virtual void Emit()=0;
|
||||
};
|
||||
|
||||
class LightningBoltEmitter:public Emitter{
|
||||
class LightningBoltEmitter:public IEmitter{
|
||||
vf2d startPos,endPos;
|
||||
bool upperLevel;
|
||||
void DrawLightningBolt();
|
||||
|
||||
@ -35,29 +35,26 @@ Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||
All rights reserved.
|
||||
*/
|
||||
#pragma endregion
|
||||
#include"AdventuresInLestoria.h"
|
||||
#include"Emitter.h"
|
||||
#include "Effect.h"
|
||||
#include "DEFINES.h"
|
||||
#include "safemap.h"
|
||||
|
||||
INCLUDE_game
|
||||
INCLUDE_GFX
|
||||
|
||||
struct Blizzard:Effect{
|
||||
//This class is used when you want an effect to start in mid-air and fall down. It disappears upon hitting the ground.
|
||||
class FallEffect:public Effect{
|
||||
public:
|
||||
inline Blizzard(const vf2d pos,const float radius, const float lifetime,const int damage,const float tickRate,const bool upperLevel,const )
|
||||
:damage(damage),tickRate(tickRate),tickTimer(tickRate),radius(radius),Effect(pos,lifetime,"aiming_target.png",upperLevel,(radius*2/100)*vf2d{1.f,1.f},0.5f,{},{199,247,239,128},0.f,0.f,true){}
|
||||
inline bool Update(float fElapsedTime)override{
|
||||
tickTimer-=fElapsedTime;
|
||||
if(tickTimer<=0.f){
|
||||
tickTimer+=tickRate;
|
||||
game->Hurt(
|
||||
}
|
||||
inline FallEffect(vf2d pos,const float z,const float gravity,const std::string&imgFile, bool upperLevel,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false,const EffectType type=EffectType::NONE)
|
||||
:gravity(gravity),Effect(pos,INFINITY,imgFile,upperLevel,size,fadeout,spd,col,rotation,rotationSpd,additiveBlending){
|
||||
this->z=z;
|
||||
this->SetType(type);
|
||||
}
|
||||
inline void Draw(const Pixel blendCol)const override{
|
||||
|
||||
|
||||
inline bool Update(float fElapsedTime)override{
|
||||
z-=gravity*fElapsedTime;
|
||||
if(z<=0.f)lifetime=0.f;
|
||||
return Effect::Update(fElapsedTime);
|
||||
}
|
||||
private:
|
||||
Emitter snow{;
|
||||
const int damage;
|
||||
const int tickRate;
|
||||
int tickTimer;
|
||||
const float radius;
|
||||
const float gravity;
|
||||
};
|
||||
@ -41,16 +41,16 @@ All rights reserved.
|
||||
|
||||
INCLUDE_GFX
|
||||
|
||||
class FallingDebris:public Effect{
|
||||
const float GRAVITY=20;
|
||||
class FallEffect:public Effect{
|
||||
const float gravity=20;
|
||||
public:
|
||||
inline FallingDebris(vf2d pos, float lifetime, std::string imgFile, bool upperLevel,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false)
|
||||
inline FallEffect(vf2d pos, float lifetime,const std::string&imgFile, bool upperLevel,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false)
|
||||
:Effect(pos,lifetime,imgFile,upperLevel,size,fadeout,spd,col,rotation,rotationSpd,additiveBlending){
|
||||
|
||||
}
|
||||
|
||||
inline bool Update(float fElapsedTime)override{
|
||||
spd.y+=GRAVITY*fElapsedTime;
|
||||
spd.y+=gravity*fElapsedTime;
|
||||
return Effect::Update(fElapsedTime);
|
||||
}
|
||||
};
|
||||
@ -40,7 +40,7 @@ All rights reserved.
|
||||
#include "olcUTIL_Animate2D.h"
|
||||
#include "Monster.h"
|
||||
#include "DEFINES.h"
|
||||
#include"FriendlyTag.h"
|
||||
#include"FriendlyType.h"
|
||||
using HitList=std::unordered_set<std::variant<Monster*,Player*>>;
|
||||
|
||||
enum class HurtType{
|
||||
|
||||
@ -63,7 +63,7 @@ void LargeStone::Update(float fElapsedTime){
|
||||
for(int i=0;i<100;i++){
|
||||
const float randomDir{util::random(2*PI)};
|
||||
|
||||
game->AddEffect(std::make_unique<FallingDebris>(pos+vf2d{radius,randomDir}.cart(),0.f,"circle.png",OnUpperLevel(),vf2d{1.5f,1.5f}*util::random(2.f),util::random(1.f),vf2d{vf2d{radius,randomDir}.cart().x,-util::random(30.f)-20.f},BLACK));
|
||||
game->AddEffect(std::make_unique<FallEffect>(pos+vf2d{radius,randomDir}.cart(),0.f,"circle.png",OnUpperLevel(),vf2d{1.5f,1.5f}*util::random(2.f),util::random(1.f),vf2d{vf2d{radius,randomDir}.cart().x,-util::random(30.f)-20.f},BLACK));
|
||||
}
|
||||
|
||||
const HurtList pillarList{game->HurtMonsterType(pos,radius,3,OnUpperLevel(),GetZ(),"Stone Golem Pillar")};
|
||||
|
||||
@ -44,7 +44,7 @@ All rights reserved.
|
||||
INCLUDE_game
|
||||
|
||||
LightningBoltEmitter::LightningBoltEmitter(vf2d startPos,vf2d endPos,float frequency,float timer,bool upperLevel)
|
||||
:startPos(startPos),endPos(endPos),Emitter(frequency,timer),upperLevel(upperLevel){}
|
||||
:startPos(startPos),endPos(endPos),IEmitter(frequency,timer),upperLevel(upperLevel){}
|
||||
|
||||
|
||||
void LightningBoltEmitter::Emit(){
|
||||
|
||||
@ -1797,7 +1797,7 @@ void Monster::CastAbility(const MonsterAbilityData&data,const vf2d pos){
|
||||
}
|
||||
|
||||
void Monster::PerformSpell(const CastInfo&castData){
|
||||
MonsterAbility::SPELLS.at(castData.name)(castData.name,castData.castPos,GetWeakPointer());
|
||||
MonsterAbility::SPELLS.at(castData.name)(castData.name,castData.castPos,*this,GetStrategyName());
|
||||
PerformIdleAnimation();
|
||||
mp-=castData.mpCost;
|
||||
}
|
||||
@ -50,6 +50,7 @@ All rights reserved.
|
||||
#include "Direction.h"
|
||||
#include "HurtDamageInfo.h"
|
||||
#include "Oscillator.h"
|
||||
#include"MonsterStrategyHelpers.h"
|
||||
|
||||
INCLUDE_ITEM_DATA
|
||||
INCLUDE_MONSTER_DATA
|
||||
@ -61,8 +62,6 @@ enum class Attribute;
|
||||
|
||||
class GameEvent;
|
||||
|
||||
using StrategyName=std::string;
|
||||
|
||||
namespace MonsterTests{
|
||||
class MonsterTest;
|
||||
};
|
||||
|
||||
@ -6,15 +6,15 @@
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
std::unordered_map<std::string_view,std::function<void(SpellName,CastPos,CasterMonster)>>MonsterAbility::SPELLS{
|
||||
{"Meteor",[](SpellName spellName,CastPos pos,CasterMonster monster)->void{
|
||||
Monster&m{*(monster.lock())};
|
||||
const std::string strategy{m.GetStrategyName()};
|
||||
std::unordered_map<std::string_view,std::function<void(SpellName,CastPos,CasterMonster&,const StrategyName&)>>MonsterAbility::SPELLS{
|
||||
{"Meteor",[](SpellName spellName,CastPos pos,CasterMonster&m,const StrategyName&strategy)->void{
|
||||
game->AddEffect(std::make_unique<Meteor>(pos,3.f,m.OnUpperLevel(),Meteor::SKELETON_FIRE_MAGE,std::pair<MeteorDamage,PulsatingFireDamage>{int(m.GetAttack()*ConfigFloat("Meteor Damage Mult")),int(m.GetAttack()*ConfigFloat("Fire Ring Damage Mult"))},"Wizard.Ability 3.MeteorFadeoutTime"_F));
|
||||
}},
|
||||
{"Fire Bolt",[](SpellName spellName,CastPos pos,CasterMonster monster)->void{
|
||||
Monster&m{*(monster.lock())};
|
||||
const std::string strategy{m.GetStrategyName()};
|
||||
{"Fire Bolt",[](SpellName spellName,CastPos pos,CasterMonster&m,const StrategyName&strategy)->void{
|
||||
CreateBullet(FireBolt)(m.GetPos(),util::pointTo(m.GetPos(),game->GetPlayer()->GetPos())*ConfigFloat("Fire Bolt Bullet Speed"),"Wizard.Ability 1.Radius"_F/100*12,m.GetAttack()*ConfigFloat("Fire Bolt Damage Mult"),m.OnUpperLevel())EndBullet;
|
||||
}},
|
||||
{"Blizzard",[](SpellName spellName,CastPos pos,CasterMonster&m,const StrategyName&strategy)->void{
|
||||
}},
|
||||
{"Freeze Ground",[](SpellName spellName,CastPos pos,CasterMonster&m,const StrategyName&strategy)->void{
|
||||
}},
|
||||
};
|
||||
@ -5,14 +5,15 @@
|
||||
#include<unordered_map>
|
||||
#include<functional>
|
||||
#include"olcUTIL_Geometry2D.h"
|
||||
#include"MonsterStrategyHelpers.h"
|
||||
|
||||
class Monster;
|
||||
|
||||
using SpellName=std::string;
|
||||
using CastPos=vf2d;
|
||||
using CasterMonster=std::weak_ptr<Monster>;
|
||||
using CasterMonster=Monster;
|
||||
|
||||
class MonsterAbility{
|
||||
public:
|
||||
static std::unordered_map<std::string_view,std::function<void(SpellName,CastPos,CasterMonster)>>SPELLS;
|
||||
static std::unordered_map<std::string_view,std::function<void(SpellName,CastPos,CasterMonster&,const StrategyName&)>>SPELLS;
|
||||
};
|
||||
@ -42,6 +42,7 @@ All rights reserved.
|
||||
#include "safemap.h"
|
||||
#include "Item.h"
|
||||
#include "AdventuresInLestoria.h"
|
||||
#include"MonsterAbility.h"
|
||||
|
||||
INCLUDE_DATA
|
||||
INCLUDE_STRATEGY_DATA
|
||||
@ -216,6 +217,7 @@ void MonsterData::InitializeMonsterData(){
|
||||
auto&abilityData{DATA["Monsters"][MonsterName]["Abilities"]};
|
||||
for(auto&[key,size]:abilityData){
|
||||
auto&ability{abilityData[key]};
|
||||
if(!MonsterAbility::SPELLS.contains(key))ERR(std::format("WARNING! Monster Ability {} does not exist! Failed to add ability to Monster {}",key,MonsterName));
|
||||
monster.abilities.emplace_back(MonsterAbilityData{.name=key,.mpCost=ability.GetInt(0),.pctCastChance=ability.GetReal(1)/100.f,.castTime=ability.GetReal(2)});
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,6 +38,8 @@ All rights reserved.
|
||||
|
||||
#include"MonsterAttribute.h"
|
||||
|
||||
using StrategyName=std::string;
|
||||
|
||||
#pragma once
|
||||
#define ConfigInt(param) Monster::STRATEGY::_GetInt(m,param,strategy)
|
||||
#define ConfigFloat(param) Monster::STRATEGY::_GetFloat(m,param,strategy)
|
||||
|
||||
@ -158,7 +158,7 @@ void Monster::STRATEGY::RUN_TOWARDS(Monster&m,float fElapsedTime,std::string str
|
||||
float dist=lineToPlayer.length();
|
||||
for(int i=0;i<m.GetSizeMult()*25;i++){
|
||||
float randomDir=util::random(2*PI);
|
||||
game->AddEffect(std::make_unique<FallingDebris>(m.GetPos()+vf2d{cos(randomDir),sin(randomDir)}*m.GetSizeMult()*8,util::random(1),"circle.png",m.OnUpperLevel(),vf2d{1,1},0.5,vf2d{cos(randomDir)*util::random(5),sin(randomDir)*-util::random(15)-5}*30,BLACK),true);
|
||||
game->AddEffect(std::make_unique<FallEffect>(m.GetPos()+vf2d{cos(randomDir),sin(randomDir)}*m.GetSizeMult()*8,util::random(1),"circle.png",m.OnUpperLevel(),vf2d{1,1},0.5,vf2d{cos(randomDir)*util::random(5),sin(randomDir)*-util::random(15)-5}*30,BLACK),true);
|
||||
}
|
||||
if(dist<12*m.GetSizeMult()){
|
||||
int jumpDamage=0;
|
||||
|
||||
@ -202,7 +202,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
|
||||
float dist=lineToPlayer.length();
|
||||
for(int i=0;i<200;i++){
|
||||
float randomDir=util::random(2*PI);
|
||||
game->AddEffect(std::make_unique<FallingDebris>(m.GetPos()+vf2d{cos(randomDir),sin(randomDir)}*m.GetSizeMult()*8,util::random(1),"circle.png",m.OnUpperLevel(),vf2d{1,1},0.5,vf2d{cos(randomDir)*util::random(5),sin(randomDir)*-util::random(15)-5}*30,BLACK),true);
|
||||
game->AddEffect(std::make_unique<FallEffect>(m.GetPos()+vf2d{cos(randomDir),sin(randomDir)}*m.GetSizeMult()*8,util::random(1),"circle.png",m.OnUpperLevel(),vf2d{1,1},0.5,vf2d{cos(randomDir)*util::random(5),sin(randomDir)*-util::random(15)-5}*30,BLACK),true);
|
||||
}
|
||||
if(dist<12*m.GetSizeMult()){
|
||||
if(game->GetPlayer()->Hurt(ConfigInt("JumpAttackDamage"),m.OnUpperLevel(),m.GetZ())){
|
||||
|
||||
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_PATCH 0
|
||||
#define VERSION_BUILD 12458
|
||||
#define VERSION_BUILD 12481
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="315" height="238" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="16">
|
||||
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="315" height="238" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="17">
|
||||
<properties>
|
||||
<property name="Background Music" propertytype="BGM" value="undead_swamp"/>
|
||||
<property name="Level Type" type="int" propertytype="LevelType" value="0"/>
|
||||
@ -990,7 +990,7 @@
|
||||
<object id="6" name="Monster Spawn Zone" type="SpawnGroup" x="438" y="4770" width="216" height="246">
|
||||
<ellipse/>
|
||||
</object>
|
||||
<object id="15" template="../maps/Monsters/Skeleton Fire Mage.tx" x="582" y="4872">
|
||||
<object id="16" template="../maps/Monsters/Skeleton Frost Mage.tx" x="612" y="4794">
|
||||
<properties>
|
||||
<property name="spawner" type="object" value="6"/>
|
||||
</properties>
|
||||
|
||||
@ -2217,6 +2217,55 @@ Monsters
|
||||
Death Sound = Slime Dead
|
||||
Walk Sound = Slime Walk
|
||||
|
||||
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
|
||||
#DROP[0] = Broken Bow,30%,1,1
|
||||
}
|
||||
Skeleton Frost Mage
|
||||
{
|
||||
Health = 650
|
||||
Attack = 41
|
||||
|
||||
CollisionDmg = 41
|
||||
|
||||
MoveSpd = 80%
|
||||
Size = 90%
|
||||
|
||||
XP = 49
|
||||
|
||||
MP = 0
|
||||
MP Recovery = 5mp/s
|
||||
|
||||
Abilities
|
||||
{
|
||||
#Ability Name = Mana cost, % chance to cast (every second), Cast Time (Instant = 0.0s)
|
||||
Blizzard = 50mp, 60%, 1.5sec
|
||||
Freeze Ground = 20mp, 10%, 1.0sec
|
||||
}
|
||||
|
||||
Strategy = Skeleton Fire Mage
|
||||
|
||||
#Size of each animation frame
|
||||
SheetFrameSize = 32,32
|
||||
|
||||
# Setting this to true means every four rows indicates one animation, the ordering of the directions is: NORTH, EAST, SOUTH, WEST
|
||||
4-Way Spritesheet = False
|
||||
|
||||
Animations
|
||||
{
|
||||
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse,ReverseOneShot)
|
||||
# Animations must be defined in the same order as they are in their sprite sheets
|
||||
# The First Four animations must represent a standing, walking, attack, and death animation. Their names are up to the creator.
|
||||
IDLE = 2, 0.6, Repeat
|
||||
WALK = 3, 0.2, Repeat
|
||||
ATTACK = 4, 0.1, Repeat
|
||||
DEATH = 4, 0.15, OneShot
|
||||
CASTING = 4, 0.1, Repeat
|
||||
}
|
||||
|
||||
Hurt Sound = Monster Hurt
|
||||
Death Sound = Slime Dead
|
||||
Walk Sound = Slime Walk
|
||||
|
||||
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
|
||||
#DROP[0] = Broken Bow,30%,1,1
|
||||
}
|
||||
|
||||
Binary file not shown.
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<template>
|
||||
<tileset firstgid="1" source="../Monsters.tsx"/>
|
||||
<object name="Skeleton Frost Mage" type="Monster" gid="40" width="48" height="48"/>
|
||||
</template>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user