diff --git a/olcCodeJam2023Entry/Constant.cpp b/olcCodeJam2023Entry/Constant.cpp index 9d7fcae..1b6934f 100644 --- a/olcCodeJam2023Entry/Constant.cpp +++ b/olcCodeJam2023Entry/Constant.cpp @@ -28,4 +28,6 @@ float CONSTANT::DEBUFFICON_LIFETIME=0.8; float CONSTANT::COLLECTION_WAIT_TIME=8; -int CONSTANT::MEMORY_ALLOCATOR_COST=5; \ No newline at end of file +int CONSTANT::MEMORY_ALLOCATOR_COST=5; + +float CONSTANT::UNIT_BUILD_TIME=10; \ No newline at end of file diff --git a/olcCodeJam2023Entry/Constant.h b/olcCodeJam2023Entry/Constant.h index ed2e8b2..df804d6 100644 --- a/olcCodeJam2023Entry/Constant.h +++ b/olcCodeJam2023Entry/Constant.h @@ -33,4 +33,6 @@ public: static float COLLECTION_WAIT_TIME; static int MEMORY_ALLOCATOR_COST; + + static float UNIT_BUILD_TIME; }; \ No newline at end of file diff --git a/olcCodeJam2023Entry/Unit.cpp b/olcCodeJam2023Entry/Unit.cpp index 778e3f3..ae50101 100644 --- a/olcCodeJam2023Entry/Unit.cpp +++ b/olcCodeJam2023Entry/Unit.cpp @@ -5,67 +5,42 @@ #include "DebuffIcon.h" #include "olcPGEX_QuickGUI.h" +std::vector BasicUnit::resourceCost={{HEALTH,4},{RANGE,2},{ATKSPD,2},{MOVESPD,3},{PROCEDURE,1}}; BasicUnit::BasicUnit(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) - :Unit(pge,{ - {HEALTH,4}, - {RANGE,2}, - {ATKSPD,2}, - {MOVESPD,3}, - {PROCEDURE,1}, - },pos,12,*IMAGES[VIRUS_IMG1],WHITE,WHITE,friendly,moveable){} + :Unit(pge,BasicUnit::resourceCost,pos,12,*IMAGES[VIRUS_IMG1],WHITE,WHITE,friendly,moveable){} void BasicUnit::Attack(Unit&victim,std::vector>&otherUnits){ victim<<=1; } +std::vector BasicUnit2::resourceCost={{RANGE,2},{ATKSPD,2},{MOVESPD,3},{PROCEDURE,1},{HEALTH,4}}; BasicUnit2::BasicUnit2(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) - :Unit(pge,{ - {RANGE,2}, - {ATKSPD,2}, - {MOVESPD,3}, - {PROCEDURE,1}, - {HEALTH,4}, - },pos,12,*IMAGES[VIRUS_IMG1],WHITE,WHITE,friendly,moveable){} + :Unit(pge,BasicUnit2::resourceCost,pos,12,*IMAGES[VIRUS_IMG1],WHITE,WHITE,friendly,moveable){} void BasicUnit2::Attack(Unit&victim,std::vector>&otherUnits){ victim>>=1; } +std::vector LeftShifter::resourceCost={{RANGE,2},{ATKSPD,2},{MOVESPD,3},{PROCEDURE,1},{HEALTH,4}}; LeftShifter::LeftShifter(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) - :Unit(pge,{ - {RANGE,2}, - {ATKSPD,2}, - {MOVESPD,3}, - {PROCEDURE,1}, - {HEALTH,4}, - },pos,12,*IMAGES[LEFT_SHIFTER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){} + :Unit(pge,LeftShifter::resourceCost,pos,12,*IMAGES[LEFT_SHIFTER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){} void LeftShifter::Attack(Unit&victim,std::vector>&otherUnits){ victim<<=1; } +std::vector RightShifter::resourceCost={{HEALTH,4},{RANGE,2},{ATKSPD,2},{MOVESPD,3},{PROCEDURE,1}}; RightShifter::RightShifter(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) - :Unit(pge,{ - {HEALTH,4}, - {RANGE,2}, - {ATKSPD,2}, - {MOVESPD,3}, - {PROCEDURE,1}, - },pos,12,*IMAGES[RIGHT_SHIFTER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){} + :Unit(pge,RightShifter::resourceCost,pos,12,*IMAGES[RIGHT_SHIFTER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){} void RightShifter::Attack(Unit&victim,std::vector>&otherUnits){ victim>>=1; } +std::vector BitRestorer::resourceCost={{PROCEDURE,6},{RANGE,1},{ATKSPD,1},{MOVESPD,1},{HEALTH,2}}; BitRestorer::BitRestorer(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) - :Unit(pge,{ - {PROCEDURE,6}, - {RANGE,1}, - {ATKSPD,1}, - {MOVESPD,1}, - {HEALTH,2}, - },pos,12,*IMAGES[BIT_RESTORER],CONSTANT::HEALER_TARGET_COL,CONSTANT::HEALER_ATTACK_COL,friendly,moveable,true,false){} + :Unit(pge,BitRestorer::resourceCost,pos,12,*IMAGES[BIT_RESTORER],CONSTANT::HEALER_TARGET_COL,CONSTANT::HEALER_ATTACK_COL,friendly,moveable,true,false){} void BitRestorer::Attack(Unit&victim,std::vector>&otherUnits){ std::vectoremptyMemoryPositions; @@ -103,14 +78,9 @@ void BitRestorer::AttemptToHealOtherAllies(std::vector>&ot } } +std::vector MemorySwapper::resourceCost={{RANGE,3},{ATKSPD,1},{HEALTH,3},{PROCEDURE,3},{MOVESPD,2}}; MemorySwapper::MemorySwapper(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) - :Unit(pge,{ - {RANGE,3}, - {ATKSPD,1}, - {HEALTH,3}, - {PROCEDURE,3}, - {MOVESPD,2}, - },pos,12,*IMAGES[MEMORY_SWAPPER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable,true){ + :Unit(pge,MemorySwapper::resourceCost,pos,12,*IMAGES[MEMORY_SWAPPER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable,true){ autoAcquireFriendlyTarget=false; } @@ -118,14 +88,9 @@ void MemorySwapper::Attack(Unit&victim,std::vector>&otherU } +std::vector Corrupter::resourceCost={{ATKSPD,3},{RANGE,1},{PROCEDURE,8},{MOVESPD,4},{HEALTH,4}}; Corrupter::Corrupter(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) - :Unit(pge,{ - {ATKSPD,3}, - {RANGE,1}, - {PROCEDURE,8}, - {MOVESPD,4}, - {HEALTH,4}, - },pos,12,*IMAGES[CORRUPTER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){} + :Unit(pge,Corrupter::resourceCost,pos,12,*IMAGES[CORRUPTER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){} void Corrupter::Attack(Unit&victim,std::vector>&otherUnits){ //Chooses a bit at random and corrupts it. @@ -133,14 +98,9 @@ void Corrupter::Attack(Unit&victim,std::vector>&otherUnits victim.memory[randomBit]=victim.ghostMemory[randomBit]=false; } +std::vector MemoryAllocator::resourceCost={{RANGE,1},{ATKSPD,1},{MOVESPD,1},{PROCEDURE,1},{HEALTH,1}}; MemoryAllocator::MemoryAllocator(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) - :Unit(pge,{ - {RANGE,1}, - {ATKSPD,1}, - {MOVESPD,1}, - {PROCEDURE,1}, - {HEALTH,1}, - },pos,12,*IMAGES[UNIT_ALLOCATOR],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,true,false){ + :Unit(pge,MemoryAllocator::resourceCost,pos,12,*IMAGES[UNIT_ALLOCATOR],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,true,false){ isAllocator=true; } @@ -148,14 +108,9 @@ void MemoryAllocator::Attack(Unit&victim,std::vector>&othe } +std::vector RAMBank::resourceCost={{RANGE,0},{ATKSPD,0},{MOVESPD,0},{PROCEDURE,25},{HEALTH,16}}; RAMBank::RAMBank(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly) - :Unit(pge,{ - {RANGE,0}, - {ATKSPD,0}, - {MOVESPD,0}, - {PROCEDURE,25}, - {HEALTH,16}, - },pos,41,*IMAGES[RAM_BANK],WHITE,WHITE,friendly,false + :Unit(pge,RAMBank::resourceCost,pos,41,*IMAGES[RAM_BANK],WHITE,WHITE,friendly,false ,false,false ),randomOffset({util::random(128),util::random(128)}),matrixImg(*IMAGES[MATRIX]), originalImg(*IMAGES[RAM_BANK]){ @@ -733,11 +688,11 @@ bool Unit::IsMoveable(){ } bool Unit::CanInteractWithAllies(){ - return friendlyInteractable&&attachedPoint.expired(); + return friendlyInteractable&&attachedPoint.expired()&&buildTime<=0; } bool Unit::CanInteractWithEnemies(){ - return enemyInteractable&&attachedPoint.expired(); + return enemyInteractable&&attachedPoint.expired()&&buildTime<=0; } Renderable&Unit::GetImage(){ @@ -753,7 +708,7 @@ bool Unit::AutoAcquiresFriendlyTargets(){ } bool Unit::CanMove(){ - return moveSpd.size>0&&attachedPoint.expired(); + return moveSpd.size>0&&attachedPoint.expired()&&buildTime<=0; } void Unit::SetTargetCollectionPoint(std::weak_ptrtargetCP,std::weak_ptrself_ptr){ @@ -795,5 +750,10 @@ bool Unit::ClickHandled(TileTransformedView&game,Resources&player_resources,std: void Unit::UpdateGUIState(TileTransformedView&game,Resources&player_resources){}; bool Unit::IsAllocator(){ - return isAllocator; + return isAllocator&&attachedPoint.expired()&&buildTime<=0; +} + +void Unit::SetBuildUnit(float buildTime,std::unique_ptrfinalUnit){ + this->buildTime=buildTime; + this->buildTransformUnit=std::move(finalUnit); } \ No newline at end of file diff --git a/olcCodeJam2023Entry/Unit.h b/olcCodeJam2023Entry/Unit.h index f1e2739..c53d13f 100644 --- a/olcCodeJam2023Entry/Unit.h +++ b/olcCodeJam2023Entry/Unit.h @@ -74,6 +74,7 @@ public: virtual void UpdateGUIState(TileTransformedView&game,Resources&player_resources); virtual bool ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector>&units,std::map>&IMAGES); //If you return true here, then the left click does not pass back to the main Virus Attack class. bool IsAllocator(); + void SetBuildUnit(float buildTime,std::unique_ptrfinalUnit); std::vector& operator <<=(const int n){ for(int i=0;iself_ptr; float collectionTime=0; + float buildTime=0; + std::unique_ptrbuildTransformUnit; }; struct BasicUnit:Unit{ BasicUnit(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly=false,bool moveable=true); void Attack(Unit&victim,std::vector>&otherUnits)override; + static std::vector resourceCost; }; struct BasicUnit2:Unit{ BasicUnit2(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly=false,bool moveable=true); void Attack(Unit&victim,std::vector>&otherUnits)override; + static std::vector resourceCost; }; struct LeftShifter:Unit{ LeftShifter(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly=false,bool moveable=true); void Attack(Unit&victim,std::vector>&otherUnits)override; + static std::vector resourceCost; }; struct RightShifter:Unit{ RightShifter(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly=false,bool moveable=true); void Attack(Unit&victim,std::vector>&otherUnits)override; + static std::vector resourceCost; }; struct BitRestorer:Unit{ BitRestorer(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly=false,bool moveable=true); void Attack(Unit&victim,std::vector>&otherUnits)override; void AttemptToHealOtherAllies(std::vector>&otherUnits); + static std::vector resourceCost; }; struct MemorySwapper:Unit{ MemorySwapper(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly=false,bool moveable=true); void Attack(Unit&victim,std::vector>&otherUnits)override; + static std::vector resourceCost; }; struct Corrupter:Unit{ Corrupter(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly=false,bool moveable=true); void Attack(Unit&victim,std::vector>&otherUnits)override; + static std::vector resourceCost; }; struct MemoryAllocator:Unit{ MemoryAllocator(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly=false,bool moveable=true); void Attack(Unit&victim,std::vector>&otherUnits)override; + static std::vector resourceCost; }; struct RAMBank:Unit{ @@ -195,4 +206,5 @@ struct RAMBank:Unit{ bool ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector>&units,std::map>&IMAGES)override; void UpdateGUIState(TileTransformedView&game,Resources&player_resources)override; void DrawHud(TileTransformedView&game,std::map>&IMAGES)override; + static std::vector resourceCost; }; \ No newline at end of file diff --git a/olcCodeJam2023Entry/VirusAttack.cpp b/olcCodeJam2023Entry/VirusAttack.cpp index 2d611e4..627577f 100644 --- a/olcCodeJam2023Entry/VirusAttack.cpp +++ b/olcCodeJam2023Entry/VirusAttack.cpp @@ -123,21 +123,57 @@ void VirusAttack::InitializeSounds(){ bool VirusAttack::UnitCreationClickHandled(){ if(leftShifterButton->bPressed){ + for(auto&u:units){ + if(u->IsSelected()&&u->IsAllocator()&&CanAfford(LeftShifter::resourceCost)){ + std::unique_ptrbuildUnit=std::make_unique(this,u->GetPos(),IMAGES,u->IsFriendly()); + u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit)); + } + } return true; } if(rightShifterButton->bPressed){ + for(auto&u:units){ + if(u->IsSelected()&&u->IsAllocator()&&CanAfford(RightShifter::resourceCost)){ + std::unique_ptrbuildUnit=std::make_unique(this,u->GetPos(),IMAGES,u->IsFriendly()); + u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit)); + } + } return true; } if(bitRestorerButton->bPressed){ + for(auto&u:units){ + if(u->IsSelected()&&u->IsAllocator()&&CanAfford(BitRestorer::resourceCost)){ + std::unique_ptrbuildUnit=std::make_unique(this,u->GetPos(),IMAGES,u->IsFriendly()); + u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit)); + } + } return true; } if(memorySwapperButton->bPressed){ + for(auto&u:units){ + if(u->IsSelected()&&u->IsAllocator()&&CanAfford(MemorySwapper::resourceCost)){ + std::unique_ptrbuildUnit=std::make_unique(this,u->GetPos(),IMAGES,u->IsFriendly()); + u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit)); + } + } return true; } if(corrupterButton->bPressed){ + for(auto&u:units){ + if(u->IsSelected()&&u->IsAllocator()&&CanAfford(Corrupter::resourceCost)){ + std::unique_ptrbuildUnit=std::make_unique(this,u->GetPos(),IMAGES,u->IsFriendly()); + u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit)); + } + } return true; } if(platformButton->bPressed){ + for(auto&u:units){ + if(u->IsSelected()&&u->IsAllocator()&&CanAfford(MemoryAllocator::resourceCost)){ + std::unique_ptrbuildUnit=std::make_unique(this,u->GetPos(),IMAGES,u->IsFriendly()); + u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit)); + } + } return true; } return false; @@ -153,6 +189,12 @@ void VirusAttack::HandleDraggingSelection(){ } } unitCreationList.DisplayAllControls(allocatorSelected); + leftShifterButton->Enable(CanAfford(LeftShifter::resourceCost)); + rightShifterButton->Enable(CanAfford(RightShifter::resourceCost)); + bitRestorerButton->Enable(CanAfford(BitRestorer::resourceCost)); + memorySwapperButton->Enable(CanAfford(MemorySwapper::resourceCost)); + corrupterButton->Enable(CanAfford(Corrupter::resourceCost)); + platformButton->Enable(CanAfford(MemoryAllocator::resourceCost)); unitCreationList.Update(this); if(GetMouse(0).bPressed){ if(NotClickingOnMinimap()){ @@ -533,6 +575,29 @@ void VirusAttack::RenderFogOfWar(){ } } +bool VirusAttack::CanAfford(std::vector&unitCosts){ + for(Memory&mem:unitCosts){ + switch(mem.type){ + case HEALTH:{ + if(player_resources.health&unitCosts); public: VirusAttack();