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);
}
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);
auto TotalResources=[&](){
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){
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;
};
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(){
return isAllocator&&attachedPoint.expired()&&buildTime<=0;
@ -968,4 +968,8 @@ bool Unit::IsPlatform(){
bool Unit::IsAttached(){
return !attachedPoint.expired();
}
Unit*Unit::GetBuildUnit(){
return buildTransformUnit.get();
}

@ -87,7 +87,7 @@ public:
bool CanMove();
void SetTargetCollectionPoint(std::weak_ptr<CollectionPoint>targetCP,std::weak_ptr<Unit>self_ptr);
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.
bool IsAllocator();
void SetBuildUnit(float buildTime,std::unique_ptr<Unit>finalUnit);
@ -97,6 +97,7 @@ public:
void SaveMemory();
bool IsPlatform();
bool IsAttached();
Unit*GetBuildUnit();
Marker health={};
Marker range={};
Marker atkSpd={};
@ -225,7 +226,7 @@ struct RAMBank:Unit{
void Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES)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;
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;
static std::vector<Memory> resourceCost;
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()); \
u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit)); \
ExpendResources(player_resources,UnitClass::resourceCost); \
CalculateUsedMemory(); \
} \
} \
return true; \
@ -337,7 +338,7 @@ void VirusAttack::HandleDraggingSelection(){
bool platformSelected=false;
bool memoryAllocatorBoxHovered=false;
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->IsAllocator()){
allocatorSelected=true;
@ -450,7 +451,7 @@ void VirusAttack::HandleRightClickMove(){
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))){
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 dist=maxDist-collisionLine.length();
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);
}
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;});
playerUsedMemory=enemyUsedMemory={0};
CalculateUsedMemory();
for(auto&u:units){
u->SaveMemory();
std::weak_ptr<Unit>closestUnit;
@ -690,19 +691,6 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
}
u->AttemptAttack(u,closestUnit,units,debuffIcons,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){
@ -962,6 +950,7 @@ void VirusAttack::RenderFogOfWar(){
}
bool VirusAttack::CanAfford(Resources&resources,std::vector<Memory>&unitCosts){
int totalMemoryCost=0;
for(Memory&mem:unitCosts){
switch(mem.type){
case HEALTH:{
@ -980,8 +969,9 @@ bool VirusAttack::CanAfford(Resources&resources,std::vector<Memory>&unitCosts){
if(resources.procedure<mem.size)return false;
}break;
}
totalMemoryCost+=mem.size;
}
return true;
return totalMemoryCost+GetTotalUsedMemory()<=currentLevel->availableMemory;
}
void VirusAttack::ExpendResources(Resources&resources,std::vector<Memory>&unitCosts){
@ -1024,6 +1014,22 @@ int VirusAttack::GetEnemyUsedMemory(){
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()
{
VirusAttack app;

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

Loading…
Cancel
Save