diff --git a/Crawler/Animation.cpp b/Crawler/Animation.cpp index 87e7e747..0e0c8c58 100644 --- a/Crawler/Animation.cpp +++ b/Crawler/Animation.cpp @@ -206,6 +206,7 @@ void sig::Animation::InitializeAnimations(){ CreateStillAnimation(game->GFX_Arrow,{24,24},"ARROW"); CreateStillAnimation(game->GFX_ChargedArrow,{48,48},"CHARGED_ARROW"); CreateStillAnimation(game->GFX_Laser,{5,1},"LASER"); + CreateStillAnimation(game->GFX_RangeIndicator,{24,24},"RANGE_INDICATOR"); } void sig::Animation::SetupPlayerAnimations(){ diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index f4000d93..b6773ae1 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -116,6 +116,7 @@ bool Crawler::OnUserCreate(){ LOADIMG(GFX_Arrow) LOADIMG(GFX_Laser) LOADIMG(GFX_ChargedArrow) + LOADIMG(GFX_RangeIndicator) Monster::InitializeStrategies(); //Animations @@ -451,7 +452,7 @@ void Crawler::UpdateBullets(float fElapsedTime){ } else { b->pos+=b->vel*fElapsedTime; } - if(b->pos.x+b->radiuspos.x-b->radius>view.GetWorldBR().x||b->pos.y+b->radiuspos.y-b->radius>view.GetWorldBR().y){ + if(b->pos.x+b->radiuspos.x-b->radius>view.GetWorldBR().x+WINDOW_SIZE.x||b->pos.y+b->radiuspos.y-b->radius>view.GetWorldBR().y+WINDOW_SIZE.y){ b->dead=true; continue; } diff --git a/Crawler/Crawler.h b/Crawler/Crawler.h index 02d091f8..fea99f09 100644 --- a/Crawler/Crawler.h +++ b/Crawler/Crawler.h @@ -29,7 +29,7 @@ class Crawler : public olc::PixelGameEngine GFX_Splash_Effect,GFX_LightningBolt,GFX_LightningBoltParticle1, GFX_LightningBoltParticle2,GFX_LightningBoltParticle3,GFX_LightningBoltParticle4, GFX_ChainLightning,GFX_LightningSplash,GFX_Meteor,GFX_Arrow, - GFX_Laser,GFX_ChargedArrow; + GFX_Laser,GFX_ChargedArrow,GFX_RangeIndicator; public: Renderable GFX_BulletCircle,GFX_BulletCircleOutline,GFX_EnergyBolt,GFX_Circle; Pathfinding pathfinder; diff --git a/Crawler/Monster.cpp b/Crawler/Monster.cpp index e61300f2..a79baed0 100644 --- a/Crawler/Monster.cpp +++ b/Crawler/Monster.cpp @@ -129,11 +129,11 @@ bool Monster::Update(float fElapsedTime){ if(!HasIframes()){ for(Monster&m:MONSTER_LIST){ if(&m==this)continue; - if(!m.HasIframes()&&OnUpperLevel()==m.OnUpperLevel()&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){ + if(!m.HasIframes()&&OnUpperLevel()==m.OnUpperLevel()&&abs(m.GetZ()-GetZ())<=1&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){ m.Collision(*this); geom2d::line line(pos,m.GetPos()); float dist = line.length(); - m.SetPosition(line.rpoint(dist*1.1)); + m.SetPos(line.rpoint(dist*1.1)); if(m.IsAlive()){ vel=line.vector().norm()*-128; } @@ -142,7 +142,7 @@ bool Monster::Update(float fElapsedTime){ if(!game->GetPlayer()->HasIframes()&&game->GetPlayer()->OnUpperLevel()==OnUpperLevel()&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(game->GetPlayer()->GetPos(),12*game->GetPlayer()->GetSizeMult()/2))){ geom2d::line line(pos,game->GetPlayer()->GetPos()); float dist = line.length(); - SetPosition(line.rpoint(-0.1)); + SetPos(line.rpoint(-0.1)); vel=line.vector().norm()*-128; } } @@ -183,6 +183,7 @@ Key Monster::GetFacingDirection(){ return facingDirection; } void Monster::Draw(){ + strategyDraw(game); if(GetZ()>0){ vf2d shadowScale=vf2d{8*GetSizeMult()/3.f,1}/std::max(1.f,GetZ()/24); game->view.DrawDecal(GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6*GetSizeMult()},game->GFX_Circle.Decal(),shadowScale,BLACK); @@ -204,14 +205,14 @@ void Monster::Collision(Monster&m){ Collision(); } void Monster::Collision(){ - if(strategy==0&&GetState()==MOVE_TOWARDS){//The run towards strategy causes state to return to normal upon a collision. - SetState(NORMAL); + if(strategy==0&&GetState()==State::MOVE_TOWARDS){//The run towards strategy causes state to return to normal upon a collision. + SetState(State::NORMAL); } } void Monster::SetVelocity(vf2d vel){ this->vel=vel; } -bool Monster::SetPosition(vf2d pos){ +bool Monster::SetPos(vf2d pos){ bool resultX=SetX(pos.x); bool resultY=SetY(pos.y); if(resultY&&!resultX){ @@ -301,7 +302,7 @@ void Monster::AddBuff(BuffType type,float duration,float intensity){ } void Monster::StartPathfinding(float pathingTime){ - SetState(PATH_AROUND); + SetState(State::PATH_AROUND); path=game->pathfinder.Solve_AStar(pos,target,12,OnUpperLevel()); if(path.size()>0){ pathIndex=0; @@ -315,7 +316,7 @@ void Monster::PathAroundBehavior(float fElapsedTime){ //Move towards the new path. geom2d::line moveTowardsLine=geom2d::line(pos,path[pathIndex]*24); if(moveTowardsLine.length()>2){ - SetPosition(pos+moveTowardsLine.vector().norm()*100*fElapsedTime*GetMoveSpdMult()); + SetPos(pos+moveTowardsLine.vector().norm()*100*fElapsedTime*GetMoveSpdMult()); if(moveTowardsLine.vector().x>0){ facingDirection=RIGHT; } else { @@ -341,11 +342,11 @@ std::vectorMonster::GetBuffs(BuffType buff){ return filteredBuffs; } -State Monster::GetState(){ +State::State Monster::GetState(){ return state; } -void Monster::SetState(State newState){ +void Monster::SetState(State::State newState){ state=newState; } @@ -407,4 +408,19 @@ bool&Monster::GetBool(Attribute a){ attributes[a]=false; } return std::get(attributes[a]); +} + +vf2d&Monster::GetVf2d(Attribute a){ + if(attributes.count(a)==0){ + attributes[a]=vf2d{}; + } + return std::get(attributes[a]); +} + +void Monster::SetZ(float z){ + this->z=z; +} + +void Monster::SetStrategyDrawFunction(std::functionfunc){ + strategyDraw=func; } \ No newline at end of file diff --git a/Crawler/Monster.h b/Crawler/Monster.h index 49b73976..d80124d9 100644 --- a/Crawler/Monster.h +++ b/Crawler/Monster.h @@ -9,6 +9,7 @@ #include "MonsterAttribute.h" struct Player; +class Crawler; enum MonsterAnimation{ IDLE, @@ -72,7 +73,7 @@ private: float iframe_timer=0; Key facingDirection; int strategy; - State state=State::NORMAL; + State::State state=State::NORMAL; Animate2D::Animationanimation; Animate2D::AnimationState internal_animState; float randomFrameOffset=0.f; @@ -91,6 +92,7 @@ private: bool diesNormally=true; //If set to false, the monster death is handled in a special way. Set it to true when it's time to die. float targetSize=0; std::map>attributes; + std::functionstrategyDraw=[](Crawler*pge){}; protected: public: Monster()=delete; @@ -115,7 +117,7 @@ public: void Collision(); void SetVelocity(vf2d vel); //Returns false if the monster could not be moved to the requested location due to collision. - bool SetPosition(vf2d pos); + bool SetPos(vf2d pos); //Returns false if the monster could not be moved to the requested location due to collision. bool SetX(float x); //Returns false if the monster could not be moved to the requested location due to collision. @@ -129,17 +131,20 @@ public: void PathAroundBehavior(float fElapsedTime); void AddBuff(BuffType type,float duration,float intensity); std::vectorGetBuffs(BuffType buff); - State GetState(); - void SetState(State newState); + State::State GetState(); + void SetState(State::State newState); static void InitializeStrategies(); bool HasIframes(); float GetZ(); + void SetZ(float z); std::string GetStrategy(); void SetSize(float newSize,bool immediate=true); float&GetFloat(Attribute a); int&GetInt(Attribute a); std::string&GetString(Attribute a); bool&GetBool(Attribute a); + vf2d&GetVf2d(Attribute a); + void SetStrategyDrawFunction(std::functionfunc); private: struct STRATEGY{ static int _GetInt(Monster&m,std::string param,int strategyNumber,int index=0); diff --git a/Crawler/MonsterAttribute.h b/Crawler/MonsterAttribute.h index ece168bf..d076a59c 100644 --- a/Crawler/MonsterAttribute.h +++ b/Crawler/MonsterAttribute.h @@ -1,10 +1,11 @@ #pragma once -#define VARIANTS float,int,std::string,bool +#define VARIANTS float,int,std::string,bool,vf2d #include #define F(attr) GetFloat(attr) #define I(attr) GetInt(attr) #define S(attr) GetString(attr) #define B(attr) GetBool(attr) +#define V(attr) GetVf2d(attr) enum class Attribute{ IFRAME_TIME_UPON_HIT, @@ -13,4 +14,10 @@ enum class Attribute{ SHOOT_RING_COUNTER, SHOOT_RING_RIGHT, SHOOT_RING_OFFSET, + PATTERN_REPEAT_COUNT, + JUMP_ORIGINAL_LANDING_TIMER, + JUMP_LANDING_TIMER, + JUMP_TARGET_POS, + JUMP_ORIGINAL_POS, + RECOVERY_TIME, }; \ No newline at end of file diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index 684ad052..4a2320c8 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -160,7 +160,7 @@ float Player::GetSpinAngle(){ return spin_angle; } -State Player::GetState(){ +State::State Player::GetState(){ return state; } @@ -207,7 +207,7 @@ void Player::Update(float fElapsedTime){ //Class-specific update events. OnUpdate(fElapsedTime); switch(state){ - case SPIN:{ + case State::SPIN:{ switch(facingDirection){ case UP:{ if(lastAnimationFlip==0){ @@ -233,7 +233,7 @@ void Player::Update(float fElapsedTime){ z="Warrior.Ability 2.SpinMaxHeight"_I*sin(3.3*(GROUND_SLAM_SPIN_TIME-spin_attack_timer)/GROUND_SLAM_SPIN_TIME); spin_attack_timer=std::max(0.f,spin_attack_timer-fElapsedTime); } else { - SetState(NORMAL); + SetState(State::NORMAL); spin_angle=0; z=0; float numb=4; @@ -245,14 +245,14 @@ void Player::Update(float fElapsedTime){ } animation.UpdateState(internal_animState,fElapsedTime); }break; - case BLOCK:{ + case State::BLOCK:{ if(blockTimer<=0){ - SetState(NORMAL); + SetState(State::NORMAL); } }break; - case SWING_SONIC_SWORD:{ + case State::SWING_SONIC_SWORD:{ if(ability3.COOLDOWN_TIME-ability3.cooldown>0.5){ - SetState(NORMAL); + SetState(State::NORMAL); switch(facingDirection){ case DOWN:{ UpdateAnimation("WARRIOR_IDLE_S"); @@ -270,11 +270,11 @@ void Player::Update(float fElapsedTime){ } animation.UpdateState(internal_animState,fElapsedTime); }break; - case TELEPORT:{ + case State::TELEPORT:{ teleportAnimationTimer=std::max(0.f,teleportAnimationTimer-fElapsedTime); if(teleportAnimationTimer<=0){ SetPos(teleportTarget); - SetState(NORMAL); + SetState(State::NORMAL); } animation.UpdateState(internal_animState,fElapsedTime); }break; @@ -304,13 +304,13 @@ void Player::Update(float fElapsedTime){ ability4.cooldown=0; } for(Monster&m:MONSTER_LIST){ - if(!HasIframes()&&OnUpperLevel()==m.OnUpperLevel()&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){ + if(!HasIframes()&&abs(m.GetZ()-GetZ())<=1&&OnUpperLevel()==m.OnUpperLevel()&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){ if(m.IsAlive()){ m.Collision(this); } geom2d::line line(pos,m.GetPos()); float dist = line.length(); - m.SetPosition(line.rpoint(dist*1.1)); + m.SetPos(line.rpoint(dist*1.1)); if(m.IsAlive()){ vel=line.vector().norm()*-128; } @@ -382,7 +382,7 @@ void Player::Update(float fElapsedTime){ #pragma region Warrior switch(GetState()){ - case SWING_SWORD:{ + case State::SWING_SWORD:{ switch(GetFacingDirection()){ case UP:{ UpdateAnimation("WARRIOR_SWINGSWORD_N"); @@ -407,9 +407,9 @@ void Player::Update(float fElapsedTime){ #pragma endregion #pragma region Ranger - if(GetState()==SHOOT_ARROW){ + if(GetState()==State::SHOOT_ARROW){ if(attack_cooldown_timer<=ARROW_ATTACK_COOLDOWN-0.3){ - SetState(NORMAL); + SetState(State::NORMAL); } } if(retreatTimer>0){ @@ -467,7 +467,7 @@ void Player::SetSwordSwingTimer(float val){ swordSwingTimer=val; } -void Player::SetState(State newState){ +void Player::SetState(State::State newState){ if(GetState()==State::BLOCK){ RemoveAllBuffs(BuffType::BLOCK_SLOWDOWN); } diff --git a/Crawler/Player.h b/Crawler/Player.h index 2ed03fe5..3101f482 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -41,7 +41,7 @@ private: float manaTickTimer=0; std::pair notEnoughManaDisplay={"",0}; float teleportAttemptWaitTime=0; //If a teleport fails, we wait awhile before trying again, it's expensive. - State state=State::NORMAL; + State::State state=State::NORMAL; Animate2D::Animationanimation; Animate2D::AnimationState internal_animState; Key lastReleasedMovementKey; @@ -58,7 +58,7 @@ protected: const float MAGIC_ATTACK_COOLDOWN="Wizard.Auto Attack.Cooldown"_F; float ARROW_ATTACK_COOLDOWN="Ranger.Auto Attack.Cooldown"_F; void SetSwordSwingTimer(float val); - void SetState(State newState); + void SetState(State::State newState); void SetFacingDirection(Key direction); void SetLastReleasedMovementKey(Key k); void Spin(float duration,float spinSpd); @@ -120,7 +120,7 @@ public: float GetSizeMult(); float GetAttackRangeMult(); float GetSpinAngle(); - State GetState(); + State::State GetState(); Key GetFacingDirection(); vf2d GetVelocity(); bool HasIframes(); diff --git a/Crawler/RunTowards.cpp b/Crawler/RunTowards.cpp index 4661f535..1103dd75 100644 --- a/Crawler/RunTowards.cpp +++ b/Crawler/RunTowards.cpp @@ -18,11 +18,11 @@ void Monster::STRATEGY::RUN_TOWARDS(Monster&m,float fElapsedTime,int strategyNum } else { m.target=desiredTargetLine.upoint(1.2); } - m.SetState(MOVE_TOWARDS); + m.SetState(State::MOVE_TOWARDS); m.hasHitPlayer=false; } switch(m.state){ - case MOVE_TOWARDS:{ + 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(); if(!m.SetX(newPos.x)||!m.SetY(newPos.y)){ @@ -30,11 +30,11 @@ void Monster::STRATEGY::RUN_TOWARDS(Monster&m,float fElapsedTime,int strategyNum } m.PerformJumpAnimation(); } else { - m.SetState(NORMAL);//Revert state once we've finished moving towards target. + m.SetState(State::NORMAL);//Revert state once we've finished moving towards target. m.UpdateAnimation(MONSTER_DATA[m.id].GetIdleAnimation()); } }break; - case PATH_AROUND:{ + case State::PATH_AROUND:{ m.PathAroundBehavior(fElapsedTime); }break; default:{ diff --git a/Crawler/ShootAfar.cpp b/Crawler/ShootAfar.cpp index 972eecfb..0a30c1f0 100644 --- a/Crawler/ShootAfar.cpp +++ b/Crawler/ShootAfar.cpp @@ -24,23 +24,23 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,int strategyNumb if(line.length()<24.f*ConfigInt("Range")/100.f){ m.target=line.upoint(-1.2); if(m.canMove){ - m.SetState(MOVE_AWAY); + m.SetState(State::MOVE_AWAY); } else { - m.SetState(NORMAL); + m.SetState(State::NORMAL); } } else if(line.length()>24.f*ConfigInt("CloseInRange")/100.0f){ m.target=line.upoint(1.2); - m.SetState(MOVE_TOWARDS); + m.SetState(State::MOVE_TOWARDS); } else { - m.SetState(NORMAL); + m.SetState(State::NORMAL); } } m.canMove=true; geom2d::line moveTowardsLine=geom2d::line(m.pos,m.target); bool pathfindingDecision=false; switch(m.state){ - case MOVE_TOWARDS:{ + case State::MOVE_TOWARDS:{ if(moveTowardsLine.length()>1){ vf2d newPos=m.pos+moveTowardsLine.vector().norm()*100*fElapsedTime*m.GetMoveSpdMult(); bool movedX=m.SetX(newPos.x); @@ -52,7 +52,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,int strategyNumb m.StartPathfinding(2.5); }else if(line.length()<=24.f*ConfigInt("CloseInRange")/100.0f){ - m.SetState(NORMAL); + m.SetState(State::NORMAL); } if(moveTowardsLine.vector().x>0){ m.facingDirection=RIGHT; @@ -61,7 +61,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,int strategyNumb } m.PerformJumpAnimation(); }break; - case MOVE_AWAY:{ + case State::MOVE_AWAY:{ if(moveTowardsLine.length()>1){ vf2d newPos=m.pos+moveTowardsLine.vector().norm()*100*fElapsedTime*m.GetMoveSpdMult(); bool movedX=m.SetX(newPos.x); @@ -73,7 +73,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,int strategyNumb m.StartPathfinding(2.5); }else if(line.length()>=24.f*ConfigInt("Range")/100.f){ - m.SetState(NORMAL); + m.SetState(State::NORMAL); } if(moveTowardsLine.vector().x>0){ m.facingDirection=RIGHT; @@ -82,7 +82,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,int strategyNumb } m.PerformJumpAnimation(); }break; - case PATH_AROUND:{ + case State::PATH_AROUND:{ m.PathAroundBehavior(fElapsedTime); }break; default:{ diff --git a/Crawler/SlimeKing.cpp b/Crawler/SlimeKing.cpp index 35011e1b..1a92e2f6 100644 --- a/Crawler/SlimeKing.cpp +++ b/Crawler/SlimeKing.cpp @@ -3,9 +3,11 @@ #include "DEFINES.h" #include "Crawler.h" #include "utils.h" +#include "safemap.h" INCLUDE_game INCLUDE_BULLET_LIST +INCLUDE_ANIMATION_DATA typedef Attribute A; @@ -15,6 +17,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumbe m.F(A::SHOOT_RING_TIMER)=std::max(0.f,m.F(A::SHOOT_RING_TIMER)-fElapsedTime); m.F(A::SHOOT_RING_DELAY)=std::max(0.f,m.F(A::SHOOT_RING_DELAY)-fElapsedTime); + m.F(A::JUMP_LANDING_TIMER)=std::max(0.f,m.F(A::JUMP_LANDING_TIMER)-fElapsedTime); auto ShootBulletRing=[&](float angleOffset){ int bulletCount=ConfigInt("Phase1.RingBulletCount"); @@ -23,6 +26,42 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumbe BULLET_LIST.emplace_back(std::make_unique(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),false,YELLOW,vf2d{6,6})); } }; + auto StartJump=[&](float jumpDuration,vf2d targetPos,float recoveryTime){ + m.V(A::JUMP_ORIGINAL_POS)=m.GetPos(); + m.F(A::JUMP_ORIGINAL_LANDING_TIMER)=m.F(A::JUMP_LANDING_TIMER)=jumpDuration; + m.V(A::JUMP_TARGET_POS)=targetPos; + m.F(A::RECOVERY_TIME)=recoveryTime; + m.state=State::JUMP; + }; + + if(m.state==State::RECOVERY){ + m.F(A::RECOVERY_TIME)=std::max(0.f,m.F(A::RECOVERY_TIME)-fElapsedTime); + if(m.F(A::RECOVERY_TIME)==0){ + m.state=State::NORMAL; + } + return; + } + + if(m.state==State::JUMP){ + float jumpLandingTimerRatio=m.F(A::JUMP_LANDING_TIMER)/m.F(A::JUMP_ORIGINAL_LANDING_TIMER); + m.SetPos(m.V(A::JUMP_ORIGINAL_POS).lerp(m.V(A::JUMP_TARGET_POS),1-jumpLandingTimerRatio)); + if(m.F(A::JUMP_LANDING_TIMER)>=m.F(A::JUMP_ORIGINAL_LANDING_TIMER)/2){ + m.SetZ(util::lerp(0,ConfigInt("JumpHeight"),1-jumpLandingTimerRatio*2)); + }else{ + m.SetZ(util::lerp(0,ConfigInt("JumpHeight"),jumpLandingTimerRatio*2)); + } + if(m.F(A::JUMP_LANDING_TIMER)==0){ + m.state=State::RECOVERY; + m.SetStrategyDrawFunction([](Crawler*game){}); + } else + if(m.F(A::JUMP_LANDING_TIMER)<=ConfigFloat("JumpWarningIndicatorTime")){ + m.SetStrategyDrawFunction([&](Crawler*game){ + Decal*dec=ANIMATION_DATA["RANGE_INDICATOR"].GetFrame(game->GetElapsedTime()).GetSourceImage()->Decal(); + game->view.DrawRotatedDecal(m.GetPos(),dec,0,dec->sprite->Size()/2,vf2d{m.GetSizeMult(),m.GetSizeMult()}/2,RED); + }); + } + return; + } switch(m.phase){ case 0:{ @@ -38,11 +77,17 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumbe m.SetSize(ConfigFloat("Phase2.Size")/100,false); } if(m.F(A::SHOOT_RING_TIMER)==0){ + if(m.I(A::PATTERN_REPEAT_COUNT)>=ConfigInt("Phase1.JumpAfter")){ + StartJump(ConfigFloat("Phase1.AirborneTime"),game->GetPlayer()->GetPos(),ConfigFloat("Phase1.LandingRecoveryTime")); + m.I(A::PATTERN_REPEAT_COUNT)=0; + return; + } m.I(A::SHOOT_RING_COUNTER)=ConfigInt("Phase1.ShootRingCount")-1; m.F(A::SHOOT_RING_DELAY)=ConfigFloat("Phase1.ShootRingDelay"); ShootBulletRing(m.F(A::SHOOT_RING_OFFSET)); m.F(A::SHOOT_RING_TIMER)=ConfigFloat("Phase1.ShootRepeatTime"); m.B(A::SHOOT_RING_RIGHT)=bool(rand()%2); + m.I(A::PATTERN_REPEAT_COUNT)++; } if(m.I(A::SHOOT_RING_COUNTER)>0){ if(m.F(A::SHOOT_RING_DELAY)==0){ diff --git a/Crawler/State.h b/Crawler/State.h index 3191179a..2a41018d 100644 --- a/Crawler/State.h +++ b/Crawler/State.h @@ -1,18 +1,22 @@ #pragma once -enum State{ - NORMAL, - SWING_SWORD, - SWING_SONIC_SWORD, - SPIN, - MOVE_TOWARDS, - MOVE_AWAY, - BLOCK, - TELEPORT, - PATH_AROUND, - CASTING, - PREP_CAST, - SHOOT_ARROW, - RETREAT, - ANIMATION_LOCK, -}; \ No newline at end of file +namespace State{ + enum State{ + NORMAL, + SWING_SWORD, + SWING_SONIC_SWORD, + SPIN, + MOVE_TOWARDS, + MOVE_AWAY, + BLOCK, + TELEPORT, + PATH_AROUND, + CASTING, + PREP_CAST, + SHOOT_ARROW, + RETREAT, + ANIMATION_LOCK, + JUMP, + RECOVERY, + }; +} \ No newline at end of file diff --git a/Crawler/Version.h b/Crawler/Version.h index af864ac3..23cfb35a 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -2,7 +2,7 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 1119 +#define VERSION_BUILD 1138 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/assets/config/MonsterStrategies.txt b/Crawler/assets/config/MonsterStrategies.txt index bb784bd2..994a4729 100644 --- a/Crawler/assets/config/MonsterStrategies.txt +++ b/Crawler/assets/config/MonsterStrategies.txt @@ -75,7 +75,7 @@ MonsterStrategy # 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 = 1500 + JumpHeight = 300 ProjectileDamage = 10 JumpAttackDamage = 20 @@ -93,7 +93,6 @@ MonsterStrategy RingOffset = 10.0 JumpAfter = 4 shots AirborneTime = 3.0 - LandingRingCount = 1 LandingRecoveryTime = 2.0 } Phase2 diff --git a/Crawler/assets/config/gfx/gfx.txt b/Crawler/assets/config/gfx/gfx.txt index ef95be9e..212a1faf 100644 --- a/Crawler/assets/config/gfx/gfx.txt +++ b/Crawler/assets/config/gfx/gfx.txt @@ -29,4 +29,5 @@ Images GFX_Arrow = arrow.png GFX_Laser = laser.png GFX_ChargedArrow = charged_shot_arrow.png + GFX_RangeIndicator = range_indicator.png } \ No newline at end of file diff --git a/Crawler/assets/range_indicator.png b/Crawler/assets/range_indicator.png new file mode 100644 index 00000000..5800ab44 Binary files /dev/null and b/Crawler/assets/range_indicator.png differ diff --git a/Crawler/utils.cpp b/Crawler/utils.cpp index cf1e2af4..94eb7383 100644 --- a/Crawler/utils.cpp +++ b/Crawler/utils.cpp @@ -14,4 +14,8 @@ float util::degToRad(float deg){ float util::radToDeg(float rad){ return rad*57.2957795130823208767; +} + +float util::lerp(float n1,float n2,double t){ + return n1*(1-t)+n2*t; } \ No newline at end of file diff --git a/Crawler/utils.h b/Crawler/utils.h index 2bf204c6..e9576924 100644 --- a/Crawler/utils.h +++ b/Crawler/utils.h @@ -8,4 +8,5 @@ namespace util{ vf2d pointTo(vf2d posFrom,vf2d posTo); float degToRad(float deg); float radToDeg(float rad); + float lerp(float n1,float n2,double t); } \ No newline at end of file