Proximity targeting and healing other targets when one's health is full.

CorrectiveAction
sigonasr2 1 year ago
parent fd5e6048ac
commit bc3e2bf6b0
  1. 56
      olcCodeJam2023Entry/Unit.cpp
  2. 31
      olcCodeJam2023Entry/Unit.h
  3. 21
      olcCodeJam2023Entry/VirusAttack.cpp

@ -14,7 +14,7 @@ BasicUnit::BasicUnit(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES
},pos,12,*IMAGES[VIRUS_IMG1],friendly,moveable){}
void BasicUnit::Attack(Unit&victim){
void BasicUnit::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
victim<<=1;
}
@ -27,7 +27,7 @@ BasicUnit2::BasicUnit2(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAG
{HEALTH,4},
},pos,12,*IMAGES[VIRUS_IMG1],friendly,moveable){}
void BasicUnit2::Attack(Unit&victim){
void BasicUnit2::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
victim>>=1;
}
@ -40,7 +40,7 @@ LeftShifter::LeftShifter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IM
{HEALTH,4},
},pos,12,*IMAGES[LEFT_SHIFTER],friendly,moveable){}
void LeftShifter::Attack(Unit&victim){
void LeftShifter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
victim<<=1;
}
@ -53,7 +53,7 @@ RightShifter::RightShifter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&
{PROCEDURE,1},
},pos,12,*IMAGES[RIGHT_SHIFTER],friendly,moveable){}
void RightShifter::Attack(Unit&victim){
void RightShifter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
victim>>=1;
}
@ -66,8 +66,38 @@ BitRestorer::BitRestorer(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IM
{HEALTH,2},
},pos,12,*IMAGES[BIT_RESTORER],friendly,moveable,true,false){}
void BitRestorer::Attack(Unit&victim){
void BitRestorer::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
std::vector<int>emptyMemoryPositions;
for(int i=0;i<victim.GetMemorySize();i++){
if(!victim.memory[i]){
emptyMemoryPositions.emplace_back(i);
}
}
if(emptyMemoryPositions.size()==0){
//First see if we can find another damaged target, if we can, then we try healing them. Otherwise we exit.
AttemptToHealOtherAllies(otherUnits);
return;
}
int randomBit=emptyMemoryPositions[rand()%emptyMemoryPositions.size()];
victim.memory[randomBit]=victim.ghostMemory[randomBit]=true;
}
void BitRestorer::AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&otherUnits){
std::vector<int>emptyMemoryPositions;
for(auto&u:otherUnits){
if(u->IsFriendly()&&InRange(u)){
for(int i=0;i<u->GetMemorySize();i++){
if(!u->memory[i]){
emptyMemoryPositions.emplace_back(i);
}
}
if(emptyMemoryPositions.size()!=0){
int randomBit=emptyMemoryPositions[rand()%emptyMemoryPositions.size()];
u->memory[randomBit]=u->ghostMemory[randomBit]=true;
return;
}
}
}
}
MemorySwapper::MemorySwapper(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
@ -79,7 +109,7 @@ MemorySwapper::MemorySwapper(vf2d pos,std::map<Image,std::unique_ptr<Renderable>
{MOVESPD,2},
},pos,12,*IMAGES[MEMORY_SWAPPER],friendly,moveable,true){}
void MemorySwapper::Attack(Unit&victim){
void MemorySwapper::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
}
@ -92,7 +122,7 @@ Corrupter::Corrupter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES
{HEALTH,4},
},pos,12,*IMAGES[CORRUPTER],friendly,moveable){}
void Corrupter::Attack(Unit&victim){
void Corrupter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
}
@ -105,7 +135,7 @@ MemoryAllocator::MemoryAllocator(vf2d pos,std::map<Image,std::unique_ptr<Rendera
{HEALTH,1},
},pos,12,*IMAGES[UNIT_ALLOCATOR],friendly,false,false){}
void MemoryAllocator::Attack(Unit&victim){
void MemoryAllocator::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
}
@ -127,7 +157,7 @@ RAMBank::RAMBank(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Ren
pge->SetDrawTarget(nullptr);
}
void RAMBank::Attack(Unit&victim){
void RAMBank::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
}
@ -419,7 +449,7 @@ void Unit::SetPos(vf2d newPos){
}
}
void Unit::AttemptAttack(Unit*unit){
void Unit::AttemptAttack(Unit*unit,std::vector<std::shared_ptr<Unit>>&otherUnits){
if(reloadTimer>0)return;
Unit*finalTarget=nullptr;
if(unit!=nullptr){
@ -433,15 +463,15 @@ void Unit::AttemptAttack(Unit*unit){
}
if(finalTarget!=nullptr){
if(InRange(finalTarget)){
_Attack(finalTarget); //Call the parent function first, followed by the child.
_Attack(finalTarget,otherUnits); //Call the parent function first, followed by the child.
}
}
}
void Unit::Update(PixelGameEngine*pge){}
void Unit::_Attack(Unit*finalTarget){
Attack(*finalTarget);
void Unit::_Attack(Unit*finalTarget,std::vector<std::shared_ptr<Unit>>&otherUnits){
Attack(*finalTarget,otherUnits);
reloadTimer=1.f/(GetAtkSpd()/2.f);
}

@ -35,7 +35,7 @@ public:
std::vector<bool>memory;
std::vector<bool>ghostMemory;
virtual void Update(PixelGameEngine*pge);
virtual void Attack(Unit&victim)=0;
virtual void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)=0;
virtual void Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES);
virtual void DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES);
bool IsFriendly();
@ -48,7 +48,7 @@ public:
void SetTargetUnit(std::weak_ptr<Unit>target);
void SetTargetLocation(vf2d targetLoc);
void SetPos(vf2d newPos);
void AttemptAttack(Unit*unit);
void AttemptAttack(Unit*unit,std::vector<std::shared_ptr<Unit>>&otherUnits);
bool InFogOfWar();
bool GhostInFogOfWar();
void HideGhost();
@ -90,6 +90,9 @@ protected:
Marker procedure;
std::weak_ptr<Unit>target;
vf2d targetLoc=CONSTANT::UNSELECTED;
bool InRange(std::shared_ptr<Unit>target);
bool InRange(Unit*target);
bool InRange(vf2d pos);
private:
vf2d pos;
vf2d ghostPos;
@ -97,11 +100,8 @@ private:
int GetBits(Marker&m);
bool selected=false;
bool dead=false;
bool InRange(std::shared_ptr<Unit>target);
bool InRange(Unit*target);
bool InRange(vf2d pos);
float reloadTimer=0;
void _Attack(Unit*finalTarget);
void _Attack(Unit*finalTarget,std::vector<std::shared_ptr<Unit>>&otherUnits);
vf2d movementVel={0,0};
float changeDirTimer=0;
bool moveable=true;
@ -111,42 +111,43 @@ private:
struct BasicUnit:Unit{
BasicUnit(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim)override;
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
};
struct BasicUnit2:Unit{
BasicUnit2(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim)override;
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
};
struct LeftShifter:Unit{
LeftShifter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim)override;
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
};
struct RightShifter:Unit{
RightShifter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim)override;
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
};
struct BitRestorer:Unit{
BitRestorer(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim)override;
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
void AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&otherUnits);
};
struct MemorySwapper:Unit{
MemorySwapper(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim)override;
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
};
struct Corrupter:Unit{
Corrupter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim)override;
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
};
struct MemoryAllocator:Unit{
MemoryAllocator(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim)override;
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
};
struct RAMBank:Unit{
@ -156,6 +157,6 @@ struct RAMBank:Unit{
Renderable&matrixImg;
RAMBank(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false);
void Update(PixelGameEngine*pge)override;
void Attack(Unit&victim)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;
};

@ -64,6 +64,8 @@ bool VirusAttack::OnUserCreate(){
units.push_back(std::make_unique<RAMBank>(this,vf2d{320,320},IMAGES,false));
units.push_back(std::make_unique<RightShifter>(vf2d{360,300},IMAGES,false));
return true;
}
@ -109,19 +111,22 @@ void VirusAttack::HandleRightClickMove(){
if (GetMouse(1).bHeld){
bool selectedTarget=false;
for(auto&u:units){
if(!u->IsFriendly()){
geom2d::rect<float> unitRegion(u->GetPos()-u->GetUnitSize()/2,u->GetUnitSize());
if(geom2d::overlaps(unitRegion,GetWorldMousePos())){
for(auto&u2:units){
if(u2->IsFriendly()&&u2->IsSelected()){
if(&u!=&u2){
if(!u->IsFriendly()&&u2->IsFriendly()&&u2->IsSelected()&&u2->CanInteractWithEnemies()){
u2->SetTargetUnit(u);
} else
if(u->IsFriendly()&&u2->IsFriendly()&&u2->IsSelected()&&u2->CanInteractWithAllies()){
u2->SetTargetUnit(u);
}
}
}
selectedTarget=true;
break;
}
}
}
if(!selectedTarget){
for(auto&u:units){
if(u->IsFriendly()&&u->IsSelected()){
@ -148,7 +153,13 @@ void VirusAttack::CollisionChecking(std::shared_ptr<Unit>u,std::shared_ptr<Unit>
}
void VirusAttack::IdentifyClosestTarget(Unit*&closestUnit,float&closestDist,std::shared_ptr<Unit>u,std::shared_ptr<Unit>u2){
if(u->IsFriendly()!=u2->IsFriendly()){
bool canInteract;
canInteract=
(u->IsFriendly()&&u->CanInteractWithEnemies()&&!u2->IsFriendly())||
(u->IsFriendly()&&u->CanInteractWithAllies()&&u2->IsFriendly())||
(!u->IsFriendly()&&u->CanInteractWithEnemies()&&u2->IsFriendly())||
(!u->IsFriendly()&&u->CanInteractWithAllies()&&!u2->IsFriendly());
if(canInteract){
geom2d::line<float>unitLine(u->GetPos(),u2->GetPos());
if(unitLine.length()<closestDist){
closestUnit=u2.get();
@ -314,7 +325,7 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
}
}
}
u->AttemptAttack(closestUnit);
u->AttemptAttack(closestUnit,units);
u->_Update(this);
}
game.DrawPartialDecal({0,0},CONSTANT::WORLD_SIZE*CONSTANT::TILE_SIZE,IMAGES[TILE]->Decal(),{0,0},CONSTANT::WORLD_SIZE*CONSTANT::TILE_SIZE,DARK_GREEN);

Loading…
Cancel
Save