|
|
|
@ -5,7 +5,7 @@ |
|
|
|
|
#define AUDIO_SOURCE_IMPLEMENTATION |
|
|
|
|
#define OLC_PGEX_QUICKGUI |
|
|
|
|
|
|
|
|
|
//#define SPLASH_ENABLED
|
|
|
|
|
#define SPLASH_ENABLED |
|
|
|
|
#ifdef SPLASH_ENABLED |
|
|
|
|
#define OLC_PGEX_SPLASHSCREEN |
|
|
|
|
#endif |
|
|
|
@ -64,6 +64,8 @@ void VirusAttack::InitializeImages(){ |
|
|
|
|
LoadImage(SEGMENT_BAR,"assets/segmentBar.png",false,false); |
|
|
|
|
LoadImage(HOODED_FIGURE,"assets/hooded_figure.png"); |
|
|
|
|
LoadImage(SPOOK_HOODED_FIGURE,"assets/spook_hooded_figure.png"); |
|
|
|
|
LoadImage(RESTART,"assets/restart.png"); |
|
|
|
|
LoadImage(RESTART_HOVER,"assets/restartHover.png"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void VirusAttack::InitializeLevelData(){ |
|
|
|
@ -71,6 +73,7 @@ void VirusAttack::InitializeLevelData(){ |
|
|
|
|
{ |
|
|
|
|
//Stage 1 data.
|
|
|
|
|
LevelName stage=STAGE1; |
|
|
|
|
levelData[stage].name=stage; |
|
|
|
|
levelData[stage].cameraStart={96,96}; |
|
|
|
|
levelData[stage].worldZoom={1,1}; |
|
|
|
|
levelData[stage].scenario=scenarios[0]; |
|
|
|
@ -93,12 +96,13 @@ void VirusAttack::InitializeLevelData(){ |
|
|
|
|
{ |
|
|
|
|
//Stage 2 data.
|
|
|
|
|
LevelName stage=STAGE2; |
|
|
|
|
levelData[stage].name=stage; |
|
|
|
|
levelData[stage].cameraStart={96,96}; |
|
|
|
|
levelData[stage].worldZoom={1,1}; |
|
|
|
|
levelData[stage].size={16,16}; |
|
|
|
|
levelData[stage].scenario=scenarios[1]; |
|
|
|
|
levelData[stage].levelColor=DARK_GREEN; |
|
|
|
|
levelData[stage].bgm=Sound::COSMOS; |
|
|
|
|
levelData[stage].bgm=Sound::GRAVITY; |
|
|
|
|
levelData[stage].player_starting_resources={10,10,10,10,10}; |
|
|
|
|
levelData[stage].enemy_starting_resources={0,0,0,0,0}; |
|
|
|
|
{ |
|
|
|
@ -129,6 +133,7 @@ bool VirusAttack::OnUserCreate(){ |
|
|
|
|
memoryAllocatorBox.Initialize(CONSTANT::MEMORY_ALLOCATOR_BOX_DISPLAY_STRING,{},CONSTANT::MEMORY_ALLOCATOR_BOX_HEADER_STRING); |
|
|
|
|
memoryAllocatorBox.SetVisible(false); |
|
|
|
|
platformCreationBox.SetVisible(false); |
|
|
|
|
restartBox.SetVisible(false); |
|
|
|
|
|
|
|
|
|
IMAGES[MINIMAP_OUTLINE]=std::make_unique<Renderable>(); |
|
|
|
|
IMAGES[MINIMAP_OUTLINE]->Create(64,64); |
|
|
|
@ -212,6 +217,8 @@ void VirusAttack::LoadLevel(LevelName level){ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void VirusAttack::InitializeGUIs(){ |
|
|
|
|
restartButton=new QuickGUI::TransparentImageButton(restartManager,*IMAGES[RESTART],*IMAGES[RESTART_HOVER],{1,1},{float(ScreenWidth()-32),12.f},{28,28}); |
|
|
|
|
|
|
|
|
|
unitCreationList.colNormal = olc::DARK_GREEN; |
|
|
|
|
unitCreationList.colHover = olc::GREEN; |
|
|
|
|
unitCreationList.colClick = olc::YELLOW; |
|
|
|
@ -233,11 +240,22 @@ void VirusAttack::InitializeGUIs(){ |
|
|
|
|
|
|
|
|
|
unitCreationList.DisplayAllControls(false); |
|
|
|
|
platformCreationList.DisplayAllControls(false); |
|
|
|
|
|
|
|
|
|
campaignStartButton=new QuickGUI::TransparentButton(mainMenu,"Start Campaign",{float(ScreenWidth()/2)-120.f,80+47.5f*0+10},{240,24},CONSTANT::INCREASE_VALUE_COLOR); |
|
|
|
|
audioToggleButton=new QuickGUI::TransparentButton(mainMenu,"Audio: On",{float(ScreenWidth()/2)-120.f,80+47.5f*1+10},{240,24},CONSTANT::INCREASE_VALUE_COLOR); |
|
|
|
|
difficultyToggleButton=new QuickGUI::TransparentButton(mainMenu,"Difficulty: Normal",{float(ScreenWidth()/2)-120.f,80+47.5f*2+10},{240,24},CONSTANT::INCREASE_VALUE_COLOR); |
|
|
|
|
exitGameButton=new QuickGUI::TransparentButton(mainMenu,"Exit Game",{float(ScreenWidth()/2)-120.f,80+47.5f*3+10},{240,24},CONSTANT::INCREASE_VALUE_COLOR); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void VirusAttack::InitializeScenarios(){ |
|
|
|
|
scenarios.emplace_back(new Stage1(this)); |
|
|
|
|
scenarios.emplace_back(new Stage1(this)); |
|
|
|
|
scenarios.emplace_back(new Stage2(this)); |
|
|
|
|
scenarios.emplace_back(new Stage3(this)); |
|
|
|
|
scenarios.emplace_back(new Stage4(this)); |
|
|
|
|
scenarios.emplace_back(new Stage5(this)); |
|
|
|
|
scenarios.emplace_back(new Stage6(this)); |
|
|
|
|
scenarios.emplace_back(new Stage7(this)); |
|
|
|
|
scenarios.emplace_back(new Stage8(this)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void VirusAttack::InitializeSounds(){ |
|
|
|
@ -285,8 +303,9 @@ bool VirusAttack::UnitCreationClickHandled(){ |
|
|
|
|
CheckClick(MemoryGuard,memoryGuardButton,IsPlatform) |
|
|
|
|
return false;
|
|
|
|
|
} |
|
|
|
|
#define EnableAndHoverCheck(UnitClass,Button,box) \ |
|
|
|
|
Button->Enable(CanAfford(player_resources,UnitClass::resourceCost)); \
|
|
|
|
|
#define EnableAndHoverCheck(UnitClass,Button,box,limited) \ |
|
|
|
|
Button->Enable(CanAfford(player_resources,UnitClass::resourceCost)&&(!limited||limited&&!limitedBuildOptions)); \
|
|
|
|
|
if(limited&&!limitedBuildOptions){Button->bVisible=false;} \
|
|
|
|
|
if(Button->bHover){ \
|
|
|
|
|
box.Initialize(UnitClass::unitDescription, GetMousePos(), UnitClass::unitName,nullptr,{120,36},nullptr,UnitClass::resourceCost); \
|
|
|
|
|
hovering=true; \
|
|
|
|
@ -295,19 +314,19 @@ bool VirusAttack::UnitCreationClickHandled(){ |
|
|
|
|
} else { \
|
|
|
|
|
box.SetBackgroundColor(VERY_DARK_GREY/2); \
|
|
|
|
|
} \
|
|
|
|
|
}
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void VirusAttack::UpdateUnitCreationListGUI(bool allocatorSelected){ |
|
|
|
|
unitCreationList.DisplayAllControls(allocatorSelected); |
|
|
|
|
|
|
|
|
|
bool hovering=false; |
|
|
|
|
EnableAndHoverCheck(LeftShifter,leftShifterButton,unitCreationBox) |
|
|
|
|
EnableAndHoverCheck(RightShifter,rightShifterButton,unitCreationBox) |
|
|
|
|
EnableAndHoverCheck(BitRestorer,bitRestorerButton,unitCreationBox) |
|
|
|
|
EnableAndHoverCheck(MemorySwapper,memorySwapperButton,unitCreationBox) |
|
|
|
|
EnableAndHoverCheck(BitRestorer,bitRestorerButton,unitCreationBox) |
|
|
|
|
EnableAndHoverCheck(Corrupter,corrupterButton,unitCreationBox) |
|
|
|
|
EnableAndHoverCheck(_Platform,platformButton,unitCreationBox) |
|
|
|
|
EnableAndHoverCheck(LeftShifter,leftShifterButton,unitCreationBox,false) |
|
|
|
|
EnableAndHoverCheck(RightShifter,rightShifterButton,unitCreationBox,false) |
|
|
|
|
EnableAndHoverCheck(BitRestorer,bitRestorerButton,unitCreationBox,true) |
|
|
|
|
EnableAndHoverCheck(MemorySwapper,memorySwapperButton,unitCreationBox,true) |
|
|
|
|
EnableAndHoverCheck(BitRestorer,bitRestorerButton,unitCreationBox,true) |
|
|
|
|
EnableAndHoverCheck(Corrupter,corrupterButton,unitCreationBox,true) |
|
|
|
|
EnableAndHoverCheck(_Platform,platformButton,unitCreationBox,true) |
|
|
|
|
|
|
|
|
|
if(!hovering){ |
|
|
|
|
unitCreationBox.SetVisible(false); |
|
|
|
@ -319,10 +338,10 @@ void VirusAttack::UpdateUnitCreationListGUI(bool allocatorSelected){ |
|
|
|
|
void VirusAttack::UpdatePlatformCreationListGUI(bool platformSelected){ |
|
|
|
|
platformCreationList.DisplayAllControls(platformSelected); |
|
|
|
|
bool hovering=false; |
|
|
|
|
EnableAndHoverCheck(RAMBank,ramBankButton,platformCreationBox) |
|
|
|
|
EnableAndHoverCheck(Refresher,refresherButton,platformCreationBox) |
|
|
|
|
EnableAndHoverCheck(Turret,turretButton,platformCreationBox) |
|
|
|
|
EnableAndHoverCheck(MemoryGuard,memoryGuardButton,platformCreationBox) |
|
|
|
|
EnableAndHoverCheck(RAMBank,ramBankButton,platformCreationBox,false) |
|
|
|
|
EnableAndHoverCheck(Refresher,refresherButton,platformCreationBox,true) |
|
|
|
|
EnableAndHoverCheck(Turret,turretButton,platformCreationBox,true) |
|
|
|
|
EnableAndHoverCheck(MemoryGuard,memoryGuardButton,platformCreationBox,true) |
|
|
|
|
|
|
|
|
|
if(!hovering){ |
|
|
|
|
platformCreationBox.SetVisible(false); |
|
|
|
@ -649,144 +668,169 @@ void VirusAttack::RenderCollectionPoints(CollectionPoint*cp){ |
|
|
|
|
|
|
|
|
|
bool VirusAttack::OnUserUpdate(float fElapsedTime){ |
|
|
|
|
UpdateMatrixTexture(fElapsedTime); |
|
|
|
|
if(playerInControl){ |
|
|
|
|
HandleDraggingSelection(); |
|
|
|
|
HandleRightClickMove(); |
|
|
|
|
HandlePanAndZoom(fElapsedTime); |
|
|
|
|
HandleMinimapClick(); |
|
|
|
|
} |
|
|
|
|
currentLevel->scenario->_Update(); |
|
|
|
|
AL.vecPos=game.ScreenToWorld(GetScreenSize()/2); |
|
|
|
|
AL.fSoundFXVolume=std::min(1.f,game.GetWorldScale().x); |
|
|
|
|
AL.OnUserUpdate(fElapsedTime); |
|
|
|
|
|
|
|
|
|
for(auto&tile:TileManager::visibleTiles){ |
|
|
|
|
tile.second-=fElapsedTime; |
|
|
|
|
} |
|
|
|
|
switch(state){ |
|
|
|
|
#pragma region MAIN_MENU |
|
|
|
|
case GameState::MAIN_MENU:{ |
|
|
|
|
mainMenu.Update(this); |
|
|
|
|
mainMenu.DrawDecal(this); |
|
|
|
|
}break; |
|
|
|
|
#pragma endregion |
|
|
|
|
#pragma region GAMEPLAY |
|
|
|
|
case GameState::GAMEPLAY:{ |
|
|
|
|
if(playerInControl){ |
|
|
|
|
HandleDraggingSelection(); |
|
|
|
|
HandleRightClickMove(); |
|
|
|
|
HandlePanAndZoom(fElapsedTime); |
|
|
|
|
HandleMinimapClick(); |
|
|
|
|
} |
|
|
|
|
restartManager.Update(this); |
|
|
|
|
HandleRestartButton(fElapsedTime); |
|
|
|
|
PerformLevelTransition(fElapsedTime); |
|
|
|
|
currentLevel->scenario->_Update(); |
|
|
|
|
AL.vecPos=game.ScreenToWorld(GetScreenSize()/2); |
|
|
|
|
AL.fSoundFXVolume=std::min(1.f,game.GetWorldScale().x); |
|
|
|
|
AL.OnUserUpdate(fElapsedTime); |
|
|
|
|
|
|
|
|
|
for(auto&tile:TileManager::visibleTiles){ |
|
|
|
|
tile.second-=fElapsedTime; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::erase_if(TileManager::visibleTiles,[](std::pair<vf2d,float> key){return key.second<=0;}); |
|
|
|
|
std::erase_if(TileManager::visibleTiles,[](std::pair<vf2d,float> key){return key.second<=0;}); |
|
|
|
|
|
|
|
|
|
CalculateUsedMemory(); |
|
|
|
|
for(auto&u:units){ |
|
|
|
|
u->SaveMemory(); |
|
|
|
|
std::weak_ptr<Unit>closestUnit; |
|
|
|
|
float closestDist=999999; |
|
|
|
|
for(auto&u2:units){ |
|
|
|
|
IdentifyClosestTarget(closestUnit,closestDist,u,u2); |
|
|
|
|
CollisionChecking(u,u2); |
|
|
|
|
} |
|
|
|
|
if(u->IsFriendly()){ |
|
|
|
|
for(int y=-2;y<3;y++){ |
|
|
|
|
for(int x=-2;x<3;x++){ |
|
|
|
|
if(abs(x)+abs(y)<=2){ |
|
|
|
|
TileManager::visibleTiles[u->GetPos()/24/4+vi2d(x,y)]=5; |
|
|
|
|
CalculateUsedMemory(); |
|
|
|
|
for(auto&u:units){ |
|
|
|
|
u->SaveMemory(); |
|
|
|
|
std::weak_ptr<Unit>closestUnit; |
|
|
|
|
float closestDist=999999; |
|
|
|
|
for(auto&u2:units){ |
|
|
|
|
IdentifyClosestTarget(closestUnit,closestDist,u,u2); |
|
|
|
|
CollisionChecking(u,u2); |
|
|
|
|
} |
|
|
|
|
if(u->IsFriendly()){ |
|
|
|
|
for(int y=-2;y<3;y++){ |
|
|
|
|
for(int x=-2;x<3;x++){ |
|
|
|
|
if(abs(x)+abs(y)<=2){ |
|
|
|
|
TileManager::visibleTiles[u->GetPos()/24/4+vi2d(x,y)]=5; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
u->AttemptAttack(u,closestUnit,units,debuffIcons,IMAGES); |
|
|
|
|
u->_Update(this,SOUNDS,player_resources,enemy_resources,queuedUnits,resourceGainTimer,resourceGainIcons,IMAGES); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
u->AttemptAttack(u,closestUnit,units,debuffIcons,IMAGES); |
|
|
|
|
u->_Update(this,SOUNDS,player_resources,enemy_resources,queuedUnits,resourceGainTimer,resourceGainIcons,IMAGES); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::erase_if(units,[&](std::shared_ptr<Unit>u){ |
|
|
|
|
if(u->GetHealth()==0){ |
|
|
|
|
u->OnDeath(SOUNDS); |
|
|
|
|
deathAnimations.emplace_back(std::make_unique<DeathAnimation>(this,u->GetPos(),u->GetImage(),*IMAGES[MATRIX],u->IsFriendly())); |
|
|
|
|
return true; |
|
|
|
|
} else { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
for(auto&queuedUnit:queuedUnits){ |
|
|
|
|
units.push_back(std::move(queuedUnit)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
queuedUnits.clear(); |
|
|
|
|
|
|
|
|
|
DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+game.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*game.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,164}/2); |
|
|
|
|
game.DrawPartialDecal({0,0},WORLD_SIZE*CONSTANT::TILE_SIZE,IMAGES[TILE]->Decal(),{0,0},WORLD_SIZE*CONSTANT::TILE_SIZE,currentLevel->levelColor); |
|
|
|
|
std::erase_if(units,[&](std::shared_ptr<Unit>u){ |
|
|
|
|
if(u->GetHealth()==0){ |
|
|
|
|
u->OnDeath(SOUNDS); |
|
|
|
|
deathAnimations.emplace_back(std::make_unique<DeathAnimation>(this,u->GetPos(),u->GetImage(),*IMAGES[MATRIX],u->IsFriendly())); |
|
|
|
|
return true; |
|
|
|
|
} else { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
for(auto&u:units){ |
|
|
|
|
u->DrawRangeIndicator(this,game,IMAGES); |
|
|
|
|
} |
|
|
|
|
for(auto&queuedUnit:queuedUnits){ |
|
|
|
|
units.push_back(std::move(queuedUnit)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for(auto&u:units){ |
|
|
|
|
u->Draw(game,IMAGES); |
|
|
|
|
if(u->IsGuarded()){ |
|
|
|
|
game.DrawDecal(u->GetPos()+vf2d{float(u->GetUnitSize().x/2),-float(u->GetUnitSize().y/2)}-vf2d{float(IMAGES[GUARD_ICON]->Sprite()->width),0.f}*0.375,IMAGES[GUARD_ICON]->Decal(),{0.375,0.375}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for(auto&deadUnit:deathAnimations){ |
|
|
|
|
deadUnit->Update(fElapsedTime); |
|
|
|
|
deadUnit->Draw(game,this); |
|
|
|
|
} |
|
|
|
|
queuedUnits.clear(); |
|
|
|
|
|
|
|
|
|
std::erase_if(deathAnimations,[](auto&u){return u->IsDone();}); |
|
|
|
|
DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+game.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*game.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,164}/2); |
|
|
|
|
game.DrawPartialDecal({0,0},WORLD_SIZE*CONSTANT::TILE_SIZE,IMAGES[TILE]->Decal(),{0,0},WORLD_SIZE*CONSTANT::TILE_SIZE,currentLevel->levelColor); |
|
|
|
|
|
|
|
|
|
for(auto&collectionPoint:collectionPoints){ |
|
|
|
|
collectionPoint->Update(this,*IMAGES[MATRIX]); |
|
|
|
|
RenderCollectionPoints(collectionPoint.get()); |
|
|
|
|
} |
|
|
|
|
for(auto&u:units){ |
|
|
|
|
u->DrawRangeIndicator(this,game,IMAGES); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for(auto&u:units){ |
|
|
|
|
u->DrawUnitDamageStats(this,game,IMAGES); |
|
|
|
|
} |
|
|
|
|
for(auto&u:units){ |
|
|
|
|
u->Draw(game,IMAGES); |
|
|
|
|
if(u->IsGuarded()){ |
|
|
|
|
game.DrawDecal(u->GetPos()+vf2d{float(u->GetUnitSize().x/2),-float(u->GetUnitSize().y/2)}-vf2d{float(IMAGES[GUARD_ICON]->Sprite()->width),0.f}*0.375,IMAGES[GUARD_ICON]->Decal(),{0.375,0.375}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for(auto&deadUnit:deathAnimations){ |
|
|
|
|
deadUnit->Update(fElapsedTime); |
|
|
|
|
deadUnit->Draw(game,this); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for(DebuffIcon&icon:debuffIcons){ |
|
|
|
|
icon.Update(fElapsedTime); |
|
|
|
|
icon.Draw(game); |
|
|
|
|
} |
|
|
|
|
std::erase_if(deathAnimations,[](auto&u){return u->IsDone();}); |
|
|
|
|
|
|
|
|
|
for(ResourceGainIcon&icon:resourceGainIcons){ |
|
|
|
|
icon.Update(fElapsedTime); |
|
|
|
|
icon.Draw(game); |
|
|
|
|
} |
|
|
|
|
for(auto&collectionPoint:collectionPoints){ |
|
|
|
|
collectionPoint->Update(this,*IMAGES[MATRIX]); |
|
|
|
|
RenderCollectionPoints(collectionPoint.get()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::erase_if(debuffIcons,[](DebuffIcon&icon){return icon.lifetime<=0;}); |
|
|
|
|
std::erase_if(resourceGainIcons,[](ResourceGainIcon&icon){return icon.lifetime<=0;}); |
|
|
|
|
for(auto&u:units){ |
|
|
|
|
u->DrawUnitDamageStats(this,game,IMAGES); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for(auto&u:units){ |
|
|
|
|
u->_DrawHud(game,IMAGES,unitMetersGreyedOut); |
|
|
|
|
} |
|
|
|
|
for(DebuffIcon&icon:debuffIcons){ |
|
|
|
|
icon.Update(fElapsedTime); |
|
|
|
|
icon.Draw(game); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
DrawSelectionRectangle(); |
|
|
|
|
RenderFogOfWar(); |
|
|
|
|
for(ResourceGainIcon&icon:resourceGainIcons){ |
|
|
|
|
icon.Update(fElapsedTime); |
|
|
|
|
icon.Draw(game); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unitCreationList.DrawDecal(this); |
|
|
|
|
platformCreationList.DrawDecal(this); |
|
|
|
|
std::erase_if(debuffIcons,[](DebuffIcon&icon){return icon.lifetime<=0;}); |
|
|
|
|
std::erase_if(resourceGainIcons,[](ResourceGainIcon&icon){return icon.lifetime<=0;}); |
|
|
|
|
|
|
|
|
|
DrawSystemMemoryBar(fElapsedTime); |
|
|
|
|
DrawResourceBar(fElapsedTime); |
|
|
|
|
DrawDecal({float(ScreenWidth()-74-IMAGES[GUIDE]->Sprite()->width*0.75),float(ScreenHeight()+6-IMAGES[GUIDE]->Sprite()->height*0.75)},IMAGES[GUIDE]->Decal(),{0.75,0.75}); |
|
|
|
|
DrawMinimap(); |
|
|
|
|
currentLevel->scenario->_Draw(); |
|
|
|
|
for(auto&u:units){ |
|
|
|
|
u->_DrawHud(game,IMAGES,unitMetersGreyedOut); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unitCreationBox.UpdateAndDraw(GetMousePos()+vi2d{8,-28},this,player_resources,IMAGES,GetTotalUsedMemory(),currentLevel->availableMemory); |
|
|
|
|
testBox.UpdateAndDraw(GetMousePos()-testBox.GetSize()/2,this,player_resources,IMAGES,GetTotalUsedMemory(),currentLevel->availableMemory); |
|
|
|
|
memoryAllocatorBox.UpdateAndDraw(GetMousePos()+vi2d{8,-28},this,player_resources,IMAGES,GetTotalUsedMemory(),currentLevel->availableMemory); |
|
|
|
|
platformCreationBox.UpdateAndDraw(GetMousePos()+vi2d{8,-28},this,player_resources,IMAGES,GetTotalUsedMemory(),currentLevel->availableMemory); |
|
|
|
|
DrawSelectionRectangle(); |
|
|
|
|
RenderFogOfWar(); |
|
|
|
|
|
|
|
|
|
std::sort(units.begin(),units.end(),[&](auto&u1,auto&u2){ |
|
|
|
|
float dist1=geom2d::line<float>(u1->GetGhostPos(),GetWorldMousePos()).length(); |
|
|
|
|
float dist2=geom2d::line<float>(u2->GetGhostPos(),GetWorldMousePos()).length(); |
|
|
|
|
return dist1>dist2;}); |
|
|
|
|
unitCreationList.DrawDecal(this); |
|
|
|
|
platformCreationList.DrawDecal(this); |
|
|
|
|
restartManager.DrawDecal(this); |
|
|
|
|
|
|
|
|
|
for(auto&u:units){ |
|
|
|
|
if(u->IsGuarded()){ |
|
|
|
|
bool changeOccured=false; |
|
|
|
|
int changedBit=-1; |
|
|
|
|
for(int i=0;i<u->memory.size();i++){ |
|
|
|
|
if(u->memory[i]!=u->savedMemory[i]){ |
|
|
|
|
changeOccured=true; |
|
|
|
|
changedBit=i; |
|
|
|
|
break; |
|
|
|
|
DrawSystemMemoryBar(fElapsedTime); |
|
|
|
|
DrawResourceBar(fElapsedTime); |
|
|
|
|
if(guideEnabled){ |
|
|
|
|
DrawDecal({float(ScreenWidth()-74-IMAGES[GUIDE]->Sprite()->width*0.75),float(ScreenHeight()+6-IMAGES[GUIDE]->Sprite()->height*0.75)},IMAGES[GUIDE]->Decal(),{0.75,0.75}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if(changeOccured&&util::random(1)<=0.3){ |
|
|
|
|
u->memory[changedBit]=u->savedMemory[changedBit]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
DrawMinimap(); |
|
|
|
|
currentLevel->scenario->_Draw(); |
|
|
|
|
|
|
|
|
|
unitCreationBox.UpdateAndDraw(GetMousePos()+vi2d{8,-28},this,player_resources,IMAGES,GetTotalUsedMemory(),currentLevel->availableMemory); |
|
|
|
|
testBox.UpdateAndDraw(GetMousePos()-testBox.GetSize()/2,this,player_resources,IMAGES,GetTotalUsedMemory(),currentLevel->availableMemory); |
|
|
|
|
memoryAllocatorBox.UpdateAndDraw(GetMousePos()+vi2d{8,-28},this,player_resources,IMAGES,GetTotalUsedMemory(),currentLevel->availableMemory); |
|
|
|
|
platformCreationBox.UpdateAndDraw(GetMousePos()+vi2d{8,-28},this,player_resources,IMAGES,GetTotalUsedMemory(),currentLevel->availableMemory); |
|
|
|
|
|
|
|
|
|
std::sort(units.begin(),units.end(),[&](auto&u1,auto&u2){ |
|
|
|
|
float dist1=geom2d::line<float>(u1->GetGhostPos(),GetWorldMousePos()).length(); |
|
|
|
|
float dist2=geom2d::line<float>(u2->GetGhostPos(),GetWorldMousePos()).length(); |
|
|
|
|
return dist1>dist2;}); |
|
|
|
|
|
|
|
|
|
for(auto&u:units){ |
|
|
|
|
if(u->IsGuarded()){ |
|
|
|
|
bool changeOccured=false; |
|
|
|
|
int changedBit=-1; |
|
|
|
|
for(int i=0;i<u->memory.size();i++){ |
|
|
|
|
if(u->memory[i]!=u->savedMemory[i]){ |
|
|
|
|
changeOccured=true; |
|
|
|
|
changedBit=i; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if(changeOccured&&util::random(1)<=0.3){ |
|
|
|
|
u->memory[changedBit]=u->savedMemory[changedBit]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+game.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*game.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,uint8_t(levelForegroundFade*255)}/2); |
|
|
|
|
}break; |
|
|
|
|
#pragma endregion |
|
|
|
|
#pragma region COMPLETED |
|
|
|
|
case GameState::COMPLETED:{ |
|
|
|
|
DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+game.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*game.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,164}/2); |
|
|
|
|
}break; |
|
|
|
|
#pragma endregion |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
@ -1031,6 +1075,45 @@ bool VirusAttack::OnUserDestroy(){ |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void VirusAttack::PerformLevelTransition(float fElapsedTime){ |
|
|
|
|
if(levelToLoad!=currentLevel->name||reloadLevel){ |
|
|
|
|
levelForegroundFade=std::min(1.f,levelForegroundFade+fElapsedTime); |
|
|
|
|
if(levelForegroundFade>=1){ |
|
|
|
|
LoadLevel(levelToLoad); |
|
|
|
|
reloadLevel=false; |
|
|
|
|
} |
|
|
|
|
}else |
|
|
|
|
if(levelForegroundFade>0){ |
|
|
|
|
levelForegroundFade=std::max(0.f,levelForegroundFade-fElapsedTime); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void VirusAttack::RestartLevel(){ |
|
|
|
|
reloadLevel=true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void VirusAttack::HandleRestartButton(float fElapsedTime){ |
|
|
|
|
if(restartButton->bHover){ |
|
|
|
|
restartBox.Initialize("Click and hold to restart the level.",GetMousePos()+vf2d{0,10},"Restart Level",nullptr,{72,1}); |
|
|
|
|
restartBox.SetVisible(true); |
|
|
|
|
if(restartButton->bPressed){ |
|
|
|
|
restartButtonHeldDown=true; |
|
|
|
|
} |
|
|
|
|
if(restartButtonHeldDown){ |
|
|
|
|
restartButtonHoldTime+=fElapsedTime; |
|
|
|
|
if(restartButtonHoldTime>=CONSTANT::RESTART_BUTTON_HOLD_TIME){ |
|
|
|
|
RestartLevel(); |
|
|
|
|
restartButtonHeldDown=false; |
|
|
|
|
restartButtonHoldTime=0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}else{ |
|
|
|
|
restartBox.SetVisible(false); |
|
|
|
|
restartButtonHeldDown=false; |
|
|
|
|
restartButtonHoldTime=0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int main() |
|
|
|
|
{ |
|
|
|
|
VirusAttack app; |
|
|
|
|