From 29bba1c82bc37f2c1dcd9ebf2fe52a81c65c85a4 Mon Sep 17 00:00:00 2001 From: Ayrton Denner Date: Sat, 11 May 2024 20:54:24 -0300 Subject: [PATCH 001/144] Refactoring vehiclemission and cityview --- game/state/city/vehiclemission.cpp | 47 +++++-------- game/ui/tileview/cityview.cpp | 104 ++++++++++++++--------------- 2 files changed, 68 insertions(+), 83 deletions(-) diff --git a/game/state/city/vehiclemission.cpp b/game/state/city/vehiclemission.cpp index ae9558d1c..977d3647d 100644 --- a/game/state/city/vehiclemission.cpp +++ b/game/state/city/vehiclemission.cpp @@ -1037,19 +1037,11 @@ Reachability VehicleTargetHelper::isReachableTargetGround(const Vehicle &v, Vec3 bool VehicleMission::takeOffCheck(GameState &state, Vehicle &v) { - if (!v.tileObject) - { - if (v.currentBuilding) - { - v.addMission(state, VehicleMission::takeOff(v)); - return true; - } - else - { - return false; - } - } - return false; + if (v.tileObject || !v.currentBuilding) + return false; + + v.addMission(state, VehicleMission::takeOff(v)); + return true; } bool VehicleMission::teleportCheck(GameState &state, Vehicle &v) @@ -1992,30 +1984,27 @@ void VehicleMission::start(GameState &state, Vehicle &v) } case MissionType::AttackBuilding: { - if (!targetBuilding) + if (!targetBuilding && !acquireTargetBuilding(state, v)) { - if (!acquireTargetBuilding(state, v)) - { - cancelled = true; - return; - } + cancelled = true; + return; } + if (takeOffCheck(state, v)) { return; } - else + + if (this->currentPlannedPath.empty()) { - if (this->currentPlannedPath.empty()) - { - std::uniform_int_distribution xPos(targetBuilding->bounds.p0.x - 5, - targetBuilding->bounds.p1.x + 5); - std::uniform_int_distribution yPos(targetBuilding->bounds.p0.y - 5, - targetBuilding->bounds.p1.y + 5); - setPathTo(state, v, v.getPreferredPosition(xPos(state.rng), yPos(state.rng)), - getDefaultIterationCount(v)); - } + std::uniform_int_distribution xPos(targetBuilding->bounds.p0.x - 5, + targetBuilding->bounds.p1.x + 5); + std::uniform_int_distribution yPos(targetBuilding->bounds.p0.y - 5, + targetBuilding->bounds.p1.y + 5); + setPathTo(state, v, v.getPreferredPosition(xPos(state.rng), yPos(state.rng)), + getDefaultIterationCount(v)); } + return; } case MissionType::Crash: diff --git a/game/ui/tileview/cityview.cpp b/game/ui/tileview/cityview.cpp index 67bd482b5..cfabd6061 100644 --- a/game/ui/tileview/cityview.cpp +++ b/game/ui/tileview/cityview.cpp @@ -3773,73 +3773,69 @@ bool CityView::handleMouseDown(Event *e) scenery = std::dynamic_pointer_cast(collision.obj)->getOwner(); building = scenery->building; - if (true) + + Vec3 t = scenery->currentPosition; + UString debug = ""; + debug += format("\nCLICKED %s SCENERY %s at %s BUILDING %s", + scenery->falling || scenery->willCollapse() ? "FALLING" : "OK", + scenery->type.id, t, building.id); + // debug += format("\n LOS BLOCK %d", battle.getLosBlockID(t.x, t.y, t.z)); + + debug += + format("\nHt [%d] Con [%d] Type [%d|%d|%d] Road [%d%d%d%d] Hill [%d%d%d%d] " + "Tube " + "[%d%d%d%d%d%d]", + scenery->type->height, scenery->type->constitution, + (int)scenery->type->tile_type, (int)scenery->type->road_type, + (int)scenery->type->walk_mode, (int)scenery->type->connection[0], + (int)scenery->type->connection[1], (int)scenery->type->connection[2], + (int)scenery->type->connection[3], (int)scenery->type->hill[0], + (int)scenery->type->hill[1], (int)scenery->type->hill[2], + (int)scenery->type->hill[3], (int)scenery->type->tube[0], + (int)scenery->type->tube[1], (int)scenery->type->tube[2], + (int)scenery->type->tube[3], (int)scenery->type->tube[4], + (int)scenery->type->tube[5]); + auto &map = *state->current_city->map; + for (auto &p : scenery->supportedBy) { - Vec3 t = scenery->currentPosition; - UString debug = ""; - debug += - format("\nCLICKED %s SCENERY %s at %s BUILDING %s", - scenery->falling || scenery->willCollapse() ? "FALLING" : "OK", - scenery->type.id, t, building.id); - // debug += format("\n LOS BLOCK %d", battle.getLosBlockID(t.x, t.y, t.z)); - - debug += format( - "\nHt [%d] Con [%d] Type [%d|%d|%d] Road [%d%d%d%d] Hill [%d%d%d%d] " - "Tube " - "[%d%d%d%d%d%d]", - scenery->type->height, scenery->type->constitution, - (int)scenery->type->tile_type, (int)scenery->type->road_type, - (int)scenery->type->walk_mode, (int)scenery->type->connection[0], - (int)scenery->type->connection[1], (int)scenery->type->connection[2], - (int)scenery->type->connection[3], (int)scenery->type->hill[0], - (int)scenery->type->hill[1], (int)scenery->type->hill[2], - (int)scenery->type->hill[3], (int)scenery->type->tube[0], - (int)scenery->type->tube[1], (int)scenery->type->tube[2], - (int)scenery->type->tube[3], (int)scenery->type->tube[4], - (int)scenery->type->tube[5]); - auto &map = *state->current_city->map; - for (auto &p : scenery->supportedBy) - { - debug += format("\nCan be supported by %s", p); - } - for (auto &p : scenery->supportedParts) - { - debug += format("\nSupports %s", p); - } - for (int x = t.x - 1; x <= t.x + 1; x++) + debug += format("\nCan be supported by %s", p); + } + for (auto &p : scenery->supportedParts) + { + debug += format("\nSupports %s", p); + } + for (int x = t.x - 1; x <= t.x + 1; x++) + { + for (int y = t.y - 1; y <= t.y + 1; y++) { - for (int y = t.y - 1; y <= t.y + 1; y++) + for (int z = t.z - 1; z <= t.z + 1; z++) { - for (int z = t.z - 1; z <= t.z + 1; z++) + if (x < 0 || x >= map.size.x || y < 0 || y >= map.size.y || z < 0 || + z >= map.size.z) { - if (x < 0 || x >= map.size.x || y < 0 || y >= map.size.y || - z < 0 || z >= map.size.z) - { - continue; - } - auto tile2 = map.getTile(x, y, z); - for (auto &o2 : tile2->ownedObjects) + continue; + } + auto tile2 = map.getTile(x, y, z); + for (auto &o2 : tile2->ownedObjects) + { + if (o2->getType() == TileObject::Type::Scenery) { - if (o2->getType() == TileObject::Type::Scenery) + auto mp2 = std::static_pointer_cast(o2) + ->getOwner(); + for (auto &p : mp2->supportedParts) { - auto mp2 = - std::static_pointer_cast(o2) - ->getOwner(); - for (auto &p : mp2->supportedParts) + if (p == t) { - if (p == t) - { - debug += format( - "\nActually supported by %s at %d %d %d", - mp2->type.id, x - t.x, y - t.y, z - t.z); - } + debug += + format("\nActually supported by %s at %d %d %d", + mp2->type.id, x - t.x, y - t.y, z - t.z); } } } } } - LogWarning("%s", debug); } + LogWarning("%s", debug); } if (modifierLAlt && modifierLCtrl && modifierLShift) From 84a791dcd7903cb0a526e23d5cf309b2ee0f26e3 Mon Sep 17 00:00:00 2001 From: Ayrton Denner Date: Wed, 15 May 2024 20:11:20 -0300 Subject: [PATCH 002/144] Added few log warnings --- game/state/battle/battle.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/game/state/battle/battle.cpp b/game/state/battle/battle.cpp index 08ac2d620..0ccfc5f5b 100644 --- a/game/state/battle/battle.cpp +++ b/game/state/battle/battle.cpp @@ -3148,6 +3148,7 @@ void Battle::exitBattle(GameState &state) if (!leftoverBioLoot.empty()) { // Bio loot is wasted if can't be loaded on player craft + LogWarning("Bio loot remaining"); } // Cargo loot remaining? @@ -3158,6 +3159,7 @@ void Battle::exitBattle(GameState &state) if (state.current_battle->mission_type == Battle::MissionType::UfoRecovery) { // Still can't do anything if we're recovering UFO + LogWarning("AllowBuildingLootDeposit and UfoRecovery mission type"); } else { From 210510082e6b32b45b4d541f9ef2be501329b1b5 Mon Sep 17 00:00:00 2001 From: Ayrton Denner Date: Wed, 15 May 2024 22:02:04 -0300 Subject: [PATCH 003/144] Check if defended base has alien storage --- game/state/battle/battle.cpp | 43 +++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/game/state/battle/battle.cpp b/game/state/battle/battle.cpp index 0ccfc5f5b..b831af864 100644 --- a/game/state/battle/battle.cpp +++ b/game/state/battle/battle.cpp @@ -14,6 +14,7 @@ #include "game/state/city/base.h" #include "game/state/city/building.h" #include "game/state/city/city.h" +#include "game/state/city/facility.h" #include "game/state/city/vehicle.h" #include "game/state/city/vehiclemission.h" #include "game/state/gameevent.h" @@ -2567,15 +2568,9 @@ void Battle::finishBattle(GameState &state) // Recharge all equipment auto payload = e->getPayloadType(); - if (payload) + if (payload && payload->recharge && e->ammo < payload->max_ammo) { - if (payload->recharge) - { - if (e->ammo < payload->max_ammo) - { - e->ammo = payload->max_ammo; - } - } + e->ammo = payload->max_ammo; } } } @@ -2689,14 +2684,40 @@ void Battle::finishBattle(GameState &state) // - give him alien remains if (state.current_battle->playerWon && !state.current_battle->winnerHasRetreated) { - bool playerHasBioStorage = state.current_battle->player_craft && - state.current_battle->player_craft->getMaxBio() > 0; + + // Check if mission is base defense, and defended base has alien containment facility to + // store live aliens from battle + auto playerHasBaseAlienStorage = false; + + if (state.current_battle->mission_type == Battle::MissionType::BaseDefense) + { + for (const auto &base : state.player_bases) + { + if (base.first != state.current_base.id) + continue; + + for (const auto &facility : base.second->facilities) + { + if (facility->type->capacityType == FacilityType::Capacity::Aliens) + { + playerHasBaseAlienStorage = true; + break; + } + } + } + } + + const auto playerHasCraftBioStorage = state.current_battle->player_craft && + state.current_battle->player_craft->getMaxBio() > 0; + + const auto playerHasAlienStorage = playerHasCraftBioStorage || playerHasBaseAlienStorage; + // Live alien loot for (auto &u : liveAliens) { if (u->agent->type->liveSpeciesItem) { - if (playerHasBioStorage) + if (playerHasAlienStorage) { state.current_battle->score.liveAlienCaptured += u->agent->type->liveSpeciesItem->score; From e61cdaebf62b59131275d7f233c4d0d288ae8d61 Mon Sep 17 00:00:00 2001 From: Ayrton Denner Date: Fri, 17 May 2024 22:13:16 -0300 Subject: [PATCH 004/144] Created functions to read base being defended --- game/state/battle/battle.cpp | 137 ++++++++++++++++++++++------------- game/state/battle/battle.h | 4 + 2 files changed, 89 insertions(+), 52 deletions(-) diff --git a/game/state/battle/battle.cpp b/game/state/battle/battle.cpp index b831af864..66974e680 100644 --- a/game/state/battle/battle.cpp +++ b/game/state/battle/battle.cpp @@ -46,6 +46,7 @@ #include #include #include +#include namespace OpenApoc { @@ -2684,28 +2685,7 @@ void Battle::finishBattle(GameState &state) // - give him alien remains if (state.current_battle->playerWon && !state.current_battle->winnerHasRetreated) { - - // Check if mission is base defense, and defended base has alien containment facility to - // store live aliens from battle - auto playerHasBaseAlienStorage = false; - - if (state.current_battle->mission_type == Battle::MissionType::BaseDefense) - { - for (const auto &base : state.player_bases) - { - if (base.first != state.current_base.id) - continue; - - for (const auto &facility : base.second->facilities) - { - if (facility->type->capacityType == FacilityType::Capacity::Aliens) - { - playerHasBaseAlienStorage = true; - break; - } - } - } - } + auto playerHasBaseAlienStorage = getIfPlayerHasBaseAlienStorage(state); const auto playerHasCraftBioStorage = state.current_battle->player_craft && state.current_battle->player_craft->getMaxBio() > 0; @@ -3131,8 +3111,9 @@ void Battle::exitBattle(GameState &state) // If player has vehicle with bio capacity then all bio loot goes to leftover loot // This is regardless of "enforce limits" which only makes us enforce it // on vehicles that have capacity in the first place - bool bioCarrierPresent = false; - bool cargoCarrierPresent = false; + auto cargoCarrierPresent = false; + auto bioCarrierPresent = false; + auto playerHasBaseAlienStorage = getIfPlayerHasBaseAlienStorage(state); for (auto &v : playerVehicles) { if (v->getMaxCargo() > 0) @@ -3143,6 +3124,10 @@ void Battle::exitBattle(GameState &state) { bioCarrierPresent = true; } + + // If both variables are true, there is no reason to keep going with this loop + if (cargoCarrierPresent && bioCarrierPresent) + break; } if (!cargoCarrierPresent) { @@ -3156,7 +3141,7 @@ void Battle::exitBattle(GameState &state) } state.current_battle->cargoLoot.clear(); } - if (!bioCarrierPresent) + if (!bioCarrierPresent && !playerHasBaseAlienStorage) { for (auto &e : state.current_battle->bioLoot) { @@ -3173,43 +3158,57 @@ void Battle::exitBattle(GameState &state) } // Cargo loot remaining? - if (leftoverCargoLoot.empty()) + if (leftoverCargoLoot.empty() && config().getBool("OpenApoc.NewFeature.AllowBuildingLootDeposit")) { - if (config().getBool("OpenApoc.NewFeature.AllowBuildingLootDeposit")) + if (state.current_battle->mission_type == Battle::MissionType::UfoRecovery) { - if (state.current_battle->mission_type == Battle::MissionType::UfoRecovery) + // Still can't do anything if we're recovering UFO + LogWarning("AllowBuildingLootDeposit and UfoRecovery mission type"); + } + else + { + // Deposit loot into building, call for pickup + StateRef location = {&state, state.current_battle->mission_location_id}; + auto homeBuilding = + playerVehicles.empty() ? nullptr : playerVehicles.front()->homeBuilding; + if (!homeBuilding) { - // Still can't do anything if we're recovering UFO - LogWarning("AllowBuildingLootDeposit and UfoRecovery mission type"); + homeBuilding = state.player_bases.begin()->second->building; } - else + + // Main loop only starts with leftoverCargoLoot.empty() + // This means that the following inner loop will NEVER be executed! + // TODO: check if this can be removed + for (auto &e : leftoverCargoLoot) { - // Deposit loot into building, call for pickup - StateRef location = {&state, state.current_battle->mission_location_id}; - auto homeBuilding = - playerVehicles.empty() ? nullptr : playerVehicles.front()->homeBuilding; - if (!homeBuilding) - { - homeBuilding = state.player_bases.begin()->second->building; - } - for (auto &e : leftoverCargoLoot) - { - int price = 0; - location->cargo.emplace_back(state, e.first, e.second, price, nullptr, - homeBuilding); - } - for (auto &e : leftoverVehicleLoot) - { - int price = 0; - location->cargo.emplace_back(state, e.first, e.second, price, nullptr, - homeBuilding); - } + int price = 0; + location->cargo.emplace_back(state, e.first, e.second, price, nullptr, + homeBuilding); + } + for (auto &e : leftoverVehicleLoot) + { + int price = 0; + location->cargo.emplace_back(state, e.first, e.second, price, nullptr, + homeBuilding); } } } + // Base defense missions don't check for vehicles + if (state.current_battle->mission_type == Battle::MissionType::BaseDefense) + { + auto defendedBase = getCurrentDefendedBase(state); + + for (auto& e : state.current_battle->bioLoot) + { + for (auto &facility : defendedBase.value()->facilities) + { + // TODO: insert alien into alien containment at base + } + } + } // Load cargo/bio into vehicles - if (!playerVehicles.empty()) + else if (!playerVehicles.empty()) { // Go through every vehicle loot position // Try to load into every vehicle until amount remaining is zero @@ -3504,6 +3503,40 @@ void Battle::exitBattle(GameState &state) state.cleanUpDeathNote(); } +std::optional> Battle::getCurrentDefendedBase(GameState &state) +{ + if (state.current_battle->mission_type != Battle::MissionType::BaseDefense) + return {}; + + for (const auto& base : state.player_bases) + { + if (base.first == state.current_base.id) + return base.second; + } + + return {}; +} + +bool Battle::getIfPlayerHasBaseAlienStorage(GameState &state) +{ + // Check if mission is base defense, and defended base has alien containment facility to store live aliens from battle + if (state.current_battle->mission_type != Battle::MissionType::BaseDefense) + return false; + + auto defendedBase = getCurrentDefendedBase(state); + + // If base not found + if (!defendedBase) + return false; + + for (const auto &facility : defendedBase.value()->facilities) + { + if (facility->type->capacityType == FacilityType::Capacity::Aliens) + return true; + } + + return false; +} void Battle::loadResources(GameState &state) { battle_map->loadTilesets(state); diff --git a/game/state/battle/battle.h b/game/state/battle/battle.h index 447d49663..33ada1b39 100644 --- a/game/state/battle/battle.h +++ b/game/state/battle/battle.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace OpenApoc { @@ -351,6 +352,9 @@ class Battle : public std::enable_shared_from_this bool approachOnly = false, bool ignoreStaticUnits = false, bool ignoreMovingUnits = true, bool ignoreAllUnits = false, float *cost = nullptr, float maxCost = 0.0f); + static bool getIfPlayerHasBaseAlienStorage(GameState &state); + static std::optional> getCurrentDefendedBase(GameState &state); + private: void loadResources(GameState &state); void unloadResources(GameState &state); From 0ba51d797b860e39faffedb9497da9760ac11546 Mon Sep 17 00:00:00 2001 From: Ayrton Denner Date: Fri, 17 May 2024 23:24:41 -0300 Subject: [PATCH 005/144] Added check for alien containment at battle exit --- game/state/battle/battle.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/game/state/battle/battle.cpp b/game/state/battle/battle.cpp index 66974e680..f1bfa6637 100644 --- a/game/state/battle/battle.cpp +++ b/game/state/battle/battle.cpp @@ -3203,6 +3203,9 @@ void Battle::exitBattle(GameState &state) { for (auto &facility : defendedBase.value()->facilities) { + if (facility->type->capacityType != FacilityType::Capacity::Aliens) + continue; + // TODO: insert alien into alien containment at base } } From a6d2e1f8e608e7de64578dbdd086f8c1694e2f34 Mon Sep 17 00:00:00 2001 From: Kurtsley <73447098+Kurtsley@users.noreply.github.com> Date: Sat, 18 May 2024 20:20:39 -0500 Subject: [PATCH 006/144] Add partial clip refilling in battlescape --- game/state/shared/aequipment.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/game/state/shared/aequipment.cpp b/game/state/shared/aequipment.cpp index d85869304..fe5b0b269 100644 --- a/game/state/shared/aequipment.cpp +++ b/game/state/shared/aequipment.cpp @@ -367,8 +367,8 @@ void AEquipment::loadAmmo(GameState &state, sp ammoItem) // Store the loaded ammo type for autoreload lastLoadedAmmoType = ammoItem->type; - // If this has ammo then swap - if (payloadType) + // If this has ammo, swap if clip can't be refilled + if (payloadType && (ammoItem->ammo + ammo > payloadType->max_ammo)) { auto ejectedType = payloadType; auto ejectedAmmo = ammo; @@ -380,7 +380,8 @@ void AEquipment::loadAmmo(GameState &state, sp ammoItem) else { payloadType = ammoItem->type; - ammo = ammoItem->ammo; + // Fill partial clip + ammo = ammoItem->ammo + ammo; // Spend ammo ammoItem->ammo = 0; // Remove item from battle/agent From 9399a20636f21688db8fe62ca6a9e5c4373bdcc6 Mon Sep 17 00:00:00 2001 From: Ayrton Denner Date: Sun, 19 May 2024 13:14:05 -0300 Subject: [PATCH 007/144] Fixed base.h reference, reordered vehicle check at exitBattle() --- game/state/battle/battle.cpp | 309 ++++++++++++++++++----------------- game/state/battle/battle.h | 3 +- 2 files changed, 159 insertions(+), 153 deletions(-) diff --git a/game/state/battle/battle.cpp b/game/state/battle/battle.cpp index f1bfa6637..7b2f57515 100644 --- a/game/state/battle/battle.cpp +++ b/game/state/battle/battle.cpp @@ -3199,7 +3199,7 @@ void Battle::exitBattle(GameState &state) { auto defendedBase = getCurrentDefendedBase(state); - for (auto& e : state.current_battle->bioLoot) + for (auto &e : state.current_battle->bioLoot) { for (auto &facility : defendedBase.value()->facilities) { @@ -3210,201 +3210,206 @@ void Battle::exitBattle(GameState &state) } } } - // Load cargo/bio into vehicles - else if (!playerVehicles.empty()) + else { - // Go through every vehicle loot position - // Try to load into every vehicle until amount remaining is zero - std::list> vehicleLootToRemove; - for (auto &e : vehicleLoot) + // Load cargo/bio into vehicles + if (!playerVehicles.empty()) { - for (auto &v : playerVehicles) + // Go through every vehicle loot position + // Try to load into every vehicle until amount remaining is zero + std::list> vehicleLootToRemove; + for (auto &e : vehicleLoot) { - if (v->getMaxCargo() == 0) + for (auto &v : playerVehicles) { - continue; + if (v->getMaxCargo() == 0) + { + continue; + } + if (e.second == 0) + { + continue; + } + int maxAmount = config().getBool("OpenApoc.NewFeature.EnforceCargoLimits") + ? std::min(e.second, (v->getMaxCargo() - v->getCargo()) / + e.first->store_space) + : e.second; + if (maxAmount > 0) + { + e.second -= maxAmount; + int price = 0; + v->cargo.emplace_back(state, e.first, maxAmount, price, nullptr, + v->homeBuilding); + returningVehicles.insert(v); + } } if (e.second == 0) { - continue; - } - int maxAmount = config().getBool("OpenApoc.NewFeature.EnforceCargoLimits") - ? std::min(e.second, (v->getMaxCargo() - v->getCargo()) / - e.first->store_space) - : e.second; - if (maxAmount > 0) - { - e.second -= maxAmount; - int price = 0; - v->cargo.emplace_back(state, e.first, maxAmount, price, nullptr, - v->homeBuilding); - returningVehicles.insert(v); + vehicleLootToRemove.push_back(e.first); } } - if (e.second == 0) + // Remove stored loot + for (auto &e : vehicleLootToRemove) { - vehicleLootToRemove.push_back(e.first); + vehicleLoot.erase(e); } - } - // Remove stored loot - for (auto &e : vehicleLootToRemove) - { - vehicleLoot.erase(e); - } - // Put remainder on first vehicle - for (auto &e : vehicleLoot) - { - for (auto &v : playerVehicles) + // Put remainder on first vehicle + for (auto &e : vehicleLoot) { - if (v->getMaxCargo() == 0) + for (auto &v : playerVehicles) { - continue; - } - int maxAmount = e.second; - if (maxAmount > 0) - { - e.second -= maxAmount; - int price = 0; - v->cargo.emplace_back(state, e.first, maxAmount, price, nullptr, - v->homeBuilding); - returningVehicles.insert(v); + if (v->getMaxCargo() == 0) + { + continue; + } + int maxAmount = e.second; + if (maxAmount > 0) + { + e.second -= maxAmount; + int price = 0; + v->cargo.emplace_back(state, e.first, maxAmount, price, nullptr, + v->homeBuilding); + returningVehicles.insert(v); + } } } - } - // Go through every loot position - // Try to load into every vehicle until amount remaining is zero - std::list> cargoLootToRemove; - for (auto &e : state.current_battle->cargoLoot) - { - for (auto &v : playerVehicles) + // Go through every loot position + // Try to load into every vehicle until amount remaining is zero + std::list> cargoLootToRemove; + for (auto &e : state.current_battle->cargoLoot) { - if (v->getMaxCargo() == 0) + for (auto &v : playerVehicles) { - continue; + if (v->getMaxCargo() == 0) + { + continue; + } + if (e.second == 0) + { + continue; + } + int divisor = + e.first->type == AEquipmentType::Type::Ammo ? e.first->max_ammo : 1; + int maxAmount = config().getBool("OpenApoc.NewFeature.EnforceCargoLimits") + ? std::min(e.second, (v->getMaxCargo() - v->getCargo()) / + e.first->store_space * divisor) + : e.second; + if (maxAmount > 0) + { + e.second -= maxAmount; + int price = 0; + v->cargo.emplace_back(state, e.first, maxAmount, price, nullptr, + v->homeBuilding); + returningVehicles.insert(v); + } } if (e.second == 0) { - continue; - } - int divisor = e.first->type == AEquipmentType::Type::Ammo ? e.first->max_ammo : 1; - int maxAmount = config().getBool("OpenApoc.NewFeature.EnforceCargoLimits") - ? std::min(e.second, (v->getMaxCargo() - v->getCargo()) / - e.first->store_space * divisor) - : e.second; - if (maxAmount > 0) - { - e.second -= maxAmount; - int price = 0; - v->cargo.emplace_back(state, e.first, maxAmount, price, nullptr, - v->homeBuilding); - returningVehicles.insert(v); + cargoLootToRemove.push_back(e.first); } } - if (e.second == 0) + // Remove stored loot + for (auto &e : cargoLootToRemove) { - cargoLootToRemove.push_back(e.first); + state.current_battle->cargoLoot.erase(e); } - } - // Remove stored loot - for (auto &e : cargoLootToRemove) - { - state.current_battle->cargoLoot.erase(e); - } - // Put remainder on first vehicle - for (auto &e : state.current_battle->cargoLoot) - { - for (auto &v : playerVehicles) + // Put remainder on first vehicle + for (auto &e : state.current_battle->cargoLoot) { - if (v->getMaxCargo() == 0) + for (auto &v : playerVehicles) { - continue; - } - int maxAmount = e.second; - if (maxAmount > 0) - { - e.second -= maxAmount; - int price = 0; - v->cargo.emplace_back(state, e.first, maxAmount, price, nullptr, - v->homeBuilding); - returningVehicles.insert(v); + if (v->getMaxCargo() == 0) + { + continue; + } + int maxAmount = e.second; + if (maxAmount > 0) + { + e.second -= maxAmount; + int price = 0; + v->cargo.emplace_back(state, e.first, maxAmount, price, nullptr, + v->homeBuilding); + returningVehicles.insert(v); + } } } - } - // Go through every bio loot position - // Try to load into every vehicle until amount remaining is zero - std::list> bioLootToRemove; - for (auto &e : state.current_battle->bioLoot) - { - for (auto &v : playerVehicles) + // Go through every bio loot position + // Try to load into every vehicle until amount remaining is zero + std::list> bioLootToRemove; + for (auto &e : state.current_battle->bioLoot) { - if (v->getMaxBio() == 0) + for (auto &v : playerVehicles) { - continue; + if (v->getMaxBio() == 0) + { + continue; + } + if (e.second == 0) + { + continue; + } + int divisor = + e.first->type == AEquipmentType::Type::Ammo ? e.first->max_ammo : 1; + int maxAmount = config().getBool("OpenApoc.NewFeature.EnforceCargoLimits") + ? std::min(e.second, (v->getMaxBio() - v->getBio()) / + e.first->store_space * divisor) + : e.second; + if (maxAmount > 0) + { + e.second -= maxAmount; + int price = 0; + v->cargo.emplace_back(state, e.first, maxAmount, price, nullptr, + v->homeBuilding); + returningVehicles.insert(v); + } } if (e.second == 0) { - continue; - } - int divisor = e.first->type == AEquipmentType::Type::Ammo ? e.first->max_ammo : 1; - int maxAmount = config().getBool("OpenApoc.NewFeature.EnforceCargoLimits") - ? std::min(e.second, (v->getMaxBio() - v->getBio()) / - e.first->store_space * divisor) - : e.second; - if (maxAmount > 0) - { - e.second -= maxAmount; - int price = 0; - v->cargo.emplace_back(state, e.first, maxAmount, price, nullptr, - v->homeBuilding); - returningVehicles.insert(v); + bioLootToRemove.push_back(e.first); } } - if (e.second == 0) + // Remove stored loot + for (auto &e : bioLootToRemove) { - bioLootToRemove.push_back(e.first); + state.current_battle->bioLoot.erase(e); } - } - // Remove stored loot - for (auto &e : bioLootToRemove) - { - state.current_battle->bioLoot.erase(e); - } - // Put remainder on first vehicle - for (auto &e : state.current_battle->bioLoot) - { - for (auto &v : playerVehicles) + // Put remainder on first vehicle + for (auto &e : state.current_battle->bioLoot) { - if (v->getMaxCargo() == 0) + for (auto &v : playerVehicles) { - continue; - } - int maxAmount = e.second; - if (maxAmount > 0) - { - e.second -= maxAmount; - int price = 0; - v->cargo.emplace_back(state, e.first, maxAmount, price, nullptr, - v->homeBuilding); - returningVehicles.insert(v); + if (v->getMaxCargo() == 0) + { + continue; + } + int maxAmount = e.second; + if (maxAmount > 0) + { + e.second -= maxAmount; + int price = 0; + v->cargo.emplace_back(state, e.first, maxAmount, price, nullptr, + v->homeBuilding); + returningVehicles.insert(v); + } } } } - } - // Give player vehicle a null cargo just so it comes back to base once - for (auto v : playerVehicles) - { - v->cargo.emplace_front( - state, StateRef(&state, state.agent_equipment.begin()->first), 0, 0, - nullptr, v->homeBuilding); - if (v->city.id == "CITYMAP_HUMAN") - { - v->setMission(state, VehicleMission::gotoBuilding(state, *v)); - v->addMission(state, VehicleMission::offerService(state, *v), true); - } - else + // Give player vehicle a null cargo just so it comes back to base once + for (auto v : playerVehicles) { - v->setMission(state, VehicleMission::gotoPortal(state, *v)); + v->cargo.emplace_front( + state, StateRef(&state, state.agent_equipment.begin()->first), 0, 0, + nullptr, v->homeBuilding); + if (v->city.id == "CITYMAP_HUMAN") + { + v->setMission(state, VehicleMission::gotoBuilding(state, *v)); + v->addMission(state, VehicleMission::offerService(state, *v), true); + } + else + { + v->setMission(state, VehicleMission::gotoPortal(state, *v)); + } } } diff --git a/game/state/battle/battle.h b/game/state/battle/battle.h index 33ada1b39..37547e84e 100644 --- a/game/state/battle/battle.h +++ b/game/state/battle/battle.h @@ -14,6 +14,7 @@ #include #include #include +#include namespace OpenApoc { @@ -352,8 +353,8 @@ class Battle : public std::enable_shared_from_this bool approachOnly = false, bool ignoreStaticUnits = false, bool ignoreMovingUnits = true, bool ignoreAllUnits = false, float *cost = nullptr, float maxCost = 0.0f); - static bool getIfPlayerHasBaseAlienStorage(GameState &state); static std::optional> getCurrentDefendedBase(GameState &state); + static bool getIfPlayerHasBaseAlienStorage(GameState &state); private: void loadResources(GameState &state); From 9eecb6d6d09939860a830570fe39292584cf9839 Mon Sep 17 00:00:00 2001 From: Ayrton Denner Date: Sun, 19 May 2024 14:14:34 -0300 Subject: [PATCH 008/144] Adding live aliens at base alien storage when exiting battle --- game/state/battle/battle.cpp | 28 +++++++++++----------------- game/state/battle/battle.h | 2 +- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/game/state/battle/battle.cpp b/game/state/battle/battle.cpp index 7b2f57515..433c69d8c 100644 --- a/game/state/battle/battle.cpp +++ b/game/state/battle/battle.cpp @@ -2685,7 +2685,7 @@ void Battle::finishBattle(GameState &state) // - give him alien remains if (state.current_battle->playerWon && !state.current_battle->winnerHasRetreated) { - auto playerHasBaseAlienStorage = getIfPlayerHasBaseAlienStorage(state); + auto playerHasBaseAlienStorage = isBaseDefenseWithAlienStorage(state); const auto playerHasCraftBioStorage = state.current_battle->player_craft && state.current_battle->player_craft->getMaxBio() > 0; @@ -3113,7 +3113,7 @@ void Battle::exitBattle(GameState &state) // on vehicles that have capacity in the first place auto cargoCarrierPresent = false; auto bioCarrierPresent = false; - auto playerHasBaseAlienStorage = getIfPlayerHasBaseAlienStorage(state); + auto playerHasBaseAlienStorage = isBaseDefenseWithAlienStorage(state); for (auto &v : playerVehicles) { if (v->getMaxCargo() > 0) @@ -3195,19 +3195,16 @@ void Battle::exitBattle(GameState &state) } // Base defense missions don't check for vehicles - if (state.current_battle->mission_type == Battle::MissionType::BaseDefense) + if (state.current_battle->mission_type == Battle::MissionType::BaseDefense && isBaseDefenseWithAlienStorage(state)) { auto defendedBase = getCurrentDefendedBase(state); - for (auto &e : state.current_battle->bioLoot) + for (auto &bio : state.current_battle->bioLoot) { - for (auto &facility : defendedBase.value()->facilities) - { - if (facility->type->capacityType != FacilityType::Capacity::Aliens) - continue; + if (bio.second == 0) + continue; - // TODO: insert alien into alien containment at base - } + defendedBase.value()->inventoryBioEquipment[bio.first.id] += bio.second; } } else @@ -3525,7 +3522,7 @@ std::optional> Battle::getCurrentDefendedBase(GameState &state) return {}; } -bool Battle::getIfPlayerHasBaseAlienStorage(GameState &state) +bool Battle::isBaseDefenseWithAlienStorage(GameState &state) { // Check if mission is base defense, and defended base has alien containment facility to store live aliens from battle if (state.current_battle->mission_type != Battle::MissionType::BaseDefense) @@ -3537,13 +3534,10 @@ bool Battle::getIfPlayerHasBaseAlienStorage(GameState &state) if (!defendedBase) return false; - for (const auto &facility : defendedBase.value()->facilities) - { - if (facility->type->capacityType == FacilityType::Capacity::Aliens) - return true; - } + auto availableAlienStorageAtBase = + defendedBase.value()->getCapacityTotal(FacilityType::Capacity::Aliens) > 0; - return false; + return availableAlienStorageAtBase; } void Battle::loadResources(GameState &state) { diff --git a/game/state/battle/battle.h b/game/state/battle/battle.h index 37547e84e..4898de331 100644 --- a/game/state/battle/battle.h +++ b/game/state/battle/battle.h @@ -354,7 +354,7 @@ class Battle : public std::enable_shared_from_this bool ignoreAllUnits = false, float *cost = nullptr, float maxCost = 0.0f); static std::optional> getCurrentDefendedBase(GameState &state); - static bool getIfPlayerHasBaseAlienStorage(GameState &state); + static bool isBaseDefenseWithAlienStorage(GameState &state); private: void loadResources(GameState &state); From 6e47ceff142f91a3d26f9a5a2ae2a76c7039684a Mon Sep 17 00:00:00 2001 From: Ayrton Denner Date: Sun, 19 May 2024 14:28:29 -0300 Subject: [PATCH 009/144] Removing optional from getCurrentDefendedBase return --- game/state/battle/battle.cpp | 26 ++++++++++++++------------ game/state/battle/battle.h | 5 ++--- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/game/state/battle/battle.cpp b/game/state/battle/battle.cpp index 433c69d8c..cbf9ab6d9 100644 --- a/game/state/battle/battle.cpp +++ b/game/state/battle/battle.cpp @@ -46,7 +46,6 @@ #include #include #include -#include namespace OpenApoc { @@ -3158,7 +3157,8 @@ void Battle::exitBattle(GameState &state) } // Cargo loot remaining? - if (leftoverCargoLoot.empty() && config().getBool("OpenApoc.NewFeature.AllowBuildingLootDeposit")) + if (leftoverCargoLoot.empty() && + config().getBool("OpenApoc.NewFeature.AllowBuildingLootDeposit")) { if (state.current_battle->mission_type == Battle::MissionType::UfoRecovery) { @@ -3170,7 +3170,7 @@ void Battle::exitBattle(GameState &state) // Deposit loot into building, call for pickup StateRef location = {&state, state.current_battle->mission_location_id}; auto homeBuilding = - playerVehicles.empty() ? nullptr : playerVehicles.front()->homeBuilding; + playerVehicles.empty() ? nullptr : playerVehicles.front()->homeBuilding; if (!homeBuilding) { homeBuilding = state.player_bases.begin()->second->building; @@ -3179,23 +3179,24 @@ void Battle::exitBattle(GameState &state) // Main loop only starts with leftoverCargoLoot.empty() // This means that the following inner loop will NEVER be executed! // TODO: check if this can be removed - for (auto &e : leftoverCargoLoot) + for (auto &e : leftoverCargoLoot) { int price = 0; location->cargo.emplace_back(state, e.first, e.second, price, nullptr, - homeBuilding); + homeBuilding); } for (auto &e : leftoverVehicleLoot) { int price = 0; location->cargo.emplace_back(state, e.first, e.second, price, nullptr, - homeBuilding); + homeBuilding); } } } // Base defense missions don't check for vehicles - if (state.current_battle->mission_type == Battle::MissionType::BaseDefense && isBaseDefenseWithAlienStorage(state)) + if (state.current_battle->mission_type == Battle::MissionType::BaseDefense && + isBaseDefenseWithAlienStorage(state)) { auto defendedBase = getCurrentDefendedBase(state); @@ -3204,7 +3205,7 @@ void Battle::exitBattle(GameState &state) if (bio.second == 0) continue; - defendedBase.value()->inventoryBioEquipment[bio.first.id] += bio.second; + defendedBase->inventoryBioEquipment[bio.first.id] += bio.second; } } else @@ -3508,12 +3509,12 @@ void Battle::exitBattle(GameState &state) state.cleanUpDeathNote(); } -std::optional> Battle::getCurrentDefendedBase(GameState &state) +sp Battle::getCurrentDefendedBase(GameState &state) { if (state.current_battle->mission_type != Battle::MissionType::BaseDefense) return {}; - for (const auto& base : state.player_bases) + for (const auto &base : state.player_bases) { if (base.first == state.current_base.id) return base.second; @@ -3524,7 +3525,8 @@ std::optional> Battle::getCurrentDefendedBase(GameState &state) bool Battle::isBaseDefenseWithAlienStorage(GameState &state) { - // Check if mission is base defense, and defended base has alien containment facility to store live aliens from battle + // Check if mission is base defense, and defended base has alien containment facility to store + // live aliens from battle if (state.current_battle->mission_type != Battle::MissionType::BaseDefense) return false; @@ -3535,7 +3537,7 @@ bool Battle::isBaseDefenseWithAlienStorage(GameState &state) return false; auto availableAlienStorageAtBase = - defendedBase.value()->getCapacityTotal(FacilityType::Capacity::Aliens) > 0; + defendedBase->getCapacityTotal(FacilityType::Capacity::Aliens) > 0; return availableAlienStorageAtBase; } diff --git a/game/state/battle/battle.h b/game/state/battle/battle.h index 4898de331..1a871b569 100644 --- a/game/state/battle/battle.h +++ b/game/state/battle/battle.h @@ -9,12 +9,11 @@ #include "game/state/stateobject.h" #include "library/sp.h" #include "library/vec.h" +#include #include #include #include #include -#include -#include namespace OpenApoc { @@ -353,7 +352,7 @@ class Battle : public std::enable_shared_from_this bool approachOnly = false, bool ignoreStaticUnits = false, bool ignoreMovingUnits = true, bool ignoreAllUnits = false, float *cost = nullptr, float maxCost = 0.0f); - static std::optional> getCurrentDefendedBase(GameState &state); + static sp getCurrentDefendedBase(GameState &state); static bool isBaseDefenseWithAlienStorage(GameState &state); private: From 06905e828765cbc0d65864825fea899008f9440f Mon Sep 17 00:00:00 2001 From: Ayrton Denner Date: Sun, 19 May 2024 14:36:38 -0300 Subject: [PATCH 010/144] Added const modifiers --- game/state/battle/battle.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/game/state/battle/battle.cpp b/game/state/battle/battle.cpp index cbf9ab6d9..fac07993c 100644 --- a/game/state/battle/battle.cpp +++ b/game/state/battle/battle.cpp @@ -2684,7 +2684,7 @@ void Battle::finishBattle(GameState &state) // - give him alien remains if (state.current_battle->playerWon && !state.current_battle->winnerHasRetreated) { - auto playerHasBaseAlienStorage = isBaseDefenseWithAlienStorage(state); + const auto playerHasBaseAlienStorage = isBaseDefenseWithAlienStorage(state); const auto playerHasCraftBioStorage = state.current_battle->player_craft && state.current_battle->player_craft->getMaxBio() > 0; @@ -3112,7 +3112,7 @@ void Battle::exitBattle(GameState &state) // on vehicles that have capacity in the first place auto cargoCarrierPresent = false; auto bioCarrierPresent = false; - auto playerHasBaseAlienStorage = isBaseDefenseWithAlienStorage(state); + const auto playerHasBaseAlienStorage = isBaseDefenseWithAlienStorage(state); for (auto &v : playerVehicles) { if (v->getMaxCargo() > 0) @@ -3198,7 +3198,7 @@ void Battle::exitBattle(GameState &state) if (state.current_battle->mission_type == Battle::MissionType::BaseDefense && isBaseDefenseWithAlienStorage(state)) { - auto defendedBase = getCurrentDefendedBase(state); + const auto defendedBase = getCurrentDefendedBase(state); for (auto &bio : state.current_battle->bioLoot) { @@ -3394,7 +3394,7 @@ void Battle::exitBattle(GameState &state) } // Give player vehicle a null cargo just so it comes back to base once - for (auto v : playerVehicles) + for (auto &v : playerVehicles) { v->cargo.emplace_front( state, StateRef(&state, state.agent_equipment.begin()->first), 0, 0, @@ -3530,13 +3530,13 @@ bool Battle::isBaseDefenseWithAlienStorage(GameState &state) if (state.current_battle->mission_type != Battle::MissionType::BaseDefense) return false; - auto defendedBase = getCurrentDefendedBase(state); + const auto defendedBase = getCurrentDefendedBase(state); // If base not found if (!defendedBase) return false; - auto availableAlienStorageAtBase = + const auto availableAlienStorageAtBase = defendedBase->getCapacityTotal(FacilityType::Capacity::Aliens) > 0; return availableAlienStorageAtBase; From c0f44d625bf7fe06473f2c1e4789297725da0bc1 Mon Sep 17 00:00:00 2001 From: Ayrton Denner Date: Sun, 19 May 2024 15:23:28 -0300 Subject: [PATCH 011/144] Added missing const at loop --- game/state/battle/battle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game/state/battle/battle.cpp b/game/state/battle/battle.cpp index fac07993c..1fcdf1a51 100644 --- a/game/state/battle/battle.cpp +++ b/game/state/battle/battle.cpp @@ -3200,7 +3200,7 @@ void Battle::exitBattle(GameState &state) { const auto defendedBase = getCurrentDefendedBase(state); - for (auto &bio : state.current_battle->bioLoot) + for (const auto &bio : state.current_battle->bioLoot) { if (bio.second == 0) continue; From 3fff8f05142ea4180fb54e80c6e601e8a2460cd2 Mon Sep 17 00:00:00 2001 From: Ayrton Denner Date: Mon, 20 May 2024 20:12:22 -0300 Subject: [PATCH 012/144] Showing UFO names only after research, added const modifiers, fixed debug mode typo --- data/forms/city/debugoverlay_city.form | 2 +- game/ui/tileview/cityview.cpp | 135 +++++++++++++------------ 2 files changed, 72 insertions(+), 65 deletions(-) diff --git a/data/forms/city/debugoverlay_city.form b/data/forms/city/debugoverlay_city.form index 601b6d2ea..cc5ec97ca 100644 --- a/data/forms/city/debugoverlay_city.form +++ b/data/forms/city/debugoverlay_city.form @@ -47,7 +47,7 @@ smalfont -