Implemented lingering effect item script capabilities. Added Molotov item and item graphic. Added burning sound effect. Release Build 11755.

master
sigonasr2 1 month ago
parent 868a089666
commit 3a3d405272
  1. 1
      Adventures in Lestoria/Animation.cpp
  2. 3
      Adventures in Lestoria/BulletTypes.h
  3. 6
      Adventures in Lestoria/Effect.h
  4. 6
      Adventures in Lestoria/Item.cpp
  5. 6
      Adventures in Lestoria/Item.h
  6. 26
      Adventures in Lestoria/ItemScript.cpp
  7. 1
      Adventures in Lestoria/Oscillator.h
  8. 2
      Adventures in Lestoria/PoisonBottle.cpp
  9. 8
      Adventures in Lestoria/PoisonPool.cpp
  10. 11
      Adventures in Lestoria/ThrownProjectile.cpp
  11. 2
      Adventures in Lestoria/Version.h
  12. BIN
      Adventures in Lestoria/assets/Molotov.png
  13. 5
      Adventures in Lestoria/assets/config/audio/events.txt
  14. 2
      Adventures in Lestoria/assets/config/gfx/gfx.txt
  15. 3
      Adventures in Lestoria/assets/config/items/ItemDatabase.txt
  16. 1
      Adventures in Lestoria/assets/config/items/ItemScript.txt
  17. BIN
      Adventures in Lestoria/assets/fire_ring.png
  18. BIN
      Adventures in Lestoria/assets/gamepack.pak
  19. BIN
      Adventures in Lestoria/assets/items/Molotov.png
  20. BIN
      Adventures in Lestoria/assets/sounds/burning.ogg
  21. BIN
      x64/Release/Adventures in Lestoria.exe

@ -461,6 +461,7 @@ void sig::Animation::InitializeAnimations(){
CreateHorizontalAnimationSequence("bear_trap.png",3,{24,24},AnimationData{.frameDuration{0.1f},.style{Animate2D::Style::PingPong}});
CreateHorizontalAnimationSequence("explosive_trap.png",4,{48,48},AnimationData{.frameDuration{0.06f},.style{Animate2D::Style::PingPong}});
CreateHorizontalAnimationSequence("explosionframes.png",21,{24,24},AnimationData{.frameDuration{0.02f},.style{Animate2D::Style::OneShot}});
CreateHorizontalAnimationSequence("fire_ring.png",5,{60,60},AnimationData{.frameDuration{0.1f},.style{Animate2D::Style::Repeat}});
CreateHorizontalAnimationSequence("portal.png",8,{24,24},AnimationData{.frameDuration{0.1f},.style{Animate2D::Style::Repeat}});

@ -352,7 +352,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={});
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={});
void Update(float fElapsedTime)override;
void ModifyOutgoingDamageData(HurtDamageInfo&data);
void _OnGroundLand();
@ -369,6 +369,7 @@ protected:
const float explodeRadius;
const std::optional<Effect>explodeEffect;
const std::optional<std::string>explodeSoundEffect;
const std::optional<LingeringEffect>lingeringEffect;
const std::string img;
};

@ -204,13 +204,13 @@ struct FadeInOutEffect:Effect{
const float originalParticleSpawnTimer{};
};
struct PoisonPool:FadeInOutEffect{
PoisonPool(vf2d pos,const std::string&img,float radius,int damage,float damageFreq,const HurtType friendly,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending=false,float particleSpawnFreq=0.f,const std::function<Effect(const Effect&self)>&particleGenerator={});
struct LingeringEffect:FadeInOutEffect{
LingeringEffect(vf2d pos,const std::string&img,const std::string&soundEffect,float radius,int damage,float damageFreq,const HurtType friendly,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending=false,float particleSpawnFreq=0.f,const std::function<Effect(const Effect&self)>&particleGenerator={});
virtual bool Update(float fElapsedTime)override final;
const int damage;
float damageTimer{};
const float originalDamageTimer{};
const float radius;
HurtType friendly;
const size_t poisonPoolSFXID{};
const size_t sfxID{};
};

@ -437,15 +437,15 @@ void ItemInfo::InitializeItems(){
ItemProps::ItemProps(utils::datafile*scriptProps,utils::datafile*customProps)
:scriptProps(scriptProps),customProps(customProps){}
int ItemProps::GetIntProp(const std::string&prop,size_t index)const{
int ItemProps::GetInt(const std::string&prop,size_t index)const{
if(customProps->HasProperty(prop)) return (*customProps)[prop].GetInt(index);
else return (*scriptProps)[prop].GetInt(index);
};
float ItemProps::GetFloatProp(const std::string&prop,size_t index)const{
float ItemProps::GetFloat(const std::string&prop,size_t index)const{
if(customProps->HasProperty(prop)) return float((*customProps)[prop].GetReal(index));
else return float((*scriptProps)[prop].GetReal(index));
};
std::string ItemProps::GetStringProp(const std::string&prop,size_t index)const{
std::string ItemProps::GetString(const std::string&prop,size_t index)const{
if(customProps->HasProperty(prop)) return (*customProps)[prop].GetString(index);
else return (*scriptProps)[prop].GetString(index);
};

@ -345,9 +345,9 @@ class ItemProps{
utils::datafile*customProps;
public:
ItemProps(utils::datafile*scriptProps,utils::datafile*customProps);
int GetIntProp(const std::string&prop,size_t index=0)const;
float GetFloatProp(const std::string&prop,size_t index=0)const;
std::string GetStringProp(const std::string&prop,size_t index=0)const;
int GetInt(const std::string&prop,size_t index=0)const;
float GetFloat(const std::string&prop,size_t index=0)const;
std::string GetString(const std::string&prop,size_t index=0)const;
const uint32_t PropCount(const std::string&prop)const;
};

@ -46,11 +46,11 @@ void ItemInfo::InitializeScripts(){
ITEM_SCRIPTS["Restore"]=[](AiL*game,std::optional<vf2d>targetingPos,ItemProps props){
for(const auto&[propName,buffType]:NameToBuffType){
int restoreAmt=props.GetIntProp(propName);
int restoreAmt=props.GetInt(propName);
game->GetPlayer()->AddBuff(BuffRestorationType::ONE_OFF,NameToBuffType.at(propName),0.01f,float(restoreAmt),0.0f);
if(restoreAmt>0&&props.PropCount(propName)==3){
game->GetPlayer()->AddBuff(BuffRestorationType::OVER_TIME,NameToBuffType.at(propName),props.GetFloatProp(propName,2),float(restoreAmt),props.GetFloatProp(propName,1));
game->GetPlayer()->AddBuff(BuffRestorationType::OVER_TIME,NameToBuffType.at(propName),props.GetFloat(propName,2),float(restoreAmt),props.GetFloat(propName,1));
}
}
return true;
@ -64,28 +64,36 @@ void ItemInfo::InitializeScripts(){
ITEM_SCRIPTS["Buff"]=[](AiL*game,std::optional<vf2d>targetingPos,ItemProps props){
for(auto&[key,value]:ItemAttribute::attributes){
float intensity=props.GetFloatProp(key,0);
float intensity=props.GetFloat(key,0);
if(intensity==0.f)continue;
if(ItemAttribute::Get(key).DisplayAsPercent())intensity/=100;
game->GetPlayer()->AddBuff(BuffType::STAT_UP,props.GetFloatProp(key,1),intensity,{ItemAttribute::Get(key)});
game->GetPlayer()->AddBuff(BuffType::STAT_UP,props.GetFloat(key,1),intensity,{ItemAttribute::Get(key)});
}
return true;
};
ITEM_SCRIPTS["RestoreDuringCast"]=[](AiL*game,std::optional<vf2d>targetingPos,ItemProps props){
for(const auto&[propName,buffType]:NameToBuffType){
int restoreAmt=props.GetIntProp(propName);
int restoreAmt=props.GetInt(propName);
game->GetPlayer()->AddBuff(BuffRestorationType::ONE_OFF,NameToBuffType.at(propName),0.01f,float(restoreAmt),0.0f);
if(restoreAmt>0&&props.PropCount(propName)==3){
game->GetPlayer()->AddBuff(BuffRestorationType::OVER_TIME_DURING_CAST,NameToBuffType.at(propName),props.GetFloatProp(propName,2),float(restoreAmt),props.GetFloatProp(propName,1));
game->GetPlayer()->AddBuff(BuffRestorationType::OVER_TIME_DURING_CAST,NameToBuffType.at(propName),props.GetFloat(propName,2),float(restoreAmt),props.GetFloat(propName,1));
}
}
return true;
};
ITEM_SCRIPTS["Projectile"]=[](AiL*game,std::optional<vf2d>targetingPos,ItemProps props){
const int projectileDamage{props.GetIntProp("Base Damage")+int(game->GetPlayer()->GetAttack()*props.GetFloatProp("Player Damage Mult"))};
CreateBullet(ThrownProjectile)(game->GetPlayer()->GetPos(),targetingPos.value(),props.GetStringProp("Image"),props.GetFloatProp("Cast Size")/100.f*24,game->GetPlayer()->GetZ(),0.3f,8.f,projectileDamage,game->GetPlayer()->OnUpperLevel(),false,INFINITE,true,WHITE,props.GetFloatProp("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.GetFloatProp("Cast Size")/100.f*vf2d{1.f,1.f}},props.GetStringProp("Explode Sound Effect"))EndBullet;
const int projectileDamage{props.GetInt("Base Damage")+int(game->GetPlayer()->GetAttack()*props.GetFloat("Player Damage Mult"))};
std::optional<LingeringEffect>lingeringEffect{};
if(props.GetFloat("Linger Time")>0.f){
const int damage{props.GetInt("Tick Base Damage")+int(props.GetFloat("Tick Player Damage Mult")*game->GetPlayer()->GetAttack())};
lingeringEffect.emplace(vf2d{},props.GetString("Lingering Effect"),props.GetString("Lingering Sound"),props.GetFloat("Linger Radius")/100.f*24,damage,props.GetFloat("Tick Rate"),HurtType::MONSTER,props.GetFloat("Linger Time"),5.f,game->GetPlayer()->OnUpperLevel(),1.f,vf2d{},DARK_RED,util::random(2*PI),0.f,false,0.2f,
[](const Effect&self){
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,
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;
};

@ -41,6 +41,7 @@ All rights reserved.
template<class T>
class Oscillator{
friend class ThrownProjectile;
public:
inline Oscillator()
:Oscillator({},{},0.f){}

@ -63,7 +63,7 @@ void PoisonBottle::OnGroundLand(){
game->AddEffect(std::make_unique<Effect>(pos+vf2d{util::random(16)*poisonCircleScale,util::random(2*PI)}.cart(),util::random_range(1.f,4.f),"circle.png",game->GetPlayer()->OnUpperLevel(),vf2d{size,size},util::random_range(0.2f,0.5f),vf2d{util::random_range(-6.f,6.f),util::random_range(-12.f,-4.f)},col));
}
if(additionalBounceCount==0&&game->GetPlayer()->HasEnchant("Pooling Poison")){
game->AddEffect(std::make_unique<PoisonPool>(pos,"poison_pool.png",bounceExplodeRadius,game->GetPlayer()->GetAttack()*"Pooling Poison"_ENC["POISON POOL DAMAGE PCT"]/100.f,"Pooling Poison"_ENC["POISON POOL DAMAGE FREQUENCY"],friendly?HurtType::MONSTER:HurtType::PLAYER,"Pooling Poison"_ENC["SPLASH LINGER TIME"],0.5f,OnUpperLevel(),poisonCircleScale,vf2d{},WHITE,0.f,0.f,false,0.05f,[pos=pos,col=col,poisonCircleScale](const Effect&self){
game->AddEffect(std::make_unique<LingeringEffect>(pos,"poison_pool.png","Poison Pool",bounceExplodeRadius,game->GetPlayer()->GetAttack()*"Pooling Poison"_ENC["POISON POOL DAMAGE PCT"]/100.f,"Pooling Poison"_ENC["POISON POOL DAMAGE FREQUENCY"],friendly?HurtType::MONSTER:HurtType::PLAYER,"Pooling Poison"_ENC["SPLASH LINGER TIME"],0.5f,OnUpperLevel(),poisonCircleScale,vf2d{},WHITE,0.f,0.f,false,0.05f,[pos=pos,col=col,poisonCircleScale](const Effect&self){
float size{util::random_range(0.4f,0.8f)};
return Effect{pos+vf2d{util::random(16)*poisonCircleScale,util::random(2*PI)}.cart(),util::random_range(1.f,4.f),"circle.png",game->GetPlayer()->OnUpperLevel(),vf2d{size,size},util::random_range(0.2f,0.5f),vf2d{util::random_range(-6.f,6.f),util::random_range(-12.f,-4.f)},col};
}),true);

@ -42,10 +42,10 @@ All rights reserved.
INCLUDE_game
PoisonPool::PoisonPool(vf2d pos,const std::string&img,float radius,int damage,float damageFreq,const HurtType friendly,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending,float particleSpawnFreq,const std::function<Effect(const Effect&self)>&particleGenerator)
:damage(damage),damageTimer(damageFreq),originalDamageTimer(damageTimer),radius(radius),friendly(friendly),poisonPoolSFXID(SoundEffect::PlayLoopingSFX("Poison Pool",pos)),FadeInOutEffect(pos,img,lifetime,cycleSpd,onUpperLevel,size,spd,col,rotation,rotationSpd,additiveBlending,particleSpawnFreq,particleGenerator){}
LingeringEffect::LingeringEffect(vf2d pos,const std::string&img,const std::string&soundEffect,float radius,int damage,float damageFreq,const HurtType friendly,float lifetime,float cycleSpd,bool onUpperLevel,float size,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending,float particleSpawnFreq,const std::function<Effect(const Effect&self)>&particleGenerator)
:damage(damage),damageTimer(damageFreq),originalDamageTimer(damageTimer),radius(radius),friendly(friendly),sfxID(SoundEffect::PlayLoopingSFX(soundEffect,pos)),FadeInOutEffect(pos,img,lifetime,cycleSpd,onUpperLevel,size,spd,col,rotation,rotationSpd,additiveBlending,particleSpawnFreq,particleGenerator){}
bool PoisonPool::Update(float fElapsedTime){
bool LingeringEffect::Update(float fElapsedTime){
damageTimer-=fElapsedTime;
if(damageTimer<=0.f){
game->Hurt(pos,radius,damage,OnUpperLevel(),GetZ(),friendly,HurtFlag::DOT);
@ -53,7 +53,7 @@ bool PoisonPool::Update(float fElapsedTime){
}
if(FadeInOutEffect::Update(fElapsedTime))return true;
else{
SoundEffect::StopLoopingSFX(poisonPoolSFXID);
SoundEffect::StopLoopingSFX(sfxID);
return false;
}
}

@ -44,8 +44,8 @@ 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)
: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){
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)
: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;
}
@ -56,6 +56,13 @@ void ThrownProjectile::OnGroundLand(){
explosionEffect.pos+=pos;
}
if(explodeSoundEffect)SoundEffect::PlaySFX(explodeSoundEffect.value(),pos);
if(lingeringEffect){
LingeringEffect&lingerEffect{dynamic_cast<LingeringEffect&>(game->AddEffect(std::make_unique<LingeringEffect>(lingeringEffect.value())))};
lingerEffect.posOscillator.val1+=pos;
lingerEffect.posOscillator.val2+=pos;
lingerEffect.pos+=pos;
}
vel={};
fadeOutTime=0.25f;
Deactivate();

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_PATCH 0
#define VERSION_BUILD 11748
#define VERSION_BUILD 11755
#define stringify(a) stringify_(a)
#define stringify_(a) #a

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 B

@ -64,6 +64,11 @@ Events
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
File[0] = burn.ogg, 70%
}
Burning Fire
{
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
File[0] = burning.ogg, 100%
}
Button Click
{
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)

@ -14,6 +14,7 @@ Images
GFX_Effect_GroundSlam_Front = ground-slam-attack-front.png
GFX_EnergyBolt = energy_bolt.png
GFX_EnergyParticle = energy_particle.png
GFX_FireRing = fire_ring.png
GFX_FireRing0 = fire_ring0.png
GFX_FireRing1 = fire_ring1.png
GFX_FireRing2 = fire_ring2.png
@ -139,6 +140,7 @@ Images
GFX_MusketBullet = musket_bullet.png
GFX_SandSuction = sand_suction.png
GFX_Bomb = bomb.png
GFX_Molotov = molotov.png
GFX_Thief_Sheet = nico-thief.png
GFX_Trapper_Sheet = nico-trapper.png

@ -223,7 +223,8 @@ ItemDatabase
Tick Base Damage = 10
Tick Player Damage Mult = 0.4x
Explode Sound Effect = Bomb Explode
Lingering Effect = pixel.png
Lingering Effect = fire_ring.png
Lingering Sound = Burning Fire
Linger Radius = 250
Linger Time = 4s
Cooldown Time = 5.0

@ -61,6 +61,7 @@ ItemScript
# Set a lingering time to have a damage over time effect.
Linger Time = 0s
Lingering Effect = pixel.png
Lingering Sound = Burning Fire
Linger Radius = 250
Tick Rate = 1s
Tick Base Damage = 10

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 699 B

After

Width:  |  Height:  |  Size: 726 B

Loading…
Cancel
Save