Compare commits

...

2 Commits

  1. 2
      olcCodeJam2023Entry/CollectionPoint.h
  2. 1
      olcCodeJam2023Entry/Level.h
  3. 442
      olcCodeJam2023Entry/Scenario.cpp
  4. 50
      olcCodeJam2023Entry/Scenario.h
  5. 2
      olcCodeJam2023Entry/Sound.h
  6. 4
      olcCodeJam2023Entry/Textbox.cpp
  7. 8
      olcCodeJam2023Entry/Textbox.h
  8. 66
      olcCodeJam2023Entry/Unit.cpp
  9. 63
      olcCodeJam2023Entry/Unit.h
  10. 145
      olcCodeJam2023Entry/VirusAttack.cpp
  11. 7
      olcCodeJam2023Entry/VirusAttack.h
  12. 2
      olcCodeJam2023Entry/emscripten_build.ps1
  13. 8
      olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj
  14. 2
      olcCodeJam2023Entry/olcPGEX_AudioSource.h
  15. BIN
      olcCodeJam2023Entry/pge.data
  16. 1297
      olcCodeJam2023Entry/pge.html
  17. 11133
      olcCodeJam2023Entry/pge.js
  18. BIN
      olcCodeJam2023Entry/pge.wasm

@ -2,7 +2,7 @@
#include "olcPixelGameEngine.h" #include "olcPixelGameEngine.h"
#include "MemoryType.h" #include "MemoryType.h"
class Unit; struct Unit;
class CollectionPoint{ class CollectionPoint{
public: public:

@ -40,7 +40,6 @@ struct Level{
std::vector<UnitData>unitPlacement; std::vector<UnitData>unitPlacement;
std::vector<CPData>cpPlacement; std::vector<CPData>cpPlacement;
Sound bgm=Sound::COSMOS; Sound bgm=Sound::COSMOS;
Scenario*scenario;
vf2d cameraStart={96,96}; vf2d cameraStart={96,96};
vf2d worldZoom={1,1}; vf2d worldZoom={1,1};
Pixel levelColor=DARK_GREEN; Pixel levelColor=DARK_GREEN;

@ -1,442 +0,0 @@
#include "Scenario.h"
#include "TileManager.h"
Scenario::Scenario(VirusAttack*game)
:game(game){
}
void Scenario::Start(){}
void Scenario::_Update(){
initialWaitTimer=std::max(0.f,initialWaitTimer-game->GetElapsedTime());
waitToContinueTimer=std::max(0.f,waitToContinueTimer-game->GetElapsedTime());
if(missionCompleted){
missionCompletedTimer+=game->GetElapsedTime();
if(game->GetKey(SPACE).bPressed){
NextLevel();
}
}
if(!missionCompleted&&MissionCompleted()){
missionCompleted=true;
waitToContinueTimer=3;
}
Update();
}
void Scenario::_Draw(){
if(game->objective.length()>0){
game->DrawShadowStringDecal({4,24},missionCompleted?"Objective Complete!":"Objective:",missionCompleted?GREEN:WHITE);
vf2d textSize=game->GetTextSize(game->objective);
game->DrawShadowStringDecal({6,36},game->objective,missionCompleted?GREEN:WHITE);
if(missionCompleted&&initialWaitTimer==0){
game->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->GetTextSizeProp(continueText)*textScale;
game->DrawShadowStringPropDecal(game->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);
}
}
Draw();
}
void Scenario::DisplayDialog(std::string dialogText,bool spooky){
dialog.Initialize(dialogText,{24,64},"",spooky?game->IMAGES[SPOOK_HOODED_FIGURE].get():game->IMAGES[HOODED_FIGURE].get(),{378,28},game->SOUNDS[Sound::VOICEOVER].get());
}
void Scenario::SetObjective(std::string objective){
game->objective=objective;
}
void Scenario::SetupCameraTarget(vf2d pos){
cameraTargetPos=pos;
camera.SetTarget(cameraTargetPos);
}
void Scenario::MoveCamera(){
game->game.SetWorldOffset(camera.GetViewPosition());
camera.Update(game->GetElapsedTime());
}
void Scenario::NextLevel(){}
Stage1::Stage1(VirusAttack*game)
:Scenario(game){}
void Stage1::Start(){
state=0;
missionCompleted=false;
dialog.SetVisible(false);
game->unitMetersGreyedOut=true;
game->playerInControl=false;
game->guideEnabled=false;
camera=utils::Camera2D(game->GetScreenSize(),game->game.GetWorldOffset());
camera.SetLazyFollowRate(1);
camera.SetMode(utils::Camera2D::Mode::LazyFollow);
}
void Stage1::Update(){
switch(state){
case 0:{
DisplayDialog("Hello Hacker, thank you for taking on this request for me.");
if(dialog.bPressed){
dialog.SetVisible(false);
state=1;
}
}break;
case 1:{
DisplayDialog("It appears we have no time to waste, most sectors are already infected and it will just keep getting worse over time.");
if(dialog.bPressed){
dialog.SetVisible(false);
state=2;
}
}break;
case 2:{
game->SOUNDS[Sound::PING]->PlayCentered();
SetupCameraTarget({320,320});
state=3;
}break;
case 3:{
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;
}
}
MoveCamera();
if(camera.ReachedTarget()){
state=4;
}
}break;
case 4:{
DisplayDialog("Your mission is to take out all the RAM banks from the system, this will stop any further creation and spread of viruses.");
if(dialog.bPressed){
dialog.SetVisible(false);
SetupCameraTarget({128,128});
state=5;
}
}break;
case 5:{
MoveCamera();
if(camera.ReachedTarget()){
state=6;
}
}break;
case 6:{
DisplayDialog("The yellow bars represent a unit's Health memory allocation. Eliminate it from enemies, and make sure you have at least 1 bit of it.");
if(dialog.bPressed){
state=7;
}
}break;
case 7:{
DisplayDialog("Drag over your target unit and then select a target location via right-click.");
if(dialog.bPressed){
state=8;
}
}break;
case 8:{
DisplayDialog("That should be all you need for now. I'll be back after my coffee break.");
SetObjective("Defeat the RAM bank");
if(dialog.bPressed){
dialog.SetVisible(false);
game->playerInControl=true;
state=9;
}
}break;
}
}
bool Stage1::MissionCompleted(){
for(auto&u:game->units){
if(!u->IsFriendly()&&u->IsRAMBank()){
return false;
}
}
return true;
}
void Stage1::Draw(){
dialog.UpdateAndDraw({24,64},game,game->player_resources,game->IMAGES,game->GetTotalUsedMemory(),game->currentLevel->availableMemory);
}
void Stage1::NextLevel(){
game->levelToLoad=STAGE2;
}
Stage2::Stage2(VirusAttack*game)
:Scenario(game){}
void Stage2::Start(){
state=0;
missionCompleted=false;
dialog.SetVisible(false);
game->unitMetersGreyedOut=true;
game->limitedBuildOptions=true;
game->guideEnabled=false;
game->playerInControl=false;
camera=utils::Camera2D(game->GetScreenSize(),game->game.GetWorldOffset());
camera.SetLazyFollowRate(1);
camera.SetMode(utils::Camera2D::Mode::LazyFollow);
}
void Stage2::Update(){
switch(state){
case 0:{
DisplayDialog("I am the test dialog.");
if(dialog.bPressed){
dialog.SetVisible(false);
state=1;
}
}break;
}
}
bool Stage2::MissionCompleted(){
for(auto&u:game->units){
if(!u->IsFriendly()&&u->IsRAMBank()){
return false;
}
}
return true;
}
void Stage2::Draw(){
dialog.UpdateAndDraw({24,64},game,game->player_resources,game->IMAGES,game->GetTotalUsedMemory(),game->currentLevel->availableMemory);
}
void Stage2::NextLevel(){
game->levelToLoad=STAGE3;
}
Stage3::Stage3(VirusAttack*game)
:Scenario(game){}
void Stage3::Start(){
state=0;
missionCompleted=false;
dialog.SetVisible(false);
game->unitMetersGreyedOut=false;
game->limitedBuildOptions=true;
game->guideEnabled=false;
game->playerInControl=false;
camera=utils::Camera2D(game->GetScreenSize(),game->game.GetWorldOffset());
camera.SetLazyFollowRate(1);
camera.SetMode(utils::Camera2D::Mode::LazyFollow);
}
void Stage3::Update(){
switch(state){
case 0:{
DisplayDialog("I am the test dialog.");
if(dialog.bPressed){
dialog.SetVisible(false);
state=1;
}
}break;
}
}
bool Stage3::MissionCompleted(){
for(auto&u:game->units){
if(!u->IsFriendly()&&u->IsRAMBank()){
return false;
}
}
return true;
}
void Stage3::Draw(){
dialog.UpdateAndDraw({24,64},game,game->player_resources,game->IMAGES,game->GetTotalUsedMemory(),game->currentLevel->availableMemory);
}
void Stage3::NextLevel(){
game->levelToLoad=STAGE4;
}
Stage4::Stage4(VirusAttack*game)
:Scenario(game){}
void Stage4::Start(){
state=0;
missionCompleted=false;
dialog.SetVisible(false);
game->unitMetersGreyedOut=false;
game->limitedBuildOptions=false;
game->guideEnabled=true;
game->playerInControl=false;
camera=utils::Camera2D(game->GetScreenSize(),game->game.GetWorldOffset());
camera.SetLazyFollowRate(1);
camera.SetMode(utils::Camera2D::Mode::LazyFollow);
}
void Stage4::Update(){
switch(state){
case 0:{
DisplayDialog("I am the test dialog.");
if(dialog.bPressed){
dialog.SetVisible(false);
state=1;
}
}break;
}
}
bool Stage4::MissionCompleted(){
for(auto&u:game->units){
if(!u->IsFriendly()&&u->IsRAMBank()){
return false;
}
}
return true;
}
void Stage4::Draw(){
dialog.UpdateAndDraw({24,64},game,game->player_resources,game->IMAGES,game->GetTotalUsedMemory(),game->currentLevel->availableMemory);
}
void Stage4::NextLevel(){
game->levelToLoad=STAGE5;
}
Stage5::Stage5(VirusAttack*game)
:Scenario(game){}
void Stage5::Start(){
state=0;
missionCompleted=false;
dialog.SetVisible(false);
game->unitMetersGreyedOut=false;
game->limitedBuildOptions=false;
game->guideEnabled=true;
game->playerInControl=true;
camera=utils::Camera2D(game->GetScreenSize(),game->game.GetWorldOffset());
camera.SetLazyFollowRate(1);
camera.SetMode(utils::Camera2D::Mode::LazyFollow);
}
void Stage5::Update(){
switch(state){
case 0:{
SetObjective("Defeat all enemy units.");
state=1;
}break;
}
}
bool Stage5::MissionCompleted(){
for(auto&u:game->units){
if(!u->IsFriendly()&&u->IsRAMBank()){
return false;
}
}
return true;
}
void Stage5::Draw(){
dialog.UpdateAndDraw({24,64},game,game->player_resources,game->IMAGES,game->GetTotalUsedMemory(),game->currentLevel->availableMemory);
}
void Stage5::NextLevel(){
game->levelToLoad=STAGE6;
}
Stage6::Stage6(VirusAttack*game)
:Scenario(game){}
void Stage6::Start(){
state=0;
missionCompleted=false;
dialog.SetVisible(false);
game->unitMetersGreyedOut=false;
game->limitedBuildOptions=false;
game->guideEnabled=true;
game->playerInControl=true;
camera=utils::Camera2D(game->GetScreenSize(),game->game.GetWorldOffset());
camera.SetLazyFollowRate(1);
camera.SetMode(utils::Camera2D::Mode::LazyFollow);
}
void Stage6::Update(){
switch(state){
case 0:{
SetObjective("Defeat all enemy units.");
state=1;
}break;
}
}
bool Stage6::MissionCompleted(){
for(auto&u:game->units){
if(!u->IsFriendly()&&u->IsRAMBank()){
return false;
}
}
return true;
}
void Stage6::Draw(){
dialog.UpdateAndDraw({24,64},game,game->player_resources,game->IMAGES,game->GetTotalUsedMemory(),game->currentLevel->availableMemory);
}
void Stage6::NextLevel(){
game->levelToLoad=STAGE7;
}
Stage7::Stage7(VirusAttack*game)
:Scenario(game){}
void Stage7::Start(){
state=0;
missionCompleted=false;
dialog.SetVisible(false);
game->unitMetersGreyedOut=false;
game->limitedBuildOptions=false;
game->guideEnabled=true;
game->playerInControl=true;
camera=utils::Camera2D(game->GetScreenSize(),game->game.GetWorldOffset());
camera.SetLazyFollowRate(1);
camera.SetMode(utils::Camera2D::Mode::LazyFollow);
}
void Stage7::Update(){
switch(state){
case 0:{
SetObjective("Defeat all enemy units.");
state=1;
}break;
}
}
bool Stage7::MissionCompleted(){
for(auto&u:game->units){
if(!u->IsFriendly()&&u->IsRAMBank()){
return false;
}
}
return true;
}
void Stage7::Draw(){
dialog.UpdateAndDraw({24,64},game,game->player_resources,game->IMAGES,game->GetTotalUsedMemory(),game->currentLevel->availableMemory);
}
void Stage7::NextLevel(){
game->levelToLoad=STAGE8;
}
Stage8::Stage8(VirusAttack*game)
:Scenario(game){}
void Stage8::Start(){
state=0;
missionCompleted=false;
dialog.SetVisible(false);
game->unitMetersGreyedOut=false;
game->limitedBuildOptions=false;
game->guideEnabled=true;
game->playerInControl=true;
camera=utils::Camera2D(game->GetScreenSize(),game->game.GetWorldOffset());
camera.SetLazyFollowRate(1);
camera.SetMode(utils::Camera2D::Mode::LazyFollow);
}
void Stage8::Update(){
switch(state){
case 0:{
SetObjective("Defeat all enemy units.");
state=1;
}break;
}
}
bool Stage8::MissionCompleted(){
for(auto&u:game->units){
if(!u->IsFriendly()&&u->IsRAMBank()){
return false;
}
}
return true;
}
void Stage8::Draw(){
dialog.UpdateAndDraw({24,64},game,game->player_resources,game->IMAGES,game->GetTotalUsedMemory(),game->currentLevel->availableMemory);
}
void Stage8::NextLevel(){
game->state=GameState::COMPLETED;
}

@ -1,50 +0,0 @@
#pragma once
#include "VirusAttack.h"
#include "olcUTIL_Camera2D.h"
class Scenario{
public:
Scenario(VirusAttack*game);
virtual void Start();
void _Update();
virtual void Update()=0;
void _Draw();
virtual void Draw()=0;
void DisplayDialog(std::string dialogText,bool spooky=false);
void SetObjective(std::string objective);
void SetupCameraTarget(vf2d pos);
void MoveCamera();
virtual bool MissionCompleted()=0;
virtual void NextLevel();
protected:
VirusAttack*game;
int state=0;
Textbox dialog;
float initialWaitTimer=3;
utils::Camera2D camera;
vf2d cameraTargetPos={};
bool missionCompleted=false;
float waitToContinueTimer=0;
float missionCompletedTimer=0;
};
#define SetupStage(StageClass) \
class StageClass:public Scenario{ \
public: \
StageClass(VirusAttack*game); \
void Start()override; \
void Update()override; \
bool MissionCompleted()override; \
void Draw()override; \
void NextLevel()override; \
};
SetupStage(Stage1)
SetupStage(Stage2)
SetupStage(Stage3)
SetupStage(Stage4)
SetupStage(Stage5)
SetupStage(Stage6)
SetupStage(Stage7)
SetupStage(Stage8)

@ -1,6 +1,6 @@
#pragma once #pragma once
enum class Sound{ enum class Sound:int{
HUM, HUM,
GRAVITY, GRAVITY,
COSMOS, COSMOS,

@ -104,7 +104,7 @@ void Textbox::Update(PixelGameEngine*pge){
} }
void Textbox::Draw(PixelGameEngine*pge,Resources&resources,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,int totalUsedMemory,int memoryLimit){ void Textbox::Draw(PixelGameEngine*pge,Resources&resources,std::vector<std::unique_ptr<Renderable>>&IMAGES,int totalUsedMemory,int memoryLimit){
if(visible){ if(visible){
geom2d::rect<float>boundingRect={pos-vf2d{3,3},maxSize+vf2d{6,6}}; geom2d::rect<float>boundingRect={pos-vf2d{3,3},maxSize+vf2d{6,6}};
if(resourceCost.size()>0){ if(resourceCost.size()>0){
@ -224,7 +224,7 @@ void Textbox::SetVisible(bool visible){
} }
} }
void Textbox::UpdateAndDraw(vf2d pos,PixelGameEngine*pge,Resources&resources,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,int totalUsedMemory,int memoryLimit){ void Textbox::UpdateAndDraw(vf2d pos,PixelGameEngine*pge,Resources&resources,std::vector<std::unique_ptr<Renderable>>&IMAGES,int totalUsedMemory,int memoryLimit){
UpdatePosition(pos); UpdatePosition(pos);
Update(pge); Update(pge);
Draw(pge,resources,IMAGES,totalUsedMemory,memoryLimit); Draw(pge,resources,IMAGES,totalUsedMemory,memoryLimit);

@ -9,8 +9,8 @@ class Textbox{
std::string displayHeaderText=""; std::string displayHeaderText="";
std::string text=""; std::string text="";
std::string displayText=""; std::string displayText="";
Renderable*boxImg; Renderable*boxImg=nullptr;
Audio*dialogSound; Audio*dialogSound=nullptr;
int soundHandle=-1; int soundHandle=-1;
float audioFadeOutDelay=2; float audioFadeOutDelay=2;
vf2d pos={}; vf2d pos={};
@ -31,7 +31,7 @@ public:
Textbox(); Textbox();
void Initialize(std::string text,vf2d pos={},std::string headerText="",Renderable*boxImg=nullptr,vf2d maxSize={120,1},Audio*dialogSound=nullptr,std::vector<Memory>resourceCost={},float letterDisplayDelay=0.01); void Initialize(std::string text,vf2d pos={},std::string headerText="",Renderable*boxImg=nullptr,vf2d maxSize={120,1},Audio*dialogSound=nullptr,std::vector<Memory>resourceCost={},float letterDisplayDelay=0.01);
void UpdateAndDraw(vf2d pos,PixelGameEngine*pge,Resources&resources,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,int totalUsedMemory,int memoryLimit); void UpdateAndDraw(vf2d pos,PixelGameEngine*pge,Resources&resources,std::vector<std::unique_ptr<Renderable>>&IMAGES,int totalUsedMemory,int memoryLimit);
std::string&GetCurrentString(); std::string&GetCurrentString();
void SetVisible(bool visible); void SetVisible(bool visible);
vf2d GetSize(); vf2d GetSize();
@ -41,6 +41,6 @@ public:
private: private:
void Update(PixelGameEngine*pge); void Update(PixelGameEngine*pge);
void UpdatePosition(vf2d newPos); void UpdatePosition(vf2d newPos);
void Draw(PixelGameEngine*pge,Resources&resources,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,int totalUsedMemory,int memoryLimit); void Draw(PixelGameEngine*pge,Resources&resources,std::vector<std::unique_ptr<Renderable>>&IMAGES,int totalUsedMemory,int memoryLimit);
void SetDefaults(); void SetDefaults();
}; };

@ -6,10 +6,12 @@
#include "olcPGEX_QuickGUI.h" #include "olcPGEX_QuickGUI.h"
#include "Textbox.h" #include "Textbox.h"
Unit::~Unit(){};
std::string LeftShifter::unitName="Left Shifter"; std::string LeftShifter::unitName="Left Shifter";
std::string LeftShifter::unitDescription="Shifts target memory 1 bit to the left."; std::string LeftShifter::unitDescription="Shifts target memory 1 bit to the left.";
std::vector<Memory> LeftShifter::resourceCost={{RANGE,2},{ATKSPD,2},{MOVESPD,6},{PROCEDURE,1},{HEALTH,4}}; std::vector<Memory> LeftShifter::resourceCost={{RANGE,2},{ATKSPD,2},{MOVESPD,6},{PROCEDURE,1},{HEALTH,4}};
LeftShifter::LeftShifter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) LeftShifter::LeftShifter(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,LeftShifter::resourceCost,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<std::shared_ptr<Unit>>&otherUnits){ void LeftShifter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
@ -19,7 +21,7 @@ void LeftShifter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUni
std::string RightShifter::unitName="Right Shifter"; std::string RightShifter::unitName="Right Shifter";
std::string RightShifter::unitDescription="Shifts target memory 1 bit to the right."; std::string RightShifter::unitDescription="Shifts target memory 1 bit to the right.";
std::vector<Memory> RightShifter::resourceCost={{HEALTH,4},{RANGE,2},{ATKSPD,2},{MOVESPD,6},{PROCEDURE,1}}; std::vector<Memory> RightShifter::resourceCost={{HEALTH,4},{RANGE,2},{ATKSPD,2},{MOVESPD,6},{PROCEDURE,1}};
RightShifter::RightShifter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) RightShifter::RightShifter(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,RightShifter::resourceCost,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<std::shared_ptr<Unit>>&otherUnits){ void RightShifter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
@ -29,7 +31,7 @@ void RightShifter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUn
std::string BitRestorer::unitName="Bit Restorer"; std::string BitRestorer::unitName="Bit Restorer";
std::string BitRestorer::unitDescription="Randomly restores 1 missing bit to a target."; std::string BitRestorer::unitDescription="Randomly restores 1 missing bit to a target.";
std::vector<Memory> BitRestorer::resourceCost={{PROCEDURE,6},{RANGE,1},{ATKSPD,1},{MOVESPD,2},{HEALTH,2}}; std::vector<Memory> BitRestorer::resourceCost={{PROCEDURE,6},{RANGE,1},{ATKSPD,1},{MOVESPD,2},{HEALTH,2}};
BitRestorer::BitRestorer(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) BitRestorer::BitRestorer(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,BitRestorer::resourceCost,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<std::shared_ptr<Unit>>&otherUnits){ void BitRestorer::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
@ -71,7 +73,7 @@ void BitRestorer::AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&ot
std::string MemorySwapper::unitName="Memory Swapper"; std::string MemorySwapper::unitName="Memory Swapper";
std::string MemorySwapper::unitDescription="Flips the orientation of all bits of a target around."; std::string MemorySwapper::unitDescription="Flips the orientation of all bits of a target around.";
std::vector<Memory> MemorySwapper::resourceCost={{RANGE,3},{ATKSPD,1},{HEALTH,3},{PROCEDURE,3},{MOVESPD,4}}; std::vector<Memory> MemorySwapper::resourceCost={{RANGE,3},{ATKSPD,1},{HEALTH,3},{PROCEDURE,3},{MOVESPD,4}};
MemorySwapper::MemorySwapper(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) MemorySwapper::MemorySwapper(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,MemorySwapper::resourceCost,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; autoAcquireFriendlyTarget=false;
} }
@ -115,7 +117,7 @@ void MemorySwapper::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherU
std::string Corrupter::unitName="Corrupter"; std::string Corrupter::unitName="Corrupter";
std::string Corrupter::unitDescription="Chooses a random bit and negates it on a target."; std::string Corrupter::unitDescription="Chooses a random bit and negates it on a target.";
std::vector<Memory> Corrupter::resourceCost={{ATKSPD,3},{RANGE,1},{PROCEDURE,8},{MOVESPD,8},{HEALTH,4}}; std::vector<Memory> Corrupter::resourceCost={{ATKSPD,3},{RANGE,1},{PROCEDURE,8},{MOVESPD,8},{HEALTH,4}};
Corrupter::Corrupter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) Corrupter::Corrupter(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,Corrupter::resourceCost,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<std::shared_ptr<Unit>>&otherUnits){ void Corrupter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
@ -127,7 +129,7 @@ void Corrupter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits
std::string MemoryAllocator::unitName="Memory Allocator"; std::string MemoryAllocator::unitName="Memory Allocator";
std::string MemoryAllocator::unitDescription="A unit that builds other units."; std::string MemoryAllocator::unitDescription="A unit that builds other units.";
std::vector<Memory> MemoryAllocator::resourceCost={{RANGE,1},{ATKSPD,1},{MOVESPD,2},{PROCEDURE,1},{HEALTH,1}}; std::vector<Memory> MemoryAllocator::resourceCost={{RANGE,1},{ATKSPD,1},{MOVESPD,2},{PROCEDURE,1},{HEALTH,1}};
MemoryAllocator::MemoryAllocator(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) MemoryAllocator::MemoryAllocator(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,MemoryAllocator::resourceCost,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; isAllocator=true;
} }
@ -136,7 +138,7 @@ void MemoryAllocator::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&othe
} }
void MemoryAllocator::Update(PixelGameEngine*pge,std::map<Sound,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::unique_ptr<Unit>>&queuedUnits){
if(IsBuilding()){ if(IsBuilding()){
SetTargetLocation(CONSTANT::UNSELECTED); SetTargetLocation(CONSTANT::UNSELECTED);
target.reset(); target.reset();
@ -150,7 +152,7 @@ void MemoryAllocator::Update(PixelGameEngine*pge,std::map<Sound,std::unique_ptr<
} }
} }
void MemoryAllocator::Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ void MemoryAllocator::Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES){
if(IsBuilding()){ if(IsBuilding()){
game.GetPGE()->SetDrawTarget(img.Sprite()); game.GetPGE()->SetDrawTarget(img.Sprite());
game.GetPGE()->Clear(BLANK); game.GetPGE()->Clear(BLANK);
@ -172,7 +174,7 @@ void MemoryAllocator::Draw(TileTransformedView&game,std::map<Image,std::unique_p
std::string RAMBank::unitName="RAM Bank"; std::string RAMBank::unitName="RAM Bank";
std::string RAMBank::unitDescription="Allows for the construction of Memory Allocators."; std::string RAMBank::unitDescription="Allows for the construction of Memory Allocators.";
std::vector<Memory> RAMBank::resourceCost={{PROCEDURE,25},{HEALTH,16}}; std::vector<Memory> RAMBank::resourceCost={{PROCEDURE,25},{HEALTH,16}};
RAMBank::RAMBank(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly) RAMBank::RAMBank(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly)
:Unit(pge,RAMBank::resourceCost,pos,41,*IMAGES[RAM_BANK],WHITE,WHITE,friendly,false :Unit(pge,RAMBank::resourceCost,pos,41,*IMAGES[RAM_BANK],WHITE,WHITE,friendly,false
,false,false ,false,false
),randomOffset({util::random(128),util::random(128)}),matrixImg(*IMAGES[MATRIX]), ),randomOffset({util::random(128),util::random(128)}),matrixImg(*IMAGES[MATRIX]),
@ -196,7 +198,7 @@ void RAMBank::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
} }
void RAMBank::Update(PixelGameEngine*pge,std::map<Sound,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::unique_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++){
@ -208,27 +210,27 @@ void RAMBank::Update(PixelGameEngine*pge,std::map<Sound,std::unique_ptr<Audio>>&
} }
if(!soundStarted){ if(!soundStarted){
soundStarted=true; soundStarted=true;
soundHandle=SOUNDS[Sound::HUM]->Play(GetPos(),0.4,0.4,true); soundHandle=SOUNDS[int(Sound::HUM)]->Play(GetPos(),0.4,0.4,true);
} }
img.Decal()->Update(); img.Decal()->Update();
pge->SetDrawTarget(nullptr); pge->SetDrawTarget(nullptr);
} }
void RAMBank::DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ void RAMBank::DrawHud(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES){
if(IsSelected()){ if(IsSelected()){
allocatorManager.DrawDecal(game); allocatorManager.DrawDecal(game);
} }
} }
void RAMBank::Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ void RAMBank::Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES){
game.DrawRotatedDecal(GetGhostPos(),img.Decal(),0,img.Sprite()->Size()/2,{1,1},GetUnitColor()); game.DrawRotatedDecal(GetGhostPos(),img.Decal(),0,img.Sprite()->Size()/2,{1,1},GetUnitColor());
if(IsSelected()){ if(IsSelected()){
game.DrawRotatedDecal(GetGhostPos(),IMAGES[SELECTION_CIRCLE]->Decal(),0,IMAGES[SELECTION_CIRCLE]->Sprite()->Size()/2,vf2d(img.Sprite()->Size())/IMAGES[SELECTION_CIRCLE]->Sprite()->Size(),WHITE); game.DrawRotatedDecal(GetGhostPos(),IMAGES[SELECTION_CIRCLE]->Decal(),0,IMAGES[SELECTION_CIRCLE]->Sprite()->Size()/2,vf2d(img.Sprite()->Size())/IMAGES[SELECTION_CIRCLE]->Sprite()->Size(),WHITE);
} }
} }
void RAMBank::OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS){ void RAMBank::OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS){
SOUNDS[Sound::HUM]->Stop(soundHandle); SOUNDS[int(Sound::HUM)]->Stop(soundHandle);
} }
void RAMBank::UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered,int totalUsedMemory,int availableMemory){ void RAMBank::UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered,int totalUsedMemory,int availableMemory){
@ -249,7 +251,7 @@ void RAMBank::UpdateGUIState(TileTransformedView&game,Resources&player_resources
allocatorButton->Enable(buttonEnabled); allocatorButton->Enable(buttonEnabled);
} }
bool RAMBank::ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector<std::shared_ptr<Unit>>&units,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ bool RAMBank::ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES){
if(allocatorButton->bPressed){ if(allocatorButton->bPressed){
//First try to take one of each. //First try to take one of each.
if(player_resources.atkSpd>0&&player_resources.health>0&&player_resources.moveSpd>0&&player_resources.procedure>0&&player_resources.range>0){ if(player_resources.atkSpd>0&&player_resources.health>0&&player_resources.moveSpd>0&&player_resources.procedure>0&&player_resources.range>0){
@ -286,14 +288,14 @@ bool RAMBank::ClickHandled(TileTransformedView&game,Resources&player_resources,s
std::string _Platform::unitName="Platform"; std::string _Platform::unitName="Platform";
std::string _Platform::unitDescription="Anchored to the ground, this unit is an intermediate step for larger units."; std::string _Platform::unitDescription="Anchored to the ground, this unit is an intermediate step for larger units.";
std::vector<Memory> _Platform::resourceCost={{HEALTH,6}}; std::vector<Memory> _Platform::resourceCost={{HEALTH,6}};
_Platform::_Platform(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) _Platform::_Platform(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,_Platform::resourceCost,pos,24,*IMAGES[PLATFORM],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,false){ :Unit(pge,_Platform::resourceCost,pos,24,*IMAGES[PLATFORM],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,false){
isPlatform=true; isPlatform=true;
} }
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::map<Sound,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::unique_ptr<Unit>>&queuedUnits){
if(IsBuilding()){ if(IsBuilding()){
SetTargetLocation(CONSTANT::UNSELECTED); SetTargetLocation(CONSTANT::UNSELECTED);
target.reset(); target.reset();
@ -307,7 +309,7 @@ void _Platform::Update(PixelGameEngine*pge,std::map<Sound,std::unique_ptr<Audio>
} }
} }
void _Platform::Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ void _Platform::Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES){
if(IsBuilding()){ if(IsBuilding()){
game.GetPGE()->SetDrawTarget(img.Sprite()); game.GetPGE()->SetDrawTarget(img.Sprite());
game.GetPGE()->Clear(BLANK); game.GetPGE()->Clear(BLANK);
@ -329,7 +331,7 @@ void _Platform::Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Ren
std::string Refresher::unitName="Refresher"; std::string Refresher::unitName="Refresher";
std::string Refresher::unitDescription="Repairs missing bits to surrounding units."; std::string Refresher::unitDescription="Repairs missing bits to surrounding units.";
std::vector<Memory> Refresher::resourceCost={{ATKSPD,3},{RANGE,1},{PROCEDURE,8},{HEALTH,4}}; std::vector<Memory> Refresher::resourceCost={{ATKSPD,3},{RANGE,1},{PROCEDURE,8},{HEALTH,4}};
Refresher::Refresher(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) Refresher::Refresher(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,Refresher::resourceCost,pos,24,*IMAGES[REFRESHER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,false :Unit(pge,Refresher::resourceCost,pos,24,*IMAGES[REFRESHER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,false
,true,false){} ,true,false){}
@ -354,7 +356,7 @@ void Refresher::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits
std::string Turret::unitName="Turret"; std::string Turret::unitName="Turret";
std::string Turret::unitDescription="Automatically targets attack and movement speed memory ranges before others."; std::string Turret::unitDescription="Automatically targets attack and movement speed memory ranges before others.";
std::vector<Memory> Turret::resourceCost={{ATKSPD,4},{RANGE,5},{HEALTH,6},{PROCEDURE,16}}; std::vector<Memory> Turret::resourceCost={{ATKSPD,4},{RANGE,5},{HEALTH,6},{PROCEDURE,16}};
Turret::Turret(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) Turret::Turret(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,Turret::resourceCost,pos,24,*IMAGES[TURRET],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,false){} :Unit(pge,Turret::resourceCost,pos,24,*IMAGES[TURRET],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,false){}
void Turret::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void Turret::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
@ -389,7 +391,7 @@ void Turret::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
std::string MemoryGuard::unitName="Memory Guard"; std::string MemoryGuard::unitName="Memory Guard";
std::string MemoryGuard::unitDescription="Reduces the chance of bit modification for all surrounding units by 30%"; std::string MemoryGuard::unitDescription="Reduces the chance of bit modification for all surrounding units by 30%";
std::vector<Memory> MemoryGuard::resourceCost={{HEALTH,10},{ATKSPD,4},{RANGE,4},{PROCEDURE,12}}; std::vector<Memory> MemoryGuard::resourceCost={{HEALTH,10},{ATKSPD,4},{RANGE,4},{PROCEDURE,12}};
MemoryGuard::MemoryGuard(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) MemoryGuard::MemoryGuard(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,MemoryGuard::resourceCost,pos,24,*IMAGES[MEMORY_GUARD],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,false :Unit(pge,MemoryGuard::resourceCost,pos,24,*IMAGES[MEMORY_GUARD],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,false
,true,false){} ,true,false){}
@ -439,7 +441,7 @@ Unit::Unit(PixelGameEngine*pge,std::vector<Memory>memory,vf2d pos,float radius,R
targetingLine.Create(25,24,false,false); targetingLine.Create(25,24,false,false);
} }
void Unit::DrawRangeIndicator(PixelGameEngine*pge,TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ void Unit::DrawRangeIndicator(PixelGameEngine*pge,TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES){
if(!CanInteractWithAllies()&&!CanInteractWithEnemies())return; if(!CanInteractWithAllies()&&!CanInteractWithEnemies())return;
float dist=geom2d::line<float>(game.ScreenToWorld(pge->GetMousePos()),GetGhostPos()).length(); float dist=geom2d::line<float>(game.ScreenToWorld(pge->GetMousePos()),GetGhostPos()).length();
float range=12*(GetRange()+1); float range=12*(GetRange()+1);
@ -475,16 +477,16 @@ void Unit::DrawRangeIndicator(PixelGameEngine*pge,TileTransformedView&game,std::
} }
} }
void Unit::Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ void Unit::Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES){
game.DrawRotatedDecal(GetGhostPos(),img.Decal(),0,img.Sprite()->Size()/2,{1,1},GetUnitColor()); game.DrawRotatedDecal(GetGhostPos(),img.Decal(),0,img.Sprite()->Size()/2,{1,1},GetUnitColor());
if(IsSelected()){ if(IsSelected()){
game.DrawRotatedDecal(GetGhostPos(),IMAGES[SELECTION_CIRCLE]->Decal(),0,IMAGES[SELECTION_CIRCLE]->Sprite()->Size()/2,vf2d(img.Sprite()->Size())/IMAGES[SELECTION_CIRCLE]->Sprite()->Size(),WHITE); game.DrawRotatedDecal(GetGhostPos(),IMAGES[SELECTION_CIRCLE]->Decal(),0,IMAGES[SELECTION_CIRCLE]->Sprite()->Size()/2,vf2d(img.Sprite()->Size())/IMAGES[SELECTION_CIRCLE]->Sprite()->Size(),WHITE);
} }
} }
void Unit::DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){} void Unit::DrawHud(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES){}
void Unit::_DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool unitMetersGreyedOut){ void Unit::_DrawHud(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool unitMetersGreyedOut){
DrawHud(game,IMAGES); DrawHud(game,IMAGES);
int initialBarX=ghostPos.x-GetMemorySize()/2*CONSTANT::BAR_SQUARE_SIZE.x-CONSTANT::BAR_SQUARE_SIZE.x/2; int initialBarX=ghostPos.x-GetMemorySize()/2*CONSTANT::BAR_SQUARE_SIZE.x-CONSTANT::BAR_SQUARE_SIZE.x/2;
int initialBarY=ghostPos.y-CONSTANT::BAR_SQUARE_SIZE.y-img.Sprite()->height/2-2; int initialBarY=ghostPos.y-CONSTANT::BAR_SQUARE_SIZE.y-img.Sprite()->height/2-2;
@ -540,7 +542,7 @@ void Unit::_DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Rend
} }
} }
void Unit::DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ void Unit::DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES){
if(!target.expired()){ if(!target.expired()){
geom2d::line<float>lineToTarget(pos,target.lock()->pos); geom2d::line<float>lineToTarget(pos,target.lock()->pos);
lineToTarget.start=lineToTarget.rpoint(GetUnitSize().x/2); lineToTarget.start=lineToTarget.rpoint(GetUnitSize().x/2);
@ -608,7 +610,7 @@ int Unit::GetBits(Marker&m){
return activeBits; return activeBits;
} }
void Unit::OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS){} void Unit::OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS){}
int Unit::GetHealth(){ int Unit::GetHealth(){
return GetBits(health); return GetBits(health);
@ -640,7 +642,7 @@ void Unit::_RunAI(PixelGameEngine*pge){
RunAI(pge); RunAI(pge);
} }
void Unit::_Update(PixelGameEngine*pge,std::map<Sound,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::map<Image,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::unique_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()){
@ -789,7 +791,7 @@ void Unit::SetPos(vf2d newPos){
pos=newPos; pos=newPos;
} }
void Unit::AttemptAttack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>unit,std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<DebuffIcon>&debuffIcons,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ void Unit::AttemptAttack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>unit,std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<DebuffIcon>&debuffIcons,std::vector<std::unique_ptr<Renderable>>&IMAGES){
if(reloadTimer>0)return; if(reloadTimer>0)return;
std::weak_ptr<Unit>finalTarget; std::weak_ptr<Unit>finalTarget;
if(!unit.expired()){ if(!unit.expired()){
@ -825,7 +827,7 @@ void Unit::AttemptAttack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>unit,std
} }
} }
void Unit::Update(PixelGameEngine*pge,std::map<Sound,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::unique_ptr<Unit>>&queuedUnits){}
void Unit::Attacked(std::weak_ptr<Unit>attacker){} void Unit::Attacked(std::weak_ptr<Unit>attacker){}
@ -932,7 +934,7 @@ Pixel Unit::GetUnitColor(){
} }
} }
bool Unit::ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector<std::shared_ptr<Unit>>&units,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ bool Unit::ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES){
return false; return false;
}; };

@ -41,6 +41,7 @@ struct Memory{
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);
virtual~Unit();
int GetHealth(); int GetHealth();
int GetRange(); int GetRange();
int GetAtkSpd(); int GetAtkSpd();
@ -50,12 +51,12 @@ 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::map<Sound,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::unique_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::map<Image,std::unique_ptr<Renderable>>&IMAGES); virtual void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES);
virtual void DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES); virtual void DrawHud(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES);
void _DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool unitMetersGreyedOut); void _DrawHud(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool unitMetersGreyedOut);
virtual void OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS); virtual void OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS);
bool IsFriendly(); bool IsFriendly();
bool IsSelected(); bool IsSelected();
void Select(); void Select();
@ -66,14 +67,14 @@ public:
void SetTargetUnit(std::weak_ptr<Unit>target); void SetTargetUnit(std::weak_ptr<Unit>target);
void SetTargetLocation(vf2d targetLoc); void SetTargetLocation(vf2d targetLoc);
void SetPos(vf2d newPos); void SetPos(vf2d newPos);
void AttemptAttack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>unit,std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<DebuffIcon>&debuffIcons,std::map<Image,std::unique_ptr<Renderable>>&IMAGES); void AttemptAttack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>unit,std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<DebuffIcon>&debuffIcons,std::vector<std::unique_ptr<Renderable>>&IMAGES);
bool InFogOfWar(); bool InFogOfWar();
bool GhostInFogOfWar(); bool GhostInFogOfWar();
void HideGhost(); void HideGhost();
vf2d GetGhostPos(); vf2d GetGhostPos();
void _Update(PixelGameEngine*pge,std::map<Sound,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::map<Image,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::unique_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::map<Image,std::unique_ptr<Renderable>>&IMAGES); void DrawRangeIndicator(PixelGameEngine*pge,TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES);
bool CanInteractWithEnemies(); bool CanInteractWithEnemies();
bool CanInteractWithAllies(); bool CanInteractWithAllies();
Renderable&GetImage(); Renderable&GetImage();
@ -82,13 +83,13 @@ public:
virtual void Attacked(std::weak_ptr<Unit>attacker); virtual void Attacked(std::weak_ptr<Unit>attacker);
void _Attacked(std::weak_ptr<Unit>attacker); void _Attacked(std::weak_ptr<Unit>attacker);
std::weak_ptr<Unit>GetCurrentTarget(); std::weak_ptr<Unit>GetCurrentTarget();
void DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES); void DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES);
bool AutoAcquiresFriendlyTargets(); bool AutoAcquiresFriendlyTargets();
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,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::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::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::unique_ptr<Unit>finalUnit);
bool IsBuilding(); bool IsBuilding();
@ -163,7 +164,7 @@ private:
}; };
struct LeftShifter:Unit{ struct LeftShifter:Unit{
LeftShifter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); LeftShifter(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;
static std::vector<Memory> resourceCost; static std::vector<Memory> resourceCost;
static std::string unitName; static std::string unitName;
@ -171,7 +172,7 @@ struct LeftShifter:Unit{
}; };
struct RightShifter:Unit{ struct RightShifter:Unit{
RightShifter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); RightShifter(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;
static std::vector<Memory> resourceCost; static std::vector<Memory> resourceCost;
static std::string unitName; static std::string unitName;
@ -179,7 +180,7 @@ struct RightShifter:Unit{
}; };
struct BitRestorer:Unit{ struct BitRestorer:Unit{
BitRestorer(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); BitRestorer(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 AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&otherUnits); void AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&otherUnits);
static std::vector<Memory> resourceCost; static std::vector<Memory> resourceCost;
@ -188,7 +189,7 @@ struct BitRestorer:Unit{
}; };
struct MemorySwapper:Unit{ struct MemorySwapper:Unit{
MemorySwapper(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); MemorySwapper(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;
static std::vector<Memory> resourceCost; static std::vector<Memory> resourceCost;
static std::string unitName; static std::string unitName;
@ -196,7 +197,7 @@ struct MemorySwapper:Unit{
}; };
struct Corrupter:Unit{ struct Corrupter:Unit{
Corrupter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); Corrupter(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;
static std::vector<Memory> resourceCost; static std::vector<Memory> resourceCost;
static std::string unitName; static std::string unitName;
@ -204,10 +205,10 @@ struct Corrupter:Unit{
}; };
struct MemoryAllocator:Unit{ struct MemoryAllocator:Unit{
MemoryAllocator(PixelGameEngine*pge,vf2d pos,std::map<Image,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::map<Sound,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::unique_ptr<Unit>>&queuedUnits)override;
void Draw(TileTransformedView&game,std::map<Image,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;
static std::string unitDescription; static std::string unitDescription;
@ -219,34 +220,34 @@ struct RAMBank:Unit{
Renderable&originalImg; Renderable&originalImg;
Renderable&matrixImg; Renderable&matrixImg;
bool soundStarted=false; bool soundStarted=false;
int soundHandle; int soundHandle=-1;
QuickGUI::Manager allocatorManager; QuickGUI::Manager allocatorManager;
QuickGUI::ImageButton*allocatorButton; QuickGUI::ImageButton*allocatorButton;
RAMBank(PixelGameEngine*pge,vf2d pos,std::map<Image,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::map<Sound,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::unique_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::map<Image,std::unique_ptr<Renderable>>&IMAGES)override; void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override;
void OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS)override; void OnDeath(std::vector<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::vector<std::unique_ptr<Renderable>>&IMAGES)override;
void UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered,int totalUsedMemory,int availableMemory)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::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;
static std::string unitDescription; static std::string unitDescription;
}; };
struct _Platform:Unit{ struct _Platform:Unit{
_Platform(PixelGameEngine*pge,vf2d pos,std::map<Image,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::map<Sound,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::unique_ptr<Unit>>&queuedUnits)override;
void Draw(TileTransformedView&game,std::map<Image,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;
static std::string unitDescription; static std::string unitDescription;
}; };
struct MemoryGuard:Unit{ struct MemoryGuard:Unit{
MemoryGuard(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); MemoryGuard(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;
static std::vector<Memory> resourceCost; static std::vector<Memory> resourceCost;
static std::string unitName; static std::string unitName;
@ -254,7 +255,7 @@ struct MemoryGuard:Unit{
}; };
struct Refresher:Unit{ struct Refresher:Unit{
Refresher(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); Refresher(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;
static std::vector<Memory> resourceCost; static std::vector<Memory> resourceCost;
static std::string unitName; static std::string unitName;
@ -262,7 +263,7 @@ struct Refresher:Unit{
}; };
struct Turret:Unit{ struct Turret:Unit{
Turret(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); Turret(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;
static std::vector<Memory> resourceCost; static std::vector<Memory> resourceCost;
static std::string unitName; static std::string unitName;

@ -9,28 +9,39 @@
#ifdef SPLASH_ENABLED #ifdef SPLASH_ENABLED
#define OLC_PGEX_SPLASHSCREEN #define OLC_PGEX_SPLASHSCREEN
#endif #endif
#include "Scenario.h"
#include "olcUTIL_Geometry2D.h"
#include "TileManager.h" #include "TileManager.h"
#include "olcUTIL_Geometry2D.h"
#include "util.h" #include "util.h"
#include "Scenario.h" #include "Level.h"
#include "VirusAttack.h"
VirusAttack*game;
std::vector<std::unique_ptr<Renderable>>IMAGES;
std::vector<std::unique_ptr<Audio>>SOUNDS;
VirusAttack::VirusAttack() VirusAttack::VirusAttack()
{ {
// Name your application // Name your application
sAppName = "Virus Attack"; sAppName = "Virus Attack";
game=this;
} }
void VirusAttack::InitializeImages(){ void VirusAttack::InitializeImages(){
auto LoadImage=[&](Image img,std::string filepath,bool filter=false,bool clamp=true){ auto LoadImage=[&](Image img,std::string filepath,bool filter=false,bool clamp=true){
IMAGES[img]=std::make_unique<Renderable>(); IMAGES.emplace_back(std::make_unique<Renderable>());
IMAGES[img]->Load(filepath,nullptr,filter,clamp); IMAGES[img]->Load(filepath,nullptr,filter,clamp);
}; };
LoadImage(TILE,"assets/tile.png",false,false); LoadImage(TILE,"assets/tile.png",false,false);
LoadImage(MINIMAP_HUD,"assets/minimap_hud.png"); LoadImage(MINIMAP_HUD,"assets/minimap_hud.png");
LoadImage(OUTLINE,"assets/outline.png"); LoadImage(OUTLINE,"assets/outline.png");
IMAGES.emplace_back(std::make_unique<Renderable>());
IMAGES[MINIMAP_OUTLINE]->Create(64,64);
LoadImage(VIRUS_IMG1,"assets/unit.png"); LoadImage(VIRUS_IMG1,"assets/unit.png");
LoadImage(SELECTION_CIRCLE,"assets/selection_circle.png"); LoadImage(SELECTION_CIRCLE,"assets/selection_circle.png");
IMAGES.emplace_back(std::make_unique<Renderable>());
IMAGES[MATRIX]->Create(64,64,false,false);
IMAGES[MATRIX]->Sprite()->SetSampleMode(Sprite::PERIODIC);
LoadImage(MEMORY_COLLECTION_POINT,"assets/memory_collection_point.png"); LoadImage(MEMORY_COLLECTION_POINT,"assets/memory_collection_point.png");
LoadImage(LEFT_SHIFTER,"assets/left_shifter.png"); LoadImage(LEFT_SHIFTER,"assets/left_shifter.png");
LoadImage(RIGHT_SHIFTER,"assets/right_shifter.png"); LoadImage(RIGHT_SHIFTER,"assets/right_shifter.png");
@ -88,7 +99,6 @@ void VirusAttack::InitializeLevelData(){
levelData[stage].name=stage; levelData[stage].name=stage;
levelData[stage].cameraStart={96,96}; levelData[stage].cameraStart={96,96};
levelData[stage].worldZoom={1,1}; levelData[stage].worldZoom={1,1};
levelData[stage].scenario=scenarios[0];
levelData[stage].levelColor=DARK_RED; levelData[stage].levelColor=DARK_RED;
levelData[stage].size={24,24}; levelData[stage].size={24,24};
levelData[stage].bgm=Sound::GRAVITY; levelData[stage].bgm=Sound::GRAVITY;
@ -112,7 +122,6 @@ void VirusAttack::InitializeLevelData(){
levelData[stage].cameraStart={96,96}; levelData[stage].cameraStart={96,96};
levelData[stage].worldZoom={1,1}; levelData[stage].worldZoom={1,1};
levelData[stage].size={16,16}; levelData[stage].size={16,16};
levelData[stage].scenario=scenarios[1];
levelData[stage].levelColor=DARK_GREEN; levelData[stage].levelColor=DARK_GREEN;
levelData[stage].bgm=Sound::GRAVITY; levelData[stage].bgm=Sound::GRAVITY;
levelData[stage].player_starting_resources={10,10,10,10,10}; levelData[stage].player_starting_resources={10,10,10,10,10};
@ -134,7 +143,7 @@ bool VirusAttack::OnUserCreate(){
currentBackCol=newCol=colorChangeOptions[rand()%colorChangeOptions.size()]; currentBackCol=newCol=colorChangeOptions[rand()%colorChangeOptions.size()];
SetPixelMode(Pixel::MASK); SetPixelMode(Pixel::MASK);
game.Initialise(GetScreenSize()); gametv.Initialise(GetScreenSize());
InitializeImages(); InitializeImages();
@ -148,13 +157,6 @@ bool VirusAttack::OnUserCreate(){
platformCreationBox.SetVisible(false); platformCreationBox.SetVisible(false);
restartBox.SetVisible(false); restartBox.SetVisible(false);
IMAGES[MINIMAP_OUTLINE]=std::make_unique<Renderable>();
IMAGES[MINIMAP_OUTLINE]->Create(64,64);
IMAGES[MATRIX]=std::make_unique<Renderable>();
IMAGES[MATRIX]->Create(64,64,false,false);
IMAGES[MATRIX]->Sprite()->SetSampleMode(Sprite::PERIODIC);
attackingLineModified.Create(IMAGES[ATTACKING_LINE]->Sprite()->width,IMAGES[ATTACKING_LINE]->Sprite()->height,false,false); attackingLineModified.Create(IMAGES[ATTACKING_LINE]->Sprite()->width,IMAGES[ATTACKING_LINE]->Sprite()->height,false,false);
AL.AudioSystemInit(); AL.AudioSystemInit();
@ -165,7 +167,6 @@ bool VirusAttack::OnUserCreate(){
InitializeLevelData(); InitializeLevelData();
LoadLevel(STAGE1); LoadLevel(STAGE1);
currentLevel->scenario->Start();
return true; return true;
} }
@ -176,16 +177,16 @@ void VirusAttack::LoadLevel(LevelName level){
WORLD_SIZE=selectedLevel.size; WORLD_SIZE=selectedLevel.size;
game.SetWorldScale(selectedLevel.worldZoom); gametv.SetWorldScale(selectedLevel.worldZoom);
game.SetWorldOffset(selectedLevel.cameraStart-vf2d(GetScreenSize())/2.f/game.GetWorldScale()); gametv.SetWorldOffset(selectedLevel.cameraStart-vf2d(GetScreenSize())/2.f/gametv.GetWorldScale());
if(bgm==nullptr){ if(bgm==nullptr){
bgm=SOUNDS[selectedLevel.bgm].get(); bgm=SOUNDS[int(selectedLevel.bgm)].get();
bgm->PlayCentered(1,1,true); bgm->PlayCentered(1,1,true);
} else } else
if(bgm!=SOUNDS[selectedLevel.bgm].get()){ if(bgm!=SOUNDS[int(selectedLevel.bgm)].get()){
bgm->Stop(); bgm->Stop();
bgm=SOUNDS[selectedLevel.bgm].get(); bgm=SOUNDS[int(selectedLevel.bgm)].get();
bgm->PlayCentered(1,1,true); bgm->PlayCentered(1,1,true);
} }
player_resources=selectedLevel.player_starting_resources; player_resources=selectedLevel.player_starting_resources;
@ -201,7 +202,7 @@ void VirusAttack::LoadLevel(LevelName level){
for(auto&u:selectedLevel.unitPlacement){ for(auto&u:selectedLevel.unitPlacement){
#define TranslateUnit(type) \ #define TranslateUnit(type) \
case UnitType::type:{ \ case UnitType::type:{ \
units.push_back(std::make_unique<type>(this,u.pos,IMAGES,u.friendly)); \ units.push_back(std::make_shared<type>(this,u.pos,IMAGES,u.friendly)); \
}break; }break;
switch(u.type){ switch(u.type){
@ -223,7 +224,7 @@ void VirusAttack::LoadLevel(LevelName level){
} }
} }
for(auto&cp:selectedLevel.cpPlacement){ for(auto&cp:selectedLevel.cpPlacement){
collectionPoints.push_back(std::make_unique<CollectionPoint>(this,cp.pos,cp.rot,*IMAGES[MEMORY_COLLECTION_POINT],cp.type)); collectionPoints.push_back(std::make_shared<CollectionPoint>(this,cp.pos,cp.rot,*IMAGES[MEMORY_COLLECTION_POINT],cp.type));
} }
randomBackgroundOffset={util::random(128),util::random(128)}; randomBackgroundOffset={util::random(128),util::random(128)};
@ -264,22 +265,14 @@ void VirusAttack::InitializeGUIs(){
} }
void VirusAttack::InitializeScenarios(){ void VirusAttack::InitializeScenarios(){
scenarios.emplace_back(new Stage1(this));
scenarios.emplace_back(new Stage2(this));
scenarios.emplace_back(new Stage3(this));
scenarios.emplace_back(new Stage4(this));
scenarios.emplace_back(new Stage5(this));
scenarios.emplace_back(new Stage6(this));
scenarios.emplace_back(new Stage7(this));
scenarios.emplace_back(new Stage8(this));
} }
void VirusAttack::InitializeSounds(){ void VirusAttack::InitializeSounds(){
int soundIndex=0; int soundIndex=0;
auto LoadSound=[&](Sound sound,std::string soundFilename){ auto LoadSound=[&](Sound sound,std::string soundFilename){
SOUNDS[sound]=std::make_unique<Audio>(); SOUNDS.emplace_back(std::make_unique<Audio>());
SOUNDS[sound]->AL=&AL; SOUNDS[int(sound)]->AL=&AL;
SOUNDS[sound]->LoadAudioSample(soundIndex,std::string("./assets/"+soundFilename).c_str()); SOUNDS[int(sound)]->LoadAudioSample(soundIndex,std::string("./assets/"+soundFilename).c_str());
soundIndex++; soundIndex++;
}; };
@ -372,7 +365,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,GetTotalUsedMemory(),currentLevel->availableMemory); u->UpdateGUIState(gametv,player_resources,memoryAllocatorBox,memoryAllocatorBoxHovered,GetTotalUsedMemory(),currentLevel->availableMemory);
if(u->IsSelected()){ if(u->IsSelected()){
if(u->IsAllocator()){ if(u->IsAllocator()){
allocatorSelected=true; allocatorSelected=true;
@ -388,7 +381,7 @@ void VirusAttack::HandleDraggingSelection(){
if(GetMouse(0).bPressed){ if(GetMouse(0).bPressed){
if(NotClickingOnMinimap()){ if(NotClickingOnMinimap()){
for(auto&u:units){ for(auto&u:units){
if(u->ClickHandled(game,player_resources,units,IMAGES)){ if(u->ClickHandled(gametv,player_resources,units,IMAGES)){
goto skipLeftClick; //Break out early because this instance reported it handled a click for us. goto skipLeftClick; //Break out early because this instance reported it handled a click for us.
} }
} }
@ -421,12 +414,12 @@ void VirusAttack::HandleDraggingSelection(){
} }
vf2d VirusAttack::GetWorldMousePos(){ vf2d VirusAttack::GetWorldMousePos(){
return game.ScreenToWorld(GetMousePos()); return gametv.ScreenToWorld(GetMousePos());
} }
void VirusAttack::DrawSelectionRectangle(){ void VirusAttack::DrawSelectionRectangle(){
if(startingDragPos!=CONSTANT::UNSELECTED){ if(startingDragPos!=CONSTANT::UNSELECTED){
game.FillRectDecal(startingDragPos,GetWorldMousePos()-startingDragPos,{255,255,0,128}); gametv.FillRectDecal(startingDragPos,GetWorldMousePos()-startingDragPos,{255,255,0,128});
} }
} }
@ -437,7 +430,7 @@ void VirusAttack::HandleRightClickMove(){
for(auto&u:units){ for(auto&u:units){
if(u->IsFriendly()&&u->IsSelected()&&u->CanMove()){ if(u->IsFriendly()&&u->IsSelected()&&u->CanMove()){
vf2d minimapTL=GetScreenSize()-vf2d{64,64}; vf2d minimapTL=GetScreenSize()-vf2d{64,64};
vf2d minimapCenterClick=vf2d(GetMousePos()-minimapTL)/64*WORLD_SIZE*CONSTANT::TILE_SIZE-vf2d(GetScreenSize())/game.GetWorldScale()/2.f+vf2d(GetScreenSize()/2.f)/game.GetWorldScale(); vf2d minimapCenterClick=vf2d(GetMousePos()-minimapTL)/64*WORLD_SIZE*CONSTANT::TILE_SIZE-vf2d(GetScreenSize())/gametv.GetWorldScale()/2.f+vf2d(GetScreenSize()/2.f)/gametv.GetWorldScale();
u->SetTargetLocation(minimapCenterClick); u->SetTargetLocation(minimapCenterClick);
} }
} }
@ -522,7 +515,7 @@ void VirusAttack::DrawMinimap(){
vf2d viewingTilesPct=vf2d{float(ScreenWidth()),float(ScreenHeight())}/CONSTANT::TILE_SIZE/WORLD_SIZE; vf2d viewingTilesPct=vf2d{float(ScreenWidth()),float(ScreenHeight())}/CONSTANT::TILE_SIZE/WORLD_SIZE;
SetDrawTarget(IMAGES[MINIMAP_OUTLINE]->Sprite()); SetDrawTarget(IMAGES[MINIMAP_OUTLINE]->Sprite());
Clear(BLANK); Clear(BLANK);
DrawRect((game.GetWorldOffset()/worldPixelSize*64),viewingTilesPct*64/game.GetWorldScale()); DrawRect((gametv.GetWorldOffset()/worldPixelSize*64),viewingTilesPct*64/gametv.GetWorldScale());
for(auto&cp:collectionPoints){ for(auto&cp:collectionPoints){
Pixel col; Pixel col;
switch(cp->type){ switch(cp->type){
@ -559,33 +552,33 @@ void VirusAttack::DrawMinimap(){
} }
void VirusAttack::HandlePanAndZoom(float fElapsedTime){ void VirusAttack::HandlePanAndZoom(float fElapsedTime){
float speedScale=std::min(1.f,game.GetWorldScale().x); float speedScale=std::min(1.f,gametv.GetWorldScale().x);
bool canMouseScroll=!memoryAllocatorBox.IsVisible()&&!unitCreationBox.IsVisible()&& bool canMouseScroll=!memoryAllocatorBox.IsVisible()&&!unitCreationBox.IsVisible()&&
(GetMouseY()<=ScreenHeight()-64||GetMouseX()<=ScreenWidth()-64 (GetMouseY()<=ScreenHeight()-64||GetMouseX()<=ScreenWidth()-64
||GetMouseScreenX()>=GetWindowPos().x+GetWindowSize().x||GetMouseScreenY()>=GetWindowPos().y+GetWindowSize().y); ||GetMouseScreenX()>=GetWindowPos().x+GetWindowSize().x||GetMouseScreenY()>=GetWindowPos().y+GetWindowSize().y);
if(GetKey(A).bHeld||canMouseScroll&&GetMouseScreenX()<=GetWindowPos().x+CONSTANT::SCROLL_BOUNDARY){ if(GetKey(A).bHeld||canMouseScroll&&GetMouseScreenX()<=GetWindowPos().x+CONSTANT::SCROLL_BOUNDARY){
vf2d amt=vf2d{-300*fElapsedTime,0}/speedScale; vf2d amt=vf2d{-300*fElapsedTime,0}/speedScale;
game.MoveWorldOffset(amt); gametv.MoveWorldOffset(amt);
} }
if(GetKey(W).bHeld||canMouseScroll&&GetMouseScreenY()<=GetWindowPos().y+CONSTANT::SCROLL_BOUNDARY+24){ if(GetKey(W).bHeld||canMouseScroll&&GetMouseScreenY()<=GetWindowPos().y+CONSTANT::SCROLL_BOUNDARY+24){
game.MoveWorldOffset(vf2d{0,-300*fElapsedTime}/speedScale); gametv.MoveWorldOffset(vf2d{0,-300*fElapsedTime}/speedScale);
} }
if(GetKey(S).bHeld||canMouseScroll&&GetMouseScreenY()>=GetWindowPos().y+GetWindowSize().y-CONSTANT::SCROLL_BOUNDARY){ if(GetKey(S).bHeld||canMouseScroll&&GetMouseScreenY()>=GetWindowPos().y+GetWindowSize().y-CONSTANT::SCROLL_BOUNDARY){
game.MoveWorldOffset(vf2d{0,300*fElapsedTime}/speedScale); gametv.MoveWorldOffset(vf2d{0,300*fElapsedTime}/speedScale);
} }
if(GetKey(D).bHeld||canMouseScroll&&GetMouseScreenX()>=GetWindowPos().x+GetWindowSize().x-CONSTANT::SCROLL_BOUNDARY){ if(GetKey(D).bHeld||canMouseScroll&&GetMouseScreenX()>=GetWindowPos().x+GetWindowSize().x-CONSTANT::SCROLL_BOUNDARY){
vf2d amt=vf2d{300*fElapsedTime,0}/speedScale; vf2d amt=vf2d{300*fElapsedTime,0}/speedScale;
game.MoveWorldOffset(amt); gametv.MoveWorldOffset(amt);
} }
if(GetMouseWheel()>0){ if(GetMouseWheel()>0){
if(game.GetWorldScale().x<2){ if(gametv.GetWorldScale().x<2){
game.ZoomAtScreenPos(1.25,GetMousePos()); gametv.ZoomAtScreenPos(1.25,GetMousePos());
} }
} else } else
if(GetMouseWheel()<0){ if(GetMouseWheel()<0){
if(game.GetWorldScale().x>0.5){ if(gametv.GetWorldScale().x>0.5){
game.ZoomAtScreenPos(0.75,GetMousePos()); gametv.ZoomAtScreenPos(0.75,GetMousePos());
} }
} }
} }
@ -593,12 +586,12 @@ void VirusAttack::HandlePanAndZoom(float fElapsedTime){
void VirusAttack::HandleMinimapClick(){ void VirusAttack::HandleMinimapClick(){
if(startingDragPos==CONSTANT::UNSELECTED&&GetMouse(0).bHeld&&GetMouseX()>=ScreenWidth()-64&&GetMouseY()>=ScreenHeight()-64){ if(startingDragPos==CONSTANT::UNSELECTED&&GetMouse(0).bHeld&&GetMouseX()>=ScreenWidth()-64&&GetMouseY()>=ScreenHeight()-64){
vf2d minimapTL=GetScreenSize()-vf2d{64,64}; vf2d minimapTL=GetScreenSize()-vf2d{64,64};
game.SetWorldOffset(vf2d(GetMousePos()-minimapTL)/64*WORLD_SIZE*CONSTANT::TILE_SIZE-vf2d(GetScreenSize())/game.GetWorldScale()/2.f); gametv.SetWorldOffset(vf2d(GetMousePos()-minimapTL)/64*WORLD_SIZE*CONSTANT::TILE_SIZE-vf2d(GetScreenSize())/gametv.GetWorldScale()/2.f);
} }
vf2d offset=game.GetWorldOffset(); vf2d offset=gametv.GetWorldOffset();
offset.x=std::clamp(float(offset.x),-ScreenWidth()/2/game.GetWorldScale().x,WORLD_SIZE.x*24-(ScreenWidth()/2/game.GetWorldScale().x)); offset.x=std::clamp(float(offset.x),-ScreenWidth()/2/gametv.GetWorldScale().x,WORLD_SIZE.x*24-(ScreenWidth()/2/gametv.GetWorldScale().x));
offset.y=std::clamp(float(offset.y),-ScreenHeight()/2/game.GetWorldScale().y,WORLD_SIZE.y*24-(ScreenHeight()/2/game.GetWorldScale().y)); offset.y=std::clamp(float(offset.y),-ScreenHeight()/2/gametv.GetWorldScale().y,WORLD_SIZE.y*24-(ScreenHeight()/2/gametv.GetWorldScale().y));
game.SetWorldOffset(offset); gametv.SetWorldOffset(offset);
} }
@ -655,7 +648,7 @@ void VirusAttack::UpdateMatrixTexture(float fElapsedTime){
void VirusAttack::RenderCollectionPoints(CollectionPoint*cp){ void VirusAttack::RenderCollectionPoints(CollectionPoint*cp){
geom2d::rect<float>cpRect=geom2d::rect<float>({cp->pos-cp->img.Sprite()->Size()/2,cp->img.Sprite()->Size()}); geom2d::rect<float>cpRect=geom2d::rect<float>({cp->pos-cp->img.Sprite()->Size()/2,cp->img.Sprite()->Size()});
geom2d::rect<float>viewRegion=geom2d::rect<float>({game.GetWorldTL(),game.GetWorldVisibleArea()}); geom2d::rect<float>viewRegion=geom2d::rect<float>({gametv.GetWorldTL(),gametv.GetWorldVisibleArea()});
if(geom2d::overlaps(cpRect,viewRegion)){ if(geom2d::overlaps(cpRect,viewRegion)){
Pixel col; Pixel col;
switch(cp->type){ switch(cp->type){
@ -675,9 +668,9 @@ void VirusAttack::RenderCollectionPoints(CollectionPoint*cp){
col=CONSTANT::PROCEDURE_COLOR; col=CONSTANT::PROCEDURE_COLOR;
}break; }break;
} }
game.DrawRotatedDecal(cp->pos,cp->img.Decal(),cp->rot,cp->img.Sprite()->Size()/2,{1,1},col); gametv.DrawRotatedDecal(cp->pos,cp->img.Decal(),cp->rot,cp->img.Sprite()->Size()/2,{1,1},col);
if(geom2d::overlaps(cpRect,GetWorldMousePos())){ if(geom2d::overlaps(cpRect,GetWorldMousePos())){
game.DrawRotatedDecal(cp->pos,IMAGES[MEMORY_COLLECTION_POINT_HIGHLIGHT]->Decal(),cp->rot,cp->img.Sprite()->Size()/2,{1,1},col); gametv.DrawRotatedDecal(cp->pos,IMAGES[MEMORY_COLLECTION_POINT_HIGHLIGHT]->Decal(),cp->rot,cp->img.Sprite()->Size()/2,{1,1},col);
} }
} }
} }
@ -708,7 +701,7 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
textOrientationX=std::max(0.f,textOrientationX-fElapsedTime*50); textOrientationX=std::max(0.f,textOrientationX-fElapsedTime*50);
textOrientationY=std::max(0.f,textOrientationY-fElapsedTime*25); textOrientationY=std::max(0.f,textOrientationY-fElapsedTime*25);
} }
DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+game.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*game.GetWorldScale(),{32,32},PixelLerp(Pixel{currentBackCol.r,currentBackCol.g,currentBackCol.b,255},Pixel{newCol.r,newCol.g,newCol.b,255},transition)); DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+gametv.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*gametv.GetWorldScale(),{32,32},PixelLerp(Pixel{currentBackCol.r,currentBackCol.g,currentBackCol.b,255},Pixel{newCol.r,newCol.g,newCol.b,255},transition));
vf2d setPieceOffset={48,titleScreenY}; vf2d setPieceOffset={48,titleScreenY};
{ {
@ -779,9 +772,8 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
restartManager.Update(this); restartManager.Update(this);
HandleRestartButton(fElapsedTime); HandleRestartButton(fElapsedTime);
PerformLevelTransition(fElapsedTime); PerformLevelTransition(fElapsedTime);
currentLevel->scenario->_Update(); AL.vecPos=gametv.ScreenToWorld(GetScreenSize()/2);
AL.vecPos=game.ScreenToWorld(GetScreenSize()/2); AL.fSoundFXVolume=std::min(1.f,gametv.GetWorldScale().x);
AL.fSoundFXVolume=std::min(1.f,game.GetWorldScale().x);
AL.OnUserUpdate(fElapsedTime); AL.OnUserUpdate(fElapsedTime);
for(auto&tile:TileManager::visibleTiles){ for(auto&tile:TileManager::visibleTiles){
@ -828,22 +820,22 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
queuedUnits.clear(); queuedUnits.clear();
DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+game.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*game.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,164}/2); DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+gametv.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*gametv.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,164}/2);
game.DrawPartialDecal({0,0},WORLD_SIZE*CONSTANT::TILE_SIZE,IMAGES[TILE]->Decal(),{0,0},WORLD_SIZE*CONSTANT::TILE_SIZE,currentLevel->levelColor); gametv.DrawPartialDecal({0,0},WORLD_SIZE*CONSTANT::TILE_SIZE,IMAGES[TILE]->Decal(),{0,0},WORLD_SIZE*CONSTANT::TILE_SIZE,currentLevel->levelColor);
for(auto&u:units){ for(auto&u:units){
u->DrawRangeIndicator(this,game,IMAGES); u->DrawRangeIndicator(this,gametv,IMAGES);
} }
for(auto&u:units){ for(auto&u:units){
u->Draw(game,IMAGES); u->Draw(gametv,IMAGES);
if(u->IsGuarded()){ if(u->IsGuarded()){
game.DrawDecal(u->GetPos()+vf2d{float(u->GetUnitSize().x/2),-float(u->GetUnitSize().y/2)}-vf2d{float(IMAGES[GUARD_ICON]->Sprite()->width),0.f}*0.375,IMAGES[GUARD_ICON]->Decal(),{0.375,0.375}); gametv.DrawDecal(u->GetPos()+vf2d{float(u->GetUnitSize().x/2),-float(u->GetUnitSize().y/2)}-vf2d{float(IMAGES[GUARD_ICON]->Sprite()->width),0.f}*0.375,IMAGES[GUARD_ICON]->Decal(),{0.375,0.375});
} }
} }
for(auto&deadUnit:deathAnimations){ for(auto&deadUnit:deathAnimations){
deadUnit->Update(fElapsedTime); deadUnit->Update(fElapsedTime);
deadUnit->Draw(game,this); deadUnit->Draw(gametv,this);
} }
std::erase_if(deathAnimations,[](auto&u){return u->IsDone();}); std::erase_if(deathAnimations,[](auto&u){return u->IsDone();});
@ -854,24 +846,24 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
} }
for(auto&u:units){ for(auto&u:units){
u->DrawUnitDamageStats(this,game,IMAGES); u->DrawUnitDamageStats(this,gametv,IMAGES);
} }
for(DebuffIcon&icon:debuffIcons){ for(DebuffIcon&icon:debuffIcons){
icon.Update(fElapsedTime); icon.Update(fElapsedTime);
icon.Draw(game); icon.Draw(gametv);
} }
for(ResourceGainIcon&icon:resourceGainIcons){ for(ResourceGainIcon&icon:resourceGainIcons){
icon.Update(fElapsedTime); icon.Update(fElapsedTime);
icon.Draw(game); icon.Draw(gametv);
} }
std::erase_if(debuffIcons,[](DebuffIcon&icon){return icon.lifetime<=0;}); std::erase_if(debuffIcons,[](DebuffIcon&icon){return icon.lifetime<=0;});
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(game,IMAGES,unitMetersGreyedOut); u->_DrawHud(gametv,IMAGES,unitMetersGreyedOut);
} }
DrawSelectionRectangle(); DrawSelectionRectangle();
@ -887,7 +879,6 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
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();
currentLevel->scenario->_Draw();
unitCreationBox.UpdateAndDraw(GetMousePos()+vi2d{8,-28},this,player_resources,IMAGES,GetTotalUsedMemory(),currentLevel->availableMemory); unitCreationBox.UpdateAndDraw(GetMousePos()+vi2d{8,-28},this,player_resources,IMAGES,GetTotalUsedMemory(),currentLevel->availableMemory);
testBox.UpdateAndDraw(GetMousePos()-testBox.GetSize()/2,this,player_resources,IMAGES,GetTotalUsedMemory(),currentLevel->availableMemory); testBox.UpdateAndDraw(GetMousePos()-testBox.GetSize()/2,this,player_resources,IMAGES,GetTotalUsedMemory(),currentLevel->availableMemory);
@ -916,17 +907,17 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
} }
} }
DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+game.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*game.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,uint8_t(levelForegroundFade*255)}/2); DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+gametv.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*gametv.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,uint8_t(levelForegroundFade*255)}/2);
}break; }break;
#pragma endregion #pragma endregion
#pragma region COMPLETED #pragma region COMPLETED
case GameState::COMPLETED:{ case GameState::COMPLETED:{
DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+game.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*game.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,164}/2); DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+gametv.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*gametv.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,164}/2);
}break; }break;
#pragma endregion #pragma endregion
#pragma region CREDITS #pragma region CREDITS
case GameState::CREDITS:{ case GameState::CREDITS:{
DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+game.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*game.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,164}/2); DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+gametv.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*gametv.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,164}/2);
}break; }break;
#pragma endregion #pragma endregion
} }
@ -1076,11 +1067,11 @@ void VirusAttack::DrawResourceBar(float fElapsedTime){
} }
void VirusAttack::RenderFogOfWar(){ void VirusAttack::RenderFogOfWar(){
for(int y=game.GetTopLeftTile().y/96-1;y<=game.GetBottomRightTile().y/96+1;y++){ for(int y=gametv.GetTopLeftTile().y/96-1;y<=gametv.GetBottomRightTile().y/96+1;y++){
for(int x=game.GetTopLeftTile().x/96-1;x<=game.GetBottomRightTile().x/96+1;x++){ for(int x=gametv.GetTopLeftTile().x/96-1;x<=gametv.GetBottomRightTile().x/96+1;x++){
if(TileManager::visibleTiles.count(vi2d{x,y})==0){ if(TileManager::visibleTiles.count(vi2d{x,y})==0){
if(x>=0&&y>=0&&x<WORLD_SIZE.x/4&&y<WORLD_SIZE.y/4){ if(x>=0&&y>=0&&x<WORLD_SIZE.x/4&&y<WORLD_SIZE.y/4){
game.FillRectDecal(vf2d{float(x),float(y)}*96,{96,96},{0,0,0,128}); gametv.FillRectDecal(vf2d{float(x),float(y)}*96,{96,96},{0,0,0,128});
} }
} }
} }

@ -18,8 +18,6 @@
#include "Level.h" #include "Level.h"
#include "GameState.h" #include "GameState.h"
class Scenario;
struct Letter{ struct Letter{
vf2d pos; vf2d pos;
float spd; float spd;
@ -51,15 +49,12 @@ private:
std::vector<ResourceGainIcon>resourceGainIcons; std::vector<ResourceGainIcon>resourceGainIcons;
std::vector<Scenario*>scenarios; std::vector<Scenario*>scenarios;
std::map<Image,std::unique_ptr<Renderable>>IMAGES;
std::map<Sound,std::unique_ptr<Audio>>SOUNDS;
olcPGEX_AudioListener AL; olcPGEX_AudioListener AL;
Audio*bgm=nullptr; Audio*bgm=nullptr;
Resources player_resources,player_prev_resources,player_display_resources,enemy_resources; Resources player_resources,player_prev_resources,player_display_resources,enemy_resources;
TileTransformedView game; TileTransformedView gametv;
Textbox unitCreationBox,testBox,memoryAllocatorBox,platformCreationBox,restartBox; Textbox unitCreationBox,testBox,memoryAllocatorBox,platformCreationBox,restartBox;
Level*currentLevel; Level*currentLevel;

@ -1,2 +1,2 @@
~\Documents\emsdk\emsdk_env.ps1 activate latest ~\Documents\emsdk\emsdk_env.ps1 activate latest
em++ -std=c++20 -s ALLOW_MEMORY_GROWTH=1 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_LIBPNG=1 -s USE_SDL_MIXER=2 -sSTACK_SIZE=5MB $(Get-ChildItem *.cpp) soloud.o -o pge.html --preload-file assets em++ -std=c++20 -O2 -s ALLOW_MEMORY_GROWTH=1 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_LIBPNG=1 -s USE_SDL_MIXER=2 -sSTACK_SIZE=10MB $(Get-ChildItem *.cpp) soloud.o -o pge.html --preload-file assets

@ -83,6 +83,8 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>soloud_static.lib;sdl2.lib;sdl2main.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>soloud_static.lib;sdl2.lib;sdl2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
<StackReserveSize>2000000</StackReserveSize>
<HeapReserveSize>2000000</HeapReserveSize>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -102,6 +104,8 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>soloud_static.lib;sdl2.lib;sdl2main.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>soloud_static.lib;sdl2.lib;sdl2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
<StackReserveSize>2000000</StackReserveSize>
<HeapReserveSize>2000000</HeapReserveSize>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -117,6 +121,8 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>soloud_static.lib;sdl2.lib;sdl2main.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>soloud_static.lib;sdl2.lib;sdl2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
<StackReserveSize>2000000</StackReserveSize>
<HeapReserveSize>2000000</HeapReserveSize>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -136,6 +142,8 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>soloud_static.lib;sdl2.lib;sdl2main.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>soloud_static.lib;sdl2.lib;sdl2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
<StackReserveSize>2000000</StackReserveSize>
<HeapReserveSize>2000000</HeapReserveSize>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>

@ -68,7 +68,7 @@ class olcPGEX_AudioSource : public olc::PGEX
{ {
public: public:
// Pointer to the Audio Listener for this object // Pointer to the Audio Listener for this object
olcPGEX_AudioListener* AL; olcPGEX_AudioListener* AL=nullptr;
// Handle for this particular copy of the sound // Handle for this particular copy of the sound
int handle = 255; int handle = 255;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 MiB

After

Width:  |  Height:  |  Size: 23 MiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.
Loading…
Cancel
Save