diff --git a/source/core/entercheat.cpp b/source/core/entercheat.cpp index a9287d8bb..d45f8694a 100644 --- a/source/core/entercheat.cpp +++ b/source/core/entercheat.cpp @@ -85,8 +85,6 @@ static bool CheatCheckList (event_t *ev) if (ev->type == EV_KeyDown) { - int i; - for (auto &cht :cheats) { if (CheatAddKey (&cht, (uint8_t)ev->data2, &eat)) diff --git a/source/games/duke/CMakeLists.txt b/source/games/duke/CMakeLists.txt index e8eee42aa..4f5c84fda 100644 --- a/source/games/duke/CMakeLists.txt +++ b/source/games/duke/CMakeLists.txt @@ -11,6 +11,7 @@ set( PCH_SOURCES src/gamedef.cpp src/gameexec.cpp src/gamevar.cpp + src/input.cpp src/player.cpp src/player_d.cpp src/player_r.cpp diff --git a/source/games/duke/src/dispatch.cpp b/source/games/duke/src/dispatch.cpp index 350f7ef03..4ba08001a 100644 --- a/source/games/duke/src/dispatch.cpp +++ b/source/games/duke/src/dispatch.cpp @@ -97,6 +97,8 @@ void incur_damage_d(struct player_struct* p); void incur_damage_r(struct player_struct* p); void shoot_d(int i, int atwith); void shoot_r(int i, int atwith); +void selectweapon_d(int snum, int j); +void selectweapon_r(int snum, int j); Dispatcher fi; @@ -140,7 +142,8 @@ void SetDispatcher() check_fta_sounds_d, incur_damage_d, - shoot_d + shoot_d, + selectweapon_d, }; } else @@ -180,7 +183,8 @@ void SetDispatcher() check_fta_sounds_r, incur_damage_r, - shoot_r + shoot_r, + selectweapon_r }; } } diff --git a/source/games/duke/src/duke3d_ed.h b/source/games/duke/src/duke3d_ed.h index 05ec40488..23605450c 100644 --- a/source/games/duke/src/duke3d_ed.h +++ b/source/games/duke/src/duke3d_ed.h @@ -153,45 +153,45 @@ enum GameFunction_t gamefunc_Strafe_Right, gamefunc_Aim_Up, gamefunc_Aim_Down, - gamefunc_Weapon_1, - gamefunc_Weapon_2, - gamefunc_Weapon_3, - gamefunc_Weapon_4, - gamefunc_Weapon_5, - gamefunc_Weapon_6, - gamefunc_Weapon_7, - gamefunc_Weapon_8, - gamefunc_Weapon_9, - gamefunc_Weapon_10, - gamefunc_Inventory, - gamefunc_Inventory_Left, - gamefunc_Inventory_Right, - gamefunc_Holo_Duke, // Duke3D, RR - gamefunc_Jetpack, - gamefunc_NightVision, - gamefunc_MedKit, + gamefunc_Weapon_1, // CCMD + gamefunc_Weapon_2, // CCMD + gamefunc_Weapon_3, // CCMD + gamefunc_Weapon_4, // CCMD + gamefunc_Weapon_5, // CCMD + gamefunc_Weapon_6, // CCMD + gamefunc_Weapon_7, // CCMD + gamefunc_Weapon_8, // CCMD + gamefunc_Weapon_9, // CCMD + gamefunc_Weapon_10, // CCMD + gamefunc_Inventory, // CCMD + gamefunc_Inventory_Left, // CCMD + gamefunc_Inventory_Right, // CCMD + gamefunc_Holo_Duke, // CCMD // Duke3D, RR + gamefunc_Jetpack, // CCMD + gamefunc_NightVision, // CCMD + gamefunc_MedKit, // CCMD gamefunc_TurnAround, gamefunc_SendMessage, - gamefunc_Map, - gamefunc_Shrink_Screen, - gamefunc_Enlarge_Screen, - gamefunc_Center_View, - gamefunc_Holster_Weapon, - gamefunc_Show_Opponents_Weapon, - gamefunc_Map_Follow_Mode, - gamefunc_See_Coop_View, - gamefunc_Mouse_Aiming, - gamefunc_Toggle_Crosshair, - gamefunc_Steroids, - gamefunc_Quick_Kick, - gamefunc_Next_Weapon, - gamefunc_Previous_Weapon, + gamefunc_Map, // CCMD + gamefunc_Shrink_Screen, // CCMD + gamefunc_Enlarge_Screen, // CCMD + gamefunc_Center_View, // CCMD + gamefunc_Holster_Weapon, // CCMD + gamefunc_Show_Opponents_Weapon, // CCMD + gamefunc_Map_Follow_Mode, // CCMD + gamefunc_See_Coop_View, // CCMD + gamefunc_Mouse_Aiming, // CCMD + gamefunc_Toggle_Crosshair, // CCMD + gamefunc_Steroids, // CCMD + gamefunc_Quick_Kick, // CCMD + gamefunc_Next_Weapon, // CCMD + gamefunc_Previous_Weapon, // CCMD gamefunc_Dpad_Select, gamefunc_Dpad_Aiming, - gamefunc_Last_Weapon, + gamefunc_Last_Weapon, // CCMD gamefunc_Alt_Weapon, - gamefunc_Third_Person_View, - gamefunc_Show_DukeMatch_Scores, + gamefunc_Third_Person_View, // CCMD + gamefunc_Show_DukeMatch_Scores, // CCMD gamefunc_Toggle_Crouch, // This is the last one used by EDuke32. NUM_ACTIONS }; diff --git a/source/games/duke/src/game.h b/source/games/duke/src/game.h index 7431b5675..7d6f51e7e 100644 --- a/source/games/duke/src/game.h +++ b/source/games/duke/src/game.h @@ -476,6 +476,7 @@ static inline int G_GetMusicIdx(const char *str) extern void G_PrintCurrentMusic(void); void addspritetodelete(int spnum); +void checkavailinven(struct player_struct* p); int initspriteforspawn(int j, int pn, const std::initializer_list &excludes); void spawninitdefault(int j, int i); @@ -527,6 +528,8 @@ struct Dispatcher // player void (*incur_damage)(struct player_struct* p); void (*shoot)(int, int); + void (*selectweapon)(int snum, int j); + }; diff --git a/source/games/duke/src/global.h b/source/games/duke/src/global.h index b6294da13..2e5db81e9 100644 --- a/source/games/duke/src/global.h +++ b/source/games/duke/src/global.h @@ -381,6 +381,16 @@ inline bool PlayerInput(int pl, int bit) return TEST_SYNC_KEY(g_player[pl].input->bits, bit); } +inline void PlayerSetInput(int pl, int bit) +{ + g_player[pl].input->bits |= (1 << bit); +} + +inline int PlayerInputBits(int pl, int bits) +{ + return (g_player[pl].input->bits & bits); +} + inline bool PlayerInputSideVel(int pl) { return g_player[pl].input->svel; diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 2bac03601..3cc25206c 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -34,11 +34,467 @@ source as it is released. #include "ns.h" #include "global.h" +#include "game.h" BEGIN_DUKE_NS //--------------------------------------------------------------------------- // -// +// handles all HUD related input, i.e. inventory item selection and activation plus weapon selection. +// +// Note: This doesn't restrict the events to WW2GI - since the other games do +// not define any by default there is no harm done keeping the code clean. // //--------------------------------------------------------------------------- + +void hud_input(int snum) +{ + int i, k; + uint8_t dainv; + unsigned int j; + struct player_struct* p; + short unk; + + unk = 0; + p = &ps[snum]; + + Printf("Sync bits are %08x for %d\n", g_player[snum].input->bits, snum); + + i = p->aim_mode; + p->aim_mode = PlayerInput(snum, SK_AIMMODE); + if (p->aim_mode < i) + p->return_to_center = 9; + + if (isRR()) + { + if (PlayerInput(snum, SK_QUICK_KICK) && p->last_pissed_time == 0) + { + if (!isRRRA() || sprite[p->i].extra > 0) + { + p->last_pissed_time = 4000; + if (!ud.lockout) + spritesound(437, p->i); + if (sprite[p->i].extra <= max_player_health - max_player_health / 10) + { + sprite[p->i].extra += 2; + p->last_extra = sprite[p->i].extra; + } + else if (sprite[p->i].extra < max_player_health) + sprite[p->i].extra = max_player_health; + } + } + } + else + { + if (PlayerInput(snum, SK_QUICK_KICK) && p->quick_kick == 0 && (p->curr_weapon != KNEE_WEAPON || p->kickback_pic == 0)) + { + SetGameVarID(g_iReturnVarID, 0, -1, snum); + OnEvent(EVENT_QUICKKICK, -1, snum, -1); + if (GetGameVarID(g_iReturnVarID, -1, snum) == 0) + { + p->quick_kick = 14; + FTA(QUOTE_MIGHTY_FOOT, p); + } + } + } + + // WTF??? In the original source this was a soup of numeric literals, i.e. totally incomprehensible. + // The bit mask has been exported to the bit type enum. + if (!PlayerInputBits(snum, SK_INTERFACE_BITS)) + p->interface_toggle_flag = 0; + else if (p->interface_toggle_flag == 0) + { + p->interface_toggle_flag = 1; + + if (PlayerInput(snum, SK_PAUSE)) + { + ud.pause_on = !ud.pause_on; + if (ud.pause_on == 1 && PlayerInput(snum, SK_RUN)) ud.pause_on = 2; // Mode 2 is silent, i.e. prints no notification. + Mus_SetPaused(ud.pause_on); + S_PauseSounds(ud.pause_on); + } + } + // Don't go on if paused or dead. + if (ud.pause_on) return; + if (sprite[p->i].extra <= 0) return; + + // Activate an inventory item. This just forwards to the other inventory bits. If the inventory selector was taken out of the playsim this could be removed. + if (PlayerInput(snum, SK_INVENTORY) && p->newowner == -1) + { + SetGameVarID(g_iReturnVarID, 0, -1, snum); + OnEvent(EVENT_INVENTORY, -1, snum, -1); + if (GetGameVarID(g_iReturnVarID, -1, snum) == 0) + { + switch (p->inven_icon) + { + // Yet another place where no symbolic constants were used. :( + case ICON_JETPACK: PlayerSetInput(snum, SK_JETPACK); break; + case ICON_HOLODUKE: PlayerSetInput(snum, SK_HOLODUKE); break; + case ICON_HEATS: PlayerSetInput(snum, SK_NIGHTVISION); break; + case ICON_FIRSTAID: PlayerSetInput(snum, SK_MEDKIT); break; + case ICON_STEROIDS: PlayerSetInput(snum, SK_STEROIDS); break; + } + } + } + + if (!isRR() && PlayerInput(snum, SK_NIGHTVISION)) + { + SetGameVarID(g_iReturnVarID, 0, -1, snum); + OnEvent(EVENT_USENIGHTVISION, -1, snum, -1); + if (GetGameVarID(g_iReturnVarID, -1, snum) == 0 && p->heat_amount > 0) + { + p->heat_on = !p->heat_on; + setpal(p); + p->inven_icon = 5; + spritesound(NITEVISION_ONOFF, p->i); + FTA(106 + (!p->heat_on), p); + } + } + + if (PlayerInput(snum, SK_STEROIDS)) + { + SetGameVarID(g_iReturnVarID, 0, -1, snum); + OnEvent(EVENT_USESTEROIDS, -1, snum, -1); + if (GetGameVarID(g_iReturnVarID, -1, snum) == 0) + { + if (p->steroids_amount == 400) + { + p->steroids_amount--; + spritesound(DUKE_TAKEPILLS, p->i); + p->inven_icon = ICON_STEROIDS; + FTA(12, p); + } + } + return; + } + + if (PlayerInput(snum, SK_INV_LEFT) || PlayerInput(snum, SK_INV_RIGHT)) + { + p->invdisptime = 26 * 2; + + if (PlayerInput(snum, SK_INV_RIGHT)) k = 1; + else k = 0; + + dainv = p->inven_icon; + + i = 0; + CHECKINV1: + + if (i < 9) + { + i++; + + switch (dainv) + { + case 4: + if (p->jetpack_amount > 0 && i > 1) + break; + if (k) dainv = 5; + else dainv = 3; + goto CHECKINV1; + case 6: + if (p->scuba_amount > 0 && i > 1) + break; + if (k) dainv = 7; + else dainv = 5; + goto CHECKINV1; + case 2: + if (p->steroids_amount > 0 && i > 1) + break; + if (k) dainv = 3; + else dainv = 1; + goto CHECKINV1; + case 3: + if (p->holoduke_amount > 0 && i > 1) + break; + if (k) dainv = 4; + else dainv = 2; + goto CHECKINV1; + case 0: + case 1: + if (p->firstaid_amount > 0 && i > 1) + break; + if (k) dainv = 2; + else dainv = 7; + goto CHECKINV1; + case 5: + if (p->heat_amount > 0 && i > 1) + break; + if (k) dainv = 6; + else dainv = 4; + goto CHECKINV1; + case 7: + if (p->boot_amount > 0 && i > 1) + break; + if (k) dainv = 1; + else dainv = 6; + goto CHECKINV1; + } + } + else dainv = 0; + + // These events force us to keep the inventory selector in the playsim as opposed to the UI where it really belongs. + if (PlayerInput(snum, SK_INV_LEFT)) + { + SetGameVarID(g_iReturnVarID, dainv, -1, snum); + OnEvent(EVENT_INVENTORYLEFT, -1, snum, -1); + dainv = GetGameVarID(g_iReturnVarID, -1, snum); + } + if (PlayerInput(snum, SK_INV_RIGHT)) + { + SetGameVarID(g_iReturnVarID, dainv, -1, snum); + OnEvent(EVENT_INVENTORYRIGHT, -1, snum, -1); + dainv = GetGameVarID(g_iReturnVarID, -1, snum); + } + p->inven_icon = dainv; + // Someone must have really hated constant data, doing this with a switch/case (and of course also with literal numbers...) + static const uint8_t invquotes[] = { QUOTE_MEDKIT, QUOTE_STEROIDS, QUOTE_HOLODUKE, QUOTE_JETPACK, QUOTE_NVG, QUOTE_SCUBA, QUOTE_BOOTS }; + if (dainv >= 1 && dainv < 8) FTA(invquotes[dainv - 1], p); + + j = (PlayerInputBits(snum, SK_WEAPONMASK_BITS) >> SK_WEAPON_BITS) - 1; + if (j > 0 && p->kickback_pic > 0) + p->wantweaponfire = j; + + // Here we have to be extra careful that the weapons do not get mixed up, so let's keep the code for Duke and RR completely separate. + fi.selectweapon(snum, j); + + if (PlayerInput(snum, SK_HOLSTER)) + { + if (p->curr_weapon > KNEE_WEAPON) + { + if (p->holster_weapon == 0 && p->weapon_pos == 0) + { + p->holster_weapon = 1; + p->weapon_pos = -1; + FTA(QUOTE_WEAPON_LOWERED, p); + } + else if (p->holster_weapon == 1 && p->weapon_pos == -9) + { + p->holster_weapon = 0; + p->weapon_pos = 10; + FTA(QUOTE_WEAPON_RAISED, p); + } + } + } + } + + if (PlayerInput(snum, SK_HOLODUKE) && (isRR() || p->newowner == -1)) + { + SetGameVarID(g_iReturnVarID, 0, -1, snum); + OnEvent(EVENT_HOLODUKEON, -1, snum, -1); + if (GetGameVarID(g_iReturnVarID, -1, snum) == 0) + { + if (!isRR()) + { + if (p->holoduke_on == -1) + { + if (p->holoduke_amount > 0) + { + p->inven_icon = 3; + + p->holoduke_on = i = + EGS(p->cursectnum, + p->posx, + p->posy, + p->posz + (30 << 8), TILE_APLAYER, -64, 0, 0, p->getang(), 0, 0, -1, 10); + hittype[i].temp_data[3] = hittype[i].temp_data[4] = 0; + sprite[i].yvel = snum; + sprite[i].extra = 0; + FTA(47, p); + } + else FTA(QUOTE_HOLODUKE_ON, p); + spritesound(TELEPORTER, p->holoduke_on); + + } + else + { + spritesound(TELEPORTER, p->holoduke_on); + p->holoduke_on = -1; + FTA(QUOTE_HOLODUKE_NOT_FOUND, p); + } + } + else // In RR this means drinking whiskey. + { + if (p->holoduke_amount > 0 && sprite[p->i].extra < max_player_health) + { + p->holoduke_amount -= 400; + sprite[p->i].extra += 5; + if (sprite[p->i].extra > max_player_health) + sprite[p->i].extra = max_player_health; + + p->drink_amt += 5; + p->inven_icon = 3; + if (p->holoduke_amount == 0) + checkavailinven(p); + + if (p->drink_amt < 99 && !A_CheckSoundPlaying(p->i, 425)) + spritesound(425, p->i); + } + } + } + } + + if (isRR() && PlayerInput(snum, SK_NIGHTVISION) && p->newowner == -1) + { + SetGameVarID(g_iReturnVarID, 0, -1, snum); + OnEvent(EVENT_USENIGHTVISION, -1, snum, -1); + if (GetGameVarID(g_iReturnVarID, -1, snum) == 0) + { + if (p->yehaa_timer == 0) + { + p->yehaa_timer = 126; + spritesound(390, p->i); + p->noise_radius = 16384; + madenoise(snum); + if (sector[p->cursectnum].lotag == 857) + { + if (sprite[p->i].extra <= max_player_health) + { + sprite[p->i].extra += 10; + if (sprite[p->i].extra >= max_player_health) + sprite[p->i].extra = max_player_health; + } + } + else + { + if (sprite[p->i].extra + 1 <= max_player_health) + { + sprite[p->i].extra++; + } + } + } + } + } + + if (PlayerInput(snum, SK_MEDKIT)) + { + SetGameVarID(g_iReturnVarID, 0, -1, snum); + OnEvent(EVENT_USEMEDKIT, -1, snum, -1); + if (GetGameVarID(g_iReturnVarID, -1, snum) == 0) + { + if (p->firstaid_amount > 0 && sprite[p->i].extra < max_player_health) + { + if (!isRR()) + { + j = max_player_health - sprite[p->i].extra; + + if ((unsigned int)p->firstaid_amount > j) + { + p->firstaid_amount -= j; + sprite[p->i].extra = max_player_health; + p->inven_icon = 1; + } + else + { + sprite[p->i].extra += p->firstaid_amount; + p->firstaid_amount = 0; + checkavailinven(p); + } + spritesound(DUKE_USEMEDKIT, p->i); + } + else + { + j = 10; + if (p->firstaid_amount > j) + { + p->firstaid_amount -= j; + sprite[p->i].extra += j; + if (sprite[p->i].extra > max_player_health) + sprite[p->i].extra = max_player_health; + p->inven_icon = 1; + } + else + { + sprite[p->i].extra += p->firstaid_amount; + p->firstaid_amount = 0; + checkavailinven(p); + } + if (sprite[p->i].extra > max_player_health) + sprite[p->i].extra = max_player_health; + p->drink_amt += 10; + if (p->drink_amt <= 100 && !A_CheckSoundPlaying(p->i, DUKE_USEMEDKIT)) + spritesound(DUKE_USEMEDKIT, p->i); + } + } + } + } + + if (PlayerInput(snum, SK_JETPACK) && (isRR() || p->newowner == -1)) + { + SetGameVarID(g_iReturnVarID, 0, -1, snum); + OnEvent(EVENT_USEJETPACK, -1, snum, -1); + if (GetGameVarID(g_iReturnVarID, -1, snum) == 0) + { + if (!isRR()) + { + if (p->jetpack_amount > 0) + { + p->jetpack_on = !p->jetpack_on; + if (p->jetpack_on) + { + p->inven_icon = 4; + + S_StopEnvSound(-1, p->i, CHAN_VOICE); // this will stop the falling scream + A_PlaySound(DUKE_JETPACK_ON, p->i); + FTA(QUOTE_JETPACK_ON, p); + } + else + { + p->hard_landing = 0; + p->poszv = 0; + spritesound(DUKE_JETPACK_OFF, p->i); + S_StopEnvSound(DUKE_JETPACK_IDLE, p->i); + S_StopEnvSound(DUKE_JETPACK_ON, p->i); + FTA(QUOTE_JETPACK_OFF, p); + } + } + else FTA(QUOTE_JETPACK_NOT_FOUND, p); + } + else + { + // eat cow pie + if (p->jetpack_amount > 0 && sprite[p->i].extra < max_player_health) + { + if (!A_CheckSoundPlaying(p->i, 429)) + A_PlaySound(429, p->i); + + p->jetpack_amount -= 100; + if (p->drink_amt > 0) + { + p->drink_amt -= 5; + if (p->drink_amt < 0) + p->drink_amt = 0; + } + + if (p->eat < 100) + { + p->eat += 5; + if (p->eat > 100) + p->eat = 100; + } + + sprite[p->i].extra += 5; + + p->inven_icon = 4; + + if (sprite[p->i].extra > max_player_health) + sprite[p->i].extra = max_player_health; + + if (p->jetpack_amount <= 0) + checkavailinven(p); + } + } + } + } + + if (PlayerInput(snum, SK_TURNAROUND) && p->one_eighty_count == 0) + { + SetGameVarID(g_iReturnVarID, 0, -1, snum); + OnEvent(EVENT_TURNAROUND, -1, snum, -1); + if (GetGameVarID(g_iReturnVarID, -1, snum) == 0) + { + p->one_eighty_count = -1024; + } + } +} +END_DUKE_NS diff --git a/source/games/duke/src/macros.h b/source/games/duke/src/macros.h index 7be9786fd..7f3593883 100644 --- a/source/games/duke/src/macros.h +++ b/source/games/duke/src/macros.h @@ -72,40 +72,49 @@ inline bool AFLAMABLE(int X) // NETWORK - REDEFINABLE SHARED (SYNC) KEYS BIT POSITIONS // -#define SK_JUMP 0 -#define SK_CROUCH 1 -#define SK_FIRE 2 -#define SK_AIM_UP 3 -#define SK_AIM_DOWN 4 -#define SK_RUN 5 -#define SK_LOOK_LEFT 6 -#define SK_LOOK_RIGHT 7 -// weapons take up 4 bits... -#define SK_WEAPON_BITS 8 -#define SK_WEAPON_BITS1 9 -#define SK_WEAPON_BITS2 10 -#define SK_WEAPON_BITS3 11 -#define SK_STEROIDS 12 -#define SK_LOOK_UP 13 -#define SK_LOOK_DOWN 14 -#define SK_NIGHTVISION 15 -#define SK_MEDKIT 16 -#define SK_MULTIFLAG 17 -#define SK_CENTER_VIEW 18 -#define SK_HOLSTER 19 -#define SK_INV_LEFT 20 -#define SK_PAUSE 21 -#define SK_QUICK_KICK 22 -#define SK_AIMMODE 23 -#define SK_HOLODUKE 24 -#define SK_JETPACK 25 -#define SK_GAMEQUIT 26 -#define SK_INV_RIGHT 27 -#define SK_TURNAROUND 28 -#define SK_OPEN 29 -#define SK_INVENTORY 30 -#define SK_ESCAPE 31 +enum +{ + // Todo: Make this bit masks - cannot be done before eliminating all old code using it + SK_JUMP = 0 , + SK_CROUCH = 1 , + SK_FIRE = 2 , + SK_AIM_UP = 3 , + SK_AIM_DOWN = 4 , + SK_RUN = 5 , + SK_LOOK_LEFT = 6 , + SK_LOOK_RIGHT = 7 , + // weapons take up 4 bits... + SK_WEAPON_BITS = 8 , + SK_WEAPON_BITS1 = 9 , + SK_WEAPON_BITS2 = 10, + SK_WEAPON_BITS3 = 11, + SK_STEROIDS = 12, + SK_LOOK_UP = 13, + SK_LOOK_DOWN = 14, + SK_NIGHTVISION = 15, + SK_MEDKIT = 16, + SK_MULTIFLAG = 17, + SK_CENTER_VIEW = 18, + SK_HOLSTER = 19, + SK_INV_LEFT = 20, + SK_PAUSE = 21, + SK_QUICK_KICK = 22, + SK_AIMMODE = 23, + SK_HOLODUKE = 24, + SK_JETPACK = 25, + SK_GAMEQUIT = 26, + SK_INV_RIGHT = 27, + SK_TURNAROUND = 28, + SK_OPEN = 29, + SK_INVENTORY = 30, + SK_ESCAPE = 31, + SK_WEAPONMASK_BITS = (15u << SK_WEAPON_BITS), + SK_INTERFACE_BITS = (SK_WEAPONMASK_BITS | BIT(SK_STEROIDS) | BIT(SK_NIGHTVISION) | BIT(SK_MEDKIT) | BIT(SK_QUICK_KICK) | \ + BIT(SK_HOLSTER) | BIT(SK_INV_LEFT) | BIT(SK_PAUSE) | BIT(SK_HOLODUKE) | BIT(SK_JETPACK) | BIT(SK_INV_RIGHT) | \ + BIT(SK_TURNAROUND) | BIT(SK_OPEN) | BIT(SK_INVENTORY) | BIT(SK_ESCAPE)), + +}; // rotatesprite flags #define ROTATE_SPRITE_TRANSLUCENT (BIT(0)) #define ROTATE_SPRITE_VIEW_CLIP (BIT(1)) // clip to view diff --git a/source/games/duke/src/namesdyn.h b/source/games/duke/src/namesdyn.h index 7304afb90..6709bc302 100644 --- a/source/games/duke/src/namesdyn.h +++ b/source/games/duke/src/namesdyn.h @@ -3596,8 +3596,8 @@ enum redneck_weapon_t // These names have been pieced together from RedneckGDX and RedNukem because the reconstructed source recycled Duke's names for the first 11 weapons. // Names for 0-2 are the same RIFLEGUN_WEAPON = 3, - DYNAMITE_WEAPON = 5, - CROSSBOW_WEAPON = 4, + DYNAMITE_WEAPON = 4, + CROSSBOW_WEAPON = 5, THROWSAW_WEAPON = 6, ALIENBLASTER_WEAPON = 7, POWDERKEG_WEAPON = 8, diff --git a/source/games/duke/src/player.h b/source/games/duke/src/player.h index 5f2337b9e..4411af458 100644 --- a/source/games/duke/src/player.h +++ b/source/games/duke/src/player.h @@ -413,7 +413,7 @@ int P_GetHudPal(const DukePlayer_t *pPlayer); int P_GetKneePal(const DukePlayer_t *pPlayer); int P_GetKneePal(const DukePlayer_t *pPlayer, int hudPal); int P_GetOverheadPal(const DukePlayer_t *pPlayer); -void P_MadeNoise(int playerNum); +void madenoise(int playerNum); int P_HasKey(int sectNum, int playerNum); #define haskey P_HasKey diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index a419c2f55..cacf2aeb6 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -1091,5 +1091,214 @@ void shoot_d(int i, int atwith) return; } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void selectweapon_d(int snum, int j) // playernum, weaponnum +{ + int i, k; + auto p = &ps[snum]; + if (p->last_pissed_time <= (26 * 218) && p->show_empty_weapon == 0 && p->kickback_pic == 0 && p->quick_kick == 0 && sprite[p->i].xrepeat > 32 && p->access_incs == 0 && p->knee_incs == 0) + { + if ((p->weapon_pos == 0 || (p->holster_weapon && p->weapon_pos == -9))) + { + if (j == 10 || j == 11) + { + k = p->curr_weapon; + j = (j == 10 ? -1 : 1); // JBF: prev (-1) or next (1) weapon choice + i = 0; + + while ((k >= 0 && k < 10) || (PLUTOPAK && k == GROW_WEAPON && (p->subweapon & (1 << GROW_WEAPON)))) // JBF 20040116: so we don't select grower with v1.3d + { + if (k == GROW_WEAPON) // JBF: this is handling next/previous with the grower selected + { + if (j == (unsigned int)-1) + k = 5; + else k = 7; + + } + else + { + k += j; + if (PLUTOPAK) // JBF 20040116: so we don't select grower with v1.3d + if (k == SHRINKER_WEAPON && (p->subweapon & (1 << GROW_WEAPON))) // JBF: activates grower + k = GROW_WEAPON; // if enabled + } + + if (k == -1) k = 9; + else if (k == 10) k = 0; + + if (p->gotweapon[k] && p->ammo_amount[k] > 0) + { + if (PLUTOPAK) // JBF 20040116: so we don't select grower with v1.3d + if (k == SHRINKER_WEAPON && (p->subweapon & (1 << GROW_WEAPON))) + k = GROW_WEAPON; + j = k; + break; + } + else // JBF: grower with no ammo, but shrinker with ammo, switch to shrink + if (PLUTOPAK && k == GROW_WEAPON && p->ammo_amount[GROW_WEAPON] == 0 && p->gotweapon[SHRINKER_WEAPON] && p->ammo_amount[SHRINKER_WEAPON] > 0) // JBF 20040116: added PLUTOPAK so we don't select grower with v1.3d + { + j = SHRINKER_WEAPON; + p->subweapon &= ~(1 << GROW_WEAPON); + break; + } + else // JBF: shrinker with no ammo, but grower with ammo, switch to grow + if (PLUTOPAK && k == SHRINKER_WEAPON && p->ammo_amount[SHRINKER_WEAPON] == 0 && p->gotweapon[SHRINKER_WEAPON] && p->ammo_amount[GROW_WEAPON] > 0) // JBF 20040116: added PLUTOPAK so we don't select grower with v1.3d + { + j = GROW_WEAPON; + p->subweapon |= (1 << GROW_WEAPON); + break; + } + + i++; // absolutely no weapons, so use foot + if (i == 10) + { + fi.addweapon(p, KNEE_WEAPON); + break; + } + } + } + + k = -1; + + + if (j == HANDBOMB_WEAPON && p->ammo_amount[HANDBOMB_WEAPON] == 0) + { + k = headspritestat[1]; + while (k >= 0) + { + if (sprite[k].picnum == HEAVYHBOMB && sprite[k].owner == p->i) + { + p->gotweapon.Set(HANDBOMB_WEAPON); + j = HANDREMOTE_WEAPON; + break; + } + k = nextspritestat[k]; + } + } + + if (j == SHRINKER_WEAPON && PLUTOPAK) // JBF 20040116: so we don't select the grower with v1.3d + { + if (screenpeek == snum) pus = NUMPAGES; + + if (p->curr_weapon != GROW_WEAPON && p->curr_weapon != SHRINKER_WEAPON) + { + if (p->ammo_amount[GROW_WEAPON] > 0) + { + if ((p->subweapon & (1 << GROW_WEAPON)) == (1 << GROW_WEAPON)) + j = GROW_WEAPON; + else if (p->ammo_amount[SHRINKER_WEAPON] == 0) + { + j = GROW_WEAPON; + p->subweapon |= (1 << GROW_WEAPON); + } + } + else if (p->ammo_amount[SHRINKER_WEAPON] > 0) + p->subweapon &= ~(1 << GROW_WEAPON); + } + else if (p->curr_weapon == SHRINKER_WEAPON) + { + p->subweapon |= (1 << GROW_WEAPON); + j = GROW_WEAPON; + } + else + p->subweapon &= ~(1 << GROW_WEAPON); + } + + if (p->holster_weapon) + { + PlayerSetInput(snum, SK_HOLSTER); + p->weapon_pos = -9; + } + else if (j >= MIN_WEAPON && p->gotweapon[j] && (unsigned int)p->curr_weapon != j) switch (j) + { + case KNEE_WEAPON: + fi.addweapon(p, KNEE_WEAPON); + break; + case PISTOL_WEAPON: + if (p->ammo_amount[PISTOL_WEAPON] == 0) + if (p->show_empty_weapon == 0) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + fi.addweapon(p, PISTOL_WEAPON); + break; + case SHOTGUN_WEAPON: + if (p->ammo_amount[SHOTGUN_WEAPON] == 0 && p->show_empty_weapon == 0) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + fi.addweapon(p, SHOTGUN_WEAPON); + break; + case CHAINGUN_WEAPON: + if (p->ammo_amount[CHAINGUN_WEAPON] == 0 && p->show_empty_weapon == 0) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + fi.addweapon(p, CHAINGUN_WEAPON); + break; + case RPG_WEAPON: + if (p->ammo_amount[RPG_WEAPON] == 0) + if (p->show_empty_weapon == 0) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + fi.addweapon(p, RPG_WEAPON); + break; + case DEVISTATOR_WEAPON: + if (p->ammo_amount[DEVISTATOR_WEAPON] == 0 && p->show_empty_weapon == 0) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + fi.addweapon(p, DEVISTATOR_WEAPON); + break; + case FREEZE_WEAPON: + if (p->ammo_amount[FREEZE_WEAPON] == 0 && p->show_empty_weapon == 0) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + fi.addweapon(p, FREEZE_WEAPON); + break; + case GROW_WEAPON: + case SHRINKER_WEAPON: + + if (p->ammo_amount[j] == 0 && p->show_empty_weapon == 0) + { + p->show_empty_weapon = 32; + p->last_full_weapon = p->curr_weapon; + } + + fi.addweapon(p, j); + break; + case HANDREMOTE_WEAPON: + if (k >= 0) // Found in list of [1]'s + { + p->curr_weapon = HANDREMOTE_WEAPON; + p->last_weapon = -1; + p->weapon_pos = 10; + } + break; + case HANDBOMB_WEAPON: + if (p->ammo_amount[HANDBOMB_WEAPON] > 0 && p->gotweapon[HANDBOMB_WEAPON]) + fi.addweapon(p, HANDBOMB_WEAPON); + break; + case TRIPBOMB_WEAPON: + if (p->ammo_amount[TRIPBOMB_WEAPON] > 0 && p->gotweapon[TRIPBOMB_WEAPON]) + fi.addweapon(p, TRIPBOMB_WEAPON); + break; + } + } + } +} END_DUKE_NS diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 67959f11a..dd15b4d98 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -880,7 +880,7 @@ void shoot_r(int i, int atwith) sprite[j].extra >>= 2; } } - else if (ps[p].curr_weapon == DEVISTATOR_WEAPON) + else if (ps[p].curr_weapon == TIT_WEAPON) { sprite[j].extra >>= 2; sprite[j].ang += 16 - (krand() & 31); @@ -939,5 +939,210 @@ void shoot_r(int i, int atwith) return; } +//--------------------------------------------------------------------------- +// +// this is one lousy hack job... +// +//--------------------------------------------------------------------------- + +void selectweapon_r(int snum, int j) +{ + if (j >= 0) + { + int a = 0; + } + int i, k; + auto p = &ps[snum]; + if (p->last_pissed_time <= (26 * 218) && p->show_empty_weapon == 0 && p->kickback_pic == 0 && p->quick_kick == 0 && sprite[p->i].xrepeat > 8 && p->access_incs == 0 && p->knee_incs == 0) + { + if ((p->weapon_pos == 0 || (p->holster_weapon && p->weapon_pos == -9))) + { + if (j == 10 || j == 11) + { + k = p->curr_weapon; + if (isRRRA()) + { + if (k == CHICKEN_WEAPON) k = CROSSBOW_WEAPON; + else if (k == BUZZSAW_WEAPON) k = THROWSAW_WEAPON; + else if (k == SLINGBLADE_WEAPON) k = KNEE_WEAPON; + } + j = (j == 10 ? -1 : 1); + i = 0; + + while (k >= 0 && k < 10) + { + k += j; + if (k == -1) k = 9; + else if (k == 10) k = 0; + + if (p->gotweapon[k] && p->ammo_amount[k] > 0) + { + j = k; + break; + } + + i++; + if (i == 10) + { + fi.addweapon(p, KNEE_WEAPON); + break; + } + } + } + + k = -1; + + + if (j == DYNAMITE_WEAPON && p->ammo_amount[DYNAMITE_WEAPON] == 0) + { + k = headspritestat[1]; + while (k >= 0) + { + if (sprite[k].picnum == HEAVYHBOMB && sprite[k].owner == p->i) + { + p->gotweapon.Set(DYNAMITE_WEAPON); + j = HANDREMOTE_WEAPON; + break; + } + k = nextspritestat[k]; + } + } + else if (j == KNEE_WEAPON && isRRRA()) + { + if (p->curr_weapon == KNEE_WEAPON) + { + p->subweapon = 2; + j = SLINGBLADE_WEAPON; + } + else if (p->subweapon & 2) + { + p->subweapon = 0; + j = KNEE_WEAPON; + } + } + else if (j == CROSSBOW_WEAPON && isRRRA()) + { + if (screenpeek == snum) pus = NUMPAGES; + + if (p->curr_weapon == CROSSBOW_WEAPON || p->ammo_amount[CROSSBOW_WEAPON] == 0) + { + if (p->ammo_amount[CHICKEN_WEAPON] == 0) + return; + p->subweapon = 4; + j = CHICKEN_WEAPON; + } + else if ((p->subweapon & 4) || p->ammo_amount[CHICKEN_WEAPON] == 0) + { + p->subweapon = 0; + j = CROSSBOW_WEAPON; + } + } + else if (j == THROWSAW_WEAPON) + { + if (screenpeek == snum) pus = NUMPAGES; + + if (p->curr_weapon == THROWSAW_WEAPON || p->ammo_amount[THROWSAW_WEAPON] == 0) + { + p->subweapon = (1 << BUZZSAW_WEAPON); + j = BUZZSAW_WEAPON; + } + else if ((p->subweapon & (1 << BUZZSAW_WEAPON)) || p->ammo_amount[BUZZSAW_WEAPON] == 0) + { + p->subweapon = 0; + j = THROWSAW_WEAPON; + } + } + else if (j == POWDERKEG_WEAPON) + { + if (screenpeek == snum) pus = NUMPAGES; + + if (p->curr_weapon == POWDERKEG_WEAPON || p->ammo_amount[POWDERKEG_WEAPON] == 0) + { + p->subweapon = (1 << BOWLING_WEAPON); + j = BOWLING_WEAPON; + } + else if ((p->subweapon & (1 << BOWLING_WEAPON)) || p->ammo_amount[BOWLING_WEAPON] == 0) + { + p->subweapon = 0; + j = POWDERKEG_WEAPON; + } + } + + + if (p->holster_weapon) + { + PlayerSetInput(snum, SK_HOLSTER); + p->weapon_pos = -9; + } + else if (j >= MIN_WEAPON && p->gotweapon[j] && p->curr_weapon != j) switch (j) + { + case KNEE_WEAPON: + fi.addweapon(p, j); + break; + case SLINGBLADE_WEAPON: + if (isRRRA()) + { + spritesound(496, ps[screenpeek].i); + fi.addweapon(p, j); + } + break; + + case PISTOL_WEAPON: + if (p->ammo_amount[PISTOL_WEAPON] == 0) + if (p->show_empty_weapon == 0) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + fi.addweapon(p, PISTOL_WEAPON); + break; + + case CHICKEN_WEAPON: + if (!isRRRA()) break; + case SHOTGUN_WEAPON: + case RIFLEGUN_WEAPON: + case CROSSBOW_WEAPON: + case TIT_WEAPON: + case ALIENBLASTER_WEAPON: + case THROWSAW_WEAPON: + case BUZZSAW_WEAPON: + case POWDERKEG_WEAPON: + case BOWLING_WEAPON: + if (p->ammo_amount[j] == 0 && p->show_empty_weapon == 0) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + fi.addweapon(p, j); + break; + + case MOTORCYCLE_WEAPON: + case BOAT_WEAPON: + if (isRRRA()) + { + if (p->ammo_amount[j] == 0 && p->show_empty_weapon == 0) + { + p->show_empty_weapon = 32; + } + fi.addweapon(p, j); + } + break; + + case HANDREMOTE_WEAPON: // what's up with this? RR doesn't define this weapon. + if (k >= 0) // Found in list of [1]'s + { + p->curr_weapon = HANDREMOTE_WEAPON; + p->last_weapon = -1; + p->weapon_pos = 10; + } + break; + case DYNAMITE_WEAPON: + if (p->ammo_amount[DYNAMITE_WEAPON] > 0 && p->gotweapon[DYNAMITE_WEAPON]) + fi.addweapon(p, DYNAMITE_WEAPON); + break; + } + } + } +} END_DUKE_NS diff --git a/source/games/duke/src/sector.h b/source/games/duke/src/sector.h index 0f199c293..cc679eb31 100644 --- a/source/games/duke/src/sector.h +++ b/source/games/duke/src/sector.h @@ -64,7 +64,7 @@ void operateactivators(int l, int w); void operateforcefields_common(int s, int low, const std::initializer_list& tiles); void operatemasterswitches(int lotag); void operatesectors(int s, int i); -void P_HandleSharedKeys(int playerNum); +void hud_input(int playerNum); int getanimationgoal(const int32_t* animPtr); bool isanearoperator(int lotag); bool isanunderoperator(int lotag); diff --git a/source/games/duke/src/zz_game.cpp b/source/games/duke/src/zz_game.cpp index 5a99aa5a9..fd4844592 100644 --- a/source/games/duke/src/zz_game.cpp +++ b/source/games/duke/src/zz_game.cpp @@ -4394,7 +4394,7 @@ int G_DoMoveThings(void) sprite[g_player[i].ps->i].pal = g_player[i].pcolor; if (!DEER) - P_HandleSharedKeys(i); + hud_input(i); if (ud.pause_on == 0) { diff --git a/source/games/duke/src/zz_player.cpp b/source/games/duke/src/zz_player.cpp index 167eb5a62..c95b3cfe9 100644 --- a/source/games/duke/src/zz_player.cpp +++ b/source/games/duke/src/zz_player.cpp @@ -2942,7 +2942,7 @@ void P_DHGetInput(int const playerNum) //} } -void P_MadeNoise(int playerNum) +void madenoise(int playerNum) { DukePlayer_t *const pPlayer = g_player[playerNum].ps; pPlayer->make_noise = 1; @@ -3046,7 +3046,7 @@ static int32_t P_DoCounters(int playerNum) if (!g_netServer && numplayers < 2) { pPlayer->noise_radius = 16384; - P_MadeNoise(playerNum); + madenoise(playerNum); P_Thrust(pPlayer, 4); } pPlayer->eat -= 4; @@ -3444,7 +3444,6 @@ void P_AddAmmo(DukePlayer_t * const pPlayer, int const weaponNum, int const addA pPlayer->ammo_amount[weaponNum] = max_ammo_amount[weaponNum]; } -void checkavailinven(struct player_struct* p); void checkavailweapon(struct player_struct* p); void P_AddWeapon(DukePlayer_t *pPlayer, int weaponNum) @@ -4047,7 +4046,7 @@ static void P_ProcessWeapon(int playerNum) { pPlayer->hbomb_on = 0; pPlayer->noise_radius = 8192; - P_MadeNoise(playerNum); + madenoise(playerNum); } if ((*weaponFrame) == 12) { @@ -4119,7 +4118,7 @@ static void P_ProcessWeapon(int playerNum) fi.shoot(pPlayer->i, TILE_SHOTSPARK1); A_PlaySound(PISTOL_FIRE, pPlayer->i); pPlayer->noise_radius = 8192; - P_MadeNoise(playerNum); + madenoise(playerNum); lastvisinc = (int32_t) totalclock+32; pPlayer->visibility = 0; @@ -4189,7 +4188,7 @@ static void P_ProcessWeapon(int playerNum) A_PlaySound(SHOTGUN_FIRE, pPlayer->i); pPlayer->noise_radius = 8192; - P_MadeNoise(playerNum); + madenoise(playerNum); lastvisinc = (int32_t) totalclock + 32; pPlayer->visibility = 0; @@ -4298,7 +4297,7 @@ static void P_ProcessWeapon(int playerNum) A_PlaySound(CHAINGUN_FIRE, pPlayer->i); fi.shoot(pPlayer->i, TILE_CHAINGUN); pPlayer->noise_radius = 8192; - P_MadeNoise(playerNum); + madenoise(playerNum); lastvisinc = (int32_t) totalclock + 32; pPlayer->visibility = 0; flashColor = 255+(95<<8); @@ -4342,7 +4341,7 @@ static void P_ProcessWeapon(int playerNum) fi.shoot(pPlayer->i, TILE_GROWSPARK); pPlayer->noise_radius = 1024; - P_MadeNoise(playerNum); + madenoise(playerNum); P_CheckWeapon(pPlayer); } else @@ -4373,7 +4372,7 @@ static void P_ProcessWeapon(int playerNum) A_PlaySound(CHAINGUN_FIRE, pPlayer->i); fi.shoot(pPlayer->i, TILE_SHOTSPARK1); pPlayer->noise_radius = 16384; - P_MadeNoise(playerNum); + madenoise(playerNum); pPlayer->ammo_amount[DEVISTATOR_WEAPON]--; P_CheckWeapon(pPlayer); } @@ -4402,7 +4401,7 @@ static void P_ProcessWeapon(int playerNum) A_PlaySound(CHAINGUN_FIRE, pPlayer->i); fi.shoot(pPlayer->i, TILE_CHAINGUN); pPlayer->noise_radius = 16384; - P_MadeNoise(playerNum); + madenoise(playerNum); pPlayer->ammo_amount[MOTORCYCLE_WEAPON]--; if (pPlayer->ammo_amount[MOTORCYCLE_WEAPON] <= 0) *weaponFrame = 0; @@ -4452,7 +4451,7 @@ static void P_ProcessWeapon(int playerNum) { A_PlaySound(CAT_FIRE, pPlayer->i); pPlayer->noise_radius = 2048; - P_MadeNoise(playerNum); + madenoise(playerNum); } else if ((*weaponFrame) == 9) { @@ -4515,7 +4514,7 @@ static void P_ProcessWeapon(int playerNum) A_PlaySound(354, pPlayer->i); fi.shoot(pPlayer->i, TILE_BOWLINGBALL); pPlayer->noise_radius = 1024; - P_MadeNoise(playerNum); + madenoise(playerNum); } if ((*weaponFrame) < 30) P_Thrust(pPlayer, 4); @@ -4536,7 +4535,7 @@ static void P_ProcessWeapon(int playerNum) { fi.shoot(pPlayer->i, TILE_KNEE); pPlayer->noise_radius = 1024; - P_MadeNoise(playerNum); + madenoise(playerNum); } else if ((*weaponFrame) == 16) (*weaponFrame) = 0; @@ -4554,7 +4553,7 @@ static void P_ProcessWeapon(int playerNum) { fi.shoot(pPlayer->i, TILE_SLINGBLADE); pPlayer->noise_radius = 1024; - P_MadeNoise(playerNum); + madenoise(playerNum); } else if ((*weaponFrame) == 16) (*weaponFrame) = 0; @@ -4574,7 +4573,7 @@ static void P_ProcessWeapon(int playerNum) flashColor = 255+(95<<8); fi.shoot(pPlayer->i, TILE_RPG); pPlayer->noise_radius = 32768; - P_MadeNoise(playerNum); + madenoise(playerNum); P_CheckWeapon(pPlayer); } else if ((*weaponFrame) == 16) @@ -4593,7 +4592,7 @@ static void P_ProcessWeapon(int playerNum) flashColor = 255+(95<<8); fi.shoot(pPlayer->i, TILE_RPG2); pPlayer->noise_radius = 32768; - P_MadeNoise(playerNum); + madenoise(playerNum); P_CheckWeapon(pPlayer); } else if ((*weaponFrame) == 16) diff --git a/source/games/duke/src/zz_sector.cpp b/source/games/duke/src/zz_sector.cpp index 587ff96f9..2bd5690a6 100644 --- a/source/games/duke/src/zz_sector.cpp +++ b/source/games/duke/src/zz_sector.cpp @@ -678,7 +678,7 @@ rrtripbomb_case: pPlayer->yehaa_timer = 126; A_PlaySound(390, pPlayer->i); pPlayer->noise_radius = 16384; - P_MadeNoise(playerNum); + madenoise(playerNum); if (sector[pPlayer->cursectnum].lotag == 857) { if (sprite[pPlayer->i].extra <= max_player_health)