diff --git a/.gitignore b/.gitignore index 4dd1d94d..70e41989 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ *.sln.docstates emsdk emscripten +*.o +*.h.gch # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs diff --git a/Crawler/Ability.cpp b/Crawler/Ability.cpp index 748a394b..a316c922 100644 --- a/Crawler/Ability.cpp +++ b/Crawler/Ability.cpp @@ -1,5 +1,9 @@ #include "Ability.h" +PrecastData::PrecastData(){}; +PrecastData::PrecastData(float castTime,float range,float size) + :castTime(castTime),range(range),size(size){precastTargetingRequired=true;}; + Ability::Ability(){}; -Ability::Ability(std::string name,float cooldownTime,int manaCost,Pixel barColor1,Pixel barColor2,bool precastTargetingRequired) - :name(name),cooldown(0),COOLDOWN_TIME(cooldownTime),manaCost(manaCost),barColor1(barColor1),barColor2(barColor2),precastTargetingRequired(precastTargetingRequired){} \ No newline at end of file +Ability::Ability(std::string name,float cooldownTime,int manaCost,Pixel barColor1,Pixel barColor2,PrecastData precastInfo) + :name(name),cooldown(0),COOLDOWN_TIME(cooldownTime),manaCost(manaCost),barColor1(barColor1),barColor2(barColor2),precastInfo(precastInfo){} \ No newline at end of file diff --git a/Crawler/Ability.h b/Crawler/Ability.h index 9f09536c..2b5606c4 100644 --- a/Crawler/Ability.h +++ b/Crawler/Ability.h @@ -1,6 +1,16 @@ #pragma once #include "olcPixelGameEngine.h" +struct PrecastData{ + float castTime; + float range; + float size; + //Whether or not this ability requires precasting (automatically set to true when precast time is greater than zero) + bool precastTargetingRequired=false; + PrecastData(); + PrecastData(float castTime,float range,float size); +}; + //Abilities are tied to class data which is defined in Class.cpp. struct Ability{ std::string name=""; @@ -8,8 +18,8 @@ struct Ability{ float COOLDOWN_TIME=0; int manaCost=0; Pixel barColor1,barColor2; - bool precastTargetingRequired; + PrecastData precastInfo; std::function<bool()>action=[&](){return false;}; Ability(); - Ability(std::string name,float cooldownTime,int manaCost,Pixel barColor1=VERY_DARK_RED,Pixel barColor2=DARK_RED,bool precastTargetingRequired=false); + Ability(std::string name,float cooldownTime,int manaCost,Pixel barColor1=VERY_DARK_RED,Pixel barColor2=DARK_RED,PrecastData precastInfo={}); }; \ No newline at end of file diff --git a/Crawler/Crawler b/Crawler/Crawler index 95857e93..72a67720 100755 Binary files a/Crawler/Crawler and b/Crawler/Crawler differ diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index e0202df8..885cf087 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -181,7 +181,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ player->SetY(player->GetY()+60*fElapsedTime*player->GetMoveSpdMult()); } player->SetFacingDirection(RIGHT); - if(player->GetState()==State::NORMAL){ + if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ player->UpdateWalkingAnimation(RIGHT); } setIdleAnimation=false; @@ -196,7 +196,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(setIdleAnimation){ player->SetFacingDirection(LEFT); - if(player->GetState()==State::NORMAL){ + if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ player->UpdateWalkingAnimation(LEFT); } } @@ -206,7 +206,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ player->SetY(player->GetY()-fElapsedTime*100*player->GetMoveSpdMult()); if(setIdleAnimation){ player->SetFacingDirection(UP); - if(player->GetState()==State::NORMAL){ + if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ player->UpdateWalkingAnimation(UP); } } @@ -216,7 +216,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ player->SetY(player->GetY()+fElapsedTime*100*player->GetMoveSpdMult()); if(setIdleAnimation){ player->SetFacingDirection(DOWN); - if(player->GetState()==State::NORMAL){ + if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ player->UpdateWalkingAnimation(DOWN); } } @@ -225,7 +225,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(UpReleased()){ player->SetLastReleasedMovementKey(UP); - if(player->GetState()==State::NORMAL){ + if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(RightHeld()){ player->UpdateWalkingAnimation(RIGHT); } else @@ -239,7 +239,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(RightReleased()){ player->SetLastReleasedMovementKey(RIGHT); - if(player->GetState()==State::NORMAL){ + if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(UpHeld()){ player->UpdateWalkingAnimation(UP); } else @@ -253,7 +253,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(LeftReleased()){ player->SetLastReleasedMovementKey(LEFT); - if(player->GetState()==State::NORMAL){ + if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(RightHeld()){ player->UpdateWalkingAnimation(RIGHT); } else @@ -267,7 +267,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(DownReleased()){ player->SetLastReleasedMovementKey(DOWN); - if(player->GetState()==State::NORMAL){ + if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(RightHeld()){ player->UpdateWalkingAnimation(RIGHT); } else @@ -566,6 +566,10 @@ void Crawler::RenderWorld(float fElapsedTime){ for(Bullet*b:bulletsLower){ b->Draw(); } + if(player->GetState()==State::PREP_CAST){ + float precastSize=GetPlayer()->castPrepAbility->precastInfo.size; + view.DrawDecal(GetWorldMousePos()-vf2d{precastSize/6,precastSize/6},GFX_Circle.Decal(),{precastSize/3,precastSize/3},{255,0,0,192}); + } #pragma region Foreground Rendering for(TileGroup&group:foregroundTileGroups){ if(view.IsRectVisible(group.GetRange().pos,group.GetRange().size)){ diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index fd4fd9ac..1a436447 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -154,7 +154,7 @@ State Player::GetState(){ void Player::Update(float fElapsedTime){ Ability&rightClickAbility=GetRightClickAbility(), - &ability1=GetAbility1(), + &ability=GetAbility1(), &ability2=GetAbility2(), &ability3=GetAbility3(), &ability4=GetAbility4(); @@ -256,7 +256,7 @@ void Player::Update(float fElapsedTime){ } } rightClickAbility.cooldown=std::max(0.f,rightClickAbility.cooldown-fElapsedTime); - ability1.cooldown=std::max(0.f,ability1.cooldown-fElapsedTime); + ability.cooldown=std::max(0.f,ability.cooldown-fElapsedTime); ability2.cooldown=std::max(0.f,ability2.cooldown-fElapsedTime); ability3.cooldown=std::max(0.f,ability3.cooldown-fElapsedTime); for(Monster&m:MONSTER_LIST){ @@ -291,41 +291,44 @@ void Player::Update(float fElapsedTime){ if(attack_cooldown_timer==0&&game->GetMouse(0).bHeld){ AutoAttack(); } - if(ability1.cooldown==0&&GetMana()>=ability1.manaCost&&game->GetKey(SHIFT).bHeld){ - if(ability1.action()){ - ability1.cooldown=ability1.COOLDOWN_TIME; - mana-=ability1.manaCost; - } - } else - if(ability1.cooldown==0&&GetMana()<ability1.manaCost&&game->GetKey(SHIFT).bPressed){ - notEnoughManaDisplay={ability1.name,1}; - } - if(ability2.cooldown==0&&GetMana()>=ability2.manaCost&&game->GetKey(SPACE).bPressed){ - if(ability2.action()){ - ability2.cooldown=ability2.COOLDOWN_TIME; - mana-=ability2.manaCost; - } - } else - if(ability2.cooldown==0&&GetMana()<ability2.manaCost&&game->GetKey(SPACE).bPressed){ - notEnoughManaDisplay={ability2.name,1}; - } - if(ability3.cooldown==0&&GetMana()>=ability3.manaCost&&game->GetKey(CTRL).bPressed){ - if(ability3.action()){ - ability3.cooldown=ability3.COOLDOWN_TIME; - mana-=ability3.manaCost; - } - } else - if(ability3.cooldown==0&&GetMana()<ability3.manaCost&&game->GetKey(CTRL).bPressed){ - notEnoughManaDisplay={ability3.name,1}; - } - if(rightClickAbility.cooldown==0&&GetMana()>=rightClickAbility.manaCost&&game->GetMouse(1).bHeld){ - if(rightClickAbility.action()){ - rightClickAbility.cooldown=rightClickAbility.COOLDOWN_TIME; - mana-=rightClickAbility.manaCost; + + + auto AllowedToCast=[&](Ability&ability){return !ability.precastInfo.precastTargetingRequired||ability.precastInfo.precastTargetingRequired&&GetState()==State::PREP_CAST;}; + auto CheckAndPerformAbility=[&](Ability&ability,HWButton key){ + if(ability.cooldown==0&&GetMana()>=ability.manaCost){ + if(key.bPressed||key.bReleased&&&ability==castPrepAbility&&GetState()==State::PREP_CAST){ + if(AllowedToCast(ability)&&ability.action()){ + ability.cooldown=ability.COOLDOWN_TIME; + mana-=ability.manaCost; + }else + if(ability.precastInfo.precastTargetingRequired&&GetState()!=State::PREP_CAST){ + PrepareCast(ability); + } + } + } else + if(ability.cooldown==0&&GetMana()<ability.manaCost&&key.bPressed){ + notEnoughManaDisplay={ability.name,1}; } - } else - if(rightClickAbility.cooldown==0&&GetMana()<rightClickAbility.manaCost&&game->GetMouse(1).bPressed){ - notEnoughManaDisplay={rightClickAbility.name,1}; + }; + CheckAndPerformAbility(GetAbility1(),game->GetKey(SHIFT)); + CheckAndPerformAbility(GetAbility2(),game->GetKey(SPACE)); + CheckAndPerformAbility(GetAbility3(),game->GetKey(CTRL)); + CheckAndPerformAbility(GetAbility4(),game->GetKey(R)); + CheckAndPerformAbility(GetRightClickAbility(),game->GetMouse(1)); + + if(GetState()==State::PREP_CAST){ + #define CheckAbilityKeyReleasedAndCastSpell(ability,input) \ + if(&ability==castPrepAbility&&input.bReleased){CastSpell(ability);} + + CheckAbilityKeyReleasedAndCastSpell(rightClickAbility,game->GetMouse(1)) + else + CheckAbilityKeyReleasedAndCastSpell(ability,game->GetKey(SHIFT)) + else + CheckAbilityKeyReleasedAndCastSpell(ability2,game->GetKey(SPACE)) + else + CheckAbilityKeyReleasedAndCastSpell(ability3,game->GetKey(CTRL)) + else + CheckAbilityKeyReleasedAndCastSpell(ability4,game->GetKey(R)) } switch(GetState()){ @@ -481,8 +484,9 @@ std::vector<Buff>Player::GetBuffs(BuffType buff){ return filteredBuffs; } -void Player::CastSpell(std::string name,float castTotalTime){ - castInfo={name,castTotalTime,castTotalTime}; +void Player::CastSpell(Ability&ability){ + castInfo={ability.name,ability.precastInfo.castTime,ability.precastInfo.castTime}; + SetState(State::NORMAL); } CastInfo&Player::GetCastInfo(){ @@ -492,4 +496,9 @@ CastInfo&Player::GetCastInfo(){ bool Player::CanPathfindTo(vf2d pos,vf2d targetPos,float range){ std::vector<vf2d>pathing=game->pathfinder.Solve_AStar(pos,targetPos,8,upperLevel); return pathing.size()>0&&pathing.size()<8;//We'll say 7 tiles or less is close enough to 650 range. Have a little bit of wiggle room. +} + +void Player::PrepareCast(Ability&ability){ + castPrepAbility=&ability; + SetState(State::PREP_CAST); } \ No newline at end of file diff --git a/Crawler/Player.h b/Crawler/Player.h index 0a79addb..2425631b 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -68,8 +68,10 @@ protected: float attack_range=1.5f; Key facingDirection; float swordSwingTimer=0; - void CastSpell(std::string name,float castTotalTime); - + void CastSpell(Ability&ability); + Ability*castPrepAbility; + void PrepareCast(Ability&ability); + vf2d precastLocation={}; 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/Wizard.cpp b/Crawler/Wizard.cpp index 98a5c765..fb78a9b2 100644 --- a/Crawler/Wizard.cpp +++ b/Crawler/Wizard.cpp @@ -15,7 +15,7 @@ Class Wizard::cl=WIZARD; Ability Wizard::rightClickAbility={"Teleport",8,5,VERY_DARK_BLUE,DARK_BLUE}; Ability Wizard::ability1={"Firebolt",6,30}; Ability Wizard::ability2={"Lightning Bolt",6,25}; -Ability Wizard::ability3={"Meteor",40,75,VERY_DARK_RED,VERY_DARK_RED,true}; +Ability Wizard::ability3={"Meteor",40,75,VERY_DARK_RED,VERY_DARK_RED,{1.5,900,400}}; Ability Wizard::ability4={"???",0,0}; AnimationState Wizard::idle_n=WIZARD_IDLE_N; AnimationState Wizard::idle_e=WIZARD_IDLE_E; @@ -120,7 +120,7 @@ void Wizard::InitializeClassAbilities(){ #pragma region Wizard Ability 3 (Meteor) Wizard::ability3.action= [&](){ - CastSpell("Meteor",1.5); + CastSpell(Wizard::ability3); game->AddEffect(std::make_unique<Meteor>(GetPos(),3,AnimationState::METEOR,OnUpperLevel(),vf2d{1,1},2)); return true; };