/** * @brief Appends a new entry to the market buffers * @sa BS_MarketScroll_f * @sa BS_MarketClick_f */ static void BS_AddToList (const char *name, int storage, int market, int price) { LIST_AddString(&bsMarketNames, _(name)); LIST_AddString(&bsMarketStorage, va("%i", storage)); LIST_AddString(&bsMarketMarket, va("%i", market)); LIST_AddString(&bsMarketPrices, va(_("%i c"), price)); }
static void UI_CvarListenerNodeCallback (const char* cvarName, const char* oldValue, const char* newValue, void* data) { linkedList_t* list = static_cast<linkedList_t*>(data); linkedList_t* params = nullptr; LIST_AddString(¶ms, oldValue); LIST_AddString(¶ms, newValue); while (list) { uiNode_t* node = static_cast<uiNode_t*>(list->data); UI_ExecuteEventActionsEx(node, node->onClick, params); list = list->next; } }
static void testLinkedListIterator (void) { linkedList_t *list = NULL; char *string; int cnt; LIST_AddString(&list, "test1"); LIST_AddString(&list, "test2"); LIST_AddString(&list, "test3"); cnt = 0; LIST_Foreach(list, char, string) { CU_ASSERT_PTR_NOT_NULL(string); cnt++; }
/** * @brief Choose nation if needed for given mission. * @param[in] mission Pointer to the mission we are creating. * @param[out] nationList linkedList that will contain the name of the nation where the mission should take place. * @note nationList should be empty if no nation should be favoured. * @return True if nationList has been filled, false else. */ static qboolean CP_ChooseNation (const mission_t *mission, linkedList_t **nationList) { int randomNumber, max = 0; /* Increase this factor to make probability to select non-infected nation higher * Used to make sure that non-infected nation can still be attacked */ const int OFFSET = 1; int i; if (mission->ufo) return qfalse; /* favour mission with higher XVI level */ for (i = 0; i < ccs.numNations; i++) { const nation_t *nation = NAT_GetNationByIDX(i); const nationInfo_t *stats = NAT_GetCurrentMonthInfo(nation); max += OFFSET + stats->xviInfection; } randomNumber = (int) (frand() * (float) max); /* Select the corresponding nation */ for (i = 0; i < ccs.numNations; i++) { const nation_t *nation = NAT_GetNationByIDX(i); const nationInfo_t *stats = NAT_GetCurrentMonthInfo(nation); randomNumber -= OFFSET + stats->xviInfection; if (randomNumber < 0) { LIST_AddString(nationList, nation->id); return qtrue; } } return qfalse; }
static inline void CLMN_AddBindings (linkedList_t **list, char **bindings) { int i; for (i = K_FIRST_KEY; i < K_LAST_KEY; i++) if (bindings[i] && bindings[i][0] != '\0') LIST_AddString(list, va("%s\t%s", Key_KeynumToString(i), Cmd_GetCommandDesc(bindings[i]))); }
/** * @brief Update TEXT_AIRCRAFT_LIST with the current base aircraft names */ static void AIR_AircraftUpdateList_f (void) { linkedList_t *list = NULL; base_t *base = B_GetCurrentSelectedBase(); AIR_ForeachFromBase(aircraft, base) { LIST_AddString(&list, aircraft->name); }
static void testTeamDefsModelScriptData (void) { int i; linkedList_t *armourPaths = NULL; for (i = 0; i < csi.numTeamDefs; i++) { int j; const teamDef_t *teamDef = &csi.teamDef[i]; if (!teamDef->armour) continue; for (j = 0; j < csi.numODs; j++) { const objDef_t *od = INVSH_GetItemByIDX(j); if (!INV_IsArmour(od)) continue; /* not for this team */ if (!CHRSH_IsArmourUseableForTeam(od, teamDef)) continue; if (!LIST_ContainsString(armourPaths, od->armourPath)) LIST_AddString(&armourPaths, od->armourPath); } UFO_CU_ASSERT_TRUE_MSG(!LIST_IsEmpty(armourPaths), va("no armour definitions found for team %s - but armour is set to true", teamDef->id)); LIST_Foreach(armourPaths, char const, armourPath) { int l; for (l = NAME_NEUTRAL; l < NAME_LAST; l++) { /* no models for this gender */ if (!teamDef->numModels[l]) continue; CU_ASSERT_PTR_NOT_NULL_FATAL(teamDef->models[l]); for (linkedList_t const* list = teamDef->models[l]; list; list = list->next) { teamDef_t::model_t const& m = *static_cast<teamDef_t::model_t const*>(list->data); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s/%s", m.path, m.body)), va("%s does not exist in models/%s (teamDef: %s)", m.body, m.path, teamDef->id)); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s%s/%s", m.path, armourPath, m.body)), va("%s does not exist in models/%s%s (teamDef: %s)", m.body, m.path, armourPath, teamDef->id)); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s/%s", m.path, m.head)), va("%s does not exist in models/%s (teamDef: %s)", m.head, m.path, teamDef->id)); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s%s/%s", m.path, armourPath, m.head)), va("%s does not exist in models/%s%s (teamDef: %s)", m.head, m.path, armourPath, teamDef->id)); } } } LIST_Delete(&armourPaths); }
static inline void CLMN_AddBindings (linkedList_t **list, char **bindings) { int i; for (i = K_FIRST_KEY; i < K_LAST_KEY; i++) if (bindings[i] && bindings[i][0] != '\0') { const char *binding = Cmd_GetCommandDesc(bindings[i]); if (binding != NULL && binding[0] != '\0') binding = _(binding); LIST_AddString(list, va("%s\t%s", Key_KeynumToString(i), binding)); } }
/** * @brief Display the popup_homebase * @param[in] aircraft Pointer to aircraft we want to change homebase. * @param[in] alwaysDisplay False if popup should be displayed only if at least one base is available. * @return true if popup is displayed. */ qboolean CL_DisplayHomebasePopup (aircraft_t *aircraft, qboolean alwaysDisplay) { int homebase; int numAvailableBases = 0; baseCapacities_t capacity; linkedList_t* popupListText = NULL; base_t *base; assert(aircraft); capacity = AIR_GetCapacityByAircraftWeight(aircraft); LIST_Delete(&popupListData); popupNum = 0; homebase = -1; base = NULL; while ((base = B_GetNext(base)) != NULL) { char text[MAX_VAR]; char const* msg; if (base == aircraft->homebase) { msg = _("current homebase of aircraft"); LIST_Add(&popupListData, (byte *)&INVALID_BASE, sizeof(int)); homebase = popupNum; } else { msg = AIR_CheckMoveIntoNewHomebase(aircraft, base, capacity); if (!msg) { msg = _("base can hold aircraft"); LIST_Add(&popupListData, (byte *)&base->idx, sizeof(int)); numAvailableBases++; } else { LIST_Add(&popupListData, (byte *)&INVALID_BASE, sizeof(int)); } } Com_sprintf(text, sizeof(text), "%s\t%s", base->name, msg); LIST_AddString(&popupListText, text); popupNum++; } if (alwaysDisplay || numAvailableBases > 0) { CL_GameTimeStop(); popupListNode = UI_PopupList(_("Change homebase of aircraft"), _("Base\tStatus"), popupListText, "change_homebase <lineselected>;"); VectorSet(popupListNode->selectedColor, 0.0, 0.78, 0.0); /**< Set color for selected entry. */ popupListNode->selectedColor[3] = 1.0; UI_TextNodeSelectLine(popupListNode, homebase); MAP_SelectAircraft(aircraft); return qtrue; } return qfalse; }
static void UI_TextNodeGenerateLineSplit (uiNode_t* node) { const char* data; int bufferSize = 1024; char* buffer = Mem_AllocTypeN(char, bufferSize); LIST_Delete(&EXTRADATA(node).lineSplit); if (node->text != nullptr) data = UI_GetReferenceString(node, node->text); else if (EXTRADATA(node).super.dataID != TEXT_NULL) { const uiSharedData_t* shared; shared = &ui_global.sharedData[EXTRADATA(node).super.dataID]; switch (shared->type) { case UI_SHARED_TEXT: data = UI_GetText(EXTRADATA(node).super.dataID); break; case UI_SHARED_LINKEDLISTTEXT: return; default: return; } } else return; data = CL_Translate(data); while (data[0] != '\0') { const char* next = strchr(data, '\n'); int lineSize; if (next == nullptr) lineSize = strlen(data); else lineSize = next - data; if (lineSize + 1 > bufferSize) { bufferSize = lineSize + 1; Mem_Free(buffer); buffer = Mem_AllocTypeN(char, bufferSize); } Q_strncpyz(buffer, data, lineSize + 1); LIST_AddString(&EXTRADATA(node).lineSplit, buffer); if (next == nullptr) break; data = next + 1; }
/** * @brief Console function to push a window onto the window stack * @sa UI_PushWindow */ static void UI_PushWindow_f (void) { linkedList_t *params = NULL; int i; if (Cmd_Argc() == 0) { Com_Printf("Usage: %s <name> <params>\n", Cmd_Argv(0)); return; } for (i = 2; i < Cmd_Argc(); i++) { LIST_AddString(¶ms, Cmd_Argv(i)); } UI_PushWindow(Cmd_Argv(1), NULL, params); LIST_Delete(¶ms); }
/** * @brief Adds UI Keybindings to the list for the Keylist UI * @param[in,out] list Linked list of strings to add to */ static inline void CLMN_AddUIBindings (linkedList_t **list) { int i; for (i = 0; i < UI_GetKeyBindingCount(); i++) { const uiKeyBinding_t* binding = UI_GetKeyBindingByIndex(i); if (binding == NULL) continue; if (binding->inherited) continue; if (!Q_strvalid(binding->description)) continue; LIST_AddString(list, va("%s\t%s", Key_KeynumToString(binding->key), _(binding->description))); } }
/** * Updates the material editor node for a given image and a given material stage * @param image The image to load into the material editor * @param materialStage The material stage to display */ static void UI_MaterialEditorUpdate (image_t *image, materialStage_t *materialStage) { linkedList_t *materialStagesList = NULL; if (image->normalmap == NULL) UI_ExecuteConfunc("hideshaders true 0 0 0 0"); else UI_ExecuteConfunc("hideshaders false %f %f %f %f", image->material.bump, image->material.hardness, image->material.parallax, image->material.specular); if (image->normalmap == NULL) Cvar_Set("me_imagename", image->name); else Cvar_Set("me_imagename", va("%s (nm)", image->name)); if (!image->material.num_stages) { UI_ExecuteConfunc("hidestages true"); } else { int i; if (materialStage) { const char *stageType = Cvar_GetString("me_stagetype"); if (stageType[0] == '\0') stageType = "stretch"; UI_ExecuteConfunc("hidestages false %s", stageType); } else Cvar_Set("me_stage_id", "-1"); for (i = 0; i < image->material.num_stages; i++) { const materialStage_t *stage = UI_MaterialEditorGetStage(&image->material, i); char stageName[MAX_VAR] = "stage "; if (stage == materialStage) { UI_ExecuteConfunc("updatestagevalues %f %f %f %f %f %f %f %f %f %f %f %f %f %f", stage->rotate.hz, stage->rotate.deg, stage->stretch.hz, stage->stretch.dhz, stage->stretch.amp, stage->stretch.damp, stage->pulse.hz, stage->pulse.dhz, stage->scroll.ds, stage->scroll.dt, stage->scroll.s, stage->scroll.t, stage->scale.s, stage->scale.t); } UI_MaterialEditorStagesToName(stage, stageName, sizeof(stageName) - 1); LIST_AddString(&materialStagesList, stageName); } } UI_RegisterLinkedListText(TEXT_MATERIAL_STAGES, materialStagesList); }
void Sys_ListFilteredFiles (const char *basedir, const char *subdirs, const char *filter, linkedList_t **list) { char search[MAX_OSPATH], newsubdirs[MAX_OSPATH]; char filename[MAX_OSPATH]; DIR *directory; struct dirent *d; struct stat st; if (subdirs[0] != '\0') { Com_sprintf(search, sizeof(search), "%s/%s", basedir, subdirs); } else { Com_sprintf(search, sizeof(search), "%s", basedir); } if ((directory = opendir(search)) == NULL) return; while ((d = readdir(directory)) != NULL) { Com_sprintf(filename, sizeof(filename), "%s/%s", search, d->d_name); if (stat(filename, &st) == -1) continue; if (st.st_mode & S_IFDIR) { if (Q_strcasecmp(d->d_name, ".") && Q_strcasecmp(d->d_name, "..")) { if (subdirs[0] != '\0') { Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s/%s", subdirs, d->d_name); } else { Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s", d->d_name); } Sys_ListFilteredFiles(basedir, newsubdirs, filter, list); } } Com_sprintf(filename, sizeof(filename), "%s/%s", subdirs, d->d_name); if (!Com_Filter(filter, filename)) continue; LIST_AddString(list, filename); } closedir(directory); }
/** * @brief Update the list of item you can choose * @param[in] slot Pointer to aircraftSlot where items can be equiped */ static void AIM_UpdateAircraftItemList (const aircraftSlot_t *slot) { linkedList_t *amountList = NULL; technology_t **techList; technology_t **currentTech; const base_t *base = slot->aircraft->homebase; int count = 0; uiNode_t *AIM_items = NULL; /* Add all items corresponding to airequipID to list */ techList = AII_GetCraftitemTechsByType(airequipID); /* Count only those which are researched to buffer */ currentTech = techList; while (*currentTech) { if (AIM_CrafttypeFilter(base, airequipID, *currentTech)) count++; currentTech++; } /* List only those which are researched to buffer */ currentTech = techList; while (*currentTech) { if (AIM_CrafttypeFilter(base, airequipID, *currentTech)) { uiNode_t *option; const objDef_t *item = INVSH_GetItemByID((*currentTech)->provides); const int amount = B_ItemInBase(item, base); LIST_AddString(&amountList, va("%d", amount)); option = cgi->UI_AddOption(&AIM_items, (*currentTech)->name, _((*currentTech)->name), va("%d", (*currentTech)->idx)); if (!AIM_SelectableCraftItem(slot, *currentTech)) option->disabled = true; } currentTech++; } cgi->UI_RegisterOption(TEXT_LIST, AIM_items); cgi->UI_RegisterLinkedListText(TEXT_LIST2, amountList); }
void Sys_ListFilteredFiles (const char* basedir, const char* subdirs, const char* filter, linkedList_t** list) { char search[MAX_OSPATH], newsubdirs[MAX_OSPATH]; char filename[MAX_OSPATH]; int findhandle; struct _wfinddata_t findinfo; if (subdirs[0] != '\0') { Com_sprintf(search, sizeof(search), "%s\\%s\\*", basedir, subdirs); } else { Com_sprintf(search, sizeof(search), "%s\\*", basedir); } Sys_Utf8ToUtf16(search, wfindpath, lengthof(wfindpath)); findhandle = _wfindfirst(wfindpath, &findinfo); if (findhandle == -1) return; do { Sys_Utf16ToUtf8(findinfo.name, findname, sizeof(findname)); if (findinfo.attrib & _A_SUBDIR) { if (Q_strcasecmp(findname, ".") && Q_strcasecmp(findname, "..")) { if (subdirs[0] != '\0') { Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s\\%s", subdirs, findname); } else { Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s", findname); } Sys_ListFilteredFiles(basedir, newsubdirs, filter, list); } } Com_sprintf(filename, sizeof(filename), "%s\\%s", subdirs, findname); if (!Com_Filter(filter, filename)) continue; LIST_AddString(list, filename); } while (_wfindnext(findhandle, &findinfo) != -1); _findclose(findhandle); }
static void testTeamDefsModelScriptData (void) { int i; linkedList_t *armourPaths = NULL; for (i = 0; i < csi.numTeamDefs; i++) { int j; const teamDef_t *teamDef = &csi.teamDef[i]; if (!teamDef->armour) continue; for (j = 0; j < csi.numODs; j++) { const objDef_t *od = INVSH_GetItemByIDX(j); if (!INV_IsArmour(od)) continue; /* not for this team */ if (!CHRSH_IsArmourUseableForTeam(od, teamDef)) continue; if (!LIST_ContainsString(armourPaths, od->armourPath)) LIST_AddString(&armourPaths, od->armourPath); } UFO_CU_ASSERT_TRUE_MSG(!LIST_IsEmpty(armourPaths), va("no armour definitions found for team %s - but armour is set to true", teamDef->id)); LIST_Foreach(armourPaths, char const, armourPath) { nametypes_t l; for (l = NAME_NEUTRAL; l < NAME_LAST; l++) { linkedList_t *list = teamDef->models[l]; int k; /* no models for this gender */ if (!teamDef->numModels[l]) continue; CU_ASSERT_PTR_NOT_NULL(list); for (k = 0; k < teamDef->numModels[l]; k++) { const char *path; CU_ASSERT_PTR_NOT_NULL_FATAL(list); path = (const char*)list->data; /* body */ list = list->next; CU_ASSERT_PTR_NOT_NULL_FATAL(list); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s/%s", path, list->data)), va("%s does not exist in models/%s (teamDef: %s)", list->data, path, teamDef->id)); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s%s/%s", path, armourPath, list->data)), va("%s does not exist in models/%s%s (teamDef: %s)", list->data, path, armourPath, teamDef->id)); list = list->next; CU_ASSERT_PTR_NOT_NULL_FATAL(list); /* head */ UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s/%s", path, list->data)), va("%s does not exist in models/%s (teamDef: %s)", list->data, path, teamDef->id)); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s%s/%s", path, armourPath, list->data)), va("%s does not exist in models/%s%s (teamDef: %s)", list->data, path, armourPath, teamDef->id)); /* skip skin */ /** @todo check that the skin is valid for the given model */ list = list->next; CU_ASSERT_PTR_NOT_NULL_FATAL(list); /* new path */ list = list->next; } } } LIST_Delete(&armourPaths); }
static inline void UI_ExecuteCallAction (const uiAction_t* action, const uiCallContext_t *context) { uiNode_t* callNode = NULL; uiAction_t* param; uiAction_t* left = action->d.nonTerminal.left; uiCallContext_t newContext; const value_t* callProperty = NULL; const char* path = left->d.terminal.d1.constString; if (left->type == EA_VALUE_PATHPROPERTY || left->type == EA_VALUE_PATHNODE) path = left->d.terminal.d1.constString; else if (left->type == EA_VALUE_PATHPROPERTY_WITHINJECTION || left->type == EA_VALUE_PATHNODE_WITHINJECTION) path = UI_GenInjectedString(left->d.terminal.d1.constString, false, context); UI_ReadNodePath(path, context->source, &callNode, &callProperty); if (callNode == NULL) { Com_Printf("UI_ExecuteCallAction: Node from path \"%s\" not found (relative to \"%s\").\n", path, UI_GetPath(context->source)); return; } if (callProperty != NULL && callProperty->type != V_UI_ACTION && callProperty->type != V_UI_NODEMETHOD) { Com_Printf("UI_ExecuteCallAction: Call operand %d unsupported. (%s)\n", callProperty->type, UI_GetPath(callNode)); return; } newContext.source = callNode; newContext.params = NULL; newContext.paramNumber = 0; newContext.varNumber = 0; newContext.varPosition = context->varPosition + context->varNumber; if (action->type == EA_LISTENER) { newContext.useCmdParam = context->useCmdParam; if (!newContext.useCmdParam) { linkedList_t *p = context->params; while (p) { const char* value = (char*) p->data; LIST_AddString(&newContext.params, value); newContext.paramNumber++; p = p->next; } } } else { newContext.useCmdParam = false; param = action->d.nonTerminal.right; while (param) { const char* value; value = UI_GetStringFromExpression(param, context); LIST_AddString(&newContext.params, value); newContext.paramNumber++; param = param->next; } } if (callProperty == NULL || callProperty->type == V_UI_ACTION) { uiAction_t const* const actionsRef = callProperty ? Com_GetValue<uiAction_t*>(callNode, callProperty) : callNode->onClick; UI_ExecuteActions(actionsRef, &newContext); } else if (callProperty->type == V_UI_NODEMETHOD) { uiNodeMethod_t func = (uiNodeMethod_t) callProperty->ofs; func(callNode, &newContext); } else { /* unreachable, already checked few line before */ assert(false); } LIST_Delete(&newContext.params); }
/** * @sa CL_ParseScriptFirst */ static void CP_ParseAlienTeam (const char *name, const char **text) { const char *errhead = "CP_ParseAlienTeam: unexpected end of file (alienteam "; const char *token; int i; alienTeamCategory_t *alienCategory; /* get it's body */ token = Com_Parse(text); if (!*text || *token != '{') { Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" without body ignored\n", name); return; } if (ccs.numAlienCategories >= ALIENCATEGORY_MAX) { Com_Printf("CP_ParseAlienTeam: maximum number of alien team category reached (%i)\n", ALIENCATEGORY_MAX); return; } /* search for category with same name */ for (i = 0; i < ccs.numAlienCategories; i++) if (Q_streq(name, ccs.alienCategories[i].id)) break; if (i < ccs.numAlienCategories) { Com_Printf("CP_ParseAlienTeam: alien category def \"%s\" with same name found, second ignored\n", name); return; } alienCategory = &ccs.alienCategories[ccs.numAlienCategories++]; Q_strncpyz(alienCategory->id, name, sizeof(alienCategory->id)); do { token = Com_EParse(text, errhead, name); if (!*text) break; if (*token == '}') break; if (Q_streq(token, "equipment")) { linkedList_t **list = &alienCategory->equipment; token = Com_EParse(text, errhead, name); if (!*text || *token != '{') { Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" has equipment with no opening brace\n", name); break; } do { token = Com_EParse(text, errhead, name); if (!*text || *token == '}') break; LIST_AddString(list, token); } while (*text); } else if (Q_streq(token, "category")) { token = Com_EParse(text, errhead, name); if (!*text || *token != '{') { Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" has category with no opening brace\n", name); break; } do { token = Com_EParse(text, errhead, name); if (!*text || *token == '}') break; alienCategory->missionCategories[alienCategory->numMissionCategories] = CP_GetAlienMissionTypeByID(token); if (alienCategory->missionCategories[alienCategory->numMissionCategories] == INTERESTCATEGORY_NONE) Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" is used with no mission category. It won't be used in game.\n", name); alienCategory->numMissionCategories++; } while (*text); } else if (Q_streq(token, "team")) { alienTeamGroup_t *group; token = Com_EParse(text, errhead, name); if (!*text || *token != '{') { Com_Printf("CP_ParseAlienTeam: alien team \"%s\" has team with no opening brace\n", name); break; } if (alienCategory->numAlienTeamGroups >= MAX_ALIEN_GROUP_PER_CATEGORY) { Com_Printf("CP_ParseAlienTeam: maximum number of alien team reached (%i) in category \"%s\"\n", MAX_ALIEN_GROUP_PER_CATEGORY, name); break; } group = &alienCategory->alienTeamGroups[alienCategory->numAlienTeamGroups]; group->idx = alienCategory->numAlienTeamGroups; group->categoryIdx = alienCategory - ccs.alienCategories; alienCategory->numAlienTeamGroups++; do { token = Com_EParse(text, errhead, name); if (!Com_ParseBlockToken(name, text, group, alien_group_vals, cp_campaignPool, token)) { const teamDef_t *teamDef; if (!*text || *token == '}') break; /* This is an alien team */ if (group->numAlienTeams >= MAX_TEAMS_PER_MISSION) Com_Error(ERR_DROP, "CL_ParseAlienTeam: MAX_TEAMS_PER_MISSION hit"); teamDef = Com_GetTeamDefinitionByID(token); if (teamDef) group->alienTeams[group->numAlienTeams++] = teamDef; } } while (*text); } else { Com_Printf("CP_ParseAlienTeam: unknown token \"%s\" ignored (category %s)\n", token, name); continue; } } while (*text); if (LIST_IsEmpty(alienCategory->equipment)) Sys_Error("alien category equipment list is empty"); }
static inline void UI_ExecuteCallAction (const uiAction_t* action, const uiCallContext_t* context) { uiNode_t* callNode = nullptr; uiAction_t* param; uiAction_t* left = action->d.nonTerminal.left; uiCallContext_t newContext; const value_t* callProperty = nullptr; value_t luaMethod; const char* path = left->d.terminal.d1.constString; // clear luaMethod structure before using it memset(&luaMethod, 0, sizeof(luaMethod)); if (left->type == EA_VALUE_PATHPROPERTY || left->type == EA_VALUE_PATHNODE) path = left->d.terminal.d1.constString; else if (left->type == EA_VALUE_PATHPROPERTY_WITHINJECTION || left->type == EA_VALUE_PATHNODE_WITHINJECTION) path = UI_GenInjectedString(left->d.terminal.d1.constString, false, context); UI_ReadNodePath(path, context->source, context->tagNode, &callNode, &callProperty, &luaMethod); if ((callNode == nullptr) && (!luaMethod.type)) { Com_Printf("UI_ExecuteCallAction: Node from path \"%s\" not found (relative to \"%s\").\n", path, UI_GetPath(context->source)); return; } if (callProperty != nullptr && callProperty->type != V_UI_ACTION && callProperty->type != V_UI_NODEMETHOD && callProperty->type != V_UI_NODEMETHOD_LUA) { Com_Printf("UI_ExecuteCallAction: Call operand %d unsupported. (%s)\n", callProperty->type, UI_GetPath(callNode)); return; } newContext.source = callNode; newContext.params = nullptr; newContext.paramNumber = 0; newContext.varNumber = 0; newContext.varPosition = context->varPosition + context->varNumber; newContext.breakLoop = false; if (action->type == EA_LISTENER) { newContext.useCmdParam = context->useCmdParam; if (!newContext.useCmdParam) { linkedList_t* p = context->params; while (p) { const char* value = (char*) p->data; LIST_AddString(&newContext.params, value); newContext.paramNumber++; p = p->next; } } } else { newContext.useCmdParam = false; param = action->d.nonTerminal.right; while (param) { const char* value; value = UI_GetStringFromExpression(param, context); LIST_AddString(&newContext.params, value); newContext.paramNumber++; param = param->next; } } if (luaMethod.type == V_UI_NODEMETHOD_LUA) { UI_ExecuteLuaMethod(callNode, luaMethod.ofs, newContext.params, newContext.paramNumber); Mem_Free(const_cast<char*>(luaMethod.string)); } else if (callProperty == nullptr || callProperty->type == V_UI_ACTION) { uiAction_t const* const actionsRef = callProperty ? Com_GetValue<uiAction_t*>(callNode, callProperty) : callNode->onClick; if (actionsRef) UI_ExecuteActions(actionsRef, &newContext); if (callNode->lua_onClick != LUA_NOREF) UI_ExecuteLuaMethod(callNode, callNode->lua_onClick, newContext.params, newContext.paramNumber); } else if (callProperty->type == V_UI_NODEMETHOD) { uiNodeMethod_t func = (uiNodeMethod_t) callProperty->ofs; func(callNode, &newContext); } else { /* unreachable, already checked few line before */ assert(false); } LIST_Delete(&newContext.params); }
/** * @brief Prints a list of tab and newline separated string to keylist char array that hold the key and the command desc */ static void CLMN_InitKeyList_f (void) { linkedList_t *list = NULL; LIST_AddString(&list, _("^BGlobal bindings")); LIST_AddString(&list, ""); CLMN_AddBindings(&list, keyBindings); LIST_AddString(&list, ""); LIST_AddString(&list, ""); LIST_AddString(&list, _("^BMenu bindings")); LIST_AddString(&list, ""); CLMN_AddBindings(&list, menuKeyBindings); LIST_AddString(&list, ""); LIST_AddString(&list, ""); LIST_AddString(&list, _("^BBattlescape bindings")); LIST_AddString(&list, ""); CLMN_AddBindings(&list, battleKeyBindings); LIST_AddString(&list, ""); LIST_AddString(&list, ""); LIST_AddString(&list, _("^BUI bindings")); LIST_AddString(&list, ""); CLMN_AddUIBindings(&list); UI_RegisterLinkedListText(TEXT_LIST, list); }