/** * @brief Init function for Buy/Sell menu. */ static void BS_BuyType_f (void) { base_t *base = B_GetCurrentSelectedBase(); if (Cmd_Argc() == 2) { buyCat = INV_GetFilterTypeID(Cmd_Argv(1)); if (buyCat == FILTER_DISASSEMBLY) buyCat--; if (buyCat < 0) { buyCat = MAX_FILTERTYPES - 1; if (buyCat == FILTER_DISASSEMBLY) buyCat--; } else if (buyCat >= MAX_FILTERTYPES) { buyCat = 0; } Cvar_Set("mn_itemtype", INV_GetFilterType(buyCat)); currentSelectedMenuEntry = NULL; } BS_BuyType(base); buyList.scroll = 0; UI_ExecuteConfunc("sync_market_scroll 0 %d", buyList.scroll); UI_ExecuteConfunc("market_scroll %d", buyList.scroll); UI_ExecuteConfunc("market_click 0"); }
void CL_ActorStateChange (const eventRegister_t *self, struct dbuffer *msg) { le_t *le; int entnum, state; character_t *chr; NET_ReadFormat(msg, self->formatString, &entnum, &state); le = LE_Get(entnum); if (!le) LE_NotFoundError(entnum); if (!LE_IsActor(le)) { Com_Printf("StateChange message ignored... LE is no actor (number: %i, state: %i, type: %i)\n", entnum, state, le->type); return; } /* If standing up or crouching down remove the reserved-state for crouching. */ if (((state & STATE_CROUCHED) && !LE_IsCrouched(le)) || (!(state & STATE_CROUCHED) && LE_IsCrouched(le))) { if (CL_ActorUsableTUs(le) < TU_CROUCH && CL_ActorReservedTUs(le, RES_CROUCH) >= TU_CROUCH) { /* We have not enough non-reserved TUs, * but some reserved for crouching/standing up. * i.e. we only reset the reservation for crouching if it's the very last attempt. */ CL_ActorReserveTUs(le, RES_CROUCH, 0); /* Reset reserved TUs (0 TUs) */ } } /* killed by the server: no animation is played, etc. */ if ((state & STATE_DEAD) && LE_IsLivingActor(le)) { le->state = state; FLOOR(le) = NULL; LE_SetThink(le, NULL); VectorCopy(player_dead_maxs, le->maxs); CL_ActorRemoveFromTeamList(le); return; } else { le->state = state; LE_SetThink(le, LET_StartIdle); } /* save those states that the actor should also carry over to other missions */ chr = CL_ActorGetChr(le); if (!chr) return; chr->state = (le->state & STATE_REACTION); /* change reaction button state */ if (!(le->state & STATE_REACTION)) { UI_ExecuteConfunc("disable_reaction"); } else { UI_ExecuteConfunc("startreaction"); } /* state change may have affected move length */ CL_ActorConditionalMoveCalc(le); }
/** * @brief Console callback for handling the web auth * @sa WEB_Auth */ static void WEB_Auth_f (void) { if (Cmd_Argc() != 3) { Com_Printf("Usage: %s <username> <password>\n", Cmd_Argv(0)); return; } if (WEB_Auth(Cmd_Argv(1), Cmd_Argv(2))) { UI_ExecuteConfunc("web_authsuccessful"); } else { UI_ExecuteConfunc("web_authfailed"); } }
/** * @brief Hide the dropship selection or show it with the dropship given in the parameter * @param dropships if @c NULL, the dropship selection panel will be hidden, otherwise it * will be shown with the given list entries as content. */ static inline void GAME_SK_HideDropships (const linkedList_t *dropships) { const qboolean hide = (dropships == NULL); if (hide) { UI_ExecuteConfunc("skirmish_hide_dropships true"); Cvar_Set("rm_drop", ""); } else { const char *rma = Com_GetRandomMapAssemblyNameForCraft((const char *)dropships->data); Cvar_Set("rm_drop", rma); UI_UpdateInvisOptions(UI_GetOption(OPTION_DROPSHIPS), dropships); UI_ExecuteConfunc("skirmish_hide_dropships false"); } }
/** * @brief Hide the ufo selection or show it with the ufos given in the parameter * @param ufos if @c NULL, the ufo selection panel will be hidden, otherwise it * will be shown with the given list entries as content. */ static inline void GAME_SK_HideUFOs (const linkedList_t *ufos) { const qboolean hide = (ufos == NULL); if (hide) { UI_ExecuteConfunc("skirmish_hide_ufos true"); Cvar_Set("rm_ufo", ""); } else { const char *rma = Com_GetRandomMapAssemblyNameForCraft((const char *)ufos->data); Cvar_Set("rm_ufo", rma); UI_UpdateInvisOptions(UI_GetOption(OPTION_UFOS), ufos); UI_ExecuteConfunc("skirmish_hide_ufos false"); } }
/** * @brief Update the GUI by calling a console function * @sa BS_BuyType */ static void BS_UpdateItem (const base_t *base, int itemNum) { int min, max, value; if (BS_GetMinMaxValueByItemID(base, itemNum, &min, &max, &value)) UI_ExecuteConfunc("buy_updateitem %d %d %d %d", itemNum, value, min, max); }
/** * @brief Update the GUI with the selected item */ static void INV_UpdateObject_f (void) { /* check syntax */ if (Cmd_Argc() < 3) { Com_Printf("Usage: %s <objectid> <confunc> [mustwechangetab]\n", Cmd_Argv(0)); return; } bool changeTab = true; if (Cmd_Argc() == 4) changeTab = atoi(Cmd_Argv(3)) >= 1; const int num = atoi(Cmd_Argv(1)); if (num < 0 || num >= csi.numODs) { Com_Printf("Id %i out of range 0..%i\n", num, csi.numODs); return; } const objDef_t* obj = INVSH_GetItemByIDX(num); /* update tab */ if (changeTab) { const cvar_t* var = Cvar_FindVar("mn_equiptype"); const int filter = INV_GetFilterFromItem(obj); if (var && var->integer != filter) { Cvar_SetValue("mn_equiptype", filter); UI_ExecuteConfunc("%s", Cmd_Argv(2)); } } /* update item description */ INV_ItemDescription(obj); }
/** * @brief * @sa BS_MarketClick_f * @sa BS_AddToList */ static void BS_MarketScroll_f (void) { int i; base_t *base = B_GetCurrentSelectedBase(); if (!base || buyCat >= MAX_FILTERTYPES || buyCat < 0) return; if (Cmd_Argc() < 2) { Com_Printf("Usage: %s <scrollpos>\n", Cmd_Argv(0)); return; } buyList.scroll = atoi(Cmd_Argv(1)); assert(buyList.scroll >= 0); assert(!((buyList.length > MAX_MARKET_MENU_ENTRIES && buyList.scroll >= buyList.length - MAX_MARKET_MENU_ENTRIES))); /* now update the menu pics */ for (i = 0; i < MAX_MARKET_MENU_ENTRIES; i++) { UI_ExecuteConfunc("buy_autoselli %i", i); } /* get item list */ for (i = buyList.scroll; i < buyList.length - buyList.scroll; i++) { const objDef_t *od = BS_GetObjectDefition(&buyList.l[i]); if (i >= MAX_MARKET_MENU_ENTRIES) break; /* Check whether the item matches the proper filter, storage in current base and market. */ if (od && (B_ItemInBase(od, base) > 0 || ccs.eMarket.numItems[od->idx]) && INV_ItemMatchesFilter(od, buyCat)) { const technology_t *tech = RS_GetTechForItem(od); UI_ExecuteConfunc("buy_show %i", i - buyList.scroll); BS_UpdateItem(base, i - buyList.scroll); /* autosell setting */ if (!RS_IsResearched_ptr(tech)) continue; if (ccs.eMarket.autosell[od->idx]) UI_ExecuteConfunc("buy_autoselle %i", i - buyList.scroll); else UI_ExecuteConfunc("buy_autoselld %i", i - buyList.scroll); } } }
/** * @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) { UI_ExecuteConfunc("keybinding_clear"); CLMN_AddBindings(KEYSPACE_GAME, keyBindings); CLMN_AddBindings(KEYSPACE_UI, menuKeyBindings); const int uiBindings = CLMN_AddUIBindings(KEYSPACE_UI); CLMN_AddBindings(KEYSPACE_BATTLE, battleKeyBindings, uiBindings); }
/** * @brief Sets aircraftCurrent and updates related cvars and menutexts. * @param[in] aircraft Pointer to given aircraft that should be selected in the menu. */ void AIR_AircraftSelect (aircraft_t* aircraft) { static char aircraftInfo[256]; base_t *base; int id; if (aircraft != NULL) base = aircraft->homebase; else base = NULL; if (!AIR_BaseHasAircraft(base)) { UI_ResetData(TEXT_AIRCRAFT_INFO); return; } assert(aircraft); assert(aircraft->homebase == base); CP_UpdateActorAircraftVar(aircraft, EMPL_SOLDIER); Cvar_SetValue("mn_equipsoldierstate", CL_EquipSoldierState(aircraft)); Cvar_Set("mn_aircraftstatus", AIR_AircraftStatusToName(aircraft)); Cvar_Set("mn_aircraftinbase", AIR_IsAircraftInBase(aircraft) ? "1" : "0"); Cvar_Set("mn_aircraftname", aircraft->name); if (!aircraft->tech) Com_Error(ERR_DROP, "No technology assigned to aircraft '%s'", aircraft->id); Cvar_Set("mn_aircraft_model", aircraft->tech->mdl); Cvar_Set("mn_aircraft_health", va("%3.0f" , aircraft->stats[AIR_STATS_DAMAGE] > 0 ? (double)aircraft->damage * 100 / aircraft->stats[AIR_STATS_DAMAGE] : 0)); /* generate aircraft info text */ Com_sprintf(aircraftInfo, sizeof(aircraftInfo), _("Speed:\t%i km/h\n"), AIR_AircraftMenuStatsValues(aircraft->stats[AIR_STATS_SPEED], AIR_STATS_SPEED)); Q_strcat(aircraftInfo, va(_("Fuel:\t%i/%i\n"), AIR_AircraftMenuStatsValues(aircraft->fuel, AIR_STATS_FUELSIZE), AIR_AircraftMenuStatsValues(aircraft->stats[AIR_STATS_FUELSIZE], AIR_STATS_FUELSIZE)), sizeof(aircraftInfo)); Q_strcat(aircraftInfo, va(_("Operational range:\t%i km\n"), AIR_GetOperationRange(aircraft)), sizeof(aircraftInfo)); Q_strcat(aircraftInfo, va(_("Weapons:\t%i on %i\n"), AIR_GetSlotItems(AC_ITEM_WEAPON, aircraft), aircraft->maxWeapons), sizeof(aircraftInfo)); Q_strcat(aircraftInfo, va(_("Armour:\t%i on 1\n"), AIR_GetSlotItems(AC_ITEM_SHIELD, aircraft)), sizeof(aircraftInfo)); Q_strcat(aircraftInfo, va(_("Electronics:\t%i on %i"), AIR_GetSlotItems(AC_ITEM_ELECTRONICS, aircraft), aircraft->maxElectronics), sizeof(aircraftInfo)); UI_RegisterText(TEXT_AIRCRAFT_INFO, aircraftInfo); /** @todo This shouldn't exists. UI should use the global idx as reference */ /* compute the ID and... */ id = 0; AIR_ForeachFromBase(aircraftInBase, base) { if (aircraft == aircraftInBase) break; id++; } base->aircraftCurrent = aircraft; Cvar_SetValue("mn_aircraft_id", id); /* ...update the GUI */ UI_ExecuteConfunc("aircraft_change %i", id); }
/** * 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); }
/** * @sa G_ClientStartMatch * @sa EV_RESET */ void CL_Reset (const eventRegister_t *self, dbuffer *msg) { CL_ActorSelect(nullptr); cl.numTeamList = 0; /* set the active player */ NET_ReadFormat(msg, self->formatString, &cls.team, &cl.actTeam); Com_Printf("(player %i) It's team %i's turn!\n", cl.pnum, cl.actTeam); CL_CompleteRecalcRouting(); UI_ExecuteConfunc("disable_rescuezone"); if (cls.isOurRound()) UI_ExecuteConfunc("startround"); else Com_Printf("You lost the coin-toss for first-turn.\n"); }
static inline void CLMN_AddBindings (keyBindSpace_t scope, char** bindings, int offset = 0) { for (int i = K_FIRST_KEY; i < K_LAST_KEY; i++) { if (Q_strnull(bindings[i])) continue; const char* binding = Cmd_GetCommandDesc(bindings[i]); if (Q_strvalid(binding)) binding = _(binding); UI_ExecuteConfunc("keybinding_add %i %i \"%s\" \"%s\"", i + offset, scope, Key_KeynumToString(i), binding); } }
/** * @brief This is called if actors are spawned (or at least the spawning commands were send to * the server). This callback can e.g. be used to set initial actor states. E.g. request crouch and so on. * These events are executed without consuming time */ static void GAME_InitializeBattlescape (chrList_t *team) { int i; const cgame_export_t *list = GAME_GetCurrentType(); for (i = 0; i < lengthof(cl.teamList); i++) { UI_ExecuteConfunc("huddisable %i", i); } if (list && list->InitializeBattlescape) list->InitializeBattlescape(team); }
/** * @brief Reads the comments from team files */ void GAME_TeamSlotComments_f (void) { UI_ExecuteConfunc("teamsaveslotsclear"); char relSavePath[MAX_OSPATH]; GAME_GetRelativeSavePath(relSavePath, sizeof(relSavePath)); char pattern[MAX_OSPATH]; Q_strncpyz(pattern, relSavePath, sizeof(pattern)); Q_strcat(pattern, sizeof(pattern), "*.mpt"); FS_BuildFileList(pattern); int i = 0; const char* filename; while ((filename = FS_NextFileFromFileList(pattern)) != nullptr) { ScopedFile f; const char* savePath = va("%s/%s", relSavePath, filename); FS_OpenFile(savePath, &f, FILE_READ); if (!f) { Com_Printf("Warning: Could not open '%s'\n", filename); continue; } teamSaveFileHeader_t header; const int clen = sizeof(header); if (FS_Read(&header, clen, &f) != clen) { Com_Printf("Warning: Could not read %i bytes from savefile\n", clen); continue; } if (LittleLong(header.version) != TEAM_SAVE_FILE_VERSION) { Com_Printf("Warning: Version mismatch in '%s'\n", filename); continue; } char absSavePath[MAX_OSPATH]; GAME_GetAbsoluteSavePath(absSavePath, sizeof(absSavePath)); const bool uploadable = FS_FileExists("%s/%s", absSavePath, filename); UI_ExecuteConfunc("teamsaveslotadd %i \"%s\" \"%s\" %i %i", i++, filename, header.name, LittleLong(header.soldiercount), uploadable ? 1 : 0); } FS_NextFileFromFileList(nullptr); }
/** * @brief Update the equipment weight for the selected actor. */ static void INV_UpdateActorLoad_f (void) { if (Cmd_Argc() < 2) { Com_Printf("Usage: %s <callback>\n", Cmd_Argv(0)); return; } const character_t* chr = GAME_GetSelectedChr(); if (chr == nullptr) return; const float invWeight = chr->inv.getWeight(); const int maxWeight = GAME_GetChrMaxLoad(chr); const float penalty = GET_ENCUMBRANCE_PENALTY(invWeight, maxWeight); const int normalTU = GET_TU(chr->score.skills[ABILITY_SPEED], 1.0f - WEIGHT_NORMAL_PENALTY); const int tus = GET_TU(chr->score.skills[ABILITY_SPEED], penalty); const int tuPenalty = tus - normalTU; int count = 0; const Container* cont = nullptr; while ((cont = chr->inv.getNextCont(cont))) { if (cont->def()->temp) continue; for (Item* invList = cont->_invList, *next; invList; invList = next) { next = invList->getNext(); const fireDef_t* fireDef = invList->getFiredefs(); if (fireDef == nullptr) continue; for (int i = 0; i < MAX_FIREDEFS_PER_WEAPON; i++) { if (fireDef[i].time <= 0) continue; if (fireDef[i].time <= tus) continue; if (count <= 0) Com_sprintf(popupText, sizeof(popupText), _("This soldier no longer has enough TUs to use the following items:\n\n")); Q_strcat(popupText, sizeof(popupText), "%s: %s (%i)\n", _(invList->def()->name), _(fireDef[i].name), fireDef[i].time); ++count; } } } if ((Cmd_Argc() < 3 || atoi(Cmd_Argv(2)) == 0) && count > 0) UI_Popup(_("Warning"), popupText); char label[MAX_VAR]; char tooltip[MAX_VAR]; Com_sprintf(label, sizeof(label), "%g/%i %s %s", invWeight / WEIGHT_FACTOR, maxWeight, _("Kg"), (count > 0 ? _("Warning!") : "")); Com_sprintf(tooltip, sizeof(tooltip), "%s %i (%+i)", _("TU:"), tus, tuPenalty); UI_ExecuteConfunc("%s \"%s\" \"%s\" %f %i", Cmd_Argv(1), label, tooltip, WEIGHT_NORMAL_PENALTY - (1.0f - penalty), count); }
/** * @brief Performs end-of-turn processing. * @param[in] self Pointer to the event structure that is currently executed * @param[in] msg The netchannel message * @sa CL_EndRoundAnnounce */ void CL_DoEndRound (const eventRegister_t* self, dbuffer* msg) { /* hud changes */ if (cls.isOurRound()) UI_ExecuteConfunc("endround"); refdef.rendererFlags &= ~RDF_IRGOGGLES; /* change active player */ Com_Printf("Team %i ended round\n", cl.actTeam); cl.actTeam = NET_ReadByte(msg); Com_Printf("Team %i's round started!\n", cl.actTeam); /* hud changes */ if (cls.isOurRound()) { /* check whether a particle has to go */ CL_ParticleCheckRounds(); UI_ExecuteConfunc("startround"); HUD_DisplayMessage(_("Your round started!")); S_StartLocalSample("misc/roundstart", SND_VOLUME_DEFAULT); CL_ActorConditionalMoveCalc(selActor); } }
/** * @brief Network event function for reaction fire target handling. Responsible for updating * the HUD with the information that were received from the server * @param self The event pointer * @param msg The network message to parse the event data from */ void CL_ActorReactionFireRemoveTarget (const eventRegister_t* self, dbuffer* msg) { int shooterEntNum; int targetEntNum; int unused; NET_ReadFormat(msg, self->formatString, &shooterEntNum, &targetEntNum, &unused); const le_t* target = LE_Get(targetEntNum); if (!target) LE_NotFoundError(targetEntNum); UI_ExecuteConfunc("reactionfire_removetarget %i %i", shooterEntNum, target->entnum); }
static void CL_BattlescapeRadarGenPreview_f (void) { int x, y, width, height; /* map to screen */ CL_BattlescapeRadarMapInFrameBuffer(&x, &y, &width, &height); /* from screen to virtual screen */ x /= viddef.rx; width /= viddef.rx; y /= viddef.ry; height /= viddef.ry; y = viddef.virtualHeight - y - height; UI_ExecuteConfunc("mn_radarhud_setmapborder %d %d %d %d", x, y, width, height); }
/** * @brief Adds UI Keybindings to the list for the Keylist UI */ static inline int CLMN_AddUIBindings (keyBindSpace_t scope) { int cnt = 0; const int num = UI_GetKeyBindingCount(); for (int i = 0; i < num; i++) { const uiKeyBinding_t* binding = UI_GetKeyBindingByIndex(i); if (binding == nullptr) continue; if (binding->inherited) continue; if (!Q_strvalid(binding->description)) continue; UI_ExecuteConfunc("keybinding_add %i %i \"%s\" \"%s\"", cnt++, scope, Key_KeynumToString(binding->key), _(binding->description)); } return cnt; }
/** * @brief Sell one item of a given type. * @sa BS_BuyItem_f * @sa BS_SellAircraft_f * @sa BS_BuyAircraft_f */ static void BS_SellItem_f (void) { int num; base_t *base = B_GetCurrentSelectedBase(); if (Cmd_Argc() < 2) { Com_Printf("Usage: %s <num>\n", Cmd_Argv(0)); return; } if (!base) return; if (buyCat == FILTER_AIRCRAFT) { Com_DPrintf(DEBUG_CLIENT, "BS_SellItem_f: Redirects to BS_SellAircraft_f\n"); BS_SellAircraft_f(); return; } num = atoi(Cmd_Argv(1)); if (num < 0 || num >= buyList.length) return; UI_ExecuteConfunc("buy_selectitem %i", num + buyList.scroll); { const objDef_t *item = BS_GetObjectDefition(&buyList.l[num + buyList.scroll]); /* don't sell more items than we have */ const int numItems = min(B_ItemInBase(item, base), BS_GetBuySellFactor()); /* Normal item (or equipment for UGVs/Robots if buyCategory==BUY_HEAVY) */ assert(item); currentSelectedMenuEntry = item; INV_ItemDescription(item); /* don't sell more items than we have */ if (numItems) { /* reinit the menu */ B_UpdateStorageAndCapacity(base, item, -numItems, qfalse); BS_AddItemToMarket(item, numItems); BS_BuyType(base); CP_UpdateCredits(ccs.credits + BS_GetItemSellingPrice(item) * numItems); BS_UpdateItem(base, num); } } }
/** * @brief Network event function for reaction fire mode changes. Responsible for updating * the HUD with the information that were received from the server * @param self The event pointer * @param msg The network message to parse the event data from * @sa HUD_UpdateReactionFiremodes */ void CL_ActorReactionFireChange (const eventRegister_t* self, dbuffer* msg) { actorHands_t hand; int entnum, fmIdx, odIdx; NET_ReadFormat(msg, self->formatString, &entnum, &fmIdx, &hand, &odIdx); const le_t* le = LE_Get(entnum); if (!le) LE_NotFoundError(entnum); character_t* chr = CL_ActorGetChr(le); if (!chr) return; const objDef_t* od = INVSH_GetItemByIDX(odIdx); chr->RFmode.set(hand, fmIdx, od); UI_ExecuteConfunc("reactionfire_updated"); }
/** * @brief Network event function for reaction fire target handling. Responsible for updating * the HUD with the information that were received from the server * @param self The event pointer * @param msg The network message to parse the event data from */ void CL_ActorReactionFireTargetUpdate (const eventRegister_t* self, dbuffer* msg) { int shooterEntNum; int targetEntNum; // if these TUs have arrived at 0, the reaction fire can be triggered int tusUntilTriggered; int unused; NET_ReadFormat(msg, self->formatString, &shooterEntNum, &targetEntNum, &tusUntilTriggered, &unused); const le_t* shooter = LE_Get(shooterEntNum); if (!shooter) LE_NotFoundError(shooterEntNum); const le_t* target = LE_Get(targetEntNum); if (!target) LE_NotFoundError(targetEntNum); const bool outOfRange = CL_ActorIsReactionFireOutOfRange(shooter, target); UI_ExecuteConfunc("reactionfire_updatetarget %i %i %i %i", shooterEntNum, target->entnum, tusUntilTriggered, outOfRange); }
/** * @brief Select one entry on the list. * @sa BS_MarketScroll_f * @sa BS_AddToList */ static void BS_MarketClick_f (void) { int num; if (Cmd_Argc() < 2) { Com_Printf("Usage: %s <num>\n", Cmd_Argv(0)); return; } num = atoi(Cmd_Argv(1)); if (num >= buyList.length || num < 0) return; Cvar_Set("mn_item", ""); switch (buyCat) { case FILTER_AIRCRAFT: assert(buyList.l[num].aircraft); BS_MarketAircraftDescription(buyList.l[num].aircraft->tpl); break; case FILTER_CRAFTITEM: UP_AircraftItemDescription(buyList.l[num].item); Cvar_Set("mn_aircraftname", ""); break; case MAX_FILTERTYPES: break; default: if (buyList.l[num].item->craftitem.type != MAX_ACITEMS) UP_AircraftItemDescription(buyList.l[num].item); else INV_ItemDescription(buyList.l[num].item); currentSelectedMenuEntry = buyList.l[num].item; break; } /* update selected element */ UI_ExecuteConfunc("buy_selectitem %i", num); }
/** * @brief Buy one item of a given type. * @sa BS_SellItem_f * @sa BS_SellAircraft_f * @sa BS_BuyAircraft_f */ static void BS_BuyItem_f (void) { int num; base_t *base = B_GetCurrentSelectedBase(); if (Cmd_Argc() < 2) { Com_Printf("Usage: %s <num>\n", Cmd_Argv(0)); return; } if (!base) return; if (buyCat == FILTER_AIRCRAFT) { Com_DPrintf(DEBUG_CLIENT, "BS_BuyItem_f: Redirects to BS_BuyAircraft_f\n"); BS_BuyAircraft_f(); return; } num = atoi(Cmd_Argv(1)); if (num < 0 || num >= buyList.length) return; UI_ExecuteConfunc("buy_selectitem %i", num + buyList.scroll); { /* Normal item (or equipment for UGVs/Robots if buyCategory==BUY_HEAVY) */ const objDef_t *item = BS_GetObjectDefition(&buyList.l[num + buyList.scroll]); assert(item); currentSelectedMenuEntry = item; INV_ItemDescription(item); Com_DPrintf(DEBUG_CLIENT, "BS_BuyItem_f: item %s\n", item->id); BS_CheckAndDoBuyItem(base, item, BS_GetBuySellFactor()); /* reinit the menu */ BS_BuyType(base); BS_UpdateItem(base, num); } }
/** * @brief Init menu cvar for one savegame slot given by actual index. * @param[in] idx the savegame slot to retrieve gamecomment for * @sa SAV_GameReadGameComments_f */ static void SAV_GameReadGameComment (const int idx) { saveFileHeader_t header; qFILE f; FS_OpenFile(va("save/slot%i.%s", idx, SAVEGAME_EXTENSION), &f, FILE_READ); if (f.f || f.z) { if (FS_Read(&header, sizeof(header), &f) != sizeof(header)) Com_Printf("Warning: Savefile header may be corrupted\n"); header.compressed = LittleLong(header.compressed); header.version = LittleLong(header.version); header.xmlSize = LittleLong(header.xmlSize); header.subsystems = LittleLong(header.subsystems); if (!SAV_VerifyHeader(&header)) Com_Printf("Savegame header for slot%d is corrupted!\n", idx); else UI_ExecuteConfunc("update_save_game_info %i \"%s\" \"%s\" \"%s\"", idx, header.name, header.gameDate, header.realDate); FS_CloseFile(&f); } }
/** * @brief Reads the entity number for client interaction * @sa EV_CLIENT_ACTION * @sa Touch_DoorTrigger * @sa CL_ActorUse * @todo Hud should have a button that should be activated now */ void CL_ActorClientAction (const eventRegister_t *self, dbuffer *msg) { le_t* le; int number, actionEntityNumber; /* read data */ NET_ReadFormat(msg, self->formatString, &number, &actionEntityNumber); /* get actor le */ le = LE_Get(number); if (!le) LE_NotFoundError(number); /* set client action entity */ le->clientAction = LE_Get(actionEntityNumber); if (!le->clientAction) LE_NotFoundError(actionEntityNumber); UI_ExecuteConfunc("enable_clientaction"); Com_DPrintf(DEBUG_CLIENT, "CL_ActorClientAction: Set entity number: %i (for actor with entnum %i)\n", actionEntityNumber, number); }
/** * @brief Prints the description for items (weapons, armour, ...) * @param[in] od The object definition of the item * @note Not only called from UFOpaedia but also from other places to display * weapon and ammo statistics * @todo Do we need to add checks for @c od->isDummy here somewhere? */ void INV_ItemDescription (const objDef_t* od) { static char itemText[UI_MAX_SMALLTEXTLEN]; int i; int count; currentDisplayedObject = od; Cvar_Set("mn_firemodename", ""); Cvar_Set("mn_linkname", ""); if (!od) { /* If nothing selected return */ Cvar_Set("mn_itemname", ""); Cvar_Set("mn_item", ""); UI_ResetData(TEXT_ITEMDESCRIPTION); itemIndex = fireModeIndex = 0; UI_ExecuteConfunc("itemdesc_view 0 0;"); return; } /* select item */ Cvar_Set("mn_itemname", "%s", _(od->name)); Cvar_Set("mn_item", "%s", od->id); count = 0; if (GAME_ItemIsUseable(od)) { if (od->isAmmo()) { /* We display the pre/next buttons for changing weapon only if there are at least 2 researched weapons * we are counting the number of weapons that are usable with this ammo */ for (i = 0; i < od->numWeapons; i++) if (GAME_ItemIsUseable(od->weapons[i])) count++; if (itemIndex >= od->numWeapons || itemIndex < 0) itemIndex = 0; if (count > 0) { while (!GAME_ItemIsUseable(od->weapons[itemIndex])) { itemIndex++; if (itemIndex >= od->numWeapons) itemIndex = 0; } Cvar_ForceSet("mn_linkname", _(od->weapons[itemIndex]->name)); } } else if (od->weapon) { /* We display the pre/next buttons for changing ammo only if there are at least 2 researched ammo * we are counting the number of ammo that is usable with this weapon */ for (i = 0; i < od->numAmmos; i++) if (GAME_ItemIsUseable(od->ammos[i])) count++; if (itemIndex >= od->numAmmos || itemIndex < 0) itemIndex = 0; /* Only display ammos if at least one has been researched */ if (count > 0) { /* We have a weapon that uses ammos */ while (!GAME_ItemIsUseable(od->ammos[itemIndex])) { itemIndex++; if (itemIndex >= od->numAmmos) itemIndex = 0; } Cvar_ForceSet("mn_linkname", _(od->ammos[itemIndex]->name)); } } else { Cvar_ForceSet("mn_linkname", ""); } } /* set description text if item has been researched or one of its ammo/weapon has been researched */ if (count > 0 || GAME_ItemIsUseable(od)) { int numFiredefs = 0; *itemText = '\0'; if (od->isArmour()) { Com_sprintf(itemText, sizeof(itemText), _("Size:\t%i\n"), od->size); Q_strcat(itemText, sizeof(itemText), _("Weight:\t%g Kg\n"), od->weight); Q_strcat(itemText, sizeof(itemText), "\n"); Q_strcat(itemText, sizeof(itemText), _("^BDamage type:\tProtection:\n")); for (i = 0; i < csi.numDTs; i++) { const damageType_t* dt = &csi.dts[i]; if (!dt->showInMenu) continue; Q_strcat(itemText, sizeof(itemText), _("%s\t%i\n"), _(dt->id), od->ratings[i]); } } else if ((od->weapon && od->numAmmos) || od->isAmmo()) { const objDef_t* odAmmo; if (count > 0) { int weaponIndex; if (od->weapon) { Com_sprintf(itemText, sizeof(itemText), _("%s weapon\n"), (od->fireTwoHanded ? _("Two-handed") : _("One-handed"))); if (od->ammo > 0) Q_strcat(itemText, sizeof(itemText), _("Max ammo:\t%i\n"), od->ammo); odAmmo = (od->numAmmos) ? od->ammos[itemIndex] : od; assert(odAmmo); for (weaponIndex = 0; (weaponIndex < odAmmo->numWeapons) && (odAmmo->weapons[weaponIndex] != od); weaponIndex++) {} } else { odAmmo = od; weaponIndex = itemIndex; } Q_strcat(itemText, sizeof(itemText), _("Weight:\t%g Kg\n"), od->weight); /** @todo is there ammo with no firedefs? */ if (GAME_ItemIsUseable(odAmmo) && odAmmo->numFiredefs[weaponIndex] > 0) { const fireDef_t* fd; numFiredefs = odAmmo->numFiredefs[weaponIndex]; /* This contains everything common for weapons and ammos */ /* We check if the wanted firemode to display exists. */ if (fireModeIndex > numFiredefs - 1) fireModeIndex = 0; if (fireModeIndex < 0) fireModeIndex = numFiredefs - 1; fd = &odAmmo->fd[weaponIndex][fireModeIndex]; /* We always display the name of the firemode for an ammo */ Cvar_Set("mn_firemodename", "%s", _(fd->name)); /* We display the characteristics of this firemode */ Q_strcat(itemText, sizeof(itemText), _("Skill:\t%s\n"), CL_WeaponSkillToName(fd->weaponSkill)); Q_strcat(itemText, sizeof(itemText), _("Damage:\t%i\n"), (int) (fd->damage[0] + fd->spldmg[0]) * fd->shots); Q_strcat(itemText, sizeof(itemText), _("Time units:\t%i\n"), fd->time); Q_strcat(itemText, sizeof(itemText), _("Range:\t%g\n"), fd->range / UNIT_SIZE); Q_strcat(itemText, sizeof(itemText), _("Spreads:\t%g\n"), (fd->spread[0] + fd->spread[1]) / 2); } } else { Com_sprintf(itemText, sizeof(itemText), _("%s. No detailed info available.\n"), od->isAmmo() ? _("Ammunition") : _("Weapon")); Q_strcat(itemText, sizeof(itemText), _("Weight:\t%g Kg\n"), od->weight); } } else if (od->weapon) { Com_sprintf(itemText, sizeof(itemText), _("%s ammo-less weapon\n"), (od->fireTwoHanded ? _("Two-handed") : _("One-handed"))); Q_strcat(itemText, sizeof(itemText), _("Weight:\t%g Kg\n"), od->weight); } else { /* just an item - only primary definition */ Com_sprintf(itemText, sizeof(itemText), _("%s auxiliary equipment\n"), (od->fireTwoHanded ? _("Two-handed") : _("One-handed"))); Q_strcat(itemText, sizeof(itemText), _("Weight:\t%g Kg\n"), od->weight); if (od->numWeapons > 0 && od->numFiredefs[0] > 0) { const fireDef_t* fd = &od->fd[0][0]; Q_strcat(itemText, sizeof(itemText), _("Action:\t%s\n"), _(fd->name)); Q_strcat(itemText, sizeof(itemText), _("Time units:\t%i\n"), fd->time); Q_strcat(itemText, sizeof(itemText), _("Range:\t%g\n"), fd->range / UNIT_SIZE); } } UI_RegisterText(TEXT_ITEMDESCRIPTION, itemText); UI_ExecuteConfunc("itemdesc_view %i %i;", count, numFiredefs); } else { Com_sprintf(itemText, sizeof(itemText), _("Unknown - not useable")); UI_RegisterText(TEXT_ITEMDESCRIPTION, itemText); UI_ExecuteConfunc("itemdesc_view 0 0;"); } }
static void UI_CvarChangeListener (const char *cvarName, const char *oldValue, const char *newValue, void *data) { linkedList_t *list = static_cast<linkedList_t*>(data); LIST_Foreach(list, char const, confunc) { UI_ExecuteConfunc("%s %s %s", confunc, oldValue, newValue); }
/** * @brief Updates the Buy/Sell menu list. * @param[in] base Pointer to the base to buy/sell at * @sa BS_BuyType_f */ static void BS_BuyType (const base_t *base) { const objDef_t *od; int i, j = 0; char tmpbuf[MAX_VAR]; if (!base || buyCat >= MAX_FILTERTYPES || buyCat < 0) return; CP_UpdateCredits(ccs.credits); bsMarketNames = NULL; bsMarketStorage = NULL; bsMarketMarket = NULL; bsMarketPrices = NULL; UI_ResetData(TEXT_ITEMDESCRIPTION); /* hide autosell checkboxes by default */ for (i = 0; i < MAX_MARKET_MENU_ENTRIES; i++) { UI_ExecuteConfunc("buy_autoselli %i", i); } switch (buyCat) { case FILTER_AIRCRAFT: /* Aircraft */ { const aircraft_t *aircraftTemplate; for (i = 0, j = 0, aircraftTemplate = ccs.aircraftTemplates; i < ccs.numAircraftTemplates; i++, aircraftTemplate++) { if (!BS_AircraftIsOnMarket(aircraftTemplate)) continue; assert(aircraftTemplate->tech); if (BS_GetStorageAmountInBase(base, aircraftTemplate->id) + BS_GetAircraftOnMarket(aircraftTemplate) > 0) { if (j >= buyList.scroll && j < MAX_MARKET_MENU_ENTRIES) { UI_ExecuteConfunc("buy_show %i", j - buyList.scroll); } BS_AddToList(aircraftTemplate->name, BS_GetStorageAmountInBase(base, aircraftTemplate->id), BS_GetAircraftOnMarket(aircraftTemplate), BS_GetAircraftBuyingPrice(aircraftTemplate)); if (j >= MAX_BUYLIST) Com_Error(ERR_DROP, "Increase the MAX_BUYLIST value to handle that much items\n"); buyList.l[j].item = NULL; buyList.l[j].aircraft = aircraftTemplate; buyList.length = j + 1; BS_UpdateItem(base, j - buyList.scroll); j++; } } } break; case FILTER_CRAFTITEM: /* Aircraft items */ /* get item list */ for (i = 0, j = 0, od = csi.ods; i < csi.numODs; i++, od++) { if (!BS_IsOnMarket(od)) continue; /* Check whether the item matches the proper filter, storage in current base and market. */ if ((B_ItemInBase(od, base) || ccs.eMarket.numItems[i]) && INV_ItemMatchesFilter(od, FILTER_CRAFTITEM)) { if (j >= buyList.scroll && j < MAX_MARKET_MENU_ENTRIES) { const technology_t *tech = RS_GetTechForItem(od); UI_ExecuteConfunc("buy_show %i", j - buyList.scroll); if (RS_IsResearched_ptr(tech)) { if (ccs.eMarket.autosell[i]) UI_ExecuteConfunc("buy_autoselle %i", j - buyList.scroll); else UI_ExecuteConfunc("buy_autoselld %i", j - buyList.scroll); } } BS_AddToList(od->name, B_ItemInBase(od, base), ccs.eMarket.numItems[i], BS_GetItemBuyingPrice(od)); if (j >= MAX_BUYLIST) Com_Error(ERR_DROP, "Increase the MAX_FILTERLIST value to handle that much items\n"); buyList.l[j].item = od; buyList.l[j].aircraft = NULL; buyList.length = j + 1; BS_UpdateItem(base, j - buyList.scroll); j++; } } break; default: /* Normal items */ if (buyCat < MAX_SOLDIER_FILTERTYPES || buyCat == FILTER_DUMMY) { /* get item list */ for (i = 0, j = 0, od = csi.ods; i < csi.numODs; i++, od++) { if (!BS_IsOnMarket(od)) continue; /* Check whether the item matches the proper filter, storage in current base and market. */ if ((B_ItemInBase(od, base) || ccs.eMarket.numItems[i]) && INV_ItemMatchesFilter(od, buyCat)) { BS_AddToList(od->name, B_ItemInBase(od, base), ccs.eMarket.numItems[i], BS_GetItemBuyingPrice(od)); /* Set state of Autosell button. */ if (j >= buyList.scroll && j < MAX_MARKET_MENU_ENTRIES) { const technology_t *tech = RS_GetTechForItem(od); UI_ExecuteConfunc("buy_show %i", j - buyList.scroll); if (RS_IsResearched_ptr(tech)) { if (ccs.eMarket.autosell[i]) UI_ExecuteConfunc("buy_autoselle %i", j - buyList.scroll); else UI_ExecuteConfunc("buy_autoselld %i", j - buyList.scroll); } } if (j >= MAX_BUYLIST) Com_Error(ERR_DROP, "Increase the MAX_BUYLIST value to handle that much items\n"); buyList.l[j].item = od; buyList.l[j].aircraft = NULL; buyList.length = j + 1; BS_UpdateItem(base, j - buyList.scroll); j++; } } } break; } for (; j < MAX_MARKET_MENU_ENTRIES; j++) { /* Hide the rest of the entries. */ UI_ExecuteConfunc("buy_hide %i", j); } /* Update some menu cvars. */ /* Set up base capacities. */ Com_sprintf(tmpbuf, sizeof(tmpbuf), "%i/%i", CAP_GetCurrent(base, CAP_ITEMS), CAP_GetMax(base, CAP_ITEMS)); Cvar_Set("mn_bs_storage", tmpbuf); /* select first item */ if (buyList.length) { switch (buyCat) { /** @sa BS_MarketClick_f */ case FILTER_AIRCRAFT: BS_MarketAircraftDescription(buyList.l[0].aircraft); break; case FILTER_CRAFTITEM: Cvar_Set("mn_aircraftname", ""); /** @todo Use craftitem name here? See also BS_MarketClick_f */ /* Select current item or first one. */ if (currentSelectedMenuEntry) UP_AircraftItemDescription(currentSelectedMenuEntry); else UP_AircraftItemDescription(buyList.l[0].item); break; default: assert(buyCat != MAX_FILTERTYPES); /* Select current item or first one. */ if (currentSelectedMenuEntry) INV_ItemDescription(currentSelectedMenuEntry); else INV_ItemDescription(buyList.l[0].item); break; } } else { /* reset description */ INV_ItemDescription(NULL); } UI_RegisterLinkedListText(TEXT_MARKET_NAMES, bsMarketNames); UI_RegisterLinkedListText(TEXT_MARKET_STORAGE, bsMarketStorage); UI_RegisterLinkedListText(TEXT_MARKET_MARKET, bsMarketMarket); UI_RegisterLinkedListText(TEXT_MARKET_PRICES, bsMarketPrices); }