@ -50,19 +50,90 @@ void Monster::STRATEGY::SANDWORM(Monster&m,float fElapsedTime,std::string strate
enum PhaseName {
enum PhaseName {
INITIALIZE ,
INITIALIZE ,
UNDERGROUND ,
UNDERGROUND ,
SURFACING ,
ATTACK ,
SHOOTING ,
BURROWING ,
} ;
m . F ( A : : ATTACK_COOLDOWN ) - = fElapsedTime ;
m . F ( A : : SUCTION_TIMER ) - = fElapsedTime ;
const float distToPlayer { util : : distance ( game - > GetPlayer ( ) - > GetPos ( ) , m . GetPos ( ) ) } ;
if ( m . F ( A : : SUCTION_TIMER ) > 0.f & & distToPlayer < = ConfigPixels ( " Suction Radius " ) ) {
game - > GetPlayer ( ) - > AddVelocity ( util : : pointTo ( game - > GetPlayer ( ) - > GetPos ( ) , m . GetPos ( ) ) * 100.f * ConfigFloat ( " Suction Pull Amount " ) / 100.f ) ;
}
const auto AcquireNewUndergroundTarget = [ & ] ( ) {
const float randomRange = util : : random_range ( 0 , ConfigPixels ( " Burrow Target Range " ) ) ;
m . target = game - > GetPlayer ( ) - > GetPos ( ) + vf2d { randomRange , util : : random ( 2 * PI ) } . cart ( ) ;
} ;
} ;
switch ( PHASE ( ) ) {
switch ( PHASE ( ) ) {
case INITIALIZE : {
case INITIALIZE : {
SETPHASE ( UNDERGROUND ) ;
SETPHASE ( UNDERGROUND ) ;
const float randomRange = util : : random_range ( 0 , ConfigFloat ( " Burrow Target Range " ) / 100.f * 24 ) ;
AcquireNewUndergroundTarget ( ) ;
m . V ( A : : LOCKON_POS ) = game - > GetPlayer ( ) - > GetPos ( ) + vf2d { randomRange , util : : random ( 2 * PI ) } . cart ( ) ;
} break ;
} break ;
case UNDERGROUND : {
case UNDERGROUND : {
m . SetCollisionRadius ( 0.f ) ;
m . SetCollisionRadius ( 0.f ) ;
RUN_TOWARDS ( m , fElapsedTime , " Run Towards " ) ;
RUN_TOWARDS ( m , fElapsedTime , " Run Towards " ) ;
m . PerformAnimation ( " SWIM " , m . GetFacingDirection ( ) ) ;
m . PerformAnimation ( " SWIM " , m . GetFacingDirection ( ) ) ;
if ( m . ReachedTargetPos ( ) ) {
m . PerformAnimation ( " EMERGE " , game - > GetPlayer ( ) - > GetPos ( ) ) ;
m . F ( A : : RECOVERY_TIME ) = m . GetCurrentAnimation ( ) . GetTotalAnimationDuration ( ) ;
game - > AddEffect ( std : : make_unique < Effect > ( m . GetPos ( ) , ConfigInt ( " Suction Duration " ) , " sand_suction.png " , m . OnUpperLevel ( ) , 0.25f , 0.25f , ConfigFloat ( " Suction Animation Size " ) / 300.f * vf2d { 1.f , 1.f } , vf2d { } , WHITE , util : : random ( ) , - PI / 8 ) , true ) ;
SETPHASE ( SURFACING ) ;
m . F ( A : : SUCTION_TIMER ) = ConfigFloat ( " Suction Duration " ) + 0.25f ;
}
} break ;
case SURFACING : {
m . F ( A : : RECOVERY_TIME ) - = fElapsedTime ;
if ( m . F ( A : : RECOVERY_TIME ) < = 0.f ) {
SETPHASE ( ATTACK ) ;
m . PerformAnimation ( " IDLE " , game - > GetPlayer ( ) - > GetPos ( ) ) ;
m . SetCollisionRadius ( m . GetOriginalCollisionRadius ( ) ) ;
m . I ( A : : ATTACK_COUNT ) = ConfigInt ( " Max Attack Count " ) ;
}
} break ;
case ATTACK : {
if ( m . I ( A : : ATTACK_COUNT ) < = 0 | | distToPlayer > = ConfigPixels ( " Max Attack Range " ) ) {
m . SetCollisionRadius ( 0.f ) ;
m . PerformAnimation ( " BURROW " ) ;
m . F ( A : : CASTING_TIMER ) = m . GetCurrentAnimation ( ) . GetTotalAnimationDuration ( ) ;
SETPHASE ( BURROWING ) ;
break ;
}
if ( m . F ( A : : ATTACK_COOLDOWN ) < = 0.f ) {
m . PerformAnimation ( " SAND ATTACK " , game - > GetPlayer ( ) - > GetPos ( ) ) ;
m . F ( A : : CASTING_TIMER ) = ConfigFloat ( " Shoot Delay " ) ;
m . F ( A : : SHOOT_ANIMATION_TIME ) = m . GetCurrentAnimation ( ) . GetTotalAnimationDuration ( ) ;
m . B ( A : : BULLET_HAS_BEEN_SHOT ) = false ;
SETPHASE ( SHOOTING ) ;
}
} break ;
case SHOOTING : {
const auto ShootBullet = [ & ] ( ) {
m . B ( A : : BULLET_HAS_BEEN_SHOT ) = true ;
m . I ( A : : ATTACK_COUNT ) - - ;
CreateBullet ( Bullet ) ( m . GetPos ( ) , vf2d { ConfigPixels ( " Bullet Speed " ) , util : : angleTo ( m . GetPos ( ) , game - > GetPlayer ( ) - > GetPos ( ) ) } . cart ( ) , ConfigFloat ( " Bullet Radius " ) , m . GetAttack ( ) , m . OnUpperLevel ( ) , false , ConfigPixel ( " Bullet Color " ) , ConfigFloat ( " Bullet Radius " ) * vf2d { 1.f , 1.f } / 2.f ) EndBullet ;
} ;
m . F ( A : : CASTING_TIMER ) - = fElapsedTime ;
m . F ( A : : SHOOT_ANIMATION_TIME ) - = fElapsedTime ;
if ( m . F ( A : : CASTING_TIMER ) < = 0.f & & ! m . B ( A : : BULLET_HAS_BEEN_SHOT ) ) {
ShootBullet ( ) ;
}
if ( m . F ( A : : SHOOT_ANIMATION_TIME ) < = 0.f ) {
if ( ! m . B ( A : : BULLET_HAS_BEEN_SHOT ) ) ShootBullet ( ) ;
m . PerformAnimation ( " IDLE " , game - > GetPlayer ( ) - > GetPos ( ) ) ;
SETPHASE ( ATTACK ) ;
}
} break ;
case BURROWING : {
m . F ( A : : CASTING_TIMER ) - = fElapsedTime ;
if ( m . F ( A : : CASTING_TIMER ) < = 0.f ) {
AcquireNewUndergroundTarget ( ) ;
SETPHASE ( UNDERGROUND ) ;
}
} break ;
} break ;
}
}
}
}