diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 3a453bde..7ded8558 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -569,15 +569,18 @@ void Crawler::RenderWorld(float fElapsedTime){ } vf2d playerScale=vf2d(player->GetSizeMult(),player->GetSizeMult()); vf2d playerPosition=player->GetPos(); - #define RENDER_PLAYER \ - if(player->teleportAnimationTimer>0){ \ - playerScale.x=120*abs(pow(player->teleportAnimationTimer-0.175,3)); \ - playerPosition=player->teleportStartPosition.lerp(player->teleportTarget,(0.35-player->teleportAnimationTimer)/0.35); \ - view.DrawPartialRotatedDecal(playerPosition+vf2d{0,-player->GetZ()},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE); \ - } else {view.DrawPartialRotatedDecal(playerPosition+vf2d{0,-player->GetZ()},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE);} + auto RenderPlayer=[&](){ + if(player->teleportAnimationTimer>0){ + playerScale.x=120*abs(pow(player->teleportAnimationTimer-0.175,3)); + playerPosition=player->teleportStartPosition.lerp(player->teleportTarget,(0.35-player->teleportAnimationTimer)/0.35); + view.DrawPartialRotatedDecal(playerPosition+vf2d{0,-player->GetZ()},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE); + } else { + view.DrawPartialRotatedDecal(playerPosition+vf2d{0,-player->GetZ()},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE); + } + } //define end if(!player->upperLevel){ - RENDER_PLAYER + RenderPlayer(); } if(player->GetState()==State::BLOCK){ view.DrawDecal(player->GetPos()-vf2d{12,12},GFX_BLOCK_BUBBLE.Decal()); @@ -661,7 +664,7 @@ void Crawler::RenderWorld(float fElapsedTime){ m->Draw(); } if(player->upperLevel){ - RENDER_PLAYER + RenderPlayer(); } for(Monster*m:monstersAfterUpper){ m->Draw(); diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index ae65932f..77f3c29a 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -537,4 +537,8 @@ bool Player::CanPathfindTo(vf2d pos,vf2d targetPos,float range){ void Player::PrepareCast(Ability&ability){ castPrepAbility=&ability; SetState(State::PREP_CAST); +} + +void Player::SetVelocity(vf2d vel){ + this->vel=vel; } \ No newline at end of file diff --git a/Crawler/Player.h b/Crawler/Player.h index 74cd8f71..8243267d 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -30,7 +30,6 @@ struct Player{ int mana=100,maxmana=mana; int atk=10; vf2d pos; - float friction=400; float z=0; float moveSpd=1.0f; float size=1.0f; @@ -66,6 +65,7 @@ protected: void SetZ(float z); //Returns true if the move was valid and successful. bool SetPos(vf2d pos); + float friction=400; float attack_cooldown_timer=0; float iframe_time=0; float teleportAnimationTimer=0; @@ -81,6 +81,15 @@ protected: Ability*castPrepAbility; void PrepareCast(Ability&ability); vf2d precastLocation={}; + void SetVelocity(vf2d vel); + const float RETREAT_DISTANCE=24*2.5; + const float RETREAT_TIME=0.2; //How long the Retreat ability takes. + const int RETREAT_GHOST_FRAMES=8; + const float RETREAT_GHOST_FRAME_DELAY=0.025; + float ghostFrameTimer=0; + float ghostRemoveTimer=0; + float retreatTimer=0; + std::vectorghostPositions; public: Player(); //So this is rather fascinating and only exists because we have the ability to change classes which means we need to initialize a class diff --git a/Crawler/Ranger.cpp b/Crawler/Ranger.cpp index 52b3a40c..2b56e890 100644 --- a/Crawler/Ranger.cpp +++ b/Crawler/Ranger.cpp @@ -34,6 +34,25 @@ void Ranger::OnUpdate(float fElapsedTime){ SetState(NORMAL); } } + if(retreatTimer>0){ + SetZ(6*sin(PI/RETREAT_TIME*retreatTimer)); + retreatTimer-=fElapsedTime; + if(retreatTimer<=0){ + SetVelocity({}); + SetZ(0); + } + } + if(ghostRemoveTimer>0){ + ghostRemoveTimer-=fElapsedTime; + if(ghostRemoveTimer<=0){ + if(ghostPositions.size()>0){ + ghostPositions.erase(ghostPositions.begin()); + if(ghostPositions.size()>0){ + ghostRemoveTimer=RETREAT_GHOST_FRAME_DELAY; + } + } + } + } } bool Ranger::AutoAttack(){ @@ -62,7 +81,15 @@ void Ranger::InitializeClassAbilities(){ #pragma region Ranger Right-click Ability (???) Ranger::rightClickAbility.action= [](Player*p,vf2d pos={}){ - return false; + geom2d::line mouseDir{game->GetWorldMousePos(),p->GetPos()}; + float velocity=(0.5*-p->friction*p->RETREAT_TIME*p->RETREAT_TIME-p->RETREAT_DISTANCE)/-p->RETREAT_TIME; //Derived from kinetic motion formula. + p->SetVelocity(mouseDir.vector().norm()*velocity); + p->retreatTimer=p->RETREAT_TIME; + p->iframe_time=p->RETREAT_TIME; + p->ghostPositions.push_back(p->GetPos()); + p->ghostFrameTimer=p->RETREAT_GHOST_FRAME_DELAY; + p->ghostRemoveTimer=p->RETREAT_GHOST_FRAMES*p->RETREAT_GHOST_FRAME_DELAY; + return true; }; #pragma endregion #pragma region Ranger Ability 1 (???) diff --git a/Crawler/State.h b/Crawler/State.h index 4e253205..5cdcec7e 100644 --- a/Crawler/State.h +++ b/Crawler/State.h @@ -13,4 +13,5 @@ enum State{ CASTING, PREP_CAST, SHOOT_ARROW, + RETREAT, }; \ No newline at end of file