@ -8,14 +8,23 @@
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 : : 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 : : 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 ) {
void LeftShifter : : Attack ( Unit & victim , std : : vector < std : : shared_ptr < Unit > > & otherUnits , std : : vector < std : : unique_ptr < Audio > > & SOUNDS ) {
victim < < = 1 ;
RandomHit ( 6 , SOUNDS ) ;
}
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 )
: 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 ;
RandomHit ( 6 , SOUNDS ) ;
}
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 )
: 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 ;
for ( int i = 0 ; i < victim . GetMemorySize ( ) ; 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 ) {
//First see if we can find another damaged target, if we can, then we try healing them. Otherwise we exit.
appliedTarget . reset ( ) ;
AttemptToHealOtherAllies ( otherUnits ) ;
AttemptToHealOtherAllies ( otherUnits , SOUNDS ) ;
return ;
}
int randomBit = emptyMemoryPositions [ rand ( ) % emptyMemoryPositions . size ( ) ] ;
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 ;
for ( auto & u : otherUnits ) {
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 ( ) ] ;
u - > memory [ randomBit ] = true ;
appliedTarget = u ;
SOUNDS [ Sound : : HEAL ] - > Play ( GetPos ( ) , 1 , 0.6 ) ;
return ;
}
}
@ -78,7 +90,7 @@ MemorySwapper::MemorySwapper(PixelGameEngine*pge,vf2d pos,std::vector<std::uniqu
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 ;
for ( int i = 0 ; i < oldMemory . size ( ) ; i + + ) {
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 . moveSpd . index = = 9999999 ) victim . moveSpd . index = 0 ;
if ( victim . procedure . index = = 9999999 ) victim . procedure . index = 0 ;
RandomHit ( 4 , SOUNDS ) ;
}
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 )
: 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.
int randomBit = rand ( ) % victim . memory . size ( ) ;
if ( victim . memory [ randomBit ] ) {
RandomHit ( 5 , SOUNDS ) ;
}
victim . memory [ randomBit ] = false ;
}
@ -134,7 +150,7 @@ MemoryAllocator::MemoryAllocator(PixelGameEngine*pge,vf2d pos,std::vector<std::u
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 + + ) {
memory [ i ] = false ; //Kill the unit.
}
SOUNDS [ Sound : : SPAWN ] - > Play ( GetPos ( ) ) ;
queuedUnits . push_back ( std : : move ( buildTransformUnit ) ) ;
}
}
@ -194,7 +211,7 @@ RAMBank::RAMBank(PixelGameEngine*pge,vf2d pos,std::vector<std::unique_ptr<Render
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 ;
}
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 ) {
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 + + ) {
memory [ i ] = false ; //Kill the unit.
}
SOUNDS [ Sound : : SPAWN ] - > Play ( GetPos ( ) ) ;
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
, 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.
for ( auto & u : otherUnits ) {
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 : : 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 )
: 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 ) {
for ( int i = 0 ; i < victim . moveSpd . size ; 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 + + ;
}
}
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 : : 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
, 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.
for ( auto & u : otherUnits ) {
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 )
: 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 ;
}
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 ;
std : : weak_ptr < Unit > finalTarget ;
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 hadRange = finalTarget . lock ( ) - > GetRange ( ) > 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 ) {
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 ) {
attackFailed = false ;
float procChance = float ( GetProcedure ( ) ) / procedure . size ;
if ( util : : random ( 1 ) > = 1 - procChance ) {
Attack ( * finalTarget . lock ( ) , otherUnits ) ;
Attack ( * finalTarget . lock ( ) , otherUnits , SOUNDS ) ;
finalTarget . lock ( ) - > _Attacked ( attacker ) ;
reloadTimer = 1.f / ( GetAtkSpd ( ) / 2.f ) ;
if ( GetCurrentTarget ( ) . expired ( ) & & ! IsFriendly ( ) ) {
@ -944,9 +989,15 @@ bool Unit::IsAllocator(){
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 - > buildTransformUnit = std : : move ( finalUnit ) ;
if ( this - > IsAllocator ( ) ) {
SOUNDS [ Sound : : SMALLBUILD ] - > Play ( GetPos ( ) ) ;
} else
if ( this - > IsPlatform ( ) ) {
SOUNDS [ Sound : : BIGBUILD ] - > Play ( GetPos ( ) ) ;
}
}
bool Unit : : IsBuilding ( ) {