Implement Slam Shock enchant. Add stun effect to monsters. Release Build 11079.

pull/65/head
sigonasr2 5 months ago
parent 2129f3a4ff
commit 9da3e946e3
  1. 26
      Adventures in Lestoria Tests/EnchantTests.cpp
  2. 19
      Adventures in Lestoria/Monster.cpp
  3. 3
      Adventures in Lestoria/Monster.h
  4. 1
      Adventures in Lestoria/Player.cpp
  5. 2
      Adventures in Lestoria/Version.h
  6. BIN
      x64/Release/Adventures in Lestoria.exe

@ -1104,5 +1104,31 @@ namespace EnchantTests
player->CheckAndPerformAbility(player->GetAbility1(),testKeyboardInput);
Assert::AreEqual(newMonster.GetHealth()-player->GetDefense(),newMonster.GetMaxHealth(),L"Monster takes damage from Battlecry with the Battle Shout enchant equal to 100% of the player's Defense.");
}
TEST_METHOD(SlamShockNoEnchantCheck){
testKey->bHeld=true; //Force the key to be held down for testing purposes.
Monster&newMonster{game->SpawnMonster({},MONSTER_DATA["TestName"])};
player->CheckAndPerformAbility(player->GetAbility2(),testKeyboardInput);
game->SetElapsedTime(2.f);
game->OnUserUpdate(2.f);
game->SetElapsedTime(0.f);
game->OnUserUpdate(0.f); //The next tick should cause the ground slam to occur.
Assert::IsTrue(newMonster.CanMove(),L"Monster should still be running its AI.");
}
TEST_METHOD(SlamShockEnchantCheck){
testKey->bHeld=true; //Force the key to be held down for testing purposes.
Monster&newMonster{game->SpawnMonster({},MONSTER_DATA["TestName"])};
std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)};
Inventory::EquipItem(nullRing,EquipSlot::RING1);
nullRing.lock()->EnchantItem("Slam Shock");
player->CheckAndPerformAbility(player->GetAbility2(),testKeyboardInput);
game->SetElapsedTime(2.f);
game->OnUserUpdate(2.f);
game->SetElapsedTime(0.f);
game->OnUserUpdate(0.f); //The next tick should cause the ground slam to occur.
Assert::IsFalse(newMonster.CanMove(),L"Monster should be stunned by Slam Shock enchant and unable to run its AI.");
game->SetElapsedTime(5.f);
game->OnUserUpdate(5.f);
Assert::IsTrue(newMonster.CanMove(),L"Monster should no longer be stunned.");
}
};
}

@ -263,6 +263,7 @@ bool Monster::Update(float fElapsedTime){
lastHitTimer=std::max(0.f,lastHitTimer-fElapsedTime);
lastDotTimer=std::max(0.f,lastDotTimer-fElapsedTime);
iframe_timer=std::max(0.f,iframe_timer-fElapsedTime);
stunTimer=std::max(0.f,stunTimer-fElapsedTime);
monsterHurtSoundCooldown=std::max(0.f,monsterHurtSoundCooldown-fElapsedTime);
lastHitPlayer=std::max(0.f,lastHitPlayer-fElapsedTime);
lastPathfindingCooldown=std::max(0.f,lastPathfindingCooldown-fElapsedTime);
@ -468,17 +469,16 @@ void Monster::Draw()const{
uint8_t blendColAlpha=blendCol.a;
if(fadeTimer>0.f)blendColAlpha=uint8_t(util::lerp(0,blendCol.a,fadeTimer)); //Fade timer goes from 1 to 0 seconds.
else
if(NotOnTitleScreen
else if(NotOnTitleScreen
&&(game->GetPlayer()->HasIframes()||OnUpperLevel()!=game->GetPlayer()->OnUpperLevel()||abs(GetZ()-game->GetPlayer()->GetZ())>1))blendColAlpha=blendCol.a*0.62f;
else
if(IsSolid()&&solidFadeTimer>0.f)blendColAlpha=uint8_t(util::lerp(blendCol.a,255-TileGroup::FADE_AMT,solidFadeTimer/TileGroup::FADE_TIME));
else if(IsSolid()&&solidFadeTimer>0.f)blendColAlpha=uint8_t(util::lerp(blendCol.a,255-TileGroup::FADE_AMT,solidFadeTimer/TileGroup::FADE_TIME));
blendCol.a=blendColAlpha;
const float finalSpriteRot=HasFourWaySprites()?0.f:spriteRot; //Prevent 4-way sprites from being rotated.
const vf2d imageScale{vf2d(GetSizeMult()*(!HasFourWaySprites()&&GetFacingDirection()==Direction::EAST?-1:1),GetSizeMult())};
vf2d imageScale{vf2d(GetSizeMult()*(!HasFourWaySprites()&&GetFacingDirection()==Direction::EAST?-1:1),GetSizeMult())};
if(GetRemainingStunDuration()>0.f)imageScale*=abs(sin(3*PI*game->GetRunTime()))*0.2f+0.8f;
const vf2d glowPurpleImageScale{imageScale*1.1f};
const auto DrawBaseMonster=[&](vf2d scale={1.f,1.f},Pixel col=WHITE){
@ -1473,7 +1473,7 @@ void Monster::AddBuff(BuffRestorationType type,BuffOverTimeType::BuffOverTimeTyp
}
const bool Monster::CanMove()const{
return knockUpTimer==0.f&&IsAlive();
return knockUpTimer==0.f&&IsAlive()&&stunTimer==0.f;
}
const std::weak_ptr<Monster>Monster::GetWeakPointer()const{
@ -1522,4 +1522,11 @@ const bool Monster::IsBackstabAttack()const{
}
ERR("WARNING! An unhandled case was detected while trying to determine if an attack was a backstab attack! THIS SHOULD NOT BE HAPPENING!");
return false;
}
void Monster::Stun(const float stunDuration){
stunTimer=std::max(stunTimer,stunDuration);
}
const float&Monster::GetRemainingStunDuration()const{
return stunTimer;
}

@ -218,6 +218,8 @@ public:
Buff&EditBuff(BuffType buff,size_t buffInd);
std::vector<std::reference_wrapper<Buff>>EditBuffs(BuffType buff);
const bool IsBackstabAttack()const;
void Stun(const float stunDuration);
const float&GetRemainingStunDuration()const;
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.
@ -306,6 +308,7 @@ private:
void SetWeakPointer(std::shared_ptr<Monster>&sharedMonsterPtr);
std::weak_ptr<Monster>weakPtr;
void LongLastingMarkEffect(float&out_markDuration); //Modifies a given duration.
float stunTimer{};
private:
struct STRATEGY{
static std::string ERR;

@ -481,6 +481,7 @@ void Player::Update(float fElapsedTime){
Monster*monsterPtr=std::get<Monster*>(targetPtr);
float knockbackDir=0;
float knockbackAmt=0;
if(HasEnchant("Slam Shock"))monsterPtr->Stun("Slam Shock"_ENC["STUN DURATION"]);
if(geom2d::line<float>(GetPos(),monsterPtr->GetPos()).length()<=0.001f){
knockbackDir=util::random(2*PI);
knockbackAmt="Warrior.Ability 2.KnockbackAmt"_F;

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 2
#define VERSION_PATCH 3
#define VERSION_BUILD 11075
#define VERSION_BUILD 11079
#define stringify(a) stringify_(a)
#define stringify_(a) #a

Loading…
Cancel
Save