diff --git a/Assets/Scripts/Abilities/abilityData.lua b/Assets/Scripts/Abilities/abilityData.lua index 0bef041..d3d3ab5 100644 --- a/Assets/Scripts/Abilities/abilityData.lua +++ b/Assets/Scripts/Abilities/abilityData.lua @@ -1,5 +1,21 @@ -AbilityType = {SPEED = 0} - -ablilities = { - {type = AbilityType.SPEED, ammount = .2, units = {UnitClass.WAR_MECH}} +AbilityType = { + SPEED = 0, + HEALTH = 1, + LINE_OF_SIGHT = 1, + MAX_TURN_ANGLE = 2, + DIRECT_HIT_DAMAGE = 3, + EXPLOSION_RADIUS = 4, + EXPLOSION_DAMAGE = 5, + CAPACITY = 6, + LOAD_RATE = 7, + LOAD_SPEED = 8, + DRAW_RATE = 9, + DRAW_SPEED = 10, + HACK_RANGE = 11, + UNIT_UNLOCK = 12 +} + +abilities = { + {type = AbilityType.SPEED, gameObjType = 0, ammount = .4, gameObjIds = {UnitId.WAR_MECH}}, + {type = AbilityType.UNIT_UNLOCK, gameObjType = 0, gameObjIds = {UnitId.WAR_MECH}}, } diff --git a/Assets/Scripts/Core/player.lua b/Assets/Scripts/Core/player.lua index cf4ba0f..748e28e 100644 --- a/Assets/Scripts/Core/player.lua +++ b/Assets/Scripts/Core/player.lua @@ -38,7 +38,7 @@ function Player:trainEngineers() 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) + fort:appendToQueue(0) end return #self:getUnitsByClass(UnitClass.ENGINEER, -1) == self.numStartEngis @@ -132,7 +132,7 @@ function Player:buildHarvester() factory = landFactories[1]:toFactory() if #factory:getQueue() == 0 then - factory:appendToQueue(UnitId.RESOURCE_ROVER) + factory:appendToQueue(3) end return false @@ -157,10 +157,10 @@ function Player:startHarvesting() return true end -function Player:buildTaskforceUnitGroup(numUnits, currNumUnits, factory, unitId) +function Player:buildTaskforceUnitGroup(numUnits, currNumUnits, factory, buId) if currNumUnits < numUnits then for i = 1, numUnits - currNumUnits do - factory:appendToQueue(unitId) + factory:appendToQueue(buId) end end end @@ -175,9 +175,9 @@ function Player:buildTaskforce() currLandFactories = self:getUnitsByClass(UnitClass.LAND_FACTORY, -1) 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) + currNumWarMechs = currNumWarMechs + currLandFactories[i]:toFactory():getNumQueueUnitsById(0) + currNumTanks = currNumTanks + currLandFactories[i]:toFactory():getNumQueueUnitsById(1) + currNumArtillery = currNumArtillery + currLandFactories[i]:toFactory():getNumQueueUnitsById(2) end numWarMechs = self.numDefWarMechs + self.numTaskForceWarMechs @@ -190,9 +190,9 @@ function Player:buildTaskforce() 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) + self:buildTaskforceUnitGroup(numWarMechs, currNumWarMechs, landFactory, 0) + self:buildTaskforceUnitGroup(numTanks, currNumTanks, landFactory, 1) + self:buildTaskforceUnitGroup(numArtillery, currNumArtillery, landFactory, 2) return false end diff --git a/Assets/Scripts/GameObjects/Units/unitData.lua b/Assets/Scripts/GameObjects/Units/unitData.lua index 35505b0..972c0e0 100644 --- a/Assets/Scripts/GameObjects/Units/unitData.lua +++ b/Assets/Scripts/GameObjects/Units/unitData.lua @@ -125,6 +125,14 @@ units = { weapons = { {type = WeaponClass.HITSCAN, rateOfFire = 2000, fireSfx = PATH .. 'Sounds/Units/WarMechs/fire.ogg', damage = 20, maxRange = 8}, }, + buildableUnits = { + {id = UnitId.LAND_FACTORY, buildable = true}, + {id = UnitId.NAVAL_FACTORY, buildable = true}, + {id = UnitId.MARKET, buildable = true}, + {id = UnitId.LAB, buildable = true}, + {id = UnitId.POINT_DEFENSE, buildable = true}, + {id = UnitId.FORT, buildable = false}, + }, unitClass = UnitClass.ENGINEER, unitType = UnitType.HOVER, armor = {ArmorType.MECHANIC}, @@ -140,6 +148,7 @@ units = { name = 'Engineer', basePath = PATH .. vehiclePrefix .. 'Engineers/', meshPath = 'engineer.xml', + guiScreen = 'engineerCommands.lua', selectionSfx = PATH .. 'Sounds/Units/Engineers/selection.ogg', deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg', speed = .1, @@ -437,6 +446,12 @@ units = { garrisonCategory = 3 }, { + buildableUnits = { + {id = UnitId.WAR_MECH, buildable = true}, + {id = UnitId.TANK, buildable = true}, + {id = UnitId.ARTILLERY, buildable = true}, + {id = UnitId.RESOURCE_ROVER, buildable = true} + }, unitClass = UnitClass.LAND_FACTORY, unitType = UnitType.LAND, isVehicle = false, @@ -449,6 +464,7 @@ units = { name = 'Land factory', basePath = PATH .. structurePrefix .. 'LandFactories/', meshPath = 'landFactory.xml', + guiScreen = 'landFactoryCommands.lua', selectionSfx = PATH .. 'Sounds/Units/Sample/selection.ogg', deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg', }, @@ -465,6 +481,7 @@ units = { name = 'Naval factory', basePath = PATH .. structurePrefix .. 'NavalFactories/', meshPath = 'navalFactory.xml', + guiScreen = 'navalFactoryCommands.lua', selectionSfx = PATH .. 'Sounds/Units/Sample/selection.ogg', deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg', }, @@ -494,9 +511,13 @@ units = { size = {x = 1, y = 1.15, z = 2}, hitboxOffset = {x = 0, y = 0, z = 0}, lineOfSight = 5, + generationRate = 100, + generationSpeed = 10, + researchCost = 1, name = 'Lab', basePath = PATH .. structurePrefix .. 'Labs/', meshPath = 'lab.xml', + guiScreen = 'researchStructCommands.lua', selectionSfx = PATH .. 'Sounds/Units/Sample/selection.ogg', deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg', }, @@ -552,6 +573,7 @@ units = { deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg', }, { + buildableUnits = {{id = UnitId.ENGINEER, buildable = true}}, unitClass = UnitClass.FORT, unitType = UnitType.LAND, isVehicle = false, @@ -564,6 +586,7 @@ units = { name = 'Fort', basePath = PATH .. structurePrefix .. 'Forts/', meshPath = 'fort.xml', + guiScreen = 'fortCommands.lua', selectionSfx = PATH .. 'Sounds/Units/Sample/selection.ogg', deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg', }, diff --git a/Assets/Scripts/Gui/engineerCommands.lua b/Assets/Scripts/Gui/engineerCommands.lua index 8fe31c5..d9cd565 100644 --- a/Assets/Scripts/Gui/engineerCommands.lua +++ b/Assets/Scripts/Gui/engineerCommands.lua @@ -9,7 +9,6 @@ gui = { guiType = GuiType.BUTTON, buttonType = ButtonType.BUILD, trigger = 76, - structureId = UnitId.LAND_FACTORY }, { pos = {x = res.x - Size.x - 200, y = res.y - 200}, @@ -18,7 +17,6 @@ gui = { guiType = GuiType.BUTTON, buttonType = ButtonType.BUILD, trigger = 78, - structureId = UnitId.NAVAL_FACTORY }, { pos = {x = res.x - 2 * Size.x - 200, y = res.y - 200}, @@ -27,7 +25,6 @@ gui = { guiType = GuiType.BUTTON, buttonType = ButtonType.BUILD, trigger = 77, - structureId = UnitId.MARKET }, { pos = {x = res.x - 3 * Size.x - 200, y = res.y - 200}, @@ -36,7 +33,6 @@ gui = { guiType = GuiType.BUTTON, buttonType = ButtonType.BUILD, trigger = 84, - structureId = UnitId.LAB }, { pos = {x = res.x - 4 * Size.x - 200, y = res.y - 200}, @@ -45,7 +41,6 @@ gui = { guiType = GuiType.BUTTON, buttonType = ButtonType.BUILD, trigger = 68, - structureId = UnitId.POINT_DEFENSE }, { pos = {x = res.x - 5 * Size.x - 200, y = res.y - 200}, @@ -54,6 +49,5 @@ gui = { guiType = GuiType.BUTTON, buttonType = ButtonType.BUILD, trigger = 70, - structureId = UnitId.FORT }, } diff --git a/Assets/Scripts/Gui/fortCommands.lua b/Assets/Scripts/Gui/fortCommands.lua index a9f985e..2600775 100644 --- a/Assets/Scripts/Gui/fortCommands.lua +++ b/Assets/Scripts/Gui/fortCommands.lua @@ -8,7 +8,6 @@ gui = { imagePath = '', guiType = GuiType.BUTTON, buttonType = ButtonType.FORT_TRAIN, - trigger = 82, - unitId = UnitId.ENGINEER + trigger = 82 }, } diff --git a/Assets/Scripts/Gui/landFactoryCommands.lua b/Assets/Scripts/Gui/landFactoryCommands.lua index abece5c..8ad889f 100644 --- a/Assets/Scripts/Gui/landFactoryCommands.lua +++ b/Assets/Scripts/Gui/landFactoryCommands.lua @@ -1,4 +1,3 @@ -numGui = 2 res = graphics.resolution Size = {x = 100, y = 100} @@ -9,8 +8,7 @@ gui = { imagePath = '', guiType = GuiType.BUTTON, buttonType = ButtonType.LAND_FACTORY_TRAIN, - trigger = 84, - unitId = UnitId.TANK + trigger = 87 }, { pos = {x = res.x - Size.x - 200, y = res.y - 200}, @@ -18,7 +16,14 @@ gui = { imagePath = '', guiType = GuiType.BUTTON, buttonType = ButtonType.LAND_FACTORY_TRAIN, - trigger = 65, - unitId = UnitId.ARTILLERY + trigger = 84 + }, + { + pos = {x = res.x - 2 * Size.x - 200, y = res.y - 200}, + size = Size, + imagePath = '', + guiType = GuiType.BUTTON, + buttonType = ButtonType.LAND_FACTORY_TRAIN, + trigger = 65 } } diff --git a/Assets/Scripts/Gui/main.lua b/Assets/Scripts/Gui/main.lua index c0dc13a..390113d 100644 --- a/Assets/Scripts/Gui/main.lua +++ b/Assets/Scripts/Gui/main.lua @@ -27,7 +27,8 @@ ButtonType = { LAND_FACTORY_TRAIN = 23, NAVAL_FACTORY_TRAIN = 24, FORT_TRAIN = 25, - STATISTICS = 26 + STATISTICS = 26, + RESEARCH = 27 } ListboxType = { diff --git a/Assets/Scripts/Gui/navalFactoryCommands.lua b/Assets/Scripts/Gui/navalFactoryCommands.lua index 2ffedbd..652031d 100644 --- a/Assets/Scripts/Gui/navalFactoryCommands.lua +++ b/Assets/Scripts/Gui/navalFactoryCommands.lua @@ -1,4 +1,3 @@ -numGui = 1 res = graphics.resolution gui = { @@ -8,7 +7,6 @@ gui = { imagePath = '', guiType = GuiType.BUTTON, buttonType = ButtonType.NAVAL_FACTORY_TRAIN, - trigger = 66, - unitId = UnitId.SCOUT_TRANSPORT + trigger = 66 } } diff --git a/Assets/Scripts/Gui/researchStructCommands.lua b/Assets/Scripts/Gui/researchStructCommands.lua new file mode 100644 index 0000000..166afe1 --- /dev/null +++ b/Assets/Scripts/Gui/researchStructCommands.lua @@ -0,0 +1,15 @@ +res = graphics.resolution +Size = {x = 100, y = 100} + +gui = { + { + pos = {x = res.x - 200, y = res.y - 200}, + size = Size, + name = "Research", + imagePath = '', + guiType = GuiType.BUTTON, + buttonType = ButtonType.RESEARCH, + techId = TechId.APT, + trigger = 82, + } +} diff --git a/Assets/Scripts/Technologies/technologyData.lua b/Assets/Scripts/Technologies/technologyData.lua index 57d097e..74b412f 100644 --- a/Assets/Scripts/Technologies/technologyData.lua +++ b/Assets/Scripts/Technologies/technologyData.lua @@ -1,10 +1,49 @@ +TechId = { + APT = 0, + EFT = 1, + PCT = 2, + FPT = 3, +} + technologies = { { - name = '', - cost = 10, + id = TechId.APT, + name = 'Advanced power technology', + cost = 1000, icon = '', description = '', + parents = {}, + children = {}, abilities = {0}, - units = {} - } + }, + { + id = TechId.EFT, + name = 'Energy field technology', + cost = 1000, + icon = '', + description = '', + parents = {}, + children = {}, + abilities = {}, + }, + { + id = TechId.PCT, + name = 'Plasma casting technology', + cost = 1000, + icon = '', + description = '', + parents = {}, + children = {}, + abilities = {}, + }, + { + id = TechId.FPT, + name = 'Fusion power technology', + cost = 1000, + icon = '', + description = '', + parents = {}, + children = {}, + abilities = {}, + }, } diff --git a/CMakeLists.txt b/CMakeLists.txt index 30c1077..bb506e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ set(CMAKE_BUILD_TYPE Debug) set(BUILD_TESTS ON) cmake_policy(SET CMP0015 NEW) -set(UNIT_BUTTONS unitButton.cpp buildButton.cpp trainButton.cpp) +set(UNIT_BUTTONS unitButton.cpp buildButton.cpp trainButton.cpp researchButton.cpp) set(OPTIONS_BUTTONS optionsButton.cpp tabButton.cpp okButton.cpp defaultsButton.cpp) set(IN_GAME_APP_STATE_BUTTONS mainMenuButton.cpp) set(MAP_EDITOR_BUTTONS mapEditorButton.cpp newMapButton.cpp loadMapButton.cpp exportButton.cpp) @@ -19,12 +19,12 @@ set(GUI tooltip.cpp concreteGuiManager.cpp ${BUTTONS} ${LISTBOXES}) set(STATES activeGameState.cpp inGameAppState.cpp guiAppState.cpp mapEditorAppState.cpp) set(UTIL util.cpp binds.h) set(CONTROLLERS gameObjectFrameController.cpp cameraController.cpp) -set(CONSOLE console.cpp abstractCommand.cpp addUnitCommand.cpp addResourceCommand.cpp) +set(CONSOLE console.cpp abstractCommand.cpp addUnitCommand.cpp addResourceCommand.cpp addTechnologyCommand.cpp) set(CORE gameManager.cpp game.cpp defConfigs.cpp ${CONSOLE} ${CONTROLLERS}) set(PROJECTILES projectile.cpp cruiseMissile.cpp) set(FX fx.cpp) set(VEHICLES vehicle.cpp engineer.cpp resourceRover.cpp) -set(STRUCTURES structure.cpp factory.cpp pointDefense.cpp extractor.cpp) +set(STRUCTURES structure.cpp factory.cpp pointDefense.cpp extractor.cpp researchStruct.cpp) set(UNITS gameObjectFactory.cpp unit.cpp ${STRUCTURES} ${VEHICLES}) set(CONTENT player.cpp pathfinder.cpp map.cpp gameObject.cpp gameObjectFrame.h resourceDeposit.cpp ${UNITS} ${PROJECTILES} ${FX}) set(GAME_SRC ${STATES} ${GUI} ${CORE} ${CONTENT} ${UTIL}) diff --git a/ability.h b/ability.h new file mode 100644 index 0000000..c45f7dc --- /dev/null +++ b/ability.h @@ -0,0 +1,32 @@ +#ifndef ABILITY_H +#define ABILITY_H + +#include + +namespace battleship{ + struct Ability{ + enum class Type{ + SPEED, + HEALTH, + LINE_OF_SIGHT, + MAX_TURN_ANGLE, + DIRECT_HIT_DAMAGE, + EXPLOSION_RADIUS, + EXPLOSION_DAMAGE, + CAPACITY, + LOAD_RATE, + LOAD_SPEED, + DRAW_RATE, + DRAW_SPEED, + HACK_RANGE, + UNIT_UNLOCK + }; + + Type type; + float ammount; + int gameObjType; + std::vector gameObjIds; + }; +} + +#endif diff --git a/activeGameState.cpp b/activeGameState.cpp index 4692a9f..3e10f66 100755 --- a/activeGameState.cpp +++ b/activeGameState.cpp @@ -161,6 +161,7 @@ namespace battleship{ ConcreteGuiManager::getSingleton()->removeAllButtons(); buttons.clear(); + unitGuiScreen = ""; } bool ActiveGameState::selectedUnitsAmongst(vector units){ @@ -193,6 +194,7 @@ namespace battleship{ guiManager->getText("wealth"), guiManager->getText("research") }; + vector selUnits = mainPlayer->getSelectedUnits(); for (Unit *u : units) { @@ -200,16 +202,11 @@ namespace battleship{ Vector3 dragboxSize = ((Quad*)dragboxNode->getMesh(0))->getSize(); Vector3 dragboxOrigin = dragboxNode->getPosition(), dragboxEnd = dragboxOrigin + dragboxSize; Vector2 pos = u->getScreenPos(); + string guiScreen = u->getGuiScreen(); - if(buttons.empty()){ - if(selectedUnitsAmongst(mainPlayer->getUnitsByClass(UnitClass::ENGINEER))) - guiManager->readLuaScreenScript("engineerCommands.lua", buttons, listboxes, checkboxes, sliders, textboxes, guiRects, texts); - else if(selectedUnitsAmongst(mainPlayer->getUnitsByClass(UnitClass::FORT))) - guiManager->readLuaScreenScript("fortCommands.lua", buttons, listboxes, checkboxes, sliders, textboxes, guiRects, texts); - else if(selectedUnitsAmongst(mainPlayer->getUnitsByClass(UnitClass::LAND_FACTORY))) - guiManager->readLuaScreenScript("landFactoryCommands.lua", buttons, listboxes, checkboxes, sliders, textboxes, guiRects, texts); - else if(selectedUnitsAmongst(mainPlayer->getUnitsByClass(UnitClass::NAVAL_FACTORY))) - guiManager->readLuaScreenScript("navalFactoryCommands.lua", buttons, listboxes, checkboxes, sliders, textboxes, guiRects, texts); + if(!selUnits.empty() && u == selUnits[0] && guiScreen != "" && guiScreen != unitGuiScreen){ + guiManager->readLuaScreenScript(u->getGuiScreen(), buttons, listboxes, checkboxes, sliders, textboxes, guiRects, texts); + unitGuiScreen = guiScreen; } if(isSelectionBox && fabs(pos.x - dragboxOrigin.x) < .5 * dragboxSize.x && fabs(pos.y - dragboxOrigin.y) < .5 * dragboxSize.y){ diff --git a/activeGameState.h b/activeGameState.h index 1b01121..6de8d1b 100755 --- a/activeGameState.h +++ b/activeGameState.h @@ -47,6 +47,7 @@ namespace battleship{ GuiAppState *guiState; Player *mainPlayer; + std::string unitGuiScreen = ""; GameObject *gameObjHoveredOn = nullptr; vb01::Node *dragboxNode = nullptr; vb01::Vector2 clickPoint; diff --git a/addTechnologyCommand.cpp b/addTechnologyCommand.cpp new file mode 100644 index 0000000..7ff5025 --- /dev/null +++ b/addTechnologyCommand.cpp @@ -0,0 +1,42 @@ +#include "addTechnologyCommand.h" +#include "game.h" +#include "player.h" + +#include + +#include + +namespace battleship{ + using namespace std; + using namespace gameBase; + + void AddTechnologyCommand::validate(){ + if(arguments.size() != 2) + return; + + playerId = atoi(arguments[0].c_str()); + int numPlayers = Game::getSingleton()->getNumPlayers(); + + if(!(0 <= playerId && playerId < numPlayers)) + return; + + sol::state_view SOL_LUA_VIEW = generateView(); + SOL_LUA_VIEW.script("numTechs = #technologies"); + int numTechs = SOL_LUA_VIEW["numTechs"]; + + techId = atoi(arguments[1].c_str()); + + if(!(0 <= techId && techId < numTechs)) + return; + } + + void AddTechnologyCommand::addTechnology(){ + Game::getSingleton()->getPlayer(playerId)->addTechnology(techId); + } + + void AddTechnologyCommand::execute(){ + AbstractCommand::handle(); + validate(); + addTechnology(); + } +} diff --git a/addTechnologyCommand.h b/addTechnologyCommand.h new file mode 100644 index 0000000..d3fb32c --- /dev/null +++ b/addTechnologyCommand.h @@ -0,0 +1,19 @@ +#ifndef ADD_TECHNOLOGY_H +#define ADD_TECHNOLOGY_H + +#include "abstractCommand.h" + +namespace battleship{ + class AddTechnologyCommand : public AbstractCommand{ + public: + AddTechnologyCommand(std::string argsStr) : AbstractCommand(argsStr){} + void execute(); + private: + void validate(); + void addTechnology(); + + int playerId, techId; + }; +} + +#endif diff --git a/buildButton.cpp b/buildButton.cpp index e36c9ec..29f57e0 100644 --- a/buildButton.cpp +++ b/buildButton.cpp @@ -1,8 +1,12 @@ #include "buildButton.h" #include "gameManager.h" #include "gameObject.h" +#include "unit.h" +#include "activeGameState.h" +#include "buildableUnit.h" #include "gameObjectFrameController.h" +#include #include namespace battleship{ @@ -12,13 +16,18 @@ namespace battleship{ using namespace vb01Gui; using namespace gameBase; - BuildButton::BuildButton(Vector2 pos, Vector2 size, int structureId, string name, int trigger, string imagePath) : UnitButton(pos, size, name, GameManager::getSingleton()->getPath() + "Fonts/batang.ttf", trigger, imagePath){ - this->structureId = structureId; - } + BuildButton::BuildButton(Vector2 pos, Vector2 size, string name, int trigger, string imagePath, int uid, int slId) : + UnitButton(pos, size, name, GameManager::getSingleton()->getPath() + "Fonts/batang.ttf", trigger, imagePath, uid), slotId(slId){} void BuildButton::onClick(){ - GameObjectFrameController *ufCtr = GameObjectFrameController::getSingleton(); - ufCtr->addGameObjectFrame(GameObjectFrame(structureId, GameObject::Type::UNIT)); - ufCtr->setPlacingFrames(true); + ActiveGameState *activeState = (ActiveGameState*)(GameManager::getSingleton()->getStateManager()->getAppStateByType((int)AppStateType::ACTIVE_STATE)); + Player *player = activeState->getPlayer(); + Unit* builder = player->getUnitsById(unitId)[0]; + + if(builder->getBuildableUnit(slotId).buildable){ + GameObjectFrameController *ufCtr = GameObjectFrameController::getSingleton(); + ufCtr->addGameObjectFrame(GameObjectFrame(builder->getBuildableUnit(slotId).id, GameObject::Type::UNIT)); + ufCtr->setPlacingFrames(true); + } } } diff --git a/buildButton.h b/buildButton.h index ae4802b..b4cd97b 100644 --- a/buildButton.h +++ b/buildButton.h @@ -6,10 +6,10 @@ namespace battleship{ class BuildButton : public UnitButton{ public: - BuildButton(vb01::Vector2, vb01::Vector2, int, std::string, int, std::string); + BuildButton(vb01::Vector2, vb01::Vector2, std::string, int, std::string, int, int); void onClick(); private: - int structureId; + int slotId; }; } diff --git a/buildableUnit.h b/buildableUnit.h new file mode 100644 index 0000000..772a3b6 --- /dev/null +++ b/buildableUnit.h @@ -0,0 +1,13 @@ +#ifndef BUILDABLE_UNIT_H +#define BUILDABLE_UNIT_H + +namespace battleship{ + struct BuildableUnit{ + int id; + bool buildable; + + BuildableUnit(int i, bool build) : id(i), buildable(build){} + }; +} + +#endif diff --git a/concreteGuiManager.cpp b/concreteGuiManager.cpp index b48b393..7c04e61 100644 --- a/concreteGuiManager.cpp +++ b/concreteGuiManager.cpp @@ -24,6 +24,7 @@ #include "buildButton.h" #include "trainButton.h" #include "statsButton.h" +#include "researchButton.h" namespace battleship{ using namespace std; @@ -163,35 +164,42 @@ namespace battleship{ } case BUILD: { - int strId = guiTable["structureId"]; + int unitId = SOL_LUA_STATE["UnitId"]["ENGINEER"]; + int strId = SOL_LUA_STATE["units"][unitId + 1]["buildableUnits"][guiId + 1]["id"]; string buttonName = SOL_LUA_STATE["units"][strId + 1]["name"]; - button = new BuildButton(pos, size, strId, buttonName, (int)guiTable["trigger"], (string)guiTable["imagePath"]); + button = new BuildButton(pos, size, buttonName, (int)guiTable["trigger"], (string)guiTable["imagePath"], unitId, guiId); break; } case LAND_FACTORY_TRAIN: { - int unitId = guiTable["unitId"]; + int facId = SOL_LUA_STATE["UnitId"]["LAND_FACTORY"]; + int unitId = SOL_LUA_STATE["units"][facId + 1]["buildableUnits"][guiId + 1]["id"]; string buttonName = SOL_LUA_STATE["units"][unitId + 1]["name"]; - button = new TrainButton(pos, size, buttonName, (int)guiTable["trigger"], (string)guiTable["imagePath"], (int)SOL_LUA_STATE["UnitId"]["LAND_FACTORY"], unitId); + button = new TrainButton(pos, size, buttonName, (int)guiTable["trigger"], (string)guiTable["imagePath"], facId, guiId); break; } case NAVAL_FACTORY_TRAIN: { - int unitId = guiTable["unitId"]; + int facId = SOL_LUA_STATE["UnitId"]["NAVAL_FACTORY"]; + int unitId = SOL_LUA_STATE["units"][facId + 1]["buildableUnits"][guiId + 1]["id"]; string buttonName = SOL_LUA_STATE["units"][unitId + 1]["name"]; - button = new TrainButton(pos, size, buttonName, (int)guiTable["trigger"], (string)guiTable["imagePath"], (int)SOL_LUA_STATE["UnitId"]["NAVAL_FACTORY"], unitId); + button = new TrainButton(pos, size, buttonName, (int)guiTable["trigger"], (string)guiTable["imagePath"], facId, guiId); break; } case FORT_TRAIN: { - int unitId = guiTable["unitId"]; + int facId = SOL_LUA_STATE["UnitId"]["FORT"]; + int unitId = SOL_LUA_STATE["units"][facId + 1]["buildableUnits"][guiId + 1]["id"]; string buttonName = SOL_LUA_STATE["units"][unitId + 1]["name"]; - button = new TrainButton(pos, size, buttonName, (int)guiTable["trigger"], (string)guiTable["imagePath"], (int)SOL_LUA_STATE["UnitId"]["FORT"], unitId); + button = new TrainButton(pos, size, buttonName, (int)guiTable["trigger"], (string)guiTable["imagePath"], facId, guiId); break; } case STATISTICS: button = new StatsButton(pos, size, name, (int)guiTable["trigger"], (string)guiTable["imagePath"]); break; + case RESEARCH: + button = new ResearchButton(pos, size, name, (int)guiTable["trigger"], (string)guiTable["imagePath"], (int)SOL_LUA_STATE["UnitId"]["LAB"], (int)guiTable["techId"]); + break; } int typeArr[2]{(int)GuiElementType::BUTTON, (int)type}; diff --git a/concreteGuiManager.h b/concreteGuiManager.h index c141da2..d9bfb29 100644 --- a/concreteGuiManager.h +++ b/concreteGuiManager.h @@ -41,7 +41,8 @@ namespace battleship{ LAND_FACTORY_TRAIN, NAVAL_FACTORY_TRAIN, FORT_TRAIN, - STATISTICS + STATISTICS, + RESEARCH }; enum ListboxType { CONTROLS, diff --git a/console.cpp b/console.cpp index 421a745..58206f7 100755 --- a/console.cpp +++ b/console.cpp @@ -1,6 +1,7 @@ #include "console.h" #include "addUnitCommand.h" #include "addResourceCommand.h" +#include "addTechnologyCommand.h" using namespace std; @@ -18,5 +19,7 @@ namespace battleship{ AddUnitCommand(argsStr).execute(); else if(cmdName == "add-resource") AddResourceCommand(argsStr).execute(); + else if(cmdName == "add-technology") + AddTechnologyCommand(argsStr).execute(); } } diff --git a/defConfigs.h b/defConfigs.h index 8a74fcd..0bcf9ff 100755 --- a/defConfigs.h +++ b/defConfigs.h @@ -50,7 +50,9 @@ namespace battleship{ "Scripts/GameObjects/Projectiles/projectileData.lua", "Scripts/GameObjects/Units/unitData.lua", "Scripts/aiAgent.lua", - "Scripts/Core/player.lua" + "Scripts/Core/player.lua", + "Scripts/Technologies/technologyData.lua", + "Scripts/Abilities/abilityData.lua", }; const static Bind staticBinds[numAppStates][maxStaticBinds]{ diff --git a/engineer.cpp b/engineer.cpp index b2015d8..36a11d6 100644 --- a/engineer.cpp +++ b/engineer.cpp @@ -16,7 +16,9 @@ namespace battleship{ using namespace gameBase; Engineer::Engineer(Player *player, int id, Vector3 pos, Quaternion rot, Unit::State state) : Vehicle(player, id, pos, rot, state){ - hackRange = generateView()["units"][id + 1]["hackRange"]; + Game *game = Game::getSingleton(); + vector currTechs = player->getTechnologies(); + hackRange = generateView()["units"][id + 1]["hackRange"]; hackRange += game->calcAbilFromTech(Ability::Type::HACK_RANGE, currTechs, (int)GameObject::type, id); Vector2 size = Vector2(lenHpBar, 10); hackStatusBackground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1)); diff --git a/extractor.cpp b/extractor.cpp index 19c5692..23fcb6a 100644 --- a/extractor.cpp +++ b/extractor.cpp @@ -27,10 +27,6 @@ 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)); ammountForeground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 1, 1)); @@ -41,6 +37,16 @@ namespace battleship{ removeBar(ammountBackground); } + void Extractor::initProperties(){ + Structure::initProperties(); + Game *game = Game::getSingleton(); + vector currTechs = player->getTechnologies(); + + sol::table unitTable = generateView()["units"][id + 1]; + drawRate = unitTable["drawRate"]; drawRate += game->calcAbilFromTech(Ability::Type::DRAW_RATE, currTechs, (int)GameObject::type, id); + drawSpeed = unitTable["drawSpeed"]; drawSpeed += game->calcAbilFromTech(Ability::Type::DRAW_SPEED, currTechs, (int)GameObject::type, id); + } + void Extractor::update(){ Structure::update(); diff --git a/extractor.h b/extractor.h index a070765..0002eb4 100644 --- a/extractor.h +++ b/extractor.h @@ -17,6 +17,8 @@ namespace battleship{ bool canDraw(){return vb01::getTime() - lastDrawTime > drawRate;} inline ResourceDeposit* getDeposit(){return deposit;} private: + void initProperties(); + int drawSpeed, drawRate; vb01::s64 lastDrawTime = 0; vb01::Node *ammountBackground = nullptr, *ammountForeground = nullptr; diff --git a/factory.cpp b/factory.cpp index dfe72c1..0c02245 100644 --- a/factory.cpp +++ b/factory.cpp @@ -1,5 +1,6 @@ #include "factory.h" #include "player.h" +#include "game.h" #include "gameObjectFactory.h" #include "activeGameState.h" @@ -18,10 +19,20 @@ namespace battleship{ void Factory::update(){ Structure::update(); + if(!isComplete()) return; + if(!unitQueue.empty()) train(); } + //TODO replace repetetive string literals + void Factory::initProperties(){ + Structure::initProperties(); + Game *game = Game::getSingleton(); + vector currTechs = player->getTechnologies(); + + } + int Factory::getNumQueueUnitsById(int unitId){ int numUnits = 0; @@ -32,6 +43,11 @@ namespace battleship{ return numUnits; } + void Factory::appendToQueue(int buId){ + if(buId < buildableUnits.size() && buildableUnits[buId].buildable) + unitQueue.push_back(buildableUnits[buId].id); + } + void Factory::train(){ bool training = !unitQueue.empty(); buildStatusForeground->setVisible(training); diff --git a/factory.h b/factory.h index 851ae22..586eab8 100644 --- a/factory.h +++ b/factory.h @@ -19,14 +19,14 @@ namespace battleship{ ~Factory(){} void update(); int getNumQueueUnitsById(int); - void appendToQueue(int uid){unitQueue.push_back(uid);} + void appendToQueue(int); inline std::vector getQueue(){return unitQueue;} private: - const int MAX_LEN_QUEUE = 10; - int trainingStatus = 0; - vb01::s64 lastTrainTime = 0; std::vector unitQueue; + int maxLenQueue, trainingStatus = 0; + vb01::s64 lastTrainTime = 0; + void initProperties(); void train(); }; } diff --git a/game.cpp b/game.cpp index 24bfef0..5fd9e7a 100644 --- a/game.cpp +++ b/game.cpp @@ -7,6 +7,8 @@ #include "concreteGuiManager.h" #include "defConfigs.h" +#include + #include #include @@ -214,4 +216,88 @@ namespace battleship{ unit->setPlayer(newPlayer); unit->halt(); } + + vector Game::parseTechTable(int tid, string key, string numVarKey, string varKey){ + sol::state_view SOL_LUA_VIEW = generateView(); + SOL_LUA_VIEW.script(numVarKey + " = #" + key + "[" + to_string(tid + 1) + "]." + varKey); + int numVar = SOL_LUA_VIEW[numVarKey]; + sol::table techTable = SOL_LUA_VIEW[key][tid + 1]; + + vector varVec; + + for(int i = 0; i < numVar; i++) + varVec.push_back(techTable[varKey][i + 1]); + + return varVec; + } + + //TODO clean this method up + void Game::initTechnologies(){ + technologies.clear(); + + sol::state_view SOL_LUA_VIEW = generateView(); + string techKey = "technologies"; + SOL_LUA_VIEW.script("numTechs = #" + techKey); + int numTechs = SOL_LUA_VIEW["numTechs"]; + + for(int i = 0; i < numTechs; i++){ + sol::table techTable = SOL_LUA_VIEW[techKey][i + 1]; + + Technology t; + t.id = techTable["id"]; + t.cost = techTable["cost"]; + t.name = techTable["name"]; + t.icon = techTable["icon"]; + t.description = techTable["description"]; + t.parents = parseTechTable(i, techKey, "numParents", "parents"); + t.children = parseTechTable(i, techKey, "numChildren", "children"); + t.abilities = parseTechTable(i, techKey, "numAbilities", "abilities"); + + technologies.push_back(t); + } + + techKey = "abilities"; + SOL_LUA_VIEW.script("numAbilities = #" + techKey); + int numAbilities = SOL_LUA_VIEW["numAbilities"]; + + for(int i = 0; i < numAbilities; i++){ + sol::table techTable = SOL_LUA_VIEW[techKey][i + 1]; + + Ability ability; + ability.type = techTable["type"]; + ability.ammount = techTable["ammount"].get_or(0.0); + ability.gameObjType = techTable["gameObjType"]; + ability.gameObjIds = parseTechTable(i, techKey, "numGameObjIds", "gameObjIds"); + abilities.push_back(ability); + } + } + + float Game::calcAbilFromTech(Ability::Type type, vector techResearch, int gameObjType, int unitId){ + float ammount = 0; + + for(int techId : techResearch) + for(int abilId : technologies[techId].abilities) + if( + abilities[abilId].type == type && + abilities[abilId].gameObjType == gameObjType && + find(abilities[abilId].gameObjIds.begin(), abilities[abilId].gameObjIds.end(), unitId) != abilities[abilId].gameObjIds.end() + ){ + ammount += abilities[abilId].ammount; + } + + return ammount; + } + + bool Game::isUnitUnlocked(vector techResearch, int unitId){ + for(int techId : techResearch){ + for(int abilId : technologies[techId].abilities){ + vector ids = abilities[abilId].gameObjIds; + + if(find(ids.begin(), ids.end(), unitId) != ids.end()) + return true; + } + } + + return false; + } } diff --git a/game.h b/game.h index cb9c575..ae42ab8 100644 --- a/game.h +++ b/game.h @@ -2,6 +2,8 @@ #define GAME_H #include "fx.h" +#include "technology.h" +#include "ability.h" #include @@ -23,18 +25,26 @@ namespace battleship{ void removeAllElements(); void explode(vb01::Vector3, int, float, sf::Sound*); void changeUnitPlayer(Unit*, Player*); + void initTechnologies(); + float calcAbilFromTech(Ability::Type, std::vector, int, int); + bool isUnitUnlocked(std::vector, int); inline void addFx(Fx f){fx.push_back(f);} inline void addPlayer(Player *pl){players.push_back(pl);} inline std::vector& getPlayers(){return players;} inline Player* getPlayer(int id){return players[id];} inline int getNumPlayers(){return players.size();} + inline Technology getTechnology(int id){return technologies[id];} + inline Ability getAbility(int id){return abilities[id];} private: Game(){} void resetLuaGameObjects(); void endGame(bool); + std::vector parseTechTable(int, std::string, std::string, std::string); bool paused = false, ended = false; std::vector fx; + std::vector technologies; + std::vector abilities; std::vector players; }; } diff --git a/gameObjectFactory.cpp b/gameObjectFactory.cpp index 83fbc5f..dd39abc 100644 --- a/gameObjectFactory.cpp +++ b/gameObjectFactory.cpp @@ -8,6 +8,7 @@ #include "pointDefense.h" #include "extractor.h" #include "cruiseMissile.h" +#include "researchStruct.h" #include "defConfigs.h" #include @@ -32,8 +33,9 @@ namespace battleship{ return new PointDefense(player, id, pos, rot, buildStatus, Unit::State::STAND_GROUND); case UnitClass::EXTRACTOR: return new Extractor(player, id, pos, rot, buildStatus); - case UnitClass::MARKET: case UnitClass::LAB: + return new ResearchStruct(player, id, pos, rot, buildStatus); + case UnitClass::MARKET: case UnitClass::REFINERY: return new Structure(player, id, pos, rot, buildStatus, Unit::State::STAND_GROUND); case UnitClass::ENGINEER: diff --git a/playButton.cpp b/playButton.cpp index 7be1f3f..1d4b369 100644 --- a/playButton.cpp +++ b/playButton.cpp @@ -28,6 +28,9 @@ namespace battleship{ for(int i = 0; i < factionsListboxes.size(); i++) factions.push_back(to_string(factionsListboxes[i]->getSelectedOption())); + + Game *game = Game::getSingleton(); + game->initTechnologies(); int selectedMap = mapListbox->getSelectedOption(); string mapName = wstringToString(mapListbox->getContents()[selectedMap]); @@ -39,7 +42,7 @@ namespace battleship{ for(int i = 0; i < numPlayers; i++){ bool cpuPlayer = (i < numPlayers - 1); string name = (cpuPlayer ? "CPU player #" + to_string(i) : "Player"); - Game::getSingleton()->addPlayer(new Player(0, 0, i, Vector3(1, 1, 1), cpuPlayer, map->getSpawnPoint(i), name)); + game->addPlayer(new Player(0, 0, i, Vector3(1, 1, 1), cpuPlayer, map->getSpawnPoint(i), name)); } map->loadPlayerGameObjects(); diff --git a/player.cpp b/player.cpp index 26faa92..cec2871 100755 --- a/player.cpp +++ b/player.cpp @@ -2,6 +2,7 @@ #include "player.h" #include "structure.h" +#include "projectile.h" #include "stateManager.h" #include "activeGameState.h" #include "resourceDeposit.h" @@ -182,4 +183,8 @@ namespace battleship{ return ucUnits; } + + void Player::addTechnology(int techId){ + technologies.push_back(techId); + } } diff --git a/player.h b/player.h index a5af80b..e14e2c7 100755 --- a/player.h +++ b/player.h @@ -9,6 +9,7 @@ namespace battleship{ class ResourceDeposit; class Projectile; + class Unit; class Player { public: @@ -25,6 +26,7 @@ namespace battleship{ void selectUnits(std::vector); std::vector getUnitsById(int, int = -1); std::vector getUnitsByClass(UnitClass, int = -1); + void addTechnology(int); inline void deselectUnits(){selectedUnits.clear();} inline Unit* getSelectedUnit(int id){return selectedUnits[id];} inline std::vector getSelectedUnits(){return selectedUnits;} @@ -48,12 +50,15 @@ namespace battleship{ inline int getRefineds(){return refineds;} inline void setRefineds(int ref){this->refineds = ref;} inline void addRefineds(int ref){this->refineds += ref;} + inline void subtractRefineds(int ref){this->refineds -= ref;} inline int getWealth(){return wealth;} inline void setWealth(int w){this->wealth = w;} inline void addWealth(int w){this->wealth += w;} + inline void subtractWealth(int w){this->wealth -= w;} inline int getResearch(){return research;} inline void setResearch(int r){this->research = r;} inline void addResearch(int r){this->research += r;} + inline void subtractResearch(int r){this->research -= r;} inline bool isCpuPlayer(){return cpuPlayer;} inline int getNumVehiclesBuilt(){return vehiclesBuilt;} inline int getNumVehiclesDestroyed(){return vehiclesDestroyed;} @@ -69,9 +74,15 @@ namespace battleship{ inline void incStructuresLost(){structuresLost++;} inline vb01::Vector3 getColor(){return color;} inline std::string getName(){return name;} + inline std::vector getTechnologies(){return technologies;} private: bool cpuPlayer = false; - int refineds = 0, wealth = 0, research = 0, faction, difficulty, team, luaPlayerId, vehiclesBuilt = 0, vehiclesDestroyed = 0, vehiclesLost = 0, structuresBuilt = 0, structuresDestroyed = 0, structuresLost = 0; + std::vector technologies; + int luaPlayerId; + int refineds = 0, wealth = 0, research = 0; + int faction, difficulty, team; + int vehiclesBuilt = 0, vehiclesDestroyed = 0, vehiclesLost = 0; + int structuresBuilt = 0, structuresDestroyed = 0, structuresLost = 0; std::string name; std::vector units, selectedUnits; std::vector projectiles; diff --git a/pointDefense.cpp b/pointDefense.cpp index 42da4ff..e21c551 100644 --- a/pointDefense.cpp +++ b/pointDefense.cpp @@ -8,6 +8,8 @@ namespace battleship{ } void PointDefense::attack(Order order){ + if(!isComplete()) return; + Unit *targUnit = order.targets[0].unit; Vector3 targDir = (targUnit ? targUnit->getPos() : order.targets[0].pos) - pos; diff --git a/projectile.cpp b/projectile.cpp index b5a39a8..e362ca5 100755 --- a/projectile.cpp +++ b/projectile.cpp @@ -1,20 +1,21 @@ #include #include #include -#include -#include #include +#include +#include #include +#include "fx.h" #include "game.h" #include "unit.h" #include "util.h" +#include "player.h" #include "projectile.h" -#include "resourceDeposit.h" #include "defConfigs.h" +#include "resourceDeposit.h" #include "inGameAppState.h" -#include "fx.h" using namespace std; using namespace vb01; @@ -51,14 +52,16 @@ namespace battleship{ void Projectile::initProperties(){ GameObject::initProperties(); + Game *game = Game::getSingleton(); + vector currTechs = player->getTechnologies(); sol::table projTable = generateView()[GameObject::getGameObjTableName()][id + 1]; rayLength = projTable["rayLength"]; - directHitDamage = projTable["directHitDamage"]; + directHitDamage = projTable["directHitDamage"]; directHitDamage += game->calcAbilFromTech(Ability::Type::DIRECT_HIT_DAMAGE, currTechs, (int)GameObject::type, id); string explKey = "explosion"; - explosionDamage = projTable[explKey]["damage"]; - explosionRadius = projTable[explKey]["radius"]; + explosionDamage = projTable[explKey]["damage"]; explosionDamage += game->calcAbilFromTech(Ability::Type::EXPLOSION_DAMAGE, currTechs, (int)GameObject::type, id); + explosionRadius = projTable[explKey]["radius"]; explosionRadius += game->calcAbilFromTech(Ability::Type::EXPLOSION_RADIUS, currTechs, (int)GameObject::type, id); speed = projTable["speed"]; rotAngle = projTable["rotAngle"].get_or(0.0); } diff --git a/researchButton.cpp b/researchButton.cpp new file mode 100644 index 0000000..c950e9c --- /dev/null +++ b/researchButton.cpp @@ -0,0 +1,24 @@ +#include "researchButton.h" +#include "activeGameState.h" +#include "researchStruct.h" + +#include +#include + +namespace battleship{ + using namespace vb01; + using namespace std; + + ResearchButton::ResearchButton(Vector2 pos, Vector2 size, string name, int trigger, string imagePath, int uid, int tid) : + UnitButton(pos, size, name, GameManager::getSingleton()->getPath() + "Fonts/batang.ttf", trigger, imagePath, uid), techId(tid){} + + void ResearchButton::onClick(){ + ActiveGameState *activeState = (ActiveGameState*)(GameManager::getSingleton()->getStateManager()->getAppStateByType((int)AppStateType::ACTIVE_STATE)); + Player *player = activeState->getPlayer(); + vector selUnits = player->getSelectedUnits(), researchStructs = player->getUnitsById(unitId); + + for(Unit *rs : researchStructs) + if(find(selUnits.begin(), selUnits.end(), rs) != selUnits.end()) + ((ResearchStruct*)rs)->appendToQueue(techId); + } +} diff --git a/researchButton.h b/researchButton.h new file mode 100644 index 0000000..337bc2f --- /dev/null +++ b/researchButton.h @@ -0,0 +1,16 @@ +#ifndef RESEARCH_BUTTON_H +#define RESEARCH_BUTTON_H + +#include "unitButton.h" + +namespace battleship{ + class ResearchButton : public UnitButton{ + public: + ResearchButton(vb01::Vector2, vb01::Vector2, std::string, int, std::string, int, int); + void onClick(); + private: + int techId; + }; +} + +#endif diff --git a/researchStruct.cpp b/researchStruct.cpp new file mode 100644 index 0000000..0e498a4 --- /dev/null +++ b/researchStruct.cpp @@ -0,0 +1,67 @@ +#include "researchStruct.h" +#include "activeGameState.h" +#include "player.h" +#include "game.h" + +#include + +namespace battleship{ + using namespace std; + using namespace vb01; + using namespace gameBase; + + ResearchStruct::ResearchStruct(Player *player, int id, Vector3 pos, Quaternion rot, int buildStatus, Unit::State state) : Structure(player, id, pos, rot, buildStatus, state){ + sol::table unitTable = generateView()["units"][id + 1]; + generationRate = unitTable["generationRate"]; + generationSpeed = unitTable["generationSpeed"]; + researchCost = unitTable["researchCost"]; + + Vector2 size = Vector2(lenHpBar, 10); + researchStatusBackground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1)); + researchStatusForeground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(1, 0, 1, 1)); + } + + ResearchStruct::~ResearchStruct(){ + removeBar(researchStatusBackground); + removeBar(researchStatusForeground); + } + + void ResearchStruct::update(){ + Structure::update(); + + if(!isComplete()) return; + + ActiveGameState *activeState = (ActiveGameState*)GameManager::getSingleton()->getStateManager()->getAppStateByType(AppStateType::ACTIVE_STATE); + Player *mainPlayer = (activeState ? activeState->getPlayer() : nullptr); + + vector selectingPlayers = Unit::getSelectingPlayers(); + bool mainPlayerSelecting = (activeState && find(selectingPlayers.begin(), selectingPlayers.end(), mainPlayer) != selectingPlayers.end()); + + if(researchQueue.empty()){ + if(health > .3 * maxHealth && player->getRefineds() >= researchCost && canUpdateResearch()){ + player->addResearch(generationSpeed); + player->subtractRefineds(researchCost); + lastUpdateTime = getTime(); + } + + researchStatusBackground->setVisible(false); + researchStatusForeground->setVisible(false); + } + else if(!researchQueue.empty()){ + Unit::displayUnitStats(researchStatusForeground, researchStatusBackground, researchStatus, 100, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10)); + + int techCost = Game::getSingleton()->getTechnology(researchQueue[0]).cost; + int playerResearch = player->getResearch(); + + if(techCost > playerResearch && canUpdateResearch()){ + researchStatus += int(100 * ((float)playerResearch / techCost)); + lastUpdateTime = getTime(); + } + else if(researchStatus >= 100 || techCost <= playerResearch){ + player->addTechnology(researchQueue[0]); + researchQueue.erase(researchQueue.begin()); + researchStatus = 0; + } + } + } +} diff --git a/researchStruct.h b/researchStruct.h new file mode 100644 index 0000000..03ef393 --- /dev/null +++ b/researchStruct.h @@ -0,0 +1,28 @@ +#ifndef RESEARCH_STRUCT_H +#define RESEARCH_STRUCT_H + +#include "structure.h" + +namespace vb01{ + class Node; +} + +namespace battleship{ + class ResearchStruct : public Structure{ + public: + ResearchStruct(Player*, int, vb01::Vector3, vb01::Quaternion, int = 0, Unit::State = Unit::State::STAND_GROUND); + ~ResearchStruct(); + void update(); + inline void appendToQueue(int tid){researchQueue.push_back(tid);} + private: + vb01::s64 lastUpdateTime = 0; + int researchCost, generationRate, generationSpeed, researchStatus = 0; + std::vector researchQueue; + vb01::Node *researchStatusForeground = nullptr, *researchStatusBackground = nullptr; + + bool canUpdateResearch(){return vb01::getTime() - lastUpdateTime > generationRate;} + void generateResearch(); + }; +} + +#endif diff --git a/resourceRover.cpp b/resourceRover.cpp index d507268..a7d51b0 100644 --- a/resourceRover.cpp +++ b/resourceRover.cpp @@ -1,6 +1,7 @@ #include "resourceRover.h" #include "resourceDeposit.h" #include "map.h" +#include "game.h" #include "player.h" #include "extractor.h" #include "structure.h" @@ -14,11 +15,6 @@ namespace battleship{ using namespace gameBase; ResourceRover::ResourceRover(Player *player, int id, Vector3 pos, Quaternion rot, Unit::State state) : Vehicle(player, id, pos, rot, state) { - sol::table unitTable = generateView()["units"][id + 1]; - capacity = unitTable["capacity"]; - loadSpeed = unitTable["loadSpeed"]; - 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)); @@ -29,6 +25,17 @@ namespace battleship{ removeBar(loadBackground); } + void ResourceRover::initProperties(){ + Vehicle::initProperties(); + Game *game = Game::getSingleton(); + vector currTechs = player->getTechnologies(); + + sol::table unitTable = generateView()["units"][id + 1]; + capacity = unitTable["capacity"]; capacity += game->calcAbilFromTech(Ability::Type::CAPACITY, currTechs, (int)GameObject::type, id); + loadSpeed = unitTable["loadSpeed"]; loadSpeed += game->calcAbilFromTech(Ability::Type::LOAD_SPEED, currTechs, (int)GameObject::type, id); + loadRate = unitTable["loadRate"]; loadRate += game->calcAbilFromTech(Ability::Type::LOAD_RATE, currTechs, (int)GameObject::type, id); + } + void ResourceRover::supply(Order order){ float minDist = .5 * Map::getSingleton()->getCellSize().x; @@ -102,7 +109,7 @@ namespace battleship{ int minDistId = -1; for(int i = 0; i < structs.size(); i++) - if(structs[i]->getBuildStatus() == 100){ + if(structs[i]->isComplete()){ minDistId = i; break; } @@ -110,7 +117,7 @@ namespace battleship{ if(minDistId == -1) return nullptr; for(int i = 0; i < structs.size(); i++) - if(structs[i]->getBuildStatus() == 100 && structs[minDistId]->getPos().getDistanceFrom(pos) > structs[i]->getPos().getDistanceFrom(pos)) + if(structs[i]->isComplete() && structs[minDistId]->getPos().getDistanceFrom(pos) > structs[i]->getPos().getDistanceFrom(pos)) minDistId = i; return structs[minDistId]; diff --git a/resourceRover.h b/resourceRover.h index b8d4cee..bd1c637 100644 --- a/resourceRover.h +++ b/resourceRover.h @@ -15,6 +15,7 @@ namespace battleship{ ~ResourceRover(); void update(); private: + void initProperties(); void supply(Order); Unit* getClosestUnit(std::vector); inline bool canLoad(){return vb01::getTime() - lastLoadTime > loadRate && load < capacity;} diff --git a/structure.h b/structure.h index 10bd58a..da01ffa 100644 --- a/structure.h +++ b/structure.h @@ -13,6 +13,7 @@ namespace battleship{ Structure(Player*, int, vb01::Vector3, vb01::Quaternion, int = 0, Unit::State = Unit::State::STAND_GROUND); ~Structure(); virtual void update(); + inline bool isComplete(){return buildStatus == 100;} inline int getBuildStatus(){return buildStatus;} inline void incrementBuildStatus(){buildStatus++;} private: diff --git a/technology.h b/technology.h new file mode 100644 index 0000000..c93985f --- /dev/null +++ b/technology.h @@ -0,0 +1,19 @@ +#ifndef TECHNOLOGY_H +#define TECHNOLOGY_H + +#include +#include + +namespace battleship{ + struct Technology{ + int id, cost; + std::string name; + std::string icon; + std::string description; + std::vector parents; + std::vector children; + std::vector abilities; + }; +} + +#endif diff --git a/trainButton.cpp b/trainButton.cpp index 436c84c..bab5d5e 100644 --- a/trainButton.cpp +++ b/trainButton.cpp @@ -1,5 +1,6 @@ #include "trainButton.h" #include "activeGameState.h" +#include "buildableUnit.h" #include "factory.h" #include @@ -10,19 +11,17 @@ namespace battleship{ using namespace vb01; using namespace gameBase; - TrainButton::TrainButton(Vector2 pos, Vector2 size, string name, int trigger, string imagePath, int fid, int tuid) : - factoryId(fid), - trainableUnitId(tuid), - UnitButton(pos, size, name, GameManager::getSingleton()->getPath() + "Fonts/batang.ttf", trigger, imagePath){} + TrainButton::TrainButton(Vector2 pos, Vector2 size, string name, int trigger, string imagePath, int uid, int slId) : + UnitButton(pos, size, name, GameManager::getSingleton()->getPath() + "Fonts/batang.ttf", trigger, imagePath, uid), + slotId(slId) {} void TrainButton::onClick(){ ActiveGameState *activeState = (ActiveGameState*)(GameManager::getSingleton()->getStateManager()->getAppStateByType((int)AppStateType::ACTIVE_STATE)); Player *player = activeState->getPlayer(); - UnitClass facClass = (UnitClass)generateView()["units"][factoryId + 1]["unitClass"]; - vector selUnits = player->getSelectedUnits(), factories = player->getUnitsByClass(facClass); + vector selUnits = player->getSelectedUnits(), factories = player->getUnitsById(unitId); for(Unit *fac : factories) - if(find(selUnits.begin(), selUnits.end(), fac) != selUnits.end()) - ((Factory*)fac)->appendToQueue(trainableUnitId); + if(fac->getBuildableUnit(slotId).buildable && find(selUnits.begin(), selUnits.end(), fac) != selUnits.end()) + ((Factory*)fac)->appendToQueue(slotId); } } diff --git a/trainButton.h b/trainButton.h index e600dd1..149c906 100644 --- a/trainButton.h +++ b/trainButton.h @@ -9,7 +9,7 @@ namespace battleship{ TrainButton(vb01::Vector2, vb01::Vector2, std::string, int, std::string, int, int); void onClick(); private: - int factoryId, trainableUnitId; + int slotId; }; } diff --git a/unit.cpp b/unit.cpp index f111577..c250ef0 100755 --- a/unit.cpp +++ b/unit.cpp @@ -16,8 +16,11 @@ #include "vehicle.h" #include "gameObjectFactory.h" #include "activeGameState.h" +#include "gameManager.h" +#include "projectile.h" #include "defConfigs.h" #include "pathfinder.h" +#include "ability.h" using namespace glm; using namespace vb01; @@ -126,15 +129,23 @@ namespace battleship{ sol::state_view SOL_LUA_VIEW = generateView(); string objType = GameObject::getGameObjTableName(); sol::table unitTable = SOL_LUA_VIEW[objType][id + 1]; + + Game *game = Game::getSingleton(); + vector currTechs = player->getTechnologies(); + string name = unitTable["name"]; - health = unitTable["health"]; + health = unitTable["health"]; health += game->calcAbilFromTech(Ability::Type::HEALTH, currTechs, (int)GameObject::type, id); vehicle = unitTable["isVehicle"]; maxHealth = health; - lineOfSight = unitTable["lineOfSight"]; + lineOfSight = unitTable["lineOfSight"]; lineOfSight += game->calcAbilFromTech(Ability::Type::LINE_OF_SIGHT, currTechs, (int)GameObject::type, id); unitClass = (UnitClass)unitTable["unitClass"]; type = (UnitType)unitTable["unitType"]; + string gsk = "guiScreen"; + sol::optional nameOpt = unitTable[gsk]; + guiScreen = (nameOpt != sol::nullopt ? (string)unitTable[gsk] : ""); + string tblName = "garrisonCapacity"; sol::optional gc = unitTable[tblName]; @@ -166,6 +177,19 @@ namespace battleship{ armorTypes.push_back(arm); } } + + tblName = "buildableUnits"; + sol::optional bu = unitTable[tblName]; + + if(bu != sol::nullopt){ + SOL_LUA_VIEW.script("numBuildableUnits = #units[" + to_string(id + 1) + "]." + tblName); + int numBuildableUnits = SOL_LUA_VIEW["numBuildableUnits"]; + + for(int i = 0; i < numBuildableUnits; i++){ + sol::table buTable = unitTable[tblName][i + 1]; + buildableUnits.push_back(BuildableUnit(buTable["id"], game->isUnitUnlocked(currTechs, id) | (bool)buTable["buildable"])); + } + } } void Unit::initWeapons(){ diff --git a/unit.h b/unit.h index 2052d9e..0d8d31e 100755 --- a/unit.h +++ b/unit.h @@ -8,9 +8,8 @@ #include -#include "gameManager.h" #include "gameObject.h" -#include "projectile.h" +#include "buildableUnit.h" namespace sf{ class SoundBuffer; @@ -31,8 +30,9 @@ namespace battleship{ class Structure; class Factory; class Cruiser; - class PointDefense; class Engineer; + class PointDefense; + class Projectile; struct Order { enum class TYPE {ATTACK, BUILD, MOVE, GARRISON, EJECT, PATROL, LAUNCH, SUPPLY, HACK}; @@ -149,6 +149,8 @@ namespace battleship{ inline bool isTargetToTheRight(vb01::Vector3 dir, vb01::Vector3 lv){return lv.getAngleBetween(dir) > vb01::PI / 2;} inline Order getOrder(int i){return orders[i];} inline int getNumOrders(){return orders.size();} + inline std::string getGuiScreen(){return guiScreen;} + inline BuildableUnit getBuildableUnit(int i){return buildableUnits[i];} private: void renderOrderLine(bool); void updateScreenCoordinates(); @@ -165,12 +167,14 @@ namespace battleship{ UnitClass unitClass; UnitType type; std::vector orders; + std::string guiScreen = ""; int health, maxHealth, playerId, lenHpBar = 200; - s64 orderLineDispTime = 0, lastFireTime = 0; + vb01::s64 orderLineDispTime = 0, lastFireTime = 0; float lineOfSight; - std::vector garrisonSlots; std::vector armorTypes; std::vector weapons; + std::vector garrisonSlots; + std::vector buildableUnits; State state = State::STAND_GROUND; std::vector getSelectingPlayers(); diff --git a/unitButton.cpp b/unitButton.cpp index 3a0d8ba..bb568a1 100644 --- a/unitButton.cpp +++ b/unitButton.cpp @@ -10,7 +10,7 @@ namespace battleship{ using namespace vb01Gui; using namespace gameBase; - UnitButton::UnitButton(Vector2 pos, Vector2 size, string name, string fontPath, int trigger, string imagePath) : Button(pos, size, name, fontPath, trigger, true, imagePath){ + UnitButton::UnitButton(Vector2 pos, Vector2 size, string name, string fontPath, int trigger, string imagePath, int uid) : Button(pos, size, name, fontPath, trigger, true, imagePath), unitId(uid){ StateManager *stateManager = GameManager::getSingleton()->getStateManager(); ActiveGameState *activeState = (ActiveGameState*)stateManager->getAppStateByType((int)AppStateType::ACTIVE_STATE); diff --git a/unitButton.h b/unitButton.h index 696ae1e..3184544 100644 --- a/unitButton.h +++ b/unitButton.h @@ -8,9 +8,9 @@ namespace battleship{ class UnitButton : public vb01Gui::Button{ public: - UnitButton(vb01::Vector2, vb01::Vector2, std::string, std::string, int, std::string); + UnitButton(vb01::Vector2, vb01::Vector2, std::string, std::string, int, std::string, int); protected: - std::vector units; + int unitId; }; } diff --git a/vehicle.cpp b/vehicle.cpp index e95470f..45bd04a 100644 --- a/vehicle.cpp +++ b/vehicle.cpp @@ -10,6 +10,8 @@ #include "vehicle.h" #include "pathfinder.h" +#include "player.h" +#include "game.h" #include "map.h" using namespace gameBase; @@ -83,9 +85,12 @@ namespace battleship{ } void Vehicle::initProperties(){ + Game *game = Game::getSingleton(); + vector currTechs = player->getTechnologies(); + sol::table unitTable = generateView()[GameObject::getGameObjTableName()][id + 1]; - maxTurnAngle = unitTable["maxTurnAngle"]; - speed = unitTable["speed"]; + maxTurnAngle = unitTable["maxTurnAngle"]; maxTurnAngle += game->calcAbilFromTech(Ability::Type::MAX_TURN_ANGLE, currTechs, (int)GameObject::type, id); + speed = unitTable["speed"]; speed += game->calcAbilFromTech(Ability::Type::SPEED, currTechs, (int)GameObject::type, id); anglePrecision = unitTable["anglePrecision"]; garrisonCategory = unitTable["garrisonCategory"]; }