|
|
@ -19,7 +19,7 @@ |
|
|
|
VirusAttack::VirusAttack() |
|
|
|
VirusAttack::VirusAttack() |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Name your application
|
|
|
|
// Name your application
|
|
|
|
sAppName = "olcCodeJam 2023 Entry"; |
|
|
|
sAppName = "Virus Attack"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void VirusAttack::InitializeImages(){ |
|
|
|
void VirusAttack::InitializeImages(){ |
|
|
@ -66,8 +66,8 @@ void VirusAttack::InitializeLevelData(){ |
|
|
|
#pragma region Stage 1 |
|
|
|
#pragma region Stage 1 |
|
|
|
//Stage 1 data.
|
|
|
|
//Stage 1 data.
|
|
|
|
levelData[STAGE1].size={64,64}; |
|
|
|
levelData[STAGE1].size={64,64}; |
|
|
|
levelData[STAGE1].bgm=Sound::GRAVITY; |
|
|
|
levelData[STAGE1].bgm=Sound::BOSS2; |
|
|
|
levelData[STAGE1].player_starting_resources={5,5,5,5,5}; |
|
|
|
levelData[STAGE1].player_starting_resources={50,50,50,50,50}; |
|
|
|
levelData[STAGE1].enemy_starting_resources={0,0,0,0,0}; |
|
|
|
levelData[STAGE1].enemy_starting_resources={0,0,0,0,0}; |
|
|
|
{ |
|
|
|
{ |
|
|
|
std::vector<UnitData>&units=levelData[STAGE1].unitPlacement; |
|
|
|
std::vector<UnitData>&units=levelData[STAGE1].unitPlacement; |
|
|
@ -138,7 +138,7 @@ bool VirusAttack::OnUserCreate(){ |
|
|
|
AL.AudioSystemInit(); |
|
|
|
AL.AudioSystemInit(); |
|
|
|
InitializeSounds(); |
|
|
|
InitializeSounds(); |
|
|
|
|
|
|
|
|
|
|
|
InitializeUnitCreationGUI(); |
|
|
|
InitializeGUIs(); |
|
|
|
InitializeLevelData(); |
|
|
|
InitializeLevelData(); |
|
|
|
|
|
|
|
|
|
|
|
LoadLevel(STAGE1); |
|
|
|
LoadLevel(STAGE1); |
|
|
@ -194,19 +194,25 @@ void VirusAttack::LoadLevel(LevelName level){ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void VirusAttack::InitializeUnitCreationGUI(){ |
|
|
|
void VirusAttack::InitializeGUIs(){ |
|
|
|
unitCreationList.colNormal = olc::DARK_GREEN; |
|
|
|
unitCreationList.colNormal = olc::DARK_GREEN; |
|
|
|
unitCreationList.colHover = olc::GREEN; |
|
|
|
unitCreationList.colHover = olc::GREEN; |
|
|
|
unitCreationList.colClick = olc::YELLOW; |
|
|
|
unitCreationList.colClick = olc::YELLOW; |
|
|
|
unitCreationList.colDisable = olc::DARK_GREY; |
|
|
|
unitCreationList.colDisable = olc::DARK_GREY; |
|
|
|
unitCreationList.colBorder = olc::YELLOW; |
|
|
|
unitCreationList.colBorder = olc::YELLOW; |
|
|
|
unitCreationList.colText = olc::WHITE; |
|
|
|
unitCreationList.colText = olc::WHITE; |
|
|
|
leftShifterButton=new QuickGUI::ImageButton(unitCreationList,*IMAGES[LEFT_SHIFTER],{0.5,0.5},{16.f+32*0,float(ScreenHeight()-32)},{20,20}); |
|
|
|
platformCreationList.CopyThemeFrom(unitCreationList); |
|
|
|
rightShifterButton=new QuickGUI::ImageButton(unitCreationList,*IMAGES[RIGHT_SHIFTER],{0.5,0.5},{16.f+32*1,float(ScreenHeight()-32)},{20,20}); |
|
|
|
leftShifterButton=new QuickGUI::ImageButton(unitCreationList,*IMAGES[LEFT_SHIFTER],{0.5,0.5},{16.f+32*0,float(ScreenHeight()-48)},{20,20}); |
|
|
|
bitRestorerButton=new QuickGUI::ImageButton(unitCreationList,*IMAGES[BIT_RESTORER],{0.5,0.5},{16.f+32*2,float(ScreenHeight()-32)},{20,20}); |
|
|
|
rightShifterButton=new QuickGUI::ImageButton(unitCreationList,*IMAGES[RIGHT_SHIFTER],{0.5,0.5},{16.f+32*1,float(ScreenHeight()-48)},{20,20}); |
|
|
|
memorySwapperButton=new QuickGUI::ImageButton(unitCreationList,*IMAGES[MEMORY_SWAPPER],{0.5,0.5},{16.f+32*3,float(ScreenHeight()-32)},{20,20}); |
|
|
|
bitRestorerButton=new QuickGUI::ImageButton(unitCreationList,*IMAGES[BIT_RESTORER],{0.5,0.5},{16.f+32*2,float(ScreenHeight()-48)},{20,20}); |
|
|
|
corrupterButton=new QuickGUI::ImageButton(unitCreationList,*IMAGES[CORRUPTER],{0.5,0.5},{16.f+32*4,float(ScreenHeight()-32)},{20,20}); |
|
|
|
memorySwapperButton=new QuickGUI::ImageButton(unitCreationList,*IMAGES[MEMORY_SWAPPER],{0.5,0.5},{16.f+32*3,float(ScreenHeight()-48)},{20,20}); |
|
|
|
platformButton=new QuickGUI::ImageButton(unitCreationList,*IMAGES[PLATFORM],{0.25,0.25},{16.f+32*5,float(ScreenHeight()-32)},{20,20}); |
|
|
|
corrupterButton=new QuickGUI::ImageButton(unitCreationList,*IMAGES[CORRUPTER],{0.5,0.5},{16.f+32*4,float(ScreenHeight()-48)},{20,20}); |
|
|
|
|
|
|
|
platformButton=new QuickGUI::ImageButton(unitCreationList,*IMAGES[PLATFORM],{0.25,0.25},{16.f+32*5,float(ScreenHeight()-48)},{20,20}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ramBankButton=new QuickGUI::ImageButton(platformCreationList,*IMAGES[RAM_BANK],{0.125,0.125},{float(ScreenWidth()-48),48.f+32*0},{20,20}); |
|
|
|
|
|
|
|
refresherButton=new QuickGUI::ImageButton(platformCreationList,*IMAGES[REFRESHER],{0.25,0.25},{float(ScreenWidth()-48),48.f+32*1},{20,20}); |
|
|
|
|
|
|
|
turretButton=new QuickGUI::ImageButton(platformCreationList,*IMAGES[TURRET],{0.25,0.25},{float(ScreenWidth()-48),48.f+32*2},{20,20}); |
|
|
|
|
|
|
|
memoryGuardButton=new QuickGUI::ImageButton(platformCreationList,*IMAGES[MEMORY_GUARD],{0.25,0.25},{float(ScreenWidth()-48),48.f+32*3},{20,20}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void VirusAttack::InitializeSounds(){ |
|
|
|
void VirusAttack::InitializeSounds(){ |
|
|
@ -221,13 +227,15 @@ void VirusAttack::InitializeSounds(){ |
|
|
|
LoadSound(Sound::HUM,"machine2.wav"); |
|
|
|
LoadSound(Sound::HUM,"machine2.wav"); |
|
|
|
LoadSound(Sound::GRAVITY,"gravity.mp3"); |
|
|
|
LoadSound(Sound::GRAVITY,"gravity.mp3"); |
|
|
|
LoadSound(Sound::COSMOS,"cosmos.mp3"); |
|
|
|
LoadSound(Sound::COSMOS,"cosmos.mp3"); |
|
|
|
|
|
|
|
LoadSound(Sound::BOSS1,"boss1.mp3"); |
|
|
|
|
|
|
|
LoadSound(Sound::BOSS2,"boss2.mp3"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool VirusAttack::UnitCreationClickHandled(){ |
|
|
|
bool VirusAttack::UnitCreationClickHandled(){ |
|
|
|
#define CheckClick(UnitClass,Button) \ |
|
|
|
#define CheckClick(UnitClass,Button,Validator) \ |
|
|
|
if(Button->bPressed){ \
|
|
|
|
if(Button->bPressed){ \
|
|
|
|
for(auto&u:units){ \
|
|
|
|
for(auto&u:units){ \
|
|
|
|
if(u->IsSelected()&&u->IsAllocator()&&CanAfford(player_resources,UnitClass::resourceCost)) { \
|
|
|
|
if(u->IsSelected()&&u->Validator()&&CanAfford(player_resources,UnitClass::resourceCost)) { \
|
|
|
|
std::unique_ptr<UnitClass>buildUnit=std::make_unique<UnitClass>(this,u->GetPos(),IMAGES,u->IsFriendly()); \
|
|
|
|
std::unique_ptr<UnitClass>buildUnit=std::make_unique<UnitClass>(this,u->GetPos(),IMAGES,u->IsFriendly()); \
|
|
|
|
u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit)); \
|
|
|
|
u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit)); \
|
|
|
|
ExpendResources(player_resources,UnitClass::resourceCost); \
|
|
|
|
ExpendResources(player_resources,UnitClass::resourceCost); \
|
|
|
@ -236,38 +244,42 @@ bool VirusAttack::UnitCreationClickHandled(){ |
|
|
|
return true; \
|
|
|
|
return true; \
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
CheckClick(LeftShifter,leftShifterButton) |
|
|
|
CheckClick(LeftShifter,leftShifterButton,IsAllocator) |
|
|
|
CheckClick(RightShifter,rightShifterButton) |
|
|
|
CheckClick(RightShifter,rightShifterButton,IsAllocator) |
|
|
|
CheckClick(BitRestorer,bitRestorerButton) |
|
|
|
CheckClick(BitRestorer,bitRestorerButton,IsAllocator) |
|
|
|
CheckClick(MemorySwapper,memorySwapperButton) |
|
|
|
CheckClick(MemorySwapper,memorySwapperButton,IsAllocator) |
|
|
|
CheckClick(BitRestorer,bitRestorerButton) |
|
|
|
CheckClick(BitRestorer,bitRestorerButton,IsAllocator) |
|
|
|
CheckClick(Corrupter,corrupterButton) |
|
|
|
CheckClick(Corrupter,corrupterButton,IsAllocator) |
|
|
|
CheckClick(_Platform,platformButton) |
|
|
|
CheckClick(_Platform,platformButton,IsAllocator) |
|
|
|
|
|
|
|
CheckClick(RAMBank,ramBankButton,IsPlatform) |
|
|
|
|
|
|
|
CheckClick(Refresher,refresherButton,IsPlatform) |
|
|
|
|
|
|
|
CheckClick(Turret,turretButton,IsPlatform) |
|
|
|
|
|
|
|
CheckClick(MemoryGuard,memoryGuardButton,IsPlatform) |
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
#define EnableAndHoverCheck(UnitClass,Button,box) \ |
|
|
|
|
|
|
|
Button->Enable(CanAfford(player_resources,UnitClass::resourceCost)); \
|
|
|
|
|
|
|
|
if(Button->bHover){ \
|
|
|
|
|
|
|
|
box.Initialize(UnitClass::unitDescription, GetMousePos(), UnitClass::unitName,{120,36},UnitClass::resourceCost); \
|
|
|
|
|
|
|
|
hovering=true; \
|
|
|
|
|
|
|
|
if(CanAfford(player_resources,UnitClass::resourceCost)){ \
|
|
|
|
|
|
|
|
box.SetBackgroundColor(CONSTANT::MESSAGE_BOX_DEFAULT_BACKCOL); \
|
|
|
|
|
|
|
|
} else { \
|
|
|
|
|
|
|
|
box.SetBackgroundColor(VERY_DARK_GREY/2); \
|
|
|
|
|
|
|
|
} \
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void VirusAttack::UpdateUnitCreationListGUI(bool allocatorSelected){ |
|
|
|
void VirusAttack::UpdateUnitCreationListGUI(bool allocatorSelected){ |
|
|
|
unitCreationList.DisplayAllControls(allocatorSelected); |
|
|
|
unitCreationList.DisplayAllControls(allocatorSelected); |
|
|
|
#define EnableAndHoverCheck(UnitClass,Button) \ |
|
|
|
|
|
|
|
Button->Enable(CanAfford(player_resources,UnitClass::resourceCost)); \
|
|
|
|
|
|
|
|
if (Button->bHover) { \
|
|
|
|
|
|
|
|
unitCreationBox.Initialize(UnitClass::unitDescription, GetMousePos(), UnitClass::unitName,{120,36},UnitClass::resourceCost); \
|
|
|
|
|
|
|
|
hovering=true; \
|
|
|
|
|
|
|
|
if(CanAfford(player_resources,UnitClass::resourceCost)){ \
|
|
|
|
|
|
|
|
unitCreationBox.SetBackgroundColor(CONSTANT::MESSAGE_BOX_DEFAULT_BACKCOL); \
|
|
|
|
|
|
|
|
} else { \
|
|
|
|
|
|
|
|
unitCreationBox.SetBackgroundColor(VERY_DARK_GREY/2); \
|
|
|
|
|
|
|
|
} \
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool hovering=false; |
|
|
|
bool hovering=false; |
|
|
|
EnableAndHoverCheck(LeftShifter,leftShifterButton) |
|
|
|
EnableAndHoverCheck(LeftShifter,leftShifterButton,unitCreationBox) |
|
|
|
EnableAndHoverCheck(RightShifter,rightShifterButton) |
|
|
|
EnableAndHoverCheck(RightShifter,rightShifterButton,unitCreationBox) |
|
|
|
EnableAndHoverCheck(BitRestorer,bitRestorerButton) |
|
|
|
EnableAndHoverCheck(BitRestorer,bitRestorerButton,unitCreationBox) |
|
|
|
EnableAndHoverCheck(MemorySwapper,memorySwapperButton) |
|
|
|
EnableAndHoverCheck(MemorySwapper,memorySwapperButton,unitCreationBox) |
|
|
|
EnableAndHoverCheck(BitRestorer,bitRestorerButton) |
|
|
|
EnableAndHoverCheck(BitRestorer,bitRestorerButton,unitCreationBox) |
|
|
|
EnableAndHoverCheck(Corrupter,corrupterButton) |
|
|
|
EnableAndHoverCheck(Corrupter,corrupterButton,unitCreationBox) |
|
|
|
EnableAndHoverCheck(MemoryAllocator,platformButton) |
|
|
|
EnableAndHoverCheck(_Platform,platformButton,unitCreationBox) |
|
|
|
|
|
|
|
|
|
|
|
if(!hovering){ |
|
|
|
if(!hovering){ |
|
|
|
unitCreationBox.SetVisible(false); |
|
|
|
unitCreationBox.SetVisible(false); |
|
|
@ -276,18 +288,40 @@ void VirusAttack::UpdateUnitCreationListGUI(bool allocatorSelected){ |
|
|
|
unitCreationList.Update(this); |
|
|
|
unitCreationList.Update(this); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!hovering){ |
|
|
|
|
|
|
|
platformCreationBox.SetVisible(false); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
platformCreationList.Update(this); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void VirusAttack::HandleDraggingSelection(){ |
|
|
|
void VirusAttack::HandleDraggingSelection(){ |
|
|
|
auto NotClickingOnMinimap=[&](){return !(GetMouseX()>=ScreenWidth()-64&&GetMouseY()>=ScreenHeight()-64);}; |
|
|
|
auto NotClickingOnMinimap=[&](){return !(GetMouseX()>=ScreenWidth()-64&&GetMouseY()>=ScreenHeight()-64);}; |
|
|
|
bool allocatorSelected=false; |
|
|
|
bool allocatorSelected=false; |
|
|
|
|
|
|
|
bool platformSelected=false; |
|
|
|
bool memoryAllocatorBoxHovered=false; |
|
|
|
bool memoryAllocatorBoxHovered=false; |
|
|
|
for(auto&u:units){ |
|
|
|
for(auto&u:units){ |
|
|
|
u->UpdateGUIState(game,player_resources,memoryAllocatorBox,memoryAllocatorBoxHovered); |
|
|
|
u->UpdateGUIState(game,player_resources,memoryAllocatorBox,memoryAllocatorBoxHovered); |
|
|
|
if(u->IsSelected()&&u->IsAllocator()){ |
|
|
|
if(u->IsSelected()){ |
|
|
|
allocatorSelected=true; |
|
|
|
if(u->IsAllocator()){ |
|
|
|
|
|
|
|
allocatorSelected=true; |
|
|
|
|
|
|
|
} else |
|
|
|
|
|
|
|
if(u->IsPlatform()){ |
|
|
|
|
|
|
|
platformSelected=true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if(!memoryAllocatorBoxHovered)memoryAllocatorBox.SetVisible(false); |
|
|
|
if(!memoryAllocatorBoxHovered)memoryAllocatorBox.SetVisible(false); |
|
|
|
UpdateUnitCreationListGUI(allocatorSelected); |
|
|
|
UpdateUnitCreationListGUI(allocatorSelected); |
|
|
|
|
|
|
|
UpdatePlatformCreationListGUI(platformSelected); |
|
|
|
if(GetMouse(0).bPressed){ |
|
|
|
if(GetMouse(0).bPressed){ |
|
|
|
if(NotClickingOnMinimap()){ |
|
|
|
if(NotClickingOnMinimap()){ |
|
|
|
for(auto&u:units){ |
|
|
|
for(auto&u:units){ |
|
|
@ -392,10 +426,10 @@ void VirusAttack::CollisionChecking(std::shared_ptr<Unit>u,std::shared_ptr<Unit> |
|
|
|
float maxDist=u->GetUnitSize().x/2+u2->GetUnitSize().x/2; |
|
|
|
float maxDist=u->GetUnitSize().x/2+u2->GetUnitSize().x/2; |
|
|
|
float dist=maxDist-collisionLine.length(); |
|
|
|
float dist=maxDist-collisionLine.length(); |
|
|
|
vf2d dir=collisionLine.vector().norm(); |
|
|
|
vf2d dir=collisionLine.vector().norm(); |
|
|
|
if(u->IsMoveable()){ |
|
|
|
if(u->IsMoveable()||(!u->IsMoveable()&&!u2->IsMoveable())){ |
|
|
|
u->SetPos(u->GetPos()-dir*dist/2); |
|
|
|
u->SetPos(u->GetPos()-dir*dist/2); |
|
|
|
} |
|
|
|
} |
|
|
|
if(u2->IsMoveable()){ |
|
|
|
if(u2->IsMoveable()||(!u->IsMoveable()&&!u2->IsMoveable())){ |
|
|
|
u2->SetPos(u2->GetPos()+dir*(dist+0.001)/2); |
|
|
|
u2->SetPos(u2->GetPos()+dir*(dist+0.001)/2); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -664,6 +698,7 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){ |
|
|
|
RenderFogOfWar(); |
|
|
|
RenderFogOfWar(); |
|
|
|
|
|
|
|
|
|
|
|
unitCreationList.DrawDecal(this); |
|
|
|
unitCreationList.DrawDecal(this); |
|
|
|
|
|
|
|
platformCreationList.DrawDecal(this); |
|
|
|
|
|
|
|
|
|
|
|
DrawResourceBar(); |
|
|
|
DrawResourceBar(); |
|
|
|
|
|
|
|
|
|
|
@ -672,6 +707,7 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){ |
|
|
|
unitCreationBox.UpdateAndDraw(GetMousePos()+vi2d{8,-28},this,player_resources,IMAGES); |
|
|
|
unitCreationBox.UpdateAndDraw(GetMousePos()+vi2d{8,-28},this,player_resources,IMAGES); |
|
|
|
testBox.UpdateAndDraw(GetMousePos()-testBox.GetSize()/2,this,player_resources,IMAGES); |
|
|
|
testBox.UpdateAndDraw(GetMousePos()-testBox.GetSize()/2,this,player_resources,IMAGES); |
|
|
|
memoryAllocatorBox.UpdateAndDraw(GetMousePos()+vi2d{8,-28},this,player_resources,IMAGES); |
|
|
|
memoryAllocatorBox.UpdateAndDraw(GetMousePos()+vi2d{8,-28},this,player_resources,IMAGES); |
|
|
|
|
|
|
|
platformCreationBox.UpdateAndDraw(GetMousePos()+vi2d{8,-28},this,player_resources,IMAGES); |
|
|
|
|
|
|
|
|
|
|
|
std::sort(units.begin(),units.end(),[&](auto&u1,auto&u2){ |
|
|
|
std::sort(units.begin(),units.end(),[&](auto&u1,auto&u2){ |
|
|
|
float dist1=geom2d::line<float>(u1->GetGhostPos(),GetWorldMousePos()).length(); |
|
|
|
float dist1=geom2d::line<float>(u1->GetGhostPos(),GetWorldMousePos()).length(); |
|
|
|