/** * @brief Fills the UI with ufo yard data */ static void INS_FillUFOYardData_f (void) { installation_t* ins; cgi->UI_ExecuteConfunc("ufolist_clear"); if (cgi->Cmd_Argc() < 2 || atoi(cgi->Cmd_Argv(1)) < 0) { ins = INS_GetCurrentSelectedInstallation(); if (!ins || ins->installationTemplate->type != INSTALLATION_UFOYARD) ins = INS_GetFirstUFOYard(false); } else { ins = INS_GetByIDX(atoi(cgi->Cmd_Argv(1))); if (!ins) Com_DPrintf(DEBUG_CLIENT, "Installation not founded (idx %i)\n", atoi(cgi->Cmd_Argv(1))); } if (ins) { const nation_t* nat = GEO_GetNation(ins->pos); const int timeToBuild = std::max(0, ins->installationTemplate->buildTime - (ccs.date.day - ins->buildStart)); const char* buildTime = (timeToBuild > 0 && ins->installationStatus == INSTALLATION_UNDER_CONSTRUCTION) ? va(ngettext("%d day", "%d days", timeToBuild), timeToBuild) : "-"; const int freeCap = std::max(0, ins->ufoCapacity.max - ins->ufoCapacity.cur); const char* nationName = nat ? _(nat->name) : ""; cgi->UI_ExecuteConfunc("ufolist_addufoyard %d \"%s\" \"%s\" %d %d \"%s\"", ins->idx, ins->name, nationName, ins->ufoCapacity.max, freeCap, buildTime); US_Foreach(ufo) { if (ufo->installation != ins) continue; const char* ufoName = UFO_GetName(ufo->ufoTemplate); const char* condition = va(_("Condition: %3.0f%%"), ufo->condition * 100); const char* status = US_StoredUFOStatus(ufo); cgi->UI_ExecuteConfunc("ufolist_addufo %d \"%s\" \"%s\" \"%s\" \"%s\"", ufo->idx, ufoName, condition, ufo->ufoTemplate->model, status); } } }
/** * @brief console function for destroying an installation * @sa INS_DestroyInstallation */ static void INS_DestroyInstallation_f (void) { installation_t* installation; if (cgi->Cmd_Argc() < 2 || atoi(cgi->Cmd_Argv(1)) < 0) { installation = INS_GetCurrentSelectedInstallation(); } else { installation = INS_GetByIDX(atoi(cgi->Cmd_Argv(1))); if (!installation) { Com_DPrintf(DEBUG_CLIENT, "Installation not founded (idx %i)\n", atoi(cgi->Cmd_Argv(1))); return; } } /* Ask 'Are you sure?' by default */ if (cgi->Cmd_Argc() < 3 || !atoi(cgi->Cmd_Argv(2))) { char command[MAX_VAR]; Com_sprintf(command, sizeof(command), "mn_installation_destroy %d 1; ui_pop;", installation->idx); cgi->UI_PopupButton(_("Destroy Installation"), _("Do you really want to destroy this installation?"), command, _("Destroy"), _("Destroy installation"), "ui_pop;", _("Cancel"), _("Forget it"), nullptr, nullptr, nullptr); return; } INS_DestroyInstallation(installation); }
/** * @brief Creates console command to change the name of a installation. * Copies the value of the cvar mn_installation_title over as the name of the * current selected installation */ static void INS_ChangeInstallationName_f (void) { installation_t* installation = INS_GetCurrentSelectedInstallation(); /* maybe called without installation initialized or active */ if (!installation) return; Q_strncpyz(installation->name, cgi->Cvar_GetString("mn_installation_title"), sizeof(installation->name)); }
/** * @brief Show item description in bdef menu * @note it handles items in both slots and storage */ static void BDEF_SelectItem_f (void) { aircraftSlot_t* slot; installation_t* installation = INS_GetCurrentSelectedInstallation(); base_t* base = B_GetCurrentSelectedBase(); aircraftItemType_t bdefType; int slotIDX; int itemIDX; if (cgi->Cmd_Argc() < 4) { Com_Printf("Usage: %s <type> <slotIDX> <itemIDX>\n", cgi->Cmd_Argv(0)); return; } bdefType = BDEF_GetItemTypeFromID(cgi->Cmd_Argv(1)); slotIDX = atoi(cgi->Cmd_Argv(2)); itemIDX = atoi(cgi->Cmd_Argv(3)); if (bdefType == MAX_ACITEMS) { Com_Printf("BDEF_AddItem_f: Invalid defence type.\n"); return; } if (slotIDX >= 0) { const objDef_t* item; slot = (installation) ? BDEF_GetInstallationSlotByIDX(installation, bdefType, slotIDX) : BDEF_GetBaseSlotByIDX(base, bdefType, slotIDX); item = (slot) ? ( (slot->nextItem) ? slot->nextItem : slot->item ) : nullptr; UP_AircraftItemDescription(item); } else if (itemIDX >= 0) { technology_t** list; technology_t* itemTech = nullptr; int i = 0; slot = (installation) ? BDEF_GetInstallationSlotByIDX(installation, bdefType, 0) : BDEF_GetBaseSlotByIDX(base, bdefType, 0); list = AII_GetCraftitemTechsByType(bdefType); while (*list && i <= itemIDX) { if (AIM_SelectableCraftItem(slot, *list)) { itemTech = *list; i++; break; } list++; } UP_AircraftItemDescription((itemTech) ? INVSH_GetItemByIDSilent(itemTech->provides) : nullptr); } else { Com_Printf("BDEF_AddItem_f: Invalid item-space.\n"); } }
/** * @brief Menu callback for changing autofire state * Command: basedef_autofire <0|1> */ static void BDEF_ChangeAutoFire (void) { installation_t* installation = INS_GetCurrentSelectedInstallation(); base_t* base = B_GetCurrentSelectedBase(); int i; if (!base && !installation) return; if (base && installation) return; if (cgi->Cmd_Argc() < 2) return; if (base) { for (i = 0; i < base->numBatteries; i++) BDEF_SetAutoFire(&base->batteries[i], atoi(cgi->Cmd_Argv(1))); for (i = 0; i < base->numLasers; i++) BDEF_SetAutoFire(&base->lasers[i], atoi(cgi->Cmd_Argv(1))); } else if (installation) { for (i = 0; i < installation->numBatteries; i++) BDEF_SetAutoFire(&installation->batteries[i], atoi(cgi->Cmd_Argv(1))); } }
/** * @brief add item to a base defence slot (installation too) */ static void BDEF_RemoveItem_f (void) { aircraftSlot_t* slot; installation_t* installation = INS_GetCurrentSelectedInstallation(); base_t* base = B_GetCurrentSelectedBase(); aircraftItemType_t bdefType; int slotIDX; if ((!base && !installation) || (base && installation)) { Com_Printf("Exiting early base and install both true or both false\n"); return; } if (cgi->Cmd_Argc() < 3) { Com_Printf("Usage: %s <type> <slotIDX>\n", cgi->Cmd_Argv(0)); return; } bdefType = BDEF_GetItemTypeFromID(cgi->Cmd_Argv(1)); slotIDX = atoi(cgi->Cmd_Argv(2)); if (bdefType == MAX_ACITEMS) { Com_Printf("BDEF_AddItem_f: Invalid defence type.\n"); return; } if (slotIDX < 0) { return; } else { int maxWeapon; if (base) maxWeapon = (bdefType == AC_ITEM_BASE_MISSILE) ? base->numActiveBatteries : base->numActiveLasers; else maxWeapon = installation->numBatteries; if (slotIDX >= maxWeapon) return; } slot = (installation) ? BDEF_GetInstallationSlotByIDX(installation, bdefType, slotIDX) : BDEF_GetBaseSlotByIDX(base, bdefType, slotIDX); if (!slot) { Com_Printf("BDEF_AddItem_f: Invalid slot.\n"); return; } if (!slot->item) return; if (!slot->nextItem) { /* we change the weapon, shield, item, or base defence that is already in the slot */ /* if the item has been installed since less than 1 hour, you don't need time to remove it */ if (slot->installationTime < slot->item->craftitem.installationTime) { slot->installationTime = -slot->item->craftitem.installationTime; AII_RemoveItemFromSlot(base, slot, true); /* we remove only ammo, not item */ } else { AII_RemoveItemFromSlot(base, slot, false); /* we remove weapon and ammo */ } } else { /* we change the weapon, shield, item, or base defence that will be installed AFTER the removal * of the one in the slot atm */ AII_RemoveItemFromSlot(base, slot, false); /* we remove weapon and ammo */ /* if you canceled next item for less than 1 hour, previous item is still functional */ if (slot->installationTime == -slot->item->craftitem.installationTime) { slot->installationTime = 0; } } cgi->Cmd_ExecuteString("basedef_updatemenu %s", BDEF_GetIDFromItemType(slot->type)); }
/** * @brief add item to a base defence slot (installation too) */ static void BDEF_AddItem_f (void) { aircraftSlot_t* slot; installation_t* installation = INS_GetCurrentSelectedInstallation(); base_t* base = B_GetCurrentSelectedBase(); technology_t** list; technology_t* itemTech = nullptr; aircraftItemType_t bdefType; int slotIDX; if ((!base && !installation) || (base && installation)) { Com_Printf("Exiting early base and installation both true or both false\n"); return; } if (cgi->Cmd_Argc() < 3) { Com_Printf("Usage: %s <type> <slotIDX>\n", cgi->Cmd_Argv(0)); return; } bdefType = BDEF_GetItemTypeFromID(cgi->Cmd_Argv(1)); slotIDX = atoi(cgi->Cmd_Argv(2)); if (bdefType == MAX_ACITEMS) { Com_Printf("BDEF_AddItem_f: Invalid defence type.\n"); return; } if (slotIDX < 0) { return; } else { int maxWeapon; if (base) maxWeapon = (bdefType == AC_ITEM_BASE_MISSILE) ? base->numActiveBatteries : base->numActiveLasers; else maxWeapon = installation->numBatteries; if (slotIDX >= maxWeapon) return; } slot = (installation) ? BDEF_GetInstallationSlotByIDX(installation, bdefType, slotIDX) : BDEF_GetBaseSlotByIDX(base, bdefType, slotIDX); if (!slot) { Com_Printf("BDEF_AddItem_f: Invalid slot.\n"); return; } list = AII_GetCraftitemTechsByType(bdefType); while (*list) { if (AIM_SelectableCraftItem(slot, *list)) { itemTech = *list; break; } list++; } if (!itemTech) return; if (!slot->nextItem) { /* we add the weapon, shield, item, or base defence if slot is free or the installation of * current item just began */ if (!slot->item || (slot->item && slot->installationTime == slot->item->craftitem.installationTime)) { AII_RemoveItemFromSlot(base, slot, false); AII_AddItemToSlot(base, itemTech, slot, false); /* Aircraft stats are updated below */ AII_AutoAddAmmo(slot); } else if (slot->item == INVSH_GetItemByID(itemTech->provides)) { /* the added item is the same than the one in current slot */ if (slot->installationTime == -slot->item->craftitem.installationTime) { /* player changed his mind: he just want to re-add the item he just removed */ slot->installationTime = 0; } else if (!slot->installationTime) { /* player try to add a weapon he already have: just skip */ } } else { /* We start removing current item in slot, and the selected item will be installed afterwards */ slot->installationTime = -slot->item->craftitem.installationTime; AII_AddItemToSlot(base, itemTech, slot, true); AII_AutoAddAmmo(slot); } } else { /* remove weapon and ammo of next item */ AII_RemoveItemFromSlot(base, slot, false); AII_AddItemToSlot(base, itemTech, slot, true); AII_AutoAddAmmo(slot); } /* Reinit menu */ cgi->Cmd_ExecuteString("basedef_updatemenu %s", BDEF_GetIDFromItemType(slot->type)); }
/** * @brief Fills the battery list, descriptions, and weapons in slots * of the basedefence equip menu */ static void BDEF_BaseDefenceMenuUpdate_f (void) { char type[MAX_VAR]; base_t* base = B_GetCurrentSelectedBase(); installation_t* installation = INS_GetCurrentSelectedInstallation(); aircraftItemType_t bdefType; linkedList_t* slotList = nullptr; const bool missileResearched = RS_IsResearched_ptr(RS_GetTechByID("rs_building_missile")); const bool laserResearched = RS_IsResearched_ptr(RS_GetTechByID("rs_building_laser")); if (cgi->Cmd_Argc() != 2) type[0] = '\0'; else Q_strncpyz(type, cgi->Cmd_Argv(1), sizeof(type)); /* don't let old links appear on this menu */ cgi->UI_ResetData(TEXT_BASEDEFENCE_LIST); cgi->UI_ResetData(TEXT_LIST); cgi->UI_ResetData(TEXT_ITEMDESCRIPTION); /* base or installation should not be nullptr because we are in the menu of this base or installation */ if (!base && !installation) return; /* base and installation should not both be set. This function requires one or the other set. */ if (base && installation) { Sys_Error("BDEF_BaseDefenceMenuUpdate_f: Both the base and installation are set"); return; } cgi->Cvar_Set("mn_target", _("None")); cgi->UI_ExecuteConfunc("setautofire disable"); if (installation) { /* Every slot aims the same target */ if (installation->numBatteries) { cgi->UI_ExecuteConfunc("setautofire %i", installation->batteries[0].autofire); if (installation->batteries[0].target) cgi->Cvar_Set("mn_target", "%s", UFO_GetName(installation->batteries[0].target)); } } else if (base) { bool autofire = false; /* Every slot aims the same target */ if (base->numBatteries) { autofire |= base->batteries[0].autofire; if (base->batteries[0].target) cgi->Cvar_Set("mn_target", "%s", UFO_GetName(base->batteries[0].target)); } if (base->numLasers) { autofire |= base->lasers[0].autofire; if (base->lasers[0].target && !base->batteries[0].target) cgi->Cvar_Set("mn_target", "%s", UFO_GetName(base->lasers[0].target)); } if (base->numBatteries || base->numLasers) cgi->UI_ExecuteConfunc("setautofire %i", autofire); } /* Check if we can change to laser or missile */ if (base) { cgi->UI_ExecuteConfunc("set_defencetypes %s %s", (!missileResearched) ? "na" : (base && base->numBatteries > 0) ? "enable" : "disable", (!laserResearched) ? "na" : (base && base->numLasers > 0) ? "enable" : "disable"); } else if (installation) { cgi->UI_ExecuteConfunc("set_defencetypes %s %s", (!missileResearched) ? "na" : (installation && installation->installationStatus == INSTALLATION_WORKING && installation->numBatteries > 0) ? "enable" : "disable", "na"); } if (Q_streq(type, "missile")) bdefType = AC_ITEM_BASE_MISSILE; else if (Q_streq(type, "laser")) bdefType = AC_ITEM_BASE_LASER; else /* info page */ return; /* Check that the base or installation has at least 1 battery */ if (base) { if (base->numBatteries + base->numLasers < 1) { Com_Printf("BDEF_BaseDefenceMenuUpdate_f: there is no defence battery in this base: you shouldn't be in this function.\n"); return; } } else if (installation) { if (installation->installationStatus != INSTALLATION_WORKING) { Com_Printf("BDEF_BaseDefenceMenuUpdate_f: installation isn't working: you shouldn't be in this function.\n"); return; } else if (installation->installationTemplate->maxBatteries < 1) { Com_Printf("BDEF_BaseDefenceMenuUpdate_f: there is no defence battery in this installation: you shouldn't be in this function.\n"); return; } } if (installation) { /* we are in the installation defence menu */ if (installation->installationTemplate->maxBatteries == 0) { cgi->LIST_AddString(&slotList, _("No defence of this type in this installation")); } else { BDEF_FillSlotList(installation->batteries, installation->installationTemplate->maxBatteries, &slotList); } } else if (bdefType == AC_ITEM_BASE_MISSILE) { /* we are in the base defence menu for missile */ if (base->numBatteries == 0) { cgi->LIST_AddString(&slotList, _("No defence of this type in this base")); } else { BDEF_FillSlotList(base->batteries, base->numActiveBatteries, &slotList); } } else if (bdefType == AC_ITEM_BASE_LASER) { /* we are in the base defence menu for laser */ if (base->numLasers == 0) { cgi->LIST_AddString(&slotList, _("No defence of this type in this base")); } else { BDEF_FillSlotList(base->lasers, base->numActiveLasers, &slotList); } } else { Com_Printf("BDEF_BaseDefenceMenuUpdate_f: unknown bdefType.\n"); return; } cgi->UI_RegisterLinkedListText(TEXT_BASEDEFENCE_LIST, slotList); }