#include "Unit.h" #include "Constant.h" #include "olcUTIL_Geometry2D.h" #include "TileManager.h" #include "util.h" BasicUnit::BasicUnit(vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) :Unit({ {HEALTH,4}, {RANGE,2}, {ATKSPD,2}, {MOVESPD,3}, {PROCEDURE,1}, },pos,*IMAGES[VIRUS_IMG1],friendly,moveable){} void BasicUnit::Attack(Unit&victim){ victim<<=1; } BasicUnit2::BasicUnit2(vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) :Unit({ {RANGE,2}, {ATKSPD,2}, {MOVESPD,3}, {PROCEDURE,1}, {HEALTH,4}, },pos,*IMAGES[VIRUS_IMG1],friendly,moveable){} void BasicUnit2::Attack(Unit&victim){ } LeftShifter::LeftShifter(vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) :Unit({ {RANGE,2}, {ATKSPD,2}, {MOVESPD,3}, {PROCEDURE,1}, {HEALTH,4}, },pos,*IMAGES[LEFT_SHIFTER],friendly,moveable){} void LeftShifter::Attack(Unit&victim){ } RightShifter::RightShifter(vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) :Unit({ {HEALTH,4}, {RANGE,2}, {ATKSPD,2}, {MOVESPD,3}, {PROCEDURE,1}, },pos,*IMAGES[RIGHT_SHIFTER],friendly,moveable){} void RightShifter::Attack(Unit&victim){ } BitRestorer::BitRestorer(vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) :Unit({ {PROCEDURE,6}, {RANGE,1}, {ATKSPD,1}, {MOVESPD,1}, {HEALTH,2}, },pos,*IMAGES[BIT_RESTORER],friendly,moveable){} void BitRestorer::Attack(Unit&victim){ } MemorySwapper::MemorySwapper(vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) :Unit({ {RANGE,3}, {ATKSPD,1}, {HEALTH,3}, {PROCEDURE,3}, {MOVESPD,2}, },pos,*IMAGES[MEMORY_SWAPPER],friendly,moveable){} void MemorySwapper::Attack(Unit&victim){ } Corrupter::Corrupter(vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) :Unit({ {ATKSPD,3}, {RANGE,1}, {PROCEDURE,8}, {MOVESPD,4}, {HEALTH,4}, },pos,*IMAGES[CORRUPTER],friendly,moveable){} void Corrupter::Attack(Unit&victim){ } MemoryAllocator::MemoryAllocator(vf2d pos,std::map>&IMAGES,bool friendly,bool moveable) :Unit({ {RANGE,1}, {ATKSPD,1}, {MOVESPD,1}, {PROCEDURE,1}, {HEALTH,1}, },pos,*IMAGES[UNIT_ALLOCATOR],friendly){} void MemoryAllocator::Attack(Unit&victim){ } RAMBank::RAMBank(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly) :Unit({ {RANGE,0}, {ATKSPD,0}, {MOVESPD,0}, {PROCEDURE,25}, {HEALTH,16}, },pos,*IMAGES[RAM_BANK],friendly,false),randomOffset({util::random(128),util::random(128)}),matrixImg(*IMAGES[MATRIX]), originalImg(*IMAGES[RAM_BANK]){ img.Create(IMAGES[RAM_BANK]->Sprite()->width,IMAGES[RAM_BANK]->Sprite()->height); pge->SetDrawTarget(img.Sprite()); pge->Clear(BLANK); pge->DrawSprite({0,0},IMAGES[RAM_BANK]->Sprite()); pge->SetDrawTarget(nullptr); } void RAMBank::Attack(Unit&victim){ } void RAMBank::Update(PixelGameEngine*pge){ pge->SetDrawTarget(img.Sprite()); for(int y=0;yheight;y++){ for(int x=0;xwidth;x++){ Pixel col = originalImg.Sprite()->GetPixel(x,y); if(col==WHITE){ pge->Draw(x,y,matrixImg.Sprite()->GetPixel(int(x+randomOffset.x),int(y+randomOffset.y))); } } } img.Decal()->Update(); pge->SetDrawTarget(nullptr); } void RAMBank::Draw(TileTransformedView&game,std::map>&IMAGES){ game.DrawRotatedDecal(GetGhostPos(),img.Decal(),0,img.Sprite()->Size()/2,{1,1},friendly?Pixel{192,192,255}:Pixel{255,192,192}); 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); } } Unit::Unit(std::vectormemory,vf2d pos,Renderable&img,bool friendly,bool moveable) :pos(pos),ghostPos(pos),img(img),friendly(friendly),moveable(moveable){ int marker=0; for(Memory&mem:memory){ for(int i=0;imemory.push_back(true); this->ghostMemory.push_back(true); } switch(mem.type){ case HEALTH:{ health.index=marker; health.size=mem.size; }break; case RANGE:{ range.index=marker; range.size=mem.size; }break; case ATKSPD:{ atkSpd.index=marker; atkSpd.size=mem.size; }break; case MOVESPD:{ moveSpd.index=marker; moveSpd.size=mem.size; }break; case PROCEDURE:{ procedure.index=marker; procedure.size=mem.size; }break; } marker+=mem.size; } } void Unit::Draw(TileTransformedView&game,std::map>&IMAGES){ game.DrawRotatedDecal(ghostPos,img.Decal(),0,img.Sprite()->Size()/2,{1,1},friendly?Pixel{192,192,255}:Pixel{255,192,192}); if(IsSelected()){ game.DrawRotatedDecal(ghostPos,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>&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; Pixel col=0; auto CheckColor=[&](int i,Pixel&col){ if(health.index==i){ col=CONSTANT::HEALTH_COLOR; } if(range.index==i){ col=CONSTANT::RANGE_COLOR; } if(atkSpd.index==i){ col=CONSTANT::ATKSPD_COLOR; } if(moveSpd.index==i){ col=CONSTANT::MOVESPD_COLOR; } if(procedure.index==i){ col=CONSTANT::PROCEDURE_COLOR; } }; for(int i=0;iGetPos()-pos).norm()*GetMoveSpd()*24*pge->GetElapsedTime()); } else { //TODO Attack here. } } else if(targetLoc!=CONSTANT::UNSELECTED){ float dist=geom2d::line(pos,targetLoc).length(); if(dist>24){ SetPos(GetPos()+(targetLoc-pos).norm()*GetMoveSpd()*24*pge->GetElapsedTime()); } } if(!IsFriendly()){ if(changeDirTimer==0){ changeDirTimer=rand()%30; switch(rand()%4){ case 0:{ movementVel={16,0}; }break; case 1:{ movementVel={0,16}; }break; case 2:{ movementVel={-16,0}; }break; case 3:{ movementVel={0,-16}; }break; } } SetPos(GetPos()+movementVel*pge->GetElapsedTime()); changeDirTimer=std::max(0.f,changeDirTimer-pge->GetElapsedTime()); } if(!GhostInFogOfWar()&&InFogOfWar()){ HideGhost(); } reloadTimer=std::max(0.f,reloadTimer-pge->GetElapsedTime()); Update(pge); } std::vector operator <<(Unit&u,const int n){ std::vectortempMem=u.memory; for(int i=0;i operator >>(Unit&u,const int n){ std::vectortempMem=u.memory; for(int i=1;iSize(); } void Unit::SetTargetUnit(std::weak_ptrtarget){ this->target=target; this->targetLoc=CONSTANT::UNSELECTED; } void Unit::SetTargetLocation(vf2d targetLoc){ this->target.reset(); this->targetLoc=targetLoc; } bool Unit::InRange(std::shared_ptrtarget){ float dist=geom2d::line(GetPos(),target->GetPos()).length(); return dist<24*(GetRange()+1); } bool Unit::InRange(vf2d pos){ float dist=geom2d::line(GetPos(),pos).length(); return dist<24*(GetRange()+1); } void Unit::SetPos(vf2d newPos){ pos=newPos; if(!InFogOfWar()){ ghostPos=pos; } } void Unit::AttemptAttack(Unit*unit){ if(reloadTimer>0)return; Unit*finalTarget=nullptr; if(unit!=nullptr){ finalTarget=unit; if(!target.expired()){ auto ptrTarget=target.lock(); if(InRange(ptrTarget)){ finalTarget=ptrTarget.get(); } } } if(finalTarget!=nullptr){ if(InRange(finalTarget->GetPos())){ _Attack(finalTarget); //Call the parent function first, followed by the child. } } } void Unit::Update(PixelGameEngine*pge){} void Unit::_Attack(Unit*finalTarget){ Attack(*finalTarget); reloadTimer=1.f/(GetAtkSpd()/2.f); } bool Unit::InFogOfWar(){ return TileManager::visibleTiles.count(GetPos()/96)==0; } bool Unit::GhostInFogOfWar(){ return TileManager::visibleTiles.count(ghostPos/96)==0; } void Unit::HideGhost(){ ghostPos={99999,-99999}; } vf2d Unit::GetGhostPos(){ return ghostPos; } bool Unit::IsMoveable(){ return moveable; }