diff --git a/assets/fuelbar_outline.png b/assets/fuelbar_outline.png new file mode 100644 index 0000000..72b1730 Binary files /dev/null and b/assets/fuelbar_outline.png differ diff --git a/assets/hamster.png b/assets/hamster.png index 40e3263..e99b147 100644 Binary files a/assets/hamster.png and b/assets/hamster.png differ diff --git a/assets/hamster_jet.png b/assets/hamster_jet.png index 0c59948..65931b8 100644 Binary files a/assets/hamster_jet.png and b/assets/hamster_jet.png differ diff --git a/src/Hamster.cpp b/src/Hamster.cpp index 50819a8..ad6d8a5 100644 --- a/src/Hamster.cpp +++ b/src/Hamster.cpp @@ -92,61 +92,7 @@ void Hamster::UpdateHamsters(const float fElapsedTime){ h.imgScale=1.f; h.drownTimer=0.f; if(!h.lastSafeLocation.has_value()){ - #pragma region Safe Terrain Outline Search Algorithm - { - using TilePos=vi2d; - using TileDistance=int; - - const vi2d playerTile{h.GetPos()/16}; - geom2d::rectsearchRect{{-1,-1},{3,3}}; - std::optional>closestTile; - - const auto DetermineAndUpdateClosestTile=[&h,&playerTile,&closestTile](const vi2d&tile){ - if(!h.IsLethalTerrain(tile*16)){ - std::pairclosest{closestTile.value_or(std::pair{{},std::numeric_limits::max()})}; - int tileDist{abs(playerTile.x-tile.x)+abs(playerTile.y-tile.y)}; - if(tileDist<=closest.second)closestTile.emplace(std::pair{tile,tileDist}); - } - }; - while(!closestTile.has_value()){ - #pragma region Top Outline Check - { - for(int offsetX:std::ranges::iota_view(searchRect.pos.x,searchRect.size.x)){ - const vi2d checkTile{playerTile+vi2d{offsetX,searchRect.top().end.y}}; - DetermineAndUpdateClosestTile(checkTile); - } - } - #pragma endregion - #pragma region Bottom Outline Check - { - for(int offsetX:std::ranges::iota_view(searchRect.pos.x,searchRect.size.x)){ - const vi2d checkTile{playerTile+vi2d{offsetX,searchRect.bottom().end.y}}; - DetermineAndUpdateClosestTile(checkTile); - } - } - #pragma endregion - #pragma region Right Outline Check - { - for(int offsetY:std::ranges::iota_view(searchRect.pos.y+1,searchRect.size.y-2+1)){ - const vi2d checkTile{playerTile+vi2d{searchRect.right().end.x,offsetY}}; - DetermineAndUpdateClosestTile(checkTile); - } - } - #pragma endregion - #pragma region Left Outline Check - { - for(int offsetY:std::ranges::iota_view(searchRect.pos.y+1,searchRect.size.y-2+1)){ - const vi2d checkTile{playerTile+vi2d{searchRect.left().end.x,offsetY}}; - DetermineAndUpdateClosestTile(checkTile); - } - } - #pragma endregion - searchRect.pos-=1; - searchRect.size+=2; - } - h.lastSafeLocation=closestTile.value().first*16+8; - } - #pragma endregion + h.lastSafeLocation=h.GetNearestSafeLocation(); } h.SetPos(h.lastSafeLocation.value()); h.state=NORMAL; @@ -162,6 +108,13 @@ void Hamster::UpdateHamsters(const float fElapsedTime){ h.state=WAIT; } }break; + case KNOCKOUT:{ + h.knockoutTimer-=fElapsedTime; + if(h.knockoutTimer<=0.f){ + h.state=NORMAL; + h.animations.ChangeState(h.internalAnimState,HamsterGame::DEFAULT); + } + }break; } if(h.hamsterJet.has_value())h.hamsterJet.value().Update(fElapsedTime); if(h.state!=FLYING){ @@ -182,6 +135,12 @@ void Hamster::UpdateHamsters(const float fElapsedTime){ } h.TurnTowardsTargetDirection(); h.MoveHamster(); + if(h.IsPlayerControlled){ + h.hamsterJetDisplay.Update(fElapsedTime); + h.hamsterJetLightsDisplay.Update(fElapsedTime); + h.readyFlashTimer+=fElapsedTime; + h.jetFuelDisplayAmt+=(h.jetFuel-h.jetFuelDisplayAmt)*4.f*fElapsedTime; + } } } @@ -194,6 +153,8 @@ void Hamster::LoadHamsters(const vf2d startingLoc){ for(int i:std::ranges::iota_view(0U,NPC_HAMSTER_COUNT)){ HAMSTER_LIST.emplace_back(startingLoc,NPC_HAMSTER_IMAGES.at(util::random()%NPC_HAMSTER_IMAGES.size()),NPC); } + playerHamster.value()->hamsterJetDisplay.Initialize("hamster_jet.png",{78,223,208},{79,81,128}); + playerHamster.value()->hamsterJetLightsDisplay.Initialize("hamster_jet.png",{245,233,130},{245,233,130}); } void Hamster::DrawHamsters(TransformedView&tv){ @@ -216,10 +177,44 @@ void Hamster::DrawHamsters(TransformedView&tv){ } void Hamster::DrawOverlay(){ - if(GetPlayer().hamsterJet.has_value()){ - GetPlayer().hamsterJet.value().DrawOverlay(); - HamsterGame::Game().DrawDecal(vf2d{96.f,0.f}+HamsterGame::SCREEN_FRAME.size,HamsterGame::GetGFX("fuelmeter.png").Decal()); + if(GetPlayer().hamsterJet.has_value())GetPlayer().hamsterJet.value().DrawOverlay(); + + const vf2d jetDisplayOffset{HamsterGame::SCREEN_FRAME.pos+vf2d{HamsterGame::SCREEN_FRAME.size.x,0.f}}; + Pixel jetDisplayCol{VERY_DARK_GREY}; + if(!GetPlayer().hamsterJet.has_value()){ + if(GetPlayer().HasPowerup(Powerup::JET))jetDisplayCol=WHITE; + const Animate2D::FrameSequence&lightAnim{HamsterGame::Game().GetAnimation("hamster_jet.png",HamsterGame::AnimationState::JET_LIGHTS)}; + const Animate2D::Frame&lightFrame{lightAnim.GetFrame(HamsterGame::Game().GetRuntime())}; + HamsterGame::Game().DrawPartialRotatedDecal(jetDisplayOffset+vf2d{48.f,80.f},GetPlayer().hamsterJetDisplay.Decal(),0.f,{24.f,24.f},{0.f,0.f},{48.f,48.f},{2.f,2.f},jetDisplayCol); + HamsterGame::Game().DrawPartialRotatedDecal(jetDisplayOffset+vf2d{48.f,80.f},GetPlayer().hamsterJetLightsDisplay.Decal(),0.f,{24.f,24.f},lightFrame.GetSourceRect().pos,lightFrame.GetSourceRect().size,{2.f,2.f},jetDisplayCol); } + + if(GetPlayer().HasPowerup(Powerup::JET)&&!GetPlayer().hamsterJet.has_value()){ + const std::string readyText{"READY!"}; + const vi2d textSize{HamsterGame::Game().GetTextSize(readyText)}; + for(int y:std::ranges::iota_view(-1,2)){ + for(int x:std::ranges::iota_view(-1,2)){ + if(x==0&&y==0)continue; + HamsterGame::Game().DrawRotatedStringDecal(jetDisplayOffset+vf2d{48.f,116.f}+vi2d{x,y},readyText,0.f,textSize/2,fmod(GetPlayer().readyFlashTimer,1.5f)<=0.75f?DARK_RED:BLACK); + } + } + HamsterGame::Game().DrawRotatedStringDecal(jetDisplayOffset+vf2d{48.f,116.f},readyText,0.f,textSize/2,GREEN); + HamsterGame::Game().DrawDecal(HamsterGame::SCREEN_FRAME.pos+vf2d{HamsterGame::SCREEN_FRAME.size.x,0.f},HamsterGame::GetGFX("fuelmeter.png").Decal()); + const std::string launchText{"(SPACE)x2\nto Launch!"}; + const vi2d launchTextSize{HamsterGame::Game().GetTextSize(launchText)}; + for(int y:std::ranges::iota_view(-1,2)){ + for(int x:std::ranges::iota_view(-1,2)){ + if(x==0&&y==0)continue; + HamsterGame::Game().DrawRotatedStringDecal(jetDisplayOffset+vf2d{48.f,224.f}+vi2d{x,y},launchText,0.f,launchTextSize/2,BLACK); + } + } + HamsterGame::Game().DrawRotatedStringDecal(jetDisplayOffset+vf2d{48.f,224.f},launchText,0.f,launchTextSize/2,WHITE); + }else{ + HamsterGame::Game().DrawPartialDecal(HamsterGame::SCREEN_FRAME.pos+vf2d{HamsterGame::SCREEN_FRAME.size.x,0.f},HamsterGame::GetGFX("fuelmeter.png").Decal(),{0,0},{96,200}); + } + const float jetFuelBarHeight{float(HamsterGame::GetGFX("fuelbar.png").Sprite()->height)}; + HamsterGame::Game().DrawPartialDecal(jetDisplayOffset+vf2d{24.f,139.f}+vf2d{0.f,jetFuelBarHeight*(1.f-GetPlayer().jetFuelDisplayAmt)},HamsterGame::GetGFX("fuelbar.png").Decal(),{0.f,jetFuelBarHeight*(1.f-GetPlayer().jetFuelDisplayAmt)},{float(HamsterGame::GetGFX("fuelbar.png").Sprite()->width),jetFuelBarHeight*(GetPlayer().jetFuelDisplayAmt)}); + if(GetPlayer().HasPowerup(Powerup::JET))HamsterGame::Game().DrawDecal(jetDisplayOffset+vf2d{22.f,137.f},HamsterGame::GetGFX("fuelbar_outline.png").Decal(),{1.f,1.f},GetPlayer().jetFuel<=0.2f?(fmod(GetPlayer().readyFlashTimer,1.f)<=0.5f?RED:BLACK):BLACK); } const Animate2D::Frame&Hamster::GetCurrentAnimation()const{ @@ -265,7 +260,11 @@ void Hamster::HandlePlayerControls(){ } lastTappedSpace=0.f; } - if(HamsterGame::Game().GetKey(P).bPressed)ObtainPowerup(Powerup::JET); + if(HamsterGame::Game().GetKey(P).bPressed){ + ObtainPowerup(Powerup::JET); + Powerup tempJetPowerup{{},Powerup::JET}; + tempJetPowerup.OnPowerupObtain(*this); + } } void Hamster::TurnTowardsTargetDirection(){ @@ -276,6 +275,9 @@ void Hamster::MoveHamster(){ SetPos(GetPos()+vel*HamsterGame::Game().GetElapsedTime()); distanceTravelled+=vel.mag()*HamsterGame::Game().GetElapsedTime(); + if(state==FLYING){ + jetFuel=std::max(0.f,jetFuel-vel.mag()*HamsterGame::Game().GetElapsedTime()/100000.f); + } #pragma region Handle Friction if(frictionEnabled){ @@ -314,9 +316,11 @@ void Hamster::HandleCollision(){ } } for(Powerup&powerup:Powerup::GetPowerups()){ - if(z<=0.1f&&!HasPowerup(powerup.GetType())&&geom2d::overlaps(geom2d::circle(GetPos(),collisionRadius),geom2d::circle(powerup.GetPos(),20.f))){ + if(z<=0.1f&& + (!HasPowerup(powerup.GetType())||HasPowerup(Powerup::JET)&&powerup.GetType()==Powerup::JET&&jetFuel!=1.f) + &&geom2d::overlaps(geom2d::circle(GetPos(),collisionRadius),geom2d::circle(powerup.GetPos(),20.f))){ ObtainPowerup(powerup.GetType()); - powerup.OnPowerupObtain(); + powerup.OnPowerupObtain(*this); } } } @@ -450,4 +454,72 @@ void Hamster::OnUserDestroy(){ void Hamster::SetDrawingOffsetY(const float offsetY){ drawingOffsetY=offsetY; +} + +const vf2d Hamster::GetNearestSafeLocation()const{ + using TilePos=vi2d; + using TileDistance=int; + + const vi2d playerTile{GetPos()/16}; + geom2d::rectsearchRect{{-1,-1},{3,3}}; + std::optional>closestTile; + + const auto DetermineAndUpdateClosestTile=[this,&playerTile,&closestTile](const vi2d&tile){ + if(!IsLethalTerrain(tile*16)&&!IsSolidTerrain(tile*16)){ + std::pairclosest{closestTile.value_or(std::pair{{},std::numeric_limits::max()})}; + int tileDist{abs(playerTile.x-tile.x)+abs(playerTile.y-tile.y)}; + if(tileDist<=closest.second)closestTile.emplace(std::pair{tile,tileDist}); + } + }; + while(!closestTile.has_value()){ + #pragma region Top Outline Check + { + for(int offsetX:std::ranges::iota_view(searchRect.pos.x,searchRect.size.x)){ + const vi2d checkTile{playerTile+vi2d{offsetX,searchRect.top().end.y}}; + DetermineAndUpdateClosestTile(checkTile); + } + } + #pragma endregion + #pragma region Bottom Outline Check + { + for(int offsetX:std::ranges::iota_view(searchRect.pos.x,searchRect.size.x)){ + const vi2d checkTile{playerTile+vi2d{offsetX,searchRect.bottom().end.y}}; + DetermineAndUpdateClosestTile(checkTile); + } + } + #pragma endregion + #pragma region Right Outline Check + { + for(int offsetY:std::ranges::iota_view(searchRect.pos.y+1,searchRect.size.y-2+1)){ + const vi2d checkTile{playerTile+vi2d{searchRect.right().end.x,offsetY}}; + DetermineAndUpdateClosestTile(checkTile); + } + } + #pragma endregion + #pragma region Left Outline Check + { + for(int offsetY:std::ranges::iota_view(searchRect.pos.y+1,searchRect.size.y-2+1)){ + const vi2d checkTile{playerTile+vi2d{searchRect.left().end.x,offsetY}}; + DetermineAndUpdateClosestTile(checkTile); + } + } + #pragma endregion + searchRect.pos-=1; + searchRect.size+=2; + } + return closestTile.value().first*16+8; +} + +const bool Hamster::IsSolidTerrain(const vf2d pos)const{ + return HamsterGame::Game().IsTerrainSolid(pos); +} + +void Hamster::SetJetFuel(const float amt){ + jetFuel=amt; +} + +void Hamster::Knockout(){ + state=KNOCKOUT; + knockoutTimer=4.f; + animations.ChangeState(internalAnimState,HamsterGame::KNOCKOUT); } \ No newline at end of file diff --git a/src/Hamster.h b/src/Hamster.h index 22f4f26..de183ea 100644 --- a/src/Hamster.h +++ b/src/Hamster.h @@ -59,6 +59,7 @@ class Hamster{ FLYING, WAIT, BURNING, + KNOCKOUT, }; static std::vectorHAMSTER_LIST; @@ -103,6 +104,12 @@ class Hamster{ std::optionalhamsterJet; float lastTappedSpace{0.f}; float drawingOffsetY{0.f}; + SpecialRenderable hamsterJetDisplay; + SpecialRenderable hamsterJetLightsDisplay; + float readyFlashTimer{}; + float jetFuel{0.f}; + float jetFuelDisplayAmt{0.f}; + float knockoutTimer{0.f}; public: Hamster(const vf2d spawnPos,const std::string_view img,const PlayerControlled IsPlayerControlled=NPC); static const Hamster&GetPlayer(); @@ -129,6 +136,7 @@ public: const bool HasPowerup(const Powerup::PowerupType powerup)const; void RemoveAllPowerups(); const bool IsLethalTerrain(const vf2d pos)const; + const bool IsSolidTerrain(const vf2d pos)const; const bool IsDrowning()const; const bool IsBurning()const; const float GetDrownRatio()const; @@ -137,4 +145,7 @@ public: void SetZ(const float z); static void OnUserDestroy(); void SetDrawingOffsetY(const float offsetY); + const vf2d GetNearestSafeLocation()const; + void SetJetFuel(const float amt); + void Knockout(); }; \ No newline at end of file diff --git a/src/HamsterGame.cpp b/src/HamsterGame.cpp index 092af73..cb405a6 100644 --- a/src/HamsterGame.cpp +++ b/src/HamsterGame.cpp @@ -52,6 +52,7 @@ void HamsterGame::LoadGraphics(){ _LoadImage("fallometer_outline.png"); _LoadImage("fuelmeter.png"); _LoadImage("fuelbar.png"); + _LoadImage("fuelbar_outline.png"); UpdateMatrixTexture(); } @@ -75,6 +76,7 @@ void HamsterGame::LoadAnimations(){ LoadAnimation(DEFAULT,"hamster.png",{{0,32},{32,32}},0.3f); LoadAnimation(WHEEL_TOP,"hamster.png",{{0,96},{32,96}},0.1f); LoadAnimation(WHEEL_BOTTOM,"hamster.png",{{64,96},{96,96}},0.1f); + LoadAnimation(KNOCKOUT,"hamster.png",{{64,32},{96,32}},0.2f); Animate2D::FrameSequence&waterAnimFrames{(*ANIMATED_TILE_IDS.insert({1384,Animate2D::FrameSequence{0.2f}}).first).second}; for(vf2d&sourcePos:std::vector{{192+16*0,784},{192+16*1,784},{192+16*2,784},{192+16*3,784},{192+16*4,784},{192+16*5,784},{192+16*6,784},{192+16*7,784}}){ waterAnimFrames.AddFrame(Animate2D::Frame{&GetGFX("gametiles.png"),{sourcePos,{16,16}}}); diff --git a/src/HamsterGame.h b/src/HamsterGame.h index 2f096fb..2fab5d7 100644 --- a/src/HamsterGame.h +++ b/src/HamsterGame.h @@ -64,6 +64,7 @@ public: WHEEL_BOTTOM, JET_LIGHTS, JET_FLAMES, + KNOCKOUT, }; HamsterGame(); diff --git a/src/HamsterJet.cpp b/src/HamsterJet.cpp index 9fa16e2..d3edb10 100644 --- a/src/HamsterJet.cpp +++ b/src/HamsterJet.cpp @@ -80,19 +80,22 @@ void HamsterJet::Update(const float fElapsedTime){ hamster.SetPos(pos); hamster.SetZ(z+0.03f); if(timer<=0.f){ - state=PLAYER_CONTROL; + state=HAMSTER_CONTROL; HamsterGame::Game().SetZoom(0.6f); easeInTimer=0.6f; } }break; - case PLAYER_CONTROL:{ + case HAMSTER_CONTROL:{ jetState[TOP_LEFT]=jetState[BOTTOM_LEFT]=jetState[BOTTOM_RIGHT]=jetState[TOP_RIGHT]=OFF; HandleJetControls(); pos=hamster.GetPos(); }break; case LANDING:{ jetState[TOP_LEFT]=jetState[BOTTOM_LEFT]=jetState[BOTTOM_RIGHT]=jetState[TOP_RIGHT]=OFF; - HandleJetControls(); + if(hamster.IsPlayerControlled)HandleJetControls(); + else{ + //TODO: AI controls here! + } pos=hamster.GetPos(); hamster.SetZ(hamster.GetZ()-fallSpd*fElapsedTime); z=hamster.GetZ(); @@ -104,6 +107,14 @@ void HamsterJet::Update(const float fElapsedTime){ timer=3.f; originalPos=hamster.GetPos(); targetPos={hamster.GetPos().x+128.f,hamster.GetPos().y+32.f}; + Terrain::CrashSpeed crashSpd{Terrain::LIGHT}; + if(fallSpd>4.f)crashSpd=Terrain::MAX; + else if(fallSpd>2.f)crashSpd=Terrain::MEDIUM; + std::pairlandingResult{Terrain::GetFuelDamageTakenAndKnockoutEffect(hamster.GetTerrainStandingOn(),crashSpd)}; + hamster.jetFuel=std::max(0.f,hamster.jetFuel-landingResult.first); + if(landingResult.second)hamster.Knockout(); + if(hamster.IsTerrainStandingOnSolid())hamster.SetPos(hamster.GetNearestSafeLocation()); + if(hamster.jetFuel<=0.f)hamster.powerups.erase(Powerup::JET); } }break; case COMPLETE_LANDING:{ @@ -121,11 +132,11 @@ void HamsterJet::Update(const float fElapsedTime){ void HamsterJet::Draw(){ float drawingOffsetY{0.f}; hamster.SetDrawingOffsetY(0.f); - if((state==PLAYER_CONTROL||state==LANDING)&&z>2.f){ + if((state==HAMSTER_CONTROL||state==LANDING)&&z>2.f){ HamsterGame::Game().SetZ(z/2.f); HamsterGame::Game().tv.DrawRotatedDecal(pos,HamsterGame::GetGFX("aimingTarget.png").Decal(),0.f,HamsterGame::GetGFX("aimingTarget.png").Sprite()->Size()/2); } - if(state==PLAYER_CONTROL){ + if(state==HAMSTER_CONTROL){ drawingOffsetY=util::lerp(48.f,0.f,easeInTimer/0.6f); hamster.SetDrawingOffsetY(util::lerp(48.f,0.f,easeInTimer/0.6f)); } @@ -168,7 +179,7 @@ void HamsterJet::HandleJetControls(){ jetState[BOTTOM_RIGHT]=ON; jetState[TOP_RIGHT]=ON; } - if(aimingDir!=vf2d{}){ + if(aimingDir!=vf2d{}&&hamster.jetFuel>0.f){ hamster.targetRot=aimingDir.norm().polar().y; const vf2d currentVel{hamster.vel}; hamster.vel+=vf2d{currentVel.polar().x+(hamster.GetMaxSpeed()*HamsterGame::Game().GetElapsedTime())/hamster.GetTimeToMaxSpeed(),hamster.rot}.cart(); diff --git a/src/HamsterJet.h b/src/HamsterJet.h index b3b7de5..400e761 100644 --- a/src/HamsterJet.h +++ b/src/HamsterJet.h @@ -47,7 +47,7 @@ public: enum State{ SWOOP_DOWN, RISE_UP, - PLAYER_CONTROL, + HAMSTER_CONTROL, LANDING, COMPLETE_LANDING, }; diff --git a/src/Powerup.cpp b/src/Powerup.cpp index 1180734..85cc9be 100644 --- a/src/Powerup.cpp +++ b/src/Powerup.cpp @@ -38,6 +38,7 @@ All rights reserved. #include "HamsterGame.h" #include "Powerup.h" +#include "Hamster.h" std::vectorPowerup::powerupList; std::unordered_map>Powerup::powerupIds; @@ -112,6 +113,7 @@ const geom2d::rectPowerup::GetPowerupSubimageRect(const PowerupType power return {POWERUP_TILESET_STARTING_POS+vf2d{int(powerupType)*32.f,0.f},{32,32}}; } -void Powerup::OnPowerupObtain(){ +void Powerup::OnPowerupObtain(Hamster&pickupHamster){ spinSpd=0.3f; + if(type==JET)pickupHamster.SetJetFuel(1.f); } \ No newline at end of file diff --git a/src/Powerup.h b/src/Powerup.h index a8ec92e..69107a2 100644 --- a/src/Powerup.h +++ b/src/Powerup.h @@ -41,6 +41,8 @@ All rights reserved. #include "olcUTIL_Geometry2D.h" #include "olcPGEX_TransformedView.h" +class Hamster; + class Powerup{ public: enum PowerupType{ @@ -79,5 +81,5 @@ public: static void UpdatePowerups(const float fElapsedTime); static void DrawPowerups(TransformedView&tv); static const geom2d::rectGetPowerupSubimageRect(const PowerupType powerupType); - void OnPowerupObtain(); + void OnPowerupObtain(Hamster&pickupHamster); }; \ No newline at end of file diff --git a/src/Terrain.cpp b/src/Terrain.cpp index 32d7f72..dd69e88 100644 --- a/src/Terrain.cpp +++ b/src/Terrain.cpp @@ -73,4 +73,82 @@ const std::string Terrain::TerrainToString(const TerrainType type){ return "Void"; } } +} +const std::pairTerrain::GetFuelDamageTakenAndKnockoutEffect(const TerrainType type,const CrashSpeed crashSpeed){ + + const auto GetHardSurfaceCrashResult=[&crashSpeed](){ + switch(crashSpeed){ + case MAX:{ + return std::pair{1.f,true}; + }break; + case MEDIUM:{ + return std::pair{0.8f,false}; + }break; + case LIGHT:{ + return std::pair{0.5f,false}; + }break; + } + }; + const auto GetMediumSurfaceCrashResult=[&crashSpeed](){ + switch(crashSpeed){ + case MAX:{ + return std::pair{0.8f,true}; + }break; + case MEDIUM:{ + return std::pair{0.5f,false}; + }break; + case LIGHT:{ + return std::pair{0.25f,false}; + }break; + } + }; + const auto GetSoftSurfaceCrashResult=[&crashSpeed](){ + switch(crashSpeed){ + case MAX:{ + return std::pair{0.5f,false}; + }break; + case MEDIUM:{ + return std::pair{0.25f,false}; + }break; + case LIGHT:{ + return std::pair{0.25f,false}; + }break; + } + }; + + switch(type){ + case ROCK:{ + return GetHardSurfaceCrashResult(); + }break; + case GRASS:{ + return GetMediumSurfaceCrashResult(); + }break; + case SAND:{ + return GetSoftSurfaceCrashResult(); + }break; + case SWAMP:{ + return GetSoftSurfaceCrashResult(); + }break; + case LAVA:{ + return GetSoftSurfaceCrashResult(); + }break; + case SHORE:{ + return GetMediumSurfaceCrashResult(); + }break; + case OCEAN:{ + return GetMediumSurfaceCrashResult(); + }break; + case FOREST:{ + return GetMediumSurfaceCrashResult(); + }break; + case TUNNEL:{ + return GetHardSurfaceCrashResult(); + }break; + case ICE:{ + return GetHardSurfaceCrashResult(); + }break; + default:{ + return GetMediumSurfaceCrashResult(); + } + } } \ No newline at end of file diff --git a/src/Terrain.h b/src/Terrain.h index 4ec7d06..ef0498e 100644 --- a/src/Terrain.h +++ b/src/Terrain.h @@ -57,5 +57,13 @@ namespace Terrain{ TUNNEL, ICE, }; + enum CrashSpeed{ + MAX, + MEDIUM, + LIGHT, + }; + using FuelDamage=float; + using KnockoutOccurs=bool; const std::string TerrainToString(const TerrainType type); + const std::pairGetFuelDamageTakenAndKnockoutEffect(const TerrainType type,const CrashSpeed crashSpeed); } \ No newline at end of file