Prevent player from building units that overflow the system memory.

CorrectiveAction
sigonasr2 1 year ago
parent 86121c9da8
commit 1074d4a59a
  1. 10
      olcCodeJam2023Entry/Unit.cpp
  2. 5
      olcCodeJam2023Entry/Unit.h
  3. 42
      olcCodeJam2023Entry/VirusAttack.cpp
  4. 1
      olcCodeJam2023Entry/VirusAttack.h

@ -230,14 +230,14 @@ void RAMBank::OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS){
SOUNDS[Sound::HUM]->Stop(soundHandle); SOUNDS[Sound::HUM]->Stop(soundHandle);
} }
void RAMBank::UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered){ void RAMBank::UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered,int totalUsedMemory,int availableMemory){
allocatorManager.Update(game); allocatorManager.Update(game);
auto TotalResources=[&](){ auto TotalResources=[&](){
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&&GetProcedure()==procedure.size; bool buttonEnabled=IsSelected()&&TotalResources()>=5&&GetProcedure()==procedure.size&&5+totalUsedMemory<=availableMemory;
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);
@ -935,7 +935,7 @@ bool Unit::ClickHandled(TileTransformedView&game,Resources&player_resources,std:
return false; return false;
}; };
void Unit::UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered){}; void Unit::UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered,int totalUsedMemory,int availableMemory){};
bool Unit::IsAllocator(){ bool Unit::IsAllocator(){
return isAllocator&&attachedPoint.expired()&&buildTime<=0; return isAllocator&&attachedPoint.expired()&&buildTime<=0;
@ -968,4 +968,8 @@ bool Unit::IsPlatform(){
bool Unit::IsAttached(){ bool Unit::IsAttached(){
return !attachedPoint.expired(); return !attachedPoint.expired();
}
Unit*Unit::GetBuildUnit(){
return buildTransformUnit.get();
} }

@ -87,7 +87,7 @@ public:
bool CanMove(); bool CanMove();
void SetTargetCollectionPoint(std::weak_ptr<CollectionPoint>targetCP,std::weak_ptr<Unit>self_ptr); void SetTargetCollectionPoint(std::weak_ptr<CollectionPoint>targetCP,std::weak_ptr<Unit>self_ptr);
Pixel GetUnitColor(); Pixel GetUnitColor();
virtual void UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered); virtual void UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered,int totalUsedMemory,int availableMemory);
virtual bool ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector<std::shared_ptr<Unit>>&units,std::map<Image,std::unique_ptr<Renderable>>&IMAGES); //If you return true here, then the left click does not pass back to the main Virus Attack class. virtual bool ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector<std::shared_ptr<Unit>>&units,std::map<Image,std::unique_ptr<Renderable>>&IMAGES); //If you return true here, then the left click does not pass back to the main Virus Attack class.
bool IsAllocator(); bool IsAllocator();
void SetBuildUnit(float buildTime,std::unique_ptr<Unit>finalUnit); void SetBuildUnit(float buildTime,std::unique_ptr<Unit>finalUnit);
@ -97,6 +97,7 @@ public:
void SaveMemory(); void SaveMemory();
bool IsPlatform(); bool IsPlatform();
bool IsAttached(); bool IsAttached();
Unit*GetBuildUnit();
Marker health={}; Marker health={};
Marker range={}; Marker range={};
Marker atkSpd={}; Marker atkSpd={};
@ -225,7 +226,7 @@ struct RAMBank:Unit{
void Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES)override; void Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES)override;
void OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS)override; void OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS)override;
bool ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector<std::shared_ptr<Unit>>&units,std::map<Image,std::unique_ptr<Renderable>>&IMAGES)override; bool ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector<std::shared_ptr<Unit>>&units,std::map<Image,std::unique_ptr<Renderable>>&IMAGES)override;
void UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered)override; void UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered,int totalUsedMemory,int availableMemory)override;
void DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES)override; void DrawHud(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;

@ -267,6 +267,7 @@ bool VirusAttack::UnitCreationClickHandled(){
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); \
CalculateUsedMemory(); \
} \ } \
} \ } \
return true; \ return true; \
@ -337,7 +338,7 @@ void VirusAttack::HandleDraggingSelection(){
bool platformSelected=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,GetTotalUsedMemory(),currentLevel->availableMemory);
if(u->IsSelected()){ if(u->IsSelected()){
if(u->IsAllocator()){ if(u->IsAllocator()){
allocatorSelected=true; allocatorSelected=true;
@ -450,7 +451,7 @@ void VirusAttack::HandleRightClickMove(){
void VirusAttack::CollisionChecking(std::shared_ptr<Unit>u,std::shared_ptr<Unit>u2){ void VirusAttack::CollisionChecking(std::shared_ptr<Unit>u,std::shared_ptr<Unit>u2){
if(u!=u2&&geom2d::overlaps(geom2d::circle<float>(u->GetPos(),u->GetUnitSize().x/2),geom2d::circle<float>(u2->GetPos(),u2->GetUnitSize().x/2))){ if(u!=u2&&geom2d::overlaps(geom2d::circle<float>(u->GetPos(),u->GetUnitSize().x/2),geom2d::circle<float>(u2->GetPos(),u2->GetUnitSize().x/2))){
geom2d::line<float>collisionLine(u->GetPos(),u2->GetPos()); geom2d::line<float>collisionLine(u->GetPos(),u2->GetPos()+vf2d{0.001,0.001});
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();
@ -458,7 +459,7 @@ void VirusAttack::CollisionChecking(std::shared_ptr<Unit>u,std::shared_ptr<Unit>
u->SetPos(u->GetPos()-dir*dist/2); u->SetPos(u->GetPos()-dir*dist/2);
} }
if(u2->IsMoveable()||(!u->IsMoveable()&&!u2->IsMoveable())){ if(u2->IsMoveable()||(!u->IsMoveable()&&!u2->IsMoveable())){
u2->SetPos(u2->GetPos()+dir*(dist+0.001)/2); u2->SetPos(u2->GetPos()+dir*(dist)/2);
} }
} }
} }
@ -670,7 +671,7 @@ bool VirusAttack::OnUserUpdate(float 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;});
playerUsedMemory=enemyUsedMemory={0}; CalculateUsedMemory();
for(auto&u:units){ for(auto&u:units){
u->SaveMemory(); u->SaveMemory();
std::weak_ptr<Unit>closestUnit; std::weak_ptr<Unit>closestUnit;
@ -690,19 +691,6 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
} }
u->AttemptAttack(u,closestUnit,units,debuffIcons,IMAGES); u->AttemptAttack(u,closestUnit,units,debuffIcons,IMAGES);
u->_Update(this,SOUNDS,player_resources,enemy_resources,queuedUnits,resourceGainTimer,resourceGainIcons,IMAGES); u->_Update(this,SOUNDS,player_resources,enemy_resources,queuedUnits,resourceGainTimer,resourceGainIcons,IMAGES);
if(u->IsFriendly()){
playerUsedMemory[0]+=u->health.size;
playerUsedMemory[1]+=u->range.size;
playerUsedMemory[2]+=u->atkSpd.size;
playerUsedMemory[3]+=u->moveSpd.size;
playerUsedMemory[4]+=u->procedure.size;
} else {
enemyUsedMemory[0]+=u->health.size;
enemyUsedMemory[1]+=u->range.size;
enemyUsedMemory[2]+=u->atkSpd.size;
enemyUsedMemory[3]+=u->moveSpd.size;
enemyUsedMemory[4]+=u->procedure.size;
}
} }
std::erase_if(units,[&](std::shared_ptr<Unit>u){ std::erase_if(units,[&](std::shared_ptr<Unit>u){
@ -962,6 +950,7 @@ void VirusAttack::RenderFogOfWar(){
} }
bool VirusAttack::CanAfford(Resources&resources,std::vector<Memory>&unitCosts){ bool VirusAttack::CanAfford(Resources&resources,std::vector<Memory>&unitCosts){
int totalMemoryCost=0;
for(Memory&mem:unitCosts){ for(Memory&mem:unitCosts){
switch(mem.type){ switch(mem.type){
case HEALTH:{ case HEALTH:{
@ -980,8 +969,9 @@ bool VirusAttack::CanAfford(Resources&resources,std::vector<Memory>&unitCosts){
if(resources.procedure<mem.size)return false; if(resources.procedure<mem.size)return false;
}break; }break;
} }
totalMemoryCost+=mem.size;
} }
return true; return totalMemoryCost+GetTotalUsedMemory()<=currentLevel->availableMemory;
} }
void VirusAttack::ExpendResources(Resources&resources,std::vector<Memory>&unitCosts){ void VirusAttack::ExpendResources(Resources&resources,std::vector<Memory>&unitCosts){
@ -1024,6 +1014,22 @@ int VirusAttack::GetEnemyUsedMemory(){
return sum; return sum;
} }
void VirusAttack::CalculateUsedMemory(){
playerUsedMemory=enemyUsedMemory={0};
for(auto&u:units){
std::array<size_t,5>costs={u->health.size,u->range.size,u->atkSpd.size,u->moveSpd.size,u->procedure.size};
if(u->IsBuilding()){
costs={u->GetBuildUnit()->health.size,u->GetBuildUnit()->range.size,u->GetBuildUnit()->atkSpd.size,u->GetBuildUnit()->moveSpd.size,u->GetBuildUnit()->procedure.size};
}
std::array<int,5>&targetArr=u->IsFriendly()?playerUsedMemory:enemyUsedMemory;
for(int i=0;i<targetArr.size();i++){
targetArr[i]+=costs[i];
}
}
}
int main() int main()
{ {
VirusAttack app; VirusAttack app;

@ -110,6 +110,7 @@ private:
int GetPlayerUsedMemory(); int GetPlayerUsedMemory();
int GetEnemyUsedMemory(); int GetEnemyUsedMemory();
void DrawSystemMemoryBar(float fElapsedTime); void DrawSystemMemoryBar(float fElapsedTime);
void CalculateUsedMemory();
public: public:
VirusAttack(); VirusAttack();

Loading…
Cancel
Save