31 #include "../../cl_shared.h"
32 #include "../../../shared/parse.h"
41 #define TECH_HASH_SIZE 64
111 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_MarkOneResearchable: \"%s\" marked as researchable.\n", tech->
id);
114 if (tech->
time == -1)
158 if (!requiredAND && !requiredOR) {
159 cgi->Com_Printf(
"RS_RequirementsMet: No requirement list(s) given as parameter.\n");
165 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_RequirementsMet: No requirements set for this tech. They are 'met'.\n");
171 for (i = 0; i < requiredAND->
numLinks; i++) {
218 for (i = 0; i < requiredOR->
numLinks; i++) {
261 cgi->Com_DPrintf(
DEBUG_CLIENT,
"met_AND is %i, met_OR is %i\n", metAND, metOR);
263 return (metAND || metOR);
275 return desc->
text[0];
290 return desc->
text[
i];
294 return desc->
text[0];
336 const base_t* thisBase = base;
347 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_MarkResearchable: handling \"%s\".\n", tech->
id);
357 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_MarkResearchable: \"%s\" marked researchable. reason:requirements.\n", tech->
id);
358 if (init && tech->
time == 0)
370 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_MarkResearchable: automatically researched \"%s\"\n", tech->
id);
392 cgi->Com_Error(
ERR_DROP,
"RS_AssignTechLinks: Could not get tech definition for '%s'", req->
id);
398 cgi->Com_Error(
ERR_DROP,
"RS_AssignTechLinks: Could not get item definition for '%s'", req->
id);
404 cgi->Com_Error(
ERR_DROP,
"RS_AssignTechLinks: Could not get alien type (alien or alien_dead) definition for '%s'", req->
id);
440 assert(redirectedTech);
448 cgi->LIST_Delete(&redirectedTechs);
458 cgi->Com_Error(
ERR_DROP,
"RS_GetTechForItem: No item given");
460 cgi->Com_Error(
ERR_DROP,
"RS_GetTechForItem: Buffer overflow");
462 cgi->Com_Error(
ERR_DROP,
"RS_GetTechForItem: No technology for item %s", item->
id);
473 cgi->Com_Error(
ERR_DROP,
"RS_GetTechForTeam: No team given");
475 cgi->Com_Error(
ERR_DROP,
"RS_GetTechForTeam: Buffer overflow");
477 cgi->Com_Error(
ERR_DROP,
"RS_GetTechForTeam: No technology for team %s", team->
id);
501 cgi->Com_Error(
ERR_DROP,
"RS_InitTree: Could not find a valid tech for item %s", od->
id);
519 switch (tech->
type) {
522 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_InitTree: \"%s\" A type craftitem needs to have a 'name\txxx' defined.", tech->
id);
526 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_InitTree: \"%s\" A 'type news' item needs to have a 'name\txxx' defined.", tech->
id);
530 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_InitTree: \"%s\" A 'type tech' item needs to have a 'name\txxx' defined.", tech->
id);
553 cgi->Com_Printf(
"RS_InitTree: \"%s\" - Linked weapon or armour (provided=\"%s\") not found. Tech-id used as name.\n",
573 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_InitTree: \"%s\" - Linked building (provided=\"%s\") not found. Tech-id used as name.\n",
583 cgi->Com_Error(
ERR_FATAL,
"RS_InitTree: \"%s\" - No linked aircraft or craft-upgrade.\n", tech->
id);
590 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_InitTree: aircraft model \"%s\" \n", aircraftTemplate->
model);
592 aircraftTemplate->
tech = tech;
597 cgi->Com_Printf(
"RS_InitTree: \"%s\" - Linked aircraft or craft-upgrade (provided=\"%s\") not found.\n", tech->
id, tech->
provides);
613 cgi->Com_Error(
ERR_DROP,
"RS_InitTree: \"%s\" - no name found!", tech->
id);
626 cgi->Com_DPrintf(
DEBUG_CLIENT,
"Tech %s of type %i has no image (%p) and no model (%p) assigned.\n",
640 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_InitTree: Technology tree initialised. %i entries found.\n", i);
668 cgi->Com_DPrintf(
DEBUG_CLIENT,
"No free scientists in this base (%s) to assign to tech '%s'\n", base->
name, tech->
id);
676 CP_Popup(
_(
"Not enough laboratories"),
_(
"No free space in laboratories left.\nBuild more laboratories.\n"));
700 assert(tech->
base ==
nullptr);
708 cgi->Com_Printf(
"RS_RemoveScientist: No assigned scientists found - serious inconsistency.\n");
718 tech->
base =
nullptr;
742 if (tech ==
nullptr) {
743 cgi->Com_Printf(
"RS_RemoveFiredScientist: Cannot unassign scientist %d no tech is being researched in base %d\n", employee->
chr.
ucn, base->
idx);
778 if (base !=
nullptr) {
838 if (tech->
time <= 0) {
895 return "global alien count";
920 return "alienglobal";
934 static void RS_TechnologyList_f (
void)
944 cgi->Com_Printf(
"Tech: %s\n", tech->
id);
945 cgi->Com_Printf(
"... time -> %.2f\n", tech->
time);
946 cgi->Com_Printf(
"... name -> %s\n", tech->
name);
948 cgi->Com_Printf(
"... requires ALL ->");
949 for (j = 0; j < reqs->
numLinks; j++)
950 cgi->Com_Printf(
" %s (%s) %s", reqs->
links[j].
id, RS_TechLinkTypeToName(reqs->
links[j].
type), RS_TechReqToName(&reqs->
links[j]));
952 cgi->Com_Printf(
"\n");
953 cgi->Com_Printf(
"... requires ANY ->");
954 for (j = 0; j < reqs->
numLinks; j++)
955 cgi->Com_Printf(
" %s (%s) %s", reqs->
links[j].
id, RS_TechLinkTypeToName(reqs->
links[j].
type), RS_TechReqToName(&reqs->
links[j]));
956 cgi->Com_Printf(
"\n");
957 cgi->Com_Printf(
"... provides -> %s", tech->
provides);
958 cgi->Com_Printf(
"\n");
960 cgi->Com_Printf(
"... type -> ");
961 cgi->Com_Printf(
"%s\n", RS_TechTypeToName(tech->
type));
967 cgi->Com_Printf(
"... researchable date: %02i %02i %i\n", date.
day, date.
month, date.
year);
970 cgi->Com_Printf(
"... research -> ");
973 cgi->Com_Printf(
"nothing\n");
976 cgi->Com_Printf(
"running\n");
979 cgi->Com_Printf(
"paused\n");
982 cgi->Com_Printf(
"done\n");
984 cgi->Com_Printf(
"... research date: %02i %02i %i\n", date.
day, date.
month, date.
year);
987 cgi->Com_Printf(
"unknown\n");
997 static void RS_DebugMarkResearchedAll (
void)
1012 static void RS_DebugResearchAll_f (
void)
1014 if (
cgi->Cmd_Argc() != 2) {
1015 RS_DebugMarkResearchedAll();
1030 static void RS_DebugResearchableAll_f (
void)
1032 if (
cgi->Cmd_Argc() != 2) {
1035 cgi->Com_Printf(
"...mark %s as researchable\n", tech->
id);
1042 cgi->Com_Printf(
"...mark %s as researchable\n", tech->
id);
1049 static void RS_DebugFinishResearches_f (
void)
1072 cgi->Cmd_AddCommand(
"debug_listtech", RS_TechnologyList_f,
"Print the current parsed technologies to the game console");
1073 cgi->Cmd_AddCommand(
"debug_researchall", RS_DebugResearchAll_f,
"Mark all techs as researched");
1074 cgi->Cmd_AddCommand(
"debug_researchableall", RS_DebugResearchableAll_f,
"Mark all techs as researchable");
1075 cgi->Cmd_AddCommand(
"debug_finishresearches", RS_DebugFinishResearches_f,
"Mark all running researches as finished");
1089 cgi->LIST_Delete(&redirectedTechs);
1137 cgi->Com_Printf(
"RS_ParseTechnologies: Second tech with same name found (%s) - second ignored\n", name);
1143 cgi->Com_Printf(
"RS_ParseTechnologies: too many technology entries. limit is %i.\n",
MAX_TECHNOLOGIES);
1149 if (!*text || *token !=
'{') {
1150 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" technology def without body ignored.\n", name);
1182 techHash[
hash] = tech;
1188 const char* errhead =
"RS_ParseTechnologies: unexpected end of file.";
1206 else if (
Q_streq(token,
"weapon"))
1208 else if (
Q_streq(token,
"news"))
1210 else if (
Q_streq(token,
"armour"))
1212 else if (
Q_streq(token,
"craft"))
1214 else if (
Q_streq(token,
"craftitem"))
1216 else if (
Q_streq(token,
"building"))
1218 else if (
Q_streq(token,
"alien"))
1220 else if (
Q_streq(token,
"ugv"))
1222 else if (
Q_streq(token,
"logic"))
1225 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" unknown techtype: \"%s\" - ignored.\n", name, token);
1227 if (
Q_streq(token,
"description") ||
Q_streq(token,
"pre_description")) {
1232 if (
Q_streq(token,
"pre_description")) {
1253 if (
Q_streq(token,
"default")) {
1255 cgi->LIST_AddString(&list, token);
1257 cgi->LIST_AddString(&list, token);
1258 }
else if (
Q_streq(token,
"extra")) {
1259 if (!
cgi->Com_ParseList(text, &list)) {
1260 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: error while reading extra description tuple");
1262 if (
cgi->LIST_Count(list) != 2) {
1263 cgi->LIST_Delete(&list);
1264 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: extra description tuple must contains 2 elements (id string)");
1267 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: error while reading description: token \"%s\" not expected", token);
1271 const char*
id = (
char*)list->
data;
1272 const char* description = (
char*)list->
next->
data;
1278 if (description[0] ==
'_')
1284 cgi->Com_Printf(
"skipped description for tech '%s'\n", tech->
id);
1286 cgi->LIST_Delete(&list);
1289 }
else if (
Q_streq(token,
"redirect")) {
1292 cgi->LIST_AddPointer(&redirectedTechs, tech);
1293 cgi->LIST_AddString(&redirectedTechs, token);
1294 }
else if (
Q_streq(token,
"require_AND") ||
Q_streq(token,
"require_OR") ||
Q_streq(token,
"require_for_production")) {
1297 if (
Q_streq(token,
"require_AND")) {
1299 }
else if (
Q_streq(token,
"require_OR")) {
1321 if (
Q_streq(token,
"tech_not"))
1330 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_ParseTechnologies: require-tech ('tech' or 'tech_not')- %s\n", requiredTemp->
links[requiredTemp->
numLinks].
id);
1334 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" Too many 'required' defined. Limit is %i - ignored.\n", name,
MAX_TECHLINKS);
1336 }
else if (
Q_streq(token,
"item")) {
1340 if (!
cgi->Com_ParseList(text, &list)) {
1341 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: error while reading required item tuple");
1344 if (
cgi->LIST_Count(list) != 2) {
1345 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: required item tuple must contains 2 elements (id pos)");
1348 const char* idToken = (
char*)list->
data;
1349 const char* amountToken = (
char*)list->
next->
data;
1359 cgi->LIST_Delete(&list);
1361 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" Too many 'required' defined. Limit is %i - ignored.\n", name,
MAX_TECHLINKS);
1363 }
else if (
Q_streq(token,
"alienglobal")) {
1374 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" Too many 'required' defined. Limit is %i - ignored.\n", name,
MAX_TECHLINKS);
1376 }
else if (
Q_streq(token,
"alien_dead") ||
Q_streq(token,
"alien")) {
1380 if (
Q_streq(token,
"alien_dead")) {
1389 if (!
cgi->Com_ParseList(text, &list)) {
1390 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: error while reading required alien tuple");
1393 if (
cgi->LIST_Count(list) != 2) {
1394 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: required alien tuple must contains 2 elements (id pos)");
1397 const char* idToken = (
char*)list->
data;
1398 const char* amountToken = (
char*)list->
next->
data;
1405 cgi->LIST_Delete(&list);
1407 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" Too many 'required' defined. Limit is %i - ignored.\n", name,
MAX_TECHLINKS);
1409 }
else if (
Q_streq(token,
"ufo")) {
1413 if (!
cgi->Com_ParseList(text, &list)) {
1414 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: error while reading required item tuple");
1417 if (
cgi->LIST_Count(list) != 2) {
1418 cgi->Com_Error(
ERR_DROP,
"RS_ParseTechnologies: required item tuple must contains 2 elements (id pos)");
1421 const char* idToken = (
char*)list->
data;
1422 const char* amountToken = (
char*)list->
next->
data;
1433 }
else if (
Q_streq(token,
"antimatter")) {
1445 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" unknown requirement-type: \"%s\" - ignored.\n", name, token);
1448 }
else if (
Q_streq(token,
"up_chapter")) {
1476 cgi->Com_Printf(
"RS_ParseTechnologies: \"%s\" - chapter \"%s\" not found.\n", name, token);
1479 }
else if (
Q_streq(token,
"mail") ||
Q_streq(token,
"mail_pre")) {
1487 cgi->Com_Printf(
"RS_ParseTechnologies: more techmail-entries found than supported. \"%s\"\n", name);
1489 if (
Q_streq(token,
"mail_pre")) {
1495 if (!*text || *token !=
'{')
1500 if (!*text || *token ==
'}')
1503 cgi->Com_ParseBlockToken(name, text, mail, valid_techmail_vars,
cp_campaignPool, token);
1509 }
while (*text && *token !=
'}');
1511 if (mail->
model ==
nullptr)
1512 mail->
model =
"characters/navarre";
1514 if (!
cgi->Com_ParseBlockToken(name, text, tech, valid_tech_vars,
cp_campaignPool, token))
1515 cgi->Com_Printf(
"RS_ParseTechnologies: unknown token \"%s\" ignored (entry %s)\n", token, name);
1530 techHashProvided[
hash] = tech;
1533 Sys_Error(
"RS_ParseTechnologies: weapon or armour tech without a provides property");
1535 cgi->Com_DPrintf(
DEBUG_CLIENT,
"tech '%s' doesn't have a provides string\n", tech->
id);
1612 cgi->Com_Printf(
"RS_GetTechByID: Could not find a technology with id \"%s\"\n",
id);
1626 if (idProvided[0] ==
'\0')
1634 cgi->Com_DPrintf(
DEBUG_CLIENT,
"RS_GetTechByProvided: %s\n", idProvided);
1677 cgi->Com_Printf(
"RS_GetTechIdxByName: Could not find tech '%s'\n", name);
1693 if (tech->
base == base) {
1767 bool success =
true;
1782 cgi->Com_Printf(
"......your game doesn't know anything about tech '%s'\n", techString);
1787 cgi->Com_Printf(
"Invalid research status '%s'\n", type);
1812 cgi->Com_Printf(
"......your save game contains unknown techmail ids... \n");
1818 cgi->Com_Printf(
"No base but research is running and scientists are assigned");
1853 cgi->Com_Printf(
"...... technology '%s' has no name\n", t->
id);
1864 cgi->Com_Printf(
"...... technology '%s' doesn't provide anything\n", t->
id);
1879 cgi->Com_Printf(
"...... technology '%s' has zero (0) produceTime, is this on purpose?\n", t->
id);
1886 cgi->Com_Printf(
"...... technology '%s' has a strange 'description' value '%s'.\n", t->
id, t->
description.
text[0]);
1888 cgi->Com_Printf(
"...... technology '%s' has no 'description' value.\n", t->
id);
bool Q_strnull(const char *string)
technology_t * objDefTechs[MAX_OBJDEFS]
const struct technology_s * tech
int AL_CountAll(void)
Counts live aliens in all bases.
#define SAVE_RESEARCH_STATUSCOLLECTED
struct technology_s * redirect
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.
const char * RS_GetDescription(technologyDescriptions_t *desc)
returns the currently used description for a technology.
bool RS_IsResearched_idx(int techIdx)
Checks if the technology (tech-index) has been researched.
void Sys_Error(const char *error,...)
requirement_t links[MAX_TECHLINKS]
void UP_OpenWith(const char *techID)
Opens the UFOpaedia from everywhere with the entry given through name.
A building with all it's data.
technology_t * RS_GetTechByIDX(int techIdx)
Returns the technology pointer for a tech index. You can use this instead of "&ccs.technologies[techIdx]" to avoid having to check valid indices.
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...
#define SAVE_RESEARCHSTATUS_NAMESPACE
bool RS_IsResearched_ptr(const technology_t *tech)
Checks whether an item is already researched.
const objDef_t * INVSH_GetItemByID(const char *id)
Returns the item that belongs to the given id or nullptr if it wasn't found.
QGL_EXTERN GLint GLenum type
bool B_GetBuildingStatus(const base_t *const base, const buildingType_t buildingType)
Get the status associated to a building.
available mails for a tech - mail and mail_pre in script files
#define SAVE_RESEARCH_MAILSENT
void RS_MarkOneResearchable(technology_t *tech)
Marks one tech as researchable.
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...
void CAP_AddCurrent(base_t *base, baseCapacities_t capacity, int value)
Changes the current (used) capacity on a base.
void RS_InitStartup(void)
This is more or less the initial Bind some of the functions in this file to console-commands that you...
researchStatus_t statusResearch
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
#define B_IsUnderAttack(base)
static const constListEntry_t saveResearchConstants[]
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 ...
bool RS_LoadXML(xmlNode_t *parent)
Load callback for research and technologies.
#define SAVE_RESEARCH_TECH
const struct aircraft_s * aircraft
class AlienContainment * alienContainment
const aircraft_t * AIR_GetAircraft(const char *name)
Searches the global array of aircraft types for a given aircraft.
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.
int US_UFOsInStorage(const aircraft_t *ufoTemplate, const installation_t *installation)
Returns the number of UFOs stored (on an installation or anywhere)
Header for research related stuff.
#define SAVE_RESEARCH_BASE
requirements_t requireAND
bool markOnly[MAX_CAMPAIGNS]
void RS_RemoveScientistsExceedingCapacity(base_t *base)
Remove all exceeding scientist.
Defines all attributes of objects used in the inventory.
struct pediaChapter_s * upChapter
requirements_t requireForProduction
memPool_t * cp_campaignPool
static const value_t valid_tech_vars[]
The valid definition names in the research.ufo file.
static const value_t valid_techmail_vars[]
The valid definition names in the research.ufo file for tech mails.
int E_CountHired(const base_t *const base, employeeType_t type)
Counts hired employees of a given type in a given base.
A base with all it's data.
technology_t * teamDefTechs[MAX_TEAMDEFS]
int CAP_GetFreeCapacity(const base_t *base, baseCapacities_t capacityType)
Returns the free capacity of a type.
struct technology_s * first
static linkedList_t * redirectedTechs
struct technology_s * tech
int RS_CountScientistsInBase(const base_t *base)
Returns the number of employees searching in labs in given base.
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...
xmlNode_t *IMPORT * XML_GetDate(xmlNode_t *parent, const char *name, int *day, int *sec)
technology_t * RS_GetTechForTeam(const teamDef_t *team)
Returns technology entry for a team.
#define SAVE_RESEARCH_MAIL_ID
bool RS_MarkStoryLineEventResearched(const char *techID)
char * campaign[MAX_CAMPAIGNS]
void RS_RemoveFiredScientist(base_t *base, Employee *employee)
Remove one scientist from research project if needed.
technology_t * RS_GetTechWithMostScientists(const struct base_s *base)
Searches for the technology that has the most scientists assigned in a given base.
const struct objDef_s * od
static void RS_AssignTechLinks(requirements_t *reqs)
Assign required tech/item/etc... pointers for a single requirements list.
#define SAVE_RESEARCH_SCIENTISTS
struct technology_s * last
base_t * B_GetNext(base_t *lastBase)
Iterates through founded bases.
bool RS_ScriptSanityCheck(void)
Checks the parsed tech data for errors.
markResearched_t markResearched
static wrapCache_t * hash[MAX_WRAP_HASH]
void RS_MarkCollected(technology_t *tech)
Marks a give technology as collected.
const cgame_import_t * cgi
Employee * E_GetAssignedEmployee(const base_t *const base, const employeeType_t type)
Gets an unassigned employee of a given type from the given base.
pediaChapter_t upChapters[MAX_PEDIACHAPTERS]
void setAssigned(bool assigned)
const char *IMPORT * Com_GetConstVariable(const char *space, int value)
#define SAVE_RESEARCH_STATUSRESEARCHABLE
This is the technology parsed from research.ufo.
void RS_ResearchFinish(technology_t *tech)
Sets a technology status to researched and updates the date.
#define SAVE_RESEARCH_TIME
union requirement_s::typelink_t link
struct technology_s * upNext
char * finishedResearchEvent
aircraft_t aircraftTemplates[MAX_AIRCRAFT]
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...
Campaign geoscape time header.
#define Q_strcasecmp(a, b)
technology_t * RS_GetTechByID(const char *id)
return a pointer to the technology identified by given id string
struct technology_s * hashProvidedNext
enum researchType_s researchType_t
Types of research topics.
char cp_messageBuffer[MAX_MESSAGE_TEXT]
Alien containment class header.
static technology_t * techHashProvided[TECH_HASH_SIZE]
#define SAVE_RESEARCH_RESEARCH
int getDead(const teamDef_t *team) const
Return number of dead alien bodies of a type in the cargo.
void RS_CheckRequirements(void)
Checks if running researches still meet their requirements.
bool RS_ResearchAllowed(const base_t *base)
Returns true if the current base is able to handle research.
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
int RS_GetTechIdxByName(const char *name)
Returns the index (idx) of a "tech" entry given it's name.
int B_AntimatterInBase(const base_t *base)
returns the amount of antimatter stored in a base
static technology_t * techHash[TECH_HASH_SIZE]
static bool RS_IsValidTechIndex(int techIdx)
Human readable time information in the game.
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 CAP_SetCurrent(base_t *base, baseCapacities_t capacity, int value)
Sets the current (used) capacity on a base.
xmlNode_t *IMPORT * XML_GetNextNode(xmlNode_t *current, xmlNode_t *parent, const char *name)
technology_t technologies[MAX_TECHNOLOGIES]
void RS_RequiredLinksAssign(void)
Assign Link pointers to all required techs/items/etc...
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
void RS_StopResearch(technology_t *tech)
Stops a research (Removes scientists from it)
enum requirementType_s requirementType_t
char * tech[MAX_DESCRIPTIONS]
void CP_DateConvertLong(const date_t *date, dateLong_t *dateLong)
Converts a date from the engine in a (longer) human-readable format.
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...
unsigned int Com_HashKey(const char *name, int hashsize)
returns hash key for a string
#define MEMBER_SIZEOF(TYPE, MEMBER)
building_t buildingTemplates[MAX_BUILDINGS]
Header file for single player campaign control.
bool RS_SaveXML(xmlNode_t *parent)
Save callback for research and technologies.
#define SAVE_RESEARCH_STATUSRESEARCH
const objDef_t * INVSH_GetItemByIDX(int index)
Returns the item that belongs to the given index or nullptr if the index is invalid.
void RS_ResetTechs(void)
This is called everytime RS_ParseTechnologies is called - to prevent cyclic hash tables.
xmlNode_t *IMPORT * XML_AddNode(xmlNode_t *parent, const char *name)
const teamDef_t *IMPORT * Com_GetTeamDefinitionByID(const char *team)
Employee * E_GetUnassignedEmployee(const base_t *const base, const employeeType_t type)
Gets an assigned employee of a given type from the given base.
struct technology_s * upPrev
const char *IMPORT * Com_EParse(const char **text, const char *errhead, const char *errinfo)
int getAlive(const teamDef_t *team) const
Return number of alive aliens of a type in the cargo.
technology_t * RS_GetTechByProvided(const char *idProvided)
returns a pointer to the item tech (as listed in "provides")
objDef_t ods[MAX_OBJDEFS]
#define SAVE_RESEARCH_MAIL
#define AIR_Foreach(var)
iterates trough all aircraft
char *IMPORT * PoolStrDup(const char *in, memPool_t *pool, const int tagNum)
int RS_ResearchRun(void)
Checks the research status.
An aircraft with all it's data.
const struct teamDef_s * td
technology_t * RS_GetTechForItem(const objDef_t *item)
Returns technology entry for an item.
#define SAVE_RESEARCH_DATE
void RS_AssignScientist(technology_t *tech, base_t *base, Employee *employee)
Assigns scientist to the selected research-project.
technologyDescriptions_t description
char * text[MAX_DESCRIPTIONS]
const char *IMPORT * Cmd_Argv(int n)
XML tag constants for savegame.
#define SAVE_RESEARCH_PREDATE
void RS_RemoveScientist(technology_t *tech, Employee *employee)
Remove a scientist from a technology.
const char *IMPORT * XML_GetString(xmlNode_t *parent, const char *name)
struct technology_s * hashNext
xmlNode_t *IMPORT * XML_GetNode(xmlNode_t *parent, const char *name)
technologyDescriptions_t preDescription
techMail_t mail[TECHMAIL_MAX]