UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
cp_uforecovery_callbacks.cpp
Go to the documentation of this file.
1 
8 /*
9 Copyright (C) 2002-2020 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 "../../cl_shared.h"
28 #include "../../ui/ui_dataids.h"
29 #include "cp_campaign.h"
30 #include "cp_ufo.h"
31 #include "cp_uforecovery.h"
33 #include "cp_geoscape.h"
34 #include "cp_time.h"
35 
36 #define HAPPINESS_UFO_SALE_GAIN 0.02
37 #define HAPPINESS_UFO_SALE_LOSS 0.005
38 
44 static void UR_DialogInitStore_f (void)
45 {
46  /* Check how many bases can store this UFO. */
47  INS_Foreach(installation) {
48  const capacities_t* capacity = &installation->ufoCapacity;
49  if (capacity->max > 0 && capacity->max > capacity->cur) {
50  cgi->UI_ExecuteConfunc("ui_uforecovery_ufoyards %d \"%s\" %d %d",
51  installation->idx,
52  installation->name,
53  std::max(capacity->max - capacity->cur, 0),
54  capacity->max
55  );
56  }
57  }
58 }
59 
64 static void UR_DialogStartStore_f (void)
65 {
66 
67  if (cgi->Cmd_Argc() < 4) {
68  cgi->Com_Printf("Usage: %s <ufoType> <damage> <installationIDX>\n", cgi->Cmd_Argv(0));
69  return;
70  }
71 
72  const aircraft_t* ufo = AIR_GetAircraftSilent(cgi->Cmd_Argv(1));
73  if (ufo == nullptr || !AIR_IsUFO(ufo)) {
74  cgi->Com_Printf("%s Invalid UFO type\n", cgi->Cmd_Argv(0));
75  return;
76  }
77 
78  float condition = atof(cgi->Cmd_Argv(2));
79  if (condition < 0.0f || condition > 100.0f) {
80  cgi->Com_Printf("%s Invalid UFO damage value\n", cgi->Cmd_Argv(0));
81  return;
82  }
83 
84  installation_t* installation = INS_GetByIDX(atoi(cgi->Cmd_Argv(3)));
85  if (installation == nullptr || installation->ufoCapacity.max <= 0) {
86  cgi->Com_Printf("%s Invalid Installation IDX\n", cgi->Cmd_Argv(0));
87  return;
88  }
89 
90  if (installation->ufoCapacity.max <= installation->ufoCapacity.cur) {
91  cgi->Com_Printf("%s The selected installation has no spare capacity\n", cgi->Cmd_Argv(0));
92  return;
93  }
94 
95  Com_sprintf(cp_messageBuffer, lengthof(cp_messageBuffer), _("Recovered %s from the battlefield. UFO is being transported to %s."),
96  UFO_GetName(ufo), installation->name);
97  MS_AddNewMessage(_("UFO Recovery"), cp_messageBuffer);
98  date_t date = ccs.date;
99  date.day += (int) RECOVERY_DELAY;
100 
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  eta = CP_SecondConvert(Date_DateToSeconds(&time));
229  } else {
230  eta = "-";
231  }
232 
233  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);
234 }
235 
236 
241 static void US_DestroyStoredUFO_f (void)
242 {
243  if (cgi->Cmd_Argc() < 2) {
244  cgi->Com_DPrintf(DEBUG_CLIENT, "Usage: %s <idx> [0|1]\nWhere the second, optional parameter is the confirmation.\n", cgi->Cmd_Argv(0));
245  return;
246  }
247  storedUFO_t* ufo = US_GetStoredUFOByIDX(atoi(cgi->Cmd_Argv(1)));
248  if (!ufo) {
249  cgi->Com_DPrintf(DEBUG_CLIENT, "Stored UFO with idx: %i does not exist\n", atoi(cgi->Cmd_Argv(1)));
250  return;
251  }
252 
253  /* Ask 'Are you sure?' by default */
254  if (cgi->Cmd_Argc() < 3 || !atoi(cgi->Cmd_Argv(2))) {
255  char command[128];
256 
257  Com_sprintf(command, sizeof(command), "ui_pop; ui_destroystoredufo %d 1; mn_installation_select %d;", ufo->idx, ufo->installation->idx);
258  cgi->UI_PopupButton(_("Destroy stored UFO"), _("Do you really want to destroy this stored UFO?"),
259  command, _("Destroy"), _("Destroy stored UFO"),
260  "ui_pop;", _("Cancel"), _("Forget it"),
261  nullptr, nullptr, nullptr);
262  return;
263  }
264  US_RemoveStoredUFO(ufo);
265  cgi->Cmd_ExecuteString("mn_installation_select %d", ufo->installation->idx);
266 }
267 
271 static void US_FillUFOTransfer_f (void)
272 {
273  if (cgi->Cmd_Argc() < 2) {
274  cgi->Com_DPrintf(DEBUG_CLIENT, "Usage: %s <idx>\n", cgi->Cmd_Argv(0));
275  return;
276  }
277 
278  storedUFO_t* ufo = US_GetStoredUFOByIDX(atoi(cgi->Cmd_Argv(1)));
279  if (!ufo) {
280  cgi->Com_DPrintf(DEBUG_CLIENT, "Stored UFO with idx: %i does not exist\n", atoi(cgi->Cmd_Argv(1)));
281  return;
282  }
283 
284  cgi->UI_ExecuteConfunc("ufotransferlist_clear");
286  if (ins == ufo->installation)
287  continue;
288  nation_t* nat = GEO_GetNation(ins->pos);
289  const char* nationName = nat ? _(nat->name) : "";
290  const int freeSpace = std::max(0, ins->ufoCapacity.max - ins->ufoCapacity.cur);
291  cgi->UI_ExecuteConfunc("ufotransferlist_addyard %d \"%s\" \"%s\" %d %d", ins->idx, ins->name, nationName, freeSpace, ins->ufoCapacity.max);
292  }
293 }
294 
298 static void US_FillUFOTransferUFOs_f (void)
299 {
300  if (cgi->Cmd_Argc() < 2) {
301  cgi->Com_DPrintf(DEBUG_CLIENT, "Usage: %s <idx>\n", cgi->Cmd_Argv(0));
302  return;
303  }
304 
305  installation_t* ins = INS_GetByIDX(atoi(cgi->Cmd_Argv(1)));
306  if (!ins) {
307  cgi->Com_DPrintf(DEBUG_CLIENT, "Installation with idx: %i does not exist\n", atoi(cgi->Cmd_Argv(1)));
308  return;
309  }
310 
311  cgi->UI_ExecuteConfunc("ufotransferlist_clearufos %d", ins->idx);
312  US_Foreach(ufo) {
313  if (ufo->installation != ins)
314  continue;
315  cgi->UI_ExecuteConfunc("ufotransferlist_addufos %d %d \"%s\"", ins->idx, ufo->idx, ufo->ufoTemplate->model);
316  }
317 }
318 
322 static void US_TransferUFO_f (void)
323 {
324  storedUFO_t* ufo;
325  installation_t* ins = nullptr;
326 
327  if (cgi->Cmd_Argc() < 3) {
328  cgi->Com_Printf("Usage: %s <stored-ufo-idx> <ufoyard-idx>\n", cgi->Cmd_Argv(0));
329  return;
330  }
331  ufo = US_GetStoredUFOByIDX(atoi(cgi->Cmd_Argv(1)));
332  if (ufo == nullptr) {
333  cgi->Com_Printf("Stored ufo with idx %i not found.\n", atoi(cgi->Cmd_Argv(1)));
334  return;
335  }
336  ins = INS_GetByIDX(atoi(cgi->Cmd_Argv(2)));
337  if (!ins) {
338  cgi->Com_Printf("Installation with idx: %i does not exist\n", atoi(cgi->Cmd_Argv(2)));
339  return;
340  }
341  US_TransferUFO(ufo, ins);
342 }
343 
344 static const cmdList_t ufoRecoveryCallbacks[] = {
345  {"cp_uforecovery_sell_init", UR_DialogInitSell_f, "Function to initialize sell recovered UFO to desired nation."},
346  {"cp_uforecovery_store_init", UR_DialogInitStore_f, "Function to initialize store recovered UFO in desired base."},
347  {"cp_uforecovery_store_start", UR_DialogStartStore_f, "Function to start UFO recovery processing."},
348  {"cp_uforecovery_sell_start", UR_DialogStartSell_f, "Function to start UFO selling processing."},
349  {"ui_selectstoredufo", US_SelectStoredUfo_f, "Send Stored UFO data to the UI"},
350  {"ui_destroystoredufo", US_DestroyStoredUFO_f, "Destroy stored UFO"},
351  {"ui_fill_ufotransfer", US_FillUFOTransfer_f, "Fills UFO Yard UI with transfer destinations"},
352  {"ui_selecttransferyard", US_FillUFOTransferUFOs_f, "Send Stored UFOs of the destination UFO Yard"},
353  {"ui_transferufo", US_TransferUFO_f, "Transfer stored UFO to another UFO Yard"},
354  {nullptr, nullptr, nullptr}
355 };
356 
357 void UR_InitCallbacks (void)
358 {
359  cgi->Cmd_TableAddList(ufoRecoveryCallbacks);
360 }
361 
363 {
364  cgi->Cmd_TableRemoveList(ufoRecoveryCallbacks);
365 }
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:132
nation_t * NAT_GetNationByID(const char *nationID)
Return a nation-pointer by the nations id.
Definition: cp_nation.cpp:63
storedUFOStatus_t status
storedUFO_t * US_StoreUFO(const aircraft_t *ufoTemplate, installation_t *installation, date_t date, float condition)
Adds an UFO to the storage.
Nation definition.
Definition: cp_nation.h:44
A installation with all it's data.
const char * NAT_GetHappinessString(const float happiness)
Translates the nation happiness float value to a string.
Definition: cp_nation.cpp:143
#define _(String)
Definition: cl_shared.h:43
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.
int credits
Definition: cp_campaign.h:242
const aircraft_t * AIR_GetAircraftSilent(const char *name)
Searches the global array of aircraft types for a given aircraft.
int xviInfection
Definition: cp_nation.h:38
const aircraft_t * ufoTemplate
int Date_DateToSeconds(const date_t *date)
Convert a date_t date to seconds.
Definition: cp_time.cpp:228
int day
Definition: common.h:291
date_t date
Definition: cp_campaign.h:245
#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 * name
Definition: cp_nation.h:46
const char * UFO_GetName(const aircraft_t *ufocraft)
Returns name of the UFO if UFO has been researched.
Definition: cp_ufo.cpp:243
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:61
UFO recovery and storing callback header file.
static void UR_DialogInitSell_f(void)
Function to initialize list to sell recovered UFO to desired nation.
float happiness
Definition: cp_nation.h:37
#define INS_Foreach(var)
void US_RemoveStoredUFO(storedUFO_t *ufo)
Removes an UFO from the storage.
#define DEBUG_CLIENT
Definition: defines.h:59
#define NAT_Foreach(var)
iterates trough nations
Definition: cp_nation.h:80
void UR_InitCallbacks(void)
void NAT_SetHappiness(const float minhappiness, nation_t *nation, const float happiness)
Updates the nation happiness.
Definition: cp_nation.cpp:188
#define US_Foreach(var)
installation_t * installation
const cgame_import_t * cgi
Structure for stored UFOs.
void CP_UpdateCredits(int credits)
Sets credits and update mn_credits cvar.
UFO recovery and storing.
ccs_t ccs
Definition: cp_campaign.cpp:62
capacities_t ufoCapacity
Definition: cmd.h:86
Engine-side time information in the game.
Definition: common.h:290
date_t Date_Substract(date_t a, const date_t &b)
Substract the second date from the first and return the result.
Definition: cp_time.cpp:285
Campaign geoscape time header.
production_t * disassembly
Header for Geoscape management.
char name[MAX_VAR]
#define HAPPINESS_UFO_SALE_GAIN
char cp_messageBuffer[MAX_MESSAGE_TEXT]
Definition: cp_messages.cpp:31
#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.
static void US_FillUFOTransferUFOs_f(void)
Send Stored UFOs of the destination UFO Yard.
#define RECOVERY_DELAY
static const cmdList_t ufoRecoveryCallbacks[]
float frand(void)
Return random values between 0 and 1.
Definition: mathlib.cpp:506
#define AIR_IsUFO(aircraft)
Definition: cp_aircraft.h:205
bool US_TransferUFO(storedUFO_t *ufo, installation_t *ufoyard)
Start transferring of a stored UFO.
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
Store capacities in base.
Definition: cp_capacity.h:41
An aircraft with all it's data.
Definition: cp_aircraft.h:114
campaign_t * curCampaign
Definition: cp_campaign.h:377
static void UR_DialogInitStore_f(void)
Function to initialize list of storage locations for recovered UFO.
float minhappiness
Definition: cp_campaign.h:186
char * model
Definition: cp_aircraft.h:123
nation_t * GEO_GetNation(const vec2_t pos)
Translate nation map color to nation.
const char *IMPORT * Cmd_Argv(int n)
const char * CP_SecondConvert(int second)
Converts a number of second into a char to display.
Definition: cp_time.cpp:56
const char * US_StoredUFOStatus(const storedUFO_t *ufo)
Returns string representation of the stored UFO's status.
Detailed information about the nation relationship (currently per month, but could be used elsewhere)...
Definition: cp_nation.h:33
installation_t * INS_GetByIDX(int idx)
Get installation by it's index.