my question then is: when la ruleset is loaded, ¿this new unlocks override the other unlocks, or is added to the others?
- name: STR_SECTOPOD_CONSTRUCTION
cost: 600
points: 50
dependencies:
- STR_SECTOPOD_CORPSE
- STR_SECTOPOD_AUTOPSY
- STR_ALIEN_ELECTRONICS
- name: STR_TANK_CORPSE
unlocks:
- STR_ADVANCED_AI
- name: STR_BLACKOPS_SMARTGUN
unlocks:
- STR_ADVANCED_AI
- name: STR_BLACKOPS_SMARTPISTOL
unlocks:
- STR_ADVANCED_AI
- name: STR_BLACKOPS_SMARTRIFLE
unlocks:
- STR_ADVANCED_AI
- name: STR_ADVANCED_AI
dependencies:
- STR_TANK_CORPSE
- STR_BLACKOPS_SMARTGUN
- STR_BLACKOPS_SMARTPISTOL
- STR_BLACKOPS_SMARTRIFLE
Thanks Meridian. So, I have to suppose that the behavior with dependencies: and requires: is the same as with unlocks:, it override precedent rulesets.
- name: STR_LEADER_PLUS
cost: 0
requires:
- STR_ALIEN_ORIGINS
dependencies:
- STR_LOBSTERMAN_COMMANDER
- STR_LOBSTERMAN_NAVIGATOR
- STR_GILLMAN_COMMANDER
How this will work? Do we need STR_ALIEN_ORIGINS and one of commanders?
So, if we have in vanilla:Code: [Select]- name: STR_LEADER_PLUS
How this will work? Do we need STR_ALIEN_ORIGINS and one of commanders?
cost: 0
requires:
- STR_ALIEN_ORIGINS
dependencies:
- STR_LOBSTERMAN_COMMANDER
- STR_LOBSTERMAN_NAVIGATOR
- STR_GILLMAN_COMMANDER
If I understand well, you can get rid of the requires:, and just add STR_ALIEN_ORIGINS to dependencies.Wrong. What you suggest will drasticallly change the main story line research.
- name: STR_LEADER_PLUS
cost: 0
dependencies:
- STR_ALIEN_ORIGINS
- STR_LOBSTERMAN_COMMANDER
- STR_LOBSTERMAN_NAVIGATOR
- STR_GILLMAN_COMMANDER
- name: STR_LEADER_PLUS
cost: 0
requires:
- STR_ALIEN_ORIGINS
dependencies:
- STR_LOBSTERMAN_COMMANDER
- STR_LOBSTERMAN_NAVIGATOR
- STR_GILLMAN_COMMANDER
Thanks HellRazor.
So, to confirm that after reading the other forum post and this explanation, I´m not understanding, I will try to imagine the two scenarios.Code: [Select]- name: STR_LEADER_PLUS
cost: 0
dependencies:
- STR_ALIEN_ORIGINS
- STR_LOBSTERMAN_COMMANDER
- STR_LOBSTERMAN_NAVIGATOR
- STR_GILLMAN_COMMANDER
Just have those four in any order and STR_LEADER_PLUS will pop up.
Code: [Select]- name: STR_LEADER_PLUS
cost: 0
requires:
- STR_ALIEN_ORIGINS
dependencies:
- STR_LOBSTERMAN_COMMANDER
- STR_LOBSTERMAN_NAVIGATOR
- STR_GILLMAN_COMMANDER
In this case, STR_LEADER_PLUS will only appears after you have STR_ALIEN_ORIGINS, and get the dependencies. If you got those aliens interrogations before, you have to get it again.
I hope this time I understand well. If not, I will take pencil and paper tomorrow. :P
I have another question. There is a way to replace the logic with require: using unlock: in another tech?.
#BEGIN WIN THE GAME
#listOrder: 10-29
- name: STR_THE_ALIEN_THREAT
cost: 200
points: 20
listOrder: 10
- name: STR_ALIEN_INVASION
cost: 500
points: 40
dependencies:
- STR_THE_ALIEN_THREAT
- STR_ALIEN_DATA_SLATE
- STR_ALIEN_INVASION_UNLOCK
listOrder: 11
- name: STR_ALIEN_INVASION_UNLOCK
requires:
- STR_THE_ALIEN_THREAT
dependencies: &ALL_ALIVE_ALIENS
- STR_FLOATER_SOLDIER
- STR_FLOATER_NAVIGATOR
- STR_FLOATER_MEDIC
- STR_FLOATER_ENGINEER
- STR_FLOATER_LEADER
- STR_FLOATER_COMMANDER
- STR_SECTOID_SOLDIER
- STR_SECTOID_NAVIGATOR
- STR_SECTOID_MEDIC
- STR_SECTOID_ENGINEER
- STR_SECTOID_LEADER
- STR_SECTOID_COMMANDER
- STR_SNAKEMAN_SOLDIER
- STR_SNAKEMAN_NAVIGATOR
- STR_SNAKEMAN_ENGINEER
- STR_SNAKEMAN_LEADER
- STR_SNAKEMAN_COMMANDER
- STR_MUTON_SOLDIER
- STR_MUTON_NAVIGATOR
- STR_MUTON_ENGINEER
- STR_WASPITE_SOLDIER
- STR_WASPITE_NAVIGATOR
- STR_WASPITE_MEDIC
- STR_WASPITE_ENGINEER
- STR_WASPITE_LEADER
- STR_WASPITE_COMMANDER
- STR_GAZER_SOLDIER
- STR_GAZER_NAVIGATOR
- STR_GAZER_MEDIC
- STR_GAZER_ENGINEER
- STR_GAZER_LEADER
- STR_GAZER_COMMANDER
- STR_SECTOID_ELITE_SOLDIER
- STR_SECTOID_ELITE_NAVIGATOR
- STR_SECTOID_ELITE_MEDIC
- STR_SECTOID_ELITE_ENGINEER
- STR_SECTOID_ELITE_LEADER
- STR_SECTOID_ELITE_COMMANDER
- STR_MUTON_ELITE_SOLDIER
- STR_MUTON_ELITE_NAVIGATOR
- STR_MUTON_ELITE_ENGINEER
- STR_MUTON_ELITE_LEADER
- STR_ETHEREAL_SOLDIER
- STR_ETHEREAL_LEADER
- STR_ETHEREAL_COMMANDER
- STR_MUTON_ELITE_GUARD_SOLDIER
- STR_MUTON_ELITE_GUARD_ENGINEER
- STR_MUTON_ELITE_GUARD_LEADER
- STR_SILACOID_TERRORIST
- STR_REAPER_TERRORIST
- STR_CYBERDISC_TERRORIST
- STR_CHRYSSALID_TERRORIST
- STR_SECTOPOD_TERRORIST
- STR_CELATID_TERRORIST
- STR_MUTON_BERSERKER_TERRORIST
- STR_CYBERMITE_TERRORIST
- STR_HOLODRONE_TERRORIST
- STR_ARMORED_CYBERDISC
- STR_ARMORED_SECTOPOD
- STR_CHRYSSALID_SPITTER_TERRORIST
listOrder: 12
- delete: STR_ALIEN_ORIGINS
- name: STR_ALIEN_ORIGINS
cost: 1000
points: 60
dependencies:
- STR_LEADER_PLUS
listOrder: 13
- delete: STR_LEADER_PLUS
- name: STR_LEADER_PLUS
requires:
- STR_ALIEN_INVASION
dependencies:
- STR_FLOATER_LEADER
- STR_FLOATER_COMMANDER
- STR_SECTOID_LEADER
- STR_SECTOID_COMMANDER
- STR_SNAKEMAN_LEADER
- STR_SNAKEMAN_COMMANDER
- STR_WASPITE_LEADER
- STR_WASPITE_COMMANDER
- STR_GAZER_LEADER
- STR_GAZER_COMMANDER
- STR_SECTOID_ELITE_LEADER
- STR_SECTOID_ELITE_COMMANDER
- STR_MUTON_ELITE_LEADER
- STR_ETHEREAL_LEADER
- STR_ETHEREAL_COMMANDER
- STR_MUTON_ELITE_GUARD_LEADER
listOrder: 14
- name: STR_THE_MARTIAN_SOLUTION
cost: 2000
points: 60
dependencies:
- STR_COMMANDER_PLUS
listOrder: 15
- name: STR_COMMANDER_PLUS
unlocks:
- STR_THE_MARTIAN_SOLUTION
requires:
- STR_ALIEN_ORIGINS
dependencies:
- STR_FLOATER_COMMANDER
- STR_SECTOID_COMMANDER
- STR_SNAKEMAN_COMMANDER
- STR_WASPITE_COMMANDER
- STR_GAZER_COMMANDER
- STR_SECTOID_ELITE_COMMANDER
- STR_ETHEREAL_COMMANDER
listOrder: 16
- delete: STR_CYDONIA_OR_BUST
- name: STR_CYDONIA_OR_BUST
cost: 3000
points: 100
unlockFinalMission: true
dependencies:
- STR_CYDONIA_PLUS
listOrder: 17
- name: STR_CYDONIA_PLUS
unlocks:
- STR_CYDONIA_OR_BUST
requires:
- STR_THE_MARTIAN_SOLUTION
dependencies:
- STR_ETHEREAL_COMMANDER
listOrder: 18
#END WIN THE GAME
#BEGIN ETHEREAL
#listOrder: 1600-1699
- delete: STR_ETHEREAL_SOLDIER
- delete: STR_ETHEREAL_LEADER
- delete: STR_ETHEREAL_COMMANDER
- name: STR_ETHEREAL
listOrder: 1600
- name: STR_ETHEREAL_SOLDIER
cost: 288
points: 50
needItem: true
destroyItem: true
listOrder: 1601
lookup: STR_ETHEREAL
unlocks:
- STR_ALIEN_LANGUAGE_UNLOCK
- STR_ALIEN_INVASION_UNLOCK
- STR_PSIONICS_UNLOCK
- name: STR_ETHEREAL_LEADER
cost: 288
points: 50
needItem: true
destroyItem: true
listOrder: 1605
lookup: STR_ETHEREAL
unlocks:
- STR_ALIEN_LANGUAGE_UNLOCK
- STR_ALIEN_INVASION_UNLOCK
- STR_LEADER_PLUS
- STR_PSIONICS_UNLOCK
- name: STR_ETHEREAL_COMMANDER
cost: 288
points: 50
needItem: true
destroyItem: true
listOrder: 1606
lookup: STR_ETHEREAL
unlocks:
- STR_ALIEN_LANGUAGE_UNLOCK
- STR_ALIEN_INVASION_UNLOCK
- STR_LEADER_PLUS
- STR_COMMANDER_PLUS
- STR_PSIONICS_UNLOCK
- STR_CYDONIA_PLUS
#END ETHEREAL
Well, if i understand properly, there is a way to not use "requires" by adding "virtual" research topics, opened by "unlock", so one of equal topics(like different commanders) will unlock virtual one, and final topic (like cydonia) will have virtual as one of dependencies?
The requires are still used to ensure that the topic in questions only becomes available after the other researches in the tree have been researched before.
It depends how you use it. "requires" allows you to restrict research access, meaning that all topics listed in "requires" have to be researched completely before the topic in question is even considered to be poped for research or unlocks or getOneFree.
It's still pointless discussing using "requires".
It works only for 2 specific topics:
- STR_LEADER_PLUS
- STR_COMMANDER_PLUS
If you try anything else, it won't work.
Proof: https://github.com/SupSuper/OpenXcom/blob/master/src/Savegame/SavedGame.cpp#L1181
Proof: https://github.com/SupSuper/OpenXcom/blob/master/src/Savegame/SavedGame.cpp#L1214
Here is the general check.
research:
- name: STR_LASER_WEAPONS # simulates STR_ALIEN_ORIGINS
cost: 5
- name: STR_MOTION_SCANNER # simulates a live leader, e.g. STR_FLOATER_LEADER
cost: 5
unlocks:
- STR_MEDI_KIT # simulates STR_LEADER_PLUS
- STR_LASER_WEAPONS # simulates STR_ALIEN_ORIGINS
- name: STR_MEDI_KIT # simulates STR_LEADER_PLUS
cost: 0
requires:
- STR_LASER_WEAPONS # simulates STR_ALIEN_ORIGINS
dependencies:
- STR_MOTION_SCANNER # simulates a live leader, e.g. STR_FLOATER_LEADER
- STR_FLOATER_COMMANDER
- STR_FLOATER_LEADER
- name: STR_THE_MARTIAN_SOLUTION
cost: 5
dependencies:
- STR_LASER_WEAPONS # simulates STR_ALIEN_ORIGINS
- STR_MEDI_KIT # simulates STR_LEADER_PLUS
- name: STR_NEW_FIGHTER_TRANSPORTER
cost: 1050
points: 30
listOrder: 102
dependencies:
- STR_UFO_CONSTRUCTION
- STR_NEW_FIGHTER_TRANSPORTER_UNLOCK_1
- STR_NEW_FIGHTER_TRANSPORTER_UNLOCK_2
- name: STR_NEW_FIGHTER_TRANSPORTER_UNLOCK_1
listOrder: 103
requires:
- STR_UFO_CONSTRUCTION
dependencies: &ALL_ALIVE_ENGINEERS
- STR_FLOATER_ENGINEER
- STR_SECTOID_ENGINEER
- STR_SNAKEMAN_ENGINEER
- STR_MUTON_ENGINEER
- STR_WASPITE_ENGINEER
- STR_GAZER_ENGINEER
- STR_SECTOID_ELITE_ENGINEER
- STR_MUTON_ELITE_ENGINEER
- STR_MUTON_ELITE_GUARD_ENGINEER
- name: STR_NEW_FIGHTER_TRANSPORTER_UNLOCK_2
listOrder: 104
requires:
- STR_UFO_CONSTRUCTION
dependencies: &ALL_ALIVE_NAVIGATORS
- STR_FLOATER_NAVIGATOR
- STR_SECTOID_NAVIGATOR
- STR_SNAKEMAN_NAVIGATOR
- STR_MUTON_NAVIGATOR
- STR_WASPITE_NAVIGATOR
- STR_GAZER_NAVIGATOR
- STR_SECTOID_ELITE_NAVIGATOR
- STR_MUTON_ELITE_NAVIGATOR
I think we are both looking in the wrong function.
GetOneFree only for Alive Aliens.
And btw I never said anything about you being wrong, I just pointed out that there is a check. It only works together with the above mentioned function, otherwise it would indeed not make sense.
Also the example you mentioned, will of course not work because it is not correctly coded.
Using the hardcoded string will not work, you have to create extra unlocks.
See here:Code: [Select]...
This will also work if you replace the alive alien here with normal Items, as long as the respective research has the appropriate unlocks.
You know, if you don't believe me, ask SupSuper or Warboy... I can't give you more proof than source code + example.
GetOneFree fools you into false safety, because it allows you to repeat the research of a certain topic/unit finite-amount-of times. So, instead of 1 try, you will have let's say 7 tries.I see, so actually if you research all alien Leader or Commanders, before researching alien origins you are essentially fucked (or whatever topic comes before the STR_LEADER_PLUS holding topic). And at that point the hardcoded strings with special functions actually do save your ass.
Still, if you do all GetOneFree topics BEFORE you manage to fulfill the requirement... you will again be completely stuck.
No, it still doesn't work... only gives you a few more attempts, as mentioned above.
Also, from other side, you can remove GetOneFree from Floater Leader... and it will still show up in your research... until you unlock Martian Solution.
It is coded the same way as the vanilla Martian Solution... I copy-pasted it from vanilla.
As far as I can say (99.99998% sure), it is coded correctly.
I tried it and it worked.
Not saying it's a correct solution... it's not... it wouldn't work if I used it twice (in different topics).
I will look at your code later (probably tomorrow) and share what I found.
Looking forward to your insights.
So, assuming your code is identical to what's in Hardmode v0.99.2d, I did a test with latest nightly (commit c05326a).
Steps:
1. New game
2. Save game
3. Edit saved game:
- removed alienMissions
- increased funds 10x
- added discoveries: mind shield, alien containment
- added 2 labs, 3 mind shields, 3 living quarters, 2 alien containments
- added 140 scientists
- added 6 floater engineers and 6 floater navigators
- added discoveries: almost all topics from floater engineer/navigator GetOneFree lists... except 2 from each... to save some testing time
- added discoveries: all 3 pre-requisites for UFO construction
Save is attached in this post... feel free to test yourself.
Note:
Let's assume your STR_NEW_FIGHTER_TRANSPORTER_UNLOCK_1 and STR_NEW_FIGHTER_TRANSPORTER_UNLOCK_2 topics only work with floaters engineers/navigators and not other races... for sake of simplicity. It doesn't change anything.
4. Load edited save
5. Research:
UFO construction -> Floater engineer -> Floater navigator -> New Fighter Transporter unlocked!
6. Reload again
7. Research:
- 2x Floater engineer -> cannot research more even though there are still 4 in prison
- 2x Floater navigator -> cannot research more even though there are still 4 in prison
- research UFO construction -> New Fighter Transporter in not unlocked (which is OK)...
...BUT you cannot research floater engineers or navigators anymore... thus you will never be able to unlock it... you're stuck!
Q.E.D.
it was not my intention to offend you in any way. I just wanted to know why this behaviour can occur and why.
So thanks for the test case.
No worries, maybe a bit more faith in me next time.
Btw. I have no intention or desire to change/fix this. I was just telling new people to avoid it.
/**
* Check whether a ResearchProject can be researched.
* @param r the RuleResearch to test.
* @param unlocked the list of currently unlocked RuleResearch
* @param mod the current Mod
* @return true if the RuleResearch can be researched
*/
bool SavedGame::isResearchAvailable (RuleResearch * r, const std::vector<const RuleResearch *> & unlocked, const Mod * mod) const
{
if (r == 0)
{
return false;
}
std::vector<std::string> deps = r->getDependencies();
const std::vector<const RuleResearch *> & discovered(getDiscoveredResearch());
if (_debug || std::find(unlocked.begin(), unlocked.end(), r) != unlocked.end())
{
return true;
}
if (!r->getGetOneFree().empty())
{
for(std::vector<const RuleResearch *>::const_iterator isDiscovered = discovered.begin(); isDiscovered != discovered.end(); ++isDiscovered)
{
RuleResearch *researchDiscovered = mod->getResearch(*isDiscovered);
std::vector<std::string>::const_iterator unlockCheck = std::find(r->getUnlocked().begin(), r->getUnlocked().end(), researchDiscovered);
bool unlock ( unlockCheck != r->getUnlocked().end());
if (unlock)
{
std::vector<const RuleResearch*>::const_iterator found = std::find(discovered.begin(), discovered.end(), mod->getResearch(researchDiscovered));
if (found == discovered.end())
{
return true;
}
}
}
}
for (std::vector<std::string>::const_iterator iter = deps.begin(); iter != deps.end(); ++iter)
{
RuleResearch *research = mod->getResearch(*iter);
std::vector<const RuleResearch *>::const_iterator itDiscovered = std::find(discovered.begin(), discovered.end(), research);
if (itDiscovered == discovered.end())
{
return false;
}
}
return true;
}
No worries, maybe a bit more faith in me next time.
Btw. I have no intention or desire to change/fix this. I was just telling new people to avoid it.