42#define TECH_HASH_SIZE 64
112 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_MarkOneResearchable: \"%s\" marked as researchable.\n", tech->
id);
115 if (tech->
time == -1)
159 if (!requiredAND && !requiredOR) {
160 cgi->Com_Printf(
"RS_RequirementsMet: No requirement list(s) given as parameter.\n");
166 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_RequirementsMet: No requirements set for this tech. They are 'met'.\n");
262 cgi->Com_DPrintf(
DEBUG_CLIENT,
"met_AND is %i, met_OR is %i\n", metAND, metOR);
264 return (metAND || metOR);
276 return desc->
text[0];
291 return desc->
text[
i];
295 return desc->
text[0];
337 const base_t* thisBase = base;
339 for (
int i = 0;
i <
ccs.numTechnologies;
i++) {
348 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_MarkResearchable: handling \"%s\".\n", tech->
id);
358 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_MarkResearchable: \"%s\" marked researchable. reason:requirements.\n", tech->
id);
359 if (init && tech->
time == 0)
371 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_MarkResearchable: automatically researched \"%s\"\n", tech->
id);
393 cgi->Com_Error(
ERR_DROP,
"RS_AssignTechLinks: Could not get tech definition for '%s'", req->
id);
399 cgi->Com_Error(
ERR_DROP,
"RS_AssignTechLinks: Could not get item definition for '%s'", req->
id);
403 req->
link.
td =
cgi->Com_GetTeamDefinitionByID(req->
id);
405 cgi->Com_Error(
ERR_DROP,
"RS_AssignTechLinks: Could not get alien type (alien or alien_dead) definition for '%s'", req->
id);
424 for (
int i = 0;
i <
ccs.numTechnologies;
i++) {
441 assert(redirectedTech);
459 cgi->Com_Error(
ERR_DROP,
"RS_GetTechForItem: No item given");
461 cgi->Com_Error(
ERR_DROP,
"RS_GetTechForItem: Buffer overflow");
462 if (
ccs.objDefTechs[item->
idx] ==
nullptr)
463 cgi->Com_Error(
ERR_DROP,
"RS_GetTechForItem: No technology for item %s", item->
id);
464 return ccs.objDefTechs[item->
idx];
474 cgi->Com_Error(
ERR_DROP,
"RS_GetTechForTeam: No team given");
476 cgi->Com_Error(
ERR_DROP,
"RS_GetTechForTeam: Buffer overflow");
477 if (
ccs.teamDefTechs[team->
idx] ==
nullptr)
478 cgi->Com_Error(
ERR_DROP,
"RS_GetTechForTeam: No technology for team %s", team->
id);
479 return ccs.teamDefTechs[team->
idx];
501 if (!
ccs.objDefTechs[od->
idx])
502 cgi->Com_Error(
ERR_DROP,
"RS_InitTree: Could not find a valid tech for item %s", od->
id);
505 for (
i = 0, tech =
ccs.technologies;
i <
ccs.numTechnologies;
i++, tech++) {
520 switch (tech->
type) {
523 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_InitTree: \"%s\" A type craftitem needs to have a 'name\txxx' defined.", tech->
id);
527 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_InitTree: \"%s\" A 'type news' item needs to have a 'name\txxx' defined.", tech->
id);
531 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_InitTree: \"%s\" A 'type tech' item needs to have a 'name\txxx' defined.", tech->
id);
536 for (j = 0; j <
cgi->csi->numODs; j++) {
554 cgi->Com_Printf(
"RS_InitTree: \"%s\" - Linked weapon or armour (provided=\"%s\") not found. Tech-id used as name.\n",
560 for (j = 0; j <
ccs.numBuildingTemplates; j++) {
574 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_InitTree: \"%s\" - Linked building (provided=\"%s\") not found. Tech-id used as name.\n",
580 for (j = 0; j <
ccs.numAircraftTemplates; j++) {
584 cgi->Com_Error(
ERR_FATAL,
"RS_InitTree: \"%s\" - No linked aircraft or craft-upgrade.\n", tech->
id);
591 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_InitTree: aircraft model \"%s\" \n", aircraftTemplate->
model);
593 aircraftTemplate->
tech = tech;
598 cgi->Com_Printf(
"RS_InitTree: \"%s\" - Linked aircraft or craft-upgrade (provided=\"%s\") not found.\n", tech->
id, tech->
provides);
614 cgi->Com_Error(
ERR_DROP,
"RS_InitTree: \"%s\" - no name found!", tech->
id);
627 cgi->Com_DPrintf(
DEBUG_CLIENT,
"Tech %s of type %i has no image (%p) and no model (%p) assigned.\n",
641 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_InitTree: Technology tree initialised. %i entries found.\n",
i);
669 cgi->Com_DPrintf(
DEBUG_CLIENT,
"No free scientists in this base (%s) to assign to tech '%s'\n", base->
name, tech->
id);
677 CP_Popup(
_(
"Not enough laboratories"),
_(
"No free space in laboratories left.\nBuild more laboratories.\n"));
701 assert(tech->
base ==
nullptr);
709 cgi->Com_Printf(
"RS_RemoveScientist: No assigned scientists found - serious inconsistency.\n");
719 tech->
base =
nullptr;
743 if (tech ==
nullptr) {
744 cgi->Com_Printf(
"RS_RemoveFiredScientist: Cannot unassign scientist %d no tech is being researched in base %d\n", employee->
chr.
ucn, base->
idx);
779 if (base !=
nullptr) {
792 for (
int i = 0;
i <
ccs.numTechnologies;
i++) {
818 for (
int i = 0;
i <
ccs.numTechnologies;
i++) {
839 if (tech->
time <= 0) {
896 return "global alien count";
921 return "alienglobal";
935static void RS_TechnologyList_f (
void)
937 cgi->Com_Printf(
"#techs: %i\n",
ccs.numTechnologies);
938 for (
int i = 0;
i <
ccs.numTechnologies;
i++) {
945 cgi->Com_Printf(
"Tech: %s\n", tech->
id);
946 cgi->Com_Printf(
"... time -> %.2f\n", tech->
time);
947 cgi->Com_Printf(
"... name -> %s\n", tech->
name);
949 cgi->Com_Printf(
"... requires ALL ->");
950 for (j = 0; j < reqs->
numLinks; j++)
951 cgi->Com_Printf(
" %s (%s) %s", reqs->
links[j].
id, RS_TechLinkTypeToName(reqs->
links[j].
type), RS_TechReqToName(&reqs->
links[j]));
953 cgi->Com_Printf(
"\n");
954 cgi->Com_Printf(
"... requires ANY ->");
955 for (j = 0; j < reqs->
numLinks; j++)
956 cgi->Com_Printf(
" %s (%s) %s", reqs->
links[j].
id, RS_TechLinkTypeToName(reqs->
links[j].
type), RS_TechReqToName(&reqs->
links[j]));
957 cgi->Com_Printf(
"\n");
958 cgi->Com_Printf(
"... provides -> %s", tech->
provides);
959 cgi->Com_Printf(
"\n");
961 cgi->Com_Printf(
"... type -> ");
962 cgi->Com_Printf(
"%s\n", RS_TechTypeToName(tech->
type));
968 cgi->Com_Printf(
"... researchable date: %02i %02i %i\n", date.
day, date.
month, date.
year);
971 cgi->Com_Printf(
"... research -> ");
974 cgi->Com_Printf(
"nothing\n");
977 cgi->Com_Printf(
"running\n");
980 cgi->Com_Printf(
"paused\n");
983 cgi->Com_Printf(
"done\n");
985 cgi->Com_Printf(
"... research date: %02i %02i %i\n", date.
day, date.
month, date.
year);
988 cgi->Com_Printf(
"unknown\n");
998static void RS_DebugMarkResearchedAll (
void)
1000 for (
int i = 0;
i <
ccs.numTechnologies;
i++) {
1013static void RS_DebugResearchAll_f (
void)
1015 if (
cgi->Cmd_Argc() != 2) {
1016 RS_DebugMarkResearchedAll();
1031static void RS_DebugResearchableAll_f (
void)
1033 if (
cgi->Cmd_Argc() != 2) {
1034 for (
int i = 0;
i <
ccs.numTechnologies;
i++) {
1036 cgi->Com_Printf(
"...mark %s as researchable\n", tech->
id);
1043 cgi->Com_Printf(
"...mark %s as researchable\n", tech->
id);
1050static void RS_DebugFinishResearches_f (
void)
1052 for (
int i = 0;
i <
ccs.numTechnologies;
i++) {
1073 cgi->Cmd_AddCommand(
"debug_listtech", RS_TechnologyList_f,
"Print the current parsed technologies to the game console");
1074 cgi->Cmd_AddCommand(
"debug_researchall", RS_DebugResearchAll_f,
"Mark all techs as researched");
1075 cgi->Cmd_AddCommand(
"debug_researchableall", RS_DebugResearchableAll_f,
"Mark all techs as researchable");
1076 cgi->Cmd_AddCommand(
"debug_finishresearches", RS_DebugFinishResearches_f,
"Mark all running researches as finished");
1136 for (
int i = 0;
i <
ccs.numTechnologies;
i++) {
1138 cgi->Com_Printf(
"RS_ParseTechnologies: Second tech with same name found (%s) - second ignored\n",
name);
1144 cgi->Com_Printf(
"RS_ParseTechnologies: too many technology entries. limit is %i.\n",
MAX_TECHNOLOGIES);
1150 if (!*text || *token !=
'{') {
1151 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" technology def without body ignored.\n",
name);
1157 ccs.numTechnologies++;
1164 tech->
idx =
ccs.numTechnologies - 1;
1189 const char* errhead =
"RS_ParseTechnologies: unexpected end of file.";
1192 token =
cgi->Com_EParse(text, errhead,
name);
1200 token =
cgi->Com_EParse(text, errhead,
name);
1207 else if (
Q_streq(token,
"weapon"))
1209 else if (
Q_streq(token,
"news"))
1211 else if (
Q_streq(token,
"armour"))
1213 else if (
Q_streq(token,
"craft"))
1215 else if (
Q_streq(token,
"craftitem"))
1217 else if (
Q_streq(token,
"building"))
1219 else if (
Q_streq(token,
"alien"))
1221 else if (
Q_streq(token,
"ugv"))
1223 else if (
Q_streq(token,
"logic"))
1226 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" unknown techtype: \"%s\" - ignored.\n",
name, token);
1228 if (
Q_streq(token,
"description") ||
Q_streq(token,
"pre_description")) {
1233 if (
Q_streq(token,
"pre_description")) {
1239 token =
cgi->Com_EParse(text, errhead,
name);
1246 token =
cgi->Com_EParse(text, errhead,
name);
1254 if (
Q_streq(token,
"default")) {
1256 cgi->LIST_AddString(&list, token);
1257 token =
cgi->Com_EParse(text, errhead,
name);
1258 cgi->LIST_AddString(&list, token);
1259 }
else if (
Q_streq(token,
"extra")) {
1260 if (!
cgi->Com_ParseList(text, &list)) {
1261 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: error while reading extra description tuple");
1263 if (
cgi->LIST_Count(list) != 2) {
1264 cgi->LIST_Delete(&list);
1265 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: extra description tuple must contains 2 elements (id string)");
1268 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: error while reading description: token \"%s\" not expected", token);
1272 const char*
id = (
char*)list->
data;
1273 const char* description = (
char*)list->
next->
data;
1279 if (description[0] ==
'_')
1285 cgi->Com_Printf(
"skipped description for tech '%s'\n", tech->
id);
1287 cgi->LIST_Delete(&list);
1290 }
else if (
Q_streq(token,
"redirect")) {
1291 token =
cgi->Com_EParse(text, errhead,
name);
1295 }
else if (
Q_streq(token,
"require_AND") ||
Q_streq(token,
"require_OR") ||
Q_streq(token,
"require_for_production")) {
1298 if (
Q_streq(token,
"require_AND")) {
1300 }
else if (
Q_streq(token,
"require_OR")) {
1306 token =
cgi->Com_EParse(text, errhead,
name);
1313 token =
cgi->Com_EParse(text, errhead,
name);
1322 if (
Q_streq(token,
"tech_not"))
1331 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_ParseTechnologies: require-tech ('tech' or 'tech_not')- %s\n", requiredTemp->
links[requiredTemp->
numLinks].
id);
1335 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" Too many 'required' defined. Limit is %i - ignored.\n",
name,
MAX_TECHLINKS);
1337 }
else if (
Q_streq(token,
"item")) {
1341 if (!
cgi->Com_ParseList(text, &list)) {
1342 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: error while reading required item tuple");
1345 if (
cgi->LIST_Count(list) != 2) {
1346 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: required item tuple must contains 2 elements (id pos)");
1349 const char* idToken = (
char*)list->
data;
1350 const char* amountToken = (
char*)list->
next->
data;
1360 cgi->LIST_Delete(&list);
1362 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" Too many 'required' defined. Limit is %i - ignored.\n",
name,
MAX_TECHLINKS);
1364 }
else if (
Q_streq(token,
"alienglobal")) {
1375 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" Too many 'required' defined. Limit is %i - ignored.\n",
name,
MAX_TECHLINKS);
1377 }
else if (
Q_streq(token,
"alien_dead") ||
Q_streq(token,
"alien")) {
1381 if (
Q_streq(token,
"alien_dead")) {
1390 if (!
cgi->Com_ParseList(text, &list)) {
1391 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: error while reading required alien tuple");
1394 if (
cgi->LIST_Count(list) != 2) {
1395 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: required alien tuple must contains 2 elements (id pos)");
1398 const char* idToken = (
char*)list->
data;
1399 const char* amountToken = (
char*)list->
next->
data;
1406 cgi->LIST_Delete(&list);
1408 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" Too many 'required' defined. Limit is %i - ignored.\n",
name,
MAX_TECHLINKS);
1410 }
else if (
Q_streq(token,
"ufo")) {
1414 if (!
cgi->Com_ParseList(text, &list)) {
1415 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: error while reading required item tuple");
1418 if (
cgi->LIST_Count(list) != 2) {
1419 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: required item tuple must contains 2 elements (id pos)");
1422 const char* idToken = (
char*)list->
data;
1423 const char* amountToken = (
char*)list->
next->
data;
1434 }
else if (
Q_streq(token,
"antimatter")) {
1446 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" unknown requirement-type: \"%s\" - ignored.\n",
name, token);
1449 }
else if (
Q_streq(token,
"up_chapter")) {
1451 token =
cgi->Com_EParse(text, errhead,
name);
1457 for (
int i = 0;
i <
ccs.numChapters;
i++) {
1461 if (!
ccs.upChapters[
i].first) {
1462 ccs.upChapters[
i].first = tech;
1463 ccs.upChapters[
i].last = tech;
1469 ccs.upChapters[
i].last = tech;
1471 ccs.upChapters[
i].last->upPrev = techOld;
1472 ccs.upChapters[
i].last->upNext =
nullptr;
1476 if (
i ==
ccs.numChapters)
1477 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" - chapter \"%s\" not found.\n",
name, token);
1480 }
else if (
Q_streq(token,
"mail") ||
Q_streq(token,
"mail_pre")) {
1488 cgi->Com_Printf(
"RS_ParseTechnologies: more techmail-entries found than supported. \"%s\"\n",
name);
1490 if (
Q_streq(token,
"mail_pre")) {
1495 token =
cgi->Com_EParse(text, errhead,
name);
1496 if (!*text || *token !=
'{')
1500 token =
cgi->Com_EParse(text, errhead,
name);
1501 if (!*text || *token ==
'}')
1507 token =
cgi->Com_EParse(text, errhead,
name);
1510 }
while (*text && *token !=
'}');
1512 if (mail->
model ==
nullptr)
1513 mail->
model =
"characters/navarre";
1516 cgi->Com_Printf(
"RS_ParseTechnologies: unknown token \"%s\" ignored (entry %s)\n", token,
name);
1534 Sys_Error(
"RS_ParseTechnologies: weapon or armour tech without a provides property");
1536 cgi->Com_DPrintf(
DEBUG_CLIENT,
"tech '%s' doesn't have a provides string\n", tech->
id);
1547 if (techIdx < 0 || techIdx >=
ccs.numTechnologies)
1566 if (
ccs.technologies[techIdx].statusResearch ==
RS_FINISH)
1594 return &
ccs.technologies[techIdx];
1613 cgi->Com_Printf(
"RS_GetTechByID: Could not find a technology with id \"%s\"\n",
id);
1627 if (idProvided[0] ==
'\0')
1635 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_GetTechByProvided: %s\n", idProvided);
1652 for (
int i = 0;
i <
ccs.numTechnologies;
i++) {
1678 cgi->Com_Printf(
"RS_GetTechIdxByName: Could not find tech '%s'\n",
name);
1692 for (
int i = 0;
i <
ccs.numTechnologies;
i++) {
1694 if (tech->
base == base) {
1729 for (
int i = 0;
i <
ccs.numTechnologies;
i++) {
1768 bool success =
true;
1775 for (snode =
cgi->XML_GetNode(topnode,
SAVE_RESEARCH_TECH); snode; snode =
cgi->XML_GetNextNode(snode, topnode,
"tech")) {
1783 cgi->Com_Printf(
"......your game doesn't know anything about tech '%s'\n", techString);
1788 cgi->Com_Printf(
"Invalid research status '%s'\n",
type);
1817 cgi->Com_Printf(
"......your save game contains unknown techmail ids... \n");
1823 cgi->Com_Printf(
"No base but research is running and scientists are assigned");
1855 for (
i = 0, t =
ccs.technologies;
i <
ccs.numTechnologies;
i++, t++) {
1858 cgi->Com_Printf(
"...... technology '%s' has no name\n", t->
id);
1869 cgi->Com_Printf(
"...... technology '%s' doesn't provide anything\n", t->
id);
1884 cgi->Com_Printf(
"...... technology '%s' has zero (0) produceTime, is this on purpose?\n", t->
id);
1891 cgi->Com_Printf(
"...... technology '%s' has a strange 'description' value '%s'.\n", t->
id, t->
description.
text[0]);
1893 cgi->Com_Printf(
"...... technology '%s' has no 'description' value.\n", t->
id);
DateTime class definition.
Alien containment class header.
Share stuff between the different cgame implementations.
int getAlive(const teamDef_t *team) const
Return number of alive aliens of a type in the cargo.
int getDead(const teamDef_t *team) const
Return number of dead alien bodies of a type in the cargo.
Class describing a point of time.
int getTimeAsSeconds() const
Return the time part of the DateTime as seconds.
int getDateAsDays() const
Return the date part of the DateTime as days.
void setAssigned(bool assigned)
const aircraft_t * AIR_GetAircraft(const char *name)
Searches the global array of aircraft types for a given aircraft.
#define AIR_Foreach(var)
iterates trough all aircraft
int AL_CountAll(void)
Counts live aliens in all bases.
base_t * B_GetNext(base_t *lastBase)
Iterates through founded bases.
base_t * B_GetBaseByIDX(int baseIdx)
Array bound check for the base index. Will also return unfounded bases as long as the index is in the...
int B_AntimatterInBase(const base_t *base)
returns the amount of antimatter stored in a base
int B_ItemInBase(const objDef_t *item, const base_t *base)
Check if the item has been collected (i.e it is in the storage) in the given base.
bool B_GetBuildingStatus(const base_t *const base, const buildingType_t buildingType)
Get the status associated to a building.
#define B_IsUnderAttack(base)
memPool_t * cp_campaignPool
Header file for single player campaign control.
const cgame_import_t * cgi
void CAP_AddCurrent(base_t *base, baseCapacities_t capacity, int value)
Changes the current (used) capacity on a base.
int CAP_GetFreeCapacity(const base_t *base, baseCapacities_t capacityType)
Returns the free capacity of a type.
void CAP_SetCurrent(base_t *base, baseCapacities_t capacity, int value)
Sets the current (used) capacity on a base.
Employee * E_GetUnassignedEmployee(const base_t *const base, const employeeType_t type)
Gets an assigned employee of a given type from the given base.
int E_CountHired(const base_t *const base, employeeType_t type)
Counts hired employees of a given type in a given base.
Employee * E_GetAssignedEmployee(const base_t *const base, const employeeType_t type)
Gets an unassigned employee of a given type from the given base.
uiMessageListNodeMessage_t * MSO_CheckAddNewMessage(const notify_t messagecategory, const char *title, const char *text, messageType_t type, technology_t *pedia, bool popup)
Adds a new message to message stack. It uses message settings to verify whether sound should be playe...
char cp_messageBuffer[MAX_MESSAGE_TEXT]
bool RS_SaveXML(xmlNode_t *parent)
Save callback for research and technologies.
void RS_MarkOneResearchable(technology_t *tech)
Marks one tech as researchable.
void RS_MarkCollected(technology_t *tech)
Marks a give technology as collected.
static technology_t * techHash[TECH_HASH_SIZE]
const char * RS_GetDescription(technologyDescriptions_t *desc)
returns the currently used description for a technology.
static const value_t valid_techmail_vars[]
The valid definition names in the research.ufo file for tech mails.
void RS_RemoveScientist(technology_t *tech, Employee *employee)
Remove a scientist from a technology.
int RS_CountScientistsInBase(const base_t *base)
Returns the number of employees searching in labs in given base.
technology_t * RS_GetTechForTeam(const teamDef_t *team)
Returns technology entry for a team.
static void RS_MarkResearched(technology_t *tech, const base_t *base)
Mark technologies as researched. This includes techs that depends on "tech" and have time=0.
technology_t * RS_GetTechForItem(const objDef_t *item)
Returns technology entry for an item.
static technology_t * techHashProvided[TECH_HASH_SIZE]
int RS_GetTechIdxByName(const char *name)
Returns the index (idx) of a "tech" entry given it's name.
void RS_ResetTechs(void)
This is called everytime RS_ParseTechnologies is called - to prevent cyclic hash tables.
bool RS_IsResearched_ptr(const technology_t *tech)
Checks whether an item is already researched.
technology_t * RS_GetTechByID(const char *id)
return a pointer to the technology identified by given id string
void RS_StopResearch(technology_t *tech)
Stops a research (Removes scientists from it).
void RS_InitStartup(void)
This is more or less the initial Bind some of the functions in this file to console-commands that you...
bool RS_MarkStoryLineEventResearched(const char *techID)
technology_t * RS_GetTechWithMostScientists(const struct base_s *base)
Searches for the technology that has the most scientists assigned in a given base.
void RS_AssignScientist(technology_t *tech, base_t *base, Employee *employee)
Assigns scientist to the selected research-project.
technology_t * RS_GetTechByIDX(int techIdx)
Returns the technology pointer for a tech index. You can use this instead of "&ccs....
void RS_ResearchFinish(technology_t *tech)
Sets a technology status to researched and updates the date.
int RS_ResearchRun(void)
Checks the research status.
bool RS_RequirementsMet(const technology_t *tech, const base_t *base)
Checks if all requirements of a tech have been met so that it becomes researchable.
void RS_ParseTechnologies(const char *name, const char **text)
Parses one "tech" entry in the research.ufo file and writes it into the next free entry in technologi...
bool RS_ResearchAllowed(const base_t *base)
Returns true if the current base is able to handle research.
technology_t * RS_GetTechByProvided(const char *idProvided)
returns a pointer to the item tech (as listed in "provides")
bool RS_LoadXML(xmlNode_t *parent)
Load callback for research and technologies.
void RS_CheckRequirements(void)
Checks if running researches still meet their requirements.
static void RS_AssignTechLinks(requirements_t *reqs)
Assign required tech/item/etc... pointers for a single requirements list.
void RS_MarkResearchable(const base_t *base, bool init)
Marks all the techs that can be researched. Automatically researches 'free' techs such as ammo for a ...
void RS_RemoveScientistsExceedingCapacity(base_t *base)
Remove all exceeding scientist.
static bool RS_IsValidTechIndex(int techIdx)
static const value_t valid_tech_vars[]
The valid definition names in the research.ufo file.
void RS_RequiredLinksAssign(void)
Assign Link pointers to all required techs/items/etc...
bool RS_IsResearched_idx(int techIdx)
Checks if the technology (tech-index) has been researched.
void RS_InitTree(const campaign_t *campaign, bool load)
Gets all needed names/file-paths/etc... for each technology entry. Should be executed after the parsi...
void RS_RemoveFiredScientist(base_t *base, Employee *employee)
Remove one scientist from research project if needed.
bool RS_ScriptSanityCheck(void)
Checks the parsed tech data for errors.
static linkedList_t * redirectedTechs
Header for research related stuff.
researchType_t
Types of research topics.
void CP_DateConvertLong(const DateTime &date, dateLong_t *dateLong)
Converts a date from the engine in a (longer) human-readable format.
Campaign geoscape time header.
void UP_OpenWith(const char *techID)
Opens the UFOpaedia from everywhere with the entry given through name.
int US_UFOsInStorage(const aircraft_t *ufoTemplate, const installation_t *installation)
Returns the number of UFOs stored (on an installation or anywhere).
void Sys_Error(const char *error,...)
const objDef_t * INVSH_GetItemByIDX(int index)
Returns the item that belongs to the given index or nullptr if the index is invalid.
const objDef_t * INVSH_GetItemByID(const char *id)
Returns the item that belongs to the given id or nullptr if it wasn't found.
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
Shared parsing functions.
static wrapCache_t * hash[MAX_WRAP_HASH]
QGL_EXTERN GLint GLenum type
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
XML tag constants for savegame.
#define SAVE_RESEARCH_BASE
#define SAVE_RESEARCH_MAILSENT
#define SAVE_RESEARCH_PREDATE
#define SAVE_RESEARCH_DATE
#define SAVE_RESEARCH_STATUSRESEARCH
#define SAVE_RESEARCH_STATUSRESEARCHABLE
#define SAVE_RESEARCH_TECH
#define SAVE_RESEARCH_SCIENTISTS
static const constListEntry_t saveResearchConstants[]
#define SAVE_RESEARCHSTATUS_NAMESPACE
#define SAVE_RESEARCH_MAIL
#define SAVE_RESEARCH_STATUSCOLLECTED
#define SAVE_RESEARCH_MAIL_ID
#define SAVE_RESEARCH_TIME
#define SAVE_RESEARCH_RESEARCH
#define MEMBER_SIZEOF(TYPE, MEMBER)
#define Q_strcasecmp(a, b)
bool Q_strnull(const char *string)
unsigned int Com_HashKey(const char *name, int hashsize)
returns hash key for a string
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
An aircraft with all it's data.
struct technology_s * tech
A base with all it's data.
class AlienContainment * alienContainment
A building with all it's data.
Human readable time information in the game.
char * campaign[MAX_CAMPAIGNS]
bool markOnly[MAX_CAMPAIGNS]
Defines all attributes of objects used in the inventory.
union requirement_t::typelink_t link
requirement_t links[MAX_TECHLINKS]
available mails for a tech - mail and mail_pre in script files
This is the technology parsed from research.ufo.
struct technology_s * upPrev
requirements_t requireForProduction
researchStatus_t statusResearch
struct technology_s * hashProvidedNext
technologyDescriptions_t description
struct technology_s * hashNext
markResearched_t markResearched
char * finishedResearchEvent
technologyDescriptions_t preDescription
requirements_t requireAND
struct technology_s * redirect
class DateTime preResearchedDate
struct technology_s * upNext
struct pediaChapter_s * upChapter
techMail_t mail[TECHMAIL_MAX]
class DateTime researchedDate
char * text[MAX_DESCRIPTIONS]
char * tech[MAX_DESCRIPTIONS]
const struct objDef_s * od
const struct aircraft_s * aircraft
const struct technology_s * tech
const struct teamDef_s * td