Platform build list implemented.

CorrectiveAction
sigonasr2 1 year ago
parent 7208181b25
commit 76620a720d
  1. 2
      olcCodeJam2023Entry/Sound.h
  2. 41
      olcCodeJam2023Entry/Textbox.cpp
  3. 103
      olcCodeJam2023Entry/Unit.cpp
  4. 4
      olcCodeJam2023Entry/Unit.h
  5. 114
      olcCodeJam2023Entry/VirusAttack.cpp
  6. 16
      olcCodeJam2023Entry/VirusAttack.h
  7. 5
      olcCodeJam2023Entry/util.cpp

@ -4,4 +4,6 @@ enum class Sound{
HUM, HUM,
GRAVITY, GRAVITY,
COSMOS, COSMOS,
BOSS1,
BOSS2,
}; };

@ -72,7 +72,7 @@ void Textbox::Draw(PixelGameEngine*pge,Resources&resources,std::map<Image,std::u
if(visible){ if(visible){
geom2d::rect<float>boxRect={pos-vf2d{3,3},maxSize+vf2d{6,6}}; geom2d::rect<float>boxRect={pos-vf2d{3,3},maxSize+vf2d{6,6}};
if(resourceCost.size()>0){ if(resourceCost.size()>0){
boxRect.size.x+=24; boxRect.size.x+=36;
boxRect.size.y=std::max(36.f,boxRect.size.y); boxRect.size.y=std::max(36.f,boxRect.size.y);
} }
if(boxRect.bottom().start.y>=pge->ScreenHeight()){ if(boxRect.bottom().start.y>=pge->ScreenHeight()){
@ -103,7 +103,7 @@ void Textbox::Draw(PixelGameEngine*pge,Resources&resources,std::map<Image,std::u
drawcol=resourceAmt>=cost?GREY:RED; drawcol=resourceAmt>=cost?GREY:RED;
shadowCol=drawcol==GREY?VERY_DARK_BLUE:VERY_DARK_RED; shadowCol=drawcol==GREY?VERY_DARK_BLUE:VERY_DARK_RED;
vf2d textScale = {0.4,0.4}; vf2d textScale = {0.4,0.4};
std::string displayString = std::to_string(resourceAmt)+" / "; std::string displayString = std::to_string(resourceAmt)+(resourceAmt<10?" ":"")+"/";
if(resourceAmt<cost){ if(resourceAmt<cost){
pge->FillRectDecal(contentPos+vf2d{0,float(index*6)},vf2d{resourceBoxRect.size.x-6,6},{160,0,0,192}); pge->FillRectDecal(contentPos+vf2d{0,float(index*6)},vf2d{resourceBoxRect.size.x-6,6},{160,0,0,192});
} }
@ -111,17 +111,32 @@ void Textbox::Draw(PixelGameEngine*pge,Resources&resources,std::map<Image,std::u
pge->DrawShadowStringDecal(contentPos+vf2d{12.f+pge->GetTextSize(displayString).x*textScale.x+2,float(index*6)+1},std::to_string(cost),drawcol,shadowCol,{0.4,0.4},0.6); pge->DrawShadowStringDecal(contentPos+vf2d{12.f+pge->GetTextSize(displayString).x*textScale.x+2,float(index*6)+1},std::to_string(cost),drawcol,shadowCol,{0.4,0.4},0.6);
}; };
DrawResourceAmount(0,util::GetHealthCost(resourceCost),resources.health); int index=0;
DrawResourceAmount(1,util::GetAtkSpdCost(resourceCost),resources.atkSpd); if(util::GetHealthCost(resourceCost)!=-1){
DrawResourceAmount(2,util::GetMoveSpdCost(resourceCost),resources.moveSpd); DrawResourceAmount(index,util::GetHealthCost(resourceCost),resources.health);
DrawResourceAmount(3,util::GetRangeCost(resourceCost),resources.range); pge->DrawDecal(contentPos+vf2d{0,index*6.f},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::HEALTH_COLOR);
DrawResourceAmount(4,util::GetProcedureCost(resourceCost),resources.procedure); index++;
}
pge->DrawDecal(contentPos+vf2d{0,0*6},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::HEALTH_COLOR); if(util::GetAtkSpdCost(resourceCost)!=-1){
pge->DrawDecal(contentPos+vf2d{0,1*6},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::ATKSPD_COLOR); DrawResourceAmount(index,util::GetAtkSpdCost(resourceCost),resources.atkSpd);
pge->DrawDecal(contentPos+vf2d{0,2*6},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::MOVESPD_COLOR); pge->DrawDecal(contentPos+vf2d{0,index*6.f},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::ATKSPD_COLOR);
pge->DrawDecal(contentPos+vf2d{0,3*6},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::RANGE_COLOR); index++;
pge->DrawDecal(contentPos+vf2d{0,4*6},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::PROCEDURE_COLOR); }
if(util::GetMoveSpdCost(resourceCost)!=-1){
DrawResourceAmount(index,util::GetMoveSpdCost(resourceCost),resources.moveSpd);
pge->DrawDecal(contentPos+vf2d{0,index*6.f},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::MOVESPD_COLOR);
index++;
}
if(util::GetRangeCost(resourceCost)!=-1){
DrawResourceAmount(index,util::GetRangeCost(resourceCost),resources.range);
pge->DrawDecal(contentPos+vf2d{0,index*6.f},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::RANGE_COLOR);
index++;
}
if(util::GetProcedureCost(resourceCost)!=-1){
DrawResourceAmount(index,util::GetProcedureCost(resourceCost),resources.procedure);
pge->DrawDecal(contentPos+vf2d{0,index*6.f},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::PROCEDURE_COLOR);
index++;
}
} }
} }
} }

@ -169,7 +169,7 @@ void MemoryAllocator::Draw(TileTransformedView&game,std::map<Image,std::unique_p
std::string RAMBank::unitName="RAM Bank"; std::string RAMBank::unitName="RAM Bank";
std::string RAMBank::unitDescription="Allows for the construction of Memory Allocators."; std::string RAMBank::unitDescription="Allows for the construction of Memory Allocators.";
std::vector<Memory> RAMBank::resourceCost={{RANGE,0},{ATKSPD,0},{MOVESPD,0},{PROCEDURE,25},{HEALTH,16}}; std::vector<Memory> RAMBank::resourceCost={{PROCEDURE,25},{HEALTH,16}};
RAMBank::RAMBank(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly) RAMBank::RAMBank(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly)
:Unit(pge,RAMBank::resourceCost,pos,41,*IMAGES[RAM_BANK],WHITE,WHITE,friendly,false :Unit(pge,RAMBank::resourceCost,pos,41,*IMAGES[RAM_BANK],WHITE,WHITE,friendly,false
,false,false ,false,false
@ -235,7 +235,7 @@ void RAMBank::UpdateGUIState(TileTransformedView&game,Resources&player_resources
return player_resources.atkSpd+player_resources.health+player_resources.moveSpd+player_resources.procedure+player_resources.range; return player_resources.atkSpd+player_resources.health+player_resources.moveSpd+player_resources.procedure+player_resources.range;
}; };
bool buttonEnabled=IsSelected()&&TotalResources()>=5; bool buttonEnabled=IsSelected()&&TotalResources()>=5&&GetProcedure()==procedure.size;
if(buttonEnabled&&allocatorButton->bHover){ if(buttonEnabled&&allocatorButton->bHover){
displayBox.Initialize(CONSTANT::MEMORY_ALLOCATOR_BOX_DISPLAY_STRING,{},CONSTANT::MEMORY_ALLOCATOR_BOX_HEADER_STRING); displayBox.Initialize(CONSTANT::MEMORY_ALLOCATOR_BOX_DISPLAY_STRING,{},CONSTANT::MEMORY_ALLOCATOR_BOX_HEADER_STRING);
@ -280,36 +280,107 @@ bool RAMBank::ClickHandled(TileTransformedView&game,Resources&player_resources,s
return false; return false;
} }
std::string _Platform::unitName="Corrupter"; std::string _Platform::unitName="Platform";
std::string _Platform::unitDescription="Chooses a random bit and negates it on a target."; std::string _Platform::unitDescription="Anchored to the ground, this unit is an intermediate step for larger units.";
std::vector<Memory> _Platform::resourceCost={{ATKSPD,3},{RANGE,1},{PROCEDURE,8},{MOVESPD,4},{HEALTH,4}}; std::vector<Memory> _Platform::resourceCost={{HEALTH,6}};
_Platform::_Platform(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) _Platform::_Platform(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,_Platform::resourceCost,pos,24,*IMAGES[PLATFORM],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){} :Unit(pge,_Platform::resourceCost,pos,24,*IMAGES[PLATFORM],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,false){
isPlatform=true;
}
void _Platform::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){}; void _Platform::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){};
void _Platform::Update(PixelGameEngine*pge,std::map<Sound,std::unique_ptr<Audio>>&SOUNDS,std::vector<std::unique_ptr<Unit>>&queuedUnits){
if(IsBuilding()){
SetTargetLocation(CONSTANT::UNSELECTED);
target.reset();
buildTime-=pge->GetElapsedTime();
if(buildTime<=0){
for(int i=0;i<GetMemorySize();i++){
memory[i]=false; //Kill the unit.
}
queuedUnits.push_back(std::move(buildTransformUnit));
}
}
}
void _Platform::Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){
if(IsBuilding()){
game.GetPGE()->SetDrawTarget(img.Sprite());
game.GetPGE()->Clear(BLANK);
Renderable&targetImg=buildTransformUnit->GetImage();
game.GetPGE()->SetDrawTarget(nullptr);
game.DrawPartialRotatedDecal(GetGhostPos(),img.Decal(),0,img.Sprite()->Size()/2,{0,0},{float(img.Sprite()->width),float((buildTime/CONSTANT::UNIT_BUILD_TIME)*img.Sprite()->height)},{1,1},GetUnitColor()/3);
game.DrawPartialRotatedDecal(GetGhostPos()+vf2d{0.f,(buildTime/CONSTANT::UNIT_BUILD_TIME)*buildTransformUnit->GetImage().Sprite()->height},buildTransformUnit->GetImage().Decal(),0,buildTransformUnit->GetImage().Sprite()->Size()/2,{0.f,(buildTime/CONSTANT::UNIT_BUILD_TIME)*buildTransformUnit->GetImage().Sprite()->height},{float(buildTransformUnit->GetImage().Sprite()->width),float(buildTransformUnit->GetImage().Sprite()->height-(buildTime/CONSTANT::UNIT_BUILD_TIME)*buildTransformUnit->GetImage().Sprite()->height)},{1,1},GetUnitColor()/1.5f);
if(fmod(buildTime,1)>0.5){
game.DrawRotatedDecal(GetGhostPos(),IMAGES[SELECTION_CIRCLE]->Decal(),0,IMAGES[SELECTION_CIRCLE]->Sprite()->Size()/2,vf2d(img.Sprite()->Size())/IMAGES[SELECTION_CIRCLE]->Sprite()->Size(),{0, 202, 217});
}
} else {
game.DrawRotatedDecal(GetGhostPos(),img.Decal(),0,img.Sprite()->Size()/2,{1,1},GetUnitColor());
if(IsSelected()){
game.DrawRotatedDecal(GetGhostPos(),IMAGES[SELECTION_CIRCLE]->Decal(),0,IMAGES[SELECTION_CIRCLE]->Sprite()->Size()/2,vf2d(img.Sprite()->Size())/IMAGES[SELECTION_CIRCLE]->Sprite()->Size(),WHITE);
}
}
}
std::string Refresher::unitName="Refresher"; std::string Refresher::unitName="Refresher";
std::string Refresher::unitDescription="Repairs missing bits for all surrounding units."; std::string Refresher::unitDescription="Repairs missing bits to surrounding units.";
std::vector<Memory> Refresher::resourceCost={{ATKSPD,3},{RANGE,1},{PROCEDURE,8},{MOVESPD,4},{HEALTH,4}}; std::vector<Memory> Refresher::resourceCost={{ATKSPD,3},{RANGE,1},{PROCEDURE,8},{MOVESPD,4},{HEALTH,4}};
Refresher::Refresher(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) Refresher::Refresher(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,Refresher::resourceCost,pos,24,*IMAGES[REFRESHER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){} :Unit(pge,Refresher::resourceCost,pos,24,*IMAGES[REFRESHER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,false
,true,false){}
void Refresher::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void Refresher::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
//Chooses a bit at random and corrupts it. target.reset(); //Doesn't acquire a target.
int randomBit=rand()%victim.memory.size(); for(auto&u:otherUnits){
victim.memory[randomBit]=false; if(IsFriendly()==u->IsFriendly()&&InRange(u.get())){
int maxAttempts=1000;
int attempts=0;
while(attempts<maxAttempts){
int randomBit=rand()%u->GetMemorySize();
if(u->memory[randomBit]){
u->memory[randomBit]=true;
return;
}
attempts++;
}
}
}
} }
std::string Turret::unitName="Turret"; std::string Turret::unitName="Turret";
std::string Turret::unitDescription="Automatically targets attack and movement speed memory ranges before others."; std::string Turret::unitDescription="Automatically targets attack and movement speed memory ranges before others.";
std::vector<Memory> Turret::resourceCost={{ATKSPD,4},{RANGE,5},{HEALTH,6},{PROCEDURE,16}}; std::vector<Memory> Turret::resourceCost={{ATKSPD,4},{RANGE,5},{HEALTH,6},{PROCEDURE,16}};
Turret::Turret(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) Turret::Turret(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,Turret::resourceCost,pos,24,*IMAGES[TURRET],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){} :Unit(pge,Turret::resourceCost,pos,24,*IMAGES[TURRET],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,false){}
void Turret::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void Turret::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
//Chooses a bit at random and corrupts it. if(victim.GetMoveSpd()>0){
int randomBit=rand()%victim.memory.size(); for(int i=0;i<victim.moveSpd.size;i++){
if(victim.memory[victim.moveSpd.index+i]){
victim.memory[victim.moveSpd.index+i]=false;
return;
}
}
}
if(victim.GetAtkSpd()>0){
for(int i=0;i<victim.atkSpd.size;i++){
if(victim.memory[victim.atkSpd.index+i]){
victim.memory[victim.atkSpd.index+i]=false;
return;
}
}
}
int maxAttempts=1000;
int attempts=0;
while(attempts<maxAttempts){
int randomBit=rand()%victim.GetMemorySize();
if(victim.memory[randomBit]){
victim.memory[randomBit]=false; victim.memory[randomBit]=false;
return;
}
attempts++;
}
} }
std::string MemoryGuard::unitName="Memory Guard"; std::string MemoryGuard::unitName="Memory Guard";
@ -889,3 +960,7 @@ bool Unit::IsGuarded(){
void Unit::SaveMemory(){ void Unit::SaveMemory(){
savedMemory=memory; savedMemory=memory;
} }
bool Unit::IsPlatform(){
return isPlatform&&attachedPoint.expired()&&buildTime<=0;
}

@ -95,6 +95,7 @@ public:
void SetGuardTime(float time); void SetGuardTime(float time);
bool IsGuarded(); bool IsGuarded();
void SaveMemory(); void SaveMemory();
bool IsPlatform();
Marker health={}; Marker health={};
Marker range={}; Marker range={};
Marker atkSpd={}; Marker atkSpd={};
@ -129,6 +130,7 @@ protected:
bool attackFailed=false; bool attackFailed=false;
bool autoAcquireFriendlyTarget=true; bool autoAcquireFriendlyTarget=true;
bool isAllocator=false; bool isAllocator=false;
bool isPlatform=false;
std::unique_ptr<Unit>buildTransformUnit; std::unique_ptr<Unit>buildTransformUnit;
float buildTime=0; float buildTime=0;
private: private:
@ -232,6 +234,8 @@ struct RAMBank:Unit{
struct _Platform:Unit{ struct _Platform:Unit{
_Platform(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); _Platform(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
void Update(PixelGameEngine*pge,std::map<Sound,std::unique_ptr<Audio>>&SOUNDS,std::vector<std::unique_ptr<Unit>>&queuedUnits)override;
void Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES)override;
static std::vector<Memory> resourceCost; static std::vector<Memory> resourceCost;
static std::string unitName; static std::string unitName;
static std::string unitDescription; static std::string unitDescription;

@ -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) \
void VirusAttack::UpdateUnitCreationListGUI(bool allocatorSelected){
unitCreationList.DisplayAllControls(allocatorSelected);
#define EnableAndHoverCheck(UnitClass,Button) \
Button->Enable(CanAfford(player_resources,UnitClass::resourceCost)); \ Button->Enable(CanAfford(player_resources,UnitClass::resourceCost)); \
if (Button->bHover) { \ if(Button->bHover){ \
unitCreationBox.Initialize(UnitClass::unitDescription, GetMousePos(), UnitClass::unitName,{120,36},UnitClass::resourceCost); \ box.Initialize(UnitClass::unitDescription, GetMousePos(), UnitClass::unitName,{120,36},UnitClass::resourceCost); \
hovering=true; \ hovering=true; \
if(CanAfford(player_resources,UnitClass::resourceCost)){ \ if(CanAfford(player_resources,UnitClass::resourceCost)){ \
unitCreationBox.SetBackgroundColor(CONSTANT::MESSAGE_BOX_DEFAULT_BACKCOL); \ box.SetBackgroundColor(CONSTANT::MESSAGE_BOX_DEFAULT_BACKCOL); \
} else { \ } else { \
unitCreationBox.SetBackgroundColor(VERY_DARK_GREY/2); \ box.SetBackgroundColor(VERY_DARK_GREY/2); \
} \ } \
} }
void VirusAttack::UpdateUnitCreationListGUI(bool allocatorSelected){
unitCreationList.DisplayAllControls(allocatorSelected);
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()){
if(u->IsAllocator()){
allocatorSelected=true; 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();

@ -1,18 +1,18 @@
#include "olcPixelGameEngine.h" #include "olcPixelGameEngine.h"
#include "olcSoundWaveEngine.h" #include "olcSoundWaveEngine.h"
#include "olcPGEX_TransformedView.h" #include "olcPGEX_TransformedView.h"
#include "olcPGEX_AudioListener.h"
#include "olcPGEX_AudioSource.h"
#include "olcPGEX_SplashScreen.h"
#include "Unit.h" #include "Unit.h"
#include "Constant.h" #include "Constant.h"
#include "Image.h" #include "Image.h"
#include "DeathAnimation.h" #include "DeathAnimation.h"
#include "olcPGEX_AudioListener.h"
#include "olcPGEX_AudioSource.h"
#include "Sound.h" #include "Sound.h"
#include "DebuffIcon.h" #include "DebuffIcon.h"
#include "CollectionPoint.h" #include "CollectionPoint.h"
#include "Resources.h" #include "Resources.h"
#include "Textbox.h" #include "Textbox.h"
#include "olcPGEX_SplashScreen.h"
#include "Level.h" #include "Level.h"
struct Letter{ struct Letter{
@ -45,7 +45,7 @@ private:
TileTransformedView game; TileTransformedView game;
Textbox unitCreationBox,testBox,memoryAllocatorBox; Textbox unitCreationBox,testBox,memoryAllocatorBox,platformCreationBox;
Level*currentLevel; Level*currentLevel;
std::map<LevelName,Level>levelData; std::map<LevelName,Level>levelData;
@ -57,6 +57,11 @@ private:
QuickGUI::ImageButton*memorySwapperButton; QuickGUI::ImageButton*memorySwapperButton;
QuickGUI::ImageButton*corrupterButton; QuickGUI::ImageButton*corrupterButton;
QuickGUI::ImageButton*platformButton; QuickGUI::ImageButton*platformButton;
QuickGUI::Manager platformCreationList;
QuickGUI::ImageButton*ramBankButton;
QuickGUI::ImageButton*refresherButton;
QuickGUI::ImageButton*turretButton;
QuickGUI::ImageButton*memoryGuardButton;
float matrixTimer=0; float matrixTimer=0;
float updatePixelsTimer=0; float updatePixelsTimer=0;
@ -80,12 +85,13 @@ private:
void InitializeSounds(); void InitializeSounds();
void DrawResourceBar(); void DrawResourceBar();
bool UnitCreationClickHandled(); bool UnitCreationClickHandled();
void InitializeUnitCreationGUI(); void InitializeGUIs();
bool CanAfford(Resources&resources,std::vector<Memory>&unitCosts); bool CanAfford(Resources&resources,std::vector<Memory>&unitCosts);
void ExpendResources(Resources&resources,std::vector<Memory>&unitCosts); void ExpendResources(Resources&resources,std::vector<Memory>&unitCosts);
void UpdateUnitCreationListGUI(bool allocatorSelected); void UpdateUnitCreationListGUI(bool allocatorSelected);
void LoadLevel(LevelName level); void LoadLevel(LevelName level);
void InitializeLevelData(); void InitializeLevelData();
void UpdatePlatformCreationListGUI(bool platformSelected);
public: public:
VirusAttack(); VirusAttack();

@ -47,25 +47,30 @@ namespace util{
for(Memory&mem:unitCosts){ for(Memory&mem:unitCosts){
if(mem.type==HEALTH)return mem.size; if(mem.type==HEALTH)return mem.size;
} }
return -1;
}; };
int GetAtkSpdCost(std::vector<Memory>&unitCosts){ int GetAtkSpdCost(std::vector<Memory>&unitCosts){
for(Memory&mem:unitCosts){ for(Memory&mem:unitCosts){
if(mem.type==ATKSPD)return mem.size; if(mem.type==ATKSPD)return mem.size;
} }
return -1;
}; };
int GetMoveSpdCost(std::vector<Memory>&unitCosts){ int GetMoveSpdCost(std::vector<Memory>&unitCosts){
for(Memory&mem:unitCosts){ for(Memory&mem:unitCosts){
if(mem.type==MOVESPD)return mem.size; if(mem.type==MOVESPD)return mem.size;
} }
return -1;
}; };
int GetRangeCost(std::vector<Memory>&unitCosts){ int GetRangeCost(std::vector<Memory>&unitCosts){
for(Memory&mem:unitCosts){ for(Memory&mem:unitCosts){
if(mem.type==RANGE)return mem.size; if(mem.type==RANGE)return mem.size;
} }
return -1;
}; };
int GetProcedureCost(std::vector<Memory>&unitCosts){ int GetProcedureCost(std::vector<Memory>&unitCosts){
for(Memory&mem:unitCosts){ for(Memory&mem:unitCosts){
if(mem.type==PROCEDURE)return mem.size; if(mem.type==PROCEDURE)return mem.size;
} }
return -1;
}; };
} }
Loading…
Cancel
Save