71 if (
tr.itemCargo !=
nullptr) {
73 tr.itemCargo =
nullptr;
75 if (
tr.alienCargo !=
nullptr) {
77 tr.alienCargo =
nullptr;
81 cgi->LIST_Delete(&
tr.employees[emplType]);
83 cgi->LIST_Delete(&
tr.aircraft);
95 cgi->Com_Printf(
"TR_TransferStart_f: currentTransferType is wrong!\n");
103 Com_sprintf(message,
sizeof(message),
_(
"Transport mission started, cargo is being transported to %s"),
tr.destBase->name);
105 cgi->UI_PopWindow(
false);
128 cgi->UI_ExecuteConfunc(
"ui_cargolist_clear");
131 if (
tr.antimatter > 0) {
133 cgi->UI_ExecuteConfunc(
"ui_cargolist_add \"%s\" \"%s\" %d", od->
id,
_(od->
name),
tr.antimatter);
137 if (
tr.itemCargo !=
nullptr) {
140 if (item->amount > 0)
141 cgi->UI_ExecuteConfunc(
"ui_cargolist_add \"%s\" \"%s\" %d", item->objDef->id,
_(item->objDef->name), item->amount);
143 cgi->LIST_Delete(&cargo);
155 cgi->UI_ExecuteConfunc(
"ui_cargolist_add \"ucn_%d\" \"%s %s %s\" %d", employee->chr.ucn,
158 cgi->UI_ExecuteConfunc(
"ui_cargolist_add \"ucn_%d\" \"%s %s\" %d", employee->chr.ucn,
168 int emplCount =
cgi->LIST_Count(
tr.employees[emplType]);
171 cgi->UI_ExecuteConfunc(
"ui_cargolist_add \"%s\" \"%s\" %d", (emplType ==
EMPL_SCIENTIST) ?
"scientist" :
"worker",
176 cgi->Com_Error(
ERR_DROP,
"TR_CargoList: Invalid employeetype in cargo");
181 if (
tr.alienCargo !=
nullptr) {
185 cgi->UI_ExecuteConfunc(
"ui_cargolist_add \"dead_%s\" \"%s\" %d", item->teamDef->id,
va(
_(
"Corpse of %s"),
_(item->teamDef->name)), item->dead);
187 cgi->UI_ExecuteConfunc(
"ui_cargolist_add \"alive_%s\" \"%s\" %d", item->teamDef->id,
va(
_(
"Alive %s"),
_(item->teamDef->name)), item->alive);
189 cgi->LIST_Delete(&cargo);
194 cgi->UI_ExecuteConfunc(
"ui_cargolist_add \"aircraft_%d\" \"%s\" %d", aircraft->idx,
va(
_(
"Aircraft %s"), aircraft->name), 1);
207 if (
cgi->LIST_GetPointer(
tr.aircraft, aircraft))
224 const int antiMatterInCargo =
tr.antimatter;
228 if (antiMatterInCargo || antiMatterInSrcBase) {
229 cgi->UI_ExecuteConfunc(
"ui_translist_add \"%s\" \"%s\" %d %d %d %d %d", od->
id,
_(od->
name),
230 antiMatterInSrcBase - antiMatterInCargo, antiMatterInDstBase, 0, antiMatterInCargo, antiMatterInSrcBase);
233 for (
int i = 0;
i <
cgi->csi->numODs;
i++) {
238 const int itemCargoAmount =
tr.itemCargo ?
tr.itemCargo->getAmount(od) : 0;
241 if (itemCargoAmount || itemInSrcBase > 0) {
242 cgi->UI_ExecuteConfunc(
"ui_translist_add \"%s\" \"%s\" %d %d %d %d %d", od->
id,
_(od->
name),
243 itemInSrcBase - itemCargoAmount, itemInDstBase, 0, itemCargoAmount, itemInSrcBase);
263 if (!employee->isHiredInBase(srcBase))
267 if (
cgi->LIST_GetPointer(
tr.employees[emplType], (
void*) employee))
277 cgi->UI_ExecuteConfunc(
"ui_translist_add \"ucn_%d\" \"%s\" %d %d %d %d %d", employee->chr.ucn,
278 str, -1, -1, -1, -1, -1);
289 const int trCount =
cgi->LIST_Count(
tr.employees[emplType]);
294 cgi->UI_ExecuteConfunc(
"ui_translist_add \"%s\" \"%s\" %d %d %d %d %d",
296 hiredSrc - trCount, hiredDst, 0, trCount, hiredSrc);
300 cgi->Com_Error(
ERR_DROP,
"TR_CargoList: Invalid employeetype in cargo");
317 const int srcDead = item->dead;
318 const int srcAlive = item->alive;
321 const int transferDead = (
tr.alienCargo) ?
tr.alienCargo->getDead(item->teamDef) : 0;
322 const int transferAlive = (
tr.alienCargo) ?
tr.alienCargo->getAlive(item->teamDef) : 0;
324 if (srcDead > 0 || transferDead > 0) {
326 Com_sprintf(str,
sizeof(str),
_(
"Corpse of %s"),
_(item->teamDef->name));
327 cgi->UI_ExecuteConfunc(
"ui_translist_add \"dead_%s\" \"%s\" %d %d %d %d %d",
328 item->teamDef->id, str, srcDead - transferDead, dstDead, 0, transferDead, srcDead);
330 if (srcAlive > 0 || transferAlive > 0) {
332 Com_sprintf(str,
sizeof(str),
_(
"Alive %s"),
_(item->teamDef->name));
333 cgi->UI_ExecuteConfunc(
"ui_translist_add \"alive_%s\" \"%s\" %d %d %d %d %d",
334 item->teamDef->id, str, srcAlive - transferAlive, dstAlive, 0, transferAlive, srcAlive);
337 cgi->LIST_Delete(&list);
352 if (
cgi->LIST_GetPointer(
tr.aircraft, aircraft))
355 cgi->UI_ExecuteConfunc(
"ui_translist_add \"aircraft_%d\" \"%s\" %d %d %d %d %d",
356 aircraft->idx, aircraft->name, -1, -1, -1, -1, -1);
370 if (srcBase ==
nullptr || destBase ==
nullptr)
375 cgi->UI_ExecuteConfunc(
"ui_translist_clear");
376 switch (transferType) {
390 cgi->Com_Error(
ERR_DROP,
"invalid transfertype given: %i", transferType);
404 if (!
tr.destBase || !base)
406 if (
cgi->Cmd_Argc() < 2)
422 if (
cgi->Cmd_Argc() < 3) {
423 cgi->Com_Printf(
"Usage: %s <itemid> <amount>",
cgi->Cmd_Argv(0));
428 int amount = atoi(
cgi->Cmd_Argv(2));
440 cgi->LIST_AddPointer(&
tr.aircraft, (
void*)aircraft);
444 cgi->Cmd_ExecuteString(
"ui_trans_add ucn_%d 1", aircraft->pilot->chr.ucn);
448 cgi->Cmd_ExecuteString(
"ui_trans_add ucn_%d 1", employee->chr.ucn);
450 }
else if (amount < 0) {
452 cgi->LIST_Remove(&
tr.aircraft, (
void*)aircraft);
456 cgi->Cmd_ExecuteString(
"ui_trans_add ucn_%d -1", aircraft->pilot->chr.ucn);
460 cgi->Cmd_ExecuteString(
"ui_trans_add ucn_%d -1", employee->chr.ucn);
471 if (
cgi->LIST_GetPointer(
tr.employees[employee->
getType()], (
void*)employee))
475 cgi->LIST_AddPointer(&
tr.employees[employee->getType()], (
void*)employee);
479 while ((cont = employee->chr.inv.getNextCont(cont,
true))) {
482 const Item item = *ic;
487 cgi->Cmd_ExecuteString(
"ui_trans_add %s 1", od->
id);
491 cgi->Cmd_ExecuteString(
"ui_trans_add %s 1", ammo->
id);
496 }
else if (amount < 0) {
498 cgi->LIST_Remove(&
tr.employees[employee->
getType()], (
void*)employee);
502 while ((cont = employee->chr.inv.getNextCont(cont,
true))) {
505 const Item item = *ic;
510 cgi->Cmd_ExecuteString(
"ui_trans_add %s -1", od->
id);
514 cgi->Cmd_ExecuteString(
"ui_trans_add %s -1", ammo->
id);
520 }
else if (
Q_streq(itemId,
"scientist")) {
525 if (!employee->isHiredInBase(base))
533 }
else if (amount < 0) {
539 }
else if (
Q_streq(itemId,
"worker")) {
544 if (!employee->isHiredInBase(base))
552 }
else if (amount < 0) {
559 if (
tr.alienCargo ==
nullptr)
561 if (
tr.alienCargo ==
nullptr)
562 cgi->Com_Error(
ERR_DROP,
"TR_Add_f: Cannot create AlienCargo object\n");
564 const teamDef_t* teamDef =
cgi->Com_GetTeamDefinitionByID(itemId + 6);
566 const int cargo =
tr.alienCargo->getAlive(teamDef);
570 amount = std::min(amount, store - cargo);
572 amount = std::max(amount, -cargo);
575 tr.alienCargo->add(teamDef, amount, 0);
578 if (
tr.alienCargo ==
nullptr)
580 if (
tr.alienCargo ==
nullptr)
581 cgi->Com_Error(
ERR_DROP,
"TR_Add_f: Cannot create AlienCargo object\n");
583 const teamDef_t* teamDef =
cgi->Com_GetTeamDefinitionByID(itemId + 5);
585 const int cargo =
tr.alienCargo->getDead(teamDef);
589 amount = std::min(amount, store - cargo);
591 amount = std::max(amount, -cargo);
594 tr.alienCargo->add(teamDef, 0, amount);
598 const int cargo =
tr.antimatter;
602 amount = std::min(amount, store - cargo);
604 amount = std::max(amount, -cargo);
606 tr.antimatter += amount;
615 if (
tr.itemCargo ==
nullptr)
617 const int cargo =
tr.itemCargo->getAmount(od);
620 amount = std::min(amount, store - cargo);
622 amount = std::max(amount, -cargo);
624 tr.itemCargo->add(od, amount, 0);
630 cgi->Cmd_ExecuteString(
"ui_trans_caplist %d",
tr.destBase->idx);
652 cgi->Cmd_ExecuteString(
"ui_trans_caplist %d",
tr.destBase->idx);
663 if (!destbase || !srcbase)
667 tr.destBase = destbase;
668 cgi->Cvar_Set(
"mn_trans_base_name",
"%s", destbase->
name);
669 cgi->Cvar_SetValue(
"mn_trans_base_id", destbase->
idx);
676 cgi->Cmd_ExecuteString(
"ui_trans_caplist %d",
tr.destBase->idx);
688 while ((base =
B_GetNext(base)) !=
nullptr) {
689 if (base == currentBase)
692 cgi->UI_AddOption(&baseList,
va(
"base%i", base->
idx), base->
name,
va(
"%i", base->
idx));
707 if (
cgi->Cmd_Argc() < 2) {
708 cgi->Com_Printf(
"Usage: %s <baseIdx>\n",
cgi->Cmd_Argv(0));
712 baseIdx = atoi(
cgi->Cmd_Argv(1));
737 cgi->Com_Error(
ERR_DROP,
"No bases! Transfer needs at least two...");
741 cgi->Cvar_Set(
"mn_trans_base_name",
"%s",
tr.destBase->name);
742 cgi->Cvar_SetValue(
"mn_trans_base_id",
tr.destBase->idx);
744 cgi->Cvar_Set(
"mn_trans_base_id",
"");
771 cgi->UI_ExecuteConfunc(
"tr_listclear");
773 const char* source = transfer->srcBase ? transfer->srcBase->name :
"mission";
774 const DateTime remainingTime = transfer->event -
ccs.date;
778 if (transfer->antimatter) {
779 cgi->UI_ExecuteConfunc(
"tr_listaddcargo %d \"%s\" \"%s\" \"%s\"",
i,
"tr_cargo",
"antimatter",
_(
"Antimatter"));
781 cgi->UI_ExecuteConfunc(
"tr_listaddcargo %d \"%s\" \"%s\" \"%s\"",
i,
"tr_cargo.antimatter", od->
id,
va(
"%i %s", transfer->antimatter,
_(od->
name)));
784 if (transfer->itemCargo !=
nullptr) {
785 cgi->UI_ExecuteConfunc(
"tr_listaddcargo %d \"%s\" \"%s\" \"%s\"",
i,
"tr_cargo",
"items",
_(
"Items"));
788 if (item->amount <= 0)
790 cgi->UI_ExecuteConfunc(
"tr_listaddcargo %d \"%s\" \"%s\" \"%s\"",
i,
"tr_cargo.items", item->objDef->id,
va(
"%i %s", item->amount,
_(item->objDef->name)));
792 cgi->LIST_Delete(&cargo);
795 if (transfer->hasEmployees) {
797 cgi->UI_ExecuteConfunc(
"tr_listaddcargo %d \"%s\" \"%s\" \"%s\"",
i,
"tr_cargo",
"employee",
_(
"Employee"));
801 if (employee->getUGV()) {
804 cgi->UI_ExecuteConfunc(
"tr_listaddcargo %d \"%s\" \"%s\" \"%s\"",
i,
"tr_cargo.employee",
va(
"ucn_%i", employee->chr.ucn),
va(
"%s %s",
E_GetEmployeeString(employee->getType(), 1), employee->chr.name));
810 if (transfer->alienCargo !=
nullptr) {
811 cgi->UI_ExecuteConfunc(
"tr_listaddcargo %d \"%s\" \"%s\" \"%s\"",
i,
"tr_cargo",
"aliens",
_(
"Aliens"));
815 cgi->UI_ExecuteConfunc(
"tr_listaddcargo %d \"%s\" \"%s\" \"%s\"",
i,
"tr_cargo.aliens",
va(
"%s_alive", item->teamDef->id),
va(
"%i %s %s", item->alive,
_(
"alive"),
_(item->teamDef->name)));
817 cgi->UI_ExecuteConfunc(
"tr_listaddcargo %d \"%s\" \"%s\" \"%s\"",
i,
"tr_cargo.aliens",
va(
"%s_dead", item->teamDef->id),
va(
"%i %s %s", item->dead,
_(
"dead"),
_(item->teamDef->name)));
819 cgi->LIST_Delete(&cargo);
822 if (!
cgi->LIST_IsEmpty(transfer->aircraft)) {
823 cgi->UI_ExecuteConfunc(
"tr_listaddcargo %d \"%s\" \"%s\" \"%s\"",
i,
"tr_cargo",
"aircraft",
ngettext(
"Aircraft",
"Aircraft",
LIST_Count(transfer->aircraft)));
826 cgi->UI_ExecuteConfunc(
"tr_listaddcargo %d \"%s\" \"%s\" \"%s\"",
i,
"tr_cargo.aircraft",
va(
"craft%i", aircraft->idx), aircraft->name);
862 if (
cgi->Cmd_Argc() < 2) {
863 cgi->Com_Printf(
"Usage: %s <destinationBaseIdx>\n",
cgi->Cmd_Argv(0));
869 cgi->Com_Printf(
"Invalid destinationBaseIdx: %s\n",
cgi->Cmd_Argv(1));
878 if (transfer->destBase != base)
883 currentCap[
CAP_ITEMS] += transfer->itemCargo ? transfer->itemCargo->size() : 0;
886 currentCap[
CAP_ALIENS] += (transfer->alienCargo) ? transfer->alienCargo->getAlive() : 0;
894 currentCap[
CAP_ITEMS] +=
tr.itemCargo ?
tr.itemCargo->size() : 0;
898 currentCap[
CAP_ALIENS] +=
tr.alienCargo ?
tr.alienCargo->getAlive() : 0;
902 cgi->UI_ExecuteConfunc(
"ui_t_capacities_clear");
903 for (
int i = 0;
i <
ccs.numBuildingTemplates;
i++) {
915 currentCap[capType] += cap.
cur;
916 if (cap.
max <= 0 && currentCap[capType] <= 0)
919 cgi->UI_ExecuteConfunc(
"ui_t_capacities_add \"%s\" \"%s\" %d %d", building->
id,
_(building->
name), currentCap[capType], cap.
max);
924 {
"trans_list",
TR_List_f,
"Assembles the transferlist"},
925 {
"trans_init",
TR_Init_f,
"Init function for Transfer menu"},
929 {
"trans_selectbase",
TR_SelectBase_f,
"Callback for selecting a base"},
931 {
"ui_trans_fill",
TR_Fill_f,
"Fill itemlists for transfer"},
932 {
"ui_trans_add",
TR_Add_f,
"Add/Remove items to transfercargo"},
933 {
nullptr,
nullptr,
nullptr}
DateTime class definition.
Alien cargo class header.
Alien containment class header.
Share stuff between the different cgame implementations.
linkedList_t * list(void) const
Returns a copy of the cargo list.
int getAlive(const teamDef_t *team) const
Return number of alive aliens of a type in the cargo.
int getDead(const teamDef_t *team) const
Return number of dead alien bodies of a type in the cargo.
Item * getNextItem(const Item *prev) const
Class describing a point of time.
bool isHiredInBase(const base_t *const base) const
Checks whether the given employee is in the given base.
employeeType_t getType() const
item instance data, with linked list capability
const objDef_t * ammoDef(void) const
const objDef_t * def(void) const
bool AIR_IsAircraftInBase(const aircraft_t *aircraft)
Checks whether given aircraft is in its homebase.
baseCapacities_t AIR_GetHangarCapacityType(const aircraft_t *aircraft)
Returns capacity type needed for an aircraft.
aircraft_t * AIR_AircraftGetFromIDX(int aircraftIdx)
Returns aircraft for a given global index.
#define AIR_ForeachFromBase(var, base)
iterates trough all aircraft from a specific homebase
baseCapacities_t B_GetCapacityFromBuildingType(buildingType_t type)
Get the capacity associated to a building type.
base_t * B_GetFoundedBaseByIDX(int baseIdx)
Array bound check for the base index.
base_t * B_GetNext(base_t *lastBase)
Iterates through founded bases.
bool B_ItemIsStoredInBaseStorage(const objDef_t *obj)
Check if an item is stored in storage.
base_t * B_GetCurrentSelectedBase(void)
returns the currently selected base
int B_AntimatterInBase(const base_t *base)
returns the amount of antimatter stored in a base
int B_ItemInBase(const objDef_t *item, const base_t *base)
Check if the item has been collected (i.e it is in the storage) in the given base.
Header file for single player campaign control.
const cgame_import_t * cgi
baseCapacities_t
All possible capacities in base.
#define CAP_Get(base, capacity)
Capacity macros.
Employee * E_GetEmployeeFromChrUCN(int uniqueCharacterNumber)
Searches all employee for the ucn (character id).
const char * E_GetEmployeeString(employeeType_t type, int n)
Convert employeeType_t to translated string.
int E_CountHired(const base_t *const base, employeeType_t type)
Counts hired employees of a given type in a given base.
employeeType_t
The types of employees.
#define E_Foreach(employeeType, var)
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...
rank_t * CL_GetRankByIdx(const int index)
Returns a rank at an index.
bool RS_IsResearched_ptr(const technology_t *tech)
Checks whether an item is already researched.
#define ANTIMATTER_ITEM_ID
const char * CP_SecondConvert(int second)
Converts a number of second into a char to display.
int Date_DateToSeconds(const DateTime &date)
Convert a date to seconds.
Campaign geoscape time header.
transfer_t * TR_TransferStart(base_t *srcBase, transfer_t &transData)
Starts a transfer.
Header file for Transfer stuff.
#define TR_ForeachEmployee(var, transfer, employeeType)
#define TR_ForeachAircraft(var, transfer)
static void TR_Add_f(void)
Callback handles adding/removing items to transfercargo.
static char const *const transferTypeIDs[]
transfer typeID strings
static void TR_TransferListClear_f(void)
Unload everything from transfer cargo back to base.
static const cmdList_t transferCallbacks[]
static void TR_FillAircraft(const base_t *srcBase, const base_t *destBase)
Add aircraft to the transfer storages list.
void TR_InitCallbacks(void)
static void TR_TransferClose_f(void)
Closes Transfer Menu and resets temp arrays.
static void TR_TransferBaseSelect(base_t *srcbase, base_t *destbase)
Callback for base list click.
static void TR_SelectBase_f(void)
Callback to select destination base.
transferType_t
transfer types
static void TR_CountAircraftInList(linkedList_t *aircraftList, int capacity[])
Count capacity need of aircraft in lists.
static void TR_Fill(const base_t *srcBase, const base_t *destBase, transferType_t transferType)
Fills the items-in-base list with stuff available for transfer.
static bool TR_AircraftListSelect(const aircraft_t *aircraft)
Check if an aircraft should be displayed for transfer.
static void TR_CountEmployeeInListArray(linkedList_t *employeeListArray[], int capacity[])
Count capacity need of employee in array of lists.
static void TR_Fill_f(void)
Callback for filling list with stuff available for transfer.
static transferType_t currentTransferType
static void TR_TransferStart_f(void)
Starts the transfer.
void TR_ShutdownCallbacks(void)
static void TR_FillItems(const base_t *srcBase, const base_t *destBase)
Add items to the transfer storages list.
static void TR_CargoList(void)
Display cargo list.
static void TR_FillEmployees(const base_t *srcBase, const base_t *destBase)
Add employees to the transfer storages list.
static transferType_t TR_GetTransferType(const char *id)
Returns the transfer type.
static void TR_DestinationCapacityList_f(void)
Callback for assemble destination base capacity list.
static void TR_Init_f(void)
Transfer menu init function.
static void TR_List_f(void)
Assembles the list of transfers for the popup.
static void TR_InitBaseList(void)
Fills the optionlist with available bases to transfer to.
static void TR_FillAliens(const base_t *srcBase, const base_t *destBase)
Add aliens to the transfer storages list.
static void TR_ClearTempCargo(void)
Clear temporary cargo arrays.
Header file for menu related console command callbacks.
#define ngettext(x, y, cnt)
const objDef_t * INVSH_GetItemByIDX(int index)
Returns the item that belongs to the given index or nullptr if the index is invalid.
const objDef_t * INVSH_GetItemByID(const char *id)
Returns the item that belongs to the given id or nullptr if it wasn't found.
int LIST_Count(const linkedList_t *list)
#define LIST_Foreach(list, type, var)
Iterates over a linked list, it's safe to delete the returned entry from the list while looping over ...
QGL_EXTERN GLint GLenum type
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
char const * Q_strstart(char const *str, char const *start)
Matches the start of a string.
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
An aircraft with all it's data.
A base with all it's data.
class AlienContainment * alienContainment
A building with all it's data.
buildingType_t buildingType
struct technology_s * tech
Store capacities in base.
Defines all attributes of objects used in the inventory.
bool isReloadable() const
Describes a rank that a recruit can gain.
Transfer information (they are being stored in ccs.transfers).
Atomic structure used to define most of the UI.