From 7361fbcd6f24d80a8443d0ac33ee6f5ad40f4874 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sat, 3 Feb 2024 15:38:45 +0200 Subject: [PATCH 1/7] CPU players build a fort and train 2 engineers --- Assets/Scripts/Core/player.lua | 108 ++++++++------------------------- activeGameState.cpp | 18 ++++-- activeGameState.h | 1 + gameManager.cpp | 5 +- player.cpp | 45 ++++++++++---- player.h | 3 +- trainButton.cpp | 5 +- 7 files changed, 81 insertions(+), 104 deletions(-) diff --git a/Assets/Scripts/Core/player.lua b/Assets/Scripts/Core/player.lua index 8195c91..6e5a1ce 100644 --- a/Assets/Scripts/Core/player.lua +++ b/Assets/Scripts/Core/player.lua @@ -1,106 +1,48 @@ -Player.sizeTaskForce = 5 -Player.trainingStarted = false -Player.taskForceSent = false -Player.buildOrdered = false +Player.numStartEngis = 3 +Player.startedFort = false -function Player:sendTaskForce() - if self.taskForceSent then +function Player:buildFort() + if self.startedFort then return true end - self:deselectUnits() - taskForce = {} + engis = self:getUnitsByClass(UnitClass.ENGINEER, 1) - for i = 1, self:getNumUnits() do - if self:getUnit(i - 1):getUnitClass() == UnitClass.TANK then - taskForce[#taskForce + 1] = self:getUnit(i - 1) - end - end - - if #taskForce >= self.sizeTaskForce then - self.taskForceSent = true - self:selectUnits(taskForce) - self:issueOrder(2, Vector3:new(0, 0, 0), {Target:new(nil, Vector3:new(0, 0, 0))}, false) - return true - else + if #engis == 0 then return false end + + engineer = engis[1] + self:selectUnits({engineer}) + + fort = GameObjectFactory.createUnit(self, UnitId.FORT, engineer:getPos(), Quaternion:new(1, 0, 0, 0), 0) + self:addUnit(fort) + self:issueOrder(1, Vector3:new(0, 0, 0), {Target:new(fort, Vector3:new(0, 0, 0))}, false) + + self.startedFort = true + return true end -function Player:trainTaskForce() - if self.trainingStarted then - return true - end +function Player:trainEngineers() + forts = self:getUnitsByClass(UnitClass.FORT, 1) - landFactory = nil - - for i = 1, self:getNumUnits() do - if self:getUnit(i - 1):getUnitClass() == UnitClass.LAND_FACTORY then - landFactory = self:getUnit(i - 1):toFactory() - break - end - end - - if landFactory ~= nil then - print('Training...') - for i = 1, self.sizeTaskForce do - landFactory:appendToQueue(UnitClass.TANK) - end - - self.trainingStarted = true - return true - else + if #forts == 0 or (#forts > 0 and forts[1]:toFactory():getBuildStatus() < 100) then return false end - -end -function Player:selectEngi() - taskForce = self:getSelectedUnitsByClass(UnitClass.ENGINEER) + fort = forts[1]:toFactory() - if #taskForce == 0 then - for i = 1, self:getNumUnits() do - if self:getUnit(i - 1):getUnitClass() == UnitClass.ENGINEER then - taskForce = {self:getUnit(i - 1)} - self:selectUnits(taskForce) - break - end - end + while #fort:getQueue() + #self:getUnitsByClass(UnitClass.ENGINEER, -1) < self.numStartEngis do + fort:appendToQueue(UnitId.ENGINEER) end - return #taskForce > 0 -end - -function Player:issueBuildOrder() - if self.buildOrdered then - return true - end - - for i = 1, self:getNumUnits() do - if self:getUnit(i - 1):getUnitClass() == UnitClass.LAND_FACTORY then - return true - end - end - - spawnPoint = self:getSpawnPoint() - structure = GameObjectFactory.createUnit(self, UnitId.LAND_FACTORY, spawnPoint, Quaternion:new(1, 0, 0, 0), 0) - self:addUnit(structure) - - self:issueOrder(1, Vector3:new(0, 0, 0), {Target:new(structure, Vector3:new(0, 0, 0))}, false) - self.buildOrdered = true return true end Player.behaviour = { - type = BTNodeType.SELECTOR, + type = BTNodeType.SEQUENCE, children = { - {type = BTNodeType.FUNCTION, func = 'sendTaskForce'}, - {type = BTNodeType.FUNCTION, func = 'trainTaskForce'}, - { - type = BTNodeType.SEQUENCE, children = { - {type = BTNodeType.FUNCTION, func = 'selectEngi'}, - {type = BTNodeType.FUNCTION, func = 'issueBuildOrder'}, - } - } + {type = BTNodeType.FUNCTION, func = 'buildFort'}, + {type = BTNodeType.FUNCTION, func = 'trainEngineers'}, } } diff --git a/activeGameState.cpp b/activeGameState.cpp index 0d9823d..8978eff 100755 --- a/activeGameState.cpp +++ b/activeGameState.cpp @@ -163,6 +163,16 @@ namespace battleship{ buttons.clear(); } + bool ActiveGameState::selectedUnitsAmongst(vector units){ + vector selUnits = mainPlayer->getSelectedUnits(); + + for(Unit *unit : units) + if(find(selUnits.begin(), selUnits.end(), unit) != selUnits.end()) + return true; + + return false; + } + //TODO fix fog of war for hostile units void ActiveGameState::renderUnits() { vector units; @@ -192,13 +202,13 @@ namespace battleship{ Vector2 pos = u->getScreenPos(); if(buttons.empty()){ - if(!mainPlayer->getSelectedUnitsByClass(UnitClass::ENGINEER).empty()) + if(selectedUnitsAmongst(mainPlayer->getUnitsByClass(UnitClass::ENGINEER))) guiManager->readLuaScreenScript("engineerCommands.lua", buttons, listboxes, checkboxes, sliders, textboxes, guiRects, texts); - else if(!mainPlayer->getSelectedUnitsByClass(UnitClass::FORT).empty()) + else if(selectedUnitsAmongst(mainPlayer->getUnitsByClass(UnitClass::FORT))) guiManager->readLuaScreenScript("fortCommands.lua", buttons, listboxes, checkboxes, sliders, textboxes, guiRects, texts); - else if(!mainPlayer->getSelectedUnitsByClass(UnitClass::LAND_FACTORY).empty()) + else if(selectedUnitsAmongst(mainPlayer->getUnitsByClass(UnitClass::LAND_FACTORY))) guiManager->readLuaScreenScript("landFactoryCommands.lua", buttons, listboxes, checkboxes, sliders, textboxes, guiRects, texts); - else if(!mainPlayer->getSelectedUnitsByClass(UnitClass::NAVAL_FACTORY).empty()) + else if(selectedUnitsAmongst(mainPlayer->getUnitsByClass(UnitClass::NAVAL_FACTORY))) guiManager->readLuaScreenScript("navalFactoryCommands.lua", buttons, listboxes, checkboxes, sliders, textboxes, guiRects, texts); } diff --git a/activeGameState.h b/activeGameState.h index 2298261..35196c4 100755 --- a/activeGameState.h +++ b/activeGameState.h @@ -31,6 +31,7 @@ namespace battleship{ inline Player* getPlayer(){return mainPlayer;} inline std::vector& getUnitGroup(int i){return unitGroups[i];} private: + bool selectedUnitsAmongst(std::vector); void updateGameObjHoveredOn(); void initDragbox(); void removeDragbox(); diff --git a/gameManager.cpp b/gameManager.cpp index 699552d..af5cc8b 100755 --- a/gameManager.cpp +++ b/gameManager.cpp @@ -54,6 +54,7 @@ namespace battleship{ SOL_LUA_STATE.new_usertype( "Unit", sol::constructors(), + "getPos", &GameObject::getPos, "getUnitClass", &Unit::getUnitClass, "toEngineer", &Unit::toEngineer, "toPointDefense", &Unit::toPointDefense, @@ -63,6 +64,7 @@ namespace battleship{ SOL_LUA_STATE.new_usertype( "Factory", sol::constructors(), "appendToQueue", &Factory::appendToQueue, + "getBuildStatus", &Structure::getBuildStatus, "getQueue", &Factory::getQueue ); @@ -75,7 +77,8 @@ namespace battleship{ "selectUnits", &Player::selectUnits, "deselectUnits", &Player::deselectUnits, "getSpawnPoint", &Player::getSpawnPoint, - "getSelectedUnitsByClass", &Player::getSelectedUnitsByClass + "getUnitsById", &Player::getUnitsById, + "getUnitsByClass", &Player::getUnitsByClass ); SOL_LUA_STATE.new_usertype( diff --git a/player.cpp b/player.cpp index f7a2be1..57dfca1 100755 --- a/player.cpp +++ b/player.cpp @@ -11,7 +11,7 @@ namespace battleship{ using namespace gameBase; using namespace std; - Player::Player(int diff, int fac, int t, Vector3 col, bool cpuPl, Vector3 sp, string n) : difficulty(diff), faction(fac), team(t), color(col), cpuPlayer(cpuPl), spawnPoint(sp), name(n) {} + Player::Player(int diff, int fac, int t, Vector3 col, bool cpuPl, Vector3 sp, string n) : difficulty(diff), faction(fac), team(t), color(col), cpuPlayer(cpuPl), spawnPoint(sp), name(n), refineds(10000) {} Player::~Player() {} @@ -144,20 +144,39 @@ namespace battleship{ projectiles.erase(projectiles.begin() + id); } - vector Player::getSelectedUnitsByClass(UnitClass uc){ - vector selectedUnits = getSelectedUnits(), unitsByClass; - - for(Unit *u : selectedUnits) - if(u->getUnitClass() == uc) - unitsByClass.push_back(u); - - return unitsByClass; + void Player::selectUnits(vector selUnits){ + for(Unit *u : selUnits) + if(find(selectedUnits.begin(), selectedUnits.end(), u) == selectedUnits.end()){ + selectedUnits.push_back(u); + u->select(); + } } - void Player::selectUnits(vector selUnits){ - for(Unit *u : selUnits){ - selectedUnits.push_back(u); - u->select(); + vector Player::getUnitsById(int id, int numUnits){ + vector idUnits; + + for(Unit *unit : units){ + if(numUnits != -1 && idUnits.size() == numUnits) + break; + + if(unit->getId() == id) + idUnits.push_back(unit); } + + return idUnits; + } + + vector Player::getUnitsByClass(UnitClass uc, int numUnits){ + vector ucUnits; + + for(Unit *unit : units){ + if(numUnits != -1 && ucUnits.size() == numUnits) + break; + + if(unit->getUnitClass() == uc) + ucUnits.push_back(unit); + } + + return ucUnits; } } diff --git a/player.h b/player.h index a1b39f3..a5af80b 100755 --- a/player.h +++ b/player.h @@ -22,8 +22,9 @@ namespace battleship{ void removeProjectile(int); void removeProjectile(Projectile*); bool isThisPlayersUnit(GameObject*); - std::vector getSelectedUnitsByClass(UnitClass); void selectUnits(std::vector); + std::vector getUnitsById(int, int = -1); + std::vector getUnitsByClass(UnitClass, int = -1); inline void deselectUnits(){selectedUnits.clear();} inline Unit* getSelectedUnit(int id){return selectedUnits[id];} inline std::vector getSelectedUnits(){return selectedUnits;} diff --git a/trainButton.cpp b/trainButton.cpp index 3bb3ab1..436c84c 100644 --- a/trainButton.cpp +++ b/trainButton.cpp @@ -19,9 +19,10 @@ namespace battleship{ ActiveGameState *activeState = (ActiveGameState*)(GameManager::getSingleton()->getStateManager()->getAppStateByType((int)AppStateType::ACTIVE_STATE)); Player *player = activeState->getPlayer(); UnitClass facClass = (UnitClass)generateView()["units"][factoryId + 1]["unitClass"]; - vector factories = player->getSelectedUnitsByClass(facClass); + vector selUnits = player->getSelectedUnits(), factories = player->getUnitsByClass(facClass); for(Unit *fac : factories) - ((Factory*)fac)->appendToQueue(trainableUnitId); + if(find(selUnits.begin(), selUnits.end(), fac) != selUnits.end()) + ((Factory*)fac)->appendToQueue(trainableUnitId); } } From e6c250ed0975886302c5dc1bc28618390fdc1414 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sun, 4 Feb 2024 15:18:06 +0200 Subject: [PATCH 2/7] CPU AI builds a refinery, land factory, an extractor and starts harvesting corrected harvester unit type --- Assets/Scripts/Core/player.lua | 125 ++++++++++++++++++ Assets/Scripts/GameObjects/Units/unitData.lua | 2 +- Assets/Scripts/Gui/playerSelection.lua | 62 +++++++++ gameManager.cpp | 19 ++- 4 files changed, 204 insertions(+), 4 deletions(-) create mode 100644 Assets/Scripts/Gui/playerSelection.lua diff --git a/Assets/Scripts/Core/player.lua b/Assets/Scripts/Core/player.lua index 6e5a1ce..f8fdb2c 100644 --- a/Assets/Scripts/Core/player.lua +++ b/Assets/Scripts/Core/player.lua @@ -1,5 +1,16 @@ Player.numStartEngis = 3 +Player.dirToCenter = nil Player.startedFort = false +Player.finishedFort = false +Player.startedRefinery = false +Player.finishedRefinery = false +Player.startedLandFactory = false +Player.finishedLandFactory = false +Player.startedNavalFactory = false +Player.finishedNavalFactory = false +Player.startedExtractor = false +Player.finishedExtractor = false +Player.startedHarvesting = false function Player:buildFort() if self.startedFort then @@ -31,11 +42,120 @@ function Player:trainEngineers() end fort = forts[1]:toFactory() + dirToCenter = Vector3:new(0, 0, 0):subtr(fort:getPos()):norm() while #fort:getQueue() + #self:getUnitsByClass(UnitClass.ENGINEER, -1) < self.numStartEngis do fort:appendToQueue(UnitId.ENGINEER) end + return #self:getUnitsByClass(UnitClass.ENGINEER, -1) == 3 +end + +function Player:buildExtractor() + if self.startedExtractor then + return true + end + + engineer = self:getUnitsByClass(UnitClass.ENGINEER, -1)[1] + self:deselectUnits() + self:selectUnits({engineer}) + + deposits = self:getResourceDeposits() + depPos = nil + + if #deposits > 0 then + depPos = deposits[1]:getPos() + end + + if depPos == nil then + return false + end + + extractor = GameObjectFactory.createUnit(self, UnitId.EXTRACTOR, depPos, Quaternion:new(1, 0, 0, 0), 0) + self:addUnit(extractor) + self:issueOrder(1, Vector3:new(0, 0, 0), {Target:new(extractor, Vector3:new(0, 0, 0))}, false) + self.startedExtractor = true + + return true +end + +function Player:startBuilding(buildingId, engiId, angle) + engineer = self:getUnitsByClass(UnitClass.ENGINEER, -1)[engiId] + self:deselectUnits() + self:selectUnits({engineer}) + + dirVec = Quaternion:new(angle, Vector3:new(0, 1, 0)):multVec(dirToCenter) + refPos = self:getSpawnPoint():add(dirVec:mult(20)) + refinery = GameObjectFactory.createUnit(self, buildingId, refPos, Quaternion:new(1, 0, 0, 0), 0) + self:addUnit(refinery) + self:issueOrder(1, Vector3:new(0, 0, 0), {Target:new(refinery, Vector3:new(0, 0, 0))}, false) +end + +function Player:buildRefinery() + if not self.startedRefinery then + self.startedRefinery = true + self:startBuilding(UnitId.REFINERY, 2, -.6) + end + + if not self.finishedRefinery then + refTable = self:getUnitsByClass(UnitClass.REFINERY, 1) + + if #refTable == 1 and refTable[1]:toFactory():getBuildStatus() == 100 then + self.finishedRefinery = true + end + end + + return self.finishedRefinery +end + +function Player:buildLandFactory() + if not self.startedLandFactory then + self.startedLandFactory = true + self:startBuilding(UnitId.LAND_FACTORY, 3, .6) + end + + if not self.finishedLandFactory then + facTable = self:getUnitsByClass(UnitClass.LAND_FACTORY, 1) + + if #facTable == 1 and facTable[1]:toFactory():getBuildStatus() == 100 then + self.finishedLandFactory = true + end + end + + return self.finishedLandFactory +end + +function Player:buildHarvester() + if #self:getUnitsByClass(UnitClass.RESOURCE_ROVER, 1) > 0 then + return true + end + + landFactories = self:getUnitsByClass(UnitClass.LAND_FACTORY, 1) + if #landFactories == 0 then return false end + + factory = landFactories[1]:toFactory() + + if #factory:getQueue() == 0 then + factory:appendToQueue(UnitId.RESOURCE_ROVER) + end + + return true +end + +function Player:startHarvesting() + if self.startedHarvesting then return true end + + harvs = self:getUnitsByClass(UnitClass.RESOURCE_ROVER, 1) + extrs = self:getUnitsByClass(UnitClass.EXTRACTOR, 1) + + if #harvs == 0 or (#extrs == 0) then return false end + + self:deselectUnits() + self:selectUnits({harvs[1]}) + self:issueOrder(7, Vector3:new(0, 0, 0), {Target:new(extrs[1], Vector3:new(0, 0, 0))}, false) + + self.startedHarvesting = true + return true end @@ -44,5 +164,10 @@ Player.behaviour = { children = { {type = BTNodeType.FUNCTION, func = 'buildFort'}, {type = BTNodeType.FUNCTION, func = 'trainEngineers'}, + {type = BTNodeType.FUNCTION, func = 'buildExtractor'}, + {type = BTNodeType.FUNCTION, func = 'buildRefinery'}, + {type = BTNodeType.FUNCTION, func = 'buildLandFactory'}, + {type = BTNodeType.FUNCTION, func = 'buildHarvester'}, + {type = BTNodeType.FUNCTION, func = 'startHarvesting'}, } } diff --git a/Assets/Scripts/GameObjects/Units/unitData.lua b/Assets/Scripts/GameObjects/Units/unitData.lua index 68af32a..da3696f 100644 --- a/Assets/Scripts/GameObjects/Units/unitData.lua +++ b/Assets/Scripts/GameObjects/Units/unitData.lua @@ -194,7 +194,7 @@ units = { { weapons = {}, unitClass = UnitClass.RESOURCE_ROVER, - unitType = UnitType.SEA_LEVEL, + unitType = UnitType.HOVER, armor = {ArmorType.CAST}, isVehicle = true, health = 500, diff --git a/Assets/Scripts/Gui/playerSelection.lua b/Assets/Scripts/Gui/playerSelection.lua new file mode 100644 index 0000000..3857ed9 --- /dev/null +++ b/Assets/Scripts/Gui/playerSelection.lua @@ -0,0 +1,62 @@ +Pos = {x = 110, y = 150} +Size = {x = 100, y = 20} +space = 60 + +gui = { + { + pos = Pos, + size = Size, + guiType = GuiType.LISTBOX, + numMaxDisplay = 3, + listboxType = ListboxType.FACTIONS + }, + { + pos = {x = Pos.x, y = Pos.y + Size.y + space}, + size = Size, + guiType = GuiType.LISTBOX, + numMaxDisplay = 3, + listboxType = ListboxType.FACTIONS + }, + { + pos = {x = Pos.x, y = Pos.y + 2 * (Size.y + space)}, + size = Size, + guiType = GuiType.LISTBOX, + numMaxDisplay = 3, + listboxType = ListboxType.FACTIONS + }, + { + pos = {x = Pos.x, y = Pos.y + 3 * (Size.y + space)}, + size = Size, + guiType = GuiType.LISTBOX, + numMaxDisplay = 3, + listboxType = ListboxType.FACTIONS + }, + { + pos = {x = Pos.x, y = Pos.y + 4 * (Size.y + space)}, + size = Size, + guiType = GuiType.LISTBOX, + numMaxDisplay = 3, + listboxType = ListboxType.FACTIONS + }, + { + pos = {x = Pos.x, y = Pos.y + 5 * (Size.y + space)}, + size = Size, + guiType = GuiType.LISTBOX, + numMaxDisplay = 3, + listboxType = ListboxType.FACTIONS + }, + { + pos = {x = Pos.x, y = Pos.y + 6 * (Size.y + space)}, + size = Size, + guiType = GuiType.LISTBOX, + numMaxDisplay = 3, + listboxType = ListboxType.FACTIONS + }, + { + pos = {x = Pos.x, y = Pos.y + 7 * (Size.y + space)}, + size = Size, + guiType = GuiType.LISTBOX, + numMaxDisplay = 3, + listboxType = ListboxType.FACTIONS + }, +} diff --git a/gameManager.cpp b/gameManager.cpp index af5cc8b..e985fac 100755 --- a/gameManager.cpp +++ b/gameManager.cpp @@ -63,6 +63,7 @@ namespace battleship{ SOL_LUA_STATE.new_usertype( "Factory", sol::constructors(), + "getPos", &GameObject::getPos, "appendToQueue", &Factory::appendToQueue, "getBuildStatus", &Structure::getBuildStatus, "getQueue", &Factory::getQueue @@ -73,6 +74,7 @@ namespace battleship{ "addUnit", &Player::addUnit, "getUnit", &Player::getUnit, "getNumUnits", &Player::getNumUnits, + "getResourceDeposits", &Player::getResourceDeposits, "issueOrder", &Player::issueOrder, "selectUnits", &Player::selectUnits, "deselectUnits", &Player::deselectUnits, @@ -81,19 +83,30 @@ namespace battleship{ "getUnitsByClass", &Player::getUnitsByClass ); + SOL_LUA_STATE.new_usertype( + "ResourceDeposit", sol::constructors(), + "getPos", &GameObject::getPos + ); + SOL_LUA_STATE.new_usertype( "Vector3", sol::constructors(), "x", &Vector3::x, "y", &Vector3::y, - "z", &Vector3::z + "z", &Vector3::z, + "norm", &Vector3::norm, + "add", [](Vector3 v1, Vector3 v2){return v1 + v2;}, + "subtr", [](Vector3 v1, Vector3 v2){return v1 - v2;}, + "mult", [](Vector3 v1, float s){return v1 * s;}, + "div", [](Vector3 v1, float s){return v1 / s;} ); SOL_LUA_STATE.new_usertype( - "Quaternion", sol::constructors(), + "Quaternion", sol::constructors(), "w", &Quaternion::w, "x", &Quaternion::x, "y", &Quaternion::y, - "z", &Quaternion::z + "z", &Quaternion::z, + "multVec", [](Quaternion q, Vector3 v){return q * v;} ); } From d1394e9f2a5b6804d2b77893d9f2d105f64868cd Mon Sep 17 00:00:00 2001 From: devZoGok Date: Fri, 9 Feb 2024 20:21:38 +0200 Subject: [PATCH 3/7] AI builds a taskforce bugfixes and optimizations --- Assets/Scripts/Core/player.lua | 35 +++++++++++++++++++ Assets/Scripts/GameObjects/Units/unitData.lua | 3 ++ extractor.cpp | 5 ++- factory.cpp | 2 +- mapListbox.cpp | 34 ++++++++++++++++++ player.cpp | 2 +- resourceRover.cpp | 10 +++--- 7 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 mapListbox.cpp diff --git a/Assets/Scripts/Core/player.lua b/Assets/Scripts/Core/player.lua index f8fdb2c..591757c 100644 --- a/Assets/Scripts/Core/player.lua +++ b/Assets/Scripts/Core/player.lua @@ -11,7 +11,11 @@ Player.finishedNavalFactory = false Player.startedExtractor = false Player.finishedExtractor = false Player.startedHarvesting = false +Player.startedBuildingTaskforce = false +Player.finishedBuildingTaskforce = false +--TODO use enum-like values instead of literals for order types +--TODO simplify building construction function Player:buildFort() if self.startedFort then return true @@ -159,6 +163,36 @@ function Player:startHarvesting() return true end +function Player:buildTaskforce() + landFactory = self:getUnitsByClass(UnitClass.LAND_FACTORY, 1)[1]:toFactory() + + numWarMechs = 10 + numTanks = 5 + numArtillery = 5 + + if not self.startedBuildingTaskforce then + self.startedBuildingTaskforce = true + + for i = 0, numWarMechs do + landFactory:appendToQueue(UnitId.WAR_MECH) + end + + for i = 0, numTanks do + landFactory:appendToQueue(UnitId.TANK) + end + + for i = 0, numArtillery do + landFactory:appendToQueue(UnitId.ARTILLERY) + end + end + + currWarMechs = self:getUnitsByClass(UnitClass.WAR_MECH, -1) + currTanks = self:getUnitsByClass(UnitClass.TANK, -1) + currArtillery = self:getUnitsByClass(UnitClass.ARTILLERY, -1) + + return #currWarMechs == numWarMechs and #currTanks == numTanks and #currArtillery == numArtillery +end + Player.behaviour = { type = BTNodeType.SEQUENCE, children = { @@ -169,5 +203,6 @@ Player.behaviour = { {type = BTNodeType.FUNCTION, func = 'buildLandFactory'}, {type = BTNodeType.FUNCTION, func = 'buildHarvester'}, {type = BTNodeType.FUNCTION, func = 'startHarvesting'}, + {type = BTNodeType.FUNCTION, func = 'buildTaskforce'}, } } diff --git a/Assets/Scripts/GameObjects/Units/unitData.lua b/Assets/Scripts/GameObjects/Units/unitData.lua index da3696f..1ab03c5 100644 --- a/Assets/Scripts/GameObjects/Units/unitData.lua +++ b/Assets/Scripts/GameObjects/Units/unitData.lua @@ -196,6 +196,8 @@ units = { unitClass = UnitClass.RESOURCE_ROVER, unitType = UnitType.HOVER, armor = {ArmorType.CAST}, + capacity = 3000, + loadRate = 1, isVehicle = true, health = 500, buildTime = 1000, @@ -516,6 +518,7 @@ units = { isVehicle = false, health = 500, buildTime = 1000, + drawRate = 1, cost = 500, size = {x = 4, y = 1.15, z = 4}, hitboxOffset = {x = 0, y = 0, z = 0}, diff --git a/extractor.cpp b/extractor.cpp index ad6ebec..170991d 100644 --- a/extractor.cpp +++ b/extractor.cpp @@ -11,7 +11,7 @@ namespace battleship{ using namespace vb01; using namespace gameBase; - Extractor::Extractor(Player *player, int id, Vector3 pos, Quaternion rot, int buildStatus, ResourceDeposit *rd) : Structure(player, id, pos, rot, buildStatus), drawRate(10){ + Extractor::Extractor(Player *player, int id, Vector3 pos, Quaternion rot, int buildStatus, ResourceDeposit *rd) : Structure(player, id, pos, rot, buildStatus){ if(!rd){ vector deposits; @@ -27,6 +27,9 @@ namespace battleship{ } } + sol::table unitTable = generateView()["units"][id + 1]; + drawRate = unitTable["drawRate"]; + Vector2 size = Vector2(lenHpBar, 10); ammountBackground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1)); ammountForeground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 1, 1)); diff --git a/factory.cpp b/factory.cpp index 4d1ff5e..4897d91 100644 --- a/factory.cpp +++ b/factory.cpp @@ -35,7 +35,7 @@ namespace battleship{ bool mainPlayerSelecting = (activeState && find(selectingPlayers.begin(), selectingPlayers.end(), mainPlayer) != selectingPlayers.end()); Unit::displayUnitStats(buildStatusForeground, buildStatusBackground, trainingStatus, 100, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10)); - sol::table targTable = generateView()["units"][unitQueue[0]]; + sol::table targTable = generateView()["units"][unitQueue[0] + 1]; int costRate = (int)targTable["cost"] / 100, trainRate = (int)targTable["buildTime"] / 100; if(player->getRefineds() >= costRate && getTime() - lastTrainTime > trainRate){ diff --git a/mapListbox.cpp b/mapListbox.cpp new file mode 100644 index 0000000..f187d3f --- /dev/null +++ b/mapListbox.cpp @@ -0,0 +1,34 @@ +#include "mapListbox.h" +#include "map.h" +#include "concreteGuiManager.h" +#include "gameManager.h" + +#include +#include +#include +#include +#include +#include + +namespace battleship{ + using namespace vb01; + using namespace vb01Gui; + using namespace std; + + MapListbox::MapListbox(Vector2 pos, Vector2 size, std::vector &lines, int maxDisplay, string fontPath, bool closeable) : Listbox(pos, size, lines, maxDisplay, fontPath, closeable){} + + void MapListbox::onClose(){ + ConcreteGuiManager *guiManager = ConcreteGuiManager::getSingleton(); + + Listbox *mapListbox = guiManager->getListboxes()[0]; + int selectedMap = mapListbox->getSelectedOption(); + string mapName = wstringToString(mapListbox->getContents()[selectedMap]); + string mapPath = GameManager::getSingleton()->getPath() + "Models/Maps/" + mapName + "/" + mapName + ".lua"; + int numSpawnPoints = Map::getNumSpawnPointsByMap(mapPath); + + guiManager->readLuaScreenScript("singlePlayerMenu.lua"); + mapListbox = guiManager->getListboxes()[0]; + vector buttons = guiManager->getButtons(); + guiManager->readLuaScreenScript("playerSelection.lua", buttons, vector{mapListbox}, vector{}, vector{}, vector{}, vector{}, vector{}, numSpawnPoints); + } +} diff --git a/player.cpp b/player.cpp index 57dfca1..9b0a223 100755 --- a/player.cpp +++ b/player.cpp @@ -11,7 +11,7 @@ namespace battleship{ using namespace gameBase; using namespace std; - Player::Player(int diff, int fac, int t, Vector3 col, bool cpuPl, Vector3 sp, string n) : difficulty(diff), faction(fac), team(t), color(col), cpuPlayer(cpuPl), spawnPoint(sp), name(n), refineds(10000) {} + Player::Player(int diff, int fac, int t, Vector3 col, bool cpuPl, Vector3 sp, string n) : difficulty(diff), faction(fac), team(t), color(col), cpuPlayer(cpuPl), spawnPoint(sp), name(n), refineds(30000) {} Player::~Player() {} diff --git a/resourceRover.cpp b/resourceRover.cpp index 8be0b70..9c33d70 100644 --- a/resourceRover.cpp +++ b/resourceRover.cpp @@ -13,11 +13,11 @@ namespace battleship{ using namespace vb01; using namespace gameBase; - ResourceRover::ResourceRover(Player *player, int id, Vector3 pos, Quaternion rot) : - Vehicle(player, id, pos, rot), - capacity(300), - loadRate(10) - { + ResourceRover::ResourceRover(Player *player, int id, Vector3 pos, Quaternion rot) : Vehicle(player, id, pos, rot) { + sol::table unitTable = generateView()["units"][id + 1]; + capacity = unitTable["capacity"]; + loadRate = unitTable["loadRate"]; + Vector2 size = Vector2(lenHpBar, 10); loadBackground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1)); loadForeground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(1, 1, 0, 1)); From c090992547520e2650ca0a900d8c12bf800adda6 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sat, 10 Feb 2024 14:34:25 +0200 Subject: [PATCH 4/7] variable resource collection speed --- Assets/Scripts/GameObjects/Units/unitData.lua | 2 ++ extractor.cpp | 3 ++- extractor.h | 2 +- resourceDeposit.h | 2 +- resourceRover.cpp | 5 +++-- resourceRover.h | 2 +- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Assets/Scripts/GameObjects/Units/unitData.lua b/Assets/Scripts/GameObjects/Units/unitData.lua index 1ab03c5..7ff03c8 100644 --- a/Assets/Scripts/GameObjects/Units/unitData.lua +++ b/Assets/Scripts/GameObjects/Units/unitData.lua @@ -198,6 +198,7 @@ units = { armor = {ArmorType.CAST}, capacity = 3000, loadRate = 1, + loadSpeed = 5, isVehicle = true, health = 500, buildTime = 1000, @@ -519,6 +520,7 @@ units = { health = 500, buildTime = 1000, drawRate = 1, + drawSpeed = 5, cost = 500, size = {x = 4, y = 1.15, z = 4}, hitboxOffset = {x = 0, y = 0, z = 0}, diff --git a/extractor.cpp b/extractor.cpp index 170991d..fb5b8c4 100644 --- a/extractor.cpp +++ b/extractor.cpp @@ -29,6 +29,7 @@ namespace battleship{ sol::table unitTable = generateView()["units"][id + 1]; drawRate = unitTable["drawRate"]; + drawSpeed = unitTable["drawSpeed"]; Vector2 size = Vector2(lenHpBar, 10); ammountBackground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1)); @@ -59,7 +60,7 @@ namespace battleship{ } void Extractor::draw(){ - deposit->decrementAmmount(); + deposit->decreaseAmmount(drawSpeed); lastDrawTime = getTime(); } } diff --git a/extractor.h b/extractor.h index 3540f30..120e331 100644 --- a/extractor.h +++ b/extractor.h @@ -17,7 +17,7 @@ namespace battleship{ bool canDraw(){return vb01::getTime() - lastDrawTime > drawRate;} inline ResourceDeposit* getDeposit(){return deposit;} private: - int drawRate; + int drawSpeed, drawRate; vb01::s64 lastDrawTime = 0; vb01::Node *ammountBackground = nullptr, *ammountForeground = nullptr; ResourceDeposit *deposit = nullptr; diff --git a/resourceDeposit.h b/resourceDeposit.h index f1e5f8d..ff6e425 100644 --- a/resourceDeposit.h +++ b/resourceDeposit.h @@ -10,7 +10,7 @@ namespace battleship{ ~ResourceDeposit(); inline int getAmmount(){return ammount;} inline int getInitAmmount(){return initAmmount;} - inline void decrementAmmount(){ammount--;} + inline void decreaseAmmount(int amnt){ammount -= amnt;} private: int ammount, initAmmount; diff --git a/resourceRover.cpp b/resourceRover.cpp index 9c33d70..696a66f 100644 --- a/resourceRover.cpp +++ b/resourceRover.cpp @@ -16,6 +16,7 @@ namespace battleship{ ResourceRover::ResourceRover(Player *player, int id, Vector3 pos, Quaternion rot) : Vehicle(player, id, pos, rot) { sol::table unitTable = generateView()["units"][id + 1]; capacity = unitTable["capacity"]; + loadSpeed = unitTable["loadSpeed"]; loadRate = unitTable["loadRate"]; Vector2 size = Vector2(lenHpBar, 10); @@ -53,7 +54,7 @@ namespace battleship{ if(canLoad() && deposit->getAmmount() > 0){ if(nearestExtractor->canDraw()){ nearestExtractor->draw(); - load++; + load += loadSpeed; lastLoadTime = getTime(); } } @@ -69,7 +70,7 @@ namespace battleship{ if(nearestRefinery && nearestRefinery->getPos().getDistanceFrom(pos) <= minDist){ if(canUnload()){ - load--; + load -= loadSpeed; player->addRefineds(1); lastLoadTime = getTime(); } diff --git a/resourceRover.h b/resourceRover.h index c795f3e..5e06627 100644 --- a/resourceRover.h +++ b/resourceRover.h @@ -21,7 +21,7 @@ namespace battleship{ inline bool canUnload(){return vb01::getTime() - lastLoadTime > loadRate && load > 0;} vb01::s64 lastLoadTime = 0; - int load = 0, capacity, loadRate; + int load = 0, capacity, loadRate, loadSpeed; Extractor *nearestExtractor = nullptr; Unit *nearestRefinery = nullptr; vb01::Node *loadBackground = nullptr, *loadForeground = nullptr; From 3780b47c2bd465ac8549e626aa53e88cb89bfea3 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sat, 10 Feb 2024 20:31:42 +0200 Subject: [PATCH 5/7] expanded destroyed building reconstruction by AI utility methods --- Assets/Scripts/Core/player.lua | 172 +++++++++++++++++++-------------- factory.cpp | 10 ++ factory.h | 3 +- gameManager.cpp | 10 ++ unit.h | 2 + 5 files changed, 122 insertions(+), 75 deletions(-) diff --git a/Assets/Scripts/Core/player.lua b/Assets/Scripts/Core/player.lua index 591757c..cd26aa9 100644 --- a/Assets/Scripts/Core/player.lua +++ b/Assets/Scripts/Core/player.lua @@ -1,40 +1,29 @@ Player.numStartEngis = 3 Player.dirToCenter = nil -Player.startedFort = false -Player.finishedFort = false -Player.startedRefinery = false -Player.finishedRefinery = false -Player.startedLandFactory = false -Player.finishedLandFactory = false -Player.startedNavalFactory = false -Player.finishedNavalFactory = false -Player.startedExtractor = false -Player.finishedExtractor = false -Player.startedHarvesting = false -Player.startedBuildingTaskforce = false -Player.finishedBuildingTaskforce = false +Player.numDefWarMechs = 5 +Player.numTaskForceWarMechs = 5 +Player.numTaskForceTanks = 5 +Player.numTaskForceArtillery = 5 +Player.givenOrder = false --TODO use enum-like values instead of literals for order types --TODO simplify building construction function Player:buildFort() - if self.startedFort then + if #self:getUnitsByClass(UnitClass.FORT, 1) > 0 then return true end engis = self:getUnitsByClass(UnitClass.ENGINEER, 1) - - if #engis == 0 then - return false - end + if #engis == 0 then return false end engineer = engis[1] + self:deselectUnits() self:selectUnits({engineer}) - fort = GameObjectFactory.createUnit(self, UnitId.FORT, engineer:getPos(), Quaternion:new(1, 0, 0, 0), 0) + fort = GameObjectFactory.createUnit(self, UnitId.FORT, self:getSpawnPoint(), Quaternion:new(1, 0, 0, 0), 0) self:addUnit(fort) self:issueOrder(1, Vector3:new(0, 0, 0), {Target:new(fort, Vector3:new(0, 0, 0))}, false) - self.startedFort = true return true end @@ -52,11 +41,12 @@ function Player:trainEngineers() fort:appendToQueue(UnitId.ENGINEER) end - return #self:getUnitsByClass(UnitClass.ENGINEER, -1) == 3 + return #self:getUnitsByClass(UnitClass.ENGINEER, -1) == self.numStartEngis end +--Correct resource deposit selection function Player:buildExtractor() - if self.startedExtractor then + if #self:getUnitsByClass(UnitClass.EXTRACTOR, 1) > 0 then return true end @@ -78,7 +68,6 @@ function Player:buildExtractor() extractor = GameObjectFactory.createUnit(self, UnitId.EXTRACTOR, depPos, Quaternion:new(1, 0, 0, 0), 0) self:addUnit(extractor) self:issueOrder(1, Vector3:new(0, 0, 0), {Target:new(extractor, Vector3:new(0, 0, 0))}, false) - self.startedExtractor = true return true end @@ -90,43 +79,45 @@ function Player:startBuilding(buildingId, engiId, angle) dirVec = Quaternion:new(angle, Vector3:new(0, 1, 0)):multVec(dirToCenter) refPos = self:getSpawnPoint():add(dirVec:mult(20)) - refinery = GameObjectFactory.createUnit(self, buildingId, refPos, Quaternion:new(1, 0, 0, 0), 0) - self:addUnit(refinery) - self:issueOrder(1, Vector3:new(0, 0, 0), {Target:new(refinery, Vector3:new(0, 0, 0))}, false) + building = GameObjectFactory.createUnit(self, buildingId, refPos, Quaternion:new(1, 0, 0, 0), 0) + self:addUnit(building) + self:issueOrder(1, Vector3:new(0, 0, 0), {Target:new(building, Vector3:new(0, 0, 0))}, false) end function Player:buildRefinery() - if not self.startedRefinery then - self.startedRefinery = true + if #self:getUnitsByClass(UnitClass.REFINERY, 1) == 0 then self:startBuilding(UnitId.REFINERY, 2, -.6) end - if not self.finishedRefinery then - refTable = self:getUnitsByClass(UnitClass.REFINERY, 1) - - if #refTable == 1 and refTable[1]:toFactory():getBuildStatus() == 100 then - self.finishedRefinery = true + refineries = self:getUnitsByClass(UnitClass.REFINERY, -1) + refineryBuilt = false + + for i = 1, #refineries do + if refineries[i]:toStructure():getBuildStatus() == 100 then + refineryBuilt = true + break end end - return self.finishedRefinery + return refineryBuilt end function Player:buildLandFactory() - if not self.startedLandFactory then - self.startedLandFactory = true + if #self:getUnitsByClass(UnitClass.LAND_FACTORY, 1) == 0 then self:startBuilding(UnitId.LAND_FACTORY, 3, .6) end - if not self.finishedLandFactory then - facTable = self:getUnitsByClass(UnitClass.LAND_FACTORY, 1) - - if #facTable == 1 and facTable[1]:toFactory():getBuildStatus() == 100 then - self.finishedLandFactory = true + factories = self:getUnitsByClass(UnitClass.LAND_FACTORY, -1) + factoryBuilt = false + + for i = 1, #factories do + if factories[i]:toStructure():getBuildStatus() == 100 then + factoryBuilt = true + break end end - return self.finishedLandFactory + return factoryBuilt end function Player:buildHarvester() @@ -143,54 +134,86 @@ function Player:buildHarvester() factory:appendToQueue(UnitId.RESOURCE_ROVER) end - return true + return false end function Player:startHarvesting() - if self.startedHarvesting then return true end + harvesters = self:getUnitsByClass(UnitClass.RESOURCE_ROVER, -1) + + for i = 1, #harvesters do + if harvesters[i]:getNumOrders() > 0 and harvesters[i]:getOrder(0).type == 7 then + return true + end + end - harvs = self:getUnitsByClass(UnitClass.RESOURCE_ROVER, 1) extrs = self:getUnitsByClass(UnitClass.EXTRACTOR, 1) - - if #harvs == 0 or (#extrs == 0) then return false end + if #extrs == 0 then return false end self:deselectUnits() - self:selectUnits({harvs[1]}) + self:selectUnits({harvesters[1]}) self:issueOrder(7, Vector3:new(0, 0, 0), {Target:new(extrs[1], Vector3:new(0, 0, 0))}, false) - self.startedHarvesting = true - return true end -function Player:buildTaskforce() - landFactory = self:getUnitsByClass(UnitClass.LAND_FACTORY, 1)[1]:toFactory() - - numWarMechs = 10 - numTanks = 5 - numArtillery = 5 - - if not self.startedBuildingTaskforce then - self.startedBuildingTaskforce = true - - for i = 0, numWarMechs do - landFactory:appendToQueue(UnitId.WAR_MECH) - end - - for i = 0, numTanks do - landFactory:appendToQueue(UnitId.TANK) - end - - for i = 0, numArtillery do - landFactory:appendToQueue(UnitId.ARTILLERY) +function Player:buildTaskforceUnitGroup(numUnits, currNumUnits, factory, unitId) + if currNumUnits < numUnits then + for i = 1, numUnits - currNumUnits do + factory:appendToQueue(unitId) end end +end - currWarMechs = self:getUnitsByClass(UnitClass.WAR_MECH, -1) - currTanks = self:getUnitsByClass(UnitClass.TANK, -1) - currArtillery = self:getUnitsByClass(UnitClass.ARTILLERY, -1) +function Player:buildTaskforce() + currNumBuiltWarMechs = #self:getUnitsByClass(UnitClass.WAR_MECH, -1) + currNumBuiltTanks = #self:getUnitsByClass(UnitClass.TANK, -1) + currNumBuiltArtillery = #self:getUnitsByClass(UnitClass.ARTILLERY, -1) + currNumWarMechs = currNumBuiltWarMechs + currNumTanks = currNumBuiltTanks + currNumArtillery = currNumBuiltArtillery + currLandFactories = self:getUnitsByClass(UnitClass.LAND_FACTORY, -1) - return #currWarMechs == numWarMechs and #currTanks == numTanks and #currArtillery == numArtillery + for i = 1, #currLandFactories do + currNumWarMechs = currNumWarMechs + currLandFactories[i]:toFactory():getNumQueueUnitsById(UnitId.WAR_MECH) + currNumTanks = currNumTanks + currLandFactories[i]:toFactory():getNumQueueUnitsById(UnitId.TANK) + currNumArtillery = currNumArtillery + currLandFactories[i]:toFactory():getNumQueueUnitsById(UnitId.ARTILLERY) + end + + numWarMechs = self.numDefWarMechs + self.numTaskForceWarMechs + numTanks = self.numTaskForceTanks + numArtillery = self.numTaskForceArtillery + + if currNumBuiltWarMechs >= numWarMechs and currNumBuiltTanks >= numTanks and currNumBuiltArtillery >= numArtillery then + return true + end + + landFactory = currLandFactories[1]:toFactory() + + self:buildTaskforceUnitGroup(numWarMechs, currNumWarMechs, landFactory, UnitId.WAR_MECH) + self:buildTaskforceUnitGroup(numTanks, currNumTanks, landFactory, UnitId.TANK) + self:buildTaskforceUnitGroup(numArtillery, currNumArtillery, landFactory, UnitId.ARTILLERY) + + return false +end + +function Player:sendTaskforce() + if --[[taskForceMechs[1]:getNumOrders() > 0 and taskForceMechs[1]:getOrder(0).type == 2--]] self.givenOrder then + return true + end + + taskForceMechs = self:getUnitsByClass(UnitClass.WAR_MECH, self.numTaskForceWarMechs) + taskForceTanks = self:getUnitsByClass(UnitClass.TANK, self.numTaskForceTanks) + taskForceArtillery = self:getUnitsByClass(UnitClass.ARTILLERY, self.numTaskForceArtillery) + + self:deselectUnits() + self:selectUnits(taskForceMechs) + self:selectUnits(taskForceTanks) + self:selectUnits(taskForceArtillery) + + self:issueOrder(2, Vector3:new(0, 0, 0), {Target:new(nil, Vector3:new(0, 0, 0))}, false) + self.givenOrder = true + + return true end Player.behaviour = { @@ -204,5 +227,6 @@ Player.behaviour = { {type = BTNodeType.FUNCTION, func = 'buildHarvester'}, {type = BTNodeType.FUNCTION, func = 'startHarvesting'}, {type = BTNodeType.FUNCTION, func = 'buildTaskforce'}, + {type = BTNodeType.FUNCTION, func = 'sendTaskforce'}, } } diff --git a/factory.cpp b/factory.cpp index 4897d91..bbb4d75 100644 --- a/factory.cpp +++ b/factory.cpp @@ -22,6 +22,16 @@ namespace battleship{ train(); } + int Factory::getNumQueueUnitsById(int unitId){ + int numUnits = 0; + + for(int qu : unitQueue) + if(qu == unitId) + numUnits++; + + return numUnits; + } + void Factory::train(){ bool training = !unitQueue.empty(); buildStatusForeground->setVisible(training); diff --git a/factory.h b/factory.h index 1b65322..042fd2d 100644 --- a/factory.h +++ b/factory.h @@ -18,7 +18,8 @@ namespace battleship{ Factory(Player*, int, vb01::Vector3, vb01::Quaternion, int = 0); ~Factory(){} void update(); - void appendToQueue(int uc){unitQueue.push_back(uc);} + int getNumQueueUnitsById(int); + void appendToQueue(int uid){unitQueue.push_back(uid);} inline std::vector getQueue(){return unitQueue;} private: const int MAX_LEN_QUEUE = 10; diff --git a/gameManager.cpp b/gameManager.cpp index e985fac..a951c4b 100755 --- a/gameManager.cpp +++ b/gameManager.cpp @@ -54,18 +54,28 @@ namespace battleship{ SOL_LUA_STATE.new_usertype( "Unit", sol::constructors(), + "getOrder", &Unit::getOrder, + "getNumOrders", &Unit::getNumOrders, "getPos", &GameObject::getPos, "getUnitClass", &Unit::getUnitClass, "toEngineer", &Unit::toEngineer, "toPointDefense", &Unit::toPointDefense, + "toStructure", &Unit::toStructure, "toFactory", &Unit::toFactory ); + SOL_LUA_STATE.new_usertype( + "Structure", sol::constructors(), + "getPos", &GameObject::getPos, + "getBuildStatus", &Structure::getBuildStatus + ); + SOL_LUA_STATE.new_usertype( "Factory", sol::constructors(), "getPos", &GameObject::getPos, "appendToQueue", &Factory::appendToQueue, "getBuildStatus", &Structure::getBuildStatus, + "getNumQueueUnitsById", &Factory::getNumQueueUnitsById, "getQueue", &Factory::getQueue ); diff --git a/unit.h b/unit.h index 001eb63..a72ea33 100755 --- a/unit.h +++ b/unit.h @@ -28,6 +28,7 @@ namespace battleship{ class Player; class Unit; class Vehicle; + class Structure; class Factory; class Cruiser; class PointDefense; @@ -127,6 +128,7 @@ namespace battleship{ virtual void addOrder(Order); bool canGarrison(Vehicle*); inline Engineer* toEngineer(){return (Engineer*)this;} + inline Structure* toStructure(){return (Structure*)this;} inline Factory* toFactory(){return (Factory*)this;} inline Cruiser* toCruiser(){return (Cruiser*)this;} inline PointDefense* toPointDefense(){return (PointDefense*)this;} From 2932c2b923ba9829a4d1ac6d46fe8c83be92efa2 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sat, 10 Feb 2024 20:51:41 +0200 Subject: [PATCH 6/7] CPU AI sends taskforce by spawnpoint --- Assets/Scripts/Core/player.lua | 12 +++++++++++- gameManager.cpp | 7 +++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Assets/Scripts/Core/player.lua b/Assets/Scripts/Core/player.lua index cd26aa9..7709556 100644 --- a/Assets/Scripts/Core/player.lua +++ b/Assets/Scripts/Core/player.lua @@ -210,7 +210,17 @@ function Player:sendTaskforce() self:selectUnits(taskForceTanks) self:selectUnits(taskForceArtillery) - self:issueOrder(2, Vector3:new(0, 0, 0), {Target:new(nil, Vector3:new(0, 0, 0))}, false) + players = Game.getSingleton():getPlayers() + enemySpawnPoint = nil + + for i = 1, #players do + if players[i] ~= self then + enemySpawnPoint = players[i]:getSpawnPoint() + break + end + end + + self:issueOrder(2, Vector3:new(0, 0, 0), {Target:new(nil, enemySpawnPoint)}, false) self.givenOrder = true return true diff --git a/gameManager.cpp b/gameManager.cpp index a951c4b..af66839 100755 --- a/gameManager.cpp +++ b/gameManager.cpp @@ -8,6 +8,7 @@ #include "gameManager.h" #include "gameObjectFactory.h" +#include "game.h" #include "guiAppState.h" #include "defConfigs.h" #include "player.h" @@ -98,6 +99,12 @@ namespace battleship{ "getPos", &GameObject::getPos ); + SOL_LUA_STATE.new_usertype( + "Game", + "getSingleton", &Game::getSingleton, + "getPlayers", &Game::getPlayers + ); + SOL_LUA_STATE.new_usertype( "Vector3", sol::constructors(), "x", &Vector3::x, From 781f1649b051d686ef99783c9cc8ff99bf456a26 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sun, 11 Feb 2024 15:44:45 +0200 Subject: [PATCH 7/7] AI chooses the closest deposit to build an extractor --- Assets/Scripts/Core/player.lua | 13 +++++++------ gameManager.cpp | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Assets/Scripts/Core/player.lua b/Assets/Scripts/Core/player.lua index 7709556..8fbb056 100644 --- a/Assets/Scripts/Core/player.lua +++ b/Assets/Scripts/Core/player.lua @@ -55,14 +55,15 @@ function Player:buildExtractor() self:selectUnits({engineer}) deposits = self:getResourceDeposits() - depPos = nil + if #deposits == 0 then return false end - if #deposits > 0 then - depPos = deposits[1]:getPos() - end + depPos = deposits[1]:getPos() + spawnPoint = self:getSpawnPoint() - if depPos == nil then - return false + for i = 1, #deposits do + if deposits[i]:getPos():getDistanceFrom(spawnPoint) < depPos:getDistanceFrom(spawnPoint) then + depPos = deposits[i]:getPos() + end end extractor = GameObjectFactory.createUnit(self, UnitId.EXTRACTOR, depPos, Quaternion:new(1, 0, 0, 0), 0) diff --git a/gameManager.cpp b/gameManager.cpp index af66839..09d541a 100755 --- a/gameManager.cpp +++ b/gameManager.cpp @@ -111,6 +111,7 @@ namespace battleship{ "y", &Vector3::y, "z", &Vector3::z, "norm", &Vector3::norm, + "getDistanceFrom", &Vector3::getDistanceFrom, "add", [](Vector3 v1, Vector3 v2){return v1 + v2;}, "subtr", [](Vector3 v1, Vector3 v2){return v1 - v2;}, "mult", [](Vector3 v1, float s){return v1 * s;},