Skip to content

Commit

Permalink
Regions and countries providing "base services"
Browse files Browse the repository at this point in the history
  • Loading branch information
MeridianOXC committed Dec 30, 2023
1 parent 52cb7f7 commit 98ce77c
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/Geoscape/BuildNewBaseState.cpp
Expand Up @@ -250,6 +250,7 @@ void BuildNewBaseState::globeClick(Action *action)
_base->setFakeUnderwater(fakeUnderwaterTexture);
_base->setLongitude(lon);
_base->setLatitude(lat);
_base->calculateServices(_game->getSavedGame());
for (auto* craft : *_base->getCrafts())
{
craft->setLongitude(lon);
Expand Down
3 changes: 3 additions & 0 deletions src/Menu/NewGameState.cpp
Expand Up @@ -179,6 +179,9 @@ void NewGameState::btnOkClick(Action *)
auto* base = _game->getSavedGame()->getBases()->back();
if (base->getMarker() != -1)
{
// location known already
base->calculateServices(save);

// center and rotate 35 degrees down (to see the base location while typoing its name)
gs->getGlobe()->center(base->getLongitude(), base->getLatitude() + 0.61);

Expand Down
6 changes: 3 additions & 3 deletions src/Mod/Mod.cpp
Expand Up @@ -2698,23 +2698,23 @@ void Mod::loadFile(const FileMap::FileRecord &filerec, ModScript &parsers)
RuleCountry *rule = loadRule(*i, &_countries, &_countriesIndex);
if (rule != 0)
{
rule->load(*i, parsers);
rule->load(*i, parsers, this);
}
}
for (YAML::const_iterator i : iterateRules("extraGlobeLabels", "type"))
{
RuleCountry *rule = loadRule(*i, &_extraGlobeLabels, &_extraGlobeLabelsIndex);
if (rule != 0)
{
rule->load(*i, parsers);
rule->load(*i, parsers, this);
}
}
for (YAML::const_iterator i : iterateRules("regions", "type"))
{
RuleRegion *rule = loadRule(*i, &_regions, &_regionsIndex);
if (rule != 0)
{
rule->load(*i);
rule->load(*i, this);
}
}
for (YAML::const_iterator i : iterateRules("facilities", "type"))
Expand Down
7 changes: 5 additions & 2 deletions src/Mod/RuleCountry.cpp
Expand Up @@ -45,11 +45,11 @@ RuleCountry::~RuleCountry()
* Loads the country type from a YAML file.
* @param node YAML node.
*/
void RuleCountry::load(const YAML::Node &node, const ModScript& parsers)
void RuleCountry::load(const YAML::Node &node, const ModScript& parsers, Mod* mod)
{
if (const YAML::Node &parent = node["refNode"])
{
load(parent, parsers);
load(parent, parsers, mod);
}

_signedPactEventName = node["signedPactEvent"].as<std::string>(_signedPactEventName);
Expand All @@ -75,6 +75,9 @@ void RuleCountry::load(const YAML::Node &node, const ModScript& parsers)
std::swap(_latMin.back(), _latMax.back());
}

mod->loadBaseFunction(_type, _provideBaseFunc, node["provideBaseFunc"]);
mod->loadBaseFunction(_type, _forbiddenBaseFunc, node["forbiddenBaseFunc"]);

_countryScripts.load(_type, node, parsers.countryScripts);
_scriptValues.load(node, parsers.getShared());
}
Expand Down
9 changes: 8 additions & 1 deletion src/Mod/RuleCountry.h
Expand Up @@ -21,6 +21,7 @@
#include <yaml-cpp/yaml.h>
#include "RuleEvent.h"
#include "ModScript.h"
#include "RuleBaseFacilityFunctions.h"

namespace OpenXcom
{
Expand All @@ -43,6 +44,8 @@ class RuleCountry
int _labelColor, _zoomLevel;
const RuleEvent* _signedPactEvent = nullptr;
const RuleEvent* _rejoinedXcomEvent = nullptr;
RuleBaseFacilityFunctions _provideBaseFunc = 0;
RuleBaseFacilityFunctions _forbiddenBaseFunc = 0;

ModScript::CountryScripts::Container _countryScripts;
ScriptValues<RuleCountry> _scriptValues;
Expand All @@ -57,7 +60,7 @@ class RuleCountry
/// Cleans up the country ruleset.
~RuleCountry();
/// Loads the country from YAML.
void load(const YAML::Node& node, const ModScript& parsers);
void load(const YAML::Node& node, const ModScript& parsers, Mod* mod);
/// Cross link with other rules.
void afterLoad(const Mod* mod);
/// Gets the country's type.
Expand All @@ -84,6 +87,10 @@ class RuleCountry
int getLabelColor() const;
/// Gets the minimum zoom level required to display the label (Note: works for extraGlobeLabels only, not for vanilla countries).
int getZoomLevel() const;
/// Gets the functions provided by the country.
RuleBaseFacilityFunctions getProvidedBaseFunc() const { return _provideBaseFunc; }
/// Gets the functions forbidden by the coutry.
RuleBaseFacilityFunctions getForbiddenBaseFunc() const { return _forbiddenBaseFunc; }

/// Gets script.
template<typename Script>
Expand Down
8 changes: 6 additions & 2 deletions src/Mod/RuleRegion.cpp
Expand Up @@ -18,6 +18,7 @@
*/
#include <assert.h>
#include "RuleRegion.h"
#include "Mod.h"
#include "City.h"
#include "../Engine/Logger.h"
#include "../Engine/RNG.h"
Expand Down Expand Up @@ -48,11 +49,11 @@ RuleRegion::~RuleRegion()
* Loads the region type from a YAML file.
* @param node YAML node.
*/
void RuleRegion::load(const YAML::Node &node)
void RuleRegion::load(const YAML::Node &node, Mod* mod)
{
if (const YAML::Node &parent = node["refNode"])
{
load(parent);
load(parent, mod);
}

_cost = node["cost"].as<int>(_cost);
Expand Down Expand Up @@ -113,6 +114,9 @@ void RuleRegion::load(const YAML::Node &node)
}
_regionWeight = node["regionWeight"].as<size_t>(_regionWeight);
_missionRegion = node["missionRegion"].as<std::string>(_missionRegion);

mod->loadBaseFunction(_type, _provideBaseFunc, node["provideBaseFunc"]);
mod->loadBaseFunction(_type, _forbiddenBaseFunc, node["forbiddenBaseFunc"]);
}

/**
Expand Down
11 changes: 10 additions & 1 deletion src/Mod/RuleRegion.h
Expand Up @@ -22,6 +22,7 @@
#include <yaml-cpp/yaml.h>
#include "../fmath.h"
#include "../Savegame/WeightedOptions.h"
#include "RuleBaseFacilityFunctions.h"

namespace OpenXcom
{
Expand Down Expand Up @@ -63,6 +64,8 @@ struct MissionZone
};

class City;
class Mod;


/**
* Represents a specific region of the world.
Expand All @@ -84,13 +87,15 @@ class RuleRegion
std::vector<MissionZone> _missionZones;
/// Do missions in the region defined by this string instead.
std::string _missionRegion;
RuleBaseFacilityFunctions _provideBaseFunc = 0;
RuleBaseFacilityFunctions _forbiddenBaseFunc = 0;
public:
/// Creates a blank region ruleset.
RuleRegion(const std::string &type);
/// Cleans up the region ruleset.
~RuleRegion();
/// Loads the region from YAML.
void load(const YAML::Node& node);
void load(const YAML::Node& node, Mod* mod);
/// Gets the region's type.
const std::string& getType() const;
/// Gets the region's base cost.
Expand All @@ -117,6 +122,10 @@ class RuleRegion
const std::vector<double> &getLatMin() const { return _latMin; }
/// Gets a list of MissionZones.
const std::vector<MissionZone> &getMissionZones() const;
/// Gets the functions provided by the region.
RuleBaseFacilityFunctions getProvidedBaseFunc() const { return _provideBaseFunc; }
/// Gets the functions forbidden by the region.
RuleBaseFacilityFunctions getForbiddenBaseFunc() const { return _forbiddenBaseFunc; }
};

}
Expand Down
36 changes: 36 additions & 0 deletions src/Savegame/Base.cpp
Expand Up @@ -47,6 +47,10 @@
#include "../Engine/Collections.h"
#include "WeightedOptions.h"
#include "AlienMission.h"
#include "Country.h"
#include "../Mod/RuleCountry.h"
#include "Region.h"
#include "../Mod/RuleRegion.h"

namespace OpenXcom
{
Expand Down Expand Up @@ -277,6 +281,32 @@ void Base::finishLoading(const YAML::Node &node, SavedGame *save)
Log(LOG_ERROR) << "Failed to load craft " << type;
}
}
calculateServices(save);
}

/**
* Pre-calculates base services provided by region and country.
*/
void Base::calculateServices(SavedGame* save)
{
for (const auto* country : *save->getCountries())
{
if (country->getRules()->insideCountry(_lon, _lat))
{
_provideBaseFunc |= country->getRules()->getProvidedBaseFunc();
_forbiddenBaseFunc |= country->getRules()->getForbiddenBaseFunc();
break;
}
}
for (const auto* region : *save->getRegions())
{
if (region->getRules()->insideRegion(_lon, _lat))
{
_provideBaseFunc |= region->getRules()->getProvidedBaseFunc();
_forbiddenBaseFunc |= region->getRules()->getForbiddenBaseFunc();
break;
}
}
}

/**
Expand Down Expand Up @@ -2349,6 +2379,8 @@ RuleBaseFacilityFunctions Base::getProvidedBaseFunc(BaseAreaSubset skip) const
ret |= bf->getRules()->getProvidedBaseFunc();
}

ret |= _provideBaseFunc;

return ret;
}

Expand Down Expand Up @@ -2400,6 +2432,8 @@ RuleBaseFacilityFunctions Base::getForbiddenBaseFunc(BaseAreaSubset skip) const
ret |= bf->getRules()->getForbiddenBaseFunc();
}

ret |= _forbiddenBaseFunc;

return ret;
}

Expand All @@ -2420,6 +2454,8 @@ RuleBaseFacilityFunctions Base::getFutureBaseFunc(BaseAreaSubset skip) const
ret |= bf->getRules()->getProvidedBaseFunc();
}

ret |= _provideBaseFunc;

return ret;
}

Expand Down
3 changes: 3 additions & 0 deletions src/Savegame/Base.h
Expand Up @@ -109,6 +109,8 @@ class Base : public Target
std::vector<Vehicle*> _vehiclesFromBase;
std::vector<BaseFacility*> _defenses;
std::map<const RuleBaseFacility*, int> _destroyedFacilitiesCache;
RuleBaseFacilityFunctions _provideBaseFunc = 0;
RuleBaseFacilityFunctions _forbiddenBaseFunc = 0;

using Target::load;
public:
Expand All @@ -120,6 +122,7 @@ class Base : public Target
void load(const YAML::Node& node, SavedGame *save, bool newGame, bool newBattleGame = false);
/// Finishes loading the base (more specifically all craft in the base) from YAML.
void finishLoading(const YAML::Node& node, SavedGame *save);
void calculateServices(SavedGame* save);
/// Tests whether the base facilities are within the base boundaries and not overlapping.
bool isOverlappingOrOverflowing();
/// Saves the base to YAML.
Expand Down

0 comments on commit 98ce77c

Please sign in to comment.