UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
cl_hud_callbacks.cpp
Go to the documentation of this file.
1 
5 /*
6 Copyright (C) 2002-2020 UFO: Alien Invasion.
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17 See the GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 
23 */
24 
25 #include "../client.h"
26 #include "cl_hud_callbacks.h"
27 #include "cl_hud.h"
28 #include "cl_actor.h"
29 
36 Item* HUD_GetLeftHandWeapon (const le_t* actor, containerIndex_t* container)
37 {
38  Item* item = actor->getLeftHandItem();
39 
40  if (!item) {
41  item = actor->getRightHandItem();
42  if (item == nullptr || !item->isHeldTwoHanded())
43  item = nullptr;
44  else if (container != nullptr)
45  *container = CID_RIGHT;
46  }
47 
48  return item;
49 }
50 
57 const fireDef_t* HUD_GetFireDefinitionForHand (const le_t* actor, const actorHands_t hand)
58 {
59  if (!actor)
60  return nullptr;
61 
62  const Item* weapon = actor->getHandItem(hand);
63  if (!weapon || !weapon->def())
64  return nullptr;
65 
66  return weapon->getFiredefs();
67 }
68 
77 static bool HUD_CheckShooting (const le_t* le, Item* weapon)
78 {
79  if (!le)
80  return false;
81 
82  /* No item in hand. */
83  if (!weapon || !weapon->def()) {
84  HUD_DisplayMessage(_("Can't perform action - no item in hand!"));
85  return false;
86  }
87  /* Cannot shoot because of lack of ammo. */
88  if (weapon->mustReload()) {
89  HUD_DisplayMessage(_("Can't perform action - no ammo!"));
90  return false;
91  }
92  /* Cannot shoot because weapon is fireTwoHanded, yet both hands handle items. */
93  if (weapon->def()->fireTwoHanded && le->getLeftHandItem()) {
94  HUD_DisplayMessage(_("Can't perform action - weapon cannot be fired one handed!"));
95  return false;
96  }
97 
98  return true;
99 }
100 
106 static void HUD_FireWeapon_f (void)
107 {
108  if (Cmd_Argc() < 3) { /* no argument given */
109  Com_Printf("Usage: %s <l|r> <firemode number>\n", Cmd_Argv(0));
110  return;
111  }
112 
113  le_t* actor = selActor;
114  if (actor == nullptr)
115  return;
116 
117  const actorHands_t hand = ACTOR_GET_HAND_INDEX(Cmd_Argv(1)[0]);
118  const fireDefIndex_t firemode = atoi(Cmd_Argv(2));
119  if (firemode >= MAX_FIREDEFS_PER_WEAPON || firemode < 0)
120  return;
121 
122  const fireDef_t* fd = HUD_GetFireDefinitionForHand(actor, hand);
123  if (fd == nullptr)
124  return;
125 
126  const objDef_t* ammo = fd->obj;
127 
128  /* Let's check if shooting is possible. */
129  if (!HUD_CheckShooting(actor, actor->getHandItem(hand)))
130  return;
131 
132  if (CL_ActorTimeForFireDef(actor, &ammo->fd[fd->weapFdsIdx][firemode]) <= CL_ActorUsableTUs(actor)) {
133  /* Actually start aiming. This is done by changing the current mode of display. */
134  if (hand == ACTOR_HAND_RIGHT)
135  CL_ActorSetMode(actor, M_FIRE_R);
136  else
137  CL_ActorSetMode(actor, M_FIRE_L);
138  /* Store firemode. */
139  actor->currentSelectedFiremode = firemode;
140  } else {
141  /* Can not shoot because of not enough TUs - every other
142  * case should be checked previously in this function. */
143  HUD_DisplayMessage(_("Can't perform action - not enough TUs!"));
144  }
145 }
146 
147 static void HUD_SetMoveMode_f (void)
148 {
149  le_t* actor = selActor;
150 
151  if (actor == nullptr)
152  return;
153 
154  CL_ActorSetMode(actor, M_MOVE);
155 }
156 
161 {
162  const le_t* actor = selActor;
163 
164  if (!CL_ActorCheckAction(actor))
165  return;
166 
167  if (CL_ActorReservedTUs(actor, RES_CROUCH) >= TU_CROUCH) {
168  /* Reset reserved TUs to 0 */
169  CL_ActorReserveTUs(actor, RES_CROUCH, 0);
170  HUD_DisplayMessage(_("Disabled crouching/standing up TUs reservation."));
171  } else {
172  /* Reserve the exact amount for crouching/standing up (if we have enough to do so). */
174  HUD_DisplayMessage(va(_("Reserved %i TUs for crouching/standing up."), TU_CROUCH));
175  }
176 }
177 
181 static void HUD_ToggleReaction_f (void)
182 {
183  int state = 0;
184  const le_t* actor = selActor;
185 
186  if (!CL_ActorCheckAction(actor))
187  return;
188 
189  if (!(actor->state & STATE_REACTION)) {
190  if (actor->inv.holdsReactionFireWeapon() && CL_ActorUsableTUs(actor) >= HUD_ReactionFireGetTUs(actor)) {
191  state = STATE_REACTION;
192  HUD_DisplayMessage(_("Reaction fire enabled."));
193  } else {
194  return;
195  }
196  } else {
197  state = ~STATE_REACTION;
198  HUD_DisplayMessage(_("Reaction fire disabled."));
199  }
200 
201  /* Send request to update actor's reaction state to the server. */
202  MSG_Write_PA(PA_STATE, actor->entnum, state);
203 }
204 
217 int HUD_CalcReloadTime (const le_t* le, const objDef_t* weapon, containerIndex_t toContainer)
218 {
219  if (toContainer == NONE)
220  return -1;
221 
222  assert(le);
223  assert(weapon);
224 
225  Item* ic;
226  const containerIndex_t container = CL_ActorGetContainerForReload(&ic, &le->inv, weapon);
227  if (container == NONE)
228  return -1;
229 
230  /* total TU cost is the sum of 3 numbers:
231  * TU for weapon reload + TU to get ammo out + TU to put ammo in hands */
232  return INVDEF(container)->out + INVDEF(toContainer)->in + weapon->getReloadTime();
233 }
234 
244 static bool HUD_CheckReload (const le_t* le, const Item* weapon, containerIndex_t container)
245 {
246  if (!le)
247  return false;
248 
249  /* No item in hand. */
250  if (!weapon || !weapon->def()) {
251  HUD_DisplayMessage(_("Can't perform action - no item in hand!"));
252  return false;
253  }
254 
255  /* Cannot reload because this item is not reloadable. */
256  if (!weapon->isReloadable()) {
257  HUD_DisplayMessage(_("Can't perform action - this item is not reloadable!"));
258  return false;
259  }
260 
261  const int tus = HUD_CalcReloadTime(le, weapon->def(), container);
262  /* Cannot reload because of no ammo in inventory. */
263  if (tus == -1) {
264  HUD_DisplayMessage(_("Can't perform action - no ammo!"));
265  return false;
266  }
267  /* Cannot reload because of not enough TUs. */
268  if (le->TU < tus) {
269  HUD_DisplayMessage(_("Can't perform action - not enough TUs!"));
270  return false;
271  }
272 
273  return true;
274 }
275 
279 static void HUD_ReloadLeft_f (void)
280 {
281  le_t* actor = selActor;
282 
283  if (actor == nullptr)
284  return;
285 
286  containerIndex_t container = CID_LEFT;
287  if (!HUD_CheckReload(actor, HUD_GetLeftHandWeapon(actor, &container), container))
288  return;
289  CL_ActorReload(actor, container);
290  HUD_DisplayMessage(_("Left hand weapon reloaded."));
291 }
292 
296 static void HUD_ReloadRight_f (void)
297 {
298  le_t* actor = selActor;
299 
300  if (!actor || !HUD_CheckReload(actor, actor->getRightHandItem(), CID_RIGHT))
301  return;
302  CL_ActorReload(actor, CID_RIGHT);
303  HUD_DisplayMessage(_("Right hand weapon reloaded."));
304 }
305 
310 static void HUD_ExecuteAction_f (void)
311 {
312  if (!selActor)
313  return;
314 
315  if (Cmd_Argc() < 2) {
316  Com_Printf("Usage: %s <actionid>\n", Cmd_Argv(0));
317  return;
318  }
319 
320  if (Q_streq(Cmd_Argv(1), "reload_handl")) {
322  return;
323  }
324 
325  if (Q_streq(Cmd_Argv(1), "reload_handr")) {
327  return;
328  }
329 
330  if (char const* const rest = Q_strstart(Cmd_Argv(1), "fire_hand")) {
331  if (strlen(rest) >= 4) {
332  char const hand = rest[0];
333  int const index = atoi(rest + 3);
334  Cmd_ExecuteString("hud_fireweapon %c %i", hand, index);
335  return;
336  }
337  }
338 
339  Com_Printf("HUD_ExecuteAction_f: Action \"%s\" unknown.\n", Cmd_Argv(1));
340 }
341 
342 void HUD_InitCallbacks (void)
343 {
344  Cmd_AddCommand("hud_movemode", HUD_SetMoveMode_f, N_("Set selected actor to move mode (it cancels the fire mode)."));
345  Cmd_AddCommand("hud_reloadleft", HUD_ReloadLeft_f, N_("Reload the weapon in the soldiers left hand."));
346  Cmd_AddCommand("hud_reloadright", HUD_ReloadRight_f, N_("Reload the weapon in the soldiers right hand."));
347  Cmd_AddCommand("hud_togglecrouchreserve", HUD_ToggleCrouchReservation_f, N_("Toggle reservation for crouching."));
348  Cmd_AddCommand("hud_togglereaction", HUD_ToggleReaction_f, N_("Toggle reaction fire."));
349  Cmd_AddCommand("hud_fireweapon", HUD_FireWeapon_f, N_("Start aiming the weapon."));
350  Cmd_AddCommand("hud_executeaction", HUD_ExecuteAction_f, N_("Execute an action."));
351 }
const char * Cmd_Argv(int arg)
Returns a given argument.
Definition: cmd.cpp:516
void Cmd_AddCommand(const char *cmdName, xcommand_t function, const char *desc)
Add a new command to the script interface.
Definition: cmd.cpp:744
bool mustReload() const
Definition: inv_shared.h:483
void HUD_InitCallbacks(void)
Item * getLeftHandItem() const
static void HUD_ToggleReaction_f(void)
Toggles reaction fire states for the current selected actor.
void MSG_Write_PA(player_action_t playerAction, int entnum,...)
Writes player action with its data.
Definition: cl_actor.cpp:73
this is a fire definition for our weapons/ammo
Definition: inv_shared.h:110
int entnum
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
#define _(String)
Definition: cl_shared.h:43
weaponFireDefIndex_t weapFdsIdx
Definition: inv_shared.h:126
#define STATE_REACTION
Definition: q_shared.h:272
int getReloadTime() const
Definition: inv_shared.h:349
int HUD_CalcReloadTime(const le_t *le, const objDef_t *weapon, containerIndex_t toContainer)
Calculate total reload time for selected actor.
const fireDef_t * getFiredefs() const
Returns the firedefinitions for a given weapon/ammo.
Definition: inv_shared.cpp:576
#define TU_CROUCH
Definition: defines.h:72
const objDef_t * def(void) const
Definition: inv_shared.h:469
fireDef_t fd[MAX_WEAPONS_PER_OBJDEF][MAX_FIREDEFS_PER_WEAPON]
Definition: inv_shared.h:314
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
static void HUD_ReloadLeft_f(void)
Reload left weapon.
Defines all attributes of objects used in the inventory.
Definition: inv_shared.h:264
bool holdsReactionFireWeapon() const
Checks if there is a weapon in the hands that can be used for reaction fire.
const struct objDef_s * obj
Definition: inv_shared.h:125
static bool HUD_CheckReload(const le_t *le, const Item *weapon, containerIndex_t container)
Check if reload is possible.
void Cmd_ExecuteString(const char *text,...)
A complete command line has been parsed, so try to execute it.
Definition: cmd.cpp:1007
#define CID_LEFT
Definition: inv_shared.h:48
bool fireTwoHanded
Definition: inv_shared.h:279
Item * getRightHandItem() const
item instance data, with linked list capability
Definition: inv_shared.h:402
void CL_ActorReserveTUs(const le_t *le, const reservation_types_t type, const int tus)
Replace the reserved TUs for a certain type.
Definition: cl_actor.cpp:273
#define CID_RIGHT
Definition: inv_shared.h:47
static void HUD_ToggleCrouchReservation_f(void)
Toggles if the current actor reserves TUs for crouching.
const fireDef_t * HUD_GetFireDefinitionForHand(const le_t *actor, const actorHands_t hand)
Returns the fire definition of the item the actor has in the given hand.
int Cmd_Argc(void)
Return the number of arguments of the current command. "command parameter" will result in a argc of 2...
Definition: cmd.cpp:505
int HUD_ReactionFireGetTUs(const le_t *actor)
Get the weapon firing TUs for reaction fire.
Definition: cl_hud.cpp:774
int32_t fireDefIndex_t
Definition: inv_shared.h:78
#define MAX_FIREDEFS_PER_WEAPON
Definition: inv_shared.h:42
int CL_ActorReservedTUs(const le_t *le, const reservation_types_t type)
Returns the amount of reserved TUs for a certain type.
Definition: cl_actor.cpp:214
actorHands_t
Definition: inv_shared.h:626
static void HUD_ReloadRight_f(void)
Reload right weapon.
char const * Q_strstart(char const *str, char const *start)
Matches the start of a string.
Definition: shared.cpp:587
void CL_ActorReload(le_t *le, containerIndex_t containerID)
Reload weapon with actor.
Definition: cl_actor.cpp:948
Item * HUD_GetLeftHandWeapon(const le_t *actor, containerIndex_t *container)
returns the weapon the actor's left hand is touching. In case the actor holds a two handed weapon in ...
#define INVDEF(containerID)
Definition: cl_shared.h:47
int CL_ActorUsableTUs(const le_t *le)
Returns the amount of usable (overall-reserved) TUs for an actor.
Definition: cl_actor.cpp:259
QGL_EXTERN GLuint index
Definition: r_gl.h:110
int CL_ActorCheckAction(const le_t *le)
Checks that an action is valid.
Definition: cl_actor.cpp:713
a local entity
Inventory inv
int32_t containerIndex_t
Definition: inv_shared.h:46
le_t * selActor
Definition: cl_actor.cpp:49
bool isReloadable() const
Definition: inv_shared.h:479
static void HUD_ExecuteAction_f(void)
int CL_ActorTimeForFireDef(const le_t *le, const fireDef_t *fd, bool reaction)
Find the TUs needed for the given fireDef taking into account the actor wound penalties.
Definition: cl_actor.cpp:342
static bool HUD_CheckShooting(const le_t *le, Item *weapon)
Check if shooting is possible. i.e. The weapon has ammo and can be fired with the 'available' hands...
Item * getHandItem(actorHands_t hand) const
HUD related routines.
bool isHeldTwoHanded() const
Definition: inv_shared.h:476
#define N_(String)
Definition: cl_shared.h:45
int TU
void CL_ActorSetMode(le_t *actor, actorModes_t actorMode)
Definition: cl_actor.cpp:835
#define NONE
Definition: defines.h:68
#define Q_streq(a, b)
Definition: shared.h:136
#define ACTOR_GET_HAND_INDEX(hand)
Definition: cl_hud.h:34
static void HUD_FireWeapon_f(void)
Starts aiming/target mode for selected left/right firemode.
int CL_ActorGetContainerForReload(Item **ammoItem, const Inventory *inv, const objDef_t *weapon)
Searches the clip with the least TU usage to put it into the weapon.
Definition: cl_actor.cpp:916
fireDefIndex_t currentSelectedFiremode
static void HUD_SetMoveMode_f(void)
int state
void HUD_DisplayMessage(const char *text)
Displays a message on the hud.
Definition: cl_hud.cpp:138