Skip to content

Commit

Permalink
Disable useless structures and research
Browse files Browse the repository at this point in the history
If structure limits are enforced and VTOLs are disabled, disable also
AA structures and related research. This improves the AIs in no-VTOL
games. Likewise, disable useless research for no-cyborg, no-lassat and
no-satlink games.

Closes #510.
  • Loading branch information
topimiettinen committed Sep 16, 2019
1 parent d667ba1 commit a6ef33f
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 8 deletions.
7 changes: 2 additions & 5 deletions src/game.cpp
Expand Up @@ -6218,10 +6218,7 @@ bool loadSaveResearch(const char *pFileName)
psPlRes = &asPlayerResList[plr][statInc];
// Copy the research status
psPlRes->ResearchStatus = (researched & RESBITS);
if (possible != 0)
{
MakeResearchPossible(psPlRes);
}
SetResearchPossible(psPlRes, possible);
psPlRes->currentPoints = points;
//for any research that has been completed - perform so that upgrade values are set up
if (researched == RESEARCHED)
Expand All @@ -6247,7 +6244,7 @@ static bool writeResearchFile(char *pFileName)
std::vector<WzString> possibles, researched, points;
for (int player = 0; player < game.maxPlayers; player++)
{
possibles.push_back(WzString::number(IsResearchPossible(&asPlayerResList[player][i])));
possibles.push_back(WzString::number(GetResearchPossible(&asPlayerResList[player][i])));
researched.push_back(WzString::number(asPlayerResList[player][i].ResearchStatus & RESBITS));
points.push_back(WzString::number(asPlayerResList[player][i].currentPoints));
if (IsResearchPossible(&asPlayerResList[player][i]) || (asPlayerResList[player][i].ResearchStatus & RESBITS) || asPlayerResList[player][i].currentPoints)
Expand Down
52 changes: 52 additions & 0 deletions src/multilimit.cpp
Expand Up @@ -371,6 +371,7 @@ void applyLimitSet()

// Get the limits and decode
const MULTISTRUCTLIMITS *pEntry = ingame.pStructureLimits;
bool no_vtols = false, no_cyborgs = false, no_lassat = false, no_satlink = false;
for (int i = 0; i < ingame.numStructureLimits; ++i)
{
int id = pEntry[i].id;
Expand Down Expand Up @@ -398,6 +399,57 @@ void applyLimitSet()
}
}
}
if (asStructureStats[id].type == REF_VTOL_FACTORY && pEntry[i].limit == 0)
{
no_vtols = true;
}
if (asStructureStats[id].type == REF_CYBORG_FACTORY && pEntry[i].limit == 0)
{
no_cyborgs = true;
}
if (asStructureStats[id].type == REF_GENERIC && asStructureStats[id].id == "A0LasSatCommand" && pEntry[i].limit == 0)
{
no_lassat = true;
}
if (asStructureStats[id].type == REF_SAT_UPLINK && pEntry[i].limit == 0)
{
no_satlink = true;
}
}
}

// If structure limits are enforced and VTOLs are disabled, disable also AA structures
if ((ingame.flags & MPFLAGS_FORCELIMITS) && no_vtols)
{
for (int i = 0; i < numStructureStats; i++)
{
if (asStructureStats[i].numWeaps > 0 && asStructureStats[i].psWeapStat[0]->surfaceToAir == SHOOT_IN_AIR)
{
for (int player = 0; player < MAX_PLAYERS; player++)
{
asStructureStats[i].upgrade[player].limit = 0;
}
}
}
// Disable most VTOL and AA research
RecursivelyDisableResearch("R-Struc-VTOLPad-Upgrade02", "R-Wpn-AAGun02", "R-Wpn-AAGun03",
"R-Wpn-Sunburst", "R-Wpn-AAGun-Damage01", "R-Wpn-Missile-LtSAM",
"R-Wpn-AALaser", "R-Wpn-Bomb01", "R-Cyborg-Transport",
"R-SuperTransport", nullptr);
}
if ((ingame.flags & MPFLAGS_FORCELIMITS) && no_cyborgs)
{
// Disable most cyborg research
RecursivelyDisableResearch("R-Cyborg-Metals01", "R-Cyborg-Hvywpn-PulseLsr", nullptr);
}
if ((ingame.flags & MPFLAGS_FORCELIMITS) && no_lassat)
{
// Disable Laser Satellite Command Post research
RecursivelyDisableResearch("R-Wpn-LasSat", nullptr);
// Also Satellite Uplink Center research if it is disabled
if (no_satlink)
{
RecursivelyDisableResearch("R-Sys-Sensor-UpLink", nullptr);
}
}

Expand Down
55 changes: 55 additions & 0 deletions src/research.cpp
Expand Up @@ -368,6 +368,11 @@ bool researchAvailable(int inc, int playerID, QUEUE_MODE mode)
{
return true;
}
// Ignore disabled
if (IsResearchDisabled(&asPlayerResList[playerID][inc]))
{
return false;
}
// if the topic is possible and has not already been researched - add to list
if ((IsResearchPossible(&asPlayerResList[playerID][inc])))
{
Expand Down Expand Up @@ -1395,3 +1400,53 @@ std::vector<AllyResearch> const &listAllyResearch(unsigned ref)
}
return i->second;
}

/* Recursively disable research for all players */
static void RecursivelyDisableResearchByID(UWORD index)
{
if (IsResearchDisabled(&asPlayerResList[0][index]))
{
return;
}

for (int player = 0; player < MAX_PLAYERS; ++player)
{
DisableResearch(&asPlayerResList[player][index]);
}

for (size_t inc = 0; inc < asResearch.size(); inc++)
{
for (size_t prereq = 0; prereq < asResearch[inc].pPRList.size(); prereq++)
{
if (asResearch[inc].pPRList[prereq] == index)
{
RecursivelyDisableResearchByID(inc);
}
}
}
}

static void RecursivelyDisableResearchByName(const char *name)
{
RESEARCH *r = getResearch(name);
if (r)
{
RecursivelyDisableResearchByID(r->index);
}
}

/* Recursively disable a list of research for all players */
void RecursivelyDisableResearch(const char *names ...)
{
va_list args;
va_start(args, names);

RecursivelyDisableResearchByName(names);
const char *name;
while ((name = va_arg(args, const char *)))
{
RecursivelyDisableResearchByName(name);
}
va_end(args);
return;
}
35 changes: 32 additions & 3 deletions src/researchdef.h
Expand Up @@ -78,7 +78,7 @@ struct PLAYER_RESEARCH

UBYTE ResearchStatus; // Bit flags ... see below

bool possible; ///< is the research possible ... so can enable topics vis scripts
UBYTE possible; ///< is the research possible ... so can enable topics vis scripts
};

#define STARTED_RESEARCH 0x01 // research in progress
Expand All @@ -90,14 +90,41 @@ struct PLAYER_RESEARCH
#define RESBITS_PENDING_ONLY (STARTED_RESEARCH_PENDING|CANCELLED_RESEARCH_PENDING)
#define RESBITS_PENDING (RESBITS|RESBITS_PENDING_ONLY)

#define RESEARCH_IMPOSSIBLE 0x00 // research is (temporarily) not possible
#define RESEARCH_POSSIBLE 0x01 // research is possible
#define RESEARCH_DISABLED 0x02 // research is disabled (e.g. most VTOL research in no-VTOL games)

static inline bool IsResearchPossible(const PLAYER_RESEARCH *research)
{
return research->possible;
return research->possible == RESEARCH_POSSIBLE;
}

static inline bool IsResearchDisabled(const PLAYER_RESEARCH *research)
{
return research->possible == RESEARCH_DISABLED;
}

static inline void MakeResearchPossible(PLAYER_RESEARCH *research)
{
research->possible = true;
if (research->possible == RESEARCH_IMPOSSIBLE)
{
research->possible = RESEARCH_POSSIBLE;
}
}

static inline void DisableResearch(PLAYER_RESEARCH *research)
{
research->possible = RESEARCH_DISABLED;
}

static inline int GetResearchPossible(const PLAYER_RESEARCH *research)
{
return research->possible;
}

static inline void SetResearchPossible(PLAYER_RESEARCH *research, UBYTE possible)
{
research->possible = possible;
}

static inline bool IsResearchCompleted(PLAYER_RESEARCH const *x)
Expand Down Expand Up @@ -163,4 +190,6 @@ static inline void ResetResearchStatus(PLAYER_RESEARCH *x)
x->ResearchStatus &= ~RESBITS_PENDING;
}

void RecursivelyDisableResearch(const char *names ...);

#endif // __INCLUDED_RESEARCHDEF_H__

0 comments on commit a6ef33f

Please sign in to comment.