UFO: Alien Invasion
Loading...
Searching...
No Matches
cp_uforecovery_callbacks.cpp
Go to the documentation of this file.
1
7
8/*
9Copyright (C) 2002-2025 UFO: Alien Invasion.
10
11This program is free software; you can redistribute it and/or
12modify it under the terms of the GNU General Public License
13as published by the Free Software Foundation; either version 2
14of the License, or (at your option) any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19
20See the GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with this program; if not, write to the Free Software
24Foundation, 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
45static 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
65static 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
108static 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
143static 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
191const 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
213static 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")) {
227 eta = CP_SecondConvert(Date_DateToSeconds(ufo->arrive - ccs.date));
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
240static 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 }
264 cgi->Cmd_ExecuteString("mn_installation_select %d", ufo->installation->idx);
265}
266
270static 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
297static 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
321static 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
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
357{
358 cgi->Cmd_TableAddList(ufoRecoveryCallbacks);
359}
360
362{
363 cgi->Cmd_TableRemoveList(ufoRecoveryCallbacks);
364}
DateTime class definition.
Share stuff between the different cgame implementations.
#define _(String)
Definition cl_shared.h:44
Class describing a point of time.
Definition DateTime.h:31
const aircraft_t * AIR_GetAircraft(const char *name)
Searches the global array of aircraft types for a given aircraft.
const aircraft_t * AIR_GetAircraftSilent(const char *name)
Searches the global array of aircraft types for a given aircraft.
#define AIR_IsUFO(aircraft)
void CP_UpdateCredits(int credits)
Sets credits and update mn_credits cvar.
ccs_t ccs
Header file for single player campaign control.
const cgame_import_t * cgi
nation_t * GEO_GetNation(const vec2_t pos)
Translate nation map color to nation.
Header for Geoscape management.
installation_t * INS_GetByIDX(int idx)
Get installation by it's index.
@ INSTALLATION_UFOYARD
#define INS_ForeachOfType(var, installationType)
#define INS_Foreach(var)
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.
char cp_messageBuffer[MAX_MESSAGE_TEXT]
void NAT_SetHappiness(const float minhappiness, nation_t *nation, const float happiness)
Updates the nation happiness.
nation_t * NAT_GetNationByID(const char *nationID)
Return a nation-pointer by the nations id.
Definition cp_nation.cpp:64
const nationInfo_t * NAT_GetCurrentMonthInfo(const nation_t *const nation)
Get the current month nation stats.
const char * NAT_GetHappinessString(const float happiness)
Translates the nation happiness float value to a string.
#define NAT_Foreach(var)
iterates trough nations
Definition cp_nation.h:80
const char * CP_SecondConvert(int second)
Converts a number of second into a char to display.
Definition cp_time.cpp:57
int Date_DateToSeconds(const DateTime &date)
Convert a date to seconds.
Definition cp_time.cpp:228
Campaign geoscape time header.
const char * UFO_GetName(const aircraft_t *ufocraft)
Returns name of the UFO if UFO has been researched.
Definition cp_ufo.cpp:243
storedUFO_t * US_GetStoredUFOByIDX(const int idx)
Returns a stored ufo.
void US_RemoveStoredUFO(storedUFO_t *ufo)
Removes an UFO from the storage.
storedUFO_t * US_StoreUFO(const aircraft_t *ufoTemplate, installation_t *installation, DateTime &date, float condition)
Adds an UFO to the storage.
bool US_TransferUFO(storedUFO_t *ufo, installation_t *ufoyard)
Start transferring of a stored UFO.
UFO recovery and storing.
#define RECOVERY_DELAY
@ SUFO_STORED
@ SUFO_RECOVERED
@ SUFO_TRANSFERED
#define US_Foreach(var)
void UR_InitCallbacks(void)
static void US_SelectStoredUfo_f(void)
Send Stored UFO data to the UI.
static void US_TransferUFO_f(void)
Callback to start the transfer of a stored UFO.
static void UR_DialogInitStore_f(void)
Function to initialize list of storage locations for recovered UFO.
#define HAPPINESS_UFO_SALE_LOSS
static void US_FillUFOTransfer_f(void)
Fills UFO Yard UI with transfer destinations.
const char * US_StoredUFOStatus(const storedUFO_t *ufo)
Returns string representation of the stored UFO's status.
static void UR_DialogStartStore_f(void)
Function to start UFO recovery process.
static const cmdList_t ufoRecoveryCallbacks[]
static void US_DestroyStoredUFO_f(void)
Destroys a stored UFO.
static void UR_DialogInitSell_f(void)
Function to initialize list to sell recovered UFO to desired nation.
static void UR_DialogStartSell_f(void)
Function to start UFO selling process.
#define HAPPINESS_UFO_SALE_GAIN
void UR_ShutdownCallbacks(void)
static void US_FillUFOTransferUFOs_f(void)
Send Stored UFOs of the destination UFO Yard.
UFO recovery and storing callback header file.
#define DEBUG_CLIENT
Definition defines.h:59
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
float frand(void)
Return random values between 0 and 1.
Definition mathlib.cpp:506
#define Q_streq(a, b)
Definition shared.h:136
#define lengthof(x)
Definition shared.h:105
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition shared.cpp:494
An aircraft with all it's data.
char * model
Store capacities in base.
Definition cp_capacity.h:41
A installation with all it's data.
char name[MAX_VAR]
capacities_t ufoCapacity
Nation definition.
Definition cp_nation.h:46
const char * name
Definition cp_nation.h:48
Detailed information about the nation relationship (currently per month, but could be used elsewhere)...
Definition cp_nation.h:35
float happiness
Definition cp_nation.h:39
int xviInfection
Definition cp_nation.h:40
Structure for stored UFOs.
production_t * disassembly
DateTime arrive
const aircraft_t * ufoTemplate
storedUFOStatus_t status
installation_t * installation