UFO: Alien Invasion
cp_uforecovery_callbacks.cpp
Go to the documentation of this file.
1 
8 /*
9 Copyright (C) 2002-2022 UFO: Alien Invasion.
10 
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 as published by the Free Software Foundation; either version 2
14 of the License, or (at your option) any later version.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 
20 See the GNU General Public License for more details.
21 
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26 
27 #include "../../DateTime.h"
28 #include "../../cl_shared.h"
29 #include "../../ui/ui_dataids.h"
30 #include "cp_campaign.h"
31 #include "cp_ufo.h"
32 #include "cp_uforecovery.h"
34 #include "cp_geoscape.h"
35 #include "cp_time.h"
36 
37 #define HAPPINESS_UFO_SALE_GAIN 0.02
38 #define HAPPINESS_UFO_SALE_LOSS 0.005
39 
45 static void UR_DialogInitStore_f (void)
46 {
47  /* Check how many bases can store this UFO. */
48  INS_Foreach(installation) {
49  const capacities_t* capacity = &installation->ufoCapacity;
50  if (capacity->max > 0 && capacity->max > capacity->cur) {
51  cgi->UI_ExecuteConfunc("ui_uforecovery_ufoyards %d \"%s\" %d %d",
52  installation->idx,
53  installation->name,
54  std::max(capacity->max - capacity->cur, 0),
55  capacity->max
56  );
57  }
58  }
59 }
60 
65 static void UR_DialogStartStore_f (void)
66 {
67 
68  if (cgi->Cmd_Argc() < 4) {
69  cgi->Com_Printf("Usage: %s <ufoType> <damage> <installationIDX>\n", cgi->Cmd_Argv(0));
70  return;
71  }
72 
73  const aircraft_t* ufo = AIR_GetAircraftSilent(cgi->Cmd_Argv(1));
74  if (ufo == nullptr || !AIR_IsUFO(ufo)) {
75  cgi->Com_Printf("%s Invalid UFO type\n", cgi->Cmd_Argv(0));
76  return;
77  }
78 
79  float condition = atof(cgi->Cmd_Argv(2));
80  if (condition < 0.0f || condition > 100.0f) {
81  cgi->Com_Printf("%s Invalid UFO damage value\n", cgi->Cmd_Argv(0));
82  return;
83  }
84 
85  installation_t* installation = INS_GetByIDX(atoi(cgi->Cmd_Argv(3)));
86  if (installation == nullptr || installation->ufoCapacity.max <= 0) {
87  cgi->Com_Printf("%s Invalid Installation IDX\n", cgi->Cmd_Argv(0));
88  return;
89  }
90 
91  if (installation->ufoCapacity.max <= installation->ufoCapacity.cur) {
92  cgi->Com_Printf("%s The selected installation has no spare capacity\n", cgi->Cmd_Argv(0));
93  return;
94  }
95 
96  Com_sprintf(cp_messageBuffer, lengthof(cp_messageBuffer), _("Recovered %s from the battlefield. UFO is being transported to %s."),
97  UFO_GetName(ufo), installation->name);
98  MS_AddNewMessage(_("UFO Recovery"), cp_messageBuffer);
99 
100  DateTime date = DateTime(ccs.date) + DateTime((int) RECOVERY_DELAY, 0);
101  US_StoreUFO(ufo, installation, date, condition);
102 }
103 
108 static void UR_DialogInitSell_f (void)
109 {
110  if (cgi->Cmd_Argc() < 2) {
111  cgi->Com_Printf("Usage: %s <ufoType>\n", cgi->Cmd_Argv(0));
112  return;
113  }
114 
115  const aircraft_t* ufo = AIR_GetAircraft(cgi->Cmd_Argv(1));
116  if (ufo == nullptr) {
117  cgi->Com_Printf("%s Invalid ufo Type\n", cgi->Cmd_Argv(0));
118  return;
119  }
120 
121  NAT_Foreach(nation) {
122  const nationInfo_t* stats = NAT_GetCurrentMonthInfo(nation);
123  int price;
124 
125  price = (int) (ufo->price * (.85f + frand() * .3f));
126  /* Nation will pay less if corrupted */
127  price = (int) (price * exp(-stats->xviInfection / 20.0f));
128 
129  cgi->UI_ExecuteConfunc("ui_uforecovery_nations %s \"%s\" %d %s %.2f",
130  nation->id,
131  _(nation->name),
132  price,
134  stats->happiness
135  );
136  }
137 }
138 
143 static void UR_DialogStartSell_f (void)
144 {
145  if (cgi->Cmd_Argc() < 4) {
146  cgi->Com_Printf("Usage: %s <ufoID> <nationId> <price>\n", cgi->Cmd_Argv(0));
147  return;
148  }
149 
150  const nation_t* nation = NAT_GetNationByID(cgi->Cmd_Argv(2));
151  if (nation == nullptr) {
152  cgi->Com_Printf("%s: Nation not found\n", cgi->Cmd_Argv(0));
153  return;
154  }
155 
156  int price = atoi(cgi->Cmd_Argv(3));
157  if (price <= 0) {
158  cgi->Com_Printf("%s: Invalid price\n", cgi->Cmd_Argv(0));
159  return;
160  }
161 
162  Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("Recovered %s from the battlefield. UFO sold to nation %s, gained %i credits."),
163  cgi->Cmd_Argv(1), _(nation->name), price);
164  MS_AddNewMessage(_("UFO Recovery"), cp_messageBuffer);
165  CP_UpdateCredits(ccs.credits + price);
166 
167  /* update nation happiness */
168  NAT_Foreach(nat) {
169  float ufoHappiness;
170 
171  assert(nat);
172  if (nat == nation)
173  /* nation is happy because it got the UFO */
174  ufoHappiness = HAPPINESS_UFO_SALE_GAIN;
175  else
176  /* nation is unhappy because it wanted the UFO */
177  ufoHappiness = HAPPINESS_UFO_SALE_LOSS;
178 
179  NAT_SetHappiness(ccs.curCampaign->minhappiness, nat, nat->stats[0].happiness + ufoHappiness);
180  }
181 }
182 
183 
184 /* --- UFO storage management --- */
185 
186 
191 const char* US_StoredUFOStatus (const storedUFO_t* ufo)
192 {
193  assert(ufo);
194 
195  if (ufo->disassembly != nullptr)
196  return "disassembling";
197 
198  switch (ufo->status) {
199  case SUFO_STORED:
200  return "stored";
201  case SUFO_RECOVERED:
202  case SUFO_TRANSFERED:
203  return "transferring";
204  default:
205  return "unknown";
206  }
207 }
208 
213 static void US_SelectStoredUfo_f (void)
214 {
215  const storedUFO_t* ufo;
216 
217  if (cgi->Cmd_Argc() < 2 || (ufo = US_GetStoredUFOByIDX(atoi(cgi->Cmd_Argv(1)))) == nullptr) {
218  cgi->UI_ExecuteConfunc("show_storedufo -");
219  return;
220  }
221 
222  const char* ufoName = UFO_GetName(ufo->ufoTemplate);
223  const char* status = US_StoredUFOStatus(ufo);
224  const char* eta;
225 
226  if (Q_streq(status, "transferring")) {
228  } else {
229  eta = "-";
230  }
231 
232  cgi->UI_ExecuteConfunc("show_storedufo %d \"%s\" %3.0f \"%s\" \"%s\" \"%s\" \"%s\"", ufo->idx, ufoName, ufo->condition * 100, ufo->ufoTemplate->model, status, eta, ufo->installation->name);
233 }
234 
235 
240 static void US_DestroyStoredUFO_f (void)
241 {
242  if (cgi->Cmd_Argc() < 2) {
243  cgi->Com_DPrintf(DEBUG_CLIENT, "Usage: %s <idx> [0|1]\nWhere the second, optional parameter is the confirmation.\n", cgi->Cmd_Argv(0));
244  return;
245  }
246  storedUFO_t* ufo = US_GetStoredUFOByIDX(atoi(cgi->Cmd_Argv(1)));
247  if (!ufo) {
248  cgi->Com_DPrintf(DEBUG_CLIENT, "Stored UFO with idx: %i does not exist\n", atoi(cgi->Cmd_Argv(1)));
249  return;
250  }
251 
252  /* Ask 'Are you sure?' by default */
253  if (cgi->Cmd_Argc() < 3 || !atoi(cgi->Cmd_Argv(2))) {
254  char command[128];
255 
256  Com_sprintf(command, sizeof(command), "ui_pop; ui_destroystoredufo %d 1; mn_installation_select %d;", ufo->idx, ufo->installation->idx);
257  cgi->UI_PopupButton(_("Destroy stored UFO"), _("Do you really want to destroy this stored UFO?"),
258  command, _("Destroy"), _("Destroy stored UFO"),
259  "ui_pop;", _("Cancel"), _("Forget it"),
260  nullptr, nullptr, nullptr);
261  return;
262  }
263  US_RemoveStoredUFO(ufo);
264  cgi->Cmd_ExecuteString("mn_installation_select %d", ufo->installation->idx);
265 }
266 
270 static void US_FillUFOTransfer_f (void)
271 {
272  if (cgi->Cmd_Argc() < 2) {
273  cgi->Com_DPrintf(DEBUG_CLIENT, "Usage: %s <idx>\n", cgi->Cmd_Argv(0));
274  return;
275  }
276 
277  storedUFO_t* ufo = US_GetStoredUFOByIDX(atoi(cgi->Cmd_Argv(1)));
278  if (!ufo) {
279  cgi->Com_DPrintf(DEBUG_CLIENT, "Stored UFO with idx: %i does not exist\n", atoi(cgi->Cmd_Argv(1)));
280  return;
281  }
282 
283  cgi->UI_ExecuteConfunc("ufotransferlist_clear");
285  if (ins == ufo->installation)
286  continue;
287  nation_t* nat = GEO_GetNation(ins->pos);
288  const char* nationName = nat ? _(nat->name) : "";
289  const int freeSpace = std::max(0, ins->ufoCapacity.max - ins->ufoCapacity.cur);
290  cgi->UI_ExecuteConfunc("ufotransferlist_addyard %d \"%s\" \"%s\" %d %d", ins->idx, ins->name, nationName, freeSpace, ins->ufoCapacity.max);
291  }
292 }
293 
297 static void US_FillUFOTransferUFOs_f (void)
298 {
299  if (cgi->Cmd_Argc() < 2) {
300  cgi->Com_DPrintf(DEBUG_CLIENT, "Usage: %s <idx>\n", cgi->Cmd_Argv(0));
301  return;
302  }
303 
304  installation_t* ins = INS_GetByIDX(atoi(cgi->Cmd_Argv(1)));
305  if (!ins) {
306  cgi->Com_DPrintf(DEBUG_CLIENT, "Installation with idx: %i does not exist\n", atoi(cgi->Cmd_Argv(1)));
307  return;
308  }
309 
310  cgi->UI_ExecuteConfunc("ufotransferlist_clearufos %d", ins->idx);
311  US_Foreach(ufo) {
312  if (ufo->installation != ins)
313  continue;
314  cgi->UI_ExecuteConfunc("ufotransferlist_addufos %d %d \"%s\"", ins->idx, ufo->idx, ufo->ufoTemplate->model);
315  }
316 }
317 
321 static void US_TransferUFO_f (void)
322 {
323  storedUFO_t* ufo;
324  installation_t* ins = nullptr;
325 
326  if (cgi->Cmd_Argc() < 3) {
327  cgi->Com_Printf("Usage: %s <stored-ufo-idx> <ufoyard-idx>\n", cgi->Cmd_Argv(0));
328  return;
329  }
330  ufo = US_GetStoredUFOByIDX(atoi(cgi->Cmd_Argv(1)));
331  if (ufo == nullptr) {
332  cgi->Com_Printf("Stored ufo with idx %i not found.\n", atoi(cgi->Cmd_Argv(1)));
333  return;
334  }
335  ins = INS_GetByIDX(atoi(cgi->Cmd_Argv(2)));
336  if (!ins) {
337  cgi->Com_Printf("Installation with idx: %i does not exist\n", atoi(cgi->Cmd_Argv(2)));
338  return;
339  }
340  US_TransferUFO(ufo, ins);
341 }
342 
343 static const cmdList_t ufoRecoveryCallbacks[] = {
344  {"cp_uforecovery_sell_init", UR_DialogInitSell_f, "Function to initialize sell recovered UFO to desired nation."},
345  {"cp_uforecovery_store_init", UR_DialogInitStore_f, "Function to initialize store recovered UFO in desired base."},
346  {"cp_uforecovery_store_start", UR_DialogStartStore_f, "Function to start UFO recovery processing."},
347  {"cp_uforecovery_sell_start", UR_DialogStartSell_f, "Function to start UFO selling processing."},
348  {"ui_selectstoredufo", US_SelectStoredUfo_f, "Send Stored UFO data to the UI"},
349  {"ui_destroystoredufo", US_DestroyStoredUFO_f, "Destroy stored UFO"},
350  {"ui_fill_ufotransfer", US_FillUFOTransfer_f, "Fills UFO Yard UI with transfer destinations"},
351  {"ui_selecttransferyard", US_FillUFOTransferUFOs_f, "Send Stored UFOs of the destination UFO Yard"},
352  {"ui_transferufo", US_TransferUFO_f, "Transfer stored UFO to another UFO Yard"},
353  {nullptr, nullptr, nullptr}
354 };
355 
356 void UR_InitCallbacks (void)
357 {
358  cgi->Cmd_TableAddList(ufoRecoveryCallbacks);
359 }
360 
362 {
363  cgi->Cmd_TableRemoveList(ufoRecoveryCallbacks);
364 }
void UR_ShutdownCallbacks(void)
static void US_DestroyStoredUFO_f(void)
Destroys a stored UFO.
const nationInfo_t * NAT_GetCurrentMonthInfo(const nation_t *const nation)
Get the current month nation stats.
Definition: cp_nation.cpp:133
nation_t * NAT_GetNationByID(const char *nationID)
Return a nation-pointer by the nations id.
Definition: cp_nation.cpp:64
Store capacities in base.
Definition: cp_capacity.h:41
const char * NAT_GetHappinessString(const float happiness)
Translates the nation happiness float value to a string.
Definition: cp_nation.cpp:144
#define _(String)
Definition: cl_shared.h:44
int Date_DateToSeconds(const DateTime &date)
Convert a date to seconds.
Definition: cp_time.cpp:228
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition: shared.cpp:494
static void UR_DialogStartStore_f(void)
Function to start UFO recovery process.
const aircraft_t * AIR_GetAircraftSilent(const char *name)
Searches the global array of aircraft types for a given aircraft.
Detailed information about the nation relationship (currently per month, but could be used elsewhere)...
Definition: cp_nation.h:35
Class describing a point of time.
Definition: DateTime.h:30
char * model
Definition: cp_aircraft.h:124
storedUFO_t * US_StoreUFO(const aircraft_t *ufoTemplate, installation_t *installation, DateTime &date, float condition)
Adds an UFO to the storage.
#define INS_ForeachOfType(var, installationType)
const aircraft_t * AIR_GetAircraft(const char *name)
Searches the global array of aircraft types for a given aircraft.
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
const char *IMPORT * Cmd_Argv(int n)
const char * UFO_GetName(const aircraft_t *ufocraft)
Returns name of the UFO if UFO has been researched.
Definition: cp_ufo.cpp:243
Nation definition.
Definition: cp_nation.h:46
Structure for stored UFOs.
A installation with all it&#39;s data.
uiMessageListNodeMessage_t * MS_AddNewMessage(const char *title, const char *text, messageType_t type, technology_t *pedia, bool popup, bool playSound)
Adds a new message to message stack.
Definition: cp_messages.cpp:63
UFO recovery and storing callback header file.
static void UR_DialogInitSell_f(void)
Function to initialize list to sell recovered UFO to desired nation.
#define INS_Foreach(var)
int xviInfection
Definition: cp_nation.h:40
void US_RemoveStoredUFO(storedUFO_t *ufo)
Removes an UFO from the storage.
float happiness
Definition: cp_nation.h:39
#define DEBUG_CLIENT
Definition: defines.h:59
#define NAT_Foreach(var)
iterates trough nations
Definition: cp_nation.h:80
DateTime arrive
void UR_InitCallbacks(void)
void NAT_SetHappiness(const float minhappiness, nation_t *nation, const float happiness)
Updates the nation happiness.
Definition: cp_nation.cpp:189
float minhappiness
Definition: cp_campaign.h:187
#define US_Foreach(var)
capacities_t ufoCapacity
const cgame_import_t * cgi
void CP_UpdateCredits(int credits)
Sets credits and update mn_credits cvar.
UFO recovery and storing.
ccs_t ccs
Definition: cp_campaign.cpp:63
production_t * disassembly
Campaign geoscape time header.
Header for Geoscape management.
#define HAPPINESS_UFO_SALE_GAIN
const aircraft_t * ufoTemplate
char cp_messageBuffer[MAX_MESSAGE_TEXT]
Definition: cp_messages.cpp:33
#define HAPPINESS_UFO_SALE_LOSS
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
storedUFO_t * US_GetStoredUFOByIDX(const int idx)
Returns a stored ufo.
An aircraft with all it&#39;s data.
Definition: cp_aircraft.h:115
static void US_FillUFOTransferUFOs_f(void)
Send Stored UFOs of the destination UFO Yard.
#define RECOVERY_DELAY
static const cmdList_t ufoRecoveryCallbacks[]
campaign_t * curCampaign
Definition: cp_campaign.h:378
char name[MAX_VAR]
float frand(void)
Return random values between 0 and 1.
Definition: mathlib.cpp:506
installation_t * installation
#define AIR_IsUFO(aircraft)
Definition: cp_aircraft.h:206
class DateTime date
Definition: cp_campaign.h:246
Definition: cmd.h:86
bool US_TransferUFO(storedUFO_t *ufo, installation_t *ufoyard)
Start transferring of a stored UFO.
storedUFOStatus_t status
static void US_FillUFOTransfer_f(void)
Fills UFO Yard UI with transfer destinations.
static void US_SelectStoredUfo_f(void)
Send Stored UFO data to the UI.
Header file for single player campaign control.
static void US_TransferUFO_f(void)
Callback to start the transfer of a stored UFO.
static void UR_DialogStartSell_f(void)
Function to start UFO selling process.
#define lengthof(x)
Definition: shared.h:105
#define Q_streq(a, b)
Definition: shared.h:136
static void UR_DialogInitStore_f(void)
Function to initialize list of storage locations for recovered UFO.
int credits
Definition: cp_campaign.h:243
const char * name
Definition: cp_nation.h:48
nation_t * GEO_GetNation(const vec2_t pos)
Translate nation map color to nation.
const char * CP_SecondConvert(int second)
Converts a number of second into a char to display.
Definition: cp_time.cpp:57
const char * US_StoredUFOStatus(const storedUFO_t *ufo)
Returns string representation of the stored UFO&#39;s status.
installation_t * INS_GetByIDX(int idx)
Get installation by it&#39;s index.