Add monster jumping inside run towards monster strategy.

mac-build
sigonasr2, Sig, Sigo 9 months ago
parent 3e7b7ed06e
commit dc6d333e5b
  1. 1
      Adventures in Lestoria/MonsterAttribute.h
  2. 132
      Adventures in Lestoria/RunTowards.cpp
  3. 20
      Adventures in Lestoria/assets/config/MonsterStrategies.txt

@ -104,4 +104,5 @@ enum class Attribute{
ABILITY_COUNT,
DEFENSIVE_COUNT,
ITEM_USE_COUNT,
LAST_JUMP_TIMER,
};

@ -45,7 +45,11 @@ INCLUDE_game
INCLUDE_MONSTER_DATA
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.F(A::JUMP_LANDING_TIMER)=std::max(0.f,m.F(A::JUMP_LANDING_TIMER)-fElapsedTime);
if(m.targetAcquireTimer==0){
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){
m.UpdateFacingDirection(m.target);
}
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();
const auto StartJumpTowardsPlayer=[&](float jumpDuration,float recoveryTime,float jumpMoveSpd){
m.F(A::JUMP_ORIGINAL_LANDING_TIMER)=m.F(A::JUMP_LANDING_TIMER)=jumpDuration;
m.B(A::JUMP_TOWARDS_PLAYER)=true;
m.F(A::RECOVERY_TIME)=recoveryTime;
m.F(A::JUMP_MOVE_SPD)=jumpMoveSpd;
m.F(A::LAST_JUMP_TIMER)=ConfigFloat("JumpTimer");
m.SetState(State::JUMP);
};
switch(m.I(A::PHASE)){
case 0:{//Setup jump behaviors.
if(jumpingEnabled){
m.F(A::LAST_JUMP_TIMER)=ConfigFloat("JumpTimer");
}
m.I(A::PHASE)++;
}break;
case State::PATH_AROUND:{
m.PathAroundBehavior(fElapsedTime);
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.F(A::LAST_JUMP_TIMER)=std::max(0.f,m.F(A::LAST_JUMP_TIMER)-fElapsedTime);
if(m.F(A::LAST_JUMP_TIMER)==0.f){
StartJumpTowardsPlayer(ConfigFloat("JumpDelayTime"),ConfigFloat("JumpRecoveryTime",ConfigFloat("JumpMoveSpd")));
}
}
}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;
default:{
}
}
}

@ -44,6 +44,26 @@ MonsterStrategy
MaxDistance = 999999
# 1 of X chance to stop after bumping into something.
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
{

Loading…
Cancel
Save