Add overlay sprite feature, extra animations for second boss.
This commit is contained in:
parent
afdb85e16f
commit
7a557fe5fc
@ -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 |
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user