Fix bug with double rendering. Not using iterator marker to determine what else to draw. Fix bug with maximum health not healing to maximum when health is affected by Health %. Refactored wind speed to be a global value within the game's engine. Included speed reduction properties for wind when warrior blocks. Include projectiles/player being affected by wind and casting to be allowed when pushed by wind. Release Build 9507.

mac-build
sigonasr2 9 months ago
parent 25a2879929
commit 46ee54d7c5
  1. 38
      Adventures in Lestoria/AdventuresInLestoria.cpp
  2. 3
      Adventures in Lestoria/AdventuresInLestoria.h
  3. 3
      Adventures in Lestoria/Bullet.cpp
  4. 2
      Adventures in Lestoria/Monster.cpp
  5. 46
      Adventures in Lestoria/Player.cpp
  6. 19
      Adventures in Lestoria/Player.h
  7. 1
      Adventures in Lestoria/TODO.txt
  8. 2
      Adventures in Lestoria/Version.h
  9. 4
      Adventures in Lestoria/Zephy.cpp
  10. BIN
      x64/Release/Adventures in Lestoria.exe

@ -1403,15 +1403,19 @@ void AiL::RenderWorld(float fElapsedTime){
} }
#pragma endregion #pragma endregion
#pragma region Remaining Rendering #pragma region Remaining Rendering
for(Monster*m:monstersBeforeLower){ while(monstersBeforeLowerIt!=monstersBeforeLower.end()){
Monster*const m=*monstersBeforeLowerIt;
m->strategyDraw(this,*m,MONSTER_DATA[m->GetName()].GetAIStrategy()); m->strategyDraw(this,*m,MONSTER_DATA[m->GetName()].GetAIStrategy());
m->Draw(); m->Draw();
++monstersBeforeLowerIt;
} }
for(const Effect*const e:backgroundEffectsLower){ for(const Effect*const e:backgroundEffectsLower){
e->Draw(); e->Draw();
} }
for(const int dropInd:dropsBeforeLower){ while(dropsBeforeLowerIt!=dropsBeforeLower.end()){
const int dropInd=*dropsBeforeLowerIt;
ItemDrop::drops[dropInd].Draw(); ItemDrop::drops[dropInd].Draw();
++dropsBeforeLowerIt;
} }
if(!player->rendered&&!player->upperLevel){ if(!player->rendered&&!player->upperLevel){
player->rendered=true; player->rendered=true;
@ -1421,11 +1425,14 @@ void AiL::RenderWorld(float fElapsedTime){
} }
RenderPlayer(player->GetPos(),{1,1}); RenderPlayer(player->GetPos(),{1,1});
} }
for(Monster* m:monstersAfterLower){ while(monstersAfterLowerIt!=monstersAfterLower.end()){
Monster*const m=*monstersAfterLowerIt;
m->strategyDraw(this,*m,MONSTER_DATA[m->GetName()].GetAIStrategy()); m->strategyDraw(this,*m,MONSTER_DATA[m->GetName()].GetAIStrategy());
m->Draw(); m->Draw();
++monstersAfterLowerIt;
} }
for(const int dropInd:dropsAfterLower){ while(dropsAfterLowerIt!=dropsAfterLower.end()){
const int dropInd=*dropsAfterLowerIt;
ItemDrop::drops[dropInd].Draw(); ItemDrop::drops[dropInd].Draw();
} }
for(const Bullet*const b:bulletsLower){ for(const Bullet*const b:bulletsLower){
@ -1697,14 +1704,17 @@ void AiL::RenderWorld(float fElapsedTime){
} }
#pragma endregion #pragma endregion
#pragma region Remaining Upper Rendering #pragma region Remaining Upper Rendering
for(Monster*m:monstersBeforeUpper){ while(monstersBeforeUpperIt!=monstersBeforeUpper.end()){
Monster*const m=*monstersBeforeUpperIt;
m->strategyDraw(this,*m,MONSTER_DATA[m->GetName()].GetAIStrategy()); m->strategyDraw(this,*m,MONSTER_DATA[m->GetName()].GetAIStrategy());
m->Draw(); m->Draw();
++monstersBeforeUpperIt;
} }
for(const Effect*const e:backgroundEffectsUpper){ for(const Effect*const e:backgroundEffectsUpper){
e->Draw(); e->Draw();
} }
for(const int dropInd:dropsBeforeUpper){ while(dropsBeforeUpperIt!=dropsBeforeUpper.end()){
const int dropInd=*dropsBeforeUpperIt;
ItemDrop::drops[dropInd].Draw(); ItemDrop::drops[dropInd].Draw();
} }
if(!player->rendered&&player->upperLevel){ if(!player->rendered&&player->upperLevel){
@ -1715,12 +1725,16 @@ void AiL::RenderWorld(float fElapsedTime){
} }
RenderPlayer(player->GetPos(),{1,1}); RenderPlayer(player->GetPos(),{1,1});
} }
for(Monster*m:monstersAfterUpper){ while(monstersAfterUpperIt!=monstersAfterUpper.end()){
Monster*const m=*monstersAfterUpperIt;
m->strategyDraw(this,*m,MONSTER_DATA[m->GetName()].GetAIStrategy()); m->strategyDraw(this,*m,MONSTER_DATA[m->GetName()].GetAIStrategy());
m->Draw(); m->Draw();
++monstersAfterUpperIt;
} }
for(const int dropInd:dropsAfterUpper){ while(dropsAfterUpperIt!=dropsAfterUpper.end()){
const int dropInd=*dropsAfterUpperIt;
ItemDrop::drops[dropInd].Draw(); ItemDrop::drops[dropInd].Draw();
++dropsAfterUpperIt;
} }
for(const Bullet*const b:bulletsUpper){ for(const Bullet*const b:bulletsUpper){
b->Draw(); b->Draw();
@ -2285,6 +2299,7 @@ void AiL::_PrepareLevel(MapName map,MusicChange changeMusic){
totalDamageDealt=0; totalDamageDealt=0;
encounterStarted=false; encounterStarted=false;
totalBossEncounterMobs=0; totalBossEncounterMobs=0;
SetWindSpeed({});
Inventory::Clear("Monster Loot"); Inventory::Clear("Monster Loot");
Inventory::Clear("Stage Loot"); Inventory::Clear("Stage Loot");
Inventory::ResetLoadoutItemsUsed(); Inventory::ResetLoadoutItemsUsed();
@ -4274,3 +4289,10 @@ Overlay&AiL::GetOverlay(){
void AiL::SetOverlay(std::string animationName,Pixel overlayCol){ void AiL::SetOverlay(std::string animationName,Pixel overlayCol){
hudOverlay=Overlay{animationName,overlayCol}; hudOverlay=Overlay{animationName,overlayCol};
} }
void AiL::SetWindSpeed(vf2d newWindSpd){
windSpd=newWindSpd;
}
const vf2d&AiL::GetWindSpeed()const{
return windSpd;
}

@ -196,6 +196,7 @@ private:
float vignetteDisplayTime=0.f; float vignetteDisplayTime=0.f;
bool savingFile=false; bool savingFile=false;
bool prevStageCompleted=false; bool prevStageCompleted=false;
vf2d windSpd{};
void ValidateGameStatus(); void ValidateGameStatus();
void _PrepareLevel(MapName map,MusicChange changeMusic); void _PrepareLevel(MapName map,MusicChange changeMusic);
@ -351,6 +352,8 @@ public:
void SetBossIndicatorPos(const vf2d pos); void SetBossIndicatorPos(const vf2d pos);
void SetOverlay(std::string animationName,Pixel overlayCol); void SetOverlay(std::string animationName,Pixel overlayCol);
Overlay&GetOverlay(); Overlay&GetOverlay();
void SetWindSpeed(vf2d newWindSpd);
const vf2d&GetWindSpeed()const;
struct TileGroupData{ struct TileGroupData{
vi2d tilePos; vi2d tilePos;

@ -139,6 +139,7 @@ void Bullet::_Update(const float fElapsedTime){
}else{ }else{
pos+=vel*fElapsedTime; pos+=vel*fElapsedTime;
} }
if(IsPlayerAutoAttackProjectile()){pos+=game->GetWindSpeed()*game->GetElapsedTime();}
if(/*World size in PIXELS!*/vi2d worldSize=game->GetCurrentMapData().MapSize*game->GetCurrentMapData().TileSize;pos.x+radius<-WINDOW_SIZE.x||pos.x-radius>worldSize.x+WINDOW_SIZE.x||pos.y+radius<-WINDOW_SIZE.y||pos.y-radius>worldSize.y+WINDOW_SIZE.y){ if(/*World size in PIXELS!*/vi2d worldSize=game->GetCurrentMapData().MapSize*game->GetCurrentMapData().TileSize;pos.x+radius<-WINDOW_SIZE.x||pos.x-radius>worldSize.x+WINDOW_SIZE.x||pos.y+radius<-WINDOW_SIZE.y||pos.y-radius>worldSize.y+WINDOW_SIZE.y){
dead=true; dead=true;
return; return;
@ -225,5 +226,5 @@ const bool Bullet::IsPlayerAutoAttackProjectile()const{
} }
void Bullet::AddVelocity(vf2d vel){ void Bullet::AddVelocity(vf2d vel){
this->vel+=vel; this->vel+=vel*game->GetElapsedTime();
} }

@ -440,7 +440,7 @@ void Monster::Draw()const{
if(GetZ()>0){ if(GetZ()>0){
vf2d shadowScale=vf2d{8*GetSizeMult()/3.f,1}/std::max(1.f,GetZ()/24); vf2d shadowScale=vf2d{8*GetSizeMult()/3.f,1}/std::max(1.f,GetZ()/24);
game->view.DrawDecal(drawPos-vf2d{3,3}*shadowScale/2+vf2d{0,6*GetSizeMult()},GFX["circle.png"].Decal(),shadowScale,BLACK); game->view.DrawDecal(GetPos()+hitTimerOffset-vf2d{3,3}*shadowScale/2+vf2d{0,6*GetSizeMult()},GFX["circle.png"].Decal(),shadowScale,BLACK);
} }
const bool NotOnTitleScreen=GameState::STATE!=GameState::states[States::MAIN_MENU]; const bool NotOnTitleScreen=GameState::STATE!=GameState::states[States::MAIN_MENU];

@ -143,7 +143,7 @@ void Player::ForceSetPos(vf2d pos){
Moved(); Moved();
} }
bool Player::_SetX(float x,const bool playerInvoked){ bool Player::_SetX(float x,MoveFlag::MoveFlag flags,const bool playerInvoked){
vf2d newPos={x,pos.y}; vf2d newPos={x,pos.y};
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth; vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel); geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
@ -152,7 +152,7 @@ bool Player::_SetX(float x,const bool playerInvoked){
#pragma endregion #pragma endregion
if(NoTileCollisionExistsHere()){ if(NoTileCollisionExistsHere()){
pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult())); pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
Moved(); Moved(flags);
return true; return true;
} else { } else {
geom2d::rect<float>collision={collisionRect.pos,collisionRect.size}; geom2d::rect<float>collision={collisionRect.pos,collisionRect.size};
@ -162,21 +162,21 @@ bool Player::_SetX(float x,const bool playerInvoked){
collision.pos+=tilePos; collision.pos+=tilePos;
if(NoPlayerCollisionWithTile()){ if(NoPlayerCollisionWithTile()){
pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult())); pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
Moved(); Moved(flags);
return true; return true;
}else }else
if(playerInvoked){ //If player invoked, we'll try the smart move system. if(playerInvoked){ //If player invoked, we'll try the smart move system.
vf2d pushDir=geom2d::line<float>(collision.middle(),pos).vector().norm(); vf2d pushDir=geom2d::line<float>(collision.middle(),pos).vector().norm();
newPos={newPos.x,pos.y+pushDir.y*12}; newPos={newPos.x,pos.y+pushDir.y*12};
if(NoPlayerCollisionWithTile()){ if(NoPlayerCollisionWithTile()){
return _SetY(pos.y+pushDir.y*game->GetElapsedTime()*12,false); return _SetY(pos.y+pushDir.y*game->GetElapsedTime()*12,flags,false);
} }
} }
} }
return false; return false;
}; };
bool Player::_SetY(float y,const bool playerInvoked){ bool Player::_SetY(float y,MoveFlag::MoveFlag flags,const bool playerInvoked){
vf2d newPos={pos.x,y}; vf2d newPos={pos.x,y};
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth; vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel); geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
@ -185,7 +185,7 @@ bool Player::_SetY(float y,const bool playerInvoked){
#pragma endregion #pragma endregion
if(NoTileCollisionExistsHere()){ if(NoTileCollisionExistsHere()){
pos.y=std::clamp(y,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().height*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult())); pos.y=std::clamp(y,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().height*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
Moved(); Moved(flags);
return true; return true;
} else { } else {
geom2d::rect<float>collision={collisionRect.pos,collisionRect.size}; geom2d::rect<float>collision={collisionRect.pos,collisionRect.size};
@ -195,37 +195,37 @@ bool Player::_SetY(float y,const bool playerInvoked){
collision.pos+=tilePos; collision.pos+=tilePos;
if(NoPlayerCollisionWithTile()){ if(NoPlayerCollisionWithTile()){
pos.y=std::clamp(y,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().height*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult())); pos.y=std::clamp(y,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().height*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
Moved(); Moved(flags);
return true; return true;
}else }else
if(playerInvoked){ //If player invoked, we'll try the smart move system.{ if(playerInvoked){ //If player invoked, we'll try the smart move system.{
vf2d pushDir=geom2d::line<float>(collision.middle(),pos).vector().norm(); vf2d pushDir=geom2d::line<float>(collision.middle(),pos).vector().norm();
newPos={pos.x+pushDir.x*12,newPos.y}; newPos={pos.x+pushDir.x*12,newPos.y};
if(NoPlayerCollisionWithTile()){ if(NoPlayerCollisionWithTile()){
return _SetX(pos.x+pushDir.x*game->GetElapsedTime()*12,false); return _SetX(pos.x+pushDir.x*game->GetElapsedTime()*12,flags,false);
} }
} }
} }
return false; return false;
} }
bool Player::SetX(float x){ bool Player::SetX(float x,MoveFlag::MoveFlag flags){
return _SetX(x); return _SetX(x,flags);
} }
bool Player::SetY(float y){ bool Player::SetY(float y,MoveFlag::MoveFlag flags){
return _SetY(y); return _SetY(y,flags);
} }
void Player::SetZ(float z){ void Player::SetZ(float z){
this->z=z; this->z=z;
} }
bool Player::SetPos(vf2d pos){ bool Player::SetPos(vf2d pos,MoveFlag::MoveFlag flags){
bool resultX=SetX(pos.x); bool resultX=SetX(pos.x,flags);
bool resultY=SetY(pos.y); bool resultY=SetY(pos.y,flags);
if(resultY&&!resultX){ if(resultY&&!resultX){
resultX=SetX(pos.x); resultX=SetX(pos.x,flags);
} }
return resultX||resultY; return resultX||resultY;
} }
@ -548,6 +548,12 @@ void Player::Update(float fElapsedTime){
ERR(std::format("WARNING! The velocity vector for the player is NOT normal! Current vel:{} . Attempting manual resetting of velocity.",vel.str())); ERR(std::format("WARNING! The velocity vector for the player is NOT normal! Current vel:{} . Attempting manual resetting of velocity.",vel.str()));
vel={}; vel={};
} }
vf2d finalWindSpd=game->GetWindSpeed();
if(GetState()==State::BLOCK)finalWindSpd*=1-("Warrior.Right Click Ability.Knockback Reduction"_F/100.f);
game->GetPlayer()->SetPos(game->GetPlayer()->GetPos()+finalWindSpd*game->GetElapsedTime(),MoveFlag::PREVENT_CAST_CANCELLING);
if(vel!=vf2d{0,0}){ if(vel!=vf2d{0,0}){
float newX=pos.x+vel.x*fElapsedTime; float newX=pos.x+vel.x*fElapsedTime;
float newY=pos.y+vel.y*fElapsedTime; float newY=pos.y+vel.y*fElapsedTime;
@ -875,8 +881,8 @@ void Player::CancelCast(){
} }
} }
void Player::Moved(){ void Player::Moved(MoveFlag::MoveFlag flags){
if(state==State::CASTING){ if(!(flags&MoveFlag::PREVENT_CAST_CANCELLING)&&state==State::CASTING){
state=State::NORMAL; state=State::NORMAL;
castPrepAbility->waitForRelease=true; castPrepAbility->waitForRelease=true;
CancelCast(); CancelCast();
@ -1078,7 +1084,7 @@ void Player::_SetIframes(float duration){
} }
bool Player::Heal(int damage,bool suppressDamageNumber){ bool Player::Heal(int damage,bool suppressDamageNumber){
hp=std::clamp(hp+damage,0,int(GetStat("Health"))); hp=std::clamp(hp+damage,0,int(GetMaxHealth()));
if(!suppressDamageNumber&&damage>0){ if(!suppressDamageNumber&&damage>0){
DAMAGENUMBER_LIST.push_back(std::make_shared<DamageNumber>(GetPos(),damage,true,HEALTH_GAIN)); DAMAGENUMBER_LIST.push_back(std::make_shared<DamageNumber>(GetPos(),damage,true,HEALTH_GAIN));
} }
@ -1577,5 +1583,5 @@ void Player::ProximityKnockback(const vf2d centerPoint,const float knockbackFact
} }
void Player::AddVelocity(vf2d vel){ void Player::AddVelocity(vf2d vel){
this->vel+=vel; this->vel+=vel*game->GetElapsedTime();
} }

@ -62,6 +62,13 @@ struct CastInfo{
vf2d castPos{}; vf2d castPos{};
}; };
namespace MoveFlag{
enum MoveFlag{
NONE = 0b0,
PREVENT_CAST_CANCELLING = 0b1,
};
};
class EntityStats{ class EntityStats{
friend class Inventory; friend class Inventory;
ItemAttributable equipStats; //The stats after gear calculations are applied. ItemAttributable equipStats; //The stats after gear calculations are applied.
@ -148,12 +155,12 @@ public:
void RestoreMana(int amt,bool suppressDamageNumber=false); void RestoreMana(int amt,bool suppressDamageNumber=false);
void ConsumeMana(int amt); void ConsumeMana(int amt);
//Returns true if the move was valid and successful. //Returns true if the move was valid and successful.
bool SetX(float x); bool SetX(float x,MoveFlag::MoveFlag flags=MoveFlag::NONE);
//Returns true if the move was valid and successful. //Returns true if the move was valid and successful.
bool SetY(float y); bool SetY(float y,MoveFlag::MoveFlag flags=MoveFlag::NONE);
void SetZ(float z); void SetZ(float z);
//Returns true if the move was valid and successful. //Returns true if the move was valid and successful.
bool SetPos(vf2d pos); bool SetPos(vf2d pos,MoveFlag::MoveFlag flags=MoveFlag::NONE);
//Ignores collision checking and sets the player at the given position. //Ignores collision checking and sets the player at the given position.
void ForceSetPos(vf2d pos); void ForceSetPos(vf2d pos);
void SetState(State::State newState); void SetState(State::State newState);
@ -189,7 +196,7 @@ public:
bool IsOutOfCombat(); bool IsOutOfCombat();
float GetEndZoneStandTime(); float GetEndZoneStandTime();
//Triggers when the player has moved. //Triggers when the player has moved.
void Moved(); void Moved(MoveFlag::MoveFlag flags=MoveFlag::NONE);
virtual ~Player()=default; virtual ~Player()=default;
virtual Class GetClass()=0; virtual Class GetClass()=0;
virtual bool AutoAttack()=0; virtual bool AutoAttack()=0;
@ -311,12 +318,12 @@ private:
//If playerInvoked is true, this means the player was the one that instantiated this input, and it's not an extra movement done via collision. //If playerInvoked is true, this means the player was the one that instantiated this input, and it's not an extra movement done via collision.
//Set playerInvoked to false when you don't want a movement loop due to collisions. //Set playerInvoked to false when you don't want a movement loop due to collisions.
//Typical usage is playerInvoked is true on first call, and playerInvoked is false on all subsequent chained calls. //Typical usage is playerInvoked is true on first call, and playerInvoked is false on all subsequent chained calls.
bool _SetX(float x,const bool playerInvoked=true); bool _SetX(float x,MoveFlag::MoveFlag flags=MoveFlag::NONE,const bool playerInvoked=true);
//Returns true if the move was valid and successful. //Returns true if the move was valid and successful.
//If playerInvoked is true, this means the player was the one that instantiated this input, and it's not an extra movement done via collision. //If playerInvoked is true, this means the player was the one that instantiated this input, and it's not an extra movement done via collision.
//Set playerInvoked to false when you don't want a movement loop due to collisions. //Set playerInvoked to false when you don't want a movement loop due to collisions.
//Typical usage is playerInvoked is true on first call, and playerInvoked is false on all subsequent chained calls. //Typical usage is playerInvoked is true on first call, and playerInvoked is false on all subsequent chained calls.
bool _SetY(float y,const bool playerInvoked=true); bool _SetY(float y,MoveFlag::MoveFlag flags=MoveFlag::NONE,const bool playerInvoked=true);
const bool UsingAutoAim()const; const bool UsingAutoAim()const;
void InitializeMinimapImage(); void InitializeMinimapImage();
bool lowHealthSoundPlayed=false; bool lowHealthSoundPlayed=false;

@ -23,4 +23,5 @@ New Monster Sound Effects
DEMO DEMO
==== ====
Health % max health healing bug
Go back and apply new rendering code. Go back and apply new rendering code.

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1 #define VERSION_MAJOR 1
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 3 #define VERSION_PATCH 3
#define VERSION_BUILD 9497 #define VERSION_BUILD 9507
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -256,10 +256,8 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy)
vf2d windSpd={m.F(A::WIND_STRENGTH)*"Player.MoveSpd"_F,0.f}; //Assume we landed left and causing a wind attack to the right. vf2d windSpd={m.F(A::WIND_STRENGTH)*"Player.MoveSpd"_F,0.f}; //Assume we landed left and causing a wind attack to the right.
if(!LeftLandingSite)windSpd*=-1; if(!LeftLandingSite)windSpd*=-1;
game->GetPlayer()->AddVelocity(windSpd); game->SetWindSpeed(windSpd);
m.F(A::CASTING_TIMER)=ConfigFloat("Wind Attack.Wind Duration"); m.F(A::CASTING_TIMER)=ConfigFloat("Wind Attack.Wind Duration");
std::for_each(BULLET_LIST.begin(),BULLET_LIST.end(),[&](const std::unique_ptr<Bullet>&bullet){if(bullet->IsPlayerAutoAttackProjectile()){bullet->AddVelocity(windSpd);}});
#pragma endregion #pragma endregion
if(m.F(A::CASTING_TIMER)<=0.f){ if(m.F(A::CASTING_TIMER)<=0.f){

Loading…
Cancel
Save