Add monster jumping inside run towards monster strategy.
This commit is contained in:
parent
3e7b7ed06e
commit
dc6d333e5b
@ -104,4 +104,5 @@ enum class Attribute{
|
|||||||
ABILITY_COUNT,
|
ABILITY_COUNT,
|
||||||
DEFENSIVE_COUNT,
|
DEFENSIVE_COUNT,
|
||||||
ITEM_USE_COUNT,
|
ITEM_USE_COUNT,
|
||||||
|
LAST_JUMP_TIMER,
|
||||||
};
|
};
|
@ -45,7 +45,11 @@ INCLUDE_game
|
|||||||
INCLUDE_MONSTER_DATA
|
INCLUDE_MONSTER_DATA
|
||||||
|
|
||||||
void Monster::STRATEGY::RUN_TOWARDS(Monster&m,float fElapsedTime,std::string strategy){
|
void Monster::STRATEGY::RUN_TOWARDS(Monster&m,float fElapsedTime,std::string strategy){
|
||||||
|
const bool jumpingEnabled=ConfigFloat("JumpTimer")<0.f;
|
||||||
|
|
||||||
m.targetAcquireTimer=std::max(0.f,m.targetAcquireTimer-fElapsedTime);
|
m.targetAcquireTimer=std::max(0.f,m.targetAcquireTimer-fElapsedTime);
|
||||||
|
m.F(A::JUMP_LANDING_TIMER)=std::max(0.f,m.F(A::JUMP_LANDING_TIMER)-fElapsedTime);
|
||||||
|
|
||||||
if(m.targetAcquireTimer==0){
|
if(m.targetAcquireTimer==0){
|
||||||
m.targetAcquireTimer=ConfigFloat("WaitTime");
|
m.targetAcquireTimer=ConfigFloat("WaitTime");
|
||||||
|
|
||||||
@ -61,31 +65,113 @@ void Monster::STRATEGY::RUN_TOWARDS(Monster&m,float fElapsedTime,std::string str
|
|||||||
if(geom2d::line(m.pos,m.target).length()>4.f){
|
if(geom2d::line(m.pos,m.target).length()>4.f){
|
||||||
m.UpdateFacingDirection(m.target);
|
m.UpdateFacingDirection(m.target);
|
||||||
}
|
}
|
||||||
switch(m.state){
|
|
||||||
case State::MOVE_TOWARDS:{
|
const auto StartJumpTowardsPlayer=[&](float jumpDuration,float recoveryTime,float jumpMoveSpd){
|
||||||
if(geom2d::line(m.pos,m.target).length()>100*fElapsedTime*m.GetMoveSpdMult()){
|
m.F(A::JUMP_ORIGINAL_LANDING_TIMER)=m.F(A::JUMP_LANDING_TIMER)=jumpDuration;
|
||||||
vf2d newPos=m.pos+geom2d::line(m.pos,m.target).vector().norm()*100*fElapsedTime*m.GetMoveSpdMult();
|
m.B(A::JUMP_TOWARDS_PLAYER)=true;
|
||||||
m.SetPos(newPos);
|
m.F(A::RECOVERY_TIME)=recoveryTime;
|
||||||
if(m.GetPos()!=newPos){
|
m.F(A::JUMP_MOVE_SPD)=jumpMoveSpd;
|
||||||
bool pathFound=m.StartPathfinding(4);
|
m.F(A::LAST_JUMP_TIMER)=ConfigFloat("JumpTimer");
|
||||||
if(!pathFound){
|
m.SetState(State::JUMP);
|
||||||
m.SetState(State::MOVE_TOWARDS);
|
};
|
||||||
//Choose a random position around us and move towards it.
|
|
||||||
float randomAngle=util::random(2*PI);
|
switch(m.I(A::PHASE)){
|
||||||
float randomDist=util::random(24*6);
|
case 0:{//Setup jump behaviors.
|
||||||
m.target=m.GetPos()+vf2d{sin(randomAngle),cos(randomAngle)}*randomDist;
|
if(jumpingEnabled){
|
||||||
|
m.F(A::LAST_JUMP_TIMER)=ConfigFloat("JumpTimer");
|
||||||
|
}
|
||||||
|
|
||||||
|
m.I(A::PHASE)++;
|
||||||
|
}break;
|
||||||
|
case 1:{//Main behaviors.
|
||||||
|
switch(m.state){
|
||||||
|
case State::MOVE_TOWARDS:{
|
||||||
|
if(geom2d::line(m.pos,m.target).length()>100*fElapsedTime*m.GetMoveSpdMult()){
|
||||||
|
vf2d newPos=m.pos+geom2d::line(m.pos,m.target).vector().norm()*100*fElapsedTime*m.GetMoveSpdMult();
|
||||||
|
m.SetPos(newPos);
|
||||||
|
if(m.GetPos()!=newPos){
|
||||||
|
bool pathFound=m.StartPathfinding(4);
|
||||||
|
if(!pathFound){
|
||||||
|
m.SetState(State::MOVE_TOWARDS);
|
||||||
|
//Choose a random position around us and move towards it.
|
||||||
|
float randomAngle=util::random(2*PI);
|
||||||
|
float randomDist=util::random(24*6);
|
||||||
|
m.target=m.GetPos()+vf2d{sin(randomAngle),cos(randomAngle)}*randomDist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.PerformJumpAnimation();
|
||||||
|
} else {
|
||||||
|
m.SetState(State::NORMAL);//Revert state once we've finished moving towards target.
|
||||||
|
m.PerformIdleAnimation();
|
||||||
}
|
}
|
||||||
}
|
if(jumpingEnabled){
|
||||||
m.PerformJumpAnimation();
|
m.F(A::LAST_JUMP_TIMER)=std::max(0.f,m.F(A::LAST_JUMP_TIMER)-fElapsedTime);
|
||||||
} else {
|
if(m.F(A::LAST_JUMP_TIMER)==0.f){
|
||||||
m.SetState(State::NORMAL);//Revert state once we've finished moving towards target.
|
StartJumpTowardsPlayer(ConfigFloat("JumpDelayTime"),ConfigFloat("JumpRecoveryTime",ConfigFloat("JumpMoveSpd")));
|
||||||
m.PerformIdleAnimation();
|
}
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case State::PATH_AROUND:{
|
||||||
|
m.PathAroundBehavior(fElapsedTime);
|
||||||
|
}break;
|
||||||
|
case State::JUMP:{
|
||||||
|
float jumpLandingTimerRatio=m.F(A::JUMP_LANDING_TIMER)/m.F(A::JUMP_ORIGINAL_LANDING_TIMER);
|
||||||
|
vf2d jumpTargetPos=m.V(A::JUMP_TARGET_POS);
|
||||||
|
if(m.B(A::JUMP_TOWARDS_PLAYER)){
|
||||||
|
jumpTargetPos=game->GetPlayer()->GetPos();
|
||||||
|
}
|
||||||
|
if(m.GetPos().x>jumpTargetPos.x){
|
||||||
|
m.SetX(std::max(jumpTargetPos.x,m.GetPos().x-m.F(A::JUMP_MOVE_SPD)*game->GetElapsedTime()));
|
||||||
|
} else
|
||||||
|
if(m.GetPos().x<jumpTargetPos.x){
|
||||||
|
m.SetX(std::min(jumpTargetPos.x,m.GetPos().x+m.F(A::JUMP_MOVE_SPD)*game->GetElapsedTime()));
|
||||||
|
}
|
||||||
|
if(m.GetPos().y>jumpTargetPos.y){
|
||||||
|
m.SetY(std::max(jumpTargetPos.y,m.GetPos().y-m.F(A::JUMP_MOVE_SPD)*game->GetElapsedTime()));
|
||||||
|
} else
|
||||||
|
if(m.GetPos().y<jumpTargetPos.y){
|
||||||
|
m.SetY(std::min(jumpTargetPos.y,m.GetPos().y+m.F(A::JUMP_MOVE_SPD)*game->GetElapsedTime()));
|
||||||
|
}
|
||||||
|
if(m.F(A::JUMP_LANDING_TIMER)>=m.F(A::JUMP_ORIGINAL_LANDING_TIMER)/2){
|
||||||
|
m.SetZ(util::lerp(0,float(ConfigInt("JumpHeight")),1-jumpLandingTimerRatio));
|
||||||
|
}else{
|
||||||
|
m.SetZ(util::lerp(0,float(ConfigInt("JumpHeight")),jumpLandingTimerRatio*2));
|
||||||
|
}
|
||||||
|
if(m.F(A::JUMP_LANDING_TIMER)==0){
|
||||||
|
m.state=State::RECOVERY;
|
||||||
|
game->SetupWorldShake(0.6f);
|
||||||
|
geom2d::line<float>lineToPlayer(m.GetPos(),game->GetPlayer()->GetPos());
|
||||||
|
float dist=lineToPlayer.length();
|
||||||
|
for(int i=0;i<200;i++){
|
||||||
|
float randomDir=util::random(2*PI);
|
||||||
|
game->AddEffect(std::make_unique<FallingDebris>(m.GetPos()+vf2d{cos(randomDir),sin(randomDir)}*m.GetSizeMult()*8,util::random(1),"circle.png",m.OnUpperLevel(),vf2d{1,1},0.5,vf2d{cos(randomDir)*util::random(5),sin(randomDir)*-util::random(15)-5}*30,BLACK),true);
|
||||||
|
}
|
||||||
|
if(dist<12*m.GetSizeMult()){
|
||||||
|
int jumpDamage=0;
|
||||||
|
if(ConfigInt("JumpAttackDamage")>0)jumpDamage=ConfigInt("JumpAttackDamage");
|
||||||
|
game->GetPlayer()->Hurt(jumpDamage,m.OnUpperLevel(),m.GetZ());
|
||||||
|
if(dist<0.001){
|
||||||
|
float randomDir=util::random(2*PI);
|
||||||
|
lineToPlayer={m.GetPos(),m.GetPos()+vf2d{cos(randomDir),sin(randomDir)}*1};
|
||||||
|
}
|
||||||
|
game->GetPlayer()->Knockback(lineToPlayer.vector().norm()*float(ConfigInt("JumpKnockbackFactor")));
|
||||||
|
if(m.phase!=2){ //In phase 2, the player can get slammed multiple times. No iframes for messing up.
|
||||||
|
game->GetPlayer()->SetIframes(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.SetZ(0);
|
||||||
|
Landed(m.phase);
|
||||||
|
m.SetStrategyDrawFunction([](AiL*game,Monster&m,const std::string&strategy){});
|
||||||
|
} else
|
||||||
|
if(m.F(A::JUMP_LANDING_TIMER)<=ConfigFloat("JumpWarningIndicatorTime")){
|
||||||
|
m.SetStrategyDrawFunction([](AiL*game,Monster&m,const std::string&strategy){
|
||||||
|
Decal*dec=GFX["range_indicator.png"].Decal();
|
||||||
|
game->view.DrawRotatedDecal(m.GetPos(),dec,0,dec->sprite->Size()/2,vf2d{m.GetSizeMult(),m.GetSizeMult()},RED);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
default:{}
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
case State::PATH_AROUND:{
|
|
||||||
m.PathAroundBehavior(fElapsedTime);
|
|
||||||
}break;
|
|
||||||
default:{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -44,6 +44,26 @@ MonsterStrategy
|
|||||||
MaxDistance = 999999
|
MaxDistance = 999999
|
||||||
# 1 of X chance to stop after bumping into something.
|
# 1 of X chance to stop after bumping into something.
|
||||||
BumpStopChance = 5
|
BumpStopChance = 5
|
||||||
|
|
||||||
|
# How long to wait before deciding to perform a Jump. Set to -1 to disable jumping.
|
||||||
|
JumpTimer = -1.0
|
||||||
|
# How much damage the jump attack does. Uses the monster's attack stat if set to -1.
|
||||||
|
JumpAttackDamage = -1
|
||||||
|
# How far the player gets knocked back if hit.
|
||||||
|
JumpKnockbackFactor = 0.0
|
||||||
|
# How fast to move during a jump attack.
|
||||||
|
JumpMoveSpd = 100
|
||||||
|
# How long the monster is in the air for.
|
||||||
|
JumpDelayTime = 1.2
|
||||||
|
# How long the monster waits after landing.
|
||||||
|
JumpRecoveryTime = 2.0
|
||||||
|
# How much time a jump will be pre-telegraphed.
|
||||||
|
JumpWarningIndicatorTime = 1.0
|
||||||
|
# Distance to jump up into the sky. A higher value causes it to launch up and down seemingly faster.
|
||||||
|
JumpHeight = 750
|
||||||
|
# Maximum distance the player can be away from the enemy for a jump to occur.
|
||||||
|
MaxPlayerJumpEngageDistance = 900
|
||||||
|
|
||||||
}
|
}
|
||||||
Shoot Afar
|
Shoot Afar
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user