Add visual indicator/graphics for Trapper Mark on targets. Added TriggerMark and ApplyMark helper functions. Release Build 10264.
This commit is contained in:
parent
a1eb109e70
commit
c3e7c62bd3
@ -403,7 +403,7 @@ namespace MonsterTests
|
||||
|
||||
Assert::AreEqual(0,testMonster.GetMarkStacks(),L"Monster has 0 marks initially.");
|
||||
|
||||
testMonster.AddBuff(BuffType::TRAPPER_MARK,7.f,5); //Apply 5 marks of Trapper Mark.
|
||||
testMonster.ApplyMark(7.f,5U);
|
||||
|
||||
Assert::AreEqual(5,testMonster.GetMarkStacks(),L"Monster has 5 marks after receiving a buff.");
|
||||
|
||||
@ -438,6 +438,11 @@ namespace MonsterTests
|
||||
|
||||
Assert::AreEqual(1,testMonster.GetMarkStacks(),L"Monster should have 1 mark remaining after using TriggerMark function");
|
||||
Assert::AreEqual(24,testMonster.GetHealth(),L"Monster should not take damage from the TriggerMark function (Mark deals 6 damage though).");
|
||||
|
||||
game->SetElapsedTime(10.f);
|
||||
testMonster.Update(10.f);
|
||||
|
||||
Assert::AreEqual(0,testMonster.GetMarkStacks(),L"The marks should have expired after 10 seconds.");
|
||||
}
|
||||
};
|
||||
}
|
@ -332,6 +332,15 @@ void sig::Animation::InitializeAnimations(){
|
||||
ANIMATION_DATA[std::format("GOBLIN_BOW_ATTACK_{}",animationIndex)]=mountShootAnimation;
|
||||
}
|
||||
|
||||
#pragma region Trapper Target Mark Debuff
|
||||
AnimationData targetAnimData{.frameDuration{0.1f},.style{Animate2D::Style::Repeat}};
|
||||
Animate2D::FrameSequence targetAnim(targetAnimData.frameDuration,targetAnimData.style);
|
||||
targetAnim.AddFrame({&GFX["target.png"],{{int(0*24),0},{24,24}}});
|
||||
targetAnim.AddFrame({&GFX["target.png"],{{int(0*24),0},{24,24}}});
|
||||
targetAnim.AddFrame({&GFX["target.png"],{{int(1*24),0},{24,24}}});
|
||||
ANIMATION_DATA["target.png"]=targetAnim;
|
||||
#pragma endregion
|
||||
|
||||
for(auto&dat:GFX){
|
||||
std::string imgFile=dat.first;
|
||||
if(!ANIMATION_DATA.count(imgFile)){
|
||||
|
@ -265,8 +265,10 @@ bool Monster::Update(float fElapsedTime){
|
||||
monsterHurtSoundCooldown=std::max(0.f,monsterHurtSoundCooldown-fElapsedTime);
|
||||
lastHitPlayer=std::max(0.f,lastHitPlayer-fElapsedTime);
|
||||
lastPathfindingCooldown=std::max(0.f,lastPathfindingCooldown-fElapsedTime);
|
||||
markApplicationTimer=std::max(0.f,markApplicationTimer-fElapsedTime);
|
||||
lastFacingDirectionChange+=fElapsedTime;
|
||||
timeSpentAlive+=fElapsedTime;
|
||||
|
||||
if(IsSolid()){
|
||||
if(GetPos().y>=game->GetPlayer()->GetPos().y)solidFadeTimer=std::min(TileGroup::FADE_TIME,solidFadeTimer+game->GetElapsedTime());
|
||||
else solidFadeTimer=std::max(0.f,solidFadeTimer-game->GetElapsedTime());
|
||||
@ -467,9 +469,29 @@ void Monster::Draw()const{
|
||||
|
||||
std::vector<Buff>shieldBuffs=GetBuffs(BARRIER_DAMAGE_REDUCTION);
|
||||
if(shieldBuffs.size()>0){
|
||||
game->view.DrawRotatedDecal(drawPos,GFX["block.png"].Decal(),0.f,GFX["block.png"].Sprite()->Size()/2,{GetSizeMult(),GetSizeMult()});
|
||||
game->view.DrawRotatedDecal(drawPos,GFX["block.png"].Decal(),0.f,GFX["block.png"].Sprite()->Size()/2,{GetSizeMult(),GetSizeMult()},blendCol);
|
||||
}
|
||||
|
||||
#pragma region Render Trapper Marked Targets
|
||||
const uint8_t markStackCount{GetMarkStacks()};
|
||||
if(markStackCount>0){
|
||||
float markRotation{-util::lerp(0.f,10.f,markApplicationTimer/0.5f)*sin(PI*markApplicationTimer)};
|
||||
vf2d markScale{vf2d{}.lerp(vf2d{GetSizeMult(),GetSizeMult()},(0.5f-markApplicationTimer)/0.5f)};
|
||||
const Animate2D::Frame&markImg{ANIMATION_DATA["target.png"].GetFrame(game->GetRunTime())};
|
||||
Pixel markCol{markStackCount>1?WHITE:RED};
|
||||
const std::vector<Buff>&buffList{GetBuffs(BuffType::TRAPPER_MARK)};
|
||||
float remainingStackDuration{};
|
||||
for(const Buff&b:buffList){
|
||||
if(b.type==BuffType::TRAPPER_MARK){
|
||||
remainingStackDuration=b.duration;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(remainingStackDuration<1.f)markCol.a*=remainingStackDuration;
|
||||
game->view.DrawPartialRotatedDecal(drawPos,markImg.GetSourceImage()->Decal(),markRotation,markImg.GetSourceRect().size/2.f,markImg.GetSourceRect().pos,markImg.GetSourceRect().size,markScale,markCol);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
if(GameSettings::TerrainCollisionBoxesEnabled()&&IsSolid()&&solidFadeTimer>0.f){
|
||||
float distToPlayer=geom2d::line<float>(game->GetPlayer()->GetPos(),GetPos()).length();
|
||||
const float collisionRadiusFactor=GetCollisionRadius()/12.f;
|
||||
@ -1201,7 +1223,7 @@ const std::optional<geom2d::rect<float>>&Monster::GetRectangleCollision()const{
|
||||
return MONSTER_DATA.at(GetName()).GetRectangleCollision();
|
||||
}
|
||||
|
||||
const int Monster::GetMarkStacks()const{
|
||||
const uint8_t Monster::GetMarkStacks()const{
|
||||
const std::vector<Buff>&markBuffs{GetBuffs(BuffType::TRAPPER_MARK)};
|
||||
int stackCount{};
|
||||
for(const Buff&b:markBuffs){
|
||||
@ -1212,14 +1234,30 @@ const int Monster::GetMarkStacks()const{
|
||||
|
||||
void Monster::RemoveMarkStack(){
|
||||
if(GetMarkStacks()<=0)ERR("WARNING! Tried to remove a mark stack, but no stacks exist. THIS SHOULD NOT BE HAPPENING!");
|
||||
bool removeMarkDebuff{false};
|
||||
for(Buff&b:buffList){
|
||||
if(b.type==BuffType::TRAPPER_MARK&&b.intensity>0){
|
||||
b.intensity--;
|
||||
if(b.intensity==0)removeMarkDebuff=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(removeMarkDebuff)RemoveBuff(BuffType::TRAPPER_MARK);
|
||||
}
|
||||
|
||||
void Monster::TriggerMark(){
|
||||
Hurt(0,OnUpperLevel(),GetZ(),HurtFlag::PLAYER_ABILITY);
|
||||
}
|
||||
|
||||
void Monster::ApplyMark(float time,uint8_t stackCount){
|
||||
if(GetMarkStacks()>0){
|
||||
for(Buff&b:buffList){
|
||||
if(b.type==BuffType::TRAPPER_MARK){
|
||||
b.intensity+=stackCount;
|
||||
b.duration=std::max(b.duration,time);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else AddBuff(BuffType::TRAPPER_MARK,time,stackCount);
|
||||
markApplicationTimer=0.5f;
|
||||
}
|
@ -199,8 +199,9 @@ public:
|
||||
const float GetModdedStatBonuses(std::string_view stat)const;
|
||||
//The collision rectangle is only used currently for determining the safe spots for the stone golem boss fight.
|
||||
const std::optional<geom2d::rect<float>>&GetRectangleCollision()const;
|
||||
const int GetMarkStacks()const; //Number of Trapper marks on this target.
|
||||
const uint8_t GetMarkStacks()const; //Number of Trapper marks on this target.
|
||||
void TriggerMark(); //Deals no damage, but causes a mark proc to occur.
|
||||
void ApplyMark(float time,uint8_t stackCount); //Adds stackCount mark stacks to the target, refreshing the buff to time time.
|
||||
private:
|
||||
//NOTE: Marking a monster for deletion does not trigger any death events. It just simply removes the monster from the field!!
|
||||
// The way this works is that monsters marked for deletion will cause the monster update loop to detect there's at least one or more monsters that must be deleted and will call erase_if on the list at the end of the iteration loop.
|
||||
@ -283,6 +284,7 @@ private:
|
||||
float solidFadeTimer{0.f};
|
||||
bool _Hurt(int damage,bool onUpperLevel,float z,const TrueDamageFlag damageRule,HurtFlag::HurtFlag hurtFlags);
|
||||
void RemoveMarkStack();
|
||||
float markApplicationTimer{}; //Used for animations involving the mark being applied to the target.
|
||||
private:
|
||||
struct STRATEGY{
|
||||
static std::string ERR;
|
||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 3
|
||||
#define VERSION_BUILD 10262
|
||||
#define VERSION_BUILD 10264
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
@ -109,6 +109,7 @@ Images
|
||||
GFX_LargeRock = large_rock.png
|
||||
GFX_Dagger = dagger.png
|
||||
GFX_Shine = shine.png
|
||||
GFX_TargetMark = target.png
|
||||
|
||||
GFX_Thief_Sheet = nico-thief.png
|
||||
GFX_Trapper_Sheet = nico-trapper.png
|
||||
|
Binary file not shown.
BIN
Adventures in Lestoria/assets/target.png
Normal file
BIN
Adventures in Lestoria/assets/target.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 695 B |
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user