@ -51,6 +51,7 @@ All rights reserved.
# ifndef __EMSCRIPTEN__
# include "steam/isteamuserstats.h"
# endif
# include "GameSettings.h"
INCLUDE_ANIMATION_DATA
INCLUDE_MONSTER_DATA
@ -265,6 +266,10 @@ bool Monster::Update(float fElapsedTime){
lastPathfindingCooldown = std : : max ( 0.f , lastPathfindingCooldown - 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 ( ) ) ;
}
if ( HasArrowIndicator ( ) & & IsAlive ( ) ) game - > SetBossIndicatorPos ( GetPos ( ) ) ;
@ -330,8 +335,10 @@ bool Monster::Update(float fElapsedTime){
}
if ( ! HasIframes ( ) ) {
for ( std : : unique_ptr < Monster > & m : MONSTER_LIST ) {
const float monsterRadius { GetCollisionRadius ( ) } ;
const float otherMonsterRadius { m - > GetCollisionRadius ( ) } ;
if ( & * m = = this ) continue ;
if ( ! m - > HasIframes ( ) & & OnUpperLevel ( ) = = m - > OnUpperLevel ( ) & & abs ( m - > GetZ ( ) - GetZ ( ) ) < = 1 & & geom2d : : overlaps ( geom2d : : circle ( pos , GetCollisionRadius ( ) ) , geom2d : : circle ( m - > GetPos ( ) , m - > GetCollisionRadius ( ) ) ) ) {
if ( ! m - > HasIframes ( ) & & OnUpperLevel ( ) = = m - > OnUpperLevel ( ) & & abs ( m - > GetZ ( ) - GetZ ( ) ) < = 1 & & geom2d : : overlaps ( geom2d : : circle ( pos , monsterRadius ) , geom2d : : circle ( m - > GetPos ( ) , otherMonsterRadius ) ) ) {
m - > Collision ( * this ) ;
geom2d : : line line ( pos , m - > GetPos ( ) ) ;
float dist = line . length ( ) ;
@ -339,24 +346,21 @@ bool Monster::Update(float fElapsedTime){
line = { pos + vf2d { util : : random ( 0.2f ) - 0.1f , util : : random ( 0.2f ) - 0.1f } , m - > GetPos ( ) } ;
dist = line . length ( ) ;
}
m - > SetPos ( line . rpoint ( dist * 1.1f ) ) ;
if ( ! Immovable ( ) & & m - > IsAlive ( ) ) {
float knockbackStrength = 1.f ;
std : : vector < Buff > knockbackBuffs = m - > GetBuffs ( COLLISION_KNOCKBACK_STRENGTH ) ;
for ( Buff & b : knockbackBuffs ) {
knockbackStrength + = b . intensity ;
const float displacementDist = ( otherMonsterRadius + monsterRadius ) - dist ;
if ( m - > IsAlive ( ) ) {
if ( ! m - > IsSolid ( ) ) {
float knockbackStrength = 1.f ;
std : : vector < Buff > knockbackBuffs = m - > GetBuffs ( COLLISION_KNOCKBACK_STRENGTH ) ;
for ( Buff & b : knockbackBuffs ) {
knockbackStrength + = b . intensity ;
}
Knockback ( line . vector ( ) . norm ( ) * - 128 * knockbackStrength ) ;
} else {
SetPos ( line . rpoint ( - displacementDist ) ) ;
}
Knockback ( line . vector ( ) . norm ( ) * - 128 * knockbackStrength ) ;
}
}
}
if ( ! Immovable ( ) & &
! game - > GetPlayer ( ) - > HasIframes ( ) & & abs ( game - > GetPlayer ( ) - > GetZ ( ) - GetZ ( ) ) < = 1 & & game - > GetPlayer ( ) - > OnUpperLevel ( ) = = OnUpperLevel ( ) & & geom2d : : overlaps ( geom2d : : circle ( pos , GetCollisionRadius ( ) ) , geom2d : : circle ( game - > GetPlayer ( ) - > GetPos ( ) , 12 * game - > GetPlayer ( ) - > GetSizeMult ( ) / 2 ) ) ) {
geom2d : : line line ( pos , game - > GetPlayer ( ) - > GetPos ( ) ) ;
float dist = line . length ( ) ;
SetPos ( line . rpoint ( - 0.1f ) ) ;
vel = line . vector ( ) . norm ( ) * - 128 ;
}
}
if ( GetState ( ) = = State : : NORMAL ) {
UpdateFacingDirection ( game - > GetPlayer ( ) - > GetPos ( ) ) ;
@ -439,12 +443,14 @@ void Monster::Draw()const{
}
const bool NotOnTitleScreen = GameState : : STATE ! = GameState : : states [ States : : MAIN_MENU ] ;
uint8_t blendColAlpha = 255U ;
if ( NotOnTitleScreen
& & ( game - > GetPlayer ( ) - > HasIframes ( ) | | OnUpperLevel ( ) ! = game - > GetPlayer ( ) - > OnUpperLevel ( ) | | abs ( GetZ ( ) - game - > GetPlayer ( ) - > GetZ ( ) ) > 1 ) ) blendColAlpha = 160 ;
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
& & ( 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 ) ) ;
blendCol . a = blendColAlpha ;
@ -458,6 +464,17 @@ void Monster::Draw()const{
if ( shieldBuffs . size ( ) > 0 ) {
game - > view . DrawRotatedDecal ( drawPos , GFX [ " block.png " ] . Decal ( ) , 0.f , GFX [ " block.png " ] . Sprite ( ) - > Size ( ) / 2 , { GetSizeMult ( ) , GetSizeMult ( ) } ) ;
}
if ( GameSettings : : TerrainCollisionBoxesEnabled ( ) & & IsSolid ( ) & & solidFadeTimer > 0.f ) {
float distToPlayer = geom2d : : line < float > ( game - > GetPlayer ( ) - > GetPos ( ) , GetPos ( ) ) . length ( ) ;
const float collisionRadiusFactor = GetCollisionRadius ( ) / 12.f ;
if ( distToPlayer < 24 * 3 * collisionRadiusFactor ) {
game - > DrawPie ( game - > view . WorldToScreen ( GetPos ( ) ) , GetCollisionRadius ( ) , 0.f , { 255 , 0 , 0 , uint8_t ( 128 * ( blendColAlpha / 255.f ) / sqrt ( distToPlayer * collisionRadiusFactor ) ) } ) ;
game - > SetDecalMode ( DecalMode : : WIREFRAME ) ;
game - > DrawPie ( game - > view . WorldToScreen ( GetPos ( ) ) , GetCollisionRadius ( ) , 0.f , { 128 , 0 , 0 , 255 } ) ;
game - > SetDecalMode ( DecalMode : : NORMAL ) ;
}
}
# pragma region Debug Pathfinding
# ifdef _DEBUG
@ -1090,4 +1107,8 @@ const bool Monster::ReachedTargetPos(const float maxDistanceFromTarget)const{
const float Monster : : GetHealthRatio ( ) const {
return GetHealth ( ) / float ( GetMaxHealth ( ) ) ;
}
const bool Monster : : IsSolid ( ) const {
return Immovable ( ) ;
}