|
|
@ -47,5 +47,72 @@ using A=Attribute; |
|
|
|
INCLUDE_game |
|
|
|
INCLUDE_game |
|
|
|
|
|
|
|
|
|
|
|
void Monster::STRATEGY::CRAB(Monster&m,float fElapsedTime,std::string strategy){ |
|
|
|
void Monster::STRATEGY::CRAB(Monster&m,float fElapsedTime,std::string strategy){ |
|
|
|
|
|
|
|
enum PhaseName{ |
|
|
|
|
|
|
|
INIT, |
|
|
|
|
|
|
|
MOVE, |
|
|
|
|
|
|
|
PREPARE_CHARGE, |
|
|
|
|
|
|
|
CHARGE, |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch(PHASE()){ |
|
|
|
|
|
|
|
case INIT:{ |
|
|
|
|
|
|
|
m.B(A::RANDOM_DIRECTION)=util::random()%2; |
|
|
|
|
|
|
|
m.F(A::RANDOM_RANGE)=util::random_range(ConfigPixelsArr("Random Direction Range",0),ConfigPixelsArr("Random Direction Range",1)); |
|
|
|
|
|
|
|
SETPHASE(MOVE); |
|
|
|
|
|
|
|
}break;
|
|
|
|
|
|
|
|
case MOVE:{ |
|
|
|
|
|
|
|
m.F(A::ATTACK_COOLDOWN)+=fElapsedTime; |
|
|
|
|
|
|
|
m.F(A::LAST_JUMP_TIMER)+=fElapsedTime; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float distToPlayer=m.GetDistanceFrom(game->GetPlayer()->GetPos()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const bool outsideMaxShootingRange=distToPlayer>=ConfigPixelsArr("Stand Still and Shoot Range",1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(m.F(A::LAST_JUMP_TIMER)>=ConfigFloat("Stop Check Interval")){ |
|
|
|
|
|
|
|
if(util::random(100)<=ConfigFloat("Stop Percent")){ |
|
|
|
|
|
|
|
SETPHASE(PREPARE_CHARGE); |
|
|
|
|
|
|
|
m.PerformAnimation("CHARGEUP",m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos())); |
|
|
|
|
|
|
|
m.F(A::CASTING_TIMER)=ConfigFloat("Charge Wait Time"); |
|
|
|
|
|
|
|
m.target=game->GetPlayer()->GetPos()+util::distance(m.GetPos(),game->GetPlayer()->GetPos())*util::pointTo(m.GetPos(),game->GetPlayer()->GetPos()); |
|
|
|
|
|
|
|
}else |
|
|
|
|
|
|
|
if(util::random(100)<=ConfigFloat("Change Direction Chance"))m.B(A::RANDOM_DIRECTION)=!m.B(A::RANDOM_DIRECTION); |
|
|
|
|
|
|
|
m.F(A::LAST_JUMP_TIMER)=0.f; |
|
|
|
|
|
|
|
}else |
|
|
|
|
|
|
|
if(outsideMaxShootingRange){ |
|
|
|
|
|
|
|
m.target=game->GetPlayer()->GetPos(); |
|
|
|
|
|
|
|
RUN_TOWARDS(m,fElapsedTime,"Run Towards"); |
|
|
|
|
|
|
|
}else |
|
|
|
|
|
|
|
if(distToPlayer<ConfigPixels("Run Away Range")){ |
|
|
|
|
|
|
|
m.target=geom2d::line<float>(m.GetPos(),game->GetPlayer()->GetPos()).upoint(-1); |
|
|
|
|
|
|
|
RUN_TOWARDS(m,fElapsedTime,"Run Towards"); |
|
|
|
|
|
|
|
}else |
|
|
|
|
|
|
|
if(distToPlayer>=ConfigPixelsArr("Random Direction Range",0)&&distToPlayer<ConfigPixelsArr("Random Direction Range",1)){ |
|
|
|
|
|
|
|
#define CW true |
|
|
|
|
|
|
|
#define CCW false |
|
|
|
|
|
|
|
//We are going to walk in a circular direction either CW or CCW (determined in windup phase)
|
|
|
|
|
|
|
|
float dirFromPlayer=util::angleTo(game->GetPlayer()->GetPos(),m.GetPos()); |
|
|
|
|
|
|
|
float targetDir=m.B(A::RANDOM_DIRECTION)==CW?dirFromPlayer+PI/4:dirFromPlayer-PI/4; |
|
|
|
|
|
|
|
m.target=game->GetPlayer()->GetPos()+vf2d{m.F(A::RANDOM_RANGE),targetDir}.cart(); |
|
|
|
|
|
|
|
RUN_TOWARDS(m,fElapsedTime,"Run Towards");
|
|
|
|
|
|
|
|
m.F(A::CHASE_TIMER)=1.f; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case PREPARE_CHARGE:{ |
|
|
|
|
|
|
|
m.F(A::CASTING_TIMER)-=fElapsedTime; |
|
|
|
|
|
|
|
if(m.F(A::CASTING_TIMER)<=0.f){ |
|
|
|
|
|
|
|
SETPHASE(CHARGE); |
|
|
|
|
|
|
|
m.F(A::CHASE_TIMER)=ConfigFloat("Charge Max Time"); |
|
|
|
|
|
|
|
m.PerformAnimation("PINCER"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case CHARGE:{ |
|
|
|
|
|
|
|
m.F(A::CHASE_TIMER)-=fElapsedTime; |
|
|
|
|
|
|
|
RUN_TOWARDS(m,fElapsedTime,"Run Towards"); |
|
|
|
|
|
|
|
if(m.F(A::CHASE_TIMER)<=0.f||m.ReachedTargetPos()){ |
|
|
|
|
|
|
|
SETPHASE(MOVE); |
|
|
|
|
|
|
|
m.B(A::RANDOM_DIRECTION)=util::random()%2; |
|
|
|
|
|
|
|
m.F(A::RANDOM_RANGE)=util::random_range(ConfigPixelsArr("Random Direction Range",0),ConfigPixelsArr("Random Direction Range",1)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |