UFO: Alien Invasion
Loading...
Searching...
No Matches
cp_employee.cpp
Go to the documentation of this file.
1
6
7/*
8Copyright (C) 2002-2025 UFO: Alien Invasion.
9
10This program is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12as published by the Free Software Foundation; either version 2
13of the License, or (at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18
19See the GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License
22along with this program; if not, write to the Free Software
23Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24*/
25
26#include "../../cl_shared.h"
27#include "../cl_game.h" /* GAME_GetTeamDef */
28#include "../cl_game_team.h" /* character xml loading */
29#include "cp_campaign.h"
31#include "cp_rank.h"
32#include "cp_popup.h"
33#include "save/save_employee.h"
34
40{
41 return cgi->LIST_Count(ccs.employees[type]);
42}
43
50{
51 E_Foreach(type, employee) {
52 if (!employee->isHired())
53 return employee;
54 }
55
56 return nullptr;
57}
58
64{
65 const campaign_t* campaign = ccs.curCampaign;
66 const salary_t* salary = &campaign->salaries;
67 const rank_t* rank = CL_GetRankByIdx(this->chr.score.rank);
68 return salary->base[getType()] + rank->level * salary->rankBonus[getType()];
69}
70
76{
77 /* Check that employee is hired */
78 if (!isHired())
79 return false;
80
81 /* Check if employee is currently transferred. */
82 if (transfer)
83 return true;
84
85 /* for now only soldiers, ugvs and pilots can be assigned to an aircraft */
86 if (!isSoldier() && !isRobot() && !isPilot())
87 return false;
88
89 /* Crashed aircraft no longer belongs to any base but poor pilot/soldiers assigned
90 * to it are definitely away from the base so we need to iterate through all aircraft */
91 AIR_Foreach(aircraft) {
92 if (aircraft->homebase != baseHired)
93 continue;
94 if (!AIR_IsAircraftInBase(aircraft) && AIR_IsEmployeeInAircraft(this, aircraft))
95 return true;
96 }
97 return false;
98}
99
107void E_HireForBuilding (base_t* base, building_t* building, int num)
108{
109 if (num < 0)
110 num = building->maxEmployees;
111
112 if (num) {
113 employeeType_t employeeType;
114 switch (building->buildingType) {
115 case B_WORKSHOP:
116 employeeType = EMPL_WORKER;
117 break;
118 case B_LAB:
119 employeeType = EMPL_SCIENTIST;
120 break;
121 case B_HANGAR: /* the Dropship Hangar */
122 employeeType = EMPL_SOLDIER;
123 break;
124 case B_MISC:
125 cgi->Com_DPrintf(DEBUG_CLIENT, "E_HireForBuilding: Misc building type: %i with employees: %i.\n", building->buildingType, num);
126 return;
127 default:
128 cgi->Com_DPrintf(DEBUG_CLIENT, "E_HireForBuilding: Unknown building type: %i.\n", building->buildingType);
129 return;
130 }
131 /* don't try to hire more that available - see E_CreateEmployee */
132 num = std::min(num, E_CountByType(employeeType));
133 for (;num--;) {
134 assert(base);
135 if (!E_HireEmployeeByType(base, employeeType)) {
136 cgi->Com_DPrintf(DEBUG_CLIENT, "E_HireForBuilding: Hiring %i employee(s) of type %i failed.\n", num, employeeType);
137 return;
138 }
139 }
140 }
141}
142
151bool E_MoveIntoNewBase (Employee* employee, base_t* newBase)
152{
153 if (employee) {
154 base_t* oldBase = employee->baseHired;
155 employee->baseHired = newBase;
156 /* Remove employee from corresponding capacity */
157 switch (employee->getType()) {
158 case EMPL_WORKER:
159 if (oldBase != nullptr)
160 PR_UpdateProductionCap(oldBase, 0);
161 /* fall through */
162 case EMPL_PILOT:
163 case EMPL_SCIENTIST:
164 case EMPL_SOLDIER:
165 if (oldBase != nullptr)
166 CAP_AddCurrent(oldBase, CAP_EMPLOYEES, -1);
167 CAP_AddCurrent(newBase, CAP_EMPLOYEES, 1);
168 break;
169 case EMPL_ROBOT:
170 if (oldBase != nullptr)
173 break;
174 case MAX_EMPL:
175 break;
176 }
177 return true;
178 }
179
180 return false;
181}
182
190{
191 switch (type) {
192 case EMPL_SOLDIER:
193 return ngettext("Soldier", "Soldiers", n);
194 case EMPL_SCIENTIST:
195 return ngettext("Scientist", "Scientists", n);
196 case EMPL_WORKER:
197 return ngettext("Worker", "Workers", n);
198 case EMPL_PILOT:
199 return ngettext("Pilot", "Pilots", n);
200 case EMPL_ROBOT:
201 return ngettext("UGV", "UGVs", n);
202 default:
203 cgi->Com_Error(ERR_DROP, "Unknown employee type '%i'\n", type);
204 }
205}
206
214{
215 if (!type)
216 return MAX_EMPL;
217
218 /* employee types as string */
219 if (Q_streq(type, "EMPL_SCIENTIST"))
220 return EMPL_SCIENTIST;
221 else if (Q_streq(type, "EMPL_SOLDIER"))
222 return EMPL_SOLDIER;
223 else if (Q_streq(type, "EMPL_WORKER"))
224 return EMPL_WORKER;
225 else if (Q_streq(type, "EMPL_PILOT"))
226 return EMPL_PILOT;
227 else if (Q_streq(type, "EMPL_ROBOT"))
228 return EMPL_ROBOT;
229
230 /* human readable employee type strings */
231 if (Q_streq(type, "scientist"))
232 return EMPL_SCIENTIST;
233 else if (Q_streq(type, "soldier"))
234 return EMPL_SOLDIER;
235 else if (Q_streq(type, "worker"))
236 return EMPL_WORKER;
237 else if (Q_streq(type, "pilot"))
238 return EMPL_PILOT;
239 else if (Q_streq(type, "robot"))
240 return EMPL_ROBOT;
241 else if (Q_streq(type, "ugv"))
242 return EMPL_ROBOT;
243
244 return MAX_EMPL;
245}
246
254{
255 E_Foreach(EMPL_ROBOT, employee) {
256 if (!employee->isHired()) {
257 /* If no type was given we return the first ugv we find. */
258 if (!ugvType || employee->getUGV() == ugvType)
259 return employee;
260 }
261 }
262
263 return nullptr;
264}
265
273int E_GetHiredEmployees (const base_t* const base, employeeType_t type, linkedList_t** hiredEmployees)
274{
275 if (type >= MAX_EMPL) {
276 cgi->Com_Printf("E_GetHiredEmployees: Unknown EmployeeType: %i\n", type);
277 *hiredEmployees = nullptr;
278 return -1;
279 }
280
281 cgi->LIST_Delete(hiredEmployees);
282
283 E_Foreach(type, employee) {
284 if (!employee->isHired())
285 continue;
286 if (!employee->transfer && (!base || employee->isHiredInBase(base))) {
287 cgi->LIST_AddPointer(hiredEmployees, employee);
288 }
289 }
290
291 return cgi->LIST_Count(*hiredEmployees);
292}
293
301Employee* E_GetHiredRobot (const base_t* const base, const ugv_t* ugvType)
302{
303 linkedList_t* hiredEmployees = nullptr;
304 Employee* employee;
305
306 E_GetHiredEmployees(base, EMPL_ROBOT, &hiredEmployees);
307
308 employee = nullptr;
309 LIST_Foreach(hiredEmployees, Employee, e) {
310 if ((e->getUGV() == ugvType || !ugvType) /* If no type was given we return the first ugv we find. */
311 && e->isHiredInBase(base)) { /* It has to be in the defined base. */
312 assert(e->isHired());
313 employee = e;
314 break;
315 }
316 }
317
318 cgi->LIST_Delete(&hiredEmployees);
319
320 if (!employee)
321 cgi->Com_DPrintf(DEBUG_CLIENT, "Could not get unhired ugv/robot.\n");
322
323 return employee;
324}
325
335{
336 E_Foreach(type, employee) {
337 if (!employee->isHiredInBase(base))
338 continue;
339 if (employee->isAssigned())
340 return employee;
341 }
342 return nullptr;
343}
344
354{
355 E_Foreach(type, employee) {
356 if (!employee->isHiredInBase(base))
357 continue;
358 if (employee->transfer)
359 continue;
360 if (!employee->isAssigned())
361 return employee;
362 }
363 return nullptr;
364}
365
373bool E_HireEmployee (base_t* base, Employee* employee)
374{
375 if (CAP_GetFreeCapacity(base, CAP_EMPLOYEES) <= 0) {
376 CP_Popup(_("Not enough quarters"), _("You don't have enough quarters for your employees.\nBuild more quarters."));
377 return false;
378 }
379
380 if (employee) {
381 /* Now uses quarter space. */
382 employee->baseHired = base;
383 /* Update other capacities */
384 switch (employee->getType()) {
385 case EMPL_WORKER:
388 break;
389 case EMPL_PILOT:
390 AIR_AutoAddPilotToAircraft(base, employee);
391 /* fall through */
392 case EMPL_SCIENTIST:
393 case EMPL_SOLDIER:
396 break;
397 case EMPL_ROBOT:
399 break;
400 case MAX_EMPL:
401 break;
402 }
403 return true;
404 }
405 return false;
406}
407
415{
416 Employee* employee = E_GetUnhired(type);
417 return employee ? E_HireEmployee(base, employee) : false;
418}
419
426bool E_HireRobot (base_t* base, const ugv_t* ugvType)
427{
428 Employee* employee = E_GetUnhiredRobot(ugvType);
429 return employee ? E_HireEmployee(base, employee) : false;
430}
431
436{
437 if (!baseHired)
438 return false;
439
440 /* Remove employee from building/tech/production/aircraft). */
441 switch (_type) {
442 case EMPL_SCIENTIST:
443 if (isAssigned())
445 break;
446 case EMPL_ROBOT:
447 case EMPL_SOLDIER:
448 /* Remove soldier from aircraft/team if he was assigned to one. */
449 if (AIR_IsEmployeeInAircraft(this, nullptr))
450 AIR_RemoveEmployee(this, nullptr);
451 break;
452 case EMPL_PILOT:
454 break;
455 case EMPL_WORKER:
456 default:
457 break;
458 }
459
460 return true;
461}
462
467{
468 /* Destroy the inventory of the employee (carried items will remain in base->storage) */
469 cgi->INV_DestroyInventory(&chr.inv);
470}
471
481{
482 if (!isHired() || transfer) {
483 cgi->Com_DPrintf(DEBUG_CLIENT, "Could not fire employee\n");
484 return false;
485 }
486
487 unassign();
488 unequip();
489
490 /* Remove employee from corresponding capacity */
491 switch (_type) {
492 case EMPL_WORKER:
494 /* fall through */
495 case EMPL_PILOT:
496 case EMPL_SCIENTIST:
497 case EMPL_SOLDIER:
499 break;
500 case EMPL_ROBOT:
502 break;
503 case MAX_EMPL:
504 break;
505 }
506
507 /* Set all employee-tags to 'unhired'. */
508 baseHired = nullptr;
509
510 return true;
511}
512
519{
520 if (!base)
521 return;
522
523 assert(type < MAX_EMPL);
524
525 E_Foreach(type, employee) {
526 if (!employee->isHiredInBase(base))
527 continue;
528 employee->unhire();
529 }
530}
531
541{
542 const char* teamID;
543 char teamDefName[MAX_VAR];
544 const char* rank;
545
546 if (type >= MAX_EMPL)
547 return nullptr;
548
549 Employee employee(type, nation, ugvType);
550
551 teamID = GAME_CP_GetTeamDef();
552
553 /* Generate character stats, models & names. */
554 switch (type) {
555 case EMPL_SOLDIER:
556 rank = "rifleman";
557 Q_strncpyz(teamDefName, teamID, sizeof(teamDefName));
558 break;
559 case EMPL_SCIENTIST:
560 rank = "scientist";
561 Com_sprintf(teamDefName, sizeof(teamDefName), "%s_scientist", teamID);
562 break;
563 case EMPL_PILOT:
564 rank = "pilot";
565 Com_sprintf(teamDefName, sizeof(teamDefName), "%s_pilot", teamID);
566 break;
567 case EMPL_WORKER:
568 rank = "worker";
569 Com_sprintf(teamDefName, sizeof(teamDefName), "%s_worker", teamID);
570 break;
571 case EMPL_ROBOT:
572 if (ugvType == nullptr)
573 cgi->Com_Error(ERR_DROP, "E_CreateEmployee: no type given for generation of EMPL_ROBOT employee.");
574
575 rank = "ugv";
576
577 Com_sprintf(teamDefName, sizeof(teamDefName), "%s%s", teamID, ugvType->actors);
578 break;
579 default:
580 cgi->Com_Error(ERR_DROP, "E_CreateEmployee: Unknown employee type\n");
581 }
582
583 cgi->CL_GenerateCharacter(&employee.chr, teamDefName);
584 employee.chr.score.rank = CL_GetRankIdx(rank);
585
586 cgi->Com_DPrintf(DEBUG_CLIENT, "Generate character for type: %i\n", type);
587
588 return &LIST_Add(&ccs.employees[type], employee);
589}
590
603{
605
606 if (!employee)
607 return false;
608
609 type = employee->getType();
610
611 /* Fire the employee. This will also:
612 * 1) remove him from buildings&work
613 * 2) remove his inventory */
614
615 if (employee->baseHired) {
616 /* make sure that this employee is really unhired */
617 employee->transfer = false;
618 employee->unhire();
619 }
620
621 /* Remove the employee from the global list. */
622 return cgi->LIST_Remove(&ccs.employees[type], (void*) employee);
623}
624
631{
632 int i;
633
634 for (i = EMPL_SOLDIER; i < MAX_EMPL; i++) {
636 E_Foreach(type, employee) {
637 if (base == nullptr || employee->isHiredInBase(base))
638 E_DeleteEmployee(employee);
639 }
640 }
641}
642
649int E_CountHired (const base_t* const base, employeeType_t type)
650{
651 int count = 0;
652
653 E_Foreach(type, employee) {
654 if (!employee->isHired())
655 continue;
656 if (!base || employee->isHiredInBase(base))
657 count++;
658 }
659 return count;
660}
661
668int E_CountHiredRobotByType (const base_t* const base, const ugv_t* ugvType)
669{
670 int count = 0;
671
672 E_Foreach(EMPL_ROBOT, employee) {
673 if (!employee->isHired())
674 continue;
675 if (employee->getUGV() == ugvType && (!base || employee->isHiredInBase(base)))
676 count++;
677 }
678 return count;
679}
680
681
688int E_CountAllHired (const base_t* const base, const bool peopleOnly)
689{
690 if (!base)
691 return 0;
692
693 int count = 0;
694 for (int i = 0; i < MAX_EMPL; i++) {
696 if (peopleOnly && i == EMPL_ROBOT)
697 continue;
698 count += E_CountHired(base, type);
699 }
700
701 return count;
702}
703
710{
711 int count = 0;
712
713 E_Foreach(type, employee) {
714 if (!employee->isHired())
715 count++;
716 }
717 return count;
718}
719
726{
727 int count = 0;
728
729 E_Foreach(EMPL_ROBOT, employee) {
730 if (!employee->isHired() && employee->getUGV() == ugvType)
731 count++;
732 }
733 return count;
734}
735
742{
743 if (!base)
744 return 0;
745
746 int count = 0;
747 E_Foreach(type, employee) {
748 if (!employee->isHiredInBase(base))
749 continue;
750 if (!employee->isAssigned())
751 count++;
752 }
753 return count;
754}
755
759void E_InitialEmployees (const campaign_t* campaign)
760{
761 int i;
762
763 /* setup initial employee count */
764 for (i = 0; i < campaign->soldiers; i++)
766 for (i = 0; i < campaign->scientists; i++)
768 for (i = 0; i < campaign->workers; i++)
770 for (i = 0; i < campaign->pilots; i++)
772 for (i = 0; i < campaign->ugvs; i++) {
774 if (frand() > 0.5)
775 E_CreateEmployee(EMPL_ROBOT, NAT_GetRandom(), cgi->Com_GetUGVByID("ugv_ares_w"));
776 else
777 E_CreateEmployee(EMPL_ROBOT, NAT_GetRandom(), cgi->Com_GetUGVByID("ugv_phoenix"));
778 }
779}
780
781#ifdef DEBUG
785static void E_ListHired_f (void)
786{
787 int i;
788
789 for (i = 0; i < MAX_EMPL; i++) {
790 const employeeType_t emplType = (employeeType_t)i;
791 E_Foreach(emplType, employee) {
792 cgi->Com_Printf("Employee: %s (ucn: %i) %s at %s\n", E_GetEmployeeString(employee->getType(), 1), employee->chr.ucn,
793 employee->chr.name, employee->baseHired->name);
794 if (employee->getType() != emplType)
795 cgi->Com_Printf("Warning: EmployeeType mismatch: %i != %i\n", emplType, employee->getType());
796 }
797 }
798}
799
804static void CL_DebugNewEmployees_f (void)
805{
806 nation_t* nation = NAT_GetRandom();
807
808 int j;
809 for (j = 0; j < 5; j++)
810 /* Create a scientist */
811 E_CreateEmployee(EMPL_SCIENTIST, nation, nullptr);
812
813 for (j = 0; j < 5; j++)
814 /* Create a pilot. */
815 E_CreateEmployee(EMPL_PILOT, nation, nullptr);
816
817 for (j = 0; j < 5; j++)
818 /* Create a soldier. */
819 E_CreateEmployee(EMPL_SOLDIER, nation, nullptr);
820
821 for (j = 0; j < 5; j++)
822 /* Create a worker. */
823 E_CreateEmployee(EMPL_WORKER, nation, nullptr);
824}
825#endif
826
833{
834 E_Foreach(type, employee) {
835 if (employee->chr.ucn == uniqueCharacterNumber)
836 return employee;
837 }
838
839 return nullptr;
840}
841
846Employee* E_GetEmployeeFromChrUCN (int uniqueCharacterNumber)
847{
848 int i;
849
850 for (i = EMPL_SOLDIER; i < MAX_EMPL; i++) {
851 const employeeType_t emplType = (employeeType_t)i;
852 Employee* employee = E_GetEmployeeByTypeFromChrUCN(emplType, uniqueCharacterNumber);
853 if (employee)
854 return employee;
855 }
856
857 return nullptr;
858}
859
860
871{
872 int i;
873
874 cgi->Com_RegisterConstList(saveEmployeeConstants);
875 for (i = 0; i < MAX_EMPL; i++) {
876 const employeeType_t emplType = (employeeType_t)i;
877 xmlNode_t* snode = cgi->XML_AddNode(p, SAVE_EMPLOYEE_EMPLOYEES);
878
879 cgi->XML_AddString(snode, SAVE_EMPLOYEE_TYPE, cgi->Com_GetConstVariable(SAVE_EMPLOYEETYPE_NAMESPACE, emplType));
880 E_Foreach(emplType, employee) {
881 xmlNode_t* chrNode;
882 xmlNode_t* ssnode = cgi->XML_AddNode(snode, SAVE_EMPLOYEE_EMPLOYEE);
883
885 if (employee->baseHired)
886 cgi->XML_AddInt(ssnode, SAVE_EMPLOYEE_BASEHIRED, employee->baseHired->idx);
887 if (employee->isAssigned())
888 cgi->XML_AddBool(ssnode, SAVE_EMPLOYEE_ASSIGNED, employee->isAssigned());
889 /* Store the nations identifier string. */
890 assert(employee->getNation());
891 cgi->XML_AddString(ssnode, SAVE_EMPLOYEE_NATION, employee->getNation()->id);
892 /* Store the ugv-type identifier string. (Only exists for EMPL_ROBOT). */
893 if (employee->getUGV())
894 cgi->XML_AddString(ssnode, SAVE_EMPLOYEE_UGV, employee->getUGV()->id);
895 /* Character Data */
896 chrNode = cgi->XML_AddNode(ssnode, SAVE_EMPLOYEE_CHR);
897 cgi->GAME_SaveCharacter(chrNode, &employee->chr);
898 }
899 }
900 cgi->Com_UnregisterConstList(saveEmployeeConstants);
901
902 return true;
903}
904
910{
911 xmlNode_t* snode;
912 bool success = true;
913 linkedList_t* lastEmployee[MAX_EMPL];
914
915 OBJZERO(lastEmployee);
916 cgi->Com_RegisterConstList(saveEmployeeConstants);
917 for (snode = cgi->XML_GetNode(p, SAVE_EMPLOYEE_EMPLOYEES); snode;
918 snode = cgi->XML_GetNextNode(snode, p, SAVE_EMPLOYEE_EMPLOYEES)) {
919 xmlNode_t* ssnode;
920 employeeType_t emplType;
921 const char* type = cgi->XML_GetString(snode, SAVE_EMPLOYEE_TYPE);
922
923 if (!cgi->Com_GetConstIntFromNamespace(SAVE_EMPLOYEETYPE_NAMESPACE, type, (int*) &emplType)) {
924 cgi->Com_Printf("Invalid employee type '%s'\n", type);
925 success = false;
926 break;
927 }
928
929 for (ssnode = cgi->XML_GetNode(snode, SAVE_EMPLOYEE_EMPLOYEE); ssnode;
930 ssnode = cgi->XML_GetNextNode(ssnode, snode, SAVE_EMPLOYEE_EMPLOYEE)) {
931 int baseIDX;
932 xmlNode_t* chrNode;
933
934 /* nation */
935 const nation_t* nation = NAT_GetNationByID(cgi->XML_GetString(ssnode, SAVE_EMPLOYEE_NATION));
936 if (!nation) {
937 cgi->Com_Printf("No nation defined for employee\n");
938 success = false;
939 break;
940 }
941 /* UGV-Type */
942 const ugv_t* ugv = cgi->Com_GetUGVByIDSilent(cgi->XML_GetString(ssnode, SAVE_EMPLOYEE_UGV));
943 Employee e(emplType, nation, ugv);
945 /* base */
946 assert(B_AtLeastOneExists()); /* Just in case the order is ever changed. */
947 baseIDX = cgi->XML_GetInt(ssnode, SAVE_EMPLOYEE_BASEHIRED, -1);
948 e.baseHired = B_GetBaseByIDX(baseIDX);
949 /* assigned to a building? */
950 e.setAssigned(cgi->XML_GetBool(ssnode, SAVE_EMPLOYEE_ASSIGNED, false));
951 /* Character Data */
952 chrNode = cgi->XML_GetNode(ssnode, SAVE_EMPLOYEE_CHR);
953 if (!chrNode) {
954 cgi->Com_Printf("No character definition found for employee\n");
955 success = false;
956 break;
957 }
958 if (!cgi->GAME_LoadCharacter(chrNode, &e.chr)) {
959 cgi->Com_Printf("Error loading character definition for employee\n");
960 success = false;
961 break;
962 }
963 if (lastEmployee[emplType] == nullptr)
964 lastEmployee[emplType] = LIST_Add(&ccs.employees[emplType], (void*) &e, sizeof(e));
965 else
966 lastEmployee[emplType] = LIST_Add(&lastEmployee[emplType], (void*) &e, sizeof(e));
967 if (lastEmployee[emplType] == nullptr) {
968 cgi->Com_Printf("Could not add employee to the game\n");
969 success = false;
970 break;
971 }
972 }
973 if (!success)
974 break;
975 }
976 cgi->Com_UnregisterConstList(saveEmployeeConstants);
977
978 return success;
979}
980
985bool E_HireAllowed (const base_t* base)
986{
988 return true;
989 return false;
990}
991
997{
998 const character_t* chr = &employee->chr;
999
1000 assert(employee->baseHired);
1001
1002 const Container* cont = nullptr;
1003 while ((cont = chr->inv.getNextCont(cont))) {
1004 Item* item = nullptr;
1005 while ((item = cont->getNextItem(item))) {
1006 /* Remove ammo */
1007 if (item->ammoDef() && item->ammoDef() != item->def())
1008 B_AddToStorage(employee->baseHired, item->ammoDef(), -1);
1009 /* Remove Item */
1010 if (item->def())
1011 B_AddToStorage(employee->baseHired, item->def(), -1);
1012 }
1013 }
1014}
1015
1017#ifdef DEBUG
1018 {"debug_listhired", E_ListHired_f, "Debug command to list all hired employee"},
1019 {"debug_addemployees", CL_DebugNewEmployees_f, "Debug function to add 5 new unhired employees of each type"},
1020#endif
1021 {nullptr, nullptr, nullptr}
1022};
1023
1027void E_InitStartup (void)
1028{
1030 cgi->Cmd_TableAddList(debugEmployeeCmds);
1031}
1032
1036void E_Shutdown (void)
1037{
1038 for (int i = EMPL_SOLDIER; i < MAX_EMPL; i++) {
1039 const employeeType_t emplType = (employeeType_t)i;
1040 cgi->LIST_Delete(&ccs.employees[emplType]);
1041 }
1042
1044 cgi->Cmd_TableRemoveList(debugEmployeeCmds);
1045}
Shared game type headers.
CGAME_HARD_LINKED_FUNCTIONS linkedList_t * LIST_Add(linkedList_t **listDest, void const *data, size_t length)
cgame team management headers.
Share stuff between the different cgame implementations.
#define _(String)
Definition cl_shared.h:44
Item * getNextItem(const Item *prev) const
character_t chr
bool isAwayFromBase() const
Tells you if a employee is away from his home base (gone in mission).
bool isRobot() const
Definition cp_employee.h:70
const employeeType_t _type
Definition cp_employee.h:42
bool unassign()
Removes the employee from buildings and aircraft.
int salary() const
Calculates the employee's actual salary.
employeeType_t getType() const
Definition cp_employee.h:99
void setAssigned(bool assigned)
Definition cp_employee.h:62
bool transfer
bool isAssigned() const
Definition cp_employee.h:58
base_t * baseHired
bool isHired() const
Definition cp_employee.h:86
bool unhire()
Fires an employee.
bool isSoldier() const
Definition cp_employee.h:82
void unequip()
Removes the equipment from an employee.
bool isPilot() const
Definition cp_employee.h:66
const Container * getNextCont(const Container *prev, bool inclTemp=false) const
item instance data, with linked list capability
Definition inv_shared.h:402
const objDef_t * ammoDef(void) const
Definition inv_shared.h:460
const objDef_t * def(void) const
Definition inv_shared.h:469
#define ERR_DROP
Definition common.h:211
void AIR_RemovePilotFromAssignedAircraft(const base_t *base, const Employee *pilot)
Checks to see if the pilot is in any aircraft at this base. If he is then he is removed from that air...
bool AIR_RemoveEmployee(Employee *employee, aircraft_t *aircraft)
Removes a soldier from an aircraft.
void AIR_AutoAddPilotToAircraft(const base_t *base, Employee *pilot)
Adds the pilot to the first available aircraft at the specified base.
bool AIR_IsAircraftInBase(const aircraft_t *aircraft)
Checks whether given aircraft is in its homebase.
const aircraft_t * AIR_IsEmployeeInAircraft(const Employee *employee, const aircraft_t *aircraft)
Tells you if an employee is assigned to an aircraft.
#define AIR_Foreach(var)
iterates trough all aircraft
base_t * B_GetBaseByIDX(int baseIdx)
Array bound check for the base index. Will also return unfounded bases as long as the index is in the...
Definition cp_base.cpp:313
int B_AddToStorage(base_t *base, const objDef_t *obj, int amount)
Add/remove items to/from the storage.
Definition cp_base.cpp:2576
bool B_GetBuildingStatus(const base_t *const base, const buildingType_t buildingType)
Get the status associated to a building.
Definition cp_base.cpp:478
#define B_AtLeastOneExists()
Definition cp_base.h:55
#define B_IsUnderAttack(base)
Definition cp_base.h:53
@ B_QUARTERS
Definition cp_building.h:54
@ B_HANGAR
Definition cp_building.h:58
@ B_MISC
Definition cp_building.h:52
@ B_LAB
Definition cp_building.h:53
@ B_WORKSHOP
Definition cp_building.h:56
ccs_t ccs
Header file for single player campaign control.
const cgame_import_t * cgi
void CAP_AddCurrent(base_t *base, baseCapacities_t capacity, int value)
Changes the current (used) capacity on a base.
int CAP_GetFreeCapacity(const base_t *base, baseCapacities_t capacityType)
Returns the free capacity of a type.
@ CAP_ITEMS
Definition cp_capacity.h:32
@ CAP_EMPLOYEES
Definition cp_capacity.h:31
const char * GAME_CP_GetTeamDef(void)
bool E_LoadXML(xmlNode_t *p)
Load callback for savegames in XML Format.
bool E_DeleteEmployee(Employee *employee)
Removes the employee completely from the game (buildings + global list).
Employee * E_GetUnassignedEmployee(const base_t *const base, const employeeType_t type)
Gets an assigned employee of a given type from the given base.
Employee * E_GetEmployeeFromChrUCN(int uniqueCharacterNumber)
Searches all employee for the ucn (character id).
static const cmdList_t debugEmployeeCmds[]
void E_InitialEmployees(const campaign_t *campaign)
Create initial hireable employees.
bool E_SaveXML(xmlNode_t *p)
Save callback for savegames in XML Format.
bool E_MoveIntoNewBase(Employee *employee, base_t *newBase)
bool E_HireEmployeeByType(base_t *base, employeeType_t type)
Hires the first free employee of that type.
int E_CountByType(employeeType_t type)
Returns number of employees of a type.
void E_UnhireAllEmployees(base_t *base, employeeType_t type)
Reset the hired flag for all employees of a given type in a given base.
bool E_HireAllowed(const base_t *base)
Returns true if the current base is able to handle employees.
Employee * E_GetEmployeeByTypeFromChrUCN(employeeType_t type, int uniqueCharacterNumber)
Searches employee from a type for the ucn (character id).
int E_GetHiredEmployees(const base_t *const base, employeeType_t type, linkedList_t **hiredEmployees)
Return a list of hired employees in the given base of a given type.
void E_InitStartup(void)
This is more or less the initial Bind some of the functions in this file to console-commands that you...
Employee * E_GetHiredRobot(const base_t *const base, const ugv_t *ugvType)
Return a "hired" ugv-employee pointer of a given ugv-type in a given base.
int E_CountUnhiredRobotsByType(const ugv_t *ugvType)
Counts all available Robots/UGVs that are for sale.
int E_CountAllHired(const base_t *const base, const bool peopleOnly)
Counts all hired employees of a given base.
Employee * E_CreateEmployee(employeeType_t type, const nation_t *nation, const ugv_t *ugvType)
Creates an entry of a new employee in the global list and assignes it to no building/base.
void E_Shutdown(void)
Closing actions for employee-subsystem.
void E_DeleteAllEmployees(base_t *base)
Removes all employees completely from the game (buildings + global list) from a given base.
void E_RemoveInventoryFromStorage(Employee *employee)
Removes the items of an employee (soldier) from the base storage (s)he is hired at.
Employee * E_GetUnhiredRobot(const ugv_t *ugvType)
Return a "not hired" ugv-employee pointer of a given ugv-type.
bool E_HireRobot(base_t *base, const ugv_t *ugvType)
Hires the first free employee of that type.
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.
employeeType_t E_GetEmployeeType(const char *type)
Convert string to employeeType_t.
bool E_HireEmployee(base_t *base, Employee *employee)
Hires the employee in a base.
Employee * E_GetAssignedEmployee(const base_t *const base, const employeeType_t type)
Gets an unassigned employee of a given type from the given base.
int E_CountHiredRobotByType(const base_t *const base, const ugv_t *ugvType)
Counts 'hired' (i.e. bought or produced UGVs and other robots of a given ugv-type in a given base.
int E_CountUnhired(employeeType_t type)
Counts unhired employees of a given type in a given base.
void E_HireForBuilding(base_t *base, building_t *building, int num)
Hires some employees of appropriate type for a building.
Employee * E_GetUnhired(employeeType_t type)
Iterates through unhired employees.
int E_CountUnassigned(const base_t *const base, employeeType_t type)
Counts unassigned employees of a given type in a given base.
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)
void E_InitCallbacks(void)
Register UI callbacks.
void E_ShutdownCallbacks(void)
Unregister UI callbacks.
Header file for menu callback functions used for hire/fire employee menu.
nation_t * NAT_GetNationByID(const char *nationID)
Return a nation-pointer by the nations id.
Definition cp_nation.cpp:64
nation_t * NAT_GetRandom(void)
Return a pointer to a random nation.
Definition cp_nation.cpp:46
void CP_Popup(const char *title, const char *text,...)
Wrapper around UI_Popup.
Definition cp_popup.cpp:474
void PR_UpdateProductionCap(base_t *base, int workerChange)
Update the current capacity of Workshop.
#define UGV_SIZE
Definition cp_produce.h:33
rank_t * CL_GetRankByIdx(const int index)
Returns a rank at an index.
Definition cp_rank.cpp:50
int CL_GetRankIdx(const char *rankID)
Get the index of the given rankID in ccs.ranks array.
Definition cp_rank.cpp:34
void RS_RemoveFiredScientist(base_t *base, Employee *employee)
Remove one scientist from research project if needed.
#define DEBUG_CLIENT
Definition defines.h:59
#define ngettext(x, y, cnt)
Definition g_local.h:40
#define LIST_Foreach(list, type, var)
Iterates over a linked list, it's safe to delete the returned entry from the list while looping over ...
Definition list.h:41
float frand(void)
Return random values between 0 and 1.
Definition mathlib.cpp:506
QGL_EXTERN GLuint count
Definition r_gl.h:99
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLint GLenum type
Definition r_gl.h:94
XML tag constants for savegame.
#define SAVE_EMPLOYEE_EMPLOYEES
static const constListEntry_t saveEmployeeConstants[]
#define SAVE_EMPLOYEE_NATION
#define SAVE_EMPLOYEE_CHR
#define SAVE_EMPLOYEE_BASEHIRED
#define SAVE_EMPLOYEE_TYPE
#define SAVE_EMPLOYEE_ASSIGNED
#define SAVE_EMPLOYEE_UGV
#define SAVE_EMPLOYEETYPE_NAMESPACE
#define SAVE_EMPLOYEE_EMPLOYEE
#define Q_streq(a, b)
Definition shared.h:136
#define OBJZERO(obj)
Definition shared.h:178
#define MAX_VAR
Definition shared.h:36
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition shared.cpp:457
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition shared.cpp:494
A base with all it's data.
Definition cp_base.h:84
A building with all it's data.
Definition cp_building.h:73
buildingType_t buildingType
salary_t salaries
Describes a character with all its attributes.
Definition chr_shared.h:388
chrScoreGlobal_t score
Definition chr_shared.h:406
Inventory inv
Definition chr_shared.h:411
Nation definition.
Definition cp_nation.h:46
Describes a rank that a recruit can gain.
Definition cp_rank.h:29
int level
Definition cp_rank.h:40
Defines a type of UGV/Robot.
Definition chr_shared.h:245
char actors[MAX_VAR]
Definition chr_shared.h:251
#define xmlNode_t
Definition xml.h:24