|
|
|
@ -16,10 +16,11 @@ void Scenario::_Start(){ |
|
|
|
|
camera.SetTarget(targetPos); |
|
|
|
|
missionCompletedTimer=0; |
|
|
|
|
transitionToNextLevel=false; |
|
|
|
|
setupEasyMode=false; |
|
|
|
|
Start(); |
|
|
|
|
} |
|
|
|
|
void Scenario::Start(){}; |
|
|
|
|
void Scenario::_Update(){ |
|
|
|
|
void Scenario::_Update(Resources&enemy_resources,std::vector<std::shared_ptr<CollectionPoint>>&collectionPoints,int availableMemory,std::vector<std::shared_ptr<Unit>>&queuedUnits,std::vector<std::unique_ptr<Audio>>&SOUNDS){ |
|
|
|
|
initialWaitTime=std::max(0.f,initialWaitTime-game.GetPGE()->GetElapsedTime()); |
|
|
|
|
missionFinishWaitTime=std::max(0.f,missionFinishWaitTime-game.GetPGE()->GetElapsedTime()); |
|
|
|
|
smallTimePass=std::min(1.f,smallTimePass+game.GetPGE()->GetElapsedTime()); |
|
|
|
@ -31,10 +32,139 @@ void Scenario::_Update(){ |
|
|
|
|
} else { |
|
|
|
|
missionCompleted=MissionCompleted(); |
|
|
|
|
} |
|
|
|
|
if(flags.playerInControl){ |
|
|
|
|
RunAI(enemy_resources,collectionPoints,availableMemory,queuedUnits,SOUNDS); |
|
|
|
|
} |
|
|
|
|
if(initialWaitTime==0){ |
|
|
|
|
Update(); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
void Scenario::RunAI(Resources&enemy_resources,std::vector<std::shared_ptr<CollectionPoint>>&collectionPoints,int availableMemory,std::vector<std::shared_ptr<Unit>>&queuedUnits,std::vector<std::unique_ptr<Audio>>&SOUNDS){ |
|
|
|
|
if(!setupEasyMode&&flags.difficulty==0){ |
|
|
|
|
enemy_resources={100,100,100,100,100}; |
|
|
|
|
} |
|
|
|
|
unitBuildTimer=std::max(0.f,unitBuildTimer-game.GetPGE()->GetElapsedTime()); |
|
|
|
|
//See if there are collectors, if so send memory allocator units towards them.
|
|
|
|
|
for(auto cp:collectionPoints){ |
|
|
|
|
if(cp->attachedUnit.expired()){ |
|
|
|
|
if(cpCheckTimer.count(cp.get())==0||cpCheckTimer[cp.get()]<=0){ |
|
|
|
|
for(auto&u:units){ |
|
|
|
|
if(!u->IsFriendly()&&u->IsAllocator()&&u->attachTarget.expired()){ |
|
|
|
|
//Tell this unit to move towards that collection point.
|
|
|
|
|
u->SetTargetCollectionPoint(cp,u); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
//Hasn't been checked recently.
|
|
|
|
|
cpCheckTimer[cp.get()]=60; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for(auto&key:cpCheckTimer){ |
|
|
|
|
cpCheckTimer[key.first]=std::max(0.0f,game.GetPGE()->GetElapsedTime()); |
|
|
|
|
} |
|
|
|
|
int memoryAllocatorCount=0; |
|
|
|
|
for(auto&u:units){ |
|
|
|
|
if(!u->IsFriendly()&&u->IsAllocator()){ |
|
|
|
|
memoryAllocatorCount++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if(memoryAllocatorCount<3){ |
|
|
|
|
for(auto&u:units){ |
|
|
|
|
if(u->IsRAMBank()){ |
|
|
|
|
AttemptBuild(UnitType::MemoryAllocator,u->GetPos(),MemoryAllocator::resourceCost,enemy_resources,availableMemory,queuedUnits); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//Randomly turn memory allocators into other units.
|
|
|
|
|
if(unitBuildTimer==0){ |
|
|
|
|
for(auto&u:units){ |
|
|
|
|
if(!u->IsFriendly()&&u->IsAllocator()){ |
|
|
|
|
std::array<UnitType,10>unitChoiceList={UnitType::LeftShifter,UnitType::LeftShifter,UnitType::RightShifter,UnitType::RightShifter, |
|
|
|
|
UnitType::Corrupter,UnitType::MemorySwapper,UnitType::BitRestorer,UnitType::BitRestorer,UnitType::_Platform,UnitType::Corrupter}; |
|
|
|
|
std::array<std::vector<Memory>,10>unitResourceCostList={LeftShifter::resourceCost,LeftShifter::resourceCost,RightShifter::resourceCost,RightShifter::resourceCost, |
|
|
|
|
Corrupter::resourceCost,MemorySwapper::resourceCost,BitRestorer::resourceCost,BitRestorer::resourceCost,_Platform::resourceCost,Corrupter::resourceCost}; |
|
|
|
|
int randomIndex=rand()%unitChoiceList.size(); |
|
|
|
|
UnitType buildUnit=unitChoiceList[randomIndex]; |
|
|
|
|
|
|
|
|
|
int totalCost=0; |
|
|
|
|
for(int i=0;i<5;i++){ |
|
|
|
|
totalCost+=unitResourceCostList[randomIndex][i].size; |
|
|
|
|
} |
|
|
|
|
if(totalCost<=availableMemory){ |
|
|
|
|
#define Build(type) \ |
|
|
|
|
case UnitType::type:{ \
|
|
|
|
|
u->SetBuildUnit(8,std::make_shared<type>(game.GetPGE(),u->GetPos(),IMAGES,false),SOUNDS); \
|
|
|
|
|
}break; |
|
|
|
|
switch(buildUnit){ |
|
|
|
|
Build(LeftShifter) |
|
|
|
|
Build(RightShifter) |
|
|
|
|
Build(BitRestorer) |
|
|
|
|
Build(_Platform) |
|
|
|
|
Build(Corrupter) |
|
|
|
|
Build(MemorySwapper) |
|
|
|
|
} |
|
|
|
|
if(enemy_resources.health>0){enemy_resources.health=std::max(0,enemy_resources.health-totalCost);}else |
|
|
|
|
if(enemy_resources.atkSpd>0){enemy_resources.atkSpd=std::max(0,enemy_resources.atkSpd-totalCost);}else |
|
|
|
|
if(enemy_resources.moveSpd>0){enemy_resources.moveSpd=std::max(0,enemy_resources.moveSpd-totalCost);}else |
|
|
|
|
if(enemy_resources.range>0){enemy_resources.range=std::max(0,enemy_resources.range-totalCost);}else |
|
|
|
|
{enemy_resources.procedure=std::max(0,enemy_resources.procedure-totalCost); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
switch(flags.difficulty){ |
|
|
|
|
case 0:{ |
|
|
|
|
unitBuildTimer=120; |
|
|
|
|
}break; |
|
|
|
|
case 1:{ |
|
|
|
|
unitBuildTimer=60; |
|
|
|
|
}break; |
|
|
|
|
case 2:{ |
|
|
|
|
unitBuildTimer=10; |
|
|
|
|
}break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/*
|
|
|
|
|
std::shared_ptr<UnitClass>buildUnit=std::make_shared<UnitClass>(this,u->GetPos(),IMAGES,u->IsFriendly()); \
|
|
|
|
|
u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit),SOUNDS); \
|
|
|
|
|
*/ |
|
|
|
|
bool Scenario::AttemptBuild(UnitType unit,vf2d pos,std::vector<Memory>&resourceCost,Resources&enemy_resources,int availableMemory,std::vector<std::shared_ptr<Unit>>&queuedUnits){ |
|
|
|
|
int enemyTotalResources=enemy_resources.atkSpd+enemy_resources.health+enemy_resources.moveSpd+enemy_resources.procedure+enemy_resources.range; |
|
|
|
|
int totalCost=0; |
|
|
|
|
for(int i=0;i<resourceCost.size();i++){ |
|
|
|
|
totalCost+=resourceCost[i].size; |
|
|
|
|
} |
|
|
|
|
if(totalCost>availableMemory)return false; |
|
|
|
|
if(enemyTotalResources>=totalCost){ |
|
|
|
|
if(enemy_resources.health>0){enemy_resources.health=std::max(0,enemy_resources.health-totalCost);}else |
|
|
|
|
if(enemy_resources.atkSpd>0){enemy_resources.atkSpd=std::max(0,enemy_resources.atkSpd-totalCost);}else |
|
|
|
|
if(enemy_resources.moveSpd>0){enemy_resources.moveSpd=std::max(0,enemy_resources.moveSpd-totalCost);}else |
|
|
|
|
if(enemy_resources.range>0){enemy_resources.range=std::max(0,enemy_resources.range-totalCost);}else |
|
|
|
|
{enemy_resources.procedure=std::max(0,enemy_resources.procedure-totalCost);} |
|
|
|
|
#define TranslateUnit(type) \ |
|
|
|
|
case UnitType::type:{ \
|
|
|
|
|
queuedUnits.emplace_back(std::make_shared<type>(game.GetPGE(),pos,IMAGES,false)); \
|
|
|
|
|
}break; |
|
|
|
|
switch(unit){ |
|
|
|
|
TranslateUnit(MemoryAllocator) |
|
|
|
|
TranslateUnit(LeftShifter) |
|
|
|
|
TranslateUnit(RightShifter) |
|
|
|
|
TranslateUnit(BitRestorer) |
|
|
|
|
TranslateUnit(MemorySwapper) |
|
|
|
|
TranslateUnit(Corrupter) |
|
|
|
|
TranslateUnit(RAMBank) |
|
|
|
|
TranslateUnit(MemoryGuard) |
|
|
|
|
TranslateUnit(Refresher) |
|
|
|
|
TranslateUnit(Turret) |
|
|
|
|
TranslateUnit(_Platform) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool Scenario::MissionCompleted(){return false;} |
|
|
|
|
void Scenario::Update(){}; |
|
|
|
|
void Scenario::Draw(){ |
|
|
|
|