@ -267,7 +267,7 @@ bool Monster::SetY(float y){
return _SetY ( y ) ;
}
bool Monster : : Update ( float fElapsedTime ) {
void Monster : : Update ( const 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 ) ;
@ -280,6 +280,14 @@ bool Monster::Update(float fElapsedTime){
lastFacingDirectionChange + = fElapsedTime ;
timeSpentAlive + = fElapsedTime ;
if ( IsUnconscious ( ) ) {
unconsciousTimer = std : : max ( 0.f , unconsciousTimer - fElapsedTime ) ;
if ( unconsciousTimer = = 0.f ) {
Heal ( GetMaxHealth ( ) ) ;
}
}
if ( IsSolid ( ) & & FadeoutWhenStandingBehind ( ) ) {
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 ( ) ) ;
@ -394,17 +402,9 @@ bool Monster::Update(float fElapsedTime){
}
if ( ! game - > TestingModeEnabled ( ) & & CanMove ( ) ) Monster : : STRATEGY : : RUN_STRATEGY ( * this , fElapsedTime ) ;
}
if ( ! IsAlive ( ) ) {
deathTimer + = fElapsedTime ;
if ( deathTimer > 3 ) {
return false ;
}
}
animation . UpdateState ( internal_animState , randomFrameOffset + fElapsedTime ) ;
if ( HasMountedMonster ( ) ) mounted_animation . value ( ) . UpdateState ( internal_mounted_animState , fElapsedTime ) ;
randomFrameOffset = 0 ;
attackedByPlayer = false ;
return true ;
}
Direction Monster : : GetFacingDirection ( ) const {
return facingDirection ;
@ -636,6 +636,8 @@ void Monster::DrawReflection(float drawRatioX,float multiplierX){
} ;
}
if ( IsUnconscious ( ) & & animation . HasState ( MONSTER_DATA . at ( name ) . GetDefaultDeathAnimation ( ) ) ) animation . ChangeState ( internal_animState , GetDeathAnimationName ( ) ) ;
game - > view . DrawPartialWarpedDecal ( GetFrame ( ) . GetSourceImage ( ) - > Decal ( ) , points , GetFrame ( ) . GetSourceRect ( ) . pos , GetFrame ( ) . GetSourceRect ( ) . size ) ;
game - > SetDecalMode ( DecalMode : : NORMAL ) ;
}
@ -1144,21 +1146,21 @@ void Monster::OnDeath(){
}
if ( game - > GetPlayer ( ) - > HasEnchant ( " Curse of Doom " ) & & accumulatedCurseOfDeathDamage > 0 ) {
# pragma region Go Boom
float radius { " Curse of Doom " _ENC [ " EXPLODE RANGE " ] / 100.f * 24 } ;
const HurtList list { game - > Hurt ( pos , radius , accumulatedCurseOfDeathDamage , OnUpperLevel ( ) , GetZ ( ) , HurtType : : MONSTER , HurtFlag : : PLAYER_ABILITY ) } ;
for ( const auto & [ targetPtr , wasHit ] : list ) {
if ( wasHit ) {
std : : get < Monster * > ( targetPtr ) - > ProximityKnockback ( pos , " Curse of Doom " _ENC [ " EXPLODE KNOCKBACK AMOUNT " ] ) ;
std : : get < Monster * > ( targetPtr ) - > Knockup ( " Curse of Doom " _ENC [ " EXPLODE KNOCKUP AMOUNT " ] ) ;
float radius { " Curse of Doom " _ENC [ " EXPLODE RANGE " ] / 100.f * 24 } ;
const HurtList list { game - > Hurt ( pos , radius , accumulatedCurseOfDeathDamage , OnUpperLevel ( ) , GetZ ( ) , HurtType : : MONSTER , HurtFlag : : PLAYER_ABILITY ) } ;
for ( const auto & [ targetPtr , wasHit ] : list ) {
if ( wasHit ) {
std : : get < Monster * > ( targetPtr ) - > ProximityKnockback ( pos , " Curse of Doom " _ENC [ " EXPLODE KNOCKBACK AMOUNT " ] ) ;
std : : get < Monster * > ( targetPtr ) - > Knockup ( " Curse of Doom " _ENC [ " EXPLODE KNOCKUP AMOUNT " ] ) ;
}
}
}
float targetScale { radius / 24 } ;
float startingScale { GetCollisionRadius ( ) / 24 } ;
std : : unique_ptr < Effect > explodeEffect { std : : make_unique < Effect > ( pos , ANIMATION_DATA [ " explosionframes.png " ] . GetTotalAnimationDuration ( ) - 0.2f , " explosionframes.png " , OnUpperLevel ( ) , startingScale , 0.2f , vf2d { 0 , - 6.f } , WHITE , util : : random ( 2 * PI ) , 0.f ) } ;
explodeEffect - > scaleSpd = { ( targetScale - startingScale ) / ANIMATION_DATA [ " explosionframes.png " ] . GetTotalAnimationDuration ( ) , ( targetScale - startingScale ) / ANIMATION_DATA [ " explosionframes.png " ] . GetTotalAnimationDuration ( ) } ;
game - > AddEffect ( std : : move ( explodeEffect ) ) ;
SoundEffect : : PlaySFX ( " Explosion " , pos ) ;
float targetScale { radius / 24 } ;
float startingScale { GetCollisionRadius ( ) / 24 } ;
std : : unique_ptr < Effect > explodeEffect { std : : make_unique < Effect > ( pos , ANIMATION_DATA [ " explosionframes.png " ] . GetTotalAnimationDuration ( ) - 0.2f , " explosionframes.png " , OnUpperLevel ( ) , startingScale , 0.2f , vf2d { 0 , - 6.f } , WHITE , util : : random ( 2 * PI ) , 0.f ) } ;
explodeEffect - > scaleSpd = { ( targetScale - startingScale ) / ANIMATION_DATA [ " explosionframes.png " ] . GetTotalAnimationDuration ( ) , ( targetScale - startingScale ) / ANIMATION_DATA [ " explosionframes.png " ] . GetTotalAnimationDuration ( ) } ;
game - > AddEffect ( std : : move ( explodeEffect ) ) ;
SoundEffect : : PlaySFX ( " Explosion " , pos ) ;
# pragma endregion
}
@ -1354,7 +1356,7 @@ const bool Monster::Immovable()const{
return MONSTER_DATA . at ( GetName ( ) ) . Immovable ( ) ;
}
const bool Monster : : Invulnerable ( ) const {
return MONSTER_DATA . at ( GetName ( ) ) . Invulnerable ( ) ;
return MONSTER_DATA . at ( GetName ( ) ) . Invulnerable ( ) | | IsUnconscious ( ) ;
}
const std : : optional < float > Monster : : GetLifetime ( ) const {
return lifetime ;
@ -1644,3 +1646,9 @@ void Monster::MoveForward(const vf2d&moveForwardVec,const float fElapsedTime){
if ( moveForwardVec . mag ( ) = = 0.f ) ERR ( " WARNING! Passed a zero length vector into Move Forward! THIS IS NOT ALLOWED! " ) ;
SetPos ( pos + moveForwardVec . norm ( ) * 100.f * fElapsedTime * GetMoveSpdMult ( ) ) ;
}
const bool Monster : : IsUnconscious ( ) const {
return unconsciousTimer > 0.f ;
}
const float Monster : : UnconsciousTime ( ) const {
return MONSTER_DATA . at ( name ) . UnconsciousTime ( ) ;
}