00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "../client.h"
00027 #include "cl_localentity.h"
00028 #include "cl_actor.h"
00029 #include "cl_hud.h"
00030 #include "cl_hud_callbacks.h"
00031 #include "cl_view.h"
00032 #include "../cl_team.h"
00033 #include "../cl_game.h"
00034 #include "../ui/ui_main.h"
00035 #include "../ui/ui_popup.h"
00036 #include "../ui/ui_nodes.h"
00037 #include "../ui/ui_draw.h"
00038 #include "../ui/ui_render.h"
00039 #include "../renderer/r_mesh_anim.h"
00040 #include "../renderer/r_draw.h"
00041 #include "../../common/grid.h"
00042
00044 static qboolean visibleFiremodeListLeft = qfalse;
00045 static qboolean visibleFiremodeListRight = qfalse;
00046
00047 static cvar_t *cl_hud_message_timeout;
00048 static cvar_t *cl_show_cursor_tooltips;
00049 cvar_t *cl_worldlevel;
00050
00051 enum {
00052 REMAINING_TU_RELOAD_RIGHT,
00053 REMAINING_TU_RELOAD_LEFT,
00054 REMAINING_TU_CROUCH,
00055
00056 REMAINING_TU_MAX
00057 };
00058 static qboolean displayRemainingTus[REMAINING_TU_MAX];
00059
00060 typedef enum {
00061 BT_RIGHT_FIRE,
00062 BT_REACTION,
00063 BT_LEFT_FIRE,
00064 BT_RIGHT_RELOAD,
00065 BT_LEFT_RELOAD,
00066 BT_STAND,
00067 BT_CROUCH,
00068 BT_HEADGEAR,
00069
00070 BT_NUM_TYPES
00071 } buttonTypes_t;
00072
00074 static const char *shootTypeStrings[] = {
00075 "primaryright",
00076 "reaction",
00077 "primaryleft",
00078 "reloadright",
00079 "reloadleft",
00080 "stand",
00081 "crouch",
00082 "headgear"
00083 };
00084 CASSERT(lengthof(shootTypeStrings) == BT_NUM_TYPES);
00085
00090 typedef enum {
00091 BT_STATE_DISABLE,
00092 BT_STATE_DESELECT
00093 } weaponButtonState_t;
00094
00096 static const char *moveModeDescriptions[] = {
00097 N_("Crouch walk"),
00098 N_("Autostand"),
00099 N_("Walk"),
00100 N_("Crouch walk")
00101 };
00102 CASSERT(lengthof(moveModeDescriptions) == WALKTYPE_MAX);
00103
00104 typedef struct reserveShot_s {
00105 actorHands_t hand;
00106 int fireModeIndex;
00107 int weaponIndex;
00108 int TUs;
00109 } reserveShot_t;
00110
00111 static int hudTime;
00112 static char hudText[256];
00113
00119 void HUD_DisplayMessage (const char *text)
00120 {
00121 assert(text);
00122 UI_DisplayNotice(text, cl_hud_message_timeout->integer, mn_hud->string);
00123 }
00124
00130 static void HUD_UpdateAllActors (void)
00131 {
00132 int i;
00133 const size_t size = lengthof(cl.teamList);
00134
00135 Cvar_SetValue("mn_numaliensspotted", cl.numAliensSpotted);
00136 for (i = 0; i < size; i++) {
00137 const le_t *le = cl.teamList[i];
00138 if (le && !LE_IsDead(le)) {
00139 const invList_t *invList;
00140 const char* tooltip;
00141 const character_t *chr = CL_ActorGetChr(le);
00142 assert(chr);
00143
00144 invList = RIGHT(le);
00145 if ((!invList || !invList->item.t || !invList->item.t->holdTwoHanded) && LEFT(le))
00146 invList = LEFT(le);
00147
00148 tooltip = va(_("%s\nHP: %i/%i TU: %i\n%s"),
00149 chr->name, le->HP, le->maxHP, le->TU, (invList && invList->item.t) ? _(invList->item.t->name) : "");
00150
00151 UI_ExecuteConfunc("updateactorvalues %i \"%s\" \"%i\" \"%i\" \"%i\" \"%i\" \"%i\" \"%i\" \"%i\" \"%s\"",
00152 i, le->model2->name, le->HP, le->maxHP, le->TU, le->maxTU, le->morale, le->maxMorale, le->STUN, tooltip);
00153 }
00154 }
00155 }
00156
00161 static void HUD_SetWeaponButton (buttonTypes_t button, weaponButtonState_t state)
00162 {
00163 const char const* prefix;
00164
00165 switch (state) {
00166 case BT_STATE_DESELECT:
00167 prefix = "deselect_";
00168 break;
00169 case BT_STATE_DISABLE:
00170 prefix = "disable_";
00171 break;
00172 default:
00173 prefix = "";
00174 break;
00175 }
00176
00177
00178 UI_ExecuteConfunc("%s%s", prefix, shootTypeStrings[button]);
00179 }
00180
00184 void HUD_HideFiremodes (void)
00185 {
00186 visibleFiremodeListLeft = qfalse;
00187 visibleFiremodeListRight = qfalse;
00188 UI_ExecuteConfunc("hide_firemodes");
00189 }
00190
00198 static int HUD_UsableReactionTUs (const le_t * le)
00199 {
00200
00201 if (le->state & STATE_REACTION)
00202
00203 return CL_ActorUsableTUs(le) + CL_ActorReservedTUs(le, RES_REACTION);
00204 else
00205
00206 return CL_ActorUsableTUs(le);
00207 }
00208
00215 static qboolean HUD_CheckFiremodeReservation (void)
00216 {
00217 actorHands_t hand = ACTOR_HAND_RIGHT;
00218
00219 if (!selActor)
00220 return qfalse;
00221
00222 do {
00223 const fireDef_t *fireDef;
00224
00225
00226 fireDef = HUD_GetFireDefinitionForHand(selActor, hand);
00227 if (fireDef) {
00228 int i;
00229 const objDef_t *ammo = fireDef->obj;
00230 for (i = 0; i < ammo->numFiredefs[fireDef->weapFdsIdx]; i++) {
00231
00232 if (CL_ActorUsableTUs(selActor) + CL_ActorReservedTUs(selActor, RES_SHOT) >= ammo->fd[fireDef->weapFdsIdx][i].time)
00233 return qtrue;
00234 }
00235 }
00236
00237
00238 if (hand == ACTOR_HAND_RIGHT)
00239 hand = ACTOR_HAND_LEFT;
00240 else
00241 break;
00242 } while (qtrue);
00243
00244
00245 return qfalse;
00246 }
00247
00248
00257 static void HUD_SetShootReservation (const le_t* le, const int tus, const actorHands_t hand, const int fireModeIndex, const objDef_t *weapon)
00258 {
00259 character_t* chr = CL_ActorGetChr(le);
00260 assert(chr);
00261
00262 CL_ActorReserveTUs(le, RES_SHOT, tus);
00263 CL_ActorSetShotSettings(chr, hand, fireModeIndex, weapon);
00264 }
00265
00266 static linkedList_t* popupListData;
00267 static uiNode_t* popupListNode;
00268
00277 static void HUD_PopupFiremodeReservation (qboolean reset, qboolean popupReload)
00278 {
00279 actorHands_t hand = ACTOR_HAND_RIGHT;
00280 int i;
00281 static char text[MAX_VAR];
00282 int selectedEntry;
00283 linkedList_t* popupListText = NULL;
00284 reserveShot_t reserveShotData;
00285
00286 if (!selActor)
00287 return;
00288
00289 if (reset) {
00290 HUD_SetShootReservation(selActor, 0, ACTOR_HAND_NOT_SET, -1, NULL);
00291 return;
00292 }
00293
00294
00295 UI_ResetData(TEXT_LIST);
00296
00297 LIST_Delete(&popupListData);
00298
00299
00300 LIST_AddPointer(&popupListText, _("[0 TU] No reservation"));
00301 reserveShotData.hand = ACTOR_HAND_NOT_SET;
00302 reserveShotData.fireModeIndex = -1;
00303 reserveShotData.weaponIndex = NONE;
00304 reserveShotData.TUs = -1;
00305 LIST_Add(&popupListData, (byte *)&reserveShotData, sizeof(reserveShotData));
00306 selectedEntry = 0;
00307
00308 do {
00309 const fireDef_t *fd = HUD_GetFireDefinitionForHand(selActor, hand);
00310 character_t* chr = CL_ActorGetChr(selActor);
00311 assert(chr);
00312
00313 if (fd) {
00314 const objDef_t *ammo = fd->obj;
00315
00316 for (i = 0; i < ammo->numFiredefs[fd->weapFdsIdx]; i++) {
00317 const fireDef_t* ammoFD = &ammo->fd[fd->weapFdsIdx][i];
00318 if (CL_ActorUsableTUs(selActor) + CL_ActorReservedTUs(selActor, RES_SHOT) >= ammoFD->time) {
00319
00320 Com_sprintf(text, lengthof(text), _("[%i TU] %s"), ammoFD->time, _(ammoFD->name));
00321
00322
00323 LIST_AddString(&popupListText, text);
00324
00325
00326 reserveShotData.hand = hand;
00327 reserveShotData.fireModeIndex = i;
00328 reserveShotData.weaponIndex = ammo->weapons[fd->weapFdsIdx]->idx;
00329 reserveShotData.TUs = ammoFD->time;
00330 LIST_Add(&popupListData, (byte *)&reserveShotData, sizeof(reserveShotData));
00331
00332
00333 if (chr->reservedTus.shotSettings.hand == hand
00334 && chr->reservedTus.shotSettings.fmIdx == i
00335 && chr->reservedTus.shotSettings.weapon == ammo->weapons[fd->weapFdsIdx])
00336 selectedEntry = LIST_Count(popupListData) - 1;
00337 }
00338 }
00339 }
00340
00341
00342 if (hand == ACTOR_HAND_RIGHT)
00343
00344 hand = ACTOR_HAND_LEFT;
00345 else
00346 break;
00347 } while (qtrue);
00348
00349 if (LIST_Count(popupListData) > 1 || popupReload) {
00350
00351
00352 popupListNode = UI_PopupList(_("Shot Reservation"), _("Reserve TUs for firing/using."), popupListText, "hud_shotreserve <lineselected>");
00353
00354 VectorSet(popupListNode->selectedColor, 0.0, 0.78, 0.0);
00355 popupListNode->selectedColor[3] = 1.0;
00356 UI_TextNodeSelectLine(popupListNode, selectedEntry);
00357 }
00358 }
00359
00364 static void HUD_PopupFiremodeReservation_f (void)
00365 {
00366
00367
00368 HUD_PopupFiremodeReservation(Cmd_Argc() == 2, qfalse);
00369 }
00370
00375 static void HUD_ShotReserve_f (void)
00376 {
00377 int selectedPopupIndex;
00378 const reserveShot_t* reserveShotData;
00379
00380 if (Cmd_Argc() < 2) {
00381 Com_Printf("Usage: %s <popupindex>\n", Cmd_Argv(0));
00382 return;
00383 }
00384
00385 if (!selActor)
00386 return;
00387
00388
00389 selectedPopupIndex = atoi(Cmd_Argv(1));
00390 if (selectedPopupIndex < 0 || selectedPopupIndex >= LIST_Count(popupListData))
00391 return;
00392
00393 reserveShotData = LIST_GetByIdx(popupListData, selectedPopupIndex);
00394 if (!reserveShotData)
00395 return;
00396
00397 if (reserveShotData->weaponIndex == NONE) {
00398 HUD_SetShootReservation(selActor, 0, ACTOR_HAND_NOT_SET, -1, NULL);
00399 return;
00400 }
00401
00403
00404 if (CL_ActorUsableTUs(selActor) + CL_ActorReservedTUs(selActor, RES_SHOT) >= reserveShotData->TUs) {
00405 const objDef_t *od = INVSH_GetItemByIDX(reserveShotData->weaponIndex);
00406 if (GAME_ItemIsUseable(od)) {
00407 HUD_SetShootReservation(selActor, max(0, reserveShotData->TUs), reserveShotData->hand, reserveShotData->fireModeIndex, od);
00408 if (popupListNode)
00409 UI_TextNodeSelectLine(popupListNode, selectedPopupIndex);
00410 }
00411 }
00412 }
00413
00418 static void HUD_DisplayFiremodeEntry (const le_t* actor, const objDef_t* ammo, const weaponFireDefIndex_t weapFdsIdx, const actorHands_t hand, int index)
00419 {
00420 int usableTusForRF;
00421 char tuString[MAX_VAR];
00422 qboolean status;
00423 const fireDef_t *fd;
00424 const char *tooltip;
00425
00426 if (index < ammo->numFiredefs[weapFdsIdx]) {
00427
00428 fd = &ammo->fd[weapFdsIdx][index];
00429 } else {
00430
00431 if (hand == ACTOR_HAND_RIGHT)
00432 UI_ExecuteConfunc("set_right_inv %i", index);
00433 else
00434 UI_ExecuteConfunc("set_left_inv %i", index);
00435 return;
00436 }
00437
00438 assert(actor);
00439 assert(hand == ACTOR_HAND_RIGHT || hand == ACTOR_HAND_LEFT);
00440
00441 status = fd->time <= CL_ActorUsableTUs(actor);
00442 usableTusForRF = HUD_UsableReactionTUs(actor);
00443
00444 if (usableTusForRF > fd->time) {
00445 Com_sprintf(tuString, sizeof(tuString), _("Remaining TUs: %i"), usableTusForRF - fd->time);
00446 tooltip = tuString;
00447 } else
00448 tooltip = _("No remaining TUs left after shot.");
00449
00450 UI_ExecuteConfunc("set_firemode %c %i %i %i \"%s\" \"%s\" \"%s\" \"%s\"", ACTOR_GET_HAND_CHAR(hand),
00451 fd->fdIdx, fd->reaction, status, _(fd->name), va(_("TU: %i"), fd->time),
00452 va(_("Shots: %i"), fd->ammo), tooltip);
00453
00454
00455 if (fd->reaction) {
00456 character_t* chr = CL_ActorGetChr(actor);
00457 const qboolean active = THIS_FIREMODE(&chr->RFmode, hand, fd->fdIdx);
00458
00459 UI_ExecuteConfunc("set_firemode_checkbox %c %i %i", ACTOR_GET_HAND_CHAR(hand), fd->fdIdx, active);
00460 }
00461 }
00462
00463 void HUD_DisplayFiremodes (const le_t* actor, actorHands_t hand, qboolean firemodesChangeDisplay)
00464 {
00465 const objDef_t *ammo;
00466 const fireDef_t *fd;
00467 int i;
00468 character_t* chr;
00469
00470 if (!actor)
00471 return;
00472
00473 if (cls.team != cl.actTeam) {
00474 HUD_HideFiremodes();
00475 return;
00476 }
00477
00478 fd = HUD_GetFireDefinitionForHand(actor, hand);
00479 if (fd == NULL)
00480 return;
00481
00482 ammo = fd->obj;
00483 if (!ammo) {
00484 Com_DPrintf(DEBUG_CLIENT, "HUD_DisplayFiremodes: no weapon or ammo found.\n");
00485 return;
00486 }
00487
00488 if (firemodesChangeDisplay) {
00489
00490 HUD_HideFiremodes();
00491 if (hand == ACTOR_HAND_RIGHT) {
00492 visibleFiremodeListRight = qtrue;
00493 } else {
00494 visibleFiremodeListLeft = qtrue;
00495 }
00496 }
00497
00498 chr = CL_ActorGetChr(actor);
00499 assert(chr);
00500
00501 for (i = 0; i < MAX_FIREDEFS_PER_WEAPON; i++) {
00502
00503 HUD_DisplayFiremodeEntry(actor, ammo, fd->weapFdsIdx, hand, i);
00504 }
00505 }
00506
00510 static void HUD_DisplayFiremodes_f (void)
00511 {
00512 actorHands_t hand;
00513
00514 if (!selActor)
00515 return;
00516
00517 if (Cmd_Argc() < 2)
00518
00519 hand = ACTOR_HAND_RIGHT;
00520 else
00521 hand = ACTOR_GET_HAND_INDEX(Cmd_Argv(1)[0]);
00522
00523 HUD_DisplayFiremodes(selActor, hand, qtrue);
00524 }
00525
00530 static void HUD_SwitchFiremodeList_f (void)
00531 {
00532
00533 if (Cmd_Argc() < 2) {
00534 Com_Printf("Usage: %s [l|r]\n", Cmd_Argv(0));
00535 return;
00536 }
00537
00538 if (visibleFiremodeListRight || visibleFiremodeListLeft)
00539 HUD_DisplayFiremodes(selActor, ACTOR_GET_HAND_INDEX(Cmd_Argv(1)[0]), qfalse);
00540 }
00541
00548 static void HUD_UpdateReactionFiremodes (const le_t * actor, const actorHands_t hand, fireDefIndex_t firemodeActive)
00549 {
00550 const fireDef_t *fd;
00551 const objDef_t *ammo, *od;
00552
00553 assert(actor);
00554
00555 fd = HUD_GetFireDefinitionForHand(actor, hand);
00556 if (fd == NULL)
00557 return;
00558
00559 ammo = fd->obj;
00560 od = ammo->weapons[fd->weapFdsIdx];
00561
00562 if (!GAME_ItemIsUseable(od))
00563 return;
00564
00565 MSG_Write_PA(PA_REACT_SELECT, actor->entnum, hand, firemodeActive, od ? od->idx : NONE);
00566 }
00567
00571 static void HUD_SelectReactionFiremode_f (void)
00572 {
00573 actorHands_t hand;
00574 fireDefIndex_t firemode;
00575
00576 if (Cmd_Argc() < 3) {
00577 Com_Printf("Usage: %s [l|r] <num> num=firemode number\n", Cmd_Argv(0));
00578 return;
00579 }
00580
00581 if (!selActor)
00582 return;
00583
00584 hand = ACTOR_GET_HAND_INDEX(Cmd_Argv(1)[0]);
00585 firemode = atoi(Cmd_Argv(2));
00586
00587 if (firemode >= MAX_FIREDEFS_PER_WEAPON || firemode < 0) {
00588 Com_Printf("HUD_SelectReactionFiremode_f: Firemode out of bounds (%i).\n", firemode);
00589 return;
00590 }
00591
00592 HUD_UpdateReactionFiremodes(selActor, hand, firemode);
00593 }
00594
00599 static void HUD_RemainingTUs_f (void)
00600 {
00601 qboolean state;
00602 const char *type;
00603
00604 if (Cmd_Argc() < 3) {
00605 Com_Printf("Usage: %s <type> <popupindex>\n", Cmd_Argv(0));
00606 return;
00607 }
00608
00609 type = Cmd_Argv(1);
00610 state = Com_ParseBoolean(Cmd_Argv(2));
00611
00612 memset(displayRemainingTus, 0, sizeof(displayRemainingTus));
00613
00614 if (!strcmp(type, "reload_r")) {
00615 displayRemainingTus[REMAINING_TU_RELOAD_RIGHT] = state;
00616 } else if (!strcmp(type, "reload_l")) {
00617 displayRemainingTus[REMAINING_TU_RELOAD_LEFT] = state;
00618 } else if (!strcmp(type, "crouch")) {
00619 displayRemainingTus[REMAINING_TU_CROUCH] = state;
00620 }
00621 }
00622
00626 static int HUD_GetMinimumTUsForUsage (const invList_t *invList)
00627 {
00628 const fireDef_t *fdArray;
00629 int time = 100;
00630 int i;
00631
00632 assert(invList->item.t);
00633
00634 fdArray = FIRESH_FiredefForWeapon(&invList->item);
00635 if (fdArray == NULL)
00636 return time;
00637
00638
00639 for (i = 0; i < MAX_FIREDEFS_PER_WEAPON; i++) {
00640 if (!fdArray[i].time)
00641 continue;
00642 if (fdArray[i].time < time)
00643 time = fdArray[i].time;
00644 }
00645
00646 return time;
00647 }
00648
00656 static int HUD_WeaponCanBeReloaded (const le_t *le, containerIndex_t containerID, const char **reason)
00657 {
00658 const int tu = CL_ActorUsableTUs(le);
00659 const invList_t *invList = CONTAINER(le, containerID);
00660 const objDef_t *weapon;
00661
00662 assert(le);
00663
00664
00665 if (!invList) {
00666 *reason = _("No weapon.");
00667 return -1;
00668 }
00669
00670 weapon = invList->item.t;
00671 assert(weapon);
00672
00673
00674 if (!weapon->reload) {
00675 *reason = _("Weapon cannot be reloaded.");
00676 return -1;
00677 }
00678
00679
00680 if (invList->item.m && weapon->ammo == invList->item.a) {
00681 *reason = _("No reload possible, already fully loaded.");
00682 return -1;
00683 }
00684
00685
00686 if (!invList->item.m || weapon->ammo > invList->item.a) {
00687 const int tuCosts = HUD_CalcReloadTime(le, weapon, containerID);
00688 if (tuCosts >= 0) {
00689 if (tu >= tuCosts)
00690 return tuCosts;
00691 *reason = _("Not enough TUs for reloading weapon.");
00692 } else {
00693
00694 *reason = _("No reload possible, you don't have backup ammo.");
00695 }
00696 }
00697
00698 return -1;
00699 }
00700
00705 static qboolean HUD_WeaponWithReaction (const le_t * actor)
00706 {
00707 const objDef_t *weapon = INVSH_HasReactionFireEnabledWeapon(RIGHT(actor));
00708 if (weapon)
00709 return qtrue;
00710 return INVSH_HasReactionFireEnabledWeapon(LEFT(actor)) != NULL;
00711 }
00712
00718 static qboolean HUD_DisplayImpossibleReaction (const le_t * actor)
00719 {
00720 if (!actor)
00721 return qfalse;
00722
00723
00724 if (!actor->selected)
00725 return qfalse;
00726
00727
00728 if (actor->state & STATE_REACTION_ONCE)
00729 UI_ExecuteConfunc("startreactiononce_impos");
00730 else if (actor->state & STATE_REACTION_MANY)
00731 UI_ExecuteConfunc("startreactionmany_impos");
00732 else
00733 return qtrue;
00734
00735 return qfalse;
00736 }
00737
00742 static void HUD_DisplayPossibleReaction (const le_t * actor)
00743 {
00744 if (!actor)
00745 return;
00746
00747
00748 if (!actor->selected)
00749 return;
00750
00751
00752 if (actor->state & STATE_REACTION_ONCE)
00753 UI_ExecuteConfunc("startreactiononce");
00754 else if (actor->state & STATE_REACTION_MANY)
00755 UI_ExecuteConfunc("startreactionmany");
00756 }
00757
00762 static void HUD_RefreshButtons (const le_t *le)
00763 {
00764 invList_t *weaponr;
00765 invList_t *weaponl;
00766 invList_t *headgear;
00767 int rightCanBeReloaded, leftCanBeReloaded;
00768 const int time = CL_ActorUsableTUs(le);
00769 const char *reason;
00770
00771 if (!le)
00772 return;
00773
00774 weaponr = RIGHT(le);
00775 headgear = HEADGEAR(le);
00776
00777
00778 if (!weaponr || !weaponr->item.t->holdTwoHanded)
00779 weaponl = LEFT(le);
00780 else
00781 weaponl = NULL;
00782
00783
00784 if (LE_IsCrouched(le)) {
00785 if (time + CL_ActorReservedTUs(le, RES_CROUCH) < TU_CROUCH) {
00786 Cvar_Set("mn_crouchstand_tt", _("Not enough TUs for standing up."));
00787 HUD_SetWeaponButton(BT_CROUCH, BT_STATE_DISABLE);
00788 } else {
00789 Cvar_Set("mn_crouchstand_tt", va(_("Stand up (%i TU)"), TU_CROUCH));
00790 HUD_SetWeaponButton(BT_CROUCH, BT_STATE_DESELECT);
00791 }
00792 } else {
00793 if (time + CL_ActorReservedTUs(le, RES_CROUCH) < TU_CROUCH) {
00794 Cvar_Set("mn_crouchstand_tt", _("Not enough TUs for crouching."));
00795 HUD_SetWeaponButton(BT_STAND, BT_STATE_DISABLE);
00796 } else {
00797 Cvar_Set("mn_crouchstand_tt", va(_("Crouch (%i TU)"), TU_CROUCH));
00798 HUD_SetWeaponButton(BT_STAND, BT_STATE_DESELECT);
00799 }
00800 }
00801
00802
00803 if (CL_ActorReservedTUs(le, RES_CROUCH) >= TU_CROUCH) {
00804 UI_ExecuteConfunc("crouch_checkbox_check");
00805 Cvar_Set("mn_crouch_reservation_tt", va(_("%i TUs reserved for crouching/standing up.\nClick to clear."),
00806 CL_ActorReservedTUs(le, RES_CROUCH)));
00807 } else if (time >= TU_CROUCH) {
00808 UI_ExecuteConfunc("crouch_checkbox_clear");
00809 Cvar_Set("mn_crouch_reservation_tt", va(_("Reserve %i TUs for crouching/standing up."), TU_CROUCH));
00810 } else {
00811 UI_ExecuteConfunc("crouch_checkbox_disable");
00812 Cvar_Set("mn_crouch_reservation_tt", _("Not enough TUs left to reserve for crouching/standing up."));
00813 }
00814
00815
00816 if (CL_ActorReservedTUs(le, RES_SHOT)) {
00817 UI_ExecuteConfunc("reserve_shot_check");
00818 Cvar_Set("mn_shot_reservation_tt", va(_("%i TUs reserved for shooting.\nClick to change.\nRight-Click to clear."),
00819 CL_ActorReservedTUs(le, RES_SHOT)));
00820 } else if (HUD_CheckFiremodeReservation()) {
00821 UI_ExecuteConfunc("reserve_shot_clear");
00822 Cvar_Set("mn_shot_reservation_tt", _("Reserve TUs for shooting."));
00823 } else {
00824 UI_ExecuteConfunc("reserve_shot_disable");
00825 Cvar_Set("mn_shot_reservation_tt", _("Reserving TUs for shooting not possible."));
00826 }
00827
00828
00829 if (!(le->state & STATE_REACTION)) {
00830 if (time >= CL_ActorReservedTUs(le, RES_REACTION) && HUD_WeaponWithReaction(le))
00831 HUD_SetWeaponButton(BT_REACTION, BT_STATE_DESELECT);
00832 else
00833 HUD_SetWeaponButton(BT_REACTION, BT_STATE_DISABLE);
00834 } else {
00835 if (HUD_WeaponWithReaction(le)) {
00836 HUD_DisplayPossibleReaction(le);
00837 } else {
00838 HUD_DisplayImpossibleReaction(le);
00839 }
00840 }
00841
00842
00843 rightCanBeReloaded = HUD_WeaponCanBeReloaded(le, csi.idRight, &reason);
00844 if (rightCanBeReloaded != -1) {
00845 HUD_SetWeaponButton(BT_RIGHT_RELOAD, BT_STATE_DESELECT);
00846 Cvar_Set("mn_reloadright_tt", va(_("Reload weapon (%i TU)."), rightCanBeReloaded));
00847 } else {
00848 Cvar_Set("mn_reloadright_tt", reason);
00849 HUD_SetWeaponButton(BT_RIGHT_RELOAD, BT_STATE_DISABLE);
00850 }
00851
00852 leftCanBeReloaded = HUD_WeaponCanBeReloaded(le, csi.idLeft, &reason);
00853 if (leftCanBeReloaded != -1) {
00854 HUD_SetWeaponButton(BT_LEFT_RELOAD, BT_STATE_DESELECT);
00855 Cvar_Set("mn_reloadleft_tt", va(_("Reload weapon (%i TU)."), leftCanBeReloaded));
00856 } else {
00857 Cvar_Set("mn_reloadleft_tt", reason);
00858 HUD_SetWeaponButton(BT_LEFT_RELOAD, BT_STATE_DISABLE);
00859 }
00860
00861
00862 if (headgear) {
00863 const int minheadgeartime = HUD_GetMinimumTUsForUsage(headgear);
00864 if (time < minheadgeartime)
00865 HUD_SetWeaponButton(BT_HEADGEAR, BT_STATE_DISABLE);
00866 else
00867 HUD_SetWeaponButton(BT_HEADGEAR, BT_STATE_DESELECT);
00868 } else {
00869 HUD_SetWeaponButton(BT_HEADGEAR, BT_STATE_DISABLE);
00870 }
00871
00872
00873 if (weaponr) {
00874 const int minweaponrtime = HUD_GetMinimumTUsForUsage(weaponr);
00875 if (time < minweaponrtime)
00876 HUD_SetWeaponButton(BT_RIGHT_FIRE, BT_STATE_DISABLE);
00877 else
00878 HUD_SetWeaponButton(BT_RIGHT_FIRE, BT_STATE_DESELECT);
00879 } else {
00880 HUD_SetWeaponButton(BT_RIGHT_FIRE, BT_STATE_DISABLE);
00881 }
00882
00883 if (weaponl) {
00884 const int minweaponltime = HUD_GetMinimumTUsForUsage(weaponl);
00885 if (time < minweaponltime)
00886 HUD_SetWeaponButton(BT_LEFT_FIRE, BT_STATE_DISABLE);
00887 else
00888 HUD_SetWeaponButton(BT_LEFT_FIRE, BT_STATE_DESELECT);
00889 } else {
00890 HUD_SetWeaponButton(BT_LEFT_FIRE, BT_STATE_DISABLE);
00891 }
00892
00893
00894 {
00895 const char* menuName = UI_GetActiveWindowName();
00896 if (menuName[0] != '\0' && strstr(UI_GetActiveWindowName(), POPUPLIST_NODE_NAME)) {
00897
00899 HUD_PopupFiremodeReservation(qfalse, qtrue);
00900 }
00901 }
00902 }
00903
00910 static void HUD_DrawMouseCursorText (int xOffset, int yOffset, int textId)
00911 {
00912 const char *string = UI_GetText(textId);
00913
00914 if (string && cl_show_cursor_tooltips->integer) {
00915 int width = 0;
00916 int height = 0;
00917
00918 R_FontTextSize("f_verysmall", string, viddef.virtualWidth - mousePosX, LONGLINES_WRAP, &width, &height, NULL, NULL);
00919
00920 if (!width)
00921 return;
00922
00923 UI_DrawString("f_verysmall", ALIGN_UL, mousePosX + xOffset, mousePosY - yOffset, 0, viddef.virtualWidth, 12, string, 0, 0, NULL, qfalse, 0);
00924 }
00925 }
00926
00930 void HUD_UpdateCursor (void)
00931 {
00932
00933 int iconOffsetX = 16;
00934
00935
00936 const int iconSpacing = 2;
00937 le_t *le = selActor;
00938 if (le) {
00939 int iconOffsetY = 16;
00940 image_t *image;
00941
00942 int iconW = 16;
00943
00944 int iconH = 16;
00945 int width = 0;
00946 int bgX = mousePosX + iconOffsetX / 2 - 2;
00947
00948
00949 if (!(LE_IsCrouched(le) || (le->state & STATE_REACTION)))
00950
00951 bgX += iconW + 4;
00952
00953
00954 if (UI_GetText(TEXT_MOUSECURSOR_PLAYERNAMES))
00955 R_FontTextSize("f_verysmall", UI_GetText(TEXT_MOUSECURSOR_PLAYERNAMES), viddef.virtualWidth - bgX, LONGLINES_WRAP, &width, NULL, NULL, NULL);
00956
00957
00958 if (width == 0 && UI_GetText(TEXT_MOUSECURSOR_RIGHT)) {
00959 R_FontTextSize("f_verysmall", UI_GetText(TEXT_MOUSECURSOR_RIGHT), viddef.virtualWidth - bgX, LONGLINES_WRAP, &width, NULL, NULL, NULL);
00960 }
00961
00962
00963 if (LE_IsCrouched(le)) {
00964 image = R_FindImage("pics/cursors/ducked", it_pic);
00965 if (image)
00966 R_DrawImage(mousePosX - image->width / 2 + iconOffsetX, mousePosY - image->height / 2 + iconOffsetY, image);
00967 }
00968
00969
00970 iconOffsetY += 16;
00971 iconOffsetY += iconSpacing;
00972
00973
00974 if (le->state & STATE_REACTION_ONCE)
00975 image = R_FindImage("pics/cursors/reactionfire", it_pic);
00976 else if (le->state & STATE_REACTION_MANY)
00977 image = R_FindImage("pics/cursors/reactionfiremany", it_pic);
00978 else
00979 image = NULL;
00980
00981 if (image)
00982 R_DrawImage(mousePosX - image->width / 2 + iconOffsetX, mousePosY - image->height / 2 + iconOffsetY, image);
00983
00984
00985 iconOffsetY += iconH;
00986 iconOffsetY += iconSpacing;
00987
00988
00989 HUD_DrawMouseCursorText(iconOffsetX + iconW, -10, TEXT_MOUSECURSOR_RIGHT);
00990 }
00991
00992
00993 HUD_DrawMouseCursorText(iconOffsetX + 16, -26, TEXT_MOUSECURSOR_PLAYERNAMES);
00994 UI_ResetData(TEXT_MOUSECURSOR_PLAYERNAMES);
00995
00996 if (cl_map_debug->integer & MAPDEBUG_TEXT) {
00997
00998 HUD_DrawMouseCursorText(0, -64, TEXT_MOUSECURSOR_TOP);
00999
01000 HUD_DrawMouseCursorText(0, 64, TEXT_MOUSECURSOR_BOTTOM);
01001
01002 HUD_DrawMouseCursorText(-64, 0, TEXT_MOUSECURSOR_LEFT);
01003 }
01004 }
01005
01010 static void HUD_MapDebugCursor (const le_t *le)
01011 {
01012 if (cl_map_debug->integer & MAPDEBUG_TEXT) {
01013 int dv;
01014
01015 static char topText[UI_MAX_SMALLTEXTLEN];
01016 static char bottomText[UI_MAX_SMALLTEXTLEN];
01017 static char leftText[UI_MAX_SMALLTEXTLEN];
01018
01019
01020 Com_sprintf(topText, lengthof(topText), "%u-(%i,%i,%i)\n",
01021 Grid_Ceiling(cl.mapData->map, ACTOR_GET_FIELDSIZE(le), truePos), truePos[0], truePos[1], truePos[2]);
01022
01023 UI_RegisterText(TEXT_MOUSECURSOR_TOP, topText);
01024
01025
01026 Com_sprintf(bottomText, lengthof(bottomText), "%i-(%i,%i,%i)\n",
01027 Grid_Floor(cl.mapData->map, ACTOR_GET_FIELDSIZE(le), truePos), mousePos[0], mousePos[1], mousePos[2]);
01028
01029 UI_RegisterText(TEXT_MOUSECURSOR_BOTTOM, bottomText);
01030
01031
01032 dv = Grid_MoveNext(le->pathMap, mousePos, 0);
01033 Com_sprintf(leftText, lengthof(leftText), "%i-%i\n", getDVdir(dv), getDVz(dv));
01034
01035 UI_RegisterText(TEXT_MOUSECURSOR_LEFT, leftText);
01036 }
01037 }
01038
01043 static int HUD_UpdateActorFireMode (le_t *actor)
01044 {
01045 const invList_t *selWeapon;
01046 int time = 0;
01047
01048
01049 if (IS_MODE_FIRE_HEADGEAR(actor->actorMode)) {
01050 selWeapon = HEADGEAR(actor);
01051 } else if (IS_MODE_FIRE_LEFT(actor->actorMode)) {
01052 selWeapon = HUD_GetLeftHandWeapon(actor, NULL);
01053 } else {
01054 selWeapon = RIGHT(actor);
01055 }
01056
01057 UI_ResetData(TEXT_MOUSECURSOR_RIGHT);
01058
01059 if (selWeapon) {
01060 static char infoText[UI_MAX_SMALLTEXTLEN];
01061
01062 if (!selWeapon->item.t) {
01063
01064 CL_ActorSetFireDef(actor, NULL);
01065 } else {
01066
01067 if (!selWeapon->item.m) {
01068 CL_ActorSetFireDef(actor, NULL);
01069
01070
01071 if (selWeapon->item.t->numWeapons > 0) {
01072 if (selWeapon->item.t->weapon || selWeapon->item.t->weapons[0] == selWeapon->item.t) {
01073 const fireDef_t *fdArray = FIRESH_FiredefForWeapon(&selWeapon->item);
01074 if (fdArray != NULL) {
01075
01076 const fireDef_t *old = FIRESH_GetFiredef(selWeapon->item.t, fdArray->weapFdsIdx, actor->currentSelectedFiremode);
01077 CL_ActorSetFireDef(actor, old);
01078 }
01079 }
01080 }
01081 } else {
01082 const fireDef_t *fdArray = FIRESH_FiredefForWeapon(&selWeapon->item);
01083 if (fdArray != NULL) {
01084 const fireDef_t *old = FIRESH_GetFiredef(selWeapon->item.m, fdArray->weapFdsIdx, actor->currentSelectedFiremode);
01085
01086 CL_ActorSetFireDef(actor, old);
01087 }
01088 }
01089 }
01090
01091 if (!GAME_ItemIsUseable(selWeapon->item.t)) {
01092 HUD_DisplayMessage(_("You cannot use this unknown item.\nYou need to research it first.\n"));
01093 CL_ActorSetMode(actor, M_MOVE);
01094 } else if (actor->fd) {
01095 const int hitProbability = CL_GetHitProbability(actor);
01096 static char mouseText[UI_MAX_SMALLTEXTLEN];
01097
01098 Com_sprintf(infoText, lengthof(infoText),
01099 "%s\n%s (%i) [%i%%] %i\n", _(selWeapon->item.t->name), _(actor->fd->name),
01100 actor->fd->ammo, hitProbability, actor->fd->time);
01101
01102
01103 Q_strncpyz(mouseText, infoText, lengthof(mouseText));
01104 UI_RegisterText(TEXT_MOUSECURSOR_RIGHT, mouseText);
01105
01106 time = actor->fd->time;
01107
01108
01109
01110 if ((selWeapon->item.t->reload && selWeapon->item.a <= 0) || CL_ActorUsableTUs(actor) < time)
01111 CL_ActorSetMode(actor, M_MOVE);
01112 } else if (selWeapon) {
01113 Com_sprintf(infoText, lengthof(infoText), _("%s\n(empty)\n"), _(selWeapon->item.t->name));
01114 }
01115
01116 UI_RegisterText(TEXT_STANDARD, infoText);
01117 } else {
01118 CL_ActorSetMode(actor, M_MOVE);
01119 }
01120
01121 return time;
01122 }
01123
01128 static int HUD_UpdateActorMove (const le_t *actor)
01129 {
01130 const int reservedTUs = CL_ActorReservedTUs(actor, RES_ALL_ACTIVE);
01131 static char infoText[UI_MAX_SMALLTEXTLEN];
01132 if (actor->actorMoveLength == ROUTING_NOT_REACHABLE) {
01133 UI_ResetData(TEXT_MOUSECURSOR_RIGHT);
01134 if (reservedTUs > 0)
01135 Com_sprintf(infoText, lengthof(infoText), _("Morale %i | Reserved TUs: %i\n"), actor->morale, reservedTUs);
01136 else
01137 Com_sprintf(infoText, lengthof(infoText), _("Morale %i"), actor->morale);
01138 } else {
01139 static char mouseText[UI_MAX_SMALLTEXTLEN];
01140 const int moveMode = CL_ActorMoveMode(actor, actor->actorMoveLength);
01141 if (reservedTUs > 0)
01142 Com_sprintf(infoText, lengthof(infoText), _("Morale %i | Reserved TUs: %i\n%s %i (%i|%i TU left)\n"),
01143 actor->morale, reservedTUs, _(moveModeDescriptions[moveMode]), actor->actorMoveLength,
01144 actor->TU - actor->actorMoveLength, actor->TU - reservedTUs - actor->actorMoveLength);
01145 else
01146 Com_sprintf(infoText, lengthof(infoText), _("Morale %i\n%s %i (%i TU left)\n"), actor->morale,
01147 _(moveModeDescriptions[moveMode]), actor->actorMoveLength, actor->TU - actor->actorMoveLength);
01148
01149 if (actor->actorMoveLength <= CL_ActorUsableTUs(actor))
01150 Com_sprintf(mouseText, lengthof(mouseText), "%i (%i)\n", actor->actorMoveLength, CL_ActorUsableTUs(actor));
01151 else
01152 Com_sprintf(mouseText, lengthof(mouseText), "- (-)\n");
01153
01154 UI_RegisterText(TEXT_MOUSECURSOR_RIGHT, mouseText);
01155 }
01156
01157 UI_RegisterText(TEXT_STANDARD, infoText);
01158
01159 return actor->actorMoveLength;
01160 }
01161
01162 static void HUD_UpdateActorCvar (le_t *actor, const char *cvarPrefix)
01163 {
01164 const invList_t* invList;
01165 const char *animName;
01166 static char tuTooltipText[UI_MAX_SMALLTEXTLEN];
01167
01168 Cvar_SetValue(va("%s%s", cvarPrefix, "hp"), actor->HP);
01169 Cvar_SetValue(va("%s%s", cvarPrefix, "hpmax"), actor->maxHP);
01170 Cvar_SetValue(va("%s%s", cvarPrefix, "tu"), actor->TU);
01171 Cvar_SetValue(va("%s%s", cvarPrefix, "tumax"), actor->maxTU);
01172 Cvar_SetValue(va("%s%s", cvarPrefix, "tureserved"), CL_ActorReservedTUs(actor, RES_ALL_ACTIVE));
01173 Cvar_SetValue(va("%s%s", cvarPrefix, "morale"), actor->morale);
01174 Cvar_SetValue(va("%s%s", cvarPrefix, "moralemax"), actor->maxMorale);
01175 Cvar_SetValue(va("%s%s", cvarPrefix, "stun"), actor->STUN);
01176
01177 Com_sprintf(tuTooltipText, lengthof(tuTooltipText),
01178 _("Time Units\n- Available: %i (of %i)\n- Reserved: %i\n- Remaining: %i\n"),
01179 actor->TU, actor->maxTU, CL_ActorReservedTUs(actor, RES_ALL_ACTIVE), CL_ActorUsableTUs(actor));
01180 Cvar_Set(va("%s%s", cvarPrefix, "tu_tooltips"), tuTooltipText);
01181
01182
01183 animName = R_AnimGetName(&actor->as, actor->model1);
01184 if (animName)
01185 Cvar_Set(va("%s%s", cvarPrefix, "anim"), animName);
01186 if (RIGHT(actor)) {
01187 const invList_t *i = RIGHT(actor);
01188 Cvar_Set(va("%s%s", cvarPrefix, "rweapon"), i->item.t->model);
01189 Cvar_Set(va("%s%s", cvarPrefix, "rweapon_item"), i->item.t->id);
01190 } else {
01191 Cvar_Set(va("%s%s", cvarPrefix, "rweapon"), "");
01192 Cvar_Set(va("%s%s", cvarPrefix, "rweapon_item"), "");
01193 }
01194 if (LEFT(actor)) {
01195 const invList_t *i = LEFT(actor);
01196 Cvar_Set(va("%s%s", cvarPrefix, "lweapon"), i->item.t->model);
01197 Cvar_Set(va("%s%s", cvarPrefix, "lweapon_item"), i->item.t->id);
01198 } else {
01199 Cvar_Set(va("%s%s", cvarPrefix, "lweapon"), "");
01200 Cvar_Set(va("%s%s", cvarPrefix, "lweapon_item"), "");
01201 }
01202
01203
01204 invList = RIGHT(actor);
01205 if (invList)
01206 Cvar_SetValue(va("%s%s", cvarPrefix, "ammoright"), invList->item.a);
01207 else
01208 Cvar_Set(va("%s%s", cvarPrefix, "ammoright"), "");
01209
01210 invList = HUD_GetLeftHandWeapon(actor, NULL);
01211 if (invList)
01212 Cvar_SetValue(va("%s%s", cvarPrefix, "ammoleft"), invList->item.a);
01213 else
01214 Cvar_Set(va("%s%s", cvarPrefix, "ammoleft"), "");
01215 }
01216
01220 static void HUD_ActorGetCvarData_f (void)
01221 {
01222 if (Cmd_Argc() < 3) {
01223 Com_Printf("Usage: %s <soldiernum> <cvarprefix>\n", Cmd_Argv(0));
01224 return;
01225 }
01226
01227
01228 if (CL_BattlescapeRunning()) {
01229 const int num = atoi(Cmd_Argv(1));
01230 const char *cvarPrefix = Cmd_Argv(2);
01231 le_t *le;
01232 character_t *chr;
01233
01234
01235 if (num >= cl.numTeamList || num < 0)
01236 return;
01237
01238
01239 le = cl.teamList[num];
01240 if (!le)
01241 return;
01242
01243 chr = CL_ActorGetChr(le);
01244 if (!chr) {
01245 Com_Error(ERR_DROP, "No character given for local entity");
01246 return;
01247 }
01248
01249 CL_UpdateCharacterValues(chr, cvarPrefix);
01250
01251
01252 HUD_UpdateActorCvar(le, cvarPrefix);
01253
01254 return;
01255 }
01256 }
01257
01262 static void HUD_UpdateActor (le_t *actor)
01263 {
01264 int time;
01265
01266 HUD_UpdateActorCvar(actor, "mn_");
01267
01268
01269 time = 0;
01270
01271
01272 if (LE_IsPaniced(actor)) {
01273 UI_RegisterText(TEXT_STANDARD, _("Currently panics!\n"));
01274 } else if (displayRemainingTus[REMAINING_TU_CROUCH]) {
01275 if (CL_ActorUsableTUs(actor) >= TU_CROUCH)
01276 time = TU_CROUCH;
01277 } else if (displayRemainingTus[REMAINING_TU_RELOAD_RIGHT]
01278 || displayRemainingTus[REMAINING_TU_RELOAD_LEFT]) {
01279 const invList_t *invList;
01280 containerIndex_t container;
01281
01282 if (displayRemainingTus[REMAINING_TU_RELOAD_RIGHT] && RIGHT(actor)) {
01283 container = csi.idRight;
01284 invList = RIGHT(actor);
01285 } else if (displayRemainingTus[REMAINING_TU_RELOAD_LEFT] && LEFT(actor)) {
01286 container = NONE;
01287 invList = HUD_GetLeftHandWeapon(actor, &container);
01288 } else {
01289 container = NONE;
01290 invList = NULL;
01291 }
01292
01293 if (invList && invList->item.t && invList->item.m && invList->item.t->reload) {
01294 const int reloadtime = HUD_CalcReloadTime(actor, invList->item.t, container);
01295 if (reloadtime != -1 && reloadtime <= CL_ActorUsableTUs(actor))
01296 time = reloadtime;
01297 }
01298 } else if (CL_ActorFireModeActivated(actor->actorMode)) {
01299 time = HUD_UpdateActorFireMode(actor);
01300 } else {
01301
01302
01303 if (mouseSpace != MS_WORLD && actor->actorMode < M_PEND_MOVE)
01304 actor->actorMoveLength = ROUTING_NOT_REACHABLE;
01305 time = HUD_UpdateActorMove(actor);
01306 }
01307
01308
01309
01310 time = max(0, actor->TU - time);
01311 Cvar_Set("mn_turemain", va("%i", time));
01312
01313 HUD_MapDebugCursor(actor);
01314 }
01315
01326 void HUD_Update (void)
01327 {
01328 if (cls.state != ca_active)
01329 return;
01330
01331
01332 if (cl_worldlevel->modified) {
01333 int i;
01334 for (i = 0; i < PATHFINDING_HEIGHT; i++) {
01335 int status = 0;
01336 if (i == cl_worldlevel->integer)
01337 status = 2;
01338 else if (i < cl.mapMaxLevel)
01339 status = 1;
01340 UI_ExecuteConfunc("updateLevelStatus %i %i", i, status);
01341 }
01342 cl_worldlevel->modified = qfalse;
01343 }
01344
01345
01346 HUD_UpdateAllActors();
01347
01348
01349 Cvar_Set("mn_anim", "stand0");
01350 Cvar_Set("mn_rweapon", "");
01351 Cvar_Set("mn_lweapon", "");
01352
01353 if (selActor) {
01354 HUD_UpdateActor(selActor);
01355 } else if (!cl.numTeamList) {
01356
01357 Cvar_SetValue("mn_hp", 0);
01358 Cvar_SetValue("mn_hpmax", 100);
01359 Cvar_SetValue("mn_tu", 0);
01360 Cvar_SetValue("mn_tumax", 100);
01361 Cvar_SetValue("mn_tureserved", 0);
01362 Cvar_SetValue("mn_morale", 0);
01363 Cvar_SetValue("mn_moralemax", 100);
01364 Cvar_SetValue("mn_stun", 0);
01365 }
01366
01367
01368 if (cl.time < hudTime)
01369 UI_RegisterText(TEXT_STANDARD, hudText);
01370 }
01371
01378 static void HUD_ActorSelectionChangeListener (const char *cvarName, const char *oldValue, const char *newValue)
01379 {
01380 if (!CL_OnBattlescape())
01381 return;
01382
01383 if (newValue[0] != '\0') {
01384 const int actorIdx = atoi(newValue);
01385 const size_t size = lengthof(cl.teamList);
01386 if (actorIdx >= 0 && actorIdx < size)
01387 UI_ExecuteConfunc("hudselect %s", newValue);
01388 }
01389 }
01390
01397 static void HUD_RightHandChangeListener (const char *cvarName, const char *oldValue, const char *newValue)
01398 {
01399 if (!CL_OnBattlescape())
01400 return;
01401
01402 HUD_RefreshButtons(selActor);
01403 }
01404
01411 static void HUD_LeftHandChangeListener (const char *cvarName, const char *oldValue, const char *newValue)
01412 {
01413 if (!CL_OnBattlescape())
01414 return;
01415
01416 HUD_RefreshButtons(selActor);
01417 }
01418
01425 static void HUD_TUChangeListener (const char *cvarName, const char *oldValue, const char *newValue)
01426 {
01427 if (!CL_OnBattlescape())
01428 return;
01429
01430 HUD_RefreshButtons(selActor);
01431 }
01432
01433 static qboolean CL_CvarWorldLevel (cvar_t *cvar)
01434 {
01435 const int maxLevel = cl.mapMaxLevel ? cl.mapMaxLevel - 1 : PATHFINDING_HEIGHT - 1;
01436 return Cvar_AssertValue(cvar, 0, maxLevel, qtrue);
01437 }
01438
01439 void HUD_InitStartup (void)
01440 {
01441 HUD_InitCallbacks();
01442
01443 Cmd_AddCommand("hud_remainingtus", HUD_RemainingTUs_f, "Define if remaining TUs should be displayed in the TU-bar for some hovered-over button.");
01444 Cmd_AddCommand("hud_shotreserve", HUD_ShotReserve_f, "Reserve The TUs for the selected entry in the popup.");
01445 Cmd_AddCommand("hud_shotreservationpopup", HUD_PopupFiremodeReservation_f, "Pop up a list of possible firemodes for reservation in the current turn.");
01446 Cmd_AddCommand("hud_switchfiremodelist", HUD_SwitchFiremodeList_f, "Switch firemode-list to one for the given hand, but only if the list is visible already.");
01447 Cmd_AddCommand("hud_selectreactionfiremode", HUD_SelectReactionFiremode_f, "Change/Select firemode used for reaction fire.");
01448 Cmd_AddCommand("hud_listfiremodes", HUD_DisplayFiremodes_f, "Display a list of firemodes for a weapon+ammo.");
01449 Cmd_AddCommand("hud_getactorcvar", HUD_ActorGetCvarData_f, _("Update cvars from actor from list"));
01450
01451 cl_worldlevel = Cvar_Get("cl_worldlevel", "0", 0, "Current worldlevel in tactical mode");
01452 Cvar_SetCheckFunction("cl_worldlevel", CL_CvarWorldLevel);
01453 cl_worldlevel->modified = qfalse;
01454
01455 Cvar_Get("mn_ammoleft", "", 0, "The remaining amount of ammunition in for the left hand weapon");
01456 Cvar_Get("mn_lweapon", "", 0, "The left hand weapon model of the current selected actor - empty if no weapon");
01457 Cvar_RegisterChangeListener("mn_ammoleft", HUD_LeftHandChangeListener);
01458 Cvar_RegisterChangeListener("mn_lweapon", HUD_LeftHandChangeListener);
01459
01460 Cvar_Get("mn_ammoright", "", 0, "The remaining amount of ammunition in for the right hand weapon");
01461 Cvar_Get("mn_rweapon", "", 0, "The right hand weapon model of the current selected actor - empty if no weapon");
01462 Cvar_RegisterChangeListener("mn_ammoright", HUD_RightHandChangeListener);
01463 Cvar_RegisterChangeListener("mn_rweapon", HUD_RightHandChangeListener);
01464
01465 Cvar_Get("mn_turemain", "", 0, "Remaining TUs for the current selected actor");
01466 Cvar_RegisterChangeListener("mn_turemain", HUD_TUChangeListener);
01467
01468 Cvar_RegisterChangeListener("cl_selected", HUD_ActorSelectionChangeListener);
01469
01470 cl_hud_message_timeout = Cvar_Get("cl_hud_message_timeout", "2000", CVAR_ARCHIVE, "Timeout for HUD messages (milliseconds)");
01471 cl_show_cursor_tooltips = Cvar_Get("cl_show_cursor_tooltips", "1", CVAR_ARCHIVE, "Show cursor tooltips in tactical game mode");
01472 }