diff --git a/libs/s25main/figures/nofMiner.cpp b/libs/s25main/figures/nofMiner.cpp index 912619b58a..65836a8f4e 100644 --- a/libs/s25main/figures/nofMiner.cpp +++ b/libs/s25main/figures/nofMiner.cpp @@ -71,23 +71,32 @@ helpers::OptionalEnum nofMiner::ProduceWare() bool nofMiner::AreWaresAvailable() const { - return nofWorkman::AreWaresAvailable() && FindPointWithResource(GetRequiredResType()).isValid(); + return nofWorkman::AreWaresAvailable() + && (CanMineWithoutResource() || FindPointWithResource(GetRequiredResType()).isValid()); } bool nofMiner::StartWorking() { - MapPoint resPt = FindPointWithResource(GetRequiredResType()); - if(!resPt.isValid()) - return false; const GlobalGameSettings& settings = world->GetGGS(); - bool inexhaustibleRes = settings.isEnabled(AddonId::INEXHAUSTIBLE_MINES) - || (workplace->GetBuildingType() == BuildingType::GraniteMine - && settings.isEnabled(AddonId::INEXHAUSTIBLE_GRANITEMINES)); - if(!inexhaustibleRes) - world->ReduceResource(resPt); + const bool canMineWithoutResource = CanMineWithoutResource(); + const bool inexhaustibleRes = settings.isEnabled(AddonId::INEXHAUSTIBLE_MINES) || canMineWithoutResource; + if(!canMineWithoutResource) + { + MapPoint resPt = FindPointWithResource(GetRequiredResType()); + if(!resPt.isValid()) + return false; + if(!inexhaustibleRes) + world->ReduceResource(resPt); + } return nofWorkman::StartWorking(); } +bool nofMiner::CanMineWithoutResource() const +{ + return workplace->GetBuildingType() == BuildingType::GraniteMine + && world->GetGGS().isEnabled(AddonId::INEXHAUSTIBLE_GRANITEMINES); +} + ResourceType nofMiner::GetRequiredResType() const { switch(workplace->GetBuildingType()) diff --git a/libs/s25main/figures/nofMiner.h b/libs/s25main/figures/nofMiner.h index c3fdc810ad..d965a0fdcd 100644 --- a/libs/s25main/figures/nofMiner.h +++ b/libs/s25main/figures/nofMiner.h @@ -23,6 +23,7 @@ class nofMiner : public nofWorkman bool AreWaresAvailable() const override; bool StartWorking() override; ResourceType GetRequiredResType() const; + bool CanMineWithoutResource() const; public: nofMiner(MapPoint pos, unsigned char player, nobUsual* workplace); diff --git a/tests/s25Main/integration/testProduction.cpp b/tests/s25Main/integration/testProduction.cpp index 5ce05b76b4..75ad8525a3 100644 --- a/tests/s25Main/integration/testProduction.cpp +++ b/tests/s25Main/integration/testProduction.cpp @@ -102,4 +102,46 @@ BOOST_FIXTURE_TEST_CASE(MetalWorkerOrders, WorldWithGCExecution1P) RTTR_EXEC_TILL(1300, mw->is_working); } +BOOST_FIXTURE_TEST_CASE(GraniteMineWithoutResourcesNeedsAddon, WorldWithGCExecution1P) +{ + GoodsAndPeopleCounts inv; + inv[GoodType::Fish] = 10; + inv[GoodType::PickAxe] = 1; + inv[Job::Miner] = 1; + world.GetSpecObj(hqPos)->AddToInventory(inv, true); + + MapPoint minePos = hqPos + MapPoint(2, 0); + const auto* mine = static_cast( + BuildingFactory::CreateBuilding(world, BuildingType::GraniteMine, minePos, curPlayer, Nation::Romans)); + this->BuildRoad(world.GetNeighbour(minePos, Direction::SouthEast), false, + std::vector(2, Direction::West)); + + const Inventory& curInventory = world.GetPlayer(curPlayer).GetInventory(); + const unsigned initialStones = curInventory[GoodType::Stones]; + RTTR_EXEC_TILL(500, mine->HasWorker()); + RTTR_SKIP_GFS(2000); + + BOOST_TEST(curInventory[GoodType::Stones] == initialStones); +} + +BOOST_FIXTURE_TEST_CASE(InexhaustibleGraniteMineWorksWithoutResources, WorldWithGCExecution1P) +{ + ggs.setSelection(AddonId::INEXHAUSTIBLE_GRANITEMINES, 1); + + GoodsAndPeopleCounts inv; + inv[GoodType::Fish] = 10; + inv[GoodType::PickAxe] = 1; + inv[Job::Miner] = 1; + world.GetSpecObj(hqPos)->AddToInventory(inv, true); + + MapPoint minePos = hqPos + MapPoint(2, 0); + BuildingFactory::CreateBuilding(world, BuildingType::GraniteMine, minePos, curPlayer, Nation::Romans); + this->BuildRoad(world.GetNeighbour(minePos, Direction::SouthEast), false, + std::vector(2, Direction::West)); + + const Inventory& curInventory = world.GetPlayer(curPlayer).GetInventory(); + const unsigned initialStones = curInventory[GoodType::Stones]; + RTTR_EXEC_TILL(3000, curInventory[GoodType::Stones] > initialStones); +} + BOOST_AUTO_TEST_SUITE_END()