diff --git a/include/GameObjectManager.hpp b/include/GameObjectManager.hpp index 52c1bea2..bf62fa0b 100644 --- a/include/GameObjectManager.hpp +++ b/include/GameObjectManager.hpp @@ -5,6 +5,7 @@ #ifndef PRACTICALTOOLSFORSIMPLEDESIGN_GAMEOBJECTMANAGER_HPP #define PRACTICALTOOLSFORSIMPLEDESIGN_GAMEOBJECTMANAGER_HPP #include "GameObjectID.hpp" +#include "Player.hpp" #include "Structure/AdvencePowerPlants.hpp" #include "Structure/Barracks.hpp" #include "Structure/OreRefinery.hpp" @@ -14,6 +15,7 @@ #include "Unit/Avatar.hpp" #include #include +#include class GameObjectManager { public: GameObjectManager() {} @@ -26,6 +28,7 @@ class GameObjectManager { for (auto pair : m_BuiltStructure) { pair->Start(); } + m_StartTime = std::chrono::high_resolution_clock::now(); } glm::vec2 start; glm::vec2 end; @@ -38,6 +41,14 @@ class GameObjectManager { } CursorSelect(&start, &end); + + //currency update + std::chrono::high_resolution_clock::time_point m_currentTime = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed = m_currentTime - m_StartTime; + if(elapsed.count()-m_lastElapsed>=1){//update every second + m_lastElapsed=elapsed.count(); + updateTotalCurrency(); + } } void CursorSelect(glm::vec2 *start, glm::vec2 *end) { @@ -62,7 +73,7 @@ class GameObjectManager { newstruct->Start(); m_BuiltStructure.push_back(newstruct); } - void unitAppend(std::shared_ptr newUnit) { + void Append(std::shared_ptr newUnit) { m_UnitArray.push_back(newUnit); printf("(GOM) push back success\n"); } @@ -76,16 +87,32 @@ class GameObjectManager { } return totalPower; } + int GetTotalCurrency() { + return m_Player->getTotalCurrency(); + } + void updateTotalCurrency(){ + int totalCurrency = m_Player->getTotalCurrency(); + if(m_BuiltStructure.size()>0){ + for (int i = 0; i < m_BuiltStructure.size(); i++) { + totalCurrency += m_BuiltStructure[i]->GetBuildingIncome(); + } + } + m_Player->setTotalCurrency(totalCurrency); + } std::vector> getStructureArray() { return m_BuiltStructure; } + void importPlayer(std::shared_ptr player){m_Player=player;} private: std::vector> m_BuiltStructure; std::vector> m_UnitArray; std::vector>> m_Map; + std::shared_ptr m_Player; + std::chrono::high_resolution_clock::time_point m_StartTime; + double m_lastElapsed=0.F; }; #endif // PRACTICALTOOLSFORSIMPLEDESIGN_GAMEOBJECTMANAGER_HPP diff --git a/include/Scene/DefaultScene.hpp b/include/Scene/DefaultScene.hpp index 4b31fe22..f1d2d79f 100644 --- a/include/Scene/DefaultScene.hpp +++ b/include/Scene/DefaultScene.hpp @@ -49,7 +49,7 @@ class DefaultScene { UIClass m_UI; std::shared_ptr m_Map = std::make_shared(); std::shared_ptr m_Player = std::make_shared(); - GameObjectManager m_Manager; + std::shared_ptr m_Manager = std::make_shared(); Avatar m_dummy; }; diff --git a/include/Structure/AdvencePowerPlants.hpp b/include/Structure/AdvencePowerPlants.hpp index 49ba22fa..822afd1c 100644 --- a/include/Structure/AdvencePowerPlants.hpp +++ b/include/Structure/AdvencePowerPlants.hpp @@ -4,7 +4,7 @@ #include "Structure.hpp" class ADVPowerPlants : public Structure { public: - ADVPowerPlants(float electricPower = 200.F, float buildingTime = 25.F, + ADVPowerPlants(float electricPower = 200.F, float buildingTime = 25.F*CHEAT, float buildingCost = 500.F, float buildingHp = 700.F, HouseType house = HouseType::NONE) : Structure(electricPower, buildingTime, buildingCost, buildingHp, diff --git a/include/Structure/Barracks.hpp b/include/Structure/Barracks.hpp index 80252f62..b58a299a 100644 --- a/include/Structure/Barracks.hpp +++ b/include/Structure/Barracks.hpp @@ -3,9 +3,10 @@ #include "WayPointStructure.hpp" + class Barracks : public WayPointStructure { public: - Barracks(float electricPower = -20.F, float buildingTime = 1.F, + Barracks(float electricPower = -20.F, float buildingTime = 15.F*CHEAT, float buildingCost = 300.F, float buildingHp = 800.F, HouseType house = HouseType::NONE) diff --git a/include/Structure/OreRefinery.hpp b/include/Structure/OreRefinery.hpp index 94feede3..9a5c9473 100644 --- a/include/Structure/OreRefinery.hpp +++ b/include/Structure/OreRefinery.hpp @@ -4,12 +4,13 @@ class OreRefinery : public WayPointStructure { public: - OreRefinery(float electricPower = -30.F, float buildingTime = 100.F, + OreRefinery(float electricPower = -30.F, float buildingTime = 100.F*CHEAT, float buildingCost = 2000.F, float buildingHp = 900.F, HouseType house = HouseType::NONE) : WayPointStructure(electricPower, buildingTime, buildingCost, buildingHp, GameObjectID(unitType::ORE_REF, house)){}; void Start() override; + virtual float GetBuildingIncome()override{return 50.F;}//debug }; #endif diff --git a/include/Structure/PowerPlants.hpp b/include/Structure/PowerPlants.hpp index af00ba52..6cfdb7d9 100644 --- a/include/Structure/PowerPlants.hpp +++ b/include/Structure/PowerPlants.hpp @@ -5,7 +5,7 @@ class PowerPlants : public Structure { public: - PowerPlants(float electricPower = 100.F, float buildingTime = 15.F, + PowerPlants(float electricPower = 100.F, float buildingTime = 15.F*CHEAT, float buildingCost = 300.F, float buildingHp = 400.F, HouseType house = HouseType::NONE) : Structure(electricPower, buildingTime, buildingCost, buildingHp, diff --git a/include/Structure/Structure.hpp b/include/Structure/Structure.hpp index 4fc6269e..17ef3bd3 100644 --- a/include/Structure/Structure.hpp +++ b/include/Structure/Structure.hpp @@ -14,6 +14,7 @@ #include "Util/TransformUtils.hpp" #include "glm/glm.hpp" #define DEFAULT_ZINDEX 15 +#define CHEAT 0.1F class Structure : public Util::GameObject, public Selectable { @@ -83,6 +84,8 @@ class Structure : public Util::GameObject, public Selectable { float GetElectricPower(); float GetBuildingTime(); float GetBuildingCost(); + virtual float GetBuildingIncome(){return buildingIncome;}; + void SetBuildingIncome(float income){buildingIncome=income;} float GetBuildingHp(); GameObjectID GetID() { return m_ID; } @@ -95,6 +98,7 @@ class Structure : public Util::GameObject, public Selectable { float buildingTime; float buildingCost; float buildingHp; + float buildingIncome=0.F; HighLight m_HighLight; GameObjectID m_ID; diff --git a/include/UI/UI.hpp b/include/UI/UI.hpp index 1cee82d1..9fe9df2c 100644 --- a/include/UI/UI.hpp +++ b/include/UI/UI.hpp @@ -6,6 +6,7 @@ #define PRACTICALTOOLSFORSIMPLEDESIGN_UI_HPP #include "Camera.hpp" #include "GameObjectID.hpp" +#include "GameObjectManager.hpp" #include "Player.hpp" #include "SpriteSheet.hpp" #include "UI/UIScriptProcess.hpp" @@ -40,8 +41,11 @@ class UIClass { //import from scene void importMap(std::shared_ptr m_Map){this->m_Map=m_Map;} - void importPlayer(std::shared_ptr m_Player){this->m_Player=m_Player;} - + void importPlayer(std::shared_ptr m_Player){this->m_Player=m_Player; ButtonScript.importPlayer(m_Player);} + void importGameObjManager(std::shared_ptr gameObjectManager){ + m_gameObjectManager=gameObjectManager; + ButtonScript.importGameObjManager(gameObjectManager); + } //check if building has built void checkExistBuilding(std::vector> buildingList); private: @@ -112,6 +116,7 @@ class UIClass { //ptr import from scene std::shared_ptr m_Map; std::shared_ptr m_Player; + std::shared_ptr m_gameObjectManager; }; #endif // PRACTICALTOOLSFORSIMPLEDESIGN_UI_HPP diff --git a/include/UI/UIScriptProcess.hpp b/include/UI/UIScriptProcess.hpp index f1267dcc..80b62e53 100644 --- a/include/UI/UIScriptProcess.hpp +++ b/include/UI/UIScriptProcess.hpp @@ -5,6 +5,8 @@ #ifndef PRACTICALTOOLSFORSIMPLEDESIGN_UISCRIPTPROCESS_HPP #define PRACTICALTOOLSFORSIMPLEDESIGN_UISCRIPTPROCESS_HPP #include "GameObjectID.hpp" +#include "GameObjectManager.hpp" +#include "Player.hpp" #include "Structure/AdvencePowerPlants.hpp" #include "Structure/Barracks.hpp" #include "Structure/OreRefinery.hpp" @@ -20,6 +22,9 @@ class UIScriptProcess { private: + std::shared_ptr m_player; + std::shared_ptr m_gameObjectManager; + // building bool b_Baracks = false; bool b_OreRefinery = false; @@ -28,28 +33,37 @@ class UIScriptProcess { bool b_ADVPowerPlant = false; float m_buildCoolDownTime = 0.F; + float m_offPowerBuildCoolDownTime = 0.F; unitType m_currentStructureType; bool b_isBuildingInCoolDown = false; std::deque m_buildQueue; std::chrono::time_point m_buildStartTime; - std::chrono::time_point - m_currentCountDownTime; + std::chrono::time_point m_buildTempTime; + std::chrono::time_pointm_currentCountDownTime; + float m_lastBuildElapsed=0.F; + int m_currentBuildRemainingCost=0; // building end // avatar bool b_isReadyToSpawn = false; - float m_spawnCooldownTime = 0.F; + float m_spawnCoolDownTime = 0.F; + float m_offPowerSpawnCoolDownTime = 0.F; unitType m_currentAvatarType; bool b_isSpawningInCooldown= false; std::deque m_spawnQueue; std::chrono::time_point m_SpawnStartTime; + std::chrono::time_point m_SpawnTempTime; + float m_lastSpawnElapsed=0.F; + int m_currentSpawnRemainingCost=0; // avatar end public: UIScriptProcess(){}; ~UIScriptProcess(){}; - // + + //Getter/Setter bool GetIfFinished(unitType type); + int GetObjCost(unitType type); // if b_isBuildingInCoolDown==false not currently building // true currently is building void SetSTALL(bool value) { b_isBuildingInCoolDown = value; }; @@ -59,15 +73,19 @@ class UIScriptProcess { void SetIfFinished(unitType type, bool value); float GetCDLeft(); std::string GetFormattedCD(); + // Event void AddToBuildQueue(unitType type); void AddToSpawnQueue(unitType type); void Update(bool queueContinue); // CountDown - void SetCountDown(float time); + void SetBuildCountDown(float time); void SetSpawnCountDown(float time); + float GetBuildCountDownTime(); + float GetSpawnCountDownTime(); void CountDown(); + // transform to ptr float GetStructureTime(unitType type); float GetSpawnTime(unitType type); @@ -79,6 +97,10 @@ class UIScriptProcess { bool getIfReadytoSpawn(){return b_isReadyToSpawn;} void setIfReadytoSpawn(bool b){b_isReadyToSpawn=b;} + //import from scene + void importPlayer(std::shared_ptr player){m_player=player;} + void importGameObjManager(std::shared_ptr gameObjectManager){m_gameObjectManager=gameObjectManager;} + private: std::shared_ptr barracks = std::make_shared(); std::shared_ptr oreRefinery = std::make_shared(); diff --git a/src/Scene/DefaultScene.cpp b/src/Scene/DefaultScene.cpp index 06e40a1e..4df7e75d 100644 --- a/src/Scene/DefaultScene.cpp +++ b/src/Scene/DefaultScene.cpp @@ -25,16 +25,19 @@ void DefaultScene::Start() { // m_GameObjectManager.Start(); //m_dummy.Start({5, 5}, m_Map); + m_Manager->importPlayer(m_Player); m_UI.importMap(m_Map); m_UI.importPlayer(m_Player); + m_UI.importGameObjManager(m_Manager); - m_Player->setTotalCurrency(50000); + + m_Player->setTotalCurrency(5000); } void DefaultScene::Update() { //m_dummy.Update(); - m_Manager.Update(); + m_Manager->Update(); Util::Transform trans; m_Map->Draw(trans, 0); @@ -59,10 +62,10 @@ void DefaultScene::Update() { // m_GameObjectManager.Update(); if (m_UI.getIfAnyBuildingReadyToBuild()) { - m_Manager.Append(m_UI.getSelectedBuilding()); + m_Manager->Append(m_UI.getSelectedBuilding()); } - m_UI.checkExistBuilding(m_Manager.getStructureArray()); + m_UI.checkExistBuilding(m_Manager->getStructureArray()); if(m_UI.getIfUnitReadyToSpawn()){ - m_Manager.unitAppend(m_UI.getUnitFromUI()); + m_Manager->Append(m_UI.getUnitFromUI()); } } diff --git a/src/Structure/OreRefinery.cpp b/src/Structure/OreRefinery.cpp index 6ce38a5e..57e32791 100644 --- a/src/Structure/OreRefinery.cpp +++ b/src/Structure/OreRefinery.cpp @@ -2,8 +2,7 @@ #include "Structure/OreRefinery.hpp" void OreRefinery::Start() { // Set Texture---------------------------------------- - this->SetDrawable( - std::make_unique("../assets/sprites/barracks.png")); + SetDrawable(std::make_unique("../assets/sprites/OreRefinery.png")); m_wayPoint->SetDrawable( std::make_unique("../assets/sprites/flagB.png")); m_HighLight.SetDrawable( diff --git a/src/UI/UI.cpp b/src/UI/UI.cpp index e3716670..2067f286 100644 --- a/src/UI/UI.cpp +++ b/src/UI/UI.cpp @@ -68,8 +68,8 @@ void UIClass::ShowHeaderSection() { .c_str()); // ImGui::Text(fmt::format("Zoom: {}", // m_SceneCamera.getCameraZoom()).c_str()); - ImGui::Text(fmt::format("$ {}", 1000).c_str()); - ImGui::Text(fmt::format("Power {}", 50).c_str()); + ImGui::Text(fmt::format("$ {}", m_Player->getTotalCurrency()).c_str()); + ImGui::Text(fmt::format("Power {}", m_gameObjectManager->GetTotalPower()).c_str()); ImGui::PushFont(sacker_med); if (ImGui::Button("Grid")) { } @@ -456,14 +456,14 @@ void UIClass::checkExistBuilding( } else if (std::dynamic_pointer_cast(i) && !b_warfactoryBuilt) { m_warfactoryTargetCell = MapUtil::GlobalCoordToCellCoord( - std::dynamic_pointer_cast(i)->GetWayPointLocation()); + std::dynamic_pointer_cast(i)->GetWayPointLocation()); b_warfactoryBuilt = true; m_warfactoryCell = MapUtil::GlobalCoordToCellCoord(i->GetObjectLocation()); } else if (std::dynamic_pointer_cast(i) && !b_orerefineryBuilt) { m_orerefineryTargetCell = MapUtil::GlobalCoordToCellCoord( - std::dynamic_pointer_cast(i)->GetWayPointLocation()); + std::dynamic_pointer_cast(i)->GetWayPointLocation()); b_orerefineryBuilt = true; m_orerefineryCell = MapUtil::GlobalCoordToCellCoord(i->GetObjectLocation()); diff --git a/src/UI/UIScriptProcess.cpp b/src/UI/UIScriptProcess.cpp index d2a7ea5c..10e65f0d 100644 --- a/src/UI/UIScriptProcess.cpp +++ b/src/UI/UIScriptProcess.cpp @@ -23,7 +23,7 @@ float UIScriptProcess::GetCDLeft() { if (b_isBuildingInCoolDown) { std::chrono::duration elapsed = m_currentCountDownTime - m_buildStartTime; - return m_buildCoolDownTime - elapsed.count(); + return GetBuildCountDownTime() - elapsed.count(); } else { return -1.F; } @@ -49,38 +49,83 @@ std::string UIScriptProcess::GetFormattedCD() { } void UIScriptProcess::CountDown() { + double buildCoolDownTime = GetBuildCountDownTime(); + double spawnCoolDownTime = GetSpawnCountDownTime(); m_currentCountDownTime = std::chrono::high_resolution_clock::now(); - std::chrono::duration elapsed = - m_currentCountDownTime - m_buildStartTime; - std::chrono::duration unitElapsed = - m_currentCountDownTime - m_SpawnStartTime; + + //Structure Building + std::chrono::duration buildElapsed = m_currentCountDownTime - m_buildStartTime; + if(m_gameObjectManager->GetTotalCurrency()<=0 && b_isBuildingInCoolDown && buildElapsed.count() < buildCoolDownTime){ + if(m_gameObjectManager->GetTotalPower()<=0){ + SetBuildCountDown(buildCoolDownTime/2-buildElapsed.count()); + }else{ + SetBuildCountDown(buildCoolDownTime-buildElapsed.count()); + } + }else{ + if((b_isBuildingInCoolDown && buildElapsed.count()-m_lastBuildElapsed>=1)|| buildElapsed.count()==0){//update every second + m_lastBuildElapsed=buildElapsed.count(); + int buildCost= GetObjCost(m_currentStructureType)/buildCoolDownTime; + if(buildCost>=m_currentBuildRemainingCost){ + buildCost=m_currentBuildRemainingCost; + } + if(m_currentBuildRemainingCost>0){ + m_currentBuildRemainingCost-=buildCost; + m_player->addCurrency(-1*buildCost); + } + } + // if finish building + if (buildElapsed.count() >= buildCoolDownTime && b_isBuildingInCoolDown) { + // printf("(Button) Construction Finished\n"); + SetIfFinished(m_currentStructureType, true); + b_isBuildingInCoolDown = false; + } + } + + //Unit Spawning + std::chrono::duration spawnElapsed = m_currentCountDownTime - m_SpawnStartTime; + if(m_gameObjectManager->GetTotalCurrency()<=0 && b_isSpawningInCooldown && spawnElapsed.count() < spawnCoolDownTime){ + if(m_gameObjectManager->GetTotalPower()<=0){ + SetSpawnCountDown(spawnCoolDownTime/2-spawnElapsed.count()); + }else{ + SetSpawnCountDown(spawnCoolDownTime-spawnElapsed.count()); + } + }else{ + if((b_isSpawningInCooldown && spawnElapsed.count()-m_lastSpawnElapsed>=1) || spawnElapsed.count()==0){//update every second + m_lastSpawnElapsed=spawnElapsed.count(); + int spawnCost=GetObjCost(m_currentAvatarType)/spawnCoolDownTime; + if(spawnCost>=m_currentSpawnRemainingCost){ + spawnCost=m_currentSpawnRemainingCost; + } + if(m_currentSpawnRemainingCost>0){ + m_currentSpawnRemainingCost-=spawnCost; + m_player->addCurrency(-1*spawnCost); + } + } + //if finish spawning + if (spawnElapsed.count() >= spawnCoolDownTime && b_isSpawningInCooldown) { + b_isReadyToSpawn=true; + b_isSpawningInCooldown = false; + // printf("(UISC)Unit Ready\n"); + } + } + if (b_isBuildingInCoolDown) { // printf("(Button) CD: %.2f,%s\n", m_buildCoolDownTime - elapsed.count(), // elapsed.count() >= m_buildCoolDownTime ? "True" : "False"); } if (b_isSpawningInCooldown) { - printf("(UISC) CD: %.2f,%s\n", unitElapsed.count(), - elapsed.count() >= m_spawnCooldownTime ? "True" : "False"); - } - if (elapsed.count() >= m_buildCoolDownTime && b_isBuildingInCoolDown) { - // printf("(Button) Construction Finished\n"); - SetIfFinished(m_currentStructureType, true); - b_isBuildingInCoolDown = false; - return; - } - if (unitElapsed.count() >= m_spawnCooldownTime && b_isSpawningInCooldown) { - b_isReadyToSpawn=true; - b_isSpawningInCooldown = false; - printf("(UISC)Unit Ready\n"); - return; +// printf("(UISC) CD: %.2f,%s\n", unitElapsed.count(), +// elapsed.count() >= m_spawnCooldownTime ? "True" : "False"); } } -void UIScriptProcess::SetCountDown(float time) { +void UIScriptProcess::SetBuildCountDown(float time) { m_buildCoolDownTime = time; + m_offPowerBuildCoolDownTime = time*2; m_buildStartTime = std::chrono::high_resolution_clock::now(); } void UIScriptProcess::SetSpawnCountDown(float time) { - m_spawnCooldownTime = time; + m_spawnCoolDownTime = time; + m_offPowerSpawnCoolDownTime = time*2; m_SpawnStartTime = std::chrono::high_resolution_clock::now(); } @@ -99,13 +144,15 @@ void UIScriptProcess::Update(bool queueContinue) { m_currentStructureType = m_buildQueue.front(); m_buildQueue.pop_front(); b_isBuildingInCoolDown = true; - SetCountDown(GetStructureTime(m_currentStructureType)); + SetBuildCountDown(GetStructureTime(m_currentStructureType)); + m_currentBuildRemainingCost= GetObjCost(m_currentStructureType); } if (m_spawnQueue.size() !=0 && !b_isSpawningInCooldown) { m_currentAvatarType = m_spawnQueue.front(); m_spawnQueue.pop_front(); b_isSpawningInCooldown = true; SetSpawnCountDown(GetSpawnTime(m_currentAvatarType)); + m_currentSpawnRemainingCost=GetObjCost(m_currentAvatarType); } CountDown(); } @@ -153,7 +200,7 @@ void UIScriptProcess::SetIfFinished(unitType type, bool value) { } void UIScriptProcess::AddToSpawnQueue(unitType type){ - printf("(UISC)Add Spawn Queue\n"); +// printf("(UISC)Add Spawn Queue\n"); m_spawnQueue.push_back(type); return; @@ -167,10 +214,46 @@ float UIScriptProcess::GetSpawnTime(unitType type){ } std::shared_ptr UIScriptProcess::spawnAvatar(){ - printf("(UISC)spawnAvatar\n"); +// printf("(UISC)spawnAvatar\n"); switch (m_currentAvatarType) { case unitType::INFANTRY:{ return std::make_unique(); } } +} + +float UIScriptProcess::GetBuildCountDownTime(){ + if(m_gameObjectManager->GetTotalPower()<=0){ + return m_offPowerBuildCoolDownTime; + }else{ + return m_buildCoolDownTime; + } +} +float UIScriptProcess::GetSpawnCountDownTime(){ + if(m_gameObjectManager->GetTotalPower()<=0){ + return m_offPowerSpawnCoolDownTime; + }else{ + return m_spawnCoolDownTime; + } +} +int UIScriptProcess::GetObjCost(unitType type){ + switch (type) { + case unitType::BARRACKS: + return barracks->GetBuildingCost(); + case unitType::ORE_REF: + return oreRefinery->GetBuildingCost(); + case unitType::POWER_PLANT: + return powerPlant->GetBuildingCost(); + case unitType::WAR_FACT: + return warFactory->GetBuildingCost(); + case unitType::ADV_POWER_PLANT: + return advPowerPlant->GetBuildingCost(); + case unitType::INFANTRY: + return 100; + default: + // Handle the case when type doesn't match any of the options + // For example, you might throw an exception or set a default value + break; + } + } \ No newline at end of file