UFO: Alien Invasion
Loading...
Searching...
No Matches
cp_employee_callbacks.cpp
Go to the documentation of this file.
1
5
6/*
7Copyright (C) 2002-2025 UFO: Alien Invasion.
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18See the GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24*/
25#include "../../cl_shared.h"
26#include "../../ui/ui_dataids.h"
27#include "cp_campaign.h"
28#include "cp_hospital.h" /* HOS_NeedsHealing */
30#include "cp_employee.h"
31
33static Employee* selectedEmployee = nullptr;
34/* Holds the current active employee category */
35static int employeeCategory = 0;
36
37/* List of (hired) emplyoees in the current category (employeeType). */
39/* How many employees in current list (changes on every category change, too) */
41
46static void E_UpdateGUICount_f (void)
47{
48 const base_t* base = B_GetCurrentSelectedBase();
49
50 if (!base)
51 return;
52
53 const int max = CAP_GetMax(base, CAP_EMPLOYEES);
54 cgi->Cvar_SetValue("mn_hiresoldiers", E_CountHired(base, EMPL_SOLDIER));
55 cgi->Cvar_SetValue("mn_hireworkers", E_CountHired(base, EMPL_WORKER));
56 cgi->Cvar_SetValue("mn_hirescientists", E_CountHired(base, EMPL_SCIENTIST));
57 cgi->Cvar_SetValue("mn_hirepilots", E_CountHired(base, EMPL_PILOT));
58 cgi->Cvar_Set("mn_hirepeople", "%d/%d", E_CountAllHired(base), max);
59}
60
61static void E_EmployeeSelect (Employee* employee)
62{
63 const base_t* base = B_GetCurrentSelectedBase();
64 if (!base)
65 return;
66
67 selectedEmployee = employee;
68 if (selectedEmployee) {
69 const character_t* chr = &selectedEmployee->chr;
70 /* mn_employee_hired is needed to allow renaming */
71 cgi->Cvar_SetValue("mn_employee_hired", selectedEmployee->isHired() ? 1 : 0);
72 cgi->Cvar_SetValue("mn_ucn", chr->ucn);
73
74 /* set info cvars */
75 cgi->CL_UpdateCharacterValues(chr);
76 }
77}
78
84{
85 return static_cast<Employee*>(cgi->LIST_GetByIdx(employeeList, num));
86}
87
92static void E_EmployeeList_f (void)
93{
94 const base_t* base = B_GetCurrentSelectedBase();
95
96 if (!base)
97 return;
98
99 if (cgi->Cmd_Argc() < 2) {
100 cgi->Com_Printf("Usage: %s <category> <employeeid>\n", cgi->Cmd_Argv(0));
101 return;
102 }
103
104 employeeCategory = atoi(cgi->Cmd_Argv(1));
107
108 int hiredEmployeeIdx;
109 if (cgi->Cmd_Argc() == 3)
110 hiredEmployeeIdx = atoi(cgi->Cmd_Argv(2));
111 else
112 hiredEmployeeIdx = -1;
113
114 /* reset the employee list */
116 cgi->LIST_Delete(&employeeList);
117 cgi->UI_ExecuteConfunc("hire_clear");
118
120 /* don't show employees of other bases */
121 if (e->isHired() && !e->isHiredInBase(base))
122 continue;
123 /* don't show employees being transferred to other bases */
124 if (e->transfer)
125 continue;
126 cgi->LIST_AddPointer(&employeeList, e);
127 const int needsHealing = HOS_NeedsHealing(e->chr) ? 1 : 0;
128 const aircraft_t* craft = AIR_IsEmployeeInAircraft(e, nullptr);
129 cgi->UI_ExecuteConfunc("hire_addemployee %i \"%s\" %i \"%s\"",
130 employeesInCurrentList, e->chr.name, needsHealing, craft ? craft->name : "");
131 if (e->isHired()) {
132 if (e->isAwayFromBase())
133 cgi->UI_ExecuteConfunc("employeedisable %i", employeesInCurrentList);
134 else
135 cgi->UI_ExecuteConfunc("employeefire %i", employeesInCurrentList);
136 } else {
137 cgi->UI_ExecuteConfunc("employeehire %i", employeesInCurrentList);
138 }
140 }
141
142 /* If the list is empty OR we are in pilots/scientists/workers-mode: don't show the model&stats. */
150 if (employeesInCurrentList == 0) {
151 cgi->Cvar_Set("mn_show_employee", "0");
152 } else {
154 cgi->Cvar_Set("mn_show_employee", "3");
155 else if (employeeCategory == EMPL_PILOT)
156 cgi->Cvar_Set("mn_show_employee", "2");
157 else
158 cgi->Cvar_Set("mn_show_employee", "1");
159 }
160 /* Select the current employee if name was changed or first one. Use the direct string
161 * execution here - otherwise the employeeCategory might be out of sync */
162 Employee* employee = nullptr;
163 if (hiredEmployeeIdx < 0 || selectedEmployee == nullptr)
164 employee = E_GetEmployeeByMenuIndex(0);
165 else
166 employee = selectedEmployee;
167
168 E_EmployeeSelect(employee);
169}
170
175static void E_ChangeName_f (void)
176{
177 Employee* employee = E_GetEmployeeFromChrUCN(cgi->Cvar_GetInteger("mn_ucn"));
178 if (!employee)
179 return;
180
181 /* employee name should not contain " */
182 if (!Com_IsValidName(cgi->Cvar_GetString("mn_name"))) {
183 cgi->Cvar_ForceSet("mn_name", employee->chr.name);
184 return;
185 }
186
187 Q_strncpyz(employee->chr.name, cgi->Cvar_GetString("mn_name"), sizeof(employee->chr.name));
188}
189
194static void E_EmployeeDelete_f (void)
195{
196 /* Check syntax. */
197 if (cgi->Cmd_Argc() < 2) {
198 cgi->Com_Printf("Usage: %s <num>\n", cgi->Cmd_Argv(0));
199 return;
200 }
201
202 /* num - menu index (line in text) */
203 int num = atoi(cgi->Cmd_Argv(1));
204
205 Employee* employee = E_GetEmployeeByMenuIndex(num);
206 /* empty slot selected */
207 if (!employee)
208 return;
209
210 if (employee->isHired()) {
211 if (!employee->unhire()) {
212 cgi->UI_DisplayNotice(_("Could not fire employee"), 2000, "employees");
213 cgi->Com_DPrintf(DEBUG_CLIENT, "Couldn't fire employee\n");
214 return;
215 }
216 }
217 E_DeleteEmployee(employee);
218 cgi->Cbuf_AddText("employee_init %i\n", employeeCategory);
219
220 num = std::max(0, num - 1);
221 cgi->Cbuf_AddText("employee_select %i\n", num);
222 cgi->Cbuf_AddText("hire_select %i\n", num);
223
224 cgi->Cbuf_AddText("employee_update_count\n");
225}
226
232static void E_EmployeeHire_f (void)
233{
235
236 if (!base)
237 return;
238
239 /* Check syntax. */
240 if (cgi->Cmd_Argc() < 2) {
241 cgi->Com_Printf("Usage: %s <+num>\n", cgi->Cmd_Argv(0));
242 return;
243 }
244
245 const char* arg = cgi->Cmd_Argv(1);
246
247 if (arg[0] == '+')
248 ++arg;
249
250 const int num = atoi(arg);
251
252 Employee* employee = E_GetEmployeeByMenuIndex(num);
253 /* empty slot selected */
254 if (!employee)
255 return;
256
257 if (employee->isHired()) {
258 if (!employee->unhire()) {
259 cgi->Com_DPrintf(DEBUG_CLIENT, "Couldn't fire employee\n");
260 cgi->UI_DisplayNotice(_("Could not fire employee"), 2000, "employees");
261 } else {
262 cgi->UI_ExecuteConfunc("employeehire %i", num);
263 }
264 } else {
265 if (!E_HireEmployee(base, employee)) {
266 cgi->Com_DPrintf(DEBUG_CLIENT, "Couldn't hire employee\n");
267 cgi->UI_DisplayNotice(_("Could not hire employee"), 2000, "employees");
268 cgi->UI_ExecuteConfunc("employeehire %i", num);
269 } else {
270 cgi->UI_ExecuteConfunc("employeefire %i", num);
271 }
272 }
273 E_EmployeeSelect(employee);
274 cgi->Cbuf_AddText("hire_select %i\n", num);
275
277}
278
282static void E_EmployeeSelect_f (void)
283{
284 /* Check syntax. */
285 if (cgi->Cmd_Argc() < 2) {
286 cgi->Com_Printf("Usage: %s <num>\n", cgi->Cmd_Argv(0));
287 return;
288 }
289
290 const int num = atoi(cgi->Cmd_Argv(1));
291 if (num < 0 || num >= employeesInCurrentList)
292 return;
293
295}
296
303{
304 switch (type) {
305 case EMPL_SOLDIER:
306 return "soldier";
307 case EMPL_SCIENTIST:
308 return "scientist";
309 case EMPL_WORKER:
310 return "worker";
311 case EMPL_PILOT:
312 return "pilot";
313 case EMPL_ROBOT:
314 return "ugv";
315 default:
316 cgi->Com_Error(ERR_DROP, "Unknown employee type '%i'\n", type);
317 }
318}
319
323static void E_GetCounts_f (void)
324{
325 if (cgi->Cmd_Argc() < 3) {
326 cgi->Com_Printf("Usage: %s <callback> <base-IDX>\n", cgi->Cmd_Argv(0));
327 return;
328 }
329
330 char callback[MAX_VAR];
331 Q_strncpyz(callback, cgi->Cmd_Argv(1), sizeof(callback));
332 const int baseIdx = atoi(cgi->Cmd_Argv(2));
333 const base_t* base = B_GetFoundedBaseByIDX(baseIdx);
334 if (base == nullptr) {
335 cgi->Com_Printf("E_GetCounts_f: Invalid base Idx given\n");
336 return;
337 }
338
339 for (int type = EMPL_SOLDIER; type < EMPL_ROBOT; type++) {
340 const int count = E_CountHired(base, (employeeType_t)type);
341 cgi->UI_ExecuteConfunc("%s %s %d %s",
342 callback,
344 count,
346 );
347 }
348}
349
353static const cmdList_t employeeCmds[] = {
354 {"employee_update_count", E_UpdateGUICount_f, "Callback to update the employee count of the current GUI"},
355 {"employee_init", E_EmployeeList_f, "Init function for employee hire menu"},
356 {"employee_delete", E_EmployeeDelete_f, "Remove an employee from the global employee list"},
357 {"employee_hire", E_EmployeeHire_f, nullptr},
358 {"employee_select", E_EmployeeSelect_f, nullptr},
359 {"employee_changename", E_ChangeName_f, "Change the name of an employee"},
360
361 {"ui_get_employee_counts", E_GetCounts_f, "Callback return the number of each employee types hired on a base"},
362 {nullptr, nullptr, nullptr}
363};
364
369{
370 cgi->Cmd_TableAddList(employeeCmds);
371}
372
377{
378 cgi->Cmd_TableRemoveList(employeeCmds);
379}
Share stuff between the different cgame implementations.
#define _(String)
Definition cl_shared.h:44
character_t chr
bool isHired() const
Definition cp_employee.h:86
bool unhire()
Fires an employee.
#define ERR_DROP
Definition common.h:211
const aircraft_t * AIR_IsEmployeeInAircraft(const Employee *employee, const aircraft_t *aircraft)
Tells you if an employee is assigned to an aircraft.
base_t * B_GetFoundedBaseByIDX(int baseIdx)
Array bound check for the base index.
Definition cp_base.cpp:326
base_t * B_GetCurrentSelectedBase(void)
returns the currently selected base
Definition cp_base.cpp:1578
Header file for single player campaign control.
const cgame_import_t * cgi
@ CAP_EMPLOYEES
Definition cp_capacity.h:31
#define CAP_GetMax(base, capacity)
Definition cp_capacity.h:51
bool E_DeleteEmployee(Employee *employee)
Removes the employee completely from the game (buildings + global list).
Employee * E_GetEmployeeFromChrUCN(int uniqueCharacterNumber)
Searches all employee for the ucn (character id).
int E_CountAllHired(const base_t *const base, const bool peopleOnly)
Counts all hired employees of a given base.
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.
bool E_HireEmployee(base_t *base, Employee *employee)
Hires the employee in a base.
Header for employee related stuff.
employeeType_t
The types of employees.
Definition cp_employee.h:30
@ EMPL_SOLDIER
Definition cp_employee.h:31
@ MAX_EMPL
Definition cp_employee.h:36
@ EMPL_ROBOT
Definition cp_employee.h:35
@ EMPL_PILOT
Definition cp_employee.h:34
@ EMPL_WORKER
Definition cp_employee.h:33
@ EMPL_SCIENTIST
Definition cp_employee.h:32
#define E_Foreach(employeeType, var)
static int employeeCategory
static const cmdList_t employeeCmds[]
List of UI command callbacks.
static const char * E_GetEmployeeTypeString(employeeType_t type)
Convert employeeType_t to string id.
static void E_EmployeeDelete_f(void)
This removes an employee from the global list so that he/she is no longer hireable.
void E_InitCallbacks(void)
Register UI callbacks.
static void E_UpdateGUICount_f(void)
Update GUI with the current number of employee per category.
static void E_EmployeeSelect(Employee *employee)
void E_ShutdownCallbacks(void)
Unregister UI callbacks.
static void E_EmployeeHire_f(void)
Callback for employee_hire command.
static void E_ChangeName_f(void)
Change the name of the selected actor.
static int employeesInCurrentList
static linkedList_t * employeeList
static Employee * E_GetEmployeeByMenuIndex(int num)
Find an hired or free employee by the menu index.
static void E_GetCounts_f(void)
Returns the number of employees hired on a base for the UI.
static Employee * selectedEmployee
static void E_EmployeeSelect_f(void)
Callback function that updates the character cvars when calling employee_select.
static void E_EmployeeList_f(void)
Will fill the list with employees.
Header file for menu callback functions used for hire/fire employee menu.
bool HOS_NeedsHealing(const character_t &chr)
Header file for hospital related stuff.
#define DEBUG_CLIENT
Definition defines.h:59
QGL_EXTERN GLuint count
Definition r_gl.h:99
QGL_EXTERN GLint GLenum type
Definition r_gl.h:94
#define MAX_VAR
Definition shared.h:36
bool Com_IsValidName(const char *input)
Checks whether the given input string is allowed to be used as a user-given name string for aircraft,...
Definition shared.cpp:612
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition shared.cpp:457
An aircraft with all it's data.
char name[MAX_VAR]
A base with all it's data.
Definition cp_base.h:84
Describes a character with all its attributes.
Definition chr_shared.h:388
char name[MAX_VAR]
Definition chr_shared.h:390