cl_hud_callbacks.c

Go to the documentation of this file.
00001 
00005 /*
00006 Copyright (C) 2002-2010 UFO: Alien Invasion.
00007 
00008 This program is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU General Public License
00010 as published by the Free Software Foundation; either version 2
00011 of the License, or (at your option) any later version.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016 
00017 See the GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00023 */
00024 
00025 #include "../client.h"
00026 #include "cl_hud_callbacks.h"
00027 #include "cl_hud.h"
00028 #include "cl_actor.h"
00029 
00036 invList_t* HUD_GetLeftHandWeapon (le_t *actor, containerIndex_t *container)
00037 {
00038     invList_t *invList = LEFT(actor);
00039 
00040     if (!invList) {
00041         invList = RIGHT(actor);
00042         if (invList == NULL || !invList->item.t->holdTwoHanded)
00043             invList = NULL;
00044         else if (container != NULL)
00045             *container = csi.idRight;
00046     }
00047 
00048     return invList;
00049 }
00050 
00057 const fireDef_t *HUD_GetFireDefinitionForHand (const le_t * actor, const actorHands_t hand)
00058 {
00059     const invList_t *invlistWeapon;
00060 
00061     if (!actor)
00062         return NULL;
00063 
00064     invlistWeapon = ACTOR_GET_INV(actor, hand);
00065     if (!invlistWeapon || !invlistWeapon->item.t)
00066         return NULL;
00067 
00068     return FIRESH_FiredefForWeapon(&invlistWeapon->item);
00069 }
00070 
00079 static qboolean HUD_CheckShooting (const le_t* le, invList_t *weapon)
00080 {
00081     if (!le)
00082         return qfalse;
00083 
00084     /* No item in hand. */
00085     if (!weapon || !weapon->item.t) {
00086         HUD_DisplayMessage(_("No item in hand.\n"));
00087         return qfalse;
00088     }
00089 
00090     /* Cannot shoot because of lack of ammo. */
00091     if (weapon->item.a <= 0 && weapon->item.t->reload) {
00092         HUD_DisplayMessage(_("Can't perform action:\nout of ammo.\n"));
00093         return qfalse;
00094     }
00095     /* Cannot shoot because weapon is fireTwoHanded, yet both hands handle items. */
00096     if (weapon->item.t->fireTwoHanded && LEFT(le)) {
00097         HUD_DisplayMessage(_("This weapon cannot be fired\none handed.\n"));
00098         return qfalse;
00099     }
00100 
00101     return qtrue;
00102 }
00103 
00109 static void HUD_FireWeapon_f (void)
00110 {
00111     actorHands_t hand;
00112     fireDefIndex_t firemode;
00113     const objDef_t *ammo;
00114     const fireDef_t *fd;
00115 
00116     if (Cmd_Argc() < 3) { /* no argument given */
00117         Com_Printf("Usage: %s <l|r> <firemode number>\n", Cmd_Argv(0));
00118         return;
00119     }
00120 
00121     if (!selActor)
00122         return;
00123 
00124     hand = ACTOR_GET_HAND_INDEX(Cmd_Argv(1)[0]);
00125     firemode = atoi(Cmd_Argv(2));
00126     if (firemode >= MAX_FIREDEFS_PER_WEAPON || firemode < 0)
00127         return;
00128 
00129     fd = HUD_GetFireDefinitionForHand(selActor, hand);
00130     if (fd == NULL)
00131         return;
00132 
00133     ammo = fd->obj;
00134 
00135     /* Let's check if shooting is possible. */
00136     if (!HUD_CheckShooting(selActor, ACTOR_GET_INV(selActor, hand)))
00137         return;
00138 
00139     if (ammo->fd[fd->weapFdsIdx][firemode].time <= CL_ActorUsableTUs(selActor)) {
00140         /* Actually start aiming. This is done by changing the current mode of display. */
00141         if (hand == ACTOR_HAND_RIGHT)
00142             CL_ActorSetMode(selActor, M_FIRE_R);
00143         else
00144             CL_ActorSetMode(selActor, M_FIRE_L);
00145         /* Store firemode. */
00146         selActor->currentSelectedFiremode = firemode;
00147         HUD_HideFiremodes();
00148     } else {
00149         /* Cannot shoot because of not enough TUs - every other
00150          * case should be checked previously in this function. */
00151         HUD_DisplayMessage(_("Can't perform action:\nnot enough TUs.\n"));
00152     }
00153 }
00154 
00158 static void HUD_ToggleCrouchReservation_f (void)
00159 {
00160     if (!CL_ActorCheckAction(selActor))
00161         return;
00162 
00163     if (CL_ActorReservedTUs(selActor, RES_CROUCH) >= TU_CROUCH) {
00164         /* Reset reserved TUs to 0 */
00165         CL_ActorReserveTUs(selActor, RES_CROUCH, 0);
00166     } else {
00167         /* Reserve the exact amount for crouching/standing up (if we have enough to do so). */
00168         CL_ActorReserveTUs(selActor, RES_CROUCH, TU_CROUCH);
00169     }
00170 }
00171 
00175 static void HUD_ToggleReaction_f (void)
00176 {
00177     int state = 0;
00178 
00179     if (!CL_ActorCheckAction(selActor))
00180         return;
00181 
00182     if (!(selActor->state & STATE_REACTION))
00183         state = STATE_REACTION_ONCE;
00184     else if (selActor->state & STATE_REACTION_ONCE)
00185         state = STATE_REACTION_MANY;
00186     else if (selActor->state & STATE_REACTION_MANY)
00187         state = ~STATE_REACTION;
00188 
00189     /* Send request to update actor's reaction state to the server. */
00190     MSG_Write_PA(PA_STATE, selActor->entnum, state);
00191 }
00192 
00203 int HUD_CalcReloadTime (const le_t *le, const objDef_t *weapon, containerIndex_t toContainer)
00204 {
00205     containerIndex_t container;
00206     invList_t *ic;
00207 
00208     if (toContainer == NONE)
00209         return -1;
00210 
00211     assert(le);
00212     assert(weapon);
00213 
00214     container = CL_ActorGetContainerForReload(&ic, &le->i, weapon);
00215     if (container == NONE)
00216         return -1;
00217 
00218     /* total TU cost is the sum of 3 numbers:
00219      * TU for weapon reload + TU to get ammo out + TU to put ammo in hands */
00220     return TU_GET_RELOAD(container, toContainer, weapon);
00221 }
00222 
00231 static qboolean HUD_CheckReload (const le_t* le, const invList_t *weapon, containerIndex_t container)
00232 {
00233     int tus;
00234 
00235     if (!le)
00236         return qfalse;
00237 
00238     /* No item in hand. */
00239     if (!weapon || !weapon->item.t) {
00240         HUD_DisplayMessage(_("No item in hand.\n"));
00241         return qfalse;
00242     }
00243 
00244     /* Cannot reload because this item is not reloadable. */
00245     if (!weapon->item.t->reload) {
00246         HUD_DisplayMessage(_("Can't perform action:\nthis item is not reloadable.\n"));
00247         return qfalse;
00248     }
00249 
00250     tus = HUD_CalcReloadTime(le, weapon->item.t, container);
00251     /* Cannot reload because of no ammo in inventory. */
00252     if (tus == -1) {
00253         HUD_DisplayMessage(_("Can't perform action:\nammo not available.\n"));
00254         return qfalse;
00255     }
00256     /* Cannot reload because of not enough TUs. */
00257     if (le->TU < tus) {
00258         HUD_DisplayMessage(_("Can't perform action:\nnot enough TUs.\n"));
00259         return qfalse;
00260     }
00261 
00262     return qtrue;
00263 }
00264 
00268 static void HUD_ReloadLeft_f (void)
00269 {
00270     containerIndex_t container = csi.idLeft;
00271     if (!HUD_CheckReload(selActor, HUD_GetLeftHandWeapon(selActor, &container), container))
00272         return;
00273     CL_ActorReload(selActor, container);
00274 }
00275 
00279 static void HUD_ReloadRight_f (void)
00280 {
00281     if (!selActor || !HUD_CheckReload(selActor, RIGHT(selActor), csi.idRight))
00282         return;
00283     CL_ActorReload(selActor, csi.idRight);
00284 }
00285 
00286 void HUD_InitCallbacks (void)
00287 {
00288     Cmd_AddCommand("hud_reloadleft", HUD_ReloadLeft_f, _("Reload the weapon in the soldiers left hand"));
00289     Cmd_AddCommand("hud_reloadright", HUD_ReloadRight_f, _("Reload the weapon in the soldiers right hand"));
00290     Cmd_AddCommand("hud_togglecrouchreserve", HUD_ToggleCrouchReservation_f, _("Toggle reservation for crouching."));
00291     Cmd_AddCommand("hud_togglereaction", HUD_ToggleReaction_f, _("Toggle reaction fire"));
00292     Cmd_AddCommand("hud_fireweapon", HUD_FireWeapon_f, "Start aiming the weapon.");
00293 }

Generated by  doxygen 1.6.2