Skip to content

Commit

Permalink
Chase and attack Update
Browse files Browse the repository at this point in the history
  • Loading branch information
ntut-Tu committed Jun 7, 2024
1 parent 1b9c348 commit c78a3e6
Show file tree
Hide file tree
Showing 14 changed files with 141 additions and 37 deletions.
66 changes: 49 additions & 17 deletions include/AI/AIGroupCommander.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef PRACTICALTOOLSFORSIMPLEDESIGN_AIGROUPCOMMANDER_HPP
#define PRACTICALTOOLSFORSIMPLEDESIGN_AIGROUPCOMMANDER_HPP
#include "Mechanics/UnitManager.hpp"
#include "Avatar/Avatar.hpp"
#define GROUP_SIZE 4
#define AUTO_FIND_RANGE 4
#define AUTO_ATTACK_METHOD 2
Expand Down Expand Up @@ -122,31 +123,62 @@ class AIGroupCommander {
}
}
void updateOffensiveTroopAttackTarget(){
for(auto i : m_offensiveGroup){
if(i.size()>0){
if (!m_AIAvatarManager->ifAvatarHasNemesis(i.front())){
for(int i = static_cast<int>(m_offensiveGroup.size());i>0;--i){
auto& currentGroup = m_offensiveGroup[i-1];
printf("(updateOffensiveTroopAttackTarget)groupSize : %d\n",static_cast<int>(currentGroup.size()));
if(!currentGroup.empty()){
if (!m_AIAvatarManager->ifAvatarHasNemesis(currentGroup.front())){
// find new target
if(m_PlayerUnitManager->getAvatarCount()==0){
return;
}
glm::vec2 targetCell = m_Map->findEnemyInRange(
100, i.front()->getCurrentLocationInCell(),
HouseType::ENEMY);
if (targetCell.x == -1 && targetCell.y == -1) {
return;
glm::vec2 targetCell = findTargetForOffensiveUnit(currentGroup.front());
if(targetCell.x==-1.f){
printf("(updateOffensiveTroopAttackTarget) No Target\n");
break;
}
// attack
for (int j=static_cast<int>(i.size());j>0;--j) {
if(i[j-1]->getHealth()->ifDead()){
i.erase(i.begin()+j-1);
for (int j=static_cast<int>(currentGroup.size());j>0;--j) {
if(currentGroup[j-1]->getHealth()->ifDead()){
currentGroup.erase(currentGroup.begin()+j-1);
}else{
m_AIAvatarManager->assignAttackOrderToAvatar(
currentGroup[j-1], targetCell,HouseType::ENEMY);
}
m_AIAvatarManager->assignMoveOrderToAvatar(i[j-1],targetCell);
m_AIAvatarManager->assignAttackOrderToAvatar(
i[j-1], targetCell,HouseType::ENEMY);
}
}else{
glm::vec2 targetCell = m_AIAvatarManager->getAvatarNemesisCell(currentGroup.front());
printf("(updateOffensiveTroopAttackTarget)AvatarHasNemesis : {%d,%d}\n",static_cast<int>(targetCell.x),static_cast<int>(targetCell.y));
}
}else{
m_offensiveGroup.erase(m_offensiveGroup.begin()+i-1);
}
}
}

glm::vec2 findTargetForOffensiveUnit(std::shared_ptr<Avatar> unit){
glm::vec2 targetCell = {-1.f,-1.f};
//issue: empty group should delete before this
if(false&&static_cast<int>(m_offensiveGroup.size())>=static_cast<int>(m_PlayerUnitManager->getAvatarManager()->getAvatarArray().size())){
if(!m_PlayerUnitManager->getStructureManager()->getStructureArray()->getBuiltStructureArray().empty()){
targetCell=m_PlayerUnitManager->getStructureManager()->getStructureArray()->getBuiltStructureArray().front()->getCurrentLocationInCell();
}
for(auto i : m_PlayerUnitManager->getStructureManager()->getStructureArray()->getBuiltStructureArray()){
if(unit->getDistance(i->getCurrentLocationInCell())<unit->getDistance(targetCell)){
//attack
targetCell = i->getCurrentLocationInCell();
}
}
}else{
if(!m_PlayerUnitManager->getAvatarManager()->getAvatarArray().empty()){
targetCell=m_PlayerUnitManager->getAvatarManager()->getAvatarArray().front()->getCurrentLocationInCell();
}
for(auto i : m_PlayerUnitManager->getAvatarManager()->getAvatarArray()){
if(i->getDistance(unit->getCurrentLocationInCell())<unit->getDistance(targetCell)){
//attack
targetCell = i->getCurrentLocationInCell();
}
}
}
printf("(findTargetForOffensiveUnit) TargetCell : {%d,%d}\n",targetCell.x,targetCell.y);
return targetCell;
}
};

Expand Down
2 changes: 1 addition & 1 deletion include/Avatar/AvatarOrder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#ifndef PRACTICALTOOLSFORSIMPLEDESIGN_AVATARORDER_HPP
#define PRACTICALTOOLSFORSIMPLEDESIGN_AVATARORDER_HPP
enum class AvatarOrderType { SPAWNED, OPEN_FIRE, MOVE, NO_ORDER, TAKEN_DAMAGE };
enum class AvatarOrderType { SPAWNED, OPEN_FIRE,CHASE, MOVE, NO_ORDER, TAKEN_DAMAGE };
class AvatarOrder {
public:
AvatarOrder() {}
Expand Down
2 changes: 2 additions & 0 deletions include/Avatar/PathUtility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class PathUtility {
MoveDirection currentdir);
static MoveDirection findNewDirWhenCrash(Side side, glm::vec2 currentcell,
MoveDirection currentdir);
static std::string debug_dirToString(MoveDirection dir);

};

#endif // PRACTICALTOOLSFORSIMPLEDESIGN_PATHUTILITY_HPP
3 changes: 3 additions & 0 deletions include/Mechanics/AvatarManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class AvatarManager {
bool ifAvatarHasNemesis(std::shared_ptr<Avatar> unit){
return m_NemesisManager->ifAvatarHasNemesis(unit);
}
glm::vec2 getAvatarNemesisCell(std::shared_ptr<Avatar> unit){
return m_NemesisManager->getNemesisCell(unit);
}
protected:
void assignOrderToMyAvatar(std::shared_ptr<Avatar> unit);
void updateTileWhileAvatarMoving(std::shared_ptr<Avatar> unit);
Expand Down
1 change: 1 addition & 0 deletions include/Mechanics/AvatarNavigator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ class AvatarNavigator {

private:
std::shared_ptr<MapClass> m_Map = std::make_shared<MapClass>();
MoveDirection recursionCrashHandler(MoveDirection currentDir,int count);
};
#endif // PRACTICALTOOLSFORSIMPLEDESIGN_AVATARNAVIGATOR_HPP
6 changes: 6 additions & 0 deletions include/Mechanics/NemesisManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ class NemesisManager {
return false;
}
}
glm::vec2 getNemesisCell(std::shared_ptr<Avatar> avatar){
if(!ifAvatarHasNemesis(avatar)){
return {-1.f,-1.f};
}
return m_Nemesis[avatar]->getCurrentLocationInCell();
}
bool ifNemesisWithinWeaponRange(std::shared_ptr<Avatar> hunter) {
if (ifAvatarHasNemesis(hunter) == false) {
return false;
Expand Down
5 changes: 2 additions & 3 deletions include/Mechanics/UnitManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ class UnitManager : public Player {

m_AvatarManager->Start(m_Map);
m_CursorSelection->Start(m_Map);
m_StartTime = std::chrono::high_resolution_clock::now();
}

void Update();
Expand Down Expand Up @@ -79,8 +78,8 @@ class UnitManager : public Player {
std::shared_ptr<AvatarManager> m_AvatarManager =
std::make_shared<AvatarManager>();
std::shared_ptr<MapClass> m_Map = std::make_shared<MapClass>();
std::chrono::high_resolution_clock::time_point m_StartTime;
double m_lastElapsed = 0.F;
float m_mainDeltaTime = 0;
Util::Time m_Time;
};

#endif // PRACTICALTOOLSFORSIMPLEDESIGN_UNITMANAGER_HPP
2 changes: 1 addition & 1 deletion src/AI/EnemyScripts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ void EnemyScripts::buildADV() {

void EnemyScripts::spawnUnit() {
if (m_selectedAvatarType != UnitType::NONE ||
m_EnemyObjectManager->getAvatarCount() > 50) {
m_EnemyObjectManager->getAvatarCount() > 16) {
return;
}
if (m_EnemyObjectManager->getAvatarCount() <= 25 &&
Expand Down
6 changes: 6 additions & 0 deletions src/Avatar/Avatar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ void Avatar::Update() {
getAvatarOrder()->setAvatarOrder(AvatarOrderType::NO_ORDER);
}
} else if (getAvatarOrder()->getAvatarOrder() ==
AvatarOrderType::CHASE) {
m_Moving->moveUpdate();
if (getMoving()->getCurrentDir() == MoveDirection::IDLE) {
getAvatarOrder()->setAvatarOrder(AvatarOrderType::NO_ORDER);
}
}else if (getAvatarOrder()->getAvatarOrder() ==
AvatarOrderType::NO_ORDER) {
noorderUpdate();
} else if (getAvatarOrder()->getAvatarOrder() ==
Expand Down
30 changes: 27 additions & 3 deletions src/Avatar/PathUtility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,6 @@ MoveDirection PathUtility::getDirByRelativeCells(glm::vec2 currentcell,
int destinationCellY = destinationcell.y;
int currCellX = currentcell.x;
int currCellY = currentcell.y;
printf("(findNextCellDir)Cell now :{%.d,%.d}\n(find)Cell destination : "
"{%.d,%.d}\n",
currCellX, currCellY, destinationCellX, destinationCellY);
int xDiff = destinationCellX - currCellX;
int yDiff = destinationCellY - currCellY;
int xAbs = abs(xDiff);
Expand Down Expand Up @@ -125,8 +122,35 @@ MoveDirection PathUtility::getDirByRelativeCells(glm::vec2 currentcell,
}
}
}
printf("-----\n(PathUtil)Cell now :{%.d,%.d}\n(PathUtil)Cell destination : "
"{%.d,%.d}\n(PathUtil)Dir : %s\n-----\n",
currCellX, currCellY, destinationCellX, destinationCellY,debug_dirToString(direction).c_str());
return direction;
}
std::string PathUtility::debug_dirToString(MoveDirection dir){
switch (dir) {
case MoveDirection::UP:
return "Up";
case MoveDirection::UP_RIGHT:
return "Up Right";
case MoveDirection::UP_LEFT:
return "Up Left";
case MoveDirection::RIGHT:
return "Right";
case MoveDirection::LEFT:
return "Left";
case MoveDirection::DOWN_RIGHT:
return "Down Right";
case MoveDirection::DOWN_LEFT:
return "Down Left";
case MoveDirection::DOWN:
return "Down";
case MoveDirection::IDLE:
return "Idle";
default:
return "Unknown";
}
}

glm::vec2 PathUtility::getNextCellByCurrent(MoveDirection currentdir,
glm::vec2 currentcell) {
Expand Down
17 changes: 17 additions & 0 deletions src/Mechanics/AvatarManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ void AvatarManager::Update() {
updateTileWhileAvatarMoving(m_AvatarArray[i]);
}

if (m_AvatarArray[i]->getAvatarOrder()->getAvatarOrder() ==
AvatarOrderType::CHASE) {
updateTileWhileAvatarMoving(m_AvatarArray[i]);
}

if(m_AvatarArray[i]->getAvatarOrder()->getAvatarOrder()==AvatarOrderType::CHASE && m_AvatarArray[i]->getMoving()->ifMovePathEmpty()){
glm::vec2 targetCell = m_NemesisManager->getNemesisCell(m_AvatarArray[i]);
auto queue =
m_Navigator->findPath(m_AvatarArray[i]->getMoving()->getCurrentCell(), targetCell);
m_AvatarArray[i]->getMoving()->setMovePath(queue);
m_AvatarArray[i]->getAvatarOrder()->setAvatarOrder(AvatarOrderType::CHASE);
}

// give order to avatar
if (m_AvatarArray[i]->getSelected()) {
assignOrderToMyAvatar(m_AvatarArray[i]);
Expand Down Expand Up @@ -67,6 +80,10 @@ void AvatarManager::assignAttackOrderToAvatar(std::shared_ptr<Avatar> avatar,
avatar,
m_Map->getTileByCellPosition(destcell)->getAvatars()[0]);
}
auto queue =
m_Navigator->findPath(avatar->getMoving()->getCurrentCell(), destcell);
avatar->getMoving()->setMovePath(queue);
avatar->getAvatarOrder()->setAvatarOrder(AvatarOrderType::CHASE);
}
}

Expand Down
22 changes: 19 additions & 3 deletions src/Mechanics/AvatarNavigator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ std::deque<MoveDirection> AvatarNavigator::findPath(glm::vec2 currentcell,

Side whichSideToTouchObstacle = randomlyChooseSide();

while (currentcell != destinationcell) {
int count = 0;
while (currentcell != destinationcell && count<100) {
printf("(findPath)\n");
count++;
std::vector<MoveDirection> staightDirque;
bool canFindStraightPath =
findStraightPath(currentcell, destinationcell, &staightDirque);
Expand All @@ -27,6 +30,7 @@ std::deque<MoveDirection> AvatarNavigator::findPath(glm::vec2 currentcell,
}
break;
} else {

auto facingDir = PathUtility::getDirByRelativeCells(
currentcell, destinationcell);
// turn
Expand Down Expand Up @@ -57,7 +61,7 @@ AvatarNavigator::moveAlongsideObstacle(Side side, glm::vec2 currentcell,

std::vector<MoveDirection> path;
while (!canResumeWalkingStraight(currentcell, destinationcell)) {

printf("(moveAlongsideObstacle)\n");
// if next is not touched by obstacle, turn
if (!isTouchedByObstacle(side, currentcell, currentdir)) {
currentdir = PathUtility::findNewDirWhenNotTouchedByObstacle(
Expand All @@ -79,6 +83,7 @@ MoveDirection AvatarNavigator::findNewDirWhenCrash(Side side,
glm::vec2 currentcell,
MoveDirection currentdir) {
MoveDirection newdir = currentdir;
int crashCount = 0;
while (m_Map
->getTileByCellPosition(
PathUtility::getNextCellByCurrent(newdir, currentcell))
Expand Down Expand Up @@ -153,10 +158,20 @@ MoveDirection AvatarNavigator::findNewDirWhenCrash(Side side,
break;
}
}
// newdir=recursionCrashHandler(newdir,crashCount);
crashCount++;
}
return newdir;
}

MoveDirection AvatarNavigator::recursionCrashHandler(MoveDirection currentDir,int count){
int enumSize = 8;
int newDirValue = (static_cast<int>(currentDir) + count) % enumSize;
if (newDirValue < 0) {
newDirValue += enumSize;
}
printf("(recursionCrashHandler)crashCount : %d\n",count);
return static_cast<MoveDirection>(newDirValue);
}
bool AvatarNavigator::isTouchedByObstacle(Side side, glm::vec2 currentcell,
MoveDirection currentdir) {
currentcell = PathUtility::getNextCellByCurrent(currentdir, currentcell);
Expand Down Expand Up @@ -262,6 +277,7 @@ bool AvatarNavigator::findStraightPath(glm::vec2 currentcell,
std::vector<MoveDirection> *path) {

while (currentcell != destinationcell) {
printf("(findStraightPath)\n");
MoveDirection followingDir =
PathUtility::getDirByRelativeCells(currentcell, destinationcell);

Expand Down
10 changes: 4 additions & 6 deletions src/Mechanics/UnitManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,12 @@ void UnitManager::Update() {
m_AvatarManager->Update();
m_CursorSelection->Update();

m_mainDeltaTime += m_Time.GetDeltaTime();
// currency update
std::chrono::high_resolution_clock::time_point m_currentTime =
std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = m_currentTime - m_StartTime;
if (elapsed.count() - m_lastElapsed >= 1) { // update every second
m_lastElapsed = elapsed.count();
if (m_mainDeltaTime >= 1) {
m_mainDeltaTime = 0;
updateCurrency();
}

m_StructureManager->SelectingBuildSite();
}

Expand Down
6 changes: 3 additions & 3 deletions src/Scene/SandBoxScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ void SandBoxScene::stageStart() {
break;
}
case Stages::STAGE4: {
m_GameObjectManager->spawn( UnitType::BARRACKS, HouseType::MY,{5,5});
m_GameObjectManager->spawn(UnitType::INFANTRY, HouseType::MY, {5, 7});
m_GameObjectManager->spawn(UnitType::INFANTRY, HouseType::MY, {5, 6});
m_GameObjectManager->spawn( UnitType::BARRACKS, HouseType::MY,{7,5});
m_GameObjectManager->spawn(UnitType::INFANTRY, HouseType::MY, {7, 9});
m_GameObjectManager->spawn(UnitType::INFANTRY, HouseType::MY, {7, 8});
m_stage = Stages::END;
break;
}
Expand Down

0 comments on commit c78a3e6

Please sign in to comment.