Skip to content

Commit

Permalink
Ability to define the item needed for research
Browse files Browse the repository at this point in the history
  • Loading branch information
MeridianOXC committed Dec 29, 2023
1 parent 8c42920 commit bfaf3ee
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/Basescape/GlobalAlienContainmentState.cpp
Expand Up @@ -170,7 +170,7 @@ void GlobalAlienContainmentState::fillPrisonerList()
for (const auto* proj : xbase->getResearch())
{
const RuleResearch* research = proj->getRules();
RuleItem* item = _game->getMod()->getItem(research->getName());
const RuleItem* item = _game->getMod()->getItem(research->getName()); // don't use getNeededItem()
if (research->needItem() && research->destroyItem() && item && item->isAlien() && item->getPrisonType() == prisonType)
{
researchList.push_back(research->getName());
Expand Down
2 changes: 1 addition & 1 deletion src/Basescape/ManageAlienContainmentState.cpp
Expand Up @@ -214,7 +214,7 @@ void ManageAlienContainmentState::resetListAndTotals()
for (const auto* proj : _base->getResearch())
{
const RuleResearch *research = proj->getRules();
RuleItem *item = _game->getMod()->getItem(research->getName());
const RuleItem *item = _game->getMod()->getItem(research->getName()); // don't use getNeededItem()
if (research->needItem() && research->destroyItem() && item && item->isAlien() && item->getPrisonType() == _prisonType)
{
researchList.push_back(research->getName());
Expand Down
2 changes: 1 addition & 1 deletion src/Basescape/ResearchInfoState.cpp
Expand Up @@ -130,7 +130,7 @@ void ResearchInfoState::buildUi()
_base->addResearch(_project);
if (_rule->needItem() && _rule->destroyItem())
{
_base->getStorageItems()->removeItem(_rule->getName(), 1);
_base->getStorageItems()->removeItem(_rule->getNeededItem(), 1);
}
}
setAssignedScientist();
Expand Down
5 changes: 3 additions & 2 deletions src/Basescape/StoresState.cpp
Expand Up @@ -309,9 +309,10 @@ void StoresState::initList(bool grandTotal)
// 4. items/aliens in research
for (const auto* research : xbase->getResearch())
{
if (research->getRules()->needItem() && research->getRules()->getName() == itemType)
const auto* rrule = research->getRules();
if (rrule->needItem() && rrule->destroyItem())
{
if (research->getRules()->destroyItem())
if (rrule->getNeededItem() && rrule->getNeededItem()->getType() == itemType)
{
qty += 1;
break;
Expand Down
23 changes: 17 additions & 6 deletions src/Basescape/TechTreeViewerState.cpp
Expand Up @@ -537,12 +537,23 @@ void TechTreeViewerState::initLists()
_leftTopics.push_back("-");
_leftFlags.push_back(TTV_NONE);
++row;
std::string itemName = tr(_selectedTopic);
itemName.insert(0, " ");
_lstLeft->addRow(1, itemName.c_str());
_lstLeft->setRowColor(row, getResearchColor(_selectedTopic));
_leftTopics.push_back(_selectedTopic);
_leftFlags.push_back(TTV_ITEMS);
if (rule->getNeededItem())
{
std::string itemName = tr(rule->getNeededItem()->getType());
itemName.insert(0, " ");
_lstLeft->addRow(1, itemName.c_str());
_lstLeft->setRowColor(row, _white);
_leftTopics.push_back(rule->getNeededItem()->getType());
_leftFlags.push_back(TTV_ITEMS);
}
else
{
std::string itemName = " -";
_lstLeft->addRow(1, itemName.c_str());
_lstLeft->setRowColor(row, _white);
_leftTopics.push_back("-");
_leftFlags.push_back(TTV_NONE);
}
++row;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Geoscape/GeoscapeState.cpp
Expand Up @@ -2382,7 +2382,7 @@ void GeoscapeState::time1Day()
// 3b. handle interrogation
if (Options::retainCorpses && research->needItem() && research->destroyItem())
{
auto* ruleUnit = mod->getUnit(research->getName(), false);
auto* ruleUnit = mod->getUnit(research->getName(), false); // don't use getNeededItem()
if (ruleUnit)
{
auto* ruleCorpse = ruleUnit->getArmor()->getCorpseGeoscape();
Expand Down
16 changes: 16 additions & 0 deletions src/Mod/RuleResearch.cpp
Expand Up @@ -60,6 +60,7 @@ void RuleResearch::load(const YAML::Node &node, Mod* mod, const ModScript& parse
mod->loadBaseFunction(_name, _requiresBaseFunc, node["requiresBaseFunc"]);
_sequentialGetOneFree = node["sequentialGetOneFree"].as<bool>(_sequentialGetOneFree);
mod->loadNamesToNames(_name, _getOneFreeProtectedName, node["getOneFreeProtected"]);
mod->loadNameNull(_name, _neededItemName, node["neededItem"]);
_needItem = node["needItem"].as<bool>(_needItem);
_destroyItem = node["destroyItem"].as<bool>(_destroyItem);
_unlockFinalMission = node["unlockFinalMission"].as<bool>(_unlockFinalMission);
Expand All @@ -82,6 +83,21 @@ void RuleResearch::afterLoad(const Mod* mod)
_lookup = "";
}

if (_needItem)
{
// FIXME: this would break all mods unfortunately, maybe one day...
//mod->linkRule(_neededItem, _neededItemName.empty() ? _name : _neededItemName);

if (_neededItemName.empty())
{
_neededItem = mod->getItem(_name, false); // false, because even vanilla ruleset is a mess
}
else
{
_neededItem = mod->getItem(_neededItemName, true);
}
}

_dependencies = mod->getResearch(_dependenciesName);
_unlocks = mod->getResearch(_unlocksName);
_disables = mod->getResearch(_disablesName);
Expand Down
4 changes: 4 additions & 0 deletions src/Mod/RuleResearch.h
Expand Up @@ -54,6 +54,8 @@ class RuleResearch
bool _sequentialGetOneFree;
std::vector<std::pair<std::string, std::vector<std::string> > > _getOneFreeProtectedName;
std::vector<std::pair<const RuleResearch*, std::vector<const RuleResearch*> > > _getOneFreeProtected;
std::string _neededItemName;
const RuleItem* _neededItem = nullptr;
bool _needItem, _destroyItem, _unlockFinalMission;
int _listOrder;

Expand Down Expand Up @@ -82,6 +84,8 @@ class RuleResearch
const std::vector<const RuleResearch*> &getDependencies() const;
/// Checks if this ResearchProject gives free topics in sequential order (or random order).
bool sequentialGetOneFree() const;
/// Gets the Item needed for this research.
const RuleItem* getNeededItem() const { return _neededItem; }
/// Checks if this ResearchProject needs a corresponding Item to be researched.
bool needItem() const;
/// Checks if this ResearchProject consumes the corresponding Item when research completes.
Expand Down
8 changes: 4 additions & 4 deletions src/Savegame/Base.cpp
Expand Up @@ -1301,7 +1301,7 @@ void Base::removeResearch(ResearchProject * project)
{
if (ruleResearch->needItem() && ruleResearch->destroyItem())
{
getStorageItems()->addItem(ruleResearch->getName(), 1);
getStorageItems()->addItem(ruleResearch->getNeededItem(), 1);
}
}

Expand Down Expand Up @@ -1455,7 +1455,7 @@ int Base::getUsedContainment(int prisonType, bool onlyExternal) const
const RuleResearch *projRules = proj->getRules();
if (projRules->needItem() && projRules->destroyItem())
{
rule = _mod->getItem(projRules->getName());
rule = _mod->getItem(projRules->getName()); // don't use getNeededItem()
if (rule->isAlien() && rule->getPrisonType() == prisonType)
{
++total;
Expand Down Expand Up @@ -2060,12 +2060,12 @@ void Base::cleanupPrisons(int prisonType)
const RuleResearch* projRules = project->getRules();
if (projRules->needItem() && projRules->destroyItem())
{
RuleItem* rule = _mod->getItem(projRules->getName());
RuleItem* rule = _mod->getItem(projRules->getName()); // don't use getNeededItem()
if (rule->isAlien() && rule->getPrisonType() == prisonType)
{
_scientists += project->getAssigned();
project->setAssigned(0);
getStorageItems()->addItem(projRules->getName(), 1);
getStorageItems()->addItem(projRules->getNeededItem(), 1);
return true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Savegame/SavedGame.cpp
Expand Up @@ -1840,7 +1840,7 @@ void SavedGame::getAvailableResearchProjects(std::vector<RuleResearch *> &projec
}

// Check for needed item in the given base
if (research->needItem() && base->getStorageItems()->getItem(research->getName()) == 0)
if (research->needItem() && base->getStorageItems()->getItem(research->getNeededItem()) == 0)
{
continue;
}
Expand Down

0 comments on commit bfaf3ee

Please sign in to comment.