@ -113,7 +113,7 @@ void Monster::PerformShootAnimation(){
void Monster : : PerformIdleAnimation ( ) {
animation . ChangeState ( internal_animState , MONSTER_DATA [ name ] . GetIdleAnimation ( ) ) ;
}
bool Monster : : SetX ( float x ) {
bool Monster : : _ SetX( float x , const bool monsterInvoked ) {
vf2d newPos = { x , pos . y } ;
vi2d tilePos = vi2d ( newPos / float ( game - > GetCurrentMapData ( ) . tilewidth ) ) * game - > GetCurrentMapData ( ) . tilewidth ;
geom2d : : rect < float > collisionRect = game - > GetTileCollision ( game - > GetCurrentLevel ( ) , newPos , upperLevel ) ;
@ -123,16 +123,27 @@ bool Monster::SetX(float x){
return true ;
} else {
geom2d : : rect < float > collision = { collisionRect . pos , collisionRect . size } ;
# pragma region lambdas
auto NoEnemyCollisionWithTile = [ & ] ( ) { return ! geom2d : : overlaps ( geom2d : : circle < float > ( newPos , game - > GetCurrentMapData ( ) . tilewidth / 2 * GetSizeMult ( ) ) , collision ) ; } ;
# pragma endregion
collision . pos + = tilePos ;
if ( ! geom2d : : overlaps ( geom2d : : circle < float > ( newPos , 12 * GetSizeMult ( ) ) , collision ) ) {
if ( NoEnemyCollisionWithTile ( ) ) {
pos . x = std : : clamp ( x , game - > GetCurrentMapData ( ) . tilewidth / 2.f * GetSizeMult ( ) , float ( game - > GetCurrentMapData ( ) . width * game - > GetCurrentMapData ( ) . tilewidth - game - > GetCurrentMapData ( ) . tilewidth / 2.f * GetSizeMult ( ) ) ) ;
Moved ( ) ;
return true ;
} else
if ( monsterInvoked ) { //If player invoked, we'll try the smart move system.
vf2d pushDir = geom2d : : line < float > ( collision . middle ( ) , pos ) . vector ( ) . norm ( ) ;
newPos = { newPos . x , pos . y + pushDir . y * 12 } ;
if ( NoEnemyCollisionWithTile ( ) ) {
return _SetY ( pos . y + pushDir . y , false ) ;
}
}
}
return false ;
}
bool Monster : : SetY ( float y ) {
bool Monster : : _SetY ( float y , const bool monsterInvoked ) {
vf2d newPos = { pos . x , y } ;
vi2d tilePos = vi2d ( newPos / float ( game - > GetCurrentMapData ( ) . tilewidth ) ) * game - > GetCurrentMapData ( ) . tilewidth ;
geom2d : : rect < float > collisionRect = game - > GetTileCollision ( game - > GetCurrentLevel ( ) , newPos , upperLevel ) ;
@ -142,19 +153,39 @@ bool Monster::SetY(float y){
return true ;
} else {
geom2d : : rect < float > collision = { collisionRect . pos , collisionRect . size } ;
# pragma region lambdas
auto NoEnemyCollisionWithTile = [ & ] ( ) { return ! geom2d : : overlaps ( geom2d : : circle < float > ( newPos , game - > GetCurrentMapData ( ) . tilewidth / 2 * GetSizeMult ( ) ) , collision ) ; } ;
# pragma endregion
collision . pos + = tilePos ;
if ( ! geom2d : : overlaps ( geom2d : : circle < float > ( newPos , game - > GetCurrentMapData ( ) . tilewidth / 2 * GetSizeMult ( ) ) , collision ) ) {
if ( NoEnemyCollisionWithTile ( ) ) {
pos . y = std : : clamp ( y , game - > GetCurrentMapData ( ) . tilewidth / 2.f * GetSizeMult ( ) , float ( game - > GetCurrentMapData ( ) . height * game - > GetCurrentMapData ( ) . tilewidth - game - > GetCurrentMapData ( ) . tilewidth / 2.f * GetSizeMult ( ) ) ) ;
Moved ( ) ;
return true ;
} else
if ( monsterInvoked ) { //If player invoked, we'll try the smart move system.{
vf2d pushDir = geom2d : : line < float > ( collision . middle ( ) , pos ) . vector ( ) . norm ( ) ;
newPos = { pos . x + pushDir . x * 12 , newPos . y } ;
if ( NoEnemyCollisionWithTile ( ) ) {
return _SetX ( pos . x + pushDir . x , false ) ;
}
}
}
return false ;
}
bool Monster : : SetX ( float x ) {
return _SetX ( x ) ;
}
bool Monster : : SetY ( float y ) {
return _SetY ( y ) ;
}
bool Monster : : Update ( float fElapsedTime ) {
lastHitTimer = std : : max ( 0.f , lastHitTimer - fElapsedTime ) ;
iframe_timer = std : : max ( 0.f , iframe_timer - fElapsedTime ) ;
monsterHurtSoundCooldown = std : : max ( 0.f , monsterHurtSoundCooldown - fElapsedTime ) ;
lastHitPlayer = std : : max ( 0.f , lastHitPlayer - fElapsedTime ) ;
if ( size ! = targetSize ) {
if ( size > targetSize ) {
@ -270,9 +301,9 @@ void Monster::DrawReflection(float drawRatioX,float multiplierX){
game - > SetDecalMode ( DecalMode : : NORMAL ) ;
}
void Monster : : Collision ( Player * p ) {
if ( MONSTER_DATA [ name ] . GetCollisionDmg ( ) > 0 & & ! hasHitPlayer ) {
if ( MONSTER_DATA [ name ] . GetCollisionDmg ( ) > 0 & & lastHitPlayer = = 0.0f ) {
if ( p - > Hurt ( MONSTER_DATA [ name ] . GetCollisionDmg ( ) , OnUpperLevel ( ) , GetZ ( ) ) ) {
hasHitPlayer = true ;
lastHitPlayer = 1.0f ;
}
}
Collision ( ) ;
@ -419,7 +450,7 @@ void Monster::AddBuff(BuffType type,float duration,float intensity){
buffList . push_back ( Buff { type , duration , intensity } ) ;
}
void Monster : : StartPathfinding ( float pathingTime ) {
bool Monster : : StartPathfinding ( float pathingTime ) {
SetState ( State : : PATH_AROUND ) ;
path = game - > pathfinder . Solve_WalkPath ( pos , target , 12 , OnUpperLevel ( ) ) ;
if ( path . points . size ( ) > 0 ) {
@ -427,6 +458,7 @@ void Monster::StartPathfinding(float pathingTime){
//We gives this mob 5 seconds to figure out a path to the target.
targetAcquireTimer = pathingTime ;
}
return path . points . size ( ) > 0 ;
}
void Monster : : PathAroundBehavior ( float fElapsedTime ) {
@ -434,7 +466,12 @@ void Monster::PathAroundBehavior(float fElapsedTime){
//Move towards the new path.
geom2d : : line moveTowardsLine = geom2d : : line ( pos , path . GetSplinePoint ( pathIndex ) . pos ) ;
if ( moveTowardsLine . length ( ) > 2 ) {
SetPos ( pos + moveTowardsLine . vector ( ) . norm ( ) * 100 * fElapsedTime * GetMoveSpdMult ( ) ) ;
if ( ! SetPos ( pos + moveTowardsLine . vector ( ) . norm ( ) * 100 * fElapsedTime * GetMoveSpdMult ( ) ) ) {
//We are stuck, so stop pathfinding.
path . points . clear ( ) ;
pathIndex = 0 ;
targetAcquireTimer = 0 ;
}
if ( moveTowardsLine . vector ( ) . x > 0 ) {
facingDirection = RIGHT ;
} else {