From: fgsfds Date: Thu, 6 May 2021 14:18:48 +0000 (+0300) Subject: game: add option to disable hits on friendly players X-Git-Url: http://deadsoftware.ru/gitweb?p=d2df-sdl.git;a=commitdiff_plain;h=a9b641b6421fe1ab2ae3ffdf6a7fb41c56df1970 game: add option to disable hits on friendly players --- diff --git a/src/game/g_console.pas b/src/game/g_console.pas index bbbd1c2..8eaad12 100644 --- a/src/game/g_console.pas +++ b/src/game/g_console.pas @@ -1039,6 +1039,8 @@ begin AddCommand('g_max_corpses', GameCVars); AddCommand('g_gamemode', GameCVars); AddCommand('g_friendlyfire', GameCVars); + AddCommand('g_friendly_hit_trace', GameCVars); + AddCommand('g_friendly_hit_projectile', GameCVars); AddCommand('g_weaponstay', GameCVars); AddCommand('g_allow_exit', GameCVars); AddCommand('g_dm_keys', GameCVars); @@ -1154,6 +1156,8 @@ begin WhitelistCommand('g_gamemode'); WhitelistCommand('g_friendlyfire'); + WhitelistCommand('g_friendly_hit_trace'); + WhitelistCommand('g_friendly_hit_projectile'); WhitelistCommand('g_weaponstay'); WhitelistCommand('g_allow_exit'); WhitelistCommand('g_dm_keys'); @@ -2132,6 +2136,8 @@ begin WriteLn(f, 'g_warmup_time ', gsWarmupTime); WriteFlag('g_friendlyfire ', GAME_OPTION_TEAMDAMAGE); + WriteFlag('g_friendly_hit_trace ', GAME_OPTION_TEAMHITTRACE); + WriteFlag('g_friendly_hit_projectile ', GAME_OPTION_TEAMHITPROJECTILE); WriteFlag('g_allow_exit ', GAME_OPTION_ALLOWEXIT); WriteFlag('g_allow_monsters ', GAME_OPTION_MONSTERS); WriteFlag('g_dm_keys ', GAME_OPTION_DMKEYS); diff --git a/src/game/g_game.pas b/src/game/g_game.pas index 2fd8408..2cf72c1 100644 --- a/src/game/g_game.pas +++ b/src/game/g_game.pas @@ -176,14 +176,16 @@ const EXIT_ENDLEVELSINGLE = 4; EXIT_ENDLEVELCUSTOM = 5; - GAME_OPTION_RESERVED = 1; - GAME_OPTION_TEAMDAMAGE = 2; - GAME_OPTION_ALLOWEXIT = 4; - GAME_OPTION_WEAPONSTAY = 8; - GAME_OPTION_MONSTERS = 16; - GAME_OPTION_BOTVSPLAYER = 32; - GAME_OPTION_BOTVSMONSTER = 64; - GAME_OPTION_DMKEYS = 128; + GAME_OPTION_RESERVED = 1; + GAME_OPTION_TEAMDAMAGE = 2; + GAME_OPTION_ALLOWEXIT = 4; + GAME_OPTION_WEAPONSTAY = 8; + GAME_OPTION_MONSTERS = 16; + GAME_OPTION_BOTVSPLAYER = 32; + GAME_OPTION_BOTVSMONSTER = 64; + GAME_OPTION_DMKEYS = 128; + GAME_OPTION_TEAMHITTRACE = 256; + GAME_OPTION_TEAMHITPROJECTILE = 512; STATE_NONE = 0; STATE_MENU = 1; @@ -5510,6 +5512,14 @@ begin begin ParseGameFlag(GAME_OPTION_TEAMDAMAGE, I_MSG_FRIENDLY_FIRE_OFF, I_MSG_FRIENDLY_FIRE_ON); end + else if cmd = 'g_friendly_hit_trace' then + begin + ParseGameFlag(GAME_OPTION_TEAMHITTRACE, I_MSG_FRIENDLY_FIRE_OFF, I_MSG_FRIENDLY_FIRE_ON); + end + else if cmd = 'g_friendly_hit_projectile' then + begin + ParseGameFlag(GAME_OPTION_TEAMHITPROJECTILE, I_MSG_FRIENDLY_FIRE_OFF, I_MSG_FRIENDLY_FIRE_ON); + end else if cmd = 'g_weaponstay' then begin ParseGameFlag(GAME_OPTION_WEAPONSTAY, I_MSG_WEAPONSTAY_OFF, I_MSG_WEAPONSTAY_ON); diff --git a/src/game/g_language.pas b/src/game/g_language.pas index dc216c9..8e821af 100644 --- a/src/game/g_language.pas +++ b/src/game/g_language.pas @@ -163,6 +163,11 @@ type I_MENU_GOAL_LIMIT, I_MENU_MAX_LIVES, I_MENU_TEAM_DAMAGE, + I_MENU_TEAM_HIT, + I_MENU_TEAM_HIT_BOTH, + I_MENU_TEAM_HIT_TRACE, + I_MENU_TEAM_HIT_PROJECTILE, + I_MENU_TEAM_HIT_NOTHING, I_MENU_ITEM_RESPAWN_TIME, I_MENU_DEATHMATCH_KEYS, I_MENU_ENABLE_EXITS, @@ -927,6 +932,16 @@ const 'Æèçíè:'), ('MENU TEAM DAMAGE', 'Friendly Fire:', 'Óðîí ñâîèõ:'), + ('MENU TEAM HIT', 'Hit friendlies with:', + 'Ïîïàäàíèÿ ïî ñâîèì:'), + ('MENU TEAM HIT BOTH', 'Everything', + 'Ïóëÿìè è ñíàðÿäàìè'), + ('MENU TEAM HIT TRACE', 'Hitscan only', + 'Òîëüêî ïóëÿìè'), + ('MENU TEAM HIT PROJECTILE', 'Projectiles only', + 'Òîëüêî ñíàðÿäàìè'), + ('MENU TEAM HIT NONE', 'Nothing', + 'Íè÷åì'), ('MENU ITEM RESPAWN TIME', 'Item respawn time:', 'Âðåìÿ ðåñïàâíà ïðåäìåòîâ:'), ('MENU DEATHMATCH KEYS', 'Give all keys in DM:', diff --git a/src/game/g_menu.pas b/src/game/g_menu.pas index 484b513..bd21314 100644 --- a/src/game/g_menu.pas +++ b/src/game/g_menu.pas @@ -681,6 +681,12 @@ begin if TGUISwitch(GetControl('swMonsters')).ItemIndex = 0 then gsGameFlags := gsGameFlags or GAME_OPTION_MONSTERS; + case TGUISwitch(GetControl('swTeamHit')).ItemIndex of + 1: gsGameFlags := gsGameFlags or GAME_OPTION_TEAMHITTRACE; + 2: gsGameFlags := gsGameFlags or GAME_OPTION_TEAMHITPROJECTILE; + 0: gsGameFlags := gsGameFlags or GAME_OPTION_TEAMHITTRACE or GAME_OPTION_TEAMHITPROJECTILE; + end; + case TGUISwitch(GetControl('swBotsVS')).ItemIndex of 1: gsGameFlags := gsGameFlags or GAME_OPTION_BOTVSMONSTER; 2: gsGameFlags := gsGameFlags or GAME_OPTION_BOTVSPLAYER or GAME_OPTION_BOTVSMONSTER; @@ -1635,6 +1641,15 @@ begin ItemIndex := 0 else ItemIndex := 1; + with TGUISwitch(menu.GetControl('swTeamHit')) do + if (Options and (GAME_OPTION_TEAMHITTRACE or GAME_OPTION_TEAMHITPROJECTILE)) = (GAME_OPTION_TEAMHITTRACE or GAME_OPTION_TEAMHITPROJECTILE) then + ItemIndex := 0 + else if LongBool(Options and GAME_OPTION_TEAMHITTRACE) then + ItemIndex := 1 + else if LongBool(Options and GAME_OPTION_TEAMHITPROJECTILE) then + ItemIndex := 2 + else + ItemIndex := 3; with TGUISwitch(menu.GetControl('swDeathmatchKeys')) do if LongBool(Options and GAME_OPTION_DMKEYS) then ItemIndex := 0 @@ -1658,6 +1673,7 @@ begin if GameType in [GT_CUSTOM, GT_SERVER] then begin TGUISwitch(menu.GetControl('swTeamDamage')).Enabled := True; + TGUISwitch(menu.GetControl('swTeamHit')).Enabled := True; if (GameMode in [GM_DM, GM_TDM, GM_CTF]) then begin TGUISwitch(menu.GetControl('swDeathmatchKeys')).Enabled := True; @@ -1679,6 +1695,7 @@ begin else begin TGUISwitch(menu.GetControl('swTeamDamage')).Enabled := True; + TGUISwitch(menu.GetControl('swTeamHit')).Enabled := True; TGUISwitch(menu.GetControl('swDeathmatchKeys')).Enabled := False; TGUILabel(menu.GetControlsText('swDeathmatchKeys')).Color := MENU_UNACTIVEITEMS_COLOR; with TGUIEdit(menu.GetControl('edTimeLimit')) do @@ -1724,6 +1741,16 @@ begin Options := Options and (not GAME_OPTION_TEAMDAMAGE); end; + if TGUISwitch(menu.GetControl('swTeamHit')).Enabled then + begin + Options := Options and not (GAME_OPTION_TEAMHITTRACE or GAME_OPTION_TEAMHITPROJECTILE); + case TGUISwitch(menu.GetControl('swTeamHit')).ItemIndex of + 1: Options := Options or GAME_OPTION_TEAMHITTRACE; + 2: Options := Options or GAME_OPTION_TEAMHITPROJECTILE; + 0: Options := Options or GAME_OPTION_TEAMHITTRACE or GAME_OPTION_TEAMHITPROJECTILE; + end; + end; + if TGUISwitch(menu.GetControl('swDeathmatchKeys')).Enabled then begin if TGUISwitch(menu.GetControl('swDeathmatchKeys')).ItemIndex = 0 then @@ -2193,6 +2220,22 @@ begin else ItemIndex := 1; end; + with AddSwitch(_lc[I_MENU_TEAM_HIT]) do + begin + Name := 'swTeamHit'; + AddItem(_lc[I_MENU_TEAM_HIT_BOTH]); + AddItem(_lc[I_MENU_TEAM_HIT_TRACE]); + AddItem(_lc[I_MENU_TEAM_HIT_PROJECTILE]); + AddItem(_lc[I_MENU_TEAM_HIT_NOTHING]); + if (gsGameFlags and (GAME_OPTION_TEAMHITTRACE or GAME_OPTION_TEAMHITPROJECTILE)) = (GAME_OPTION_TEAMHITTRACE or GAME_OPTION_TEAMHITPROJECTILE) then + ItemIndex := 0 + else if LongBool(gsGameFlags and GAME_OPTION_TEAMHITTRACE) then + ItemIndex := 1 + else if LongBool(gsGameFlags and GAME_OPTION_TEAMHITPROJECTILE) then + ItemIndex := 2 + else + ItemIndex := 3; + end; with AddSwitch(_lc[I_MENU_DEATHMATCH_KEYS]) do begin Name := 'swDeathmatchKeys'; @@ -2412,6 +2455,22 @@ begin else ItemIndex := 1; end; + with AddSwitch(_lc[I_MENU_TEAM_HIT]) do + begin + Name := 'swTeamHit'; + AddItem(_lc[I_MENU_TEAM_HIT_BOTH]); + AddItem(_lc[I_MENU_TEAM_HIT_TRACE]); + AddItem(_lc[I_MENU_TEAM_HIT_PROJECTILE]); + AddItem(_lc[I_MENU_TEAM_HIT_NOTHING]); + if (gsGameFlags and (GAME_OPTION_TEAMHITTRACE or GAME_OPTION_TEAMHITPROJECTILE)) = (GAME_OPTION_TEAMHITTRACE or GAME_OPTION_TEAMHITPROJECTILE) then + ItemIndex := 0 + else if LongBool(gsGameFlags and GAME_OPTION_TEAMHITTRACE) then + ItemIndex := 1 + else if LongBool(gsGameFlags and GAME_OPTION_TEAMHITPROJECTILE) then + ItemIndex := 2 + else + ItemIndex := 3; + end; with AddSwitch(_lc[I_MENU_DEATHMATCH_KEYS]) do begin Name := 'swDeathmatchKeys'; @@ -3295,6 +3354,15 @@ begin AddItem(_lc[I_MENU_NO]); ItemIndex := 1; end; + with AddSwitch(_lc[I_MENU_TEAM_HIT]) do + begin + Name := 'swTeamHit'; + AddItem(_lc[I_MENU_TEAM_HIT_BOTH]); + AddItem(_lc[I_MENU_TEAM_HIT_TRACE]); + AddItem(_lc[I_MENU_TEAM_HIT_PROJECTILE]); + AddItem(_lc[I_MENU_TEAM_HIT_NOTHING]); + ItemIndex := 0 + end; with AddSwitch(_lc[I_MENU_DEATHMATCH_KEYS]) do begin Name := 'swDeathmatchKeys'; diff --git a/src/game/g_weapons.pas b/src/game/g_weapons.pas index 79f6f25..a64d987 100644 --- a/src/game/g_weapons.pas +++ b/src/game/g_weapons.pas @@ -893,10 +893,15 @@ begin Exit; end; - if PlayerHit() then + // È â êîíöå èãðîêîâ, íî òîëüêî åñëè ïîëîæåíî + // (èëè friendlyfire, èëè friendly_hit_projectile) + if LongBool(gGameSettings.Options and (GAME_OPTION_TEAMDAMAGE or GAME_OPTION_TEAMHITPROJECTILE)) then begin - Result := 1; - Exit; + if PlayerHit() then + begin + Result := 1; + Exit; + end; end; end; @@ -934,11 +939,15 @@ begin Exit; end; - // È â êîíöå ñâîèõ èãðîêîâ - if PlayerHit(1) then + // È â êîíöå ñâîèõ èãðîêîâ, íî òîëüêî åñëè ïîëîæåíî + // (èëè friendlyfire, èëè friendly_hit_projectile) + if LongBool(gGameSettings.Options and (GAME_OPTION_TEAMDAMAGE or GAME_OPTION_TEAMHITPROJECTILE)) then begin - Result := 1; - Exit; + if PlayerHit(1) then + begin + Result := 1; + Exit; + end; end; end; @@ -1394,12 +1403,19 @@ var x2, y2: Integer; xi, yi: Integer; wallDistSq: Integer = $3fffffff; + spawnerPlr: TPlayer = nil; function doPlayerHit (idx: Integer; hx, hy: Integer): Boolean; begin result := false; if (idx < 0) or (idx > High(gPlayers)) then exit; if (gPlayers[idx] = nil) or not gPlayers[idx].alive then exit; + if (spawnerPlr <> nil) then + begin + if ((gGameSettings.Options and (GAME_OPTION_TEAMHITTRACE or GAME_OPTION_TEAMDAMAGE)) = 0) and + (spawnerPlr.Team <> TEAM_NONE) and (spawnerPlr.Team = gPlayers[idx].Team) then + exit; + end; result := HitPlayer(gPlayers[idx], dmg, (xi*v)*10, (yi*v)*10-3, SpawnerUID, HIT_SOME); if result and (v <> 0) then gPlayers[idx].Push((xi*v), (yi*v)); {$IF DEFINED(D2F_DEBUG)} @@ -1492,6 +1508,9 @@ begin if (xd = 0) and (yd = 0) then exit; + if (g_GetUIDType(SpawnerUID) = UID_PLAYER) then + spawnerPlr := g_Player_Get(SpawnerUID); + //wgunMonHash.reset(); //FIXME: clear hash on level change wgunHitHeap.clear(); wgunHitTimeUsed := 0;