Setup stages and finally cleared out memory issues.

master
sigonasr2 1 year ago
parent 64f6b44994
commit 7fd6cf677e
  1. 8
      olcCodeJam2023Entry/GameFlags.h
  2. 3
      olcCodeJam2023Entry/Level.h
  3. 7
      olcCodeJam2023Entry/Memory.h
  4. 197
      olcCodeJam2023Entry/Scenario.cpp
  5. 47
      olcCodeJam2023Entry/Scenario.h
  6. 4
      olcCodeJam2023Entry/Sound.h
  7. 3
      olcCodeJam2023Entry/Textbox.h
  8. 12
      olcCodeJam2023Entry/Unit.cpp
  9. 24
      olcCodeJam2023Entry/Unit.h
  10. 39
      olcCodeJam2023Entry/VirusAttack.cpp
  11. 8
      olcCodeJam2023Entry/VirusAttack.h
  12. 2
      olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj
  13. 6
      olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj.filters

@ -0,0 +1,8 @@
#pragma once
struct GameFlags{
bool unitMetersGreyedOut=true;//If true, all but health meters show up as dark grey.
bool playerInControl=false;
bool limitedBuildOptions=false;
bool guideEnabled=true;
};

@ -12,6 +12,7 @@ enum LevelName{
STAGE6, STAGE6,
STAGE7, STAGE7,
STAGE8, STAGE8,
FINISH,
}; };
struct UnitData{ struct UnitData{
@ -37,7 +38,7 @@ struct Level{
Resources enemy_starting_resources; Resources enemy_starting_resources;
std::vector<UnitData>unitPlacement; std::vector<UnitData>unitPlacement;
std::vector<CPData>cpPlacement; std::vector<CPData>cpPlacement;
Sound bgm=Sound::COSMOS; Sound::Sound bgm=Sound::COSMOS;
int scenarioIndex=0; int scenarioIndex=0;
vf2d cameraStart={96,96}; vf2d cameraStart={96,96};
vf2d worldZoom={1,1}; vf2d worldZoom={1,1};

@ -0,0 +1,7 @@
#pragma once
#include "MemoryType.h"
struct Memory{
MemoryType type;
int size;
};

@ -1,43 +1,155 @@
#include "Scenario.h" #include "Scenario.h"
#include "VirusAttack.h" #include "TileManager.h"
extern VirusAttack*game;
Scenario::Scenario(){} Scenario::Scenario(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags)
:units(units),IMAGES(IMAGES),SOUNDS(SOUNDS),objective(objective),game(game),flags(flags){}
Scenario::~Scenario(){}; Scenario::~Scenario(){};
void Scenario::_Start(){ void Scenario::_Start(){
state=0; state=0;
camera=utils::Camera2D{game->gametv.GetWorldOffset(),game->currentLevel->cameraStart}; camera=utils::Camera2D{game.GetPGE()->GetScreenSize(),game.GetWorldOffset()};
camera.SetLazyFollowRate(2); camera.SetLazyFollowRate(2);
camera.SetMode(utils::Camera2D::Mode::LazyFollow); camera.SetMode(utils::Camera2D::Mode::LazyFollow);
targetPos={96,96}; targetPos={96,96};
box.SetVisible(false); box.SetVisible(false);
initialWaitTime=3; initialWaitTime=3;
camera.SetTarget(targetPos); camera.SetTarget(targetPos);
missionCompletedTimer=0;
transitionToNextLevel=false;
Start(); Start();
} }
void Scenario::Start(){}; void Scenario::Start(){};
void Scenario::_Update(){ void Scenario::_Update(){
initialWaitTime=std::max(0.f,initialWaitTime-game->GetElapsedTime()); initialWaitTime=std::max(0.f,initialWaitTime-game.GetPGE()->GetElapsedTime());
missionFinishWaitTime=std::max(0.f,missionFinishWaitTime-game.GetPGE()->GetElapsedTime());
if(missionCompleted){
missionCompletedTimer+=game.GetPGE()->GetElapsedTime();
} else {
missionCompleted=MissionCompleted();
}
if(initialWaitTime==0){ if(initialWaitTime==0){
Update(); Update();
} }
}; };
bool Scenario::MissionCompleted(){return false;}
void Scenario::Update(){}; void Scenario::Update(){};
Stage1::Stage1(){} void Scenario::Draw(){
if(objective.length()>0){
game.GetPGE()->DrawShadowStringDecal({4,24},"Objective:");
game.GetPGE()->DrawShadowStringDecal({6,36},objective);
game.GetPGE()->DrawShadowStringDecal({4,24},missionCompleted?"Objective Complete!":"Objective:",missionCompleted?GREEN:WHITE);
vf2d textSize=game.GetPGE()->GetTextSize(objective);
game.GetPGE()->DrawShadowStringDecal({6,36},objective,missionCompleted?GREEN:WHITE);
if(missionCompleted&&missionFinishWaitTime==0){
game.GetPGE()->FillRectDecal(vf2d{6,36}+vf2d{0,textSize.y/2-1},{textSize.x,3});
std::string continueText="< Press [Spacebar] to continue >";
vf2d textScale={2,3};
vf2d textSize=game.GetPGE()->GetTextSizeProp(continueText)*textScale;
game.GetPGE()->DrawShadowStringPropDecal(game.GetPGE()->GetScreenSize()/2-textSize/2+vf2d{0,72},continueText,{255,255,255,uint8_t(abs(sin(2*missionCompletedTimer))*255)},{0,0,0,uint8_t(abs(sin(2*missionCompletedTimer))*255)},textScale);
if(game.GetPGE()->GetKey(SPACE).bPressed){
}
}
}
Resources temp={0,0,0,0,0};
box.UpdateAndDraw({24,64},game.GetPGE(),temp,IMAGES,0,0);
}
void Scenario::SetCameraTarget(vf2d pos){
targetPos=pos;
camera.SetTarget(targetPos);
camera.Update(game.GetPGE()->GetElapsedTime());
game.SetWorldOffset(camera.GetViewPosition());
}
void Scenario::SetObjective(std::string objective){
this->objective=objective;
}
Stage1::Stage1(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags)
:Scenario(units,IMAGES,SOUNDS,objective,game,flags){}
void Stage1::Start(){ void Stage1::Start(){
game->unitMetersGreyedOut=true; flags.unitMetersGreyedOut=true;
game->playerInControl=false; flags.playerInControl=false;
nextLevel=LevelName::STAGE2;
}; };
void Scenario::DisplayBox(std::string text,bool scaryHoodedFigure){
box.Initialize(text,{24,64},"",scaryHoodedFigure?IMAGES[SPOOK_HOODED_FIGURE].get():IMAGES[HOODED_FIGURE].get(),{378,28},SOUNDS[Sound::VOICEOVER].get());
}
void Stage1::Update(){ void Stage1::Update(){
switch(state){ switch(state){
case 0:{ case 0:{
DisplayBox("Hello Hacker, thank you for taking on this request for me.");
if(box.bPressed){
state=1;
}
}break;
case 1:{
DisplayBox("It appears we have no time to waste, many sectors are already infected and the virus spread will just keep getting worse.");
if(box.bPressed){
state=2;
SOUNDS[Sound::PING]->PlayCentered();
for(int y=-1;y<=1;y++){
for(int x=-1;x<=1;x++){
vi2d basePos={320+x*96,320+y*96};
TileManager::visibleTiles[{basePos.x/96,basePos.y/96}]=30;
}
}
}
}break;
case 2:{
SetCameraTarget({320,320});
if(camera.ReachedTarget()){
state=3;
}
}break;
case 3:{
DisplayBox("Your mission is to take out all the RAM banks from the system, this will stop any further creation and spread of viruses.");
if(box.bPressed){
state=4;
}
}break;
case 4:{
SetCameraTarget({128,128});
if(camera.ReachedTarget()){
state=5;
}
}break;
case 5:{
DisplayBox("The yellow bar represent units' allocated Health memory. Take out the enemies' and make sure you always have at least 1 bit of it.");
if(box.bPressed){
state=6;
}
}break;
case 6:{
DisplayBox("Drag over your target unit and then select a target location via right-click.");
if(box.bPressed){
state=7;
}
}break;
case 7:{
SetObjective("Defeat the RAM bank");
DisplayBox("That should be all you need for now. I'll be back after my coffee break.");
if(box.bPressed){
state=8;
box.SetVisible(false);
flags.playerInControl=true;
}
}break;
case 8:{
}break; }break;
} }
}; };
Stage2::Stage2(){} bool Stage1::MissionCompleted(){
void Stage2::Start(){}; for(auto&u:units){
if(!u->IsFriendly()&&u->IsRAMBank()){
return false;
}
}
return true;
}
Stage2::Stage2(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags)
:Scenario(units,IMAGES,SOUNDS,objective,game,flags){}
void Stage2::Start(){
nextLevel=LevelName::STAGE3;
};
void Stage2::Update(){ void Stage2::Update(){
switch(state){ switch(state){
case 0:{ case 0:{
@ -45,8 +157,14 @@ void Stage2::Update(){
}break; }break;
} }
}; };
Stage3::Stage3(){} bool Stage2::MissionCompleted(){
void Stage3::Start(){}; return false;
}
Stage3::Stage3(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags)
:Scenario(units,IMAGES,SOUNDS,objective,game,flags){}
void Stage3::Start(){
nextLevel=LevelName::STAGE4;
};
void Stage3::Update(){ void Stage3::Update(){
switch(state){ switch(state){
case 0:{ case 0:{
@ -54,8 +172,14 @@ void Stage3::Update(){
}break; }break;
} }
}; };
Stage4::Stage4(){} bool Stage3::MissionCompleted(){
void Stage4::Start(){}; return false;
}
Stage4::Stage4(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags)
:Scenario(units,IMAGES,SOUNDS,objective,game,flags){}
void Stage4::Start(){
nextLevel=LevelName::STAGE5;
};
void Stage4::Update(){ void Stage4::Update(){
switch(state){ switch(state){
case 0:{ case 0:{
@ -63,8 +187,14 @@ void Stage4::Update(){
}break; }break;
} }
}; };
Stage5::Stage5(){} bool Stage4::MissionCompleted(){
void Stage5::Start(){}; return false;
}
Stage5::Stage5(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags)
:Scenario(units,IMAGES,SOUNDS,objective,game,flags){}
void Stage5::Start(){
nextLevel=LevelName::STAGE6;
};
void Stage5::Update(){ void Stage5::Update(){
switch(state){ switch(state){
case 0:{ case 0:{
@ -72,8 +202,14 @@ void Stage5::Update(){
}break; }break;
} }
}; };
Stage6::Stage6(){} bool Stage5::MissionCompleted(){
void Stage6::Start(){}; return false;
}
Stage6::Stage6(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags)
:Scenario(units,IMAGES,SOUNDS,objective,game,flags){}
void Stage6::Start(){
nextLevel=LevelName::STAGE7;
};
void Stage6::Update(){ void Stage6::Update(){
switch(state){ switch(state){
case 0:{ case 0:{
@ -81,8 +217,14 @@ void Stage6::Update(){
}break; }break;
} }
}; };
Stage7::Stage7(){} bool Stage6::MissionCompleted(){
void Stage7::Start(){}; return false;
}
Stage7::Stage7(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags)
:Scenario(units,IMAGES,SOUNDS,objective,game,flags){}
void Stage7::Start(){
nextLevel=LevelName::STAGE8;
};
void Stage7::Update(){ void Stage7::Update(){
switch(state){ switch(state){
case 0:{ case 0:{
@ -90,8 +232,14 @@ void Stage7::Update(){
}break; }break;
} }
}; };
Stage8::Stage8(){} bool Stage7::MissionCompleted(){
void Stage8::Start(){}; return false;
}
Stage8::Stage8(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags)
:Scenario(units,IMAGES,SOUNDS,objective,game,flags){}
void Stage8::Start(){
nextLevel=LevelName::FINISH;
};
void Stage8::Update(){ void Stage8::Update(){
switch(state){ switch(state){
case 0:{ case 0:{
@ -99,3 +247,6 @@ void Stage8::Update(){
}break; }break;
} }
}; };
bool Stage8::MissionCompleted(){
return false;
}

@ -1,76 +1,105 @@
#pragma once #pragma once
#include "olcUTIL_Camera2D.h" #include "olcUTIL_Camera2D.h"
#include "Textbox.h" #include "Textbox.h"
#include "Unit.h"
#include "olcPGEX_AudioSource.h"
#include "olcPGEX_TransformedView.h"
#include "GameFlags.h"
#include "Level.h"
class Scenario{ class Scenario{
public: public:
Scenario(); Scenario(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags);
virtual~Scenario(); virtual~Scenario();
void _Start(); void _Start();
void Draw();
virtual void Start(); virtual void Start();
void _Update(); void _Update();
bool transitionToNextLevel=false;
LevelName nextLevel=LevelName::STAGE1;
protected: protected:
void DisplayBox(std::string text,bool scaryHoodedFigure=false);
void SetCameraTarget(vf2d pos);
void SetObjective(std::string objective);
virtual bool MissionCompleted();
virtual void Update(); virtual void Update();
int state=0; int state=0;
utils::Camera2D camera; utils::Camera2D camera;
vf2d targetPos; vf2d targetPos;
Textbox box; Textbox box;
float initialWaitTime=3; float initialWaitTime=3;
bool missionCompleted=false;
float missionFinishWaitTime=3;
float missionCompletedTimer=0;
std::vector<std::shared_ptr<Unit>>&units;
std::vector<std::unique_ptr<Renderable>>&IMAGES;
std::vector<std::unique_ptr<Audio>>&SOUNDS;
GameFlags&flags;
std::string&objective;
TileTransformedView&game;
}; };
class Stage1:public Scenario{ class Stage1:public Scenario{
public: public:
Stage1(); Stage1(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags);
protected: protected:
void Start(); void Start();
void Update(); void Update();
bool MissionCompleted();
}; };
class Stage2:public Scenario{ class Stage2:public Scenario{
public: public:
Stage2(); Stage2(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags);
protected: protected:
void Start(); void Start();
void Update(); void Update();
bool MissionCompleted();
}; };
class Stage3:public Scenario{ class Stage3:public Scenario{
public: public:
Stage3(); Stage3(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags);
protected: protected:
void Start(); void Start();
void Update(); void Update();
bool MissionCompleted();
}; };
class Stage4:public Scenario{ class Stage4:public Scenario{
public: public:
Stage4(); Stage4(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags);
protected: protected:
void Start(); void Start();
void Update(); void Update();
bool MissionCompleted();
}; };
class Stage5:public Scenario{ class Stage5:public Scenario{
public: public:
Stage5(); Stage5(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags);
protected: protected:
void Start(); void Start();
void Update(); void Update();
bool MissionCompleted();
}; };
class Stage6:public Scenario{ class Stage6:public Scenario{
public: public:
Stage6(); Stage6(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags);
protected: protected:
void Start(); void Start();
void Update(); void Update();
bool MissionCompleted();
}; };
class Stage7:public Scenario{ class Stage7:public Scenario{
public: public:
Stage7(); Stage7(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags);
protected: protected:
void Start(); void Start();
void Update(); void Update();
bool MissionCompleted();
}; };
class Stage8:public Scenario{ class Stage8:public Scenario{
public: public:
Stage8(); Stage8(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags);
protected: protected:
void Start(); void Start();
void Update(); void Update();
bool MissionCompleted();
}; };

@ -1,6 +1,7 @@
#pragma once #pragma once
enum class Sound:int{ namespace Sound{
enum Sound:int{
HUM, HUM,
GRAVITY, GRAVITY,
COSMOS, COSMOS,
@ -9,3 +10,4 @@ enum class Sound:int{
VOICEOVER, VOICEOVER,
PING, PING,
}; };
}

@ -2,7 +2,8 @@
#include "olcPixelGameEngine.h" #include "olcPixelGameEngine.h"
#include "olcPGEX_TransformedView.h" #include "olcPGEX_TransformedView.h"
#include "Resources.h" #include "Resources.h"
#include "Unit.h" #include "olcPGEX_AudioSource.h"
#include "Memory.h"
class Textbox{ class Textbox{
std::string headerText=""; //If a textbox has a header, it displays at the top in a special color. std::string headerText=""; //If a textbox has a header, it displays at the top in a special color.

@ -138,7 +138,7 @@ void MemoryAllocator::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&othe
} }
void MemoryAllocator::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::unique_ptr<Unit>>&queuedUnits){ void MemoryAllocator::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits){
if(IsBuilding()){ if(IsBuilding()){
SetTargetLocation(CONSTANT::UNSELECTED); SetTargetLocation(CONSTANT::UNSELECTED);
target.reset(); target.reset();
@ -198,7 +198,7 @@ void RAMBank::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
} }
void RAMBank::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::unique_ptr<Unit>>&queuedUnits){ void RAMBank::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits){
pge->SetDrawTarget(img.Sprite()); pge->SetDrawTarget(img.Sprite());
for(int y=0;y<img.Sprite()->height;y++){ for(int y=0;y<img.Sprite()->height;y++){
for(int x=0;x<img.Sprite()->width;x++){ for(int x=0;x<img.Sprite()->width;x++){
@ -295,7 +295,7 @@ _Platform::_Platform(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Re
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::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::unique_ptr<Unit>>&queuedUnits){ void _Platform::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits){
if(IsBuilding()){ if(IsBuilding()){
SetTargetLocation(CONSTANT::UNSELECTED); SetTargetLocation(CONSTANT::UNSELECTED);
target.reset(); target.reset();
@ -642,7 +642,7 @@ void Unit::_RunAI(PixelGameEngine*pge){
RunAI(pge); RunAI(pge);
} }
void Unit::_Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,Resources&player_resources,Resources&enemy_resources,std::vector<std::unique_ptr<Unit>>&queuedUnits,std::array<float,5>&resourceGainTimer,std::vector<ResourceGainIcon>&resourceGainIcons,std::vector<std::unique_ptr<Renderable>>&IMAGES){ void Unit::_Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,Resources&player_resources,Resources&enemy_resources,std::vector<std::shared_ptr<Unit>>&queuedUnits,std::array<float,5>&resourceGainTimer,std::vector<ResourceGainIcon>&resourceGainIcons,std::vector<std::unique_ptr<Renderable>>&IMAGES){
if(!target.expired()){ if(!target.expired()){
auto ptrTarget=target.lock(); auto ptrTarget=target.lock();
if(!InRange(ptrTarget)&&CanMove()){ if(!InRange(ptrTarget)&&CanMove()){
@ -827,7 +827,7 @@ void Unit::AttemptAttack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>unit,std
} }
} }
void Unit::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::unique_ptr<Unit>>&queuedUnits){} void Unit::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits){}
void Unit::Attacked(std::weak_ptr<Unit>attacker){} void Unit::Attacked(std::weak_ptr<Unit>attacker){}
@ -944,7 +944,7 @@ bool Unit::IsAllocator(){
return isAllocator&&attachedPoint.expired()&&buildTime<=0; return isAllocator&&attachedPoint.expired()&&buildTime<=0;
} }
void Unit::SetBuildUnit(float buildTime,std::unique_ptr<Unit>finalUnit){ void Unit::SetBuildUnit(float buildTime,std::shared_ptr<Unit>finalUnit){
this->buildTime=buildTime; this->buildTime=buildTime;
this->buildTransformUnit=std::move(finalUnit); this->buildTransformUnit=std::move(finalUnit);
} }

@ -8,12 +8,11 @@
#include "olcPGEX_AudioSource.h" #include "olcPGEX_AudioSource.h"
#include "DebuffIcon.h" #include "DebuffIcon.h"
#include "CollectionPoint.h" #include "CollectionPoint.h"
#include "MemoryType.h"
#include "Resources.h" #include "Resources.h"
#include "Textbox.h"
#include "Memory.h"
#include "olcPGEX_QuickGUI.h" #include "olcPGEX_QuickGUI.h"
class Textbox;
enum class UnitType{ enum class UnitType{
LeftShifter, LeftShifter,
RightShifter, RightShifter,
@ -33,11 +32,6 @@ struct Marker{
size_t size; size_t size;
}; };
struct Memory{
MemoryType type;
int size;
};
struct Unit{ struct Unit{
public: public:
Unit(PixelGameEngine*pge,std::vector<Memory>memory,vf2d pos,float radius,Renderable&img,Pixel targetLineColor,Pixel attackingLineColor,bool friendly=false,bool moveable=true,bool friendlyInteractable=false,bool enemyInteractable=true); Unit(PixelGameEngine*pge,std::vector<Memory>memory,vf2d pos,float radius,Renderable&img,Pixel targetLineColor,Pixel attackingLineColor,bool friendly=false,bool moveable=true,bool friendlyInteractable=false,bool enemyInteractable=true);
@ -51,7 +45,7 @@ public:
std::vector<bool>memory; std::vector<bool>memory;
std::vector<bool>ghostMemory; std::vector<bool>ghostMemory;
std::vector<bool>savedMemory; std::vector<bool>savedMemory;
virtual void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::unique_ptr<Unit>>&queuedUnits); virtual void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits);
virtual void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)=0; virtual void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)=0;
virtual void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES); virtual void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES);
virtual void DrawHud(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES); virtual void DrawHud(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES);
@ -72,7 +66,7 @@ public:
bool GhostInFogOfWar(); bool GhostInFogOfWar();
void HideGhost(); void HideGhost();
vf2d GetGhostPos(); vf2d GetGhostPos();
void _Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,Resources&player_resources,Resources&enemy_resources,std::vector<std::unique_ptr<Unit>>&queuedUnits,std::array<float,5>&resourceGainTimer,std::vector<ResourceGainIcon>&resourceGainIcons,std::vector<std::unique_ptr<Renderable>>&IMAGES); void _Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,Resources&player_resources,Resources&enemy_resources,std::vector<std::shared_ptr<Unit>>&queuedUnits,std::array<float,5>&resourceGainTimer,std::vector<ResourceGainIcon>&resourceGainIcons,std::vector<std::unique_ptr<Renderable>>&IMAGES);
bool IsMoveable(); bool IsMoveable();
void DrawRangeIndicator(PixelGameEngine*pge,TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES); void DrawRangeIndicator(PixelGameEngine*pge,TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES);
bool CanInteractWithEnemies(); bool CanInteractWithEnemies();
@ -91,7 +85,7 @@ public:
virtual void UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered,int totalUsedMemory,int availableMemory); 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::vector<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::vector<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::shared_ptr<Unit>finalUnit);
bool IsBuilding(); bool IsBuilding();
void SetGuardTime(float time); void SetGuardTime(float time);
bool IsGuarded(); bool IsGuarded();
@ -135,7 +129,7 @@ protected:
bool autoAcquireFriendlyTarget=true; bool autoAcquireFriendlyTarget=true;
bool isAllocator=false; bool isAllocator=false;
bool isPlatform=false; bool isPlatform=false;
std::unique_ptr<Unit>buildTransformUnit; std::shared_ptr<Unit>buildTransformUnit;
float buildTime=0; float buildTime=0;
bool isRAMBank=false; bool isRAMBank=false;
private: private:
@ -207,7 +201,7 @@ struct Corrupter:Unit{
struct MemoryAllocator:Unit{ struct MemoryAllocator:Unit{
MemoryAllocator(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); MemoryAllocator(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&units)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&units)override;
void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::unique_ptr<Unit>>&queuedUnits)override; void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits)override;
void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override; void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override;
static std::vector<Memory> resourceCost; static std::vector<Memory> resourceCost;
static std::string unitName; static std::string unitName;
@ -224,7 +218,7 @@ struct RAMBank:Unit{
QuickGUI::Manager allocatorManager; QuickGUI::Manager allocatorManager;
QuickGUI::ImageButton*allocatorButton; QuickGUI::ImageButton*allocatorButton;
RAMBank(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly=false); RAMBank(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly=false);
void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::unique_ptr<Unit>>&queuedUnits)override; void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits)override;
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 Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override; void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override;
void OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS)override; void OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS)override;
@ -239,7 +233,7 @@ struct RAMBank:Unit{
struct _Platform:Unit{ struct _Platform:Unit{
_Platform(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); _Platform(PixelGameEngine*pge,vf2d pos,std::vector<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::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::unique_ptr<Unit>>&queuedUnits)override; void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits)override;
void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override; void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override;
static std::vector<Memory> resourceCost; static std::vector<Memory> resourceCost;
static std::string unitName; static std::string unitName;

@ -271,19 +271,19 @@ void VirusAttack::InitializeGUIs(){
} }
void VirusAttack::InitializeScenarios(){ void VirusAttack::InitializeScenarios(){
SCENARIOS.emplace_back(std::make_unique<Stage1>()); SCENARIOS.emplace_back(std::make_unique<Stage1>(units,IMAGES,SOUNDS,objective,gametv,flags));
SCENARIOS.emplace_back(std::make_unique<Stage2>()); SCENARIOS.emplace_back(std::make_unique<Stage2>(units,IMAGES,SOUNDS,objective,gametv,flags));
SCENARIOS.emplace_back(std::make_unique<Stage3>()); SCENARIOS.emplace_back(std::make_unique<Stage3>(units,IMAGES,SOUNDS,objective,gametv,flags));
SCENARIOS.emplace_back(std::make_unique<Stage4>()); SCENARIOS.emplace_back(std::make_unique<Stage4>(units,IMAGES,SOUNDS,objective,gametv,flags));
SCENARIOS.emplace_back(std::make_unique<Stage5>()); SCENARIOS.emplace_back(std::make_unique<Stage5>(units,IMAGES,SOUNDS,objective,gametv,flags));
SCENARIOS.emplace_back(std::make_unique<Stage6>()); SCENARIOS.emplace_back(std::make_unique<Stage6>(units,IMAGES,SOUNDS,objective,gametv,flags));
SCENARIOS.emplace_back(std::make_unique<Stage7>()); SCENARIOS.emplace_back(std::make_unique<Stage7>(units,IMAGES,SOUNDS,objective,gametv,flags));
SCENARIOS.emplace_back(std::make_unique<Stage8>()); SCENARIOS.emplace_back(std::make_unique<Stage8>(units,IMAGES,SOUNDS,objective,gametv,flags));
} }
void VirusAttack::InitializeSounds(){ void VirusAttack::InitializeSounds(){
int soundIndex=0; int soundIndex=0;
auto LoadSound=[&](Sound sound,std::string soundFilename){ auto LoadSound=[&](Sound::Sound sound,std::string soundFilename){
SOUNDS.emplace_back(std::make_unique<Audio>()); SOUNDS.emplace_back(std::make_unique<Audio>());
SOUNDS[int(sound)]->AL=&AL; SOUNDS[int(sound)]->AL=&AL;
SOUNDS[int(sound)]->LoadAudioSample(soundIndex,std::string("./assets/"+soundFilename).c_str()); SOUNDS[int(sound)]->LoadAudioSample(soundIndex,std::string("./assets/"+soundFilename).c_str());
@ -304,7 +304,7 @@ bool VirusAttack::UnitCreationClickHandled(){
if(Button->bPressed){ \ if(Button->bPressed){ \
for(auto&u:units){ \ for(auto&u:units){ \
if(u->IsSelected()&&u->Validator()&&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::shared_ptr<UnitClass>buildUnit=std::make_shared<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(); \ CalculateUsedMemory(); \
@ -327,8 +327,8 @@ bool VirusAttack::UnitCreationClickHandled(){
return false; return false;
} }
#define EnableAndHoverCheck(UnitClass,Button,box,limited) \ #define EnableAndHoverCheck(UnitClass,Button,box,limited) \
Button->Enable(CanAfford(player_resources,UnitClass::resourceCost)&&(!limited||limited&&!limitedBuildOptions)); \ Button->Enable(CanAfford(player_resources,UnitClass::resourceCost)&&(!limited||limited&&!flags.limitedBuildOptions)); \
if(limited&&!limitedBuildOptions){Button->bVisible=false;} \ if(limited&&!flags.limitedBuildOptions){Button->bVisible=false;} \
if(Button->bHover){ \ if(Button->bHover){ \
box.Initialize(UnitClass::unitDescription, GetMousePos(), UnitClass::unitName,nullptr,{120,36},nullptr,UnitClass::resourceCost); \ box.Initialize(UnitClass::unitDescription, GetMousePos(), UnitClass::unitName,nullptr,{120,36},nullptr,UnitClass::resourceCost); \
hovering=true; \ hovering=true; \
@ -777,13 +777,20 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
#pragma endregion #pragma endregion
#pragma region GAMEPLAY #pragma region GAMEPLAY
case GameState::GAMEPLAY:{ case GameState::GAMEPLAY:{
if(playerInControl){ if(flags.playerInControl){
HandleDraggingSelection(); HandleDraggingSelection();
HandleRightClickMove(); HandleRightClickMove();
HandlePanAndZoom(fElapsedTime); HandlePanAndZoom(fElapsedTime);
HandleMinimapClick(); HandleMinimapClick();
} }
SCENARIOS[currentScenario]->_Update(); SCENARIOS[currentScenario]->_Update();
if(SCENARIOS[currentScenario]->transitionToNextLevel){
if(SCENARIOS[currentScenario]->nextLevel!=FINISH){
levelToLoad=SCENARIOS[currentScenario]->nextLevel;
}else{
state=GameState::COMPLETED;
}
}
restartManager.Update(this); restartManager.Update(this);
HandleRestartButton(fElapsedTime); HandleRestartButton(fElapsedTime);
PerformLevelTransition(fElapsedTime); PerformLevelTransition(fElapsedTime);
@ -878,7 +885,7 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
std::erase_if(resourceGainIcons,[](ResourceGainIcon&icon){return icon.lifetime<=0;}); std::erase_if(resourceGainIcons,[](ResourceGainIcon&icon){return icon.lifetime<=0;});
for(auto&u:units){ for(auto&u:units){
u->_DrawHud(gametv,IMAGES,unitMetersGreyedOut); u->_DrawHud(gametv,IMAGES,flags.unitMetersGreyedOut);
} }
DrawSelectionRectangle(); DrawSelectionRectangle();
@ -890,7 +897,7 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
DrawSystemMemoryBar(fElapsedTime); DrawSystemMemoryBar(fElapsedTime);
DrawResourceBar(fElapsedTime); DrawResourceBar(fElapsedTime);
if(guideEnabled){ if(flags.guideEnabled){
DrawDecal({float(ScreenWidth()-74-IMAGES[GUIDE]->Sprite()->width*0.75),float(ScreenHeight()+6-IMAGES[GUIDE]->Sprite()->height*0.75)},IMAGES[GUIDE]->Decal(),{0.75,0.75}); DrawDecal({float(ScreenWidth()-74-IMAGES[GUIDE]->Sprite()->width*0.75),float(ScreenHeight()+6-IMAGES[GUIDE]->Sprite()->height*0.75)},IMAGES[GUIDE]->Decal(),{0.75,0.75});
} }
DrawMinimap(); DrawMinimap();
@ -909,6 +916,8 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
float dist2=geom2d::line<float>(u2->GetGhostPos(),GetWorldMousePos()).length(); float dist2=geom2d::line<float>(u2->GetGhostPos(),GetWorldMousePos()).length();
return dist1>dist2;}); return dist1>dist2;});
SCENARIOS[currentScenario]->Draw();
for(auto&u:units){ for(auto&u:units){
if(u->IsGuarded()){ if(u->IsGuarded()){
bool changeOccured=false; bool changeOccured=false;

@ -16,6 +16,7 @@
#include "Resources.h" #include "Resources.h"
#include "Textbox.h" #include "Textbox.h"
#include "Level.h" #include "Level.h"
#include "GameFlags.h"
#include "GameState.h" #include "GameState.h"
struct Letter{ struct Letter{
@ -32,7 +33,7 @@ public:
#endif #endif
vi2d WORLD_SIZE={64,64}; vi2d WORLD_SIZE={64,64};
std::vector<std::unique_ptr<Unit>>queuedUnits; std::vector<std::shared_ptr<Unit>>queuedUnits;
std::vector<std::shared_ptr<Unit>>units; std::vector<std::shared_ptr<Unit>>units;
std::vector<std::shared_ptr<CollectionPoint>>collectionPoints; std::vector<std::shared_ptr<CollectionPoint>>collectionPoints;
std::vector<std::unique_ptr<DeathAnimation>>deathAnimations; std::vector<std::unique_ptr<DeathAnimation>>deathAnimations;
@ -87,12 +88,8 @@ public:
float memoryDisplayDelay=0; float memoryDisplayDelay=0;
bool memoryIncreased=true; bool memoryIncreased=true;
float memoryChangeTimer=2; float memoryChangeTimer=2;
bool unitMetersGreyedOut=false; //If true, all but health meters show up as dark grey.
bool playerInControl=true;
float levelForegroundFade=0; float levelForegroundFade=0;
LevelName levelToLoad; LevelName levelToLoad;
bool limitedBuildOptions=false;
bool guideEnabled=true;
bool reloadLevel=false; bool reloadLevel=false;
bool restartButtonHeldDown=false; bool restartButtonHeldDown=false;
float restartButtonHoldTime=0; float restartButtonHoldTime=0;
@ -110,6 +107,7 @@ public:
float textOrientationY=0; float textOrientationY=0;
float textOrientationX=0; float textOrientationX=0;
int currentScenario=0; int currentScenario=0;
GameFlags flags;
std::string objective=""; std::string objective="";

@ -151,9 +151,11 @@
<ClInclude Include="Constant.h" /> <ClInclude Include="Constant.h" />
<ClInclude Include="DeathAnimation.h" /> <ClInclude Include="DeathAnimation.h" />
<ClInclude Include="DebuffIcon.h" /> <ClInclude Include="DebuffIcon.h" />
<ClInclude Include="GameFlags.h" />
<ClInclude Include="GameState.h" /> <ClInclude Include="GameState.h" />
<ClInclude Include="Image.h" /> <ClInclude Include="Image.h" />
<ClInclude Include="Level.h" /> <ClInclude Include="Level.h" />
<ClInclude Include="Memory.h" />
<ClInclude Include="MemoryType.h" /> <ClInclude Include="MemoryType.h" />
<ClInclude Include="olcPGEX_AudioListener.h" /> <ClInclude Include="olcPGEX_AudioListener.h" />
<ClInclude Include="olcPGEX_AudioSource.h" /> <ClInclude Include="olcPGEX_AudioSource.h" />

@ -102,6 +102,12 @@
<ClInclude Include="GameState.h"> <ClInclude Include="GameState.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Memory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GameFlags.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="VirusAttack.cpp"> <ClCompile Include="VirusAttack.cpp">

Loading…
Cancel
Save