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 "MemoryType.h"
class Unit;
struct Unit;
class CollectionPoint{
public:

@ -40,7 +40,6 @@ struct Level{
std::vector<UnitData>unitPlacement;
std::vector<CPData>cpPlacement;
Sound bgm=Sound::COSMOS;
Scenario*scenario;
vf2d cameraStart={96,96};
vf2d worldZoom={1,1};
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
enum class Sound{
enum class Sound:int{
HUM,
GRAVITY,
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){
geom2d::rect<float>boundingRect={pos-vf2d{3,3},maxSize+vf2d{6,6}};
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);
Update(pge);
Draw(pge,resources,IMAGES,totalUsedMemory,memoryLimit);

@ -9,8 +9,8 @@ class Textbox{
std::string displayHeaderText="";
std::string text="";
std::string displayText="";
Renderable*boxImg;
Audio*dialogSound;
Renderable*boxImg=nullptr;
Audio*dialogSound=nullptr;
int soundHandle=-1;
float audioFadeOutDelay=2;
vf2d pos={};
@ -31,7 +31,7 @@ public:
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 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();
void SetVisible(bool visible);
vf2d GetSize();
@ -41,6 +41,6 @@ public:
private:
void Update(PixelGameEngine*pge);
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();
};

@ -6,10 +6,12 @@
#include "olcPGEX_QuickGUI.h"
#include "Textbox.h"
Unit::~Unit(){};
std::string LeftShifter::unitName="Left Shifter";
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}};
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){}
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::unitDescription="Shifts target memory 1 bit to the right.";
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){}
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::unitDescription="Randomly restores 1 missing bit to a target.";
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){}
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::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}};
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){
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::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}};
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){}
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::unitDescription="A unit that builds other units.";
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){
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()){
SetTargetLocation(CONSTANT::UNSELECTED);
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()){
game.GetPGE()->SetDrawTarget(img.Sprite());
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::unitDescription="Allows for the construction of Memory Allocators.";
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
,false,false
),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());
for(int y=0;y<img.Sprite()->height;y++){
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){
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();
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()){
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());
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);
}
}
void RAMBank::OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS){
SOUNDS[Sound::HUM]->Stop(soundHandle);
void RAMBank::OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS){
SOUNDS[int(Sound::HUM)]->Stop(soundHandle);
}
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);
}
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){
//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){
@ -286,14 +288,14 @@ bool RAMBank::ClickHandled(TileTransformedView&game,Resources&player_resources,s
std::string _Platform::unitName="Platform";
std::string _Platform::unitDescription="Anchored to the ground, this unit is an intermediate step for larger units.";
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){
isPlatform=true;
}
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()){
SetTargetLocation(CONSTANT::UNSELECTED);
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()){
game.GetPGE()->SetDrawTarget(img.Sprite());
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::unitDescription="Repairs missing bits to surrounding units.";
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
,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::unitDescription="Automatically targets attack and movement speed memory ranges before others.";
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){}
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::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}};
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
,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);
}
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;
float dist=geom2d::line<float>(game.ScreenToWorld(pge->GetMousePos()),GetGhostPos()).length();
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());
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);
}
}
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);
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;
@ -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()){
geom2d::line<float>lineToTarget(pos,target.lock()->pos);
lineToTarget.start=lineToTarget.rpoint(GetUnitSize().x/2);
@ -608,7 +610,7 @@ int Unit::GetBits(Marker&m){
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(){
return GetBits(health);
@ -640,7 +642,7 @@ void Unit::_RunAI(PixelGameEngine*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()){
auto ptrTarget=target.lock();
if(!InRange(ptrTarget)&&CanMove()){
@ -789,7 +791,7 @@ void Unit::SetPos(vf2d 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;
std::weak_ptr<Unit>finalTarget;
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){}
@ -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;
};

@ -41,6 +41,7 @@ struct Memory{
struct Unit{
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);
virtual~Unit();
int GetHealth();
int GetRange();
int GetAtkSpd();
@ -50,12 +51,12 @@ public:
std::vector<bool>memory;
std::vector<bool>ghostMemory;
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 Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES);
virtual void DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES);
void _DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool unitMetersGreyedOut);
virtual void OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS);
virtual void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES);
virtual void DrawHud(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES);
void _DrawHud(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool unitMetersGreyedOut);
virtual void OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS);
bool IsFriendly();
bool IsSelected();
void Select();
@ -66,14 +67,14 @@ public:
void SetTargetUnit(std::weak_ptr<Unit>target);
void SetTargetLocation(vf2d targetLoc);
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 GhostInFogOfWar();
void HideGhost();
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();
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 CanInteractWithAllies();
Renderable&GetImage();
@ -82,13 +83,13 @@ public:
virtual void Attacked(std::weak_ptr<Unit>attacker);
void _Attacked(std::weak_ptr<Unit>attacker);
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 CanMove();
void SetTargetCollectionPoint(std::weak_ptr<CollectionPoint>targetCP,std::weak_ptr<Unit>self_ptr);
Pixel GetUnitColor();
virtual void UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered,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();
void SetBuildUnit(float buildTime,std::unique_ptr<Unit>finalUnit);
bool IsBuilding();
@ -163,7 +164,7 @@ private:
};
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;
static std::vector<Memory> resourceCost;
static std::string unitName;
@ -171,7 +172,7 @@ struct LeftShifter: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;
static std::vector<Memory> resourceCost;
static std::string unitName;
@ -179,7 +180,7 @@ struct RightShifter: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 AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&otherUnits);
static std::vector<Memory> resourceCost;
@ -188,7 +189,7 @@ struct BitRestorer: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;
static std::vector<Memory> resourceCost;
static std::string unitName;
@ -196,7 +197,7 @@ struct MemorySwapper: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;
static std::vector<Memory> resourceCost;
static std::string unitName;
@ -204,10 +205,10 @@ struct Corrupter: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 Update(PixelGameEngine*pge,std::map<Sound,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 Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::unique_ptr<Unit>>&queuedUnits)override;
void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override;
static std::vector<Memory> resourceCost;
static std::string unitName;
static std::string unitDescription;
@ -219,34 +220,34 @@ struct RAMBank:Unit{
Renderable&originalImg;
Renderable&matrixImg;
bool soundStarted=false;
int soundHandle;
int soundHandle=-1;
QuickGUI::Manager allocatorManager;
QuickGUI::ImageButton*allocatorButton;
RAMBank(PixelGameEngine*pge,vf2d pos,std::map<Image,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;
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 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 OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS)override;
bool ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector<std::shared_ptr<Unit>>&units,std::map<Image,std::unique_ptr<Renderable>>&IMAGES)override;
void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)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::vector<std::unique_ptr<Renderable>>&IMAGES)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::string unitName;
static std::string unitDescription;
};
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 Update(PixelGameEngine*pge,std::map<Sound,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 Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::unique_ptr<Unit>>&queuedUnits)override;
void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override;
static std::vector<Memory> resourceCost;
static std::string unitName;
static std::string unitDescription;
};
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;
static std::vector<Memory> resourceCost;
static std::string unitName;
@ -254,7 +255,7 @@ struct MemoryGuard: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;
static std::vector<Memory> resourceCost;
static std::string unitName;
@ -262,7 +263,7 @@ struct Refresher: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;
static std::vector<Memory> resourceCost;
static std::string unitName;

@ -9,28 +9,39 @@
#ifdef SPLASH_ENABLED
#define OLC_PGEX_SPLASHSCREEN
#endif
#include "olcUTIL_Geometry2D.h"
#include "Scenario.h"
#include "TileManager.h"
#include "olcUTIL_Geometry2D.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()
{
// Name your application
sAppName = "Virus Attack";
game=this;
}
void VirusAttack::InitializeImages(){
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);
};
LoadImage(TILE,"assets/tile.png",false,false);
LoadImage(MINIMAP_HUD,"assets/minimap_hud.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(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(LEFT_SHIFTER,"assets/left_shifter.png");
LoadImage(RIGHT_SHIFTER,"assets/right_shifter.png");
@ -88,7 +99,6 @@ void VirusAttack::InitializeLevelData(){
levelData[stage].name=stage;
levelData[stage].cameraStart={96,96};
levelData[stage].worldZoom={1,1};
levelData[stage].scenario=scenarios[0];
levelData[stage].levelColor=DARK_RED;
levelData[stage].size={24,24};
levelData[stage].bgm=Sound::GRAVITY;
@ -112,7 +122,6 @@ void VirusAttack::InitializeLevelData(){
levelData[stage].cameraStart={96,96};
levelData[stage].worldZoom={1,1};
levelData[stage].size={16,16};
levelData[stage].scenario=scenarios[1];
levelData[stage].levelColor=DARK_GREEN;
levelData[stage].bgm=Sound::GRAVITY;
levelData[stage].player_starting_resources={10,10,10,10,10};
@ -134,7 +143,7 @@ bool VirusAttack::OnUserCreate(){
currentBackCol=newCol=colorChangeOptions[rand()%colorChangeOptions.size()];
SetPixelMode(Pixel::MASK);
game.Initialise(GetScreenSize());
gametv.Initialise(GetScreenSize());
InitializeImages();
@ -148,13 +157,6 @@ bool VirusAttack::OnUserCreate(){
platformCreationBox.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);
AL.AudioSystemInit();
@ -165,7 +167,6 @@ bool VirusAttack::OnUserCreate(){
InitializeLevelData();
LoadLevel(STAGE1);
currentLevel->scenario->Start();
return true;
}
@ -176,16 +177,16 @@ void VirusAttack::LoadLevel(LevelName level){
WORLD_SIZE=selectedLevel.size;
game.SetWorldScale(selectedLevel.worldZoom);
game.SetWorldOffset(selectedLevel.cameraStart-vf2d(GetScreenSize())/2.f/game.GetWorldScale());
gametv.SetWorldScale(selectedLevel.worldZoom);
gametv.SetWorldOffset(selectedLevel.cameraStart-vf2d(GetScreenSize())/2.f/gametv.GetWorldScale());
if(bgm==nullptr){
bgm=SOUNDS[selectedLevel.bgm].get();
bgm=SOUNDS[int(selectedLevel.bgm)].get();
bgm->PlayCentered(1,1,true);
} else
if(bgm!=SOUNDS[selectedLevel.bgm].get()){
if(bgm!=SOUNDS[int(selectedLevel.bgm)].get()){
bgm->Stop();
bgm=SOUNDS[selectedLevel.bgm].get();
bgm=SOUNDS[int(selectedLevel.bgm)].get();
bgm->PlayCentered(1,1,true);
}
player_resources=selectedLevel.player_starting_resources;
@ -201,7 +202,7 @@ void VirusAttack::LoadLevel(LevelName level){
for(auto&u:selectedLevel.unitPlacement){
#define TranslateUnit(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;
switch(u.type){
@ -223,7 +224,7 @@ void VirusAttack::LoadLevel(LevelName level){
}
}
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)};
@ -264,22 +265,14 @@ void VirusAttack::InitializeGUIs(){
}
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(){
int soundIndex=0;
auto LoadSound=[&](Sound sound,std::string soundFilename){
SOUNDS[sound]=std::make_unique<Audio>();
SOUNDS[sound]->AL=&AL;
SOUNDS[sound]->LoadAudioSample(soundIndex,std::string("./assets/"+soundFilename).c_str());
SOUNDS.emplace_back(std::make_unique<Audio>());
SOUNDS[int(sound)]->AL=&AL;
SOUNDS[int(sound)]->LoadAudioSample(soundIndex,std::string("./assets/"+soundFilename).c_str());
soundIndex++;
};
@ -372,7 +365,7 @@ void VirusAttack::HandleDraggingSelection(){
bool platformSelected=false;
bool memoryAllocatorBoxHovered=false;
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->IsAllocator()){
allocatorSelected=true;
@ -388,7 +381,7 @@ void VirusAttack::HandleDraggingSelection(){
if(GetMouse(0).bPressed){
if(NotClickingOnMinimap()){
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.
}
}
@ -421,12 +414,12 @@ void VirusAttack::HandleDraggingSelection(){
}
vf2d VirusAttack::GetWorldMousePos(){
return game.ScreenToWorld(GetMousePos());
return gametv.ScreenToWorld(GetMousePos());
}
void VirusAttack::DrawSelectionRectangle(){
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){
if(u->IsFriendly()&&u->IsSelected()&&u->CanMove()){
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);
}
}
@ -522,7 +515,7 @@ void VirusAttack::DrawMinimap(){
vf2d viewingTilesPct=vf2d{float(ScreenWidth()),float(ScreenHeight())}/CONSTANT::TILE_SIZE/WORLD_SIZE;
SetDrawTarget(IMAGES[MINIMAP_OUTLINE]->Sprite());
Clear(BLANK);
DrawRect((game.GetWorldOffset()/worldPixelSize*64),viewingTilesPct*64/game.GetWorldScale());
DrawRect((gametv.GetWorldOffset()/worldPixelSize*64),viewingTilesPct*64/gametv.GetWorldScale());
for(auto&cp:collectionPoints){
Pixel col;
switch(cp->type){
@ -559,33 +552,33 @@ void VirusAttack::DrawMinimap(){
}
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()&&
(GetMouseY()<=ScreenHeight()-64||GetMouseX()<=ScreenWidth()-64
||GetMouseScreenX()>=GetWindowPos().x+GetWindowSize().x||GetMouseScreenY()>=GetWindowPos().y+GetWindowSize().y);
if(GetKey(A).bHeld||canMouseScroll&&GetMouseScreenX()<=GetWindowPos().x+CONSTANT::SCROLL_BOUNDARY){
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){
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){
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){
vf2d amt=vf2d{300*fElapsedTime,0}/speedScale;
game.MoveWorldOffset(amt);
gametv.MoveWorldOffset(amt);
}
if(GetMouseWheel()>0){
if(game.GetWorldScale().x<2){
game.ZoomAtScreenPos(1.25,GetMousePos());
if(gametv.GetWorldScale().x<2){
gametv.ZoomAtScreenPos(1.25,GetMousePos());
}
} else
if(GetMouseWheel()<0){
if(game.GetWorldScale().x>0.5){
game.ZoomAtScreenPos(0.75,GetMousePos());
if(gametv.GetWorldScale().x>0.5){
gametv.ZoomAtScreenPos(0.75,GetMousePos());
}
}
}
@ -593,12 +586,12 @@ void VirusAttack::HandlePanAndZoom(float fElapsedTime){
void VirusAttack::HandleMinimapClick(){
if(startingDragPos==CONSTANT::UNSELECTED&&GetMouse(0).bHeld&&GetMouseX()>=ScreenWidth()-64&&GetMouseY()>=ScreenHeight()-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();
offset.x=std::clamp(float(offset.x),-ScreenWidth()/2/game.GetWorldScale().x,WORLD_SIZE.x*24-(ScreenWidth()/2/game.GetWorldScale().x));
offset.y=std::clamp(float(offset.y),-ScreenHeight()/2/game.GetWorldScale().y,WORLD_SIZE.y*24-(ScreenHeight()/2/game.GetWorldScale().y));
game.SetWorldOffset(offset);
vf2d offset=gametv.GetWorldOffset();
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/gametv.GetWorldScale().y,WORLD_SIZE.y*24-(ScreenHeight()/2/gametv.GetWorldScale().y));
gametv.SetWorldOffset(offset);
}
@ -655,7 +648,7 @@ void VirusAttack::UpdateMatrixTexture(float fElapsedTime){
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>viewRegion=geom2d::rect<float>({game.GetWorldTL(),game.GetWorldVisibleArea()});
geom2d::rect<float>viewRegion=geom2d::rect<float>({gametv.GetWorldTL(),gametv.GetWorldVisibleArea()});
if(geom2d::overlaps(cpRect,viewRegion)){
Pixel col;
switch(cp->type){
@ -675,9 +668,9 @@ void VirusAttack::RenderCollectionPoints(CollectionPoint*cp){
col=CONSTANT::PROCEDURE_COLOR;
}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())){
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);
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};
{
@ -779,9 +772,8 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
restartManager.Update(this);
HandleRestartButton(fElapsedTime);
PerformLevelTransition(fElapsedTime);
currentLevel->scenario->_Update();
AL.vecPos=game.ScreenToWorld(GetScreenSize()/2);
AL.fSoundFXVolume=std::min(1.f,game.GetWorldScale().x);
AL.vecPos=gametv.ScreenToWorld(GetScreenSize()/2);
AL.fSoundFXVolume=std::min(1.f,gametv.GetWorldScale().x);
AL.OnUserUpdate(fElapsedTime);
for(auto&tile:TileManager::visibleTiles){
@ -828,22 +820,22 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
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);
game.DrawPartialDecal({0,0},WORLD_SIZE*CONSTANT::TILE_SIZE,IMAGES[TILE]->Decal(),{0,0},WORLD_SIZE*CONSTANT::TILE_SIZE,currentLevel->levelColor);
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);
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){
u->DrawRangeIndicator(this,game,IMAGES);
u->DrawRangeIndicator(this,gametv,IMAGES);
}
for(auto&u:units){
u->Draw(game,IMAGES);
u->Draw(gametv,IMAGES);
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){
deadUnit->Update(fElapsedTime);
deadUnit->Draw(game,this);
deadUnit->Draw(gametv,this);
}
std::erase_if(deathAnimations,[](auto&u){return u->IsDone();});
@ -854,24 +846,24 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
}
for(auto&u:units){
u->DrawUnitDamageStats(this,game,IMAGES);
u->DrawUnitDamageStats(this,gametv,IMAGES);
}
for(DebuffIcon&icon:debuffIcons){
icon.Update(fElapsedTime);
icon.Draw(game);
icon.Draw(gametv);
}
for(ResourceGainIcon&icon:resourceGainIcons){
icon.Update(fElapsedTime);
icon.Draw(game);
icon.Draw(gametv);
}
std::erase_if(debuffIcons,[](DebuffIcon&icon){return icon.lifetime<=0;});
std::erase_if(resourceGainIcons,[](ResourceGainIcon&icon){return icon.lifetime<=0;});
for(auto&u:units){
u->_DrawHud(game,IMAGES,unitMetersGreyedOut);
u->_DrawHud(gametv,IMAGES,unitMetersGreyedOut);
}
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});
}
DrawMinimap();
currentLevel->scenario->_Draw();
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);
@ -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;
#pragma endregion
#pragma region 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;
#pragma endregion
#pragma region 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;
#pragma endregion
}
@ -1076,11 +1067,11 @@ void VirusAttack::DrawResourceBar(float fElapsedTime){
}
void VirusAttack::RenderFogOfWar(){
for(int y=game.GetTopLeftTile().y/96-1;y<=game.GetBottomRightTile().y/96+1;y++){
for(int x=game.GetTopLeftTile().x/96-1;x<=game.GetBottomRightTile().x/96+1;x++){
for(int y=gametv.GetTopLeftTile().y/96-1;y<=gametv.GetBottomRightTile().y/96+1;y++){
for(int x=gametv.GetTopLeftTile().x/96-1;x<=gametv.GetBottomRightTile().x/96+1;x++){
if(TileManager::visibleTiles.count(vi2d{x,y})==0){
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 "GameState.h"
class Scenario;
struct Letter{
vf2d pos;
float spd;
@ -51,15 +49,12 @@ private:
std::vector<ResourceGainIcon>resourceGainIcons;
std::vector<Scenario*>scenarios;
std::map<Image,std::unique_ptr<Renderable>>IMAGES;
std::map<Sound,std::unique_ptr<Audio>>SOUNDS;
olcPGEX_AudioListener AL;
Audio*bgm=nullptr;
Resources player_resources,player_prev_resources,player_display_resources,enemy_resources;
TileTransformedView game;
TileTransformedView gametv;
Textbox unitCreationBox,testBox,memoryAllocatorBox,platformCreationBox,restartBox;
Level*currentLevel;

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

@ -68,7 +68,7 @@ class olcPGEX_AudioSource : public olc::PGEX
{
public:
// Pointer to the Audio Listener for this object
olcPGEX_AudioListener* AL;
olcPGEX_AudioListener* AL=nullptr;
// Handle for this particular copy of the sound
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