From 55f201758f237cac6c889e98572e6eda7c4067fc Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sat, 29 Jan 2022 15:43:09 +0300 Subject: [PATCH] game: disable shells for server --- src/game/Doom2DF.lpr | 3 + src/game/g_console.pas | 7 +- src/game/g_game.pas | 18 ++- src/game/g_menu.pas | 11 +- src/game/g_monsters.pas | 99 +++++++++---- src/game/g_netmsg.pas | 17 ++- src/game/g_options.pas | 7 +- src/game/g_player.pas | 269 +++++++++-------------------------- src/game/g_shells.pas | 203 ++++++++++++++++++++++++++ src/game/g_triggers.pas | 21 ++- src/game/opengl/r_game.pas | 4 +- src/game/opengl/r_player.pas | 10 +- src/shared/a_modes.inc | 16 +++ 13 files changed, 439 insertions(+), 246 deletions(-) create mode 100644 src/game/g_shells.pas diff --git a/src/game/Doom2DF.lpr b/src/game/Doom2DF.lpr index dc4d79c..ec2bdfa 100644 --- a/src/game/Doom2DF.lpr +++ b/src/game/Doom2DF.lpr @@ -129,6 +129,9 @@ uses {$IFDEF ENABLE_GIBS} g_gibs in 'g_gibs.pas', {$ENDIF} + {$IFDEF ENABLE_SHELLS} + g_shells in 'g_shells.pas', + {$ENDIF} g_items in 'g_items.pas', g_map in 'g_map.pas', g_monsters in 'g_monsters.pas', diff --git a/src/game/g_console.pas b/src/game/g_console.pas index 9a8fd11..99335ba 100644 --- a/src/game/g_console.pas +++ b/src/game/g_console.pas @@ -112,6 +112,9 @@ uses {$IFDEF ENABLE_GIBS} g_gibs, {$ENDIF} + {$IFDEF ENABLE_SHELLS} + g_shells, + {$ENDIF} g_textures, e_input, g_game, g_player, g_items, SysUtils, g_basic, g_options, Math, e_res, g_language, g_net, g_netmsg, e_log, conbuf; @@ -2006,7 +2009,9 @@ begin {$IFDEF ENABLE_GFX} WriteLn(f, 'g_max_particles ', g_GFX_GetMax()); {$ENDIF} - WriteLn(f, 'g_max_shells ', g_Shells_GetMax()); + {$IFDEF ENABLE_SHELLS} + WriteLn(f, 'g_max_shells ', g_Shells_GetMax()); + {$ENDIF} {$IFDEF ENABLE_GIBS} WriteLn(f, 'g_max_gibs ', g_Gibs_GetMax()); {$ENDIF} diff --git a/src/game/g_game.pas b/src/game/g_game.pas index 019fdc4..8d47073 100644 --- a/src/game/g_game.pas +++ b/src/game/g_game.pas @@ -454,6 +454,9 @@ uses {$IFDEF ENABLE_GIBS} g_gibs, {$ENDIF} + {$IFDEF ENABLE_SHELLS} + g_shells, + {$ENDIF} {$IFNDEF HEADLESS} r_render, g_system, {$ENDIF} @@ -2185,6 +2188,9 @@ begin g_Gibs_Update; {$ENDIF} g_Player_UpdatePhysicalObjects(); + {$IFDEF ENABLE_SHELLS} + g_Shells_Update; + {$ENDIF} // server: send newly spawned monsters unconditionally if (gGameSettings.GameType = GT_SERVER) then @@ -3976,12 +3982,18 @@ begin begin if Length(p) = 2 then begin - a := Max(0, StrToInt(p[1])); - g_Shells_SetMax(a) + {$IFDEF ENABLE_SHELLS} + a := Max(0, StrToInt(p[1])); + g_Shells_SetMax(a) + {$ENDIF} end else if Length(p) = 1 then begin - e_LogWritefln('%s', [g_Shells_GetMax()]) + {$IFDEF ENABLE_SHELLS} + e_LogWritefln('%s', [g_Shells_GetMax()]) + {$ELSE} + e_LogWritefln('%s', [0]) + {$ENDIF} end else begin diff --git a/src/game/g_menu.pas b/src/game/g_menu.pas index 62bf314..d88c79f 100644 --- a/src/game/g_menu.pas +++ b/src/game/g_menu.pas @@ -45,6 +45,9 @@ uses {$IFDEF ENABLE_GIBS} g_gibs, {$ENDIF} + {$IFDEF ENABLE_SHELLS} + g_shells, + {$ENDIF} g_gui, r_textures, r_graphics, g_game, g_map, g_base, g_basic, g_console, g_sound, g_player, g_options, g_weapons, e_log, SysUtils, CONFIG, g_playermodel, DateUtils, @@ -141,7 +144,9 @@ begin {$IFDEF ENABLE_GFX} g_GFX_SetMax(TGUIScroll(menu.GetControl('scParticlesCount')).Value*1000); {$ENDIF} - g_Shells_SetMax(TGUIScroll(menu.GetControl('scShellsMax')).Value*30); + {$IFDEF ENABLE_SHELLS} + g_Shells_SetMax(TGUIScroll(menu.GetControl('scShellsMax')).Value*30); + {$ENDIF} {$IFDEF ENABLE_GIBS} g_Gibs_SetMax(TGUIScroll(menu.GetControl('scGibsMax')).Value*25); {$ENDIF} @@ -541,7 +546,9 @@ begin {$IFDEF ENABLE_GFX} TGUIScroll(menu.GetControl('scParticlesCount')).Value := g_GFX_GetMax() div 1000; {$ENDIF} - TGUIScroll(menu.GetControl('scShellsMax')).Value := g_Shells_GetMax() div 30; + {$IFDEF ENABLE_SHELLS} + TGUIScroll(menu.GetControl('scShellsMax')).Value := g_Shells_GetMax() div 30; + {$ENDIF} {$IFDEF ENABLE_GIBS} TGUIScroll(menu.GetControl('scGibsMax')).Value := g_Gibs_GetMax() div 25; {$ENDIF} diff --git a/src/game/g_monsters.pas b/src/game/g_monsters.pas index 78ae1a4..fbb75a5 100644 --- a/src/game/g_monsters.pas +++ b/src/game/g_monsters.pas @@ -87,8 +87,10 @@ type FBloodBlue: Byte; FBloodKind: Byte; {$ENDIF} - FShellTimer: Integer; - FShellType: Byte; + {$IFDEF ENABLE_SHELLS} + FShellTimer: Integer; + FShellType: Byte; + {$ENDIF} FFirePainTime: Integer; FFireAttacker: Word; vilefire: TAnimationState; @@ -532,6 +534,9 @@ uses {$IFDEF ENABLE_GIBS} g_gibs, {$ENDIF} + {$IFDEF ENABLE_SHELLS} + g_shells, + {$ENDIF} e_log, g_sound, g_player, g_game, g_weapons, g_triggers, g_items, g_options, g_console, g_map, Math, wadreader, @@ -1591,7 +1596,9 @@ begin FDieTriggers := nil; FWaitAttackAnim := False; FChainFire := False; - FShellTimer := -1; + {$IFDEF ENABLE_SHELLS} + FShellTimer := -1; + {$ENDIF} FState := MONSTATE_SLEEP; FCurAnim := ANIM_SLEEP; @@ -1628,7 +1635,9 @@ begin FChainFire := False; FStartID := aID; FNoRespawn := False; - FShellTimer := -1; + {$IFDEF ENABLE_SHELLS} + FShellTimer := -1; + {$ENDIF} FBehaviour := BH_NORMAL; FFireTime := 0; FFirePainTime := 0; @@ -2243,25 +2252,35 @@ begin // Таймер - ждем после потери цели: FTargetTime := FTargetTime + 1; -// Гильзы +{$IFDEF ENABLE_SHELLS} + // Гильзы if FShellTimer > -1 then + begin if FShellTimer = 0 then begin if FShellType = SHELL_SHELL then - g_Player_CreateShell(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), + begin + g_Shells_Create(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), GameVelX, GameVelY-2, SHELL_SHELL) + end else if FShellType = SHELL_DBLSHELL then begin - g_Player_CreateShell(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), + g_Shells_Create(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), GameVelX-1, GameVelY-2, SHELL_SHELL); - g_Player_CreateShell(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), + g_Shells_Create(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), GameVelX+1, GameVelY-2, SHELL_SHELL); end; FShellTimer := -1; - end else Dec(FShellTimer); + end + else + begin + Dec(FShellTimer); + end; + end; +{$ENDIF} // Пробуем увернуться от летящей пули: if fall then @@ -2942,20 +2961,26 @@ _end: begin g_Sound_PlayExAt('SOUND_WEAPON_FIREPISTOL', wx, wy); g_Weapon_gun(wx, wy, tx, ty, 1, 3, FUID, True); - g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_BULLET); + {$ENDIF} end; MONSTER_SERG: begin g_Weapon_shotgun(wx, wy, tx, ty, FUID); if not gSoundEffectsDF then g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN', wx, wy); - FShellTimer := 10; - FShellType := SHELL_SHELL; + {$IFDEF ENABLE_SHELLS} + FShellTimer := 10; + FShellType := SHELL_SHELL; + {$ENDIF} end; MONSTER_MAN: begin g_Weapon_dshotgun(wx, wy, tx, ty, FUID); - FShellTimer := 13; - FShellType := SHELL_DBLSHELL; + {$IFDEF ENABLE_SHELLS} + FShellTimer := 13; + FShellType := SHELL_DBLSHELL; + {$ENDIF} FAmmo := -36; end; MONSTER_CYBER: @@ -2969,13 +2994,17 @@ _end: begin g_Weapon_mgun(wx, wy, tx, ty, FUID); if not gSoundEffectsDF then g_Sound_PlayExAt('SOUND_WEAPON_FIRECGUN', wx, wy); - g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_BULLET); + {$ENDIF} end; MONSTER_SPIDER: begin g_Weapon_mgun(wx, wy, tx, ty, FUID); if not gSoundEffectsDF then g_Sound_PlayExAt('SOUND_WEAPON_FIRECGUN', wx, wy); - g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_SHELL); + {$ENDIF} end; MONSTER_BSP: g_Weapon_aplasma(wx, wy, tx, ty, FUID); @@ -3234,24 +3263,34 @@ begin // Таймер - ждем после потери цели: FTargetTime := FTargetTime + 1; +{$IFDEF ENABLE_SHELLS} if FShellTimer > -1 then + begin if FShellTimer = 0 then begin if FShellType = SHELL_SHELL then - g_Player_CreateShell(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), + begin + g_Shells_Create(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), GameVelX, GameVelY-2, SHELL_SHELL) + end else if FShellType = SHELL_DBLSHELL then begin - g_Player_CreateShell(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), + g_Shells_Create(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), GameVelX-1, GameVelY-2, SHELL_SHELL); - g_Player_CreateShell(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), + g_Shells_Create(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), GameVelX+1, GameVelY-2, SHELL_SHELL); end; FShellTimer := -1; - end else Dec(FShellTimer); + end + else + begin + Dec(FShellTimer); + end; + end; +{$ENDIF} // Пробуем увернуться от летящей пули: if fall then @@ -3793,24 +3832,32 @@ begin MONSTER_ZOMBY: begin g_Sound_PlayExAt('SOUND_WEAPON_FIREPISTOL', wx, wy); - g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_BULLET); + {$ENDIF} end; MONSTER_SERG: begin g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN', wx, wy); - FShellTimer := 10; - FShellType := SHELL_SHELL; + {$IFDEF ENABLE_SHELLS} + FShellTimer := 10; + FShellType := SHELL_SHELL; + {$ENDIF} end; MONSTER_MAN: begin g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN2', wx, wy); - FShellTimer := 13; - FShellType := SHELL_DBLSHELL; + {$IFDEF ENABLE_SHELLS} + FShellTimer := 13; + FShellType := SHELL_DBLSHELL; + {$ENDIF} end; MONSTER_CGUN, MONSTER_SPIDER: begin g_Sound_PlayExAt('SOUND_WEAPON_FIRECGUN', wx, wy); - g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_BULLET); + {$ENDIF} end; MONSTER_IMP: g_Weapon_ball1(wx, wy, atx, aty, FUID); diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas index efb5d32..775a7ae 100644 --- a/src/game/g_netmsg.pas +++ b/src/game/g_netmsg.pas @@ -282,6 +282,9 @@ implementation {$IFDEF ENABLE_GFX} g_gfx, {$ENDIF} + {$IFDEF ENABLE_SHELLS} + g_shells, + {$ENDIF} Math, ENet, e_input, e_log, g_base, g_basic, g_textures, g_sound, g_console, g_options, g_game, g_player, g_map, g_panel, g_items, g_weapons, g_phys, @@ -1612,16 +1615,22 @@ begin end; NET_GFX_SHELL1: begin - g_Player_CreateShell(X, Y, 0, -2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(X, Y, 0, -2, SHELL_BULLET); + {$ENDIF} end; NET_GFX_SHELL2: begin - g_Player_CreateShell(X, Y, 0, -2, SHELL_SHELL); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(X, Y, 0, -2, SHELL_SHELL); + {$ENDIF} end; NET_GFX_SHELL3: begin - g_Player_CreateShell(X, Y, 0, -2, SHELL_SHELL); - g_Player_CreateShell(X, Y, 0, -2, SHELL_SHELL); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(X, Y, 0, -2, SHELL_SHELL); + g_Shells_Create(X, Y, 0, -2, SHELL_SHELL); + {$ENDIF} end; end; end; diff --git a/src/game/g_options.pas b/src/game/g_options.pas index 706b902..83bae96 100644 --- a/src/game/g_options.pas +++ b/src/game/g_options.pas @@ -131,6 +131,9 @@ uses {$IFDEF ENABLE_GIBS} g_gibs, {$ENDIF} + {$IFDEF ENABLE_SHELLS} + g_shells, + {$ENDIF} e_log, e_input, g_console, g_sound, g_player, Math, g_map, g_net, g_netmaster, SysUtils, CONFIG, g_game, g_items, wadreader, envvars; @@ -286,7 +289,9 @@ begin {$IFDEF ENABLE_GFX} g_GFX_SetMax(2000); {$ENDIF} - g_Shells_SetMax(300); + {$IFDEF ENABLE_SHELLS} + g_Shells_SetMax(DefaultShellMax); + {$ENDIF} g_Corpses_SetMax(20); {$IFDEF ENABLE_GIBS} g_Gibs_SetMax(DefaultGibsMax); diff --git a/src/game/g_player.pas b/src/game/g_player.pas index 68bee9a..aab6b38 100644 --- a/src/game/g_player.pas +++ b/src/game/g_player.pas @@ -74,10 +74,6 @@ const TEAM_BLUE = 2; TEAM_COOP = 3; - SHELL_BULLET = 0; - SHELL_SHELL = 1; - SHELL_DBLSHELL = 2; - ANGLE_NONE = Low(SmallInt); CORPSE_STATE_REMOVEME = 0; @@ -201,8 +197,10 @@ type FIncCamOld: Integer; FIncCam: Integer; FSlopeOld: Integer; - FShellTimer: Integer; - FShellType: Byte; + {$IFDEF ENABLE_SHELLS} + FShellTimer: Integer; + FShellType: Byte; + {$ENDIF} FSawSound: TPlayableSound; FSawSoundIdle: TPlayableSound; FSawSoundHit: TPlayableSound; @@ -501,20 +499,6 @@ type procedure LoadState (st: TStream); override; end; - PShell = ^TShell; - TShell = record - alive: Boolean; - SType: Byte; - RAngle: Integer; - Timeout: Cardinal; - Obj: TObj; - - procedure getMapBox (out x, y, w, h: Integer); inline; - procedure moveBy (dx, dy: Integer); inline; - - procedure positionChanged (); inline; //WARNING! call this after entity position was changed, or coldet will not work right! - end; - TCorpse = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF} private FMess: Boolean; @@ -553,7 +537,6 @@ type var gPlayers: Array of TPlayer; gCorpses: Array of TCorpse; - gShells: Array of TShell; gTeamStat: TTeamStat; gFly: Boolean = False; gAimLine: Boolean = False; @@ -565,14 +548,11 @@ var gSpectLatchPID2: Word = 0; MAX_RUNVEL: Integer = 8; VEL_JUMP: Integer = 10; - SHELL_TIMEOUT: Cardinal = 60000; function Lerp(X, Y, Factor: Integer): Integer; procedure g_Corpses_SetMax(Count: Word); function g_Corpses_GetMax(): Word; -procedure g_Shells_SetMax(Count: Word); -function g_Shells_GetMax(): Word; procedure g_Player_Init(); procedure g_Player_Free(); @@ -589,7 +569,6 @@ function g_Player_GetCount(): Byte; function g_Player_GetStats(): TPlayerStatArray; function g_Player_ValidName(Name: String): Boolean; function g_Player_CreateCorpse(Player: TPlayer): Integer; -procedure g_Player_CreateShell(fX, fY, dX, dY: Integer; T: Byte); procedure g_Player_UpdatePhysicalObjects(); procedure g_Player_RemoveAllCorpses(); procedure g_Player_Corpses_SaveState (st: TStream); @@ -618,6 +597,9 @@ uses {$IFDEF ENABLE_GIBS} g_gibs, {$ENDIF} + {$IFDEF ENABLE_SHELLS} + g_shells, + {$ENDIF} e_log, g_map, g_items, g_console, Math, g_options, g_triggers, g_game, g_grid, e_res, wadreader, g_monsters, CONFIG, g_language, @@ -692,8 +674,6 @@ const var MaxCorpses: Word = 20; - MaxShells: Word = 300; - CurrentShell: Integer = 0; BotNames: Array of String; BotList: Array of TBotProfile; SavedStates: Array of TPlayerSavedState; @@ -719,21 +699,6 @@ begin Result := g_Player_Get(UID1).FTeam = g_Player_Get(UID2).FTeam; end; -procedure g_Shells_SetMax(Count: Word); -begin - MaxShells := Count; - SetLength(gShells, Count); - - if CurrentShell >= Count then - CurrentShell := 0; -end; - -function g_Shells_GetMax(): Word; -begin - Result := MaxShells; -end; - - procedure g_Corpses_SetMax(Count: Word); begin MaxCorpses := Count; @@ -1552,61 +1517,9 @@ begin end; end; -procedure g_Player_CreateShell(fX, fY, dX, dY: Integer; T: Byte); -begin - if (gShells = nil) or (Length(gShells) = 0) then - Exit; - - with gShells[CurrentShell] do - begin - g_Obj_Init(@Obj); - Obj.Rect.X := 0; - Obj.Rect.Y := 0; - if T = SHELL_BULLET then - begin - Obj.Rect.Width := 4; - Obj.Rect.Height := 2; - end - else - begin - Obj.Rect.Width := 7; - Obj.Rect.Height := 3; - end; - SType := T; - alive := True; - Obj.X := fX; - Obj.Y := fY; - g_Obj_Push(@Obj, dX + Random(4)-Random(4), dY-Random(4)); - positionChanged(); // this updates spatial accelerators - RAngle := Random(360); - Timeout := gTime + SHELL_TIMEOUT; - - if CurrentShell >= High(gShells) then - CurrentShell := 0 - else - Inc(CurrentShell); - end; -end; - procedure g_Player_UpdatePhysicalObjects(); -var - i: Integer; - vel: TPoint2i; - mr: Word; - - procedure ShellSound_Bounce(X, Y: Integer; T: Byte); - var - k: Integer; - begin - k := 1 + Random(2); - if T = SHELL_BULLET then - g_Sound_PlayExAt('SOUND_PLAYER_CASING' + IntToStr(k), X, Y) - else - g_Sound_PlayExAt('SOUND_PLAYER_SHELL' + IntToStr(k), X, Y); - end; - + var i: Integer; begin -// Трупы: if gCorpses <> nil then for i := 0 to High(gCorpses) do if gCorpses[i] <> nil then @@ -1617,94 +1530,21 @@ begin end else gCorpses[i].Update(); - -// Гильзы: - if gShells <> nil then - for i := 0 to High(gShells) do - if gShells[i].alive then - with gShells[i] do - begin - Obj.oldX := Obj.X; - Obj.oldY := Obj.Y; - - vel := Obj.Vel; - mr := g_Obj_Move(@Obj, True, False, True); - positionChanged(); // this updates spatial accelerators - - if WordBool(mr and MOVE_FALLOUT) or (gShells[i].Timeout < gTime) then - begin - alive := False; - Continue; - end; - - // Отлетает от удара о стену/потолок/пол: - if WordBool(mr and MOVE_HITWALL) then - begin - Obj.Vel.X := -(vel.X div 2); - if not WordBool(mr and MOVE_INWATER) then - ShellSound_Bounce(Obj.X, Obj.Y, SType); - end; - if WordBool(mr and (MOVE_HITCEIL or MOVE_HITLAND)) then - begin - Obj.Vel.Y := -(vel.Y div 2); - if Obj.Vel.X <> 0 then Obj.Vel.X := Obj.Vel.X div 2; - if (Obj.Vel.X = 0) and (Obj.Vel.Y = 0) then - begin - if RAngle mod 90 <> 0 then - RAngle := (RAngle div 90) * 90; - end - else if not WordBool(mr and MOVE_INWATER) then - ShellSound_Bounce(Obj.X, Obj.Y, SType); - end; - - if (Obj.Vel.X >= 0) then - begin // Clockwise - RAngle := RAngle + Abs(Obj.Vel.X)*8 + Abs(Obj.Vel.Y); - if RAngle >= 360 then - RAngle := RAngle mod 360; - end else begin // Counter-clockwise - RAngle := RAngle - Abs(Obj.Vel.X)*8 - Abs(Obj.Vel.Y); - if RAngle < 0 then - RAngle := (360 - (Abs(RAngle) mod 360)) mod 360; - end; - end; -end; - -procedure TShell.getMapBox (out x, y, w, h: Integer); inline; -begin - x := Obj.X; - y := Obj.Y; - w := Obj.Rect.Width; - h := Obj.Rect.Height; end; -procedure TShell.moveBy (dx, dy: Integer); inline; -begin - if (dx <> 0) or (dy <> 0) then - begin - Obj.X += dx; - Obj.Y += dy; - positionChanged(); - end; -end; - -procedure TShell.positionChanged (); inline; begin end; - - procedure g_Player_RemoveAllCorpses(); var i: Integer; - {$IFDEF ENABLE_GIBS} - var maxgibs: Integer; - {$ENDIF} begin {$IFDEF ENABLE_GIBS} - maxgibs := g_Gibs_GetMax(); + i := g_Gibs_GetMax(); g_Gibs_SetMax(0); - g_Gibs_SetMax(maxgibs); + g_Gibs_SetMax(i); + {$ENDIF} + {$IFDEF ENABLE_SHELLS} + i := g_Shells_GetMax(); + g_Shells_SetMax(0); + g_Shells_SetMax(i); {$ENDIF} - gShells := nil; - SetLength(gShells, MaxShells); - CurrentShell := 0; if gCorpses <> nil then for i := 0 to High(gCorpses) do @@ -1963,7 +1803,9 @@ begin FPing := 0; FLoss := 0; FSavedStateNum := -1; - FShellTimer := -1; + {$IFDEF ENABLE_SHELLS} + FShellTimer := -1; + {$ENDIF} FFireTime := 0; FFirePainTime := 0; FFireAttacker := 0; @@ -2232,8 +2074,9 @@ begin FFireAngle := FAngle; f := True; DidFire := True; - g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX, - GameVelX, GameVelY-2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(GameX + PLAYER_RECT_CX, GameY + PLAYER_RECT_CX, GameVelX, GameVelY - 2, SHELL_BULLET); + {$ENDIF} end; WEAPON_SHOTGUN1: @@ -2246,8 +2089,10 @@ begin FFireAngle := FAngle; f := True; DidFire := True; - FShellTimer := 10; - FShellType := SHELL_SHELL; + {$IFDEF ENABLE_SHELLS} + FShellTimer := 10; + FShellType := SHELL_SHELL; + {$ENDIF} end; WEAPON_SHOTGUN2: @@ -2259,8 +2104,10 @@ begin FFireAngle := FAngle; f := True; DidFire := True; - FShellTimer := 13; - FShellType := SHELL_DBLSHELL; + {$IFDEF ENABLE_SHELLS} + FShellTimer := 13; + FShellType := SHELL_DBLSHELL; + {$ENDIF} end; WEAPON_CHAINGUN: @@ -2273,8 +2120,9 @@ begin FFireAngle := FAngle; f := True; DidFire := True; - g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX, - GameVelX, GameVelY-2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(GameX + PLAYER_RECT_CX, GameY + PLAYER_RECT_CX, GameVelX, GameVelY - 2, SHELL_BULLET); + {$ENDIF} end; WEAPON_ROCKETLAUNCHER: @@ -2319,8 +2167,9 @@ begin FFireAngle := FAngle; f := True; DidFire := True; - g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX, - GameVelX, GameVelY-2, SHELL_SHELL); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(GameX + PLAYER_RECT_CX, GameY + PLAYER_RECT_CX, GameVelX, GameVelY - 2, SHELL_SHELL); + {$ENDIF} end; WEAPON_FLAMETHROWER: @@ -2549,7 +2398,10 @@ begin FPhysics := True; FAlive := False; end; - FShellTimer := -1; + + {$IFDEF ENABLE_SHELLS} + FShellTimer := -1; + {$ENDIF} if (gGameSettings.MaxLives > 0) and Srv and (gLMSRespawn = LMS_RESPAWN_NONE) then begin @@ -3579,7 +3431,9 @@ begin FIncCamOld := 0; FIncCam := 0; FBFGFireCounter := -1; - FShellTimer := -1; + {$IFDEF ENABLE_SHELLS} + FShellTimer := -1; + {$ENDIF} FPain := 0; FLastHit := 0; FLastFrag := 0; @@ -3662,7 +3516,9 @@ begin FIncCamOld := 0; FIncCam := 0; FBFGFireCounter := -1; - FShellTimer := -1; + {$IFDEF ENABLE_SHELLS} + FShellTimer := -1; + {$ENDIF} FPain := 0; FLastHit := 0; FSpawnInvul := 0; @@ -4405,21 +4261,23 @@ begin else Dec(FReloading[b]); +{$IFDEF ENABLE_SHELLS} if FShellTimer > -1 then if FShellTimer = 0 then begin if FShellType = SHELL_SHELL then - g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX, + g_Shells_Create(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX, GameVelX, GameVelY-2, SHELL_SHELL) else if FShellType = SHELL_DBLSHELL then begin - g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX, + g_Shells_Create(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX, GameVelX+1, GameVelY-2, SHELL_SHELL); - g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX, + g_Shells_Create(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX, GameVelX-1, GameVelY-2, SHELL_SHELL); end; FShellTimer := -1; end else Dec(FShellTimer); +{$ENDIF} if (FBFGFireCounter > -1) then if FBFGFireCounter = 0 then @@ -4737,8 +4595,9 @@ begin g_Sound_PlayExAt('SOUND_WEAPON_FIREPISTOL', GameX, Gamey); FFireAngle := FAngle; f := True; - g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX, - GameVelX, GameVelY-2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(GameX + PLAYER_RECT_CX, GameY + PLAYER_RECT_CX, GameVelX, GameVelY - 2, SHELL_BULLET); + {$ENDIF} end; WEAPON_SHOTGUN1: @@ -4746,8 +4605,10 @@ begin g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN', Gamex, Gamey); FFireAngle := FAngle; f := True; - FShellTimer := 10; - FShellType := SHELL_SHELL; + {$IFDEF ENABLE_SHELLS} + FShellTimer := 10; + FShellType := SHELL_SHELL; + {$ENDIF} end; WEAPON_SHOTGUN2: @@ -4755,8 +4616,10 @@ begin g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN2', Gamex, Gamey); FFireAngle := FAngle; f := True; - FShellTimer := 13; - FShellType := SHELL_DBLSHELL; + {$IFDEF ENABLE_SHELLS} + FShellTimer := 13; + FShellType := SHELL_DBLSHELL; + {$ENDIF} end; WEAPON_CHAINGUN: @@ -4764,8 +4627,9 @@ begin g_Sound_PlayExAt('SOUND_WEAPON_FIRECGUN', Gamex, Gamey); FFireAngle := FAngle; f := True; - g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX, - GameVelX, GameVelY-2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(GameX + PLAYER_RECT_CX, GameY + PLAYER_RECT_CX, GameVelX, GameVelY - 2, SHELL_BULLET); + {$ENDIF} end; WEAPON_ROCKETLAUNCHER: @@ -4794,8 +4658,9 @@ begin g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN', Gamex, Gamey); FFireAngle := FAngle; f := True; - g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX, - GameVelX, GameVelY-2, SHELL_SHELL); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(GameX + PLAYER_RECT_CX, GameY + PLAYER_RECT_CX, GameVelX, GameVelY - 2, SHELL_SHELL); + {$ENDIF} end; WEAPON_FLAMETHROWER: diff --git a/src/game/g_shells.pas b/src/game/g_shells.pas new file mode 100644 index 0000000..de0fc86 --- /dev/null +++ b/src/game/g_shells.pas @@ -0,0 +1,203 @@ +(* Copyright (C) Doom 2D: Forever Developers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License ONLY. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *) +{$INCLUDE ../shared/a_modes.inc} +unit g_shells; + +interface + + uses g_phys; + + const + SHELL_BULLET = 0; + SHELL_SHELL = 1; + SHELL_DBLSHELL = 2; + + DefaultShellTimeout = 60000; + DefaultShellMax = 300; + + type + PShell = ^TShell; + TShell = record + alive: Boolean; + SType: Byte; + RAngle: Integer; + Timeout: Cardinal; + Obj: TObj; + + procedure getMapBox (out x, y, w, h: Integer); inline; + procedure moveBy (dx, dy: Integer); inline; + + procedure positionChanged (); inline; //WARNING! call this after entity position was changed, or coldet will not > + end; + + var + gShells: Array of TShell; + + procedure g_Shells_SetMax (Count: Word); + function g_Shells_GetMax (): Word; + + procedure g_Shells_Create (fX, fY, dX, dY: Integer; T: Byte); + procedure g_Shells_Update; + +implementation + + uses SysUtils, g_base, g_game, g_sound; + + var + SHELL_TIMEOUT: Cardinal = DefaultShellTimeout; + MaxShells: Word = DefaultShellMax; + CurrentShell: Integer = 0; + + procedure TShell.getMapBox (out x, y, w, h: Integer); inline; + begin + x := Obj.X; + y := Obj.Y; + w := Obj.Rect.Width; + h := Obj.Rect.Height; + end; + + procedure TShell.moveBy (dx, dy: Integer); inline; + begin + if (dx <> 0) or (dy <> 0) then + begin + Obj.X += dx; + Obj.Y += dy; + positionChanged; + end; + end; + + procedure TShell.positionChanged (); inline; + begin + end; + + procedure g_Shells_SetMax (Count: Word); + begin + MaxShells := Count; + SetLength(gShells, Count); + if CurrentShell >= Count then + CurrentShell := 0; + end; + + function g_Shells_GetMax (): Word; + begin + Result := MaxShells; + end; + + procedure g_Shells_Create (fX, fY, dX, dY: Integer; T: Byte); + begin + if (gShells = nil) or (Length(gShells) = 0) then + Exit; + + with gShells[CurrentShell] do + begin + g_Obj_Init(@Obj); + Obj.Rect.X := 0; + Obj.Rect.Y := 0; + if T = SHELL_BULLET then + begin + Obj.Rect.Width := 4; + Obj.Rect.Height := 2; + end + else + begin + Obj.Rect.Width := 7; + Obj.Rect.Height := 3; + end; + SType := T; + alive := True; + Obj.X := fX; + Obj.Y := fY; + g_Obj_Push(@Obj, dX + Random(4)-Random(4), dY-Random(4)); + positionChanged(); // this updates spatial accelerators + RAngle := Random(360); + Timeout := gTime + SHELL_TIMEOUT; + if CurrentShell >= High(gShells) then + CurrentShell := 0 + else + Inc(CurrentShell); + end; + end; + + procedure g_Shells_SoundBounce(X, Y: Integer; T: Byte); + var k: Integer; + begin + k := 1 + Random(2); + if T = SHELL_BULLET then + g_Sound_PlayExAt('SOUND_PLAYER_CASING' + IntToStr(k), X, Y) + else + g_Sound_PlayExAt('SOUND_PLAYER_SHELL' + IntToStr(k), X, Y); + end; + + procedure g_Shells_Update; + var i: Integer; vel: TPoint2i; mr: Word; + begin + if gShells = nil then + Exit; + + for i := 0 to High(gShells) do + begin + if gShells[i].alive then + begin + with gShells[i] do + begin + Obj.oldX := Obj.X; + Obj.oldY := Obj.Y; + + vel := Obj.Vel; + mr := g_Obj_Move(@Obj, True, False, True); + positionChanged(); // this updates spatial accelerators + + if WordBool(mr and MOVE_FALLOUT) or (gShells[i].Timeout < gTime) then + begin + alive := False; + Continue; + end; + + // Отлетает от удара о стену/потолок/пол: + if WordBool(mr and MOVE_HITWALL) then + begin + Obj.Vel.X := -(vel.X div 2); + if not WordBool(mr and MOVE_INWATER) then + g_Shells_SoundBounce(Obj.X, Obj.Y, SType); + end; + if WordBool(mr and (MOVE_HITCEIL or MOVE_HITLAND)) then + begin + Obj.Vel.Y := -(vel.Y div 2); + if Obj.Vel.X <> 0 then Obj.Vel.X := Obj.Vel.X div 2; + if (Obj.Vel.X = 0) and (Obj.Vel.Y = 0) then + begin + if RAngle mod 90 <> 0 then + RAngle := (RAngle div 90) * 90; + end + else if not WordBool(mr and MOVE_INWATER) then + g_Shells_SoundBounce(Obj.X, Obj.Y, SType); + end; + + if (Obj.Vel.X >= 0) then + begin // Clockwise + RAngle := RAngle + Abs(Obj.Vel.X)*8 + Abs(Obj.Vel.Y); + if RAngle >= 360 then + RAngle := RAngle mod 360; + end else begin // Counter-clockwise + RAngle := RAngle - Abs(Obj.Vel.X)*8 - Abs(Obj.Vel.Y); + if RAngle < 0 then + RAngle := (360 - (Abs(RAngle) mod 360)) mod 360; + end; + end; + end; + end; + end; + +end. diff --git a/src/game/g_triggers.pas b/src/game/g_triggers.pas index 6629ef5..a4dcc0a 100644 --- a/src/game/g_triggers.pas +++ b/src/game/g_triggers.pas @@ -105,6 +105,9 @@ implementation {$IFDEF ENABLE_GFX} g_gfx, {$ENDIF} + {$IFDEF ENABLE_SHELLS} + g_shells, + {$ENDIF} Math, g_player, g_map, g_panel, g_game, g_console, g_monsters, g_items, g_phys, g_weapons, @@ -681,7 +684,9 @@ begin Projectile := False; if ShotSound then begin - g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_BULLET); + {$ENDIF} if g_Game_IsNet then MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL1); end; end; @@ -694,7 +699,9 @@ begin Projectile := False; if ShotSound then begin - g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_BULLET); + {$ENDIF} if g_Game_IsNet then MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL1); end; end; @@ -706,7 +713,9 @@ begin Projectile := False; if ShotSound then begin - g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_SHELL); + {$ENDIF} if g_Game_IsNet then MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL2); end; end; @@ -718,8 +727,10 @@ begin Projectile := False; if ShotSound then begin - g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL); - g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_SHELL); + g_Shells_Create(wx, wy, 0, -2, SHELL_SHELL); + {$ENDIF} if g_Game_IsNet then MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL3); end; end; diff --git a/src/game/opengl/r_game.pas b/src/game/opengl/r_game.pas index 3a64ad5..58bbd63 100644 --- a/src/game/opengl/r_game.pas +++ b/src/game/opengl/r_game.pas @@ -1547,7 +1547,9 @@ begin drawPanelType('*step', PANEL_STEP, g_rlayer_step); drawOther('items', @r_Items_Draw); drawOther('weapons', @r_Weapon_Draw); - drawOther('shells', @r_Player_DrawShells); + {$IFDEF ENABLE_SHELLS} + drawOther('shells', @r_Player_DrawShells); + {$ENDIF} drawOther('drawall', @r_Player_DrawAll); {$IFDEF ENABLE_GIBS} drawOther('gibs', @r_PlayerModel_DrawGibs); diff --git a/src/game/opengl/r_player.pas b/src/game/opengl/r_player.pas index 225f852..c803b4c 100644 --- a/src/game/opengl/r_player.pas +++ b/src/game/opengl/r_player.pas @@ -27,7 +27,6 @@ interface procedure r_Player_DrawHealth; procedure r_Player_DrawCorpses; - procedure r_Player_DrawShells; procedure r_Player_Draw (p: TPlayer); procedure r_Player_DrawIndicator (p: TPlayer; Color: TRGB); @@ -38,6 +37,10 @@ interface procedure r_Player_DrawPain (p: TPlayer); procedure r_Player_DrawPickup (p: TPlayer); + {$IFDEF ENABLE_SHELLS} + procedure r_Player_DrawShells; + {$ENDIF} + implementation uses @@ -47,6 +50,9 @@ implementation {$IFDEF ENABLE_MENU} g_menu, {$ENDIF} + {$IFDEF ENABLE_SHELLS} + g_shells, + {$ENDIF} SysUtils, Classes, Math, MAPDEF, utils, g_basic, g_game, g_phys, g_map, g_language, g_weapons, g_items, g_net, g_options, @@ -149,6 +155,7 @@ end; r_Player_DrawCorpse(gCorpses[i]) end; +{$IFDEF ENABLE_SHELLS} procedure r_Player_DrawShells; var i, fX, fY: Integer; a: TDFPoint; TextureID: DWORD = DWORD(-1); begin @@ -180,6 +187,7 @@ end; end end end; +{$ENDIF} procedure r_Player_DrawIndicator (p: TPlayer; Color: TRGB); var diff --git a/src/shared/a_modes.inc b/src/shared/a_modes.inc index 494c574..1ba7346 100644 --- a/src/shared/a_modes.inc +++ b/src/shared/a_modes.inc @@ -125,6 +125,11 @@ {$UNDEF ENABLE_GIBS} {$DEFINE DISABLE_GIBS} {$ENDIF} + {$IFDEF ENABLE_SHELLS} + {$WARNING Shells in headless mode has no sense. Disabled.} + {$UNDEF ENABLE_SHELLS} + {$DEFINE DISABLE_SHELLS} + {$ENDIF} {$ENDIF} {$IF DEFINED(ENABLE_MENU) AND DEFINED(DISABLE_MENU)} @@ -171,6 +176,17 @@ {$ENDIF} {$ENDIF} +{$IF DEFINED(ENABLE_SHELLS) AND DEFINED(DISABLE_SHELLS)} + {$ERROR Select ENABLE_SHELLS or DISABLE_SHELLS} +{$ELSEIF NOT DEFINED(ENABLE_SHELLS) AND NOT DEFINED(DISABLE_SHELLS)} + // default ENABLE/DISABLE gibs + {$IFDEF HEADLESS} + {$DEFINE DISABLE_SHELLS} + {$ELSE} + {$DEFINE ENABLE_SHELLS} + {$ENDIF} +{$ENDIF} + {$IF DEFINED(USE_SYSSTUB)} {$IF DEFINED(USE_SDL) OR DEFINED(USE_SDL2)} {$ERROR Only one system driver must be selected!} -- 2.29.2