UFO: Alien Invasion
cp_employee_callbacks.cpp
Go to the documentation of this file.
1 
6 /*
7 Copyright (C) 2002-2022 UFO: Alien Invasion.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, 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 */
29 #include "cp_employee_callbacks.h"
30 #include "cp_employee.h"
31 
33 static Employee* selectedEmployee = nullptr;
34 /* Holds the current active employee category */
35 static 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 
46 static 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 
61 static 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 
92 static 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 
175 static 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 
194 static 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 
232 static 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 
282 static 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 
323 static 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 
353 static 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 
368 void E_InitCallbacks (void)
369 {
370  cgi->Cmd_TableAddList(employeeCmds);
371 }
372 
377 {
378  cgi->Cmd_TableRemoveList(employeeCmds);
379 }
static void E_EmployeeHire_f(void)
Callback for employee_hire command.
QGL_EXTERN GLint GLenum type
Definition: r_gl.h:94
static void E_EmployeeList_f(void)
Will fill the list with employees.
void E_ShutdownCallbacks(void)
Unregister UI callbacks.
static void E_EmployeeSelect(Employee *employee)
cvar_t *IMPORT * Cvar_Set(const char *varName, const char *value,...) __attribute__((format(__printf__
A base with all it&#39;s data.
Definition: cp_base.h:84
#define E_Foreach(employeeType, var)
Definition: cp_employee.h:122
const aircraft_t * AIR_IsEmployeeInAircraft(const Employee *employee, const aircraft_t *aircraft)
Tells you if an employee is assigned to an aircraft.
Header file for menu callback functions used for hire/fire employee menu.
#define _(String)
Definition: cl_shared.h:44
int E_CountAllHired(const base_t *const base, const bool peopleOnly)
Counts all hired employees of a given base.
static const char * E_GetEmployeeTypeString(employeeType_t type)
Convert employeeType_t to string id.
void E_InitCallbacks(void)
Register UI callbacks.
Describes a character with all its attributes.
Definition: chr_shared.h:388
base_t * B_GetCurrentSelectedBase(void)
returns the currently selected base
Definition: cp_base.cpp:1578
character_t chr
Definition: cp_employee.h:119
bool isHired() const
Definition: cp_employee.h:86
cvar_t *IMPORT * Cvar_ForceSet(const char *varName, const char *value)
const char *IMPORT * Cvar_GetString(const char *varName)
const char *IMPORT * Cmd_Argv(int n)
char name[MAX_VAR]
Definition: cp_aircraft.h:121
int E_CountHired(const base_t *const base, employeeType_t type)
Counts hired employees of a given type in a given base.
base_t * B_GetFoundedBaseByIDX(int baseIdx)
Array bound check for the base index.
Definition: cp_base.cpp:326
bool E_HireEmployee(base_t *base, Employee *employee)
Hires the employee in a base.
static Employee * selectedEmployee
bool E_DeleteEmployee(Employee *employee)
Removes the employee completely from the game (buildings + global list).
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition: shared.cpp:457
#define ERR_DROP
Definition: common.h:211
#define DEBUG_CLIENT
Definition: defines.h:59
Header for employee related stuff.
void *IMPORT * LIST_GetByIdx(linkedList_t *list, int index)
#define MAX_VAR
Definition: shared.h:36
Header file for hospital related stuff.
static int employeesInCurrentList
const cgame_import_t * cgi
employeeType_t
The types of employees.
Definition: cp_employee.h:30
static void E_EmployeeSelect_f(void)
Callback function that updates the character cvars when calling employee_select.
static void E_EmployeeDelete_f(void)
This removes an employee from the global list so that he/she is no longer hireable.
QGL_EXTERN GLuint count
Definition: r_gl.h:99
#define CAP_GetMax(base, capacity)
Definition: cp_capacity.h:51
An aircraft with all it&#39;s data.
Definition: cp_aircraft.h:115
static int employeeCategory
static linkedList_t * employeeList
static Employee * E_GetEmployeeByMenuIndex(int num)
Find an hired or free employee by the menu index.
bool unhire()
Fires an employee.
static const cmdList_t employeeCmds[]
List of UI command callbacks.
bool HOS_NeedsHealing(const character_t &chr)
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
Definition: cmd.h:86
static void E_GetCounts_f(void)
Returns the number of employees hired on a base for the UI.
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.
static void E_ChangeName_f(void)
Change the name of the selected actor.
Header file for single player campaign control.
char name[MAX_VAR]
Definition: chr_shared.h:390
static void E_UpdateGUICount_f(void)
Update GUI with the current number of employee per category.