From 86d45dd42fd3cf9c183883e4ab1abe5b607e1779 Mon Sep 17 00:00:00 2001 From: Dmitry Lyashuk Date: Thu, 24 Mar 2022 22:45:38 +0300 Subject: [PATCH] Game: Weapon autoswitch by travi$ --- src/game/g_language.pas | 3 + src/game/g_menu.pas | 11 ++++ src/game/g_netmsg.pas | 16 ++++- src/game/g_options.pas | 2 + src/game/g_player.pas | 127 ++++++++++++++++++++++++++++++++++------ 5 files changed, 140 insertions(+), 19 deletions(-) diff --git a/src/game/g_language.pas b/src/game/g_language.pas index a7791c6..362da8d 100644 --- a/src/game/g_language.pas +++ b/src/game/g_language.pas @@ -277,6 +277,7 @@ type I_MENU_GAME_INDICATOR_ARROW, I_MENU_GAME_INDICATOR_NAME, I_MENU_GAME_SCALE_FACTOR, + I_MENU_GAME_WEAPON_AUTOSWITCH, I_MENU_VIDEO_RESOLUTION, I_MENU_VIDEO_BPP, @@ -1166,6 +1167,8 @@ const 'Èìÿ'), ('MENU GAME SCALE FACTOR', 'Scale:', 'Ìàñøòàá:'), + ('MENU GAME WEAPON AUTOSWITCH', 'Weapon autoswitch:', + 'Àâòîâûáîð îðóæèÿ:'), ('MENU VIDEO RESOLUTION', 'Set video mode', 'Óñòàíîâêà âèäåîðåæèìà'), diff --git a/src/game/g_menu.pas b/src/game/g_menu.pas index 04ffd90..9e89ad9 100644 --- a/src/game/g_menu.pas +++ b/src/game/g_menu.pas @@ -170,6 +170,8 @@ begin TempScale := TGUIScroll(menu.GetControl('scScaleFactor')).Value; g_dbg_scale := TempScale + 1; end; + gWeaponAutoswitch := TGUISwitch(menu.GetControl('swWeaponAutoswitch')).ItemIndex = 0; + menu := TGUIMenu(g_GUI_GetWindow('OptionsControlsMenu').GetControl('mOptionsControlsMenu')); @@ -595,6 +597,9 @@ begin TempScale := Round(g_dbg_scale - 1); TGUIScroll(menu.GetControl('scScaleFactor')).Value := TempScale; + with TGUISwitch(menu.GetControl('swWeaponAutoswitch')) do + if gWeaponAutoswitch then ItemIndex := 0 else ItemIndex := 1; + menu := TGUIMenu(g_GUI_GetWindow('OptionsPlayersP1Menu').GetControl('mOptionsPlayersP1Menu')); TGUIListBox(menu.GetControl('lsP1Model')).SelectItem(gPlayer1Settings.Model); @@ -2990,6 +2995,12 @@ begin Max := 10; OnChange := ProcChangeGameSettings; end; + with AddSwitch(_lc[I_MENU_GAME_WEAPON_AUTOSWITCH]) do + begin + Name := 'swWeaponAutoswitch'; + AddItem(_lc[I_MENU_YES]); + AddItem(_lc[I_MENU_NO]); + end; ReAlign(); end; Menu.DefControl := 'mOptionsGameMenu'; diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas index 5b92f2f..3701038 100644 --- a/src/game/g_netmsg.pas +++ b/src/game/g_netmsg.pas @@ -2447,6 +2447,7 @@ var PID: Word; Pl: TPlayer; I, OldFire: Integer; + checkWeapon: Boolean; OldJet, Flam: Boolean; NewTeam: Byte; begin @@ -2468,8 +2469,19 @@ begin NewTeam := M.ReadByte(); for I := WP_FIRST to WP_LAST do - FWeapon[I] := (M.ReadByte() <> 0); - + begin + checkWeapon := (M.ReadByte() <> 0); + if ( ((PID = gPlayer1.UID) or ( (gPlayer2 <> nil) and (PID = gPlayer2.UID))) and (I <> WEAPON_PISTOL) and (I <> WEAPON_KASTET ) and (gWeaponAutoswitch = True)) then + begin + if ( (checkWeapon = True) and (FWeapon[I] = False) ) then + begin + FWeapon[I] := True; + if (PID = gPlayer1.UID) then gSelectWeapon[0, I] := True + else gSelectWeapon[1, I] := True; + end; + end; + FWeapon[I] := checkWeapon; + end; for I := A_BULLETS to A_HIGH do FAmmo[I] := M.ReadWord(); diff --git a/src/game/g_options.pas b/src/game/g_options.pas index 853c612..9cd3cbf 100644 --- a/src/game/g_options.pas +++ b/src/game/g_options.pas @@ -63,6 +63,7 @@ var gsSDLBufferSize: Integer; gDefaultMegawadStart: AnsiString; gBerserkAutoswitch: Boolean; + gWeaponAutoswitch: Boolean; glNPOTOverride: Boolean = false; (* Latched game settings *) @@ -255,6 +256,7 @@ begin e_FastScreenshots := True; gDefaultMegawadStart := DF_Default_Megawad_Start; gBerserkAutoswitch := True; + gWeaponAutoswitch := True; g_dbg_scale := 1.0; gSaveStats := False; diff --git a/src/game/g_player.pas b/src/game/g_player.pas index 89e3dee..80ab62e 100644 --- a/src/game/g_player.pas +++ b/src/game/g_player.pas @@ -3877,6 +3877,7 @@ function TPlayer.PickItem(ItemType: Byte; arespawn: Boolean; var remove: Boolean var a: Boolean; + hadWeapon: Boolean; begin Result := False; if g_Game_IsClient then Exit; @@ -3950,7 +3951,18 @@ begin ITEM_WEAPON_SAW: if (not FWeapon[WEAPON_SAW]) or ((not arespawn) and (gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF])) then begin - FWeapon[WEAPON_SAW] := True; + if ( (gWeaponAutoswitch = True) and ((g_Game_IsNet = False or (NetMode = NET_SERVER)) and ((Self = gPlayer1) or (Self = gPlayer2)))) then + begin + hadWeapon := FWeapon[WEAPON_SAW]; + FWeapon[WEAPON_SAW] := True; + if (hadWeapon = False) then + begin + FCurrWeap := WEAPON_SAW; + resetWeaponQueue(); + FModel.SetWeapon(WEAPON_SAW); + end; + end + else FWeapon[WEAPON_SAW] := True; Result := True; if gFlash = 2 then Inc(FPickup, 5); if a and g_Game_IsNet then MH_SEND_Sound(GameX, GameY, 'SOUND_ITEM_GETWEAPON'); @@ -3961,9 +3973,19 @@ begin begin // Íóæíî, ÷òîáû íå âçÿòü âñå ïóëè ñðàçó: if a and FWeapon[WEAPON_SHOTGUN1] then Exit; - IncMax(FAmmo[A_SHELLS], 4, FMaxAmmo[A_SHELLS]); - FWeapon[WEAPON_SHOTGUN1] := True; + if ( (gWeaponAutoswitch = True) and ((g_Game_IsNet = False or (NetMode = NET_SERVER)) and ((Self = gPlayer1) or (Self = gPlayer2)))) then + begin + hadWeapon := FWeapon[WEAPON_SHOTGUN1]; + FWeapon[WEAPON_SHOTGUN1] := True; + if (hadWeapon = False) then + begin + FCurrWeap := WEAPON_SHOTGUN1; + resetWeaponQueue(); + FModel.SetWeapon(WEAPON_SHOTGUN1); + end; + end + else FWeapon[WEAPON_SHOTGUN1] := True; Result := True; if gFlash = 2 then Inc(FPickup, 5); if a and g_Game_IsNet then MH_SEND_Sound(GameX, GameY, 'SOUND_ITEM_GETWEAPON'); @@ -3973,9 +3995,19 @@ begin if (FAmmo[A_SHELLS] < FMaxAmmo[A_SHELLS]) or not FWeapon[WEAPON_SHOTGUN2] then begin if a and FWeapon[WEAPON_SHOTGUN2] then Exit; - + if ( (gWeaponAutoswitch = True) and ((g_Game_IsNet = False or (NetMode = NET_SERVER)) and ((Self = gPlayer1) or (Self = gPlayer2)))) then + begin + hadWeapon := FWeapon[WEAPON_SHOTGUN2]; + FWeapon[WEAPON_SHOTGUN2] := True; + if (hadWeapon = False) then + begin + FCurrWeap := WEAPON_SHOTGUN2; + resetWeaponQueue(); + FModel.SetWeapon(WEAPON_SHOTGUN2); + end; + end + else FWeapon[WEAPON_SHOTGUN2] := True; IncMax(FAmmo[A_SHELLS], 4, FMaxAmmo[A_SHELLS]); - FWeapon[WEAPON_SHOTGUN2] := True; Result := True; if gFlash = 2 then Inc(FPickup, 5); if a and g_Game_IsNet then MH_SEND_Sound(GameX, GameY, 'SOUND_ITEM_GETWEAPON'); @@ -3985,9 +4017,19 @@ begin if (FAmmo[A_BULLETS] < FMaxAmmo[A_BULLETS]) or not FWeapon[WEAPON_CHAINGUN] then begin if a and FWeapon[WEAPON_CHAINGUN] then Exit; - + if ( (gWeaponAutoswitch = True) and ((g_Game_IsNet = False or (NetMode = NET_SERVER)) and ((Self = gPlayer1) or (Self = gPlayer2)))) then + begin + hadWeapon := FWeapon[WEAPON_CHAINGUN]; + FWeapon[WEAPON_CHAINGUN] := True; + if (hadWeapon = False) then + begin + FCurrWeap := WEAPON_CHAINGUN; + resetWeaponQueue(); + FModel.SetWeapon(WEAPON_CHAINGUN); + end; + end + else FWeapon[WEAPON_CHAINGUN] := True; IncMax(FAmmo[A_BULLETS], 50, FMaxAmmo[A_BULLETS]); - FWeapon[WEAPON_CHAINGUN] := True; Result := True; if gFlash = 2 then Inc(FPickup, 5); if a and g_Game_IsNet then MH_SEND_Sound(GameX, GameY, 'SOUND_ITEM_GETWEAPON'); @@ -3997,9 +4039,19 @@ begin if (FAmmo[A_ROCKETS] < FMaxAmmo[A_ROCKETS]) or not FWeapon[WEAPON_ROCKETLAUNCHER] then begin if a and FWeapon[WEAPON_ROCKETLAUNCHER] then Exit; - + if ( (gWeaponAutoswitch = True) and ((g_Game_IsNet = False or (NetMode = NET_SERVER)) and ((Self = gPlayer1) or (Self = gPlayer2)))) then + begin + hadWeapon := FWeapon[WEAPON_ROCKETLAUNCHER]; + FWeapon[WEAPON_ROCKETLAUNCHER] := True; + if (hadWeapon = False) then + begin + FCurrWeap := WEAPON_ROCKETLAUNCHER; + resetWeaponQueue(); + FModel.SetWeapon(WEAPON_ROCKETLAUNCHER); + end; + end + else FWeapon[WEAPON_ROCKETLAUNCHER] := True; IncMax(FAmmo[A_ROCKETS], 2, FMaxAmmo[A_ROCKETS]); - FWeapon[WEAPON_ROCKETLAUNCHER] := True; Result := True; if gFlash = 2 then Inc(FPickup, 5); if a and g_Game_IsNet then MH_SEND_Sound(GameX, GameY, 'SOUND_ITEM_GETWEAPON'); @@ -4009,9 +4061,19 @@ begin if (FAmmo[A_CELLS] < FMaxAmmo[A_CELLS]) or not FWeapon[WEAPON_PLASMA] then begin if a and FWeapon[WEAPON_PLASMA] then Exit; - + if ( (gWeaponAutoswitch = True) and ((g_Game_IsNet = False or (NetMode = NET_SERVER)) and ((Self = gPlayer1) or (Self = gPlayer2)))) then + begin + hadWeapon := FWeapon[WEAPON_PLASMA]; + FWeapon[WEAPON_PLASMA] := True; + if (hadWeapon = False) then + begin + FCurrWeap := WEAPON_PLASMA; + resetWeaponQueue(); + FModel.SetWeapon(WEAPON_PLASMA); + end; + end + else FWeapon[WEAPON_PLASMA] := True; IncMax(FAmmo[A_CELLS], 40, FMaxAmmo[A_CELLS]); - FWeapon[WEAPON_PLASMA] := True; Result := True; if gFlash = 2 then Inc(FPickup, 5); if a and g_Game_IsNet then MH_SEND_Sound(GameX, GameY, 'SOUND_ITEM_GETWEAPON'); @@ -4021,9 +4083,19 @@ begin if (FAmmo[A_CELLS] < FMaxAmmo[A_CELLS]) or not FWeapon[WEAPON_BFG] then begin if a and FWeapon[WEAPON_BFG] then Exit; - + if ( (gWeaponAutoswitch = True) and ((g_Game_IsNet = False or (NetMode = NET_SERVER)) and ((Self = gPlayer1) or (Self = gPlayer2)))) then + begin + hadWeapon := FWeapon[WEAPON_BFG]; + FWeapon[WEAPON_BFG] := True; + if (hadWeapon = False) then + begin + FCurrWeap := WEAPON_BFG; + resetWeaponQueue(); + FModel.SetWeapon(WEAPON_BFG); + end; + end + else FWeapon[WEAPON_BFG] := True; IncMax(FAmmo[A_CELLS], 40, FMaxAmmo[A_CELLS]); - FWeapon[WEAPON_BFG] := True; Result := True; if gFlash = 2 then Inc(FPickup, 5); if a and g_Game_IsNet then MH_SEND_Sound(GameX, GameY, 'SOUND_ITEM_GETWEAPON'); @@ -4033,9 +4105,19 @@ begin if (FAmmo[A_SHELLS] < FMaxAmmo[A_SHELLS]) or not FWeapon[WEAPON_SUPERPULEMET] then begin if a and FWeapon[WEAPON_SUPERPULEMET] then Exit; - + if ( (gWeaponAutoswitch = True) and ((g_Game_IsNet = False or (NetMode = NET_SERVER)) and ((Self = gPlayer1) or (Self = gPlayer2)))) then + begin + hadWeapon := FWeapon[WEAPON_SUPERPULEMET]; + FWeapon[WEAPON_SUPERPULEMET] := True; + if (hadWeapon = False) then + begin + FCurrWeap := WEAPON_SUPERPULEMET; + resetWeaponQueue(); + FModel.SetWeapon(WEAPON_SUPERPULEMET); + end; + end + else FWeapon[WEAPON_SUPERPULEMET] := True; IncMax(FAmmo[A_SHELLS], 4, FMaxAmmo[A_SHELLS]); - FWeapon[WEAPON_SUPERPULEMET] := True; Result := True; if gFlash = 2 then Inc(FPickup, 5); if a and g_Game_IsNet then MH_SEND_Sound(GameX, GameY, 'SOUND_ITEM_GETWEAPON'); @@ -4045,9 +4127,19 @@ begin if (FAmmo[A_FUEL] < FMaxAmmo[A_FUEL]) or not FWeapon[WEAPON_FLAMETHROWER] then begin if a and FWeapon[WEAPON_FLAMETHROWER] then Exit; - + if ( (gWeaponAutoswitch = True) and ((g_Game_IsNet = False or (NetMode = NET_SERVER)) and ((Self = gPlayer1) or (Self = gPlayer2)))) then + begin + hadWeapon := FWeapon[WEAPON_FLAMETHROWER]; + FWeapon[WEAPON_FLAMETHROWER] := True; + if (hadWeapon = False) then + begin + FCurrWeap := WEAPON_FLAMETHROWER; + resetWeaponQueue(); + FModel.SetWeapon(WEAPON_FLAMETHROWER); + end; + end + else FWeapon[WEAPON_FLAMETHROWER] := True; IncMax(FAmmo[A_FUEL], 100, FMaxAmmo[A_FUEL]); - FWeapon[WEAPON_FLAMETHROWER] := True; Result := True; if gFlash = 2 then Inc(FPickup, 5); if a and g_Game_IsNet then MH_SEND_Sound(GameX, GameY, 'SOUND_ITEM_GETWEAPON'); @@ -7920,4 +8012,5 @@ begin conRegVar('cheat_berserk_autoswitch', @gBerserkAutoswitch, 'autoswitch to fist when berserk pack taken', '', true, true); conRegVar('player_indicator', @gPlayerIndicator, 'Draw indicator only for current player, also for teammates, or not at all', 'Draw indicator only for current player, also for teammates, or not at all'); conRegVar('player_indicator_style', @gPlayerIndicatorStyle, 'Visual appearance of indicator', 'Visual appearance of indicator'); + conRegVar('weapon_autoswitch', @gWeaponAutoswitch, 'Automatically switch to a first time picked up weapon', ''); end. -- 2.29.2