@ -82,6 +82,8 @@ Monster::Monster(vf2d pos,MonsterData data,bool upperLevel,bool bossMob):
monsterWalkSoundTimer = util : : random ( 1.f ) ;
UpdateFacingDirection ( game - > GetPlayer ( ) - > GetPos ( ) ) ;
animation . UpdateState ( internal_animState , randomFrameOffset ) ;
const vf2d & currentRect { GetFrame ( ) . GetSourceRect ( ) . size } ;
afterImage . Create ( currentRect . x , currentRect . y ) ;
}
const vf2d & Monster : : GetPos ( ) const {
return pos ;
@ -406,6 +408,29 @@ void Monster::Update(const float fElapsedTime){
animation . UpdateState ( internal_animState , fElapsedTime ) ;
if ( HasMountedMonster ( ) ) mounted_animation . value ( ) . UpdateState ( internal_mounted_animState , fElapsedTime ) ;
attackedByPlayer = false ;
# pragma region Afterimage Handling
const auto RemoveScanLine = [ & ] ( uint8_t scanLine ) {
for ( int x : std : : ranges : : iota_view ( 0 , afterImage . Sprite ( ) - > width ) ) {
afterImage . Sprite ( ) - > SetPixel ( { x , scanLine } , BLANK ) ;
}
afterImage . Decal ( ) - > Update ( ) ;
} ;
//Scan Line goes through 1-(height-1) (odd numbers) first, then 0-22.
const bool ScanLineFinished { scanLine = = afterImage . Sprite ( ) - > height } ;
if ( ! ScanLineFinished ) {
removeLineTimer - = fElapsedTime ;
if ( removeLineTimer < = 0.f ) {
removeLineTimer = TIME_BETWEEN_LINE_REMOVALS ;
RemoveScanLine ( scanLine ) ;
scanLine + = 2 ;
if ( scanLine > afterImage . Sprite ( ) - > height - 1 & & scanLine % 2 = = 1 ) {
scanLine = 0 ;
}
}
}
# pragma endregion
}
Direction Monster : : GetFacingDirection ( ) const {
return facingDirection ;
@ -512,6 +537,7 @@ void Monster::Draw()const{
} ;
if ( glowPurpleBuff . has_value ( ) ) DrawBaseMonster ( glowPurpleImageScale , { 43 , 0 , 66 , blendCol . a } ) ;
DrawAfterImage : game - > view . DrawRotatedDecal ( afterImagePos , afterImage . Decal ( ) , 0.f , afterImage . Sprite ( ) - > Size ( ) / 2 , { GetSizeMult ( ) , GetSizeMult ( ) } , Pixel { 0xFFDCDA } ) ;
DrawBaseMonster ( imageScale , blendCol ) ;
if ( overlaySprite . length ( ) ! = 0 ) {
if ( glowPurpleBuff . has_value ( ) ) DrawOverlayMonster ( imageScale , { 43 , 0 , 66 , overlaySpriteTransparency } ) ;
@ -574,8 +600,8 @@ void Monster::Draw()const{
# 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 ;
const 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 ) ;
@ -1677,3 +1703,12 @@ void Monster::ForceSetPos(vf2d pos){
this - > pos = pos ;
Moved ( ) ;
}
void Monster : : SetupAfterImage ( ) {
game - > SetDrawTarget ( afterImage . Sprite ( ) ) ;
game - > Clear ( BLANK ) ;
game - > DrawPartialSprite ( { } , animation . GetFrame ( internal_animState ) . GetSourceImage ( ) - > Sprite ( ) , animation . GetFrame ( internal_animState ) . GetSourceRect ( ) . pos , animation . GetFrame ( internal_animState ) . GetSourceRect ( ) . size , 1U , 0U , { 255 , 255 , 254 } ) ; //Off-white so that the sprite is rendered completely in white.
game - > SetDrawTarget ( nullptr ) ;
afterImage . Decal ( ) - > Update ( ) ;
removeLineTimer = TIME_BETWEEN_LINE_REMOVALS ;
scanLine = 1U ;
}