Add overlay sprite feature, extra animations for second boss.

pull/35/head
sigonasr2 10 months ago
parent afdb85e16f
commit 7a557fe5fc
  1. 1
      Adventures in Lestoria/Buff.h
  2. 32
      Adventures in Lestoria/Monster.cpp
  3. 5
      Adventures in Lestoria/Monster.h
  4. 2
      Adventures in Lestoria/Player.cpp
  5. 28
      Adventures in Lestoria/Ursule.cpp
  6. 2
      Adventures in Lestoria/Version.h
  7. 2
      Adventures in Lestoria/assets/Campaigns/Boss_1_v2.tmx
  8. 8
      Adventures in Lestoria/assets/config/MonsterStrategies.txt
  9. 1
      Adventures in Lestoria/assets/config/Monsters.txt
  10. 1
      Adventures in Lestoria/assets/config/gfx/gfx.txt
  11. BIN
      Adventures in Lestoria/assets/monsters/Ursule Mother of Bears2.png
  12. BIN
      Adventures in Lestoria/assets/monsters/Ursule, Mother of Bears.png
  13. BIN
      x64/Release/Adventures in Lestoria.exe

@ -48,6 +48,7 @@ enum BuffType{
RESTORATION_DURING_CAST,
LOCKON_SPEEDBOOST, //Specifically used for wolves.
SPEEDBOOST,
BARRIER_DAMAGE_REDUCTION, //Creates a visual barrier around the target
};
class AiL;

@ -303,7 +303,17 @@ void Monster::Draw(){
vf2d shadowScale=vf2d{8*GetSizeMult()/3.f,1}/std::max(1.f,GetZ()/24);
game->view.DrawDecal(GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6*GetSizeMult()},GFX["circle.png"].Decal(),shadowScale,BLACK);
}
game->view.DrawPartialRotatedDecal(GetPos()-vf2d{0,GetZ()},GetFrame().GetSourceImage()->Decal(),spriteRot,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult()*(GetFacingDirection()==RIGHT?-1:1),GetSizeMult()),GetBuffs(BuffType::SLOWDOWN).size()>0?Pixel{uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(128+127*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration)))}:WHITE);
Pixel blendCol=GetBuffs(BuffType::SLOWDOWN).size()>0?Pixel{uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(128+127*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration)))}:WHITE;
game->view.DrawPartialRotatedDecal(GetPos()-vf2d{0,GetZ()},GetFrame().GetSourceImage()->Decal(),spriteRot,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult()*(GetFacingDirection()==RIGHT?-1:1),GetSizeMult()),blendCol);
if(overlaySprite.length()!=0){
game->view.DrawPartialRotatedDecal(GetPos()-vf2d{0,GetZ()},GFX[overlaySprite].Decal(),spriteRot,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult()*(GetFacingDirection()==RIGHT?-1:1),GetSizeMult()),{blendCol.r,blendCol.g,blendCol.b,overlaySpriteTransparency});
}
std::vector<Buff>shieldBuffs=GetBuffs(BARRIER_DAMAGE_REDUCTION);
if(shieldBuffs.size()>0){
game->view.DrawRotatedDecal(GetPos()-vf2d{0,GetZ()},GFX["block.png"].Decal(),0.f,GFX["block.png"].Sprite()->Size()/2,{GetSizeMult(),GetSizeMult()});
}
#pragma region Debug Pathfinding
#ifdef _DEBUG
@ -439,9 +449,8 @@ bool Monster::Hurt(int damage,bool onUpperLevel,float z){
}
#pragma endregion
for(Buff&b:GetBuffs(BuffType::DAMAGE_REDUCTION)){
mod_dmg-=damage*b.intensity;
}
mod_dmg-=mod_dmg*GetDamageReductionFromBuffs();
mod_dmg=std::ceil(mod_dmg);
hp=std::max(0,hp-int(mod_dmg));
@ -567,9 +576,9 @@ void Monster::PathAroundBehavior(float fElapsedTime){
}
}
std::vector<Buff>Monster::GetBuffs(BuffType buff){
std::vector<Buff>Monster::GetBuffs(BuffType buff)const{
std::vector<Buff>filteredBuffs;
std::copy_if(buffList.begin(),buffList.end(),std::back_inserter(filteredBuffs),[buff](Buff&b){return b.type==buff;});
std::copy_if(buffList.begin(),buffList.end(),std::back_inserter(filteredBuffs),[buff](const Buff&b){return b.type==buff;});
return filteredBuffs;
}
@ -690,4 +699,15 @@ void Monster::RotateTowardsPos(const vf2d&targetPos){
}
}
#pragma endregion
}
const float Monster::GetDamageReductionFromBuffs()const{
float dmgReduction=0;
for(const Buff&b:GetBuffs(BuffType::DAMAGE_REDUCTION)){
dmgReduction+=b.intensity;
}
for(const Buff&b:GetBuffs(BuffType::BARRIER_DAMAGE_REDUCTION)){
dmgReduction+=b.intensity;
}
return std::min(1.0f,dmgReduction);
}

@ -159,7 +159,7 @@ public:
bool StartPathfinding(float pathingTime);
void PathAroundBehavior(float fElapsedTime);
void AddBuff(BuffType type,float duration,float intensity);
std::vector<Buff>GetBuffs(BuffType buff);
std::vector<Buff>GetBuffs(BuffType buff)const;
//Removes all buffs of a given type.
void RemoveBuff(BuffType type);
State::State GetState();
@ -184,6 +184,7 @@ public:
const std::string&GetName()const;
//Rotates this enemy's sprite towards a given location. Also flips it to face the correct direction.
void RotateTowardsPos(const vf2d&targetPos);
const float GetDamageReductionFromBuffs()const;
private:
std::string name;
vf2d pos;
@ -202,6 +203,8 @@ private:
Key facingDirection=DOWN;
std::string strategy;
State::State state=State::NORMAL;
std::string overlaySprite="";
uint8_t overlaySpriteTransparency=0U;
Animate2D::Animation<std::string>animation;
Animate2D::AnimationState internal_animState;
float randomFrameOffset=0.f;

@ -1085,7 +1085,6 @@ void Player::AddMoneyListener(std::weak_ptr<MenuComponent>component){
moneyListeners.push_back(component);
}
const float Player::GetDamageReductionFromBuffs()const{
float dmgReduction=0;
for(const Buff&b:GetBuffs(BuffType::DAMAGE_REDUCTION)){
@ -1094,6 +1093,7 @@ const float Player::GetDamageReductionFromBuffs()const{
dmgReduction+=GetDamageReductionPct();
return std::min(0.75f,dmgReduction);
};
const float Player::GetDamageReductionFromArmor()const{
float dmgReduction=0;
dmgReduction+=Stats::GetDamageReductionPct(GetStat("Defense"));

@ -55,27 +55,43 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy
switch(m.phase){
case 0:{
m.phase=ConfigInt("StartPhase");
m.overlaySprite=ConfigString("Overlay Sprite");
m.overlaySpriteTransparency=0U;
}break;
case 1:{ //Run bear strategy in phase 1.
auto TransitionToPhase2=[&](){
m.phase=2;
m.AddBuff(BARRIER_DAMAGE_REDUCTION,INFINITE,ConfigFloat("Phase 2.Barrier Damage Reduction")/100.f);
};
if(m.GetRemainingHPPct()<=ConfigFloat("Phase 2.Change")/100.f){
if(m.F(A::RUN_AWAY_TIMER)==0.f)m.F(A::RUN_AWAY_TIMER)=10.f;
else{
m.F(A::RUN_AWAY_TIMER)-=fElapsedTime;
if(m.F(A::RUN_AWAY_TIMER)==0.f)TransitionToPhase2();
}
//before moving to Phase 2, we need to make sure we're in Phase 0 of the bear AI.
//We also need to move to the center of the map.
if(m.I(A::PHASE)!=0.f)goto bear;
else{
float distToCenter=geom2d::line<float>(m.GetPos(),game->GetCurrentMap().MapData.MapSize*vf2d{float(game->GetCurrentMap().MapData.tilewidth),float(game->GetCurrentMap().MapData.tileheight)}).length();
/*if(){
vf2d mapCenter=game->GetCurrentMap().MapData.MapSize*vf2d{float(game->GetCurrentMap().MapData.tilewidth),float(game->GetCurrentMap().MapData.tileheight)}/2.0f;
float distToCenter=geom2d::line<float>(m.GetPos(),mapCenter).length();
if(distToCenter>4.0f){
m.targetAcquireTimer=20.f;
m.target=mapCenter;
RUN_TOWARDS(m,fElapsedTime,"Run Towards");
break;
}else{ //Now we're finally good for phase 2.
m.phase=2;
}*/
TransitionToPhase2();
}
}
}
bear:
BEAR(m,fElapsedTime,"Bear");
}break;
case 2:{
}break;
}
}

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

@ -269,7 +269,7 @@
</object>
<object id="4" name="Slime King" type="Monster" x="792" y="744">
<properties>
<property name="Type" propertytype="MonsterName" value="Slime King"/>
<property name="Type" propertytype="MonsterName" value="Ursule, Mother of Bears"/>
<property name="spawner" type="object" value="3"/>
</properties>
<point/>

@ -236,6 +236,9 @@ MonsterStrategy
# The maximum amount of time to spend trying to run to the center of the map.
Run To Center Max Time = 10.0s
# The overlay sprite to use for transitioning to later phases.
Overlay Sprite = monsters/Ursule Mother of Bears2.png
Wisp Pattern 0
{
Row[0] = .O...O..
@ -318,6 +321,11 @@ MonsterStrategy
Row[5] = ........
}
Phase 1
{
# Maximum amount of time the boss takes to run towards the center before giving up and continuing through Phase 2.
Run to Center Time = 10.0s
}
Phase 2
{
# Percentage of health to transition to Phase 2

@ -384,5 +384,6 @@ Monsters
# File name, Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
# NOTE: ANIMATION[0] will always be row 5 of an animation sheet, all numbers that follow are each below each other.
ANIMATION[0] = 4, 0.1, OneShot
ANIMATION[1] = 6, 0.15, OneShot
}
}

@ -62,6 +62,7 @@ Images
GFX_Button_Face_R2 = themes/button_r2.png
GFX_Overworld_Arrow = overworld_arrow.png
GFX_Exclamation = exclamation.png
GFX_Ursule2 = monsters/Ursule Mother of Bears2.png
# Ability Icons
GFX_Warrior_BattleCry_Icon = Ability Icons/battlecry.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Loading…
Cancel
Save