Add in sound effects.

master
sigonasr2 1 year ago
parent bb33e8a8cd
commit 10bbb07894
  1. 2
      olcCodeJam2023Entry/GameFlags.h
  2. 88
      olcCodeJam2023Entry/Scenario.cpp
  3. 1
      olcCodeJam2023Entry/Scenario.h
  4. 12
      olcCodeJam2023Entry/Sound.h
  5. 2
      olcCodeJam2023Entry/Textbox.cpp
  6. 87
      olcCodeJam2023Entry/Unit.cpp
  7. 45
      olcCodeJam2023Entry/Unit.h
  8. 72
      olcCodeJam2023Entry/VirusAttack.cpp
  9. BIN
      olcCodeJam2023Entry/pge.data
  10. 2
      olcCodeJam2023Entry/pge.js
  11. BIN
      olcCodeJam2023Entry/pge.wasm

@ -4,6 +4,6 @@ struct GameFlags{
bool unitMetersGreyedOut=true;//If true, all but health meters show up as dark grey. bool unitMetersGreyedOut=true;//If true, all but health meters show up as dark grey.
bool playerInControl=false; bool playerInControl=false;
bool limitedBuildOptions=false; bool limitedBuildOptions=false;
bool guideEnabled=true; bool guideEnabled=false;
bool flashMemoryBar=false; bool flashMemoryBar=false;
}; };

@ -160,18 +160,20 @@ Stage2::Stage2(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_
void Stage2::Start(){ void Stage2::Start(){
flags.playerInControl=false; flags.playerInControl=false;
flags.limitedBuildOptions=true; flags.limitedBuildOptions=true;
flags.flashMemoryBar=false;
SetCameraTarget({7*24,10*24},true);
nextLevel=LevelName::STAGE3; nextLevel=LevelName::STAGE3;
}; };
void Stage2::Update(){ void Stage2::Update(){
switch(state){ switch(state){
case 0:{ case 0:{
SetCameraTarget({7*24,10*24},true);
DisplayBox("You took care of that sector flawlessly Hacker, this next one needs a bit more hand-holding."); DisplayBox("You took care of that sector flawlessly Hacker, this next one needs a bit more hand-holding.");
if(box.bPressed){ if(box.bPressed){
state=1; state=1;
} }
}break; }break;
case 1:{ case 1:{
SetObjective("Create a RAM bank.");
DisplayBox("We have analyzed the data from the RAM bank and can now create one. Go ahead and select the Platform here and construct one."); DisplayBox("We have analyzed the data from the RAM bank and can now create one. Go ahead and select the Platform here and construct one.");
if(box.bPressed){ if(box.bPressed){
state=2; state=2;
@ -184,6 +186,7 @@ void Stage2::Update(){
if(u->IsRAMBank()&&u->IsFriendly()){ if(u->IsRAMBank()&&u->IsFriendly()){
state=3; state=3;
flags.playerInControl=false; flags.playerInControl=false;
SetObjective("");
break; break;
} }
} }
@ -209,6 +212,7 @@ void Stage2::Update(){
} }
}break; }break;
case 6:{ case 6:{
SetObjective("Build a Memory Allocator.");
DisplayBox("To allocate 5 bits, select the RAM bank and click the Memory Allocator button.\n\nGive it a try now."); DisplayBox("To allocate 5 bits, select the RAM bank and click the Memory Allocator button.\n\nGive it a try now.");
if(box.bPressed){ if(box.bPressed){
state=7; state=7;
@ -221,11 +225,13 @@ void Stage2::Update(){
if(u->IsAllocator()&&u->IsFriendly()){ if(u->IsAllocator()&&u->IsFriendly()){
state=8; state=8;
flags.playerInControl=false; flags.playerInControl=false;
SetObjective("");
break; break;
} }
} }
}break; }break;
case 8:{ case 8:{
SetObjective("Build a Left or Right Bit Shifter.");
DisplayBox("Now select the memory allocator and let's make a Shifter unit."); DisplayBox("Now select the memory allocator and let's make a Shifter unit.");
if(box.bPressed){ if(box.bPressed){
state=9; state=9;
@ -238,6 +244,7 @@ void Stage2::Update(){
if(!u->IsAllocator()&&!u->IsRAMBank()&&u->IsFriendly()){ if(!u->IsAllocator()&&!u->IsRAMBank()&&u->IsFriendly()){
state=10; state=10;
flags.playerInControl=false; flags.playerInControl=false;
SetObjective("");
break; break;
} }
} }
@ -278,18 +285,95 @@ bool Stage2::MissionCompleted(){
Stage3::Stage3(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags) Stage3::Stage3(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags)
:Scenario(units,IMAGES,SOUNDS,objective,game,flags){} :Scenario(units,IMAGES,SOUNDS,objective,game,flags){}
void Stage3::Start(){ void Stage3::Start(){
flags.playerInControl=false;
flags.unitMetersGreyedOut=true;
flags.guideEnabled=false;
SetCameraTarget({3*24,6*24},true);
oopsTimer=0.3;
nextLevel=LevelName::STAGE4; nextLevel=LevelName::STAGE4;
}; };
void Stage3::Update(){ void Stage3::Update(){
switch(state){ switch(state){
case 0:{ case 0:{
DisplayBox("I haven't touched on what the other meters on your units are, but they are important!");
if(box.bPressed){
SOUNDS[Sound::SWITCH]->PlayCentered();
flags.unitMetersGreyedOut=false;
state=1;
}
}break;
case 1:{
DisplayBox("The Blue bits indicates movement capabilities of a unit.");
if(box.bPressed){
state=2;
}
}break;
case 2:{
DisplayBox("The Green bits indicates the range of a unit.");
if(box.bPressed){
state=3;
}
}break;
case 3:{
DisplayBox("The Red bits are the attack speed bits.");
if(box.bPressed){
state=4;
}
}break;
case 4:{
DisplayBox("And Purple are the Procedure bits. Without these, your unit will fail to recall how to function.");
if(box.bPressed){
state=5;
}
}break;
case 5:{
DisplayBox("As units attack each other, their bits are going to get shuffled around, impeding their ability to perform.");
if(box.bPressed){
state=6;
}
}break;
case 6:{
DisplayBox("Your immediate goal is to always take out the Yellow bits but sometimes taking out other bits is important too.");
if(box.bPressed){
SOUNDS[Sound::SWITCH]->PlayCentered();
flags.guideEnabled=true;
state=7;
}
}break;
case 7:{
DisplayBox("I'll leave a guide by the map in case your memory betrays you.");
if(box.bPressed){
state=8;
}
}break;
case 8:{
SetObjective("Defeat all units");
DisplayBox("You now have access to more units as well. Do check them out!");
if(box.bPressed){
SetObjective("Defeat all units (Oops)");
state=9;
}
}break;
case 9:{
oopsTimer=std::max(0.f,oopsTimer-game.GetPGE()->GetElapsedTime());
if(oopsTimer==0){
SetObjective("Defeat all enemy units.");
state=10;
flags.playerInControl=true;
}
}break;
case 10:{
}break; }break;
} }
}; };
bool Stage3::MissionCompleted(){ bool Stage3::MissionCompleted(){
for(auto&u:units){
if(!u->IsFriendly()){
return false; return false;
} }
}
return true;
}
Stage4::Stage4(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags) Stage4::Stage4(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags)
:Scenario(units,IMAGES,SOUNDS,objective,game,flags){} :Scenario(units,IMAGES,SOUNDS,objective,game,flags){}
void Stage4::Start(){ void Stage4::Start(){

@ -59,6 +59,7 @@ protected:
}; };
class Stage3:public Scenario{ class Stage3:public Scenario{
public: public:
float oopsTimer=0.3;
Stage3(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags); Stage3(std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::string&objective,TileTransformedView&game,GameFlags&flags);
protected: protected:
void Start(); void Start();

@ -10,5 +10,17 @@ namespace Sound{
VOICEOVER, VOICEOVER,
PING, PING,
ALARM, ALARM,
SWITCH,
HIT1,
HIT2,
HIT3,
BUTTONSELECT,
SMALLBUILD,
BIGBUILD,
HEAL,
REFRESHER,
TURRET,
MEMORY_GUARD,
SPAWN,
}; };
} }

@ -199,7 +199,7 @@ void Textbox::Draw(PixelGameEngine*pge,Resources&resources,std::vector<std::uniq
totalCost+=util::GetProcedureCost(resourceCost); totalCost+=util::GetProcedureCost(resourceCost);
index++; index++;
} }
std::string text="Size: "+std::to_string(totalCost)+" bytes"; std::string text="Size: "+std::to_string(totalCost)+" bits";
vi2d size=pge->GetTextSizeProp(text); vi2d size=pge->GetTextSizeProp(text);
drawcol=WHITE; drawcol=WHITE;
if(totalCost+totalUsedMemory>memoryLimit){ if(totalCost+totalUsedMemory>memoryLimit){

@ -8,14 +8,23 @@
Unit::~Unit(){}; Unit::~Unit(){};
void Unit::RandomHit(int chance,std::vector<std::unique_ptr<Audio>>&SOUNDS){
switch(rand()%chance){
case 0:{SOUNDS[Sound::HIT1]->Play(GetPos(),1,0.6);}break;
case 1:{SOUNDS[Sound::HIT2]->Play(GetPos(),1,0.6);}break;
case 2:{SOUNDS[Sound::HIT3]->Play(GetPos(),1,0.6);}break;
}
}
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::vector<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 ,std::vector<std::unique_ptr<Audio>>&SOUNDS){
victim<<=1; victim<<=1;
RandomHit(6,SOUNDS);
} }
std::string RightShifter::unitName="Right Shifter"; std::string RightShifter::unitName="Right Shifter";
@ -24,8 +33,9 @@ std::vector<Memory> RightShifter::resourceCost={{HEALTH,4},{RANGE,2},{ATKSPD,2},
RightShifter::RightShifter(PixelGameEngine*pge,vf2d pos,std::vector<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 ,std::vector<std::unique_ptr<Audio>>&SOUNDS){
victim>>=1; victim>>=1;
RandomHit(6,SOUNDS);
} }
std::string BitRestorer::unitName="Bit Restorer"; std::string BitRestorer::unitName="Bit Restorer";
@ -34,7 +44,7 @@ std::vector<Memory> BitRestorer::resourceCost={{PROCEDURE,6},{RANGE,1},{ATKSPD,1
BitRestorer::BitRestorer(PixelGameEngine*pge,vf2d pos,std::vector<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 ,std::vector<std::unique_ptr<Audio>>&SOUNDS){
std::vector<int>emptyMemoryPositions; std::vector<int>emptyMemoryPositions;
for(int i=0;i<victim.GetMemorySize();i++){ for(int i=0;i<victim.GetMemorySize();i++){
if(!victim.memory[i]){ if(!victim.memory[i]){
@ -44,14 +54,15 @@ void BitRestorer::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUni
if(emptyMemoryPositions.size()==0){ if(emptyMemoryPositions.size()==0){
//First see if we can find another damaged target, if we can, then we try healing them. Otherwise we exit. //First see if we can find another damaged target, if we can, then we try healing them. Otherwise we exit.
appliedTarget.reset(); appliedTarget.reset();
AttemptToHealOtherAllies(otherUnits); AttemptToHealOtherAllies(otherUnits,SOUNDS);
return; return;
} }
int randomBit=emptyMemoryPositions[rand()%emptyMemoryPositions.size()]; int randomBit=emptyMemoryPositions[rand()%emptyMemoryPositions.size()];
victim.memory[randomBit]=true; victim.memory[randomBit]=true;
SOUNDS[Sound::HEAL]->Play(GetPos(),1,0.6);
} }
void BitRestorer::AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&otherUnits){ void BitRestorer::AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<std::unique_ptr<Audio>>&SOUNDS){
std::vector<int>emptyMemoryPositions; std::vector<int>emptyMemoryPositions;
for(auto&u:otherUnits){ for(auto&u:otherUnits){
if(u.get()!=this&&u->IsFriendly()&&InRange(u)){ if(u.get()!=this&&u->IsFriendly()&&InRange(u)){
@ -64,6 +75,7 @@ void BitRestorer::AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&ot
int randomBit=emptyMemoryPositions[rand()%emptyMemoryPositions.size()]; int randomBit=emptyMemoryPositions[rand()%emptyMemoryPositions.size()];
u->memory[randomBit]=true; u->memory[randomBit]=true;
appliedTarget=u; appliedTarget=u;
SOUNDS[Sound::HEAL]->Play(GetPos(),1,0.6);
return; return;
} }
} }
@ -78,7 +90,7 @@ MemorySwapper::MemorySwapper(PixelGameEngine*pge,vf2d pos,std::vector<std::uniqu
autoAcquireFriendlyTarget=false; autoAcquireFriendlyTarget=false;
} }
void MemorySwapper::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void MemorySwapper::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits ,std::vector<std::unique_ptr<Audio>>&SOUNDS){
std::vector<bool>oldMemory=victim.memory; std::vector<bool>oldMemory=victim.memory;
for(int i=0;i<oldMemory.size();i++){ for(int i=0;i<oldMemory.size();i++){
victim.memory[i]=oldMemory[oldMemory.size()-i-1]; victim.memory[i]=oldMemory[oldMemory.size()-i-1];
@ -112,6 +124,7 @@ void MemorySwapper::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherU
if(victim.atkSpd.index==9999999)victim.atkSpd.index=0; if(victim.atkSpd.index==9999999)victim.atkSpd.index=0;
if(victim.moveSpd.index==9999999)victim.moveSpd.index=0; if(victim.moveSpd.index==9999999)victim.moveSpd.index=0;
if(victim.procedure.index==9999999)victim.procedure.index=0; if(victim.procedure.index==9999999)victim.procedure.index=0;
RandomHit(4,SOUNDS);
} }
std::string Corrupter::unitName="Corrupter"; std::string Corrupter::unitName="Corrupter";
@ -120,9 +133,12 @@ std::vector<Memory> Corrupter::resourceCost={{ATKSPD,3},{RANGE,1},{PROCEDURE,8},
Corrupter::Corrupter(PixelGameEngine*pge,vf2d pos,std::vector<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 ,std::vector<std::unique_ptr<Audio>>&SOUNDS){
//Chooses a bit at random and corrupts it. //Chooses a bit at random and corrupts it.
int randomBit=rand()%victim.memory.size(); int randomBit=rand()%victim.memory.size();
if(victim.memory[randomBit]){
RandomHit(5,SOUNDS);
}
victim.memory[randomBit]=false; victim.memory[randomBit]=false;
} }
@ -134,7 +150,7 @@ MemoryAllocator::MemoryAllocator(PixelGameEngine*pge,vf2d pos,std::vector<std::u
isAllocator=true; isAllocator=true;
} }
void MemoryAllocator::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void MemoryAllocator::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits ,std::vector<std::unique_ptr<Audio>>&SOUNDS){
} }
@ -147,6 +163,7 @@ void MemoryAllocator::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Aud
for(int i=0;i<GetMemorySize();i++){ for(int i=0;i<GetMemorySize();i++){
memory[i]=false; //Kill the unit. memory[i]=false; //Kill the unit.
} }
SOUNDS[Sound::SPAWN]->Play(GetPos());
queuedUnits.push_back(std::move(buildTransformUnit)); queuedUnits.push_back(std::move(buildTransformUnit));
} }
} }
@ -194,7 +211,7 @@ RAMBank::RAMBank(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Render
isRAMBank=true; isRAMBank=true;
} }
void RAMBank::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void RAMBank::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits ,std::vector<std::unique_ptr<Audio>>&SOUNDS){
} }
@ -293,7 +310,7 @@ _Platform::_Platform(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Re
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 ,std::vector<std::unique_ptr<Audio>>&SOUNDS){};
void _Platform::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits){ void _Platform::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits){
if(IsBuilding()){ if(IsBuilding()){
@ -304,6 +321,7 @@ void _Platform::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&S
for(int i=0;i<GetMemorySize();i++){ for(int i=0;i<GetMemorySize();i++){
memory[i]=false; //Kill the unit. memory[i]=false; //Kill the unit.
} }
SOUNDS[Sound::SPAWN]->Play(GetPos());
queuedUnits.push_back(std::move(buildTransformUnit)); queuedUnits.push_back(std::move(buildTransformUnit));
} }
} }
@ -335,7 +353,7 @@ Refresher::Refresher(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Re
: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){}
void Refresher::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void Refresher::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits ,std::vector<std::unique_ptr<Audio>>&SOUNDS){
target.reset(); //Doesn't acquire a target. target.reset(); //Doesn't acquire a target.
for(auto&u:otherUnits){ for(auto&u:otherUnits){
if(IsFriendly()==u->IsFriendly()&&InRange(u.get())){ if(IsFriendly()==u->IsFriendly()&&InRange(u.get())){
@ -352,6 +370,15 @@ void Refresher::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits
} }
} }
} }
void Refresher::OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS){
SOUNDS[Sound::REFRESHER]->Stop(soundHandle);
};
void Refresher::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits){
if(!soundStarted){
soundStarted=true;
soundHandle=SOUNDS[Sound::REFRESHER]->Play(GetPos(),1,1,true);
}
};
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.";
@ -359,7 +386,7 @@ std::vector<Memory> Turret::resourceCost={{ATKSPD,4},{RANGE,5},{HEALTH,6},{PROCE
Turret::Turret(PixelGameEngine*pge,vf2d pos,std::vector<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 ,std::vector<std::unique_ptr<Audio>>&SOUNDS){
if(victim.GetMoveSpd()>0){ if(victim.GetMoveSpd()>0){
for(int i=0;i<victim.moveSpd.size;i++){ for(int i=0;i<victim.moveSpd.size;i++){
if(victim.memory[victim.moveSpd.index+i]){ if(victim.memory[victim.moveSpd.index+i]){
@ -387,6 +414,15 @@ void Turret::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
attempts++; attempts++;
} }
} }
void Turret::OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS){
SOUNDS[Sound::TURRET]->Stop(soundHandle);
};
void Turret::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits){
if(!soundStarted){
soundStarted=true;
soundHandle=SOUNDS[Sound::TURRET]->Play(GetPos(),1,1,true);
}
};
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%";
@ -395,7 +431,7 @@ MemoryGuard::MemoryGuard(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_pt
: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){}
void MemoryGuard::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void MemoryGuard::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits ,std::vector<std::unique_ptr<Audio>>&SOUNDS){
target.reset(); //Doesn't acquire a target. target.reset(); //Doesn't acquire a target.
for(auto&u:otherUnits){ for(auto&u:otherUnits){
if(IsFriendly()==u->IsFriendly()&&InRange(u.get())){ if(IsFriendly()==u->IsFriendly()&&InRange(u.get())){
@ -403,6 +439,15 @@ void MemoryGuard::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUni
} }
} }
} }
void MemoryGuard::OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS){
SOUNDS[Sound::MEMORY_GUARD]->Stop(soundHandle);
};
void MemoryGuard::Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits){
if(!soundStarted){
soundStarted=true;
soundHandle=SOUNDS[Sound::MEMORY_GUARD]->Play(GetPos(),1,1,true);
}
};
Unit::Unit(PixelGameEngine*pge,std::vector<Memory>memory,vf2d pos,float radius,Renderable&img,Pixel targetLineColor,Pixel attackingLineColor,bool friendly,bool moveable,bool friendlyInteractable,bool enemyInteractable) Unit::Unit(PixelGameEngine*pge,std::vector<Memory>memory,vf2d pos,float radius,Renderable&img,Pixel targetLineColor,Pixel attackingLineColor,bool friendly,bool moveable,bool friendlyInteractable,bool enemyInteractable)
:pos(pos),radius(radius),ghostPos({-999999,-999999}),img(img),targetLineCol(targetLineColor),attackingLineCol(attackingLineColor),friendly(friendly),moveable(moveable),friendlyInteractable(friendlyInteractable),enemyInteractable(enemyInteractable){ :pos(pos),radius(radius),ghostPos({-999999,-999999}),img(img),targetLineCol(targetLineColor),attackingLineCol(attackingLineColor),friendly(friendly),moveable(moveable),friendlyInteractable(friendlyInteractable),enemyInteractable(enemyInteractable){
@ -791,7 +836,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::vector<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,std::vector<std::unique_ptr<Audio>>&SOUNDS){
if(reloadTimer>0)return; if(reloadTimer>0)return;
std::weak_ptr<Unit>finalTarget; std::weak_ptr<Unit>finalTarget;
if(!unit.expired()){ if(!unit.expired()){
@ -810,7 +855,7 @@ void Unit::AttemptAttack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>unit,std
bool hadMoveSpd=finalTarget.lock()->GetMoveSpd()>0; bool hadMoveSpd=finalTarget.lock()->GetMoveSpd()>0;
bool hadRange=finalTarget.lock()->GetRange()>0; bool hadRange=finalTarget.lock()->GetRange()>0;
bool hadProcedure=finalTarget.lock()->GetProcedure()>0; bool hadProcedure=finalTarget.lock()->GetProcedure()>0;
_Attack(attacker,finalTarget,otherUnits); //Call the parent function first, followed by the child. _Attack(attacker,finalTarget,otherUnits,SOUNDS); //Call the parent function first, followed by the child.
if(hadAtkSpd&&finalTarget.lock()->GetAtkSpd()==0){ if(hadAtkSpd&&finalTarget.lock()->GetAtkSpd()==0){
debuffIcons.emplace_back(IMAGES[RLD_ICON].get(),IMAGES[RED_X].get(),finalTarget.lock()->GetPos()-vf2d{util::random(12)-6,4}); debuffIcons.emplace_back(IMAGES[RLD_ICON].get(),IMAGES[RED_X].get(),finalTarget.lock()->GetPos()-vf2d{util::random(12)-6,4});
} }
@ -838,12 +883,12 @@ void Unit::_Attacked(std::weak_ptr<Unit>attacker){
} }
} }
void Unit::_Attack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>finalTarget,std::vector<std::shared_ptr<Unit>>&otherUnits){ void Unit::_Attack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>finalTarget,std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<std::unique_ptr<Audio>>&SOUNDS){
if(GetProcedure()>0&&GetAtkSpd()>0){ if(GetProcedure()>0&&GetAtkSpd()>0){
attackFailed=false; attackFailed=false;
float procChance=float(GetProcedure())/procedure.size; float procChance=float(GetProcedure())/procedure.size;
if(util::random(1)>=1-procChance){ if(util::random(1)>=1-procChance){
Attack(*finalTarget.lock(),otherUnits); Attack(*finalTarget.lock(),otherUnits,SOUNDS);
finalTarget.lock()->_Attacked(attacker); finalTarget.lock()->_Attacked(attacker);
reloadTimer=1.f/(GetAtkSpd()/2.f); reloadTimer=1.f/(GetAtkSpd()/2.f);
if(GetCurrentTarget().expired()&&!IsFriendly()){ if(GetCurrentTarget().expired()&&!IsFriendly()){
@ -944,9 +989,15 @@ bool Unit::IsAllocator(){
return isAllocator&&attachedPoint.expired()&&buildTime<=0; return isAllocator&&attachedPoint.expired()&&buildTime<=0;
} }
void Unit::SetBuildUnit(float buildTime,std::shared_ptr<Unit>finalUnit){ void Unit::SetBuildUnit(float buildTime,std::shared_ptr<Unit>finalUnit,std::vector<std::unique_ptr<Audio>>&SOUNDS){
this->buildTime=buildTime; this->buildTime=buildTime;
this->buildTransformUnit=std::move(finalUnit); this->buildTransformUnit=std::move(finalUnit);
if(this->IsAllocator()){
SOUNDS[Sound::SMALLBUILD]->Play(GetPos());
} else
if(this->IsPlatform()){
SOUNDS[Sound::BIGBUILD]->Play(GetPos());
}
} }
bool Unit::IsBuilding(){ bool Unit::IsBuilding(){

@ -46,7 +46,7 @@ public:
std::vector<bool>ghostMemory; std::vector<bool>ghostMemory;
std::vector<bool>savedMemory; std::vector<bool>savedMemory;
virtual void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits); virtual void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits);
virtual void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)=0; virtual void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<std::unique_ptr<Audio>>&SOUNDS)=0;
virtual void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES); virtual void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES);
virtual void DrawHud(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES); virtual void DrawHud(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES);
void _DrawHud(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool unitMetersGreyedOut); void _DrawHud(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool unitMetersGreyedOut);
@ -61,7 +61,7 @@ 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::vector<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,std::vector<std::unique_ptr<Audio>>&SOUNDS);
bool InFogOfWar(); bool InFogOfWar();
bool GhostInFogOfWar(); bool GhostInFogOfWar();
void HideGhost(); void HideGhost();
@ -85,7 +85,7 @@ public:
virtual void UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered,int totalUsedMemory,int availableMemory); virtual void UpdateGUIState(TileTransformedView&game,Resources&player_resources,Textbox&displayBox,bool&hovered,int totalUsedMemory,int availableMemory);
virtual bool ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES); //If you return true here, then the left click does not pass back to the main Virus Attack class. virtual bool ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Renderable>>&IMAGES); //If you return true here, then the left click does not pass back to the main Virus Attack class.
bool IsAllocator(); bool IsAllocator();
void SetBuildUnit(float buildTime,std::shared_ptr<Unit>finalUnit); void SetBuildUnit(float buildTime,std::shared_ptr<Unit>finalUnit,std::vector<std::unique_ptr<Audio>>&SOUNDS);
bool IsBuilding(); bool IsBuilding();
void SetGuardTime(float time); void SetGuardTime(float time);
bool IsGuarded(); bool IsGuarded();
@ -93,6 +93,7 @@ public:
bool IsPlatform(); bool IsPlatform();
bool IsAttached(); bool IsAttached();
bool IsRAMBank(); bool IsRAMBank();
void RandomHit(int chance,std::vector<std::unique_ptr<Audio>>&SOUNDS); //3 of chance odds of making a sound.
Unit*GetBuildUnit(); Unit*GetBuildUnit();
Marker health={}; Marker health={};
Marker range={}; Marker range={};
@ -142,7 +143,7 @@ private:
int GetBits(Marker&m); int GetBits(Marker&m);
bool selected=false; bool selected=false;
bool dead=false; bool dead=false;
void _Attack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>finalTarget,std::vector<std::shared_ptr<Unit>>&otherUnits); void _Attack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>finalTarget,std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<std::unique_ptr<Audio>>&SOUNDS);
bool moveable=true; bool moveable=true;
bool friendlyInteractable=false; bool friendlyInteractable=false;
bool enemyInteractable=true; bool enemyInteractable=true;
@ -159,7 +160,7 @@ private:
struct LeftShifter:Unit{ struct LeftShifter:Unit{
LeftShifter(PixelGameEngine*pge,vf2d pos,std::vector<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,std::vector<std::unique_ptr<Audio>>&SOUNDS)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;
@ -167,7 +168,7 @@ struct LeftShifter:Unit{
struct RightShifter:Unit{ struct RightShifter:Unit{
RightShifter(PixelGameEngine*pge,vf2d pos,std::vector<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,std::vector<std::unique_ptr<Audio>>&SOUNDS)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;
@ -175,8 +176,8 @@ struct RightShifter:Unit{
struct BitRestorer:Unit{ struct BitRestorer:Unit{
BitRestorer(PixelGameEngine*pge,vf2d pos,std::vector<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,std::vector<std::unique_ptr<Audio>>&SOUNDS)override;
void AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&otherUnits); void AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<std::unique_ptr<Audio>>&SOUNDS);
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;
@ -184,7 +185,7 @@ struct BitRestorer:Unit{
struct MemorySwapper:Unit{ struct MemorySwapper:Unit{
MemorySwapper(PixelGameEngine*pge,vf2d pos,std::vector<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,std::vector<std::unique_ptr<Audio>>&SOUNDS)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;
@ -192,7 +193,7 @@ struct MemorySwapper:Unit{
struct Corrupter:Unit{ struct Corrupter:Unit{
Corrupter(PixelGameEngine*pge,vf2d pos,std::vector<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,std::vector<std::unique_ptr<Audio>>&SOUNDS)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;
@ -200,7 +201,7 @@ struct Corrupter:Unit{
struct MemoryAllocator:Unit{ struct MemoryAllocator:Unit{
MemoryAllocator(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); MemoryAllocator(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&units)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&units,std::vector<std::unique_ptr<Audio>>&SOUNDS)override;
void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits)override; void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits)override;
void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override; void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override;
static std::vector<Memory> resourceCost; static std::vector<Memory> resourceCost;
@ -219,7 +220,7 @@ struct RAMBank:Unit{
QuickGUI::ImageButton*allocatorButton; QuickGUI::ImageButton*allocatorButton;
RAMBank(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly=false); RAMBank(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly=false);
void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits)override; void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits)override;
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<std::unique_ptr<Audio>>&SOUNDS)override;
void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override; void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override;
void OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS)override; void OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS)override;
bool ClickHandled(TileTransformedView&game,Resources&player_resources,std::vector<std::shared_ptr<Unit>>&units,std::vector<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;
@ -232,7 +233,7 @@ struct RAMBank:Unit{
struct _Platform:Unit{ struct _Platform:Unit{
_Platform(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); _Platform(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<std::unique_ptr<Audio>>&SOUNDS)override;
void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits)override; void Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits)override;
void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override; void Draw(TileTransformedView&game,std::vector<std::unique_ptr<Renderable>>&IMAGES)override;
static std::vector<Memory> resourceCost; static std::vector<Memory> resourceCost;
@ -241,24 +242,36 @@ struct _Platform:Unit{
}; };
struct MemoryGuard:Unit{ struct MemoryGuard:Unit{
bool soundStarted=false;
int soundHandle=-1;
MemoryGuard(PixelGameEngine*pge,vf2d pos,std::vector<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 Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits)override;
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<std::unique_ptr<Audio>>&SOUNDS)override;
void OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS)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 Refresher:Unit{ struct Refresher:Unit{
bool soundStarted=false;
int soundHandle=-1;
Refresher(PixelGameEngine*pge,vf2d pos,std::vector<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 Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits)override;
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<std::unique_ptr<Audio>>&SOUNDS)override;
void OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS)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 Turret:Unit{ struct Turret:Unit{
bool soundStarted=false;
int soundHandle=-1;
Turret(PixelGameEngine*pge,vf2d pos,std::vector<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 Update(PixelGameEngine*pge,std::vector<std::unique_ptr<Audio>>&SOUNDS,std::vector<std::shared_ptr<Unit>>&queuedUnits)override;
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits,std::vector<std::unique_ptr<Audio>>&SOUNDS)override;
void OnDeath(std::vector<std::unique_ptr<Audio>>&SOUNDS)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;

@ -145,6 +145,41 @@ void VirusAttack::InitializeLevelData(){
} }
} }
#pragma endregion #pragma endregion
#pragma region Stage 3
{
//Stage 3 data.
LevelName stage=STAGE3;
levelData[stage].name=stage;
levelData[stage].cameraStart={96,96};
levelData[stage].worldZoom={1,1};
levelData[stage].size={30,30};
levelData[stage].levelColor=DARK_GREEN;
levelData[stage].bgm=Sound::GRAVITY;
levelData[stage].scenarioIndex=int(stage);
levelData[stage].availableMemory=240;
levelData[stage].player_starting_resources={100,40,60,40,100};
levelData[stage].enemy_starting_resources={0,0,0,0,0};
{
std::vector<UnitData>&units=levelData[stage].unitPlacement;
std::vector<CPData>&collectionPoints=levelData[stage].cpPlacement;
units.push_back({UnitType::RAMBank,vf2d{3*24,6*24},true});
for(int i=0;i<4;i++){
units.push_back({UnitType::RightShifter,vf2d{3*24,8*24},true});
}
units.push_back({UnitType::LeftShifter,vf2d{3*24,7*24},true});
units.push_back({UnitType::RightShifter,vf2d{18*24,19*24},false});
units.push_back({UnitType::LeftShifter,vf2d{20*24,22*24},false});
units.push_back({UnitType::LeftShifter,vf2d{21*24,22*24},false});
for(int i=0;i<8;i++){
units.push_back({UnitType::MemoryAllocator,vf2d{20*24,17*24},false});
}
units.push_back({UnitType::_Platform,vf2d{22*24,23*24},false});
}
}
#pragma endregion
} }
bool VirusAttack::OnUserCreate(){ bool VirusAttack::OnUserCreate(){
@ -303,6 +338,17 @@ void VirusAttack::InitializeSounds(){
LoadSound(Sound::VOICEOVER,"voice.mp3"); LoadSound(Sound::VOICEOVER,"voice.mp3");
LoadSound(Sound::PING,"ping.mp3"); LoadSound(Sound::PING,"ping.mp3");
LoadSound(Sound::ALARM,"alarm.mp3"); LoadSound(Sound::ALARM,"alarm.mp3");
LoadSound(Sound::SWITCH,"switch.mp3");
LoadSound(Sound::HIT1,"hit1.mp3");
LoadSound(Sound::HIT2,"hit2.mp3");
LoadSound(Sound::HIT3,"hit3.mp3");
LoadSound(Sound::BUTTONSELECT,"buttonselect.mp3");
LoadSound(Sound::SMALLBUILD,"smallbuild.mp3");
LoadSound(Sound::BIGBUILD,"bigbuild.mp3");
LoadSound(Sound::HEAL,"heal.mp3");
LoadSound(Sound::REFRESHER,"refresher.mp3");
LoadSound(Sound::TURRET,"turret.mp3");
LoadSound(Sound::MEMORY_GUARD,"memoryguard.mp3");
} }
bool VirusAttack::UnitCreationClickHandled(){ bool VirusAttack::UnitCreationClickHandled(){
@ -311,14 +357,14 @@ bool VirusAttack::UnitCreationClickHandled(){
for(auto&u:units){ \ for(auto&u:units){ \
if(u->IsSelected()&&u->Validator()&&CanAfford(player_resources,UnitClass::resourceCost)) { \ if(u->IsSelected()&&u->Validator()&&CanAfford(player_resources,UnitClass::resourceCost)) { \
std::shared_ptr<UnitClass>buildUnit=std::make_shared<UnitClass>(this,u->GetPos(),IMAGES,u->IsFriendly()); \ std::shared_ptr<UnitClass>buildUnit=std::make_shared<UnitClass>(this,u->GetPos(),IMAGES,u->IsFriendly()); \
u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit)); \ u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit),SOUNDS); \
ExpendResources(player_resources,UnitClass::resourceCost); \ ExpendResources(player_resources,UnitClass::resourceCost); \
CalculateUsedMemory(); \ CalculateUsedMemory(); \
} \ } \
} \ } \
SOUNDS[Sound::BUTTONSELECT]->PlayCentered(); \
return true; \ return true; \
} }
CheckClick(LeftShifter,leftShifterButton,IsAllocator) CheckClick(LeftShifter,leftShifterButton,IsAllocator)
CheckClick(RightShifter,rightShifterButton,IsAllocator) CheckClick(RightShifter,rightShifterButton,IsAllocator)
CheckClick(BitRestorer,bitRestorerButton,IsAllocator) CheckClick(BitRestorer,bitRestorerButton,IsAllocator)
@ -686,9 +732,13 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
mainMenu.Update(this); mainMenu.Update(this);
if(campaignStartButton->bPressed){ if(campaignStartButton->bPressed){
SOUNDS[Sound::BUTTONSELECT]->PlayCentered();
state=GameState::GAMEPLAY; state=GameState::GAMEPLAY;
RestartLevel(); RestartLevel();
} }
if(exitGameButton->bPressed){
SOUNDS[Sound::BUTTONSELECT]->PlayCentered();
}
titleScreenY=std::min(0.f,titleScreenY+fElapsedTime*120); titleScreenY=std::min(0.f,titleScreenY+fElapsedTime*120);
nextColorChange=std::max(0.f,nextColorChange-fElapsedTime); nextColorChange=std::max(0.f,nextColorChange-fElapsedTime);
@ -816,7 +866,7 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
} }
} }
} }
u->AttemptAttack(u,closestUnit,units,debuffIcons,IMAGES); u->AttemptAttack(u,closestUnit,units,debuffIcons,IMAGES,SOUNDS);
u->_Update(this,SOUNDS,player_resources,enemy_resources,queuedUnits,resourceGainTimer,resourceGainIcons,IMAGES); u->_Update(this,SOUNDS,player_resources,enemy_resources,queuedUnits,resourceGainTimer,resourceGainIcons,IMAGES);
} }
@ -991,16 +1041,16 @@ void VirusAttack::DrawSystemMemoryBar(float fElapsedTime){
col=CONSTANT::HEALTH_COLOR; col=CONSTANT::HEALTH_COLOR;
}break; }break;
case 1:{ case 1:{
col=CONSTANT::RANGE_COLOR; col=flags.unitMetersGreyedOut?DARK_GREY:CONSTANT::RANGE_COLOR;
}break; }break;
case 2:{ case 2:{
col=CONSTANT::ATKSPD_COLOR; col=flags.unitMetersGreyedOut?DARK_GREY:CONSTANT::ATKSPD_COLOR;
}break; }break;
case 3:{ case 3:{
col=CONSTANT::MOVESPD_COLOR; col=flags.unitMetersGreyedOut?DARK_GREY:CONSTANT::MOVESPD_COLOR;
}break; }break;
case 4:{ case 4:{
col=CONSTANT::PROCEDURE_COLOR; col=flags.unitMetersGreyedOut?DARK_GREY:CONSTANT::PROCEDURE_COLOR;
}break; }break;
} }
DrawPartialDecal(barPos+vf2d{barOffset+1,1.f},{barSegmentWidth,3},IMAGES[SEGMENT_BAR]->Decal(),{0,0},{float(playerUsedDisplayMemory[i]),3.f},col); DrawPartialDecal(barPos+vf2d{barOffset+1,1.f},{barSegmentWidth,3},IMAGES[SEGMENT_BAR]->Decal(),{0,0},{float(playerUsedDisplayMemory[i]),3.f},col);
@ -1016,16 +1066,16 @@ void VirusAttack::DrawSystemMemoryBar(float fElapsedTime){
col=CONSTANT::HEALTH_COLOR; col=CONSTANT::HEALTH_COLOR;
}break; }break;
case 1:{ case 1:{
col=CONSTANT::RANGE_COLOR; col=flags.unitMetersGreyedOut?DARK_GREY:CONSTANT::RANGE_COLOR;
}break; }break;
case 2:{ case 2:{
col=CONSTANT::ATKSPD_COLOR; col=flags.unitMetersGreyedOut?DARK_GREY:CONSTANT::ATKSPD_COLOR;
}break; }break;
case 3:{ case 3:{
col=CONSTANT::MOVESPD_COLOR; col=flags.unitMetersGreyedOut?DARK_GREY:CONSTANT::MOVESPD_COLOR;
}break; }break;
case 4:{ case 4:{
col=CONSTANT::PROCEDURE_COLOR; col=flags.unitMetersGreyedOut?DARK_GREY:CONSTANT::PROCEDURE_COLOR;
}break; }break;
} }
DrawPartialDecal(barPos+vf2d{barOffset+actualBarWidth+3-barSegmentWidth,1.f},{barSegmentWidth,3},IMAGES[SEGMENT_BAR]->Decal(),{0,0},{float(enemyUsedDisplayMemory[i]),3.f},col); DrawPartialDecal(barPos+vf2d{barOffset+actualBarWidth+3-barSegmentWidth,1.f},{barSegmentWidth,3},IMAGES[SEGMENT_BAR]->Decal(),{0,0},{float(enemyUsedDisplayMemory[i]),3.f},col);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 MiB

After

Width:  |  Height:  |  Size: 24 MiB

File diff suppressed because one or more lines are too long

Binary file not shown.
Loading…
Cancel
Save