diff --git a/olcCodeJam2023Entry/CollectionPoint.h b/olcCodeJam2023Entry/CollectionPoint.h index 891143e..7340236 100644 --- a/olcCodeJam2023Entry/CollectionPoint.h +++ b/olcCodeJam2023Entry/CollectionPoint.h @@ -2,6 +2,8 @@ #include "olcPixelGameEngine.h" #include "MemoryType.h" +class Unit; + class CollectionPoint{ public: vf2d pos; @@ -10,6 +12,7 @@ public: MemoryType type; vf2d randomOffset; float rot; + std::weak_ptrattachedUnit; CollectionPoint(PixelGameEngine*pge,vf2d pos,float rot,Renderable&collectionPointImg,MemoryType type); void Update(PixelGameEngine*pge,Renderable&matrixImg); }; \ No newline at end of file diff --git a/olcCodeJam2023Entry/Constant.cpp b/olcCodeJam2023Entry/Constant.cpp index 0a3f694..aaa0c49 100644 --- a/olcCodeJam2023Entry/Constant.cpp +++ b/olcCodeJam2023Entry/Constant.cpp @@ -7,6 +7,8 @@ Pixel CONSTANT::ATKSPD_COLOR={140, 21, 13}; Pixel CONSTANT::MOVESPD_COLOR={11, 135, 212}; Pixel CONSTANT::PROCEDURE_COLOR={212, 11, 162}; +Pixel CONSTANT::MOVE_LINE_COL={147, 252, 66}; + vf2d CONSTANT::UNSELECTED={-99,-99}; vi2d CONSTANT::TILE_SIZE={24,24}; diff --git a/olcCodeJam2023Entry/Constant.h b/olcCodeJam2023Entry/Constant.h index e45e8df..edfdf0e 100644 --- a/olcCodeJam2023Entry/Constant.h +++ b/olcCodeJam2023Entry/Constant.h @@ -12,6 +12,8 @@ public: static Pixel MOVESPD_COLOR; static Pixel PROCEDURE_COLOR; + static Pixel MOVE_LINE_COL; + static vf2d UNSELECTED; static vi2d TILE_SIZE; diff --git a/olcCodeJam2023Entry/Image.h b/olcCodeJam2023Entry/Image.h index 5979da0..d79000e 100644 --- a/olcCodeJam2023Entry/Image.h +++ b/olcCodeJam2023Entry/Image.h @@ -31,5 +31,6 @@ enum Image{ RNG_ICON, SPD_ICON, RESOURCE, + MEMORY_COLLECTION_POINT_HIGHLIGHT, }; diff --git a/olcCodeJam2023Entry/Unit.cpp b/olcCodeJam2023Entry/Unit.cpp index 4c2d488..714bf64 100644 --- a/olcCodeJam2023Entry/Unit.cpp +++ b/olcCodeJam2023Entry/Unit.cpp @@ -186,7 +186,7 @@ void RAMBank::Update(PixelGameEngine*pge,std::map>& } 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}); + 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); } @@ -270,7 +270,7 @@ void Unit::DrawRangeIndicator(PixelGameEngine*pge,TileTransformedView&game,std:: } 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}); + game.DrawRotatedDecal(ghostPos,img.Decal(),0,img.Sprite()->Size()/2,{1,1},GetUnitColor()); 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); } @@ -338,6 +338,13 @@ void Unit::DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std: lineToTarget.end=lineToTarget.rpoint(lineToTarget.length()-GetUnitSize().x/4); util::ApplyMatrixEffect(game.GetPGE(),targetingLine,*IMAGES[TARGETING_LINE],IMAGES[MATRIX]); game.DrawPartialRotatedDecal(lineToTarget.upoint(0.5),targetingLine.Decal(),lineToTarget.vector().polar().y,{lineToTarget.length()/2,12},{lineShift*10,0},{lineToTarget.length(),24},{1,1},targetLineCol); + } else + if(targetLoc!=CONSTANT::UNSELECTED){ + geom2d::linelineToTarget(pos,targetLoc); + lineToTarget.start=lineToTarget.rpoint(GetUnitSize().x/2); + lineToTarget.end=lineToTarget.rpoint(lineToTarget.length()-GetUnitSize().x/4); + util::ApplyMatrixEffect(game.GetPGE(),targetingLine,*IMAGES[TARGETING_LINE],IMAGES[MATRIX]); + game.DrawPartialRotatedDecal(lineToTarget.upoint(0.5),targetingLine.Decal(),lineToTarget.vector().polar().y,{lineToTarget.length()/2,12},{lineShift*10,0},{lineToTarget.length(),24},{1,0.6},CONSTANT::MOVE_LINE_COL); } if(!appliedTarget.expired()){ geom2d::linelineToTarget(pos,appliedTarget.lock()->pos); @@ -435,6 +442,13 @@ void Unit::_Update(PixelGameEngine*pge,std::map>&SO float dist=geom2d::line(pos,targetLoc).length(); if(dist>24){ SetPos(GetPos()+(targetLoc-pos).norm()*GetMoveSpd()*24*pge->GetElapsedTime()); + } else { + if(willAttachWhenReachingDestination&&!attachTarget.expired()){ + attachedPoint=attachTarget; + attachedPoint.lock()->attachedUnit=self_ptr; + } + willAttachWhenReachingDestination=false; + targetLoc=CONSTANT::UNSELECTED; } } @@ -503,11 +517,13 @@ vf2d Unit::GetUnitSize(){ void Unit::SetTargetUnit(std::weak_ptrtarget){ this->target=target; this->targetLoc=CONSTANT::UNSELECTED; + willAttachWhenReachingDestination=false; } void Unit::SetTargetLocation(vf2d targetLoc){ this->target.reset(); this->targetLoc=targetLoc; + willAttachWhenReachingDestination=false; } bool Unit::InRange(std::shared_ptrtarget){ @@ -617,15 +633,15 @@ vf2d Unit::GetGhostPos(){ } bool Unit::IsMoveable(){ - return moveable; + return moveable&&attachedPoint.expired(); } bool Unit::CanInteractWithAllies(){ - return friendlyInteractable; + return friendlyInteractable&&attachedPoint.expired(); } bool Unit::CanInteractWithEnemies(){ - return enemyInteractable; + return enemyInteractable&&attachedPoint.expired(); } Renderable&Unit::GetImage(){ @@ -638,4 +654,40 @@ std::weak_ptrUnit::GetCurrentTarget(){ bool Unit::AutoAcquiresFriendlyTargets(){ return autoAcquireFriendlyTarget; +} + +bool Unit::CanMove(){ + return moveSpd.size>0&&attachedPoint.expired(); +} + +void Unit::SetTargetCollectionPoint(std::weak_ptrtargetCP,std::weak_ptrself_ptr){ + SetTargetLocation(targetCP.lock()->pos); + attachTarget=targetCP; + willAttachWhenReachingDestination=true; + this->self_ptr=self_ptr; +} + +Pixel Unit::GetUnitColor(){ + Pixel col; + if(!attachedPoint.expired()){ + switch(attachedPoint.lock()->type){ + case HEALTH:{ + return CONSTANT::HEALTH_COLOR/2; + }break; + case RANGE:{ + return CONSTANT::RANGE_COLOR/2; + }break; + case ATKSPD:{ + return CONSTANT::ATKSPD_COLOR/2; + }break; + case MOVESPD:{ + return CONSTANT::MOVESPD_COLOR/2; + }break; + case PROCEDURE:{ + return CONSTANT::PROCEDURE_COLOR/2; + }break; + } + } else { + return friendly?Pixel{192,192,255}:Pixel{255,192,192}; + } } \ No newline at end of file diff --git a/olcCodeJam2023Entry/Unit.h b/olcCodeJam2023Entry/Unit.h index 0f67593..c1cd72e 100644 --- a/olcCodeJam2023Entry/Unit.h +++ b/olcCodeJam2023Entry/Unit.h @@ -65,6 +65,9 @@ public: std::weak_ptrGetCurrentTarget(); void DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std::map>&IMAGES); bool AutoAcquiresFriendlyTargets(); + bool CanMove(); + void SetTargetCollectionPoint(std::weak_ptrtargetCP,std::weak_ptrself_ptr); + Pixel GetUnitColor(); std::vector& operator <<=(const int n){ for(int i=0;iattachedPoint; + std::weak_ptrattachTarget; + bool willAttachWhenReachingDestination=false; + std::weak_ptrself_ptr; }; struct BasicUnit:Unit{ diff --git a/olcCodeJam2023Entry/VirusAttack.cpp b/olcCodeJam2023Entry/VirusAttack.cpp index 407d2b9..be5bf4c 100644 --- a/olcCodeJam2023Entry/VirusAttack.cpp +++ b/olcCodeJam2023Entry/VirusAttack.cpp @@ -47,6 +47,7 @@ void VirusAttack::InitializeImages(){ LoadImage(RNG_ICON,"assets/rng_icon.png"); LoadImage(SPD_ICON,"assets/spd_icon.png"); LoadImage(RESOURCE,"assets/material.png"); + LoadImage(MEMORY_COLLECTION_POINT_HIGHLIGHT,"assets/memory_collection_point_highlight.png"); } bool VirusAttack::OnUserCreate(){ @@ -161,11 +162,25 @@ void VirusAttack::HandleRightClickMove(){ } if(!selectedTarget){ for(auto&u:units){ - if(u->IsFriendly()&&u->IsSelected()){ + if(u->IsFriendly()&&u->IsSelected()&&u->CanMove()){ + //First see if we can attach to a collection point. + for(auto&cp:collectionPoints){ + geom2d::rectcpRect=geom2d::rect({cp->pos-cp->img.Sprite()->Size()/2,cp->img.Sprite()->Size()}); + if(geom2d::overlaps(cpRect,GetWorldMousePos())){ + if(cp->attachedUnit.expired()){ + u->SetTargetCollectionPoint(cp,u); + goto targetFound; //We found a target, so now we can just leave. + } + } + } + + //Okay, nothing to do here. Simply move to the selected position. u->SetTargetLocation(GetWorldMousePos()); } } } + targetFound: + int a; } } @@ -311,23 +326,26 @@ void VirusAttack::RenderCollectionPoints(CollectionPoint*cp){ if(geom2d::overlaps(cpRect,viewRegion)){ Pixel col; switch(cp->type){ - case HEALTH:{ - col=CONSTANT::HEALTH_COLOR; - }break; - case RANGE:{ - col=CONSTANT::RANGE_COLOR; - }break; - case ATKSPD:{ - col=CONSTANT::ATKSPD_COLOR; - }break; - case MOVESPD:{ - col=CONSTANT::MOVESPD_COLOR; - }break; - case PROCEDURE:{ - col=CONSTANT::PROCEDURE_COLOR; - }break; + case HEALTH:{ + col=CONSTANT::HEALTH_COLOR; + }break; + case RANGE:{ + col=CONSTANT::RANGE_COLOR; + }break; + case ATKSPD:{ + col=CONSTANT::ATKSPD_COLOR; + }break; + case MOVESPD:{ + col=CONSTANT::MOVESPD_COLOR; + }break; + case PROCEDURE:{ + col=CONSTANT::PROCEDURE_COLOR; + }break; } game.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); + } } } @@ -416,6 +434,19 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){ DrawSelectionRectangle(); RenderFogOfWar(); + DrawResourceBar(); + + DrawMinimap(); + + std::sort(units.begin(),units.end(),[&](auto&u1,auto&u2){ + float dist1=geom2d::line(u1->GetGhostPos(),GetWorldMousePos()).length(); + float dist2=geom2d::line(u2->GetGhostPos(),GetWorldMousePos()).length(); + return dist1>dist2;}); + + return true; +} + +void VirusAttack::DrawResourceBar(){ GradientFillRectDecal({0,0},{float(ScreenWidth()),12.f},BLACK,{VERY_DARK_BLUE.r,VERY_DARK_BLUE.g,VERY_DARK_BLUE.b,128},{VERY_DARK_BLUE.r,VERY_DARK_BLUE.g,VERY_DARK_BLUE.b,128},BLACK); DrawRectDecal({0,0},{float(ScreenWidth()),12.f},{3, 194, 252}); auto DrawResourceDisplay=[&](int index,int resourceValue,Pixel col){ @@ -427,15 +458,6 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){ DrawResourceDisplay(2,player_resources.moveSpd,CONSTANT::MOVESPD_COLOR); DrawResourceDisplay(3,player_resources.range,CONSTANT::RANGE_COLOR); DrawResourceDisplay(4,player_resources.procedure,CONSTANT::PROCEDURE_COLOR); - - DrawMinimap(); - - std::sort(units.begin(),units.end(),[&](auto&u1,auto&u2){ - float dist1=geom2d::line(u1->GetGhostPos(),GetWorldMousePos()).length(); - float dist2=geom2d::line(u2->GetGhostPos(),GetWorldMousePos()).length(); - return dist1>dist2;}); - - return true; } void VirusAttack::RenderFogOfWar(){ diff --git a/olcCodeJam2023Entry/VirusAttack.h b/olcCodeJam2023Entry/VirusAttack.h index 3eca249..3017654 100644 --- a/olcCodeJam2023Entry/VirusAttack.h +++ b/olcCodeJam2023Entry/VirusAttack.h @@ -29,7 +29,7 @@ class VirusAttack : public olc::PixelGameEngine { private: std::vector>units; - std::vector>collectionPoints; + std::vector>collectionPoints; std::vector>deathAnimations; std::vectordebuffIcons; @@ -63,6 +63,7 @@ private: void RenderCollectionPoints(CollectionPoint*cp); void RenderFogOfWar(); void InitializeSounds(); + void DrawResourceBar(); public: VirusAttack(); diff --git a/olcCodeJam2023Entry/assets/memory_collection_point_highlight.png b/olcCodeJam2023Entry/assets/memory_collection_point_highlight.png new file mode 100644 index 0000000..5b8f7c1 Binary files /dev/null and b/olcCodeJam2023Entry/assets/memory_collection_point_highlight.png differ