UFO: Alien Invasion
Loading...
Searching...
No Matches
cl_team.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.m
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
26#include "client.h"
27#include "cl_team.h"
28#include "cl_inventory.h"
29#include "cgame/cl_game.h"
34#include "ui/ui_data.h"
35#include "ui/ui_nodes.h"
36
39
45{
46 if (cls.numActorSkins >= lengthof(cls.actorSkins))
47 Sys_Error("CL_AllocateActorSkin: Max actorskin hit");
48
50 actorSkin_t* skin = &cls.actorSkins[index];
51 OBJZERO(*skin);
52 skin->idx = index;
54
55 cls.numActorSkins++;
56 return skin;
57}
58
63unsigned int CL_GetActorSkinCount (void)
64{
65 return cls.numActorSkins;
66}
67
72static const actorSkin_t* CL_GetActorSkinByIDS (unsigned int idx)
73{
74 if (idx >= cls.numActorSkins)
75 return nullptr;
76 return &cls.actorSkins[idx];
77}
78
83{
84 const chrScoreGlobal_t* score = &chr->score;
85 Cvar_ForceSet("mn_name", chr->name);
86 Cvar_ForceSet("mn_body", CHRSH_CharGetBody(chr));
87 Cvar_ForceSet("mn_head", CHRSH_CharGetHead(chr));
88 Cvar_ForceSet("mn_body_skin", va("%i", chr->bodySkin));
89 Cvar_ForceSet("mn_head_skin", va("%i", chr->headSkin));
90
91 Cvar_SetValue("mn_vpwr", score->skills[ABILITY_POWER]);
92 Cvar_SetValue("mn_vspd", score->skills[ABILITY_SPEED]);
93 Cvar_SetValue("mn_vacc", score->skills[ABILITY_ACCURACY]);
94 Cvar_SetValue("mn_vmnd", score->skills[ABILITY_MIND]);
95 Cvar_SetValue("mn_vcls", score->skills[SKILL_CLOSE]);
96 Cvar_SetValue("mn_vhvy", score->skills[SKILL_HEAVY]);
97 Cvar_SetValue("mn_vass", score->skills[SKILL_ASSAULT]);
98 Cvar_SetValue("mn_vsnp", score->skills[SKILL_SNIPER]);
99 Cvar_SetValue("mn_vexp", score->skills[SKILL_EXPLOSIVE]);
100 Cvar_SetValue("mn_vpil", score->skills[SKILL_PILOTING]);
101 Cvar_SetValue("mn_vtar", score->skills[SKILL_TARGETING]);
102 Cvar_SetValue("mn_vevad", score->skills[SKILL_EVADING]);
103 Cvar_SetValue("mn_vpwri", score->initialSkills[ABILITY_POWER]);
104 Cvar_SetValue("mn_vspdi", score->initialSkills[ABILITY_SPEED]);
105 Cvar_SetValue("mn_vacci", score->initialSkills[ABILITY_ACCURACY]);
106 Cvar_SetValue("mn_vmndi", score->initialSkills[ABILITY_MIND]);
107 Cvar_SetValue("mn_vclsi", score->initialSkills[SKILL_CLOSE]);
108 Cvar_SetValue("mn_vhvyi", score->initialSkills[SKILL_HEAVY]);
109 Cvar_SetValue("mn_vassi", score->initialSkills[SKILL_ASSAULT]);
110 Cvar_SetValue("mn_vsnpi", score->initialSkills[SKILL_SNIPER]);
111 Cvar_SetValue("mn_vexpi", score->initialSkills[SKILL_EXPLOSIVE]);
112 Cvar_SetValue("mn_vpili", score->initialSkills[SKILL_PILOTING]);
113 Cvar_SetValue("mn_vtari", score->initialSkills[SKILL_TARGETING]);
114 Cvar_SetValue("mn_vevadi", score->initialSkills[SKILL_EVADING]);
115 Cvar_SetValue("mn_vhp", chr->HP);
116 Cvar_SetValue("mn_vhpmax", chr->maxHP);
117
118 Cvar_Set("mn_tpwr", "%s (%i)", CL_ActorGetSkillString(score->skills[ABILITY_POWER]), score->skills[ABILITY_POWER]);
119 Cvar_Set("mn_tspd", "%s (%i)", CL_ActorGetSkillString(score->skills[ABILITY_SPEED]), score->skills[ABILITY_SPEED]);
120 Cvar_Set("mn_tacc", "%s (%i)", CL_ActorGetSkillString(score->skills[ABILITY_ACCURACY]), score->skills[ABILITY_ACCURACY]);
121 Cvar_Set("mn_tmnd", "%s (%i)", CL_ActorGetSkillString(score->skills[ABILITY_MIND]), score->skills[ABILITY_MIND]);
122 Cvar_Set("mn_tcls", "%s (%i)", CL_ActorGetSkillString(score->skills[SKILL_CLOSE]), score->skills[SKILL_CLOSE]);
123 Cvar_Set("mn_thvy", "%s (%i)", CL_ActorGetSkillString(score->skills[SKILL_HEAVY]), score->skills[SKILL_HEAVY]);
124 Cvar_Set("mn_tass", "%s (%i)", CL_ActorGetSkillString(score->skills[SKILL_ASSAULT]), score->skills[SKILL_ASSAULT]);
125 Cvar_Set("mn_tsnp", "%s (%i)", CL_ActorGetSkillString(score->skills[SKILL_SNIPER]), score->skills[SKILL_SNIPER]);
126 Cvar_Set("mn_texp", "%s (%i)", CL_ActorGetSkillString(score->skills[SKILL_EXPLOSIVE]), score->skills[SKILL_EXPLOSIVE]);
127 Cvar_Set("mn_tpil", "%s (%i)", CL_ActorGetSkillString(score->skills[SKILL_PILOTING]), score->skills[SKILL_PILOTING]);
128 Cvar_Set("mn_ttar", "%s (%i)", CL_ActorGetSkillString(score->skills[SKILL_TARGETING]), score->skills[SKILL_TARGETING]);
129 Cvar_Set("mn_tevad", "%s (%i)", CL_ActorGetSkillString(score->skills[SKILL_EVADING]), score->skills[SKILL_EVADING]);
130 Cvar_Set("mn_thp", "%i (%i)", chr->HP, chr->maxHP);
131}
132
143static void CL_ActorCvars (const character_t* chr)
144{
145 assert(chr);
146
147 /* visible equipment */
148 Item* weapon = chr->inv.getRightHandContainer();
149 if (weapon)
150 Cvar_Set("mn_rweapon", "%s", weapon->def()->model);
151 else
152 Cvar_Set("mn_rweapon", "%s", "");
153 weapon = chr->inv.getLeftHandContainer();
154 if (weapon)
155 Cvar_Set("mn_lweapon", "%s", weapon->def()->model);
156 else
157 Cvar_Set("mn_lweapon", "%s", "");
158}
159
165const char* CL_ActorGetSkillString (const int skill)
166{
167 const int skillLevel = skill * 10 / MAX_SKILL;
168#ifdef DEBUG
169 if (skill > MAX_SKILL) {
170 Com_Printf("CL_GetSkillString: Skill is bigger than max allowed skill value (%i/%i).\n", skill, MAX_SKILL);
171 }
172#endif
173 switch (skillLevel) {
174 case 0:
175 return _("Poor");
176 case 1:
177 return _("Mediocre");
178 case 2:
179 return _("Average");
180 case 3:
181 return _("Competent");
182 case 4:
183 return _("Proficient");
184 case 5:
185 return _("Very Good");
186 case 6:
187 return _("Highly Proficient");
188 case 7:
189 return _("Exceptional");
190 case 8:
191 return _("Outstanding");
192 case 9:
193 return _("Impressive");
194 case 10:
195 return _("Superhuman");
196 default:
197 Com_Printf("CL_ActorGetSkillString: Unknown skill: %i (index: %i).\n", skill, skillLevel);
198 return "";
199 }
200}
201
210static void CL_UGVCvars (const character_t* chr)
211{
212 Cvar_Set("mn_lweapon", "%s", "");
213 Cvar_Set("mn_rweapon", "%s", "");
214 Cvar_Set("mn_vmnd", "0");
215 Cvar_Set("mn_tmnd", "%s (0)", CL_ActorGetSkillString(chr->score.skills[ABILITY_MIND]));
216}
217
219{
221
222 if (chr->teamDef->robot)
223 CL_UGVCvars(chr);
224 else
225 CL_ActorCvars(chr);
226
228}
229
235void CL_GenerateCharacter (character_t* chr, const char* teamDefName)
236{
237 chr->init();
238
239 /* link inventory */
240 cls.i.destroyInventory(&chr->inv);
241
242 /* get ucn */
243 chr->ucn = cls.nextUniqueCharacterNumber++;
244
246
247 Com_GetCharacterValues(teamDefName, chr);
248 /* Create attributes. */
250
251 chr->RFmode.set(ACTOR_HAND_NOT_SET, -1, nullptr);
252 chr->state |= STATE_REACTION;
253}
254
258static void CL_InitSkin_f (void)
259{
260 /* create option for singleplayer skins */
261 if (UI_GetOption(OPTION_SINGLEPLAYER_SKINS) == nullptr) {
262 uiNode_t* skins = nullptr;
263 int idx = 0;
264 const actorSkin_t* skin;
265 while ((skin = CL_GetActorSkinByIDS(idx++))) {
266 if (!skin->singleplayer)
267 continue;
268 UI_AddOption(&skins, skin->id, skin->name, va("%d", skin->idx));
269 }
271 }
272
273 /* create option for multiplayer skins */
274 if (UI_GetOption(OPTION_MULTIPLAYER_SKINS) == nullptr) {
275 uiNode_t* skins = nullptr;
276 int idx = 0;
277 const actorSkin_t* skin;
278 while ((skin = CL_GetActorSkinByIDS(idx++))) {
279 if (!skin->multiplayer)
280 continue;
281 UI_AddOption(&skins, skin->id, skin->name, va("%d", skin->idx));
282 }
284 }
285}
286
290static int CL_FixActorSkinIDX (int idx)
291{
292 const actorSkin_t* skin = CL_GetActorSkinByIDS(idx);
293
295 if (skin == nullptr) {
296 idx = 0;
297 } else {
298 if (GAME_IsSingleplayer() && !skin->singleplayer)
299 idx = 0;
300 else if (GAME_IsMultiplayer() && !skin->multiplayer)
301 idx = 0;
302 }
303 return idx;
304}
305
309static void CL_ChangeSkin_f (void)
310{
311 const int sel = cl_selected->integer;
313 if (chr == nullptr) {
314 return;
315 }
316 const int newSkin = CL_FixActorSkinIDX(Cvar_GetInteger("mn_body_skin"));
317 Cvar_SetValue("mn_body_skin", newSkin);
320 chr->bodySkin = newSkin;
321}
322
327{
328 /* Get selected skin and fall back to default skin if it is not valid. */
329 const int newSkin = CL_FixActorSkinIDX(Cvar_GetInteger("mn_body_skin"));
330 /* Apply new skin to all (shown/displayed) team-members. */
335 chr->bodySkin = newSkin;
336 }
337}
338
340{
341 Cmd_AddCommand("team_initskin", CL_InitSkin_f, "Init skin according to the game mode");
342 Cmd_AddCommand("team_changeskin", CL_ChangeSkin_f, "Change the skin of the soldier");
343 Cmd_AddCommand("team_changeskinteam", CL_ChangeSkinForWholeTeam_f, "Change the skin for the whole current team");
344}
void CHRSH_CharGenAbilitySkills(character_t *chr, bool multiplayer, const char *templateId)
Generates a skill and ability set for any character.
const char * CHRSH_CharGetBody(const character_t *const chr)
Returns the body model for the soldiers for armoured and non armoured soldiers.
const char * CHRSH_CharGetHead(const character_t *const chr)
Returns the head model for the soldiers for armoured and non armoured soldiers.
@ SKILL_PILOTING
Definition chr_shared.h:48
@ SKILL_HEAVY
Definition chr_shared.h:43
@ ABILITY_POWER
Definition chr_shared.h:37
@ ABILITY_SPEED
Definition chr_shared.h:38
@ SKILL_EVADING
Definition chr_shared.h:50
@ SKILL_SNIPER
Definition chr_shared.h:45
@ ABILITY_MIND
Definition chr_shared.h:40
@ SKILL_CLOSE
Definition chr_shared.h:42
@ SKILL_EXPLOSIVE
Definition chr_shared.h:46
@ SKILL_TARGETING
Definition chr_shared.h:49
@ ABILITY_ACCURACY
Definition chr_shared.h:39
@ SKILL_ASSAULT
Definition chr_shared.h:44
bool GAME_IsMultiplayer(void)
Definition cl_game.cpp:299
void GAME_CharacterCvars(const character_t *chr)
Definition cl_game.cpp:1451
Shared game type headers.
#define GAME_IsSingleplayer()
Definition cl_game.h:36
Header file for inventory handling and Equipment menu.
client_static_t cls
Definition cl_main.cpp:83
cvar_t * cl_selected
Definition cl_main.cpp:73
#define _(String)
Definition cl_shared.h:44
static void CL_UGVCvars(const character_t *chr)
Updates the UGV cvars for the given "character". The models and stats that are displayed in the menu ...
Definition cl_team.cpp:210
static const actorSkin_t * CL_GetActorSkinByIDS(unsigned int idx)
Get a actorskin from idx.
Definition cl_team.cpp:72
void TEAM_InitStartup(void)
Definition cl_team.cpp:339
static void CL_ActorCvars(const character_t *chr)
Updates the character cvars for the given character.
Definition cl_team.cpp:143
void CL_UpdateCharacterValues(const character_t *chr)
Definition cl_team.cpp:218
static void CL_CharacterSkillAndScoreCvars(const character_t *chr)
Definition cl_team.cpp:82
linkedList_t * chrDisplayList
List of currently displayed or equipable characters.
Definition cl_team.cpp:38
static void CL_InitSkin_f(void)
Init skins into the GUI.
Definition cl_team.cpp:258
unsigned int CL_GetActorSkinCount(void)
Get number of registered actorskins.
Definition cl_team.cpp:63
static void CL_ChangeSkin_f(void)
Change the skin of the selected actor.
Definition cl_team.cpp:309
static void CL_ChangeSkinForWholeTeam_f(void)
Use current skin for all team members onboard.
Definition cl_team.cpp:326
actorSkin_t * CL_AllocateActorSkin(const char *name)
Allocate a skin from the cls structure.
Definition cl_team.cpp:44
static int CL_FixActorSkinIDX(int idx)
Fix actorskin idx according to game mode.
Definition cl_team.cpp:290
const char * CL_ActorGetSkillString(const int skill)
Return the skill string for the given skill level.
Definition cl_team.cpp:165
void CL_GenerateCharacter(character_t *chr, const char *teamDefName)
Generates the skills and inventory for a character and for a 2x2 unit.
Definition cl_team.cpp:235
void set(const actorHands_t hand, const fireDefIndex_t fmIdx, const objDef_t *weapon)
Definition chr_shared.h:173
Item * getLeftHandContainer() const
Item * getRightHandContainer() const
item instance data, with linked list capability
Definition inv_shared.h:402
const objDef_t * def(void) const
Definition inv_shared.h:469
Primary header for client.
void Cmd_AddCommand(const char *cmdName, xcommand_t function, const char *desc)
Add a new command to the script interface.
Definition cmd.cpp:744
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
memPool_t * com_genericPool
Definition common.cpp:72
cvar_t * Cvar_ForceSet(const char *varName, const char *value)
Will set the variable even if NOSET or LATCH.
Definition cvar.cpp:604
void Cvar_SetValue(const char *varName, float value)
Expands value to a string and calls Cvar_Set.
Definition cvar.cpp:671
cvar_t * Cvar_Set(const char *varName, const char *value,...)
Sets a cvar value.
Definition cvar.cpp:615
int Cvar_GetInteger(const char *varName)
Returns the int value of a cvar.
Definition cvar.cpp:194
void Sys_Error(const char *error,...)
Definition g_main.cpp:421
@ ACTOR_HAND_NOT_SET
Definition inv_shared.h:627
void * LIST_GetByIdx(linkedList_t *list, int index)
Get an entry of a linked list by its index in the list.
Definition list.cpp:362
#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
#define Mem_PoolStrDup(in, pool, tagNum)
Definition mem.h:50
#define STATE_REACTION
Definition q_shared.h:272
#define MAX_SKILL
Definition q_shared.h:278
QGL_EXTERN GLuint index
Definition r_gl.h:110
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition r_gl.h:110
int R_ModAllocateActorSkin(const char *name)
Register an actorskin name.
Definition r_model.cpp:332
void Com_GetCharacterValues(const char *teamDefition, character_t *chr)
Assign character values, 3D models and names to a character.
Definition scripts.cpp:2408
#define OBJZERO(obj)
Definition shared.h:178
#define lengthof(x)
Definition shared.h:105
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
Definition shared.cpp:410
char name[MAX_VAR]
Definition cl_team.h:38
char * id
Definition cl_team.h:35
bool multiplayer
Definition cl_team.h:43
bool singleplayer
Definition cl_team.h:41
Describes a character with all its attributes.
Definition chr_shared.h:388
chrReservations_t reservedTus
Definition chr_shared.h:415
const teamDef_t * teamDef
Definition chr_shared.h:413
chrScoreGlobal_t score
Definition chr_shared.h:406
FiremodeSettings RFmode
Definition chr_shared.h:416
char name[MAX_VAR]
Definition chr_shared.h:390
Inventory inv
Definition chr_shared.h:411
FiremodeSettings shotSettings
Definition chr_shared.h:196
Structure of all stats collected for an actor over time.
Definition chr_shared.h:119
int initialSkills[SKILL_NUM_TYPES+1]
Definition chr_shared.h:123
int skills[SKILL_NUM_TYPES]
Definition chr_shared.h:122
const char * model
Definition inv_shared.h:269
Atomic structure used to define most of the UI.
Definition ui_nodes.h:80
void UI_RegisterOption(int dataId, uiNode_t *option)
Definition ui_data.cpp:311
uiNode_t * UI_GetOption(int dataId)
Definition ui_data.cpp:324
uiNode_t * UI_AddOption(uiNode_t **tree, const char *name, const char *label, const char *value)
Append an option to an option list.
Definition ui_data.cpp:172
Data and interface to share data.
@ OPTION_SINGLEPLAYER_SKINS
Definition ui_dataids.h:78
@ OPTION_MULTIPLAYER_SKINS
Definition ui_dataids.h:79