X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_weapons.pas;h=9b0952edbb1652aa1a28ca09fb948d5a23527471;hb=HEAD;hp=bb17a4138972d82f07ac7674dc966e543cec69d3;hpb=dffafd305d0df029f317cc92c1968ba0065c0cd8;p=d2df-sdl.git diff --git a/src/game/g_weapons.pas b/src/game/g_weapons.pas index bb17a41..9b0952e 100644 --- a/src/game/g_weapons.pas +++ b/src/game/g_weapons.pas @@ -51,19 +51,19 @@ function g_Weapon_Hit(obj: PObj; d: Integer; SpawnerUID: Word; t: Byte; HitCorps function g_Weapon_HitUID(UID: Word; d: Integer; SpawnerUID: Word; t: Byte): Boolean; function g_Weapon_CreateShot(I: Integer; ShotType: Byte; Spawner, TargetUID: Word; X, Y, XV, YV: Integer): LongWord; -procedure g_Weapon_gun(const x, y, xd, yd, v, dmg: Integer; SpawnerUID: Word; CheckTrigger: Boolean); +procedure g_Weapon_gun(const x, y, xd, yd, v, indmg: Integer; SpawnerUID: Word; CheckTrigger: Boolean); procedure g_Weapon_punch(x, y: Integer; d, SpawnerUID: Word); function g_Weapon_chainsaw(x, y: Integer; d, SpawnerUID: Word): Integer; -procedure g_Weapon_rocket(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False); +procedure g_Weapon_rocket(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False; compat: Boolean = true); procedure g_Weapon_revf(x, y, xd, yd: Integer; SpawnerUID, TargetUID: Word; WID: Integer = -1; Silent: Boolean = False); -procedure g_Weapon_flame(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False); -procedure g_Weapon_plasma(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False); -procedure g_Weapon_ball1(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False); -procedure g_Weapon_ball2(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False); -procedure g_Weapon_ball7(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False); -procedure g_Weapon_aplasma(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False); -procedure g_Weapon_manfire(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False); -procedure g_Weapon_bfgshot(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False); +procedure g_Weapon_flame(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False; compat: Boolean = true); +procedure g_Weapon_plasma(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False; compat: Boolean = true); +procedure g_Weapon_ball1(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False; compat: Boolean = true); +procedure g_Weapon_ball2(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False; compat: Boolean = true); +procedure g_Weapon_ball7(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False; compat: Boolean = true); +procedure g_Weapon_aplasma(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False; compat: Boolean = true); +procedure g_Weapon_manfire(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False; compat: Boolean = true); +procedure g_Weapon_bfgshot(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False; compat: Boolean = true); procedure g_Weapon_bfghit(x, y: Integer); procedure g_Weapon_pistol(x, y, xd, yd: Integer; SpawnerUID: Word; Silent: Boolean = False); procedure g_Weapon_mgun(x, y, xd, yd: Integer; SpawnerUID: Word; Silent: Boolean = False); @@ -84,7 +84,7 @@ procedure g_Weapon_LoadState (st: TStream); procedure g_Weapon_AddDynLights(); const - WEAPON_KASTET = 0; + WEAPON_IRONFIST = 0; WEAPON_SAW = 1; WEAPON_PISTOL = 2; WEAPON_SHOTGUN1 = 3; @@ -93,7 +93,7 @@ const WEAPON_ROCKETLAUNCHER = 6; WEAPON_PLASMA = 7; WEAPON_BFG = 8; - WEAPON_SUPERPULEMET = 9; + WEAPON_SUPERCHAINGUN = 9; WEAPON_FLAMETHROWER = 10; WEAPON_ZOMBY_PISTOL = 20; WEAPON_IMP_FIRE = 21; @@ -103,7 +103,7 @@ const WEAPON_MANCUB_FIRE = 25; WEAPON_SKEL_FIRE = 26; - WP_FIRST = WEAPON_KASTET; + WP_FIRST = WEAPON_IRONFIST; WP_LAST = WEAPON_FLAMETHROWER; @@ -527,7 +527,7 @@ begin g_TraceVector(X, Y, Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2), Obj.Y+Obj.Rect.Y+(Obj.Rect.Height div 2)) then begin - Damage(50, 0, 0); + Damage(50, SpawnerUID, 0, 0); g_Weapon_BFGHit(Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2), Obj.Y+Obj.Rect.Y+(Obj.Rect.Height div 2)); end; @@ -694,7 +694,7 @@ begin begin g_Obj_Init(@Obj); - Obj.Rect.Width := 32; + Obj.Rect.Width := 16; Obj.Rect.Height := 16; Triggers := nil; @@ -876,8 +876,8 @@ begin g_Obj_Collide(obj, @gCorpses[i].Obj) then begin // Ðàñïèëèâàåì òðóï: - gCorpses[i].Damage(d, (obj^.Vel.X+obj^.Accel.X) div 4, - (obj^.Vel.Y+obj^.Accel.Y) div 4); + gCorpses[i].Damage(d, SpawnerUID, (obj^.Vel.X+obj^.Accel.X) div 4, + (obj^.Vel.Y+obj^.Accel.Y) div 4); Result := 1; end; end; @@ -893,10 +893,16 @@ begin Exit; end; - if PlayerHit() then + // È â êîíöå èãðîêîâ, íî òîëüêî åñëè ïîëîæåíî + // (èëè ñíàðÿä îò ìîíñòðà, èëè friendlyfire, èëè friendly_hit_projectile) + if (g_GetUIDType(SpawnerUID) <> UID_PLAYER) or + ([TGameOption.TEAM_DAMAGE, TGameOption.TEAM_HIT_PROJECTILE] <= gGameSettings.Options) then begin - Result := 1; - Exit; + if PlayerHit() then + begin + Result := 1; + Exit; + end; end; end; @@ -934,11 +940,15 @@ begin Exit; end; - // È â êîíöå ñâîèõ èãðîêîâ - if PlayerHit(1) then + // È â êîíöå ñâîèõ èãðîêîâ, íî òîëüêî åñëè ïîëîæåíî + // (èëè friendlyfire, èëè friendly_hit_projectile) + if [TGameOption.TEAM_DAMAGE, TGameOption.TEAM_HIT_PROJECTILE] <= gGameSettings.Options then begin - Result := 1; - Exit; + if PlayerHit(1) then + begin + Result := 1; + Exit; + end; end; end; @@ -1050,7 +1060,7 @@ begin mm := Max(abs(dx), abs(dy)); if mm = 0 then mm := 1; - Damage(Round(100*(rad-m)/rad), (dx*10) div mm, (dy*10) div mm); + Damage(Round(100*(rad-m)/rad), SpawnerUID, (dx*10) div mm, (dy*10) div mm); end; end; @@ -1388,18 +1398,30 @@ end; //!!!FIXME!!! -procedure g_Weapon_gun (const x, y, xd, yd, v, dmg: Integer; SpawnerUID: Word; CheckTrigger: Boolean); +procedure g_Weapon_gun (const x, y, xd, yd, v, indmg: Integer; SpawnerUID: Word; CheckTrigger: Boolean); var x0, y0: Integer; x2, y2: Integer; xi, yi: Integer; wallDistSq: Integer = $3fffffff; + spawnerPlr: TPlayer = nil; + dmg: Integer; 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 (not ([TGameOption.TEAM_HIT_TRACE, TGameOption.TEAM_DAMAGE] <= gGameSettings.Options)) and + (spawnerPlr.Team <> TEAM_NONE) and (spawnerPlr.Team = gPlayers[idx].Team) then + begin + if (spawnerPlr <> gPlayers[idx]) and not (TGameOption.TEAM_ABSORB_DAMAGE in gGameSettings.Options) then + dmg := Max(1, dmg div 2); + exit; + end; + 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 +1514,11 @@ begin if (xd = 0) and (yd = 0) then exit; + if (g_GetUIDType(SpawnerUID) = UID_PLAYER) then + spawnerPlr := g_Player_Get(SpawnerUID); + + dmg := indmg; + //wgunMonHash.reset(); //FIXME: clear hash on level change wgunHitHeap.clear(); wgunHitTimeUsed := 0; @@ -1632,7 +1659,7 @@ begin end; procedure g_Weapon_rocket(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; - Silent: Boolean = False); + Silent: Boolean = False; compat: Boolean = true); var find_id: DWORD; dx, dy: Integer; @@ -1653,7 +1680,10 @@ begin Obj.Rect.Width := SHOT_ROCKETLAUNCHER_WIDTH; Obj.Rect.Height := SHOT_ROCKETLAUNCHER_HEIGHT; - dx := IfThen(xd > x, -Obj.Rect.Width, 0); + if compat then + dx := IfThen(xd > x, -Obj.Rect.Width, 0) + else + dx := -(Obj.Rect.Width div 2); dy := -(Obj.Rect.Height div 2); ShotType := WEAPON_ROCKETLAUNCHER; @@ -1711,7 +1741,7 @@ begin end; procedure g_Weapon_plasma(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; - Silent: Boolean = False); + Silent: Boolean = False; compat: Boolean = true); var find_id, FramesID: DWORD; dx, dy: Integer; @@ -1732,7 +1762,10 @@ begin Obj.Rect.Width := SHOT_PLASMA_WIDTH; Obj.Rect.Height := SHOT_PLASMA_HEIGHT; - dx := IfThen(xd>x, -Obj.Rect.Width, 0); + if compat then + dx := IfThen(xd > x, -Obj.Rect.Width, 0) + else + dx := -(Obj.Rect.Width div 2); dy := -(Obj.Rect.Height div 2); ShotType := WEAPON_PLASMA; @@ -1750,7 +1783,7 @@ begin end; procedure g_Weapon_flame(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; - Silent: Boolean = False); + Silent: Boolean = False; compat: Boolean = true); var find_id: DWORD; dx, dy: Integer; @@ -1771,7 +1804,10 @@ begin Obj.Rect.Width := SHOT_FLAME_WIDTH; Obj.Rect.Height := SHOT_FLAME_HEIGHT; - dx := IfThen(xd>x, -Obj.Rect.Width, 0); + if compat then + dx := IfThen(xd > x, -Obj.Rect.Width, 0) + else + dx := -(Obj.Rect.Width div 2); dy := -(Obj.Rect.Height div 2); ShotType := WEAPON_FLAMETHROWER; @@ -1790,7 +1826,7 @@ begin end; procedure g_Weapon_ball1(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; - Silent: Boolean = False); + Silent: Boolean = False; compat: Boolean = true); var find_id, FramesID: DWORD; dx, dy: Integer; @@ -1811,7 +1847,10 @@ begin Obj.Rect.Width := 16; Obj.Rect.Height := 16; - dx := IfThen(xd>x, -Obj.Rect.Width, 0); + if compat then + dx := IfThen(xd > x, -Obj.Rect.Width, 0) + else + dx := -(Obj.Rect.Width div 2); dy := -(Obj.Rect.Height div 2); ShotType := WEAPON_IMP_FIRE; @@ -1829,7 +1868,7 @@ begin end; procedure g_Weapon_ball2(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; - Silent: Boolean = False); + Silent: Boolean = False; compat: Boolean = true); var find_id, FramesID: DWORD; dx, dy: Integer; @@ -1850,7 +1889,10 @@ begin Obj.Rect.Width := 16; Obj.Rect.Height := 16; - dx := IfThen(xd>x, -Obj.Rect.Width, 0); + if compat then + dx := IfThen(xd > x, -Obj.Rect.Width, 0) + else + dx := -(Obj.Rect.Width div 2); dy := -(Obj.Rect.Height div 2); ShotType := WEAPON_CACO_FIRE; @@ -1868,7 +1910,7 @@ begin end; procedure g_Weapon_ball7(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; - Silent: Boolean = False); + Silent: Boolean = False; compat: Boolean = true); var find_id, FramesID: DWORD; dx, dy: Integer; @@ -1886,10 +1928,13 @@ begin begin g_Obj_Init(@Obj); - Obj.Rect.Width := 32; + Obj.Rect.Width := 16; Obj.Rect.Height := 16; - dx := IfThen(xd>x, -Obj.Rect.Width, 0); + if compat then + dx := IfThen(xd > x, -Obj.Rect.Width, 0) + else + dx := -(Obj.Rect.Width div 2); dy := -(Obj.Rect.Height div 2); ShotType := WEAPON_BARON_FIRE; @@ -1907,7 +1952,7 @@ begin end; procedure g_Weapon_aplasma(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; - Silent: Boolean = False); + Silent: Boolean = False; compat: Boolean = true); var find_id, FramesID: DWORD; dx, dy: Integer; @@ -1928,7 +1973,10 @@ begin Obj.Rect.Width := 16; Obj.Rect.Height := 16; - dx := IfThen(xd>x, -Obj.Rect.Width, 0); + if compat then + dx := IfThen(xd > x, -Obj.Rect.Width, 0) + else + dx := -(Obj.Rect.Width div 2); dy := -(Obj.Rect.Height div 2); ShotType := WEAPON_BSP_FIRE; @@ -1947,7 +1995,7 @@ begin end; procedure g_Weapon_manfire(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; - Silent: Boolean = False); + Silent: Boolean = False; compat: Boolean = true); var find_id, FramesID: DWORD; dx, dy: Integer; @@ -1968,7 +2016,10 @@ begin Obj.Rect.Width := 32; Obj.Rect.Height := 32; - dx := IfThen(xd>x, -Obj.Rect.Width, 0); + if compat then + dx := IfThen(xd > x, -Obj.Rect.Width, 0) + else + dx := -(Obj.Rect.Width div 2); dy := -(Obj.Rect.Height div 2); ShotType := WEAPON_MANCUB_FIRE; @@ -1987,7 +2038,7 @@ begin end; procedure g_Weapon_bfgshot(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; - Silent: Boolean = False); + Silent: Boolean = False; compat: Boolean = true); var find_id, FramesID: DWORD; dx, dy: Integer; @@ -2008,7 +2059,10 @@ begin Obj.Rect.Width := SHOT_BFG_WIDTH; Obj.Rect.Height := SHOT_BFG_HEIGHT; - dx := IfThen(xd>x, -Obj.Rect.Width, 0); + if compat then + dx := IfThen(xd > x, -Obj.Rect.Width, 0) + else + dx := -(Obj.Rect.Width div 2); dy := -(Obj.Rect.Height div 2); ShotType := WEAPON_BFG; @@ -2047,8 +2101,16 @@ begin g_Weapon_gun(x, y, xd, yd, 1, 3, SpawnerUID, True); if gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF] then begin - g_Weapon_gun(x, y+1, xd, yd+1, 1, 3, SpawnerUID, False); - g_Weapon_gun(x, y-1, xd, yd-1, 1, 2, SpawnerUID, False); + if ABS(x-xd) >= ABS(y-yd) then + begin + g_Weapon_gun(x, y+1, xd, yd+1, 1, 3, SpawnerUID, False); + g_Weapon_gun(x, y-1, xd, yd-1, 1, 2, SpawnerUID, False); + end + else + begin + g_Weapon_gun(x+1, y, xd+1, yd, 1, 3, SpawnerUID, False); + g_Weapon_gun(x-1, y, xd-1, yd, 1, 2, SpawnerUID, False); + end; end; end; @@ -2062,30 +2124,39 @@ begin if (gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF]) and (g_GetUIDType(SpawnerUID) = UID_PLAYER) then begin - g_Weapon_gun(x, y+1, xd, yd+1, 1, 2, SpawnerUID, False); - g_Weapon_gun(x, y-1, xd, yd-1, 1, 2, SpawnerUID, False); + if ABS(x-xd) >= ABS(y-yd) then + begin + g_Weapon_gun(x, y+1, xd, yd+1, 1, 2, SpawnerUID, False); + g_Weapon_gun(x, y-1, xd, yd-1, 1, 2, SpawnerUID, False); + end + else + begin + g_Weapon_gun(x+1, y, xd+1, yd, 1, 2, SpawnerUID, False); + g_Weapon_gun(x-1, y, xd-1, yd, 1, 2, SpawnerUID, False); + end; end; end; procedure g_Weapon_shotgun(x, y, xd, yd: Integer; SpawnerUID: Word; Silent: Boolean = False); var - i, j: Integer; + i, j, k: Integer; begin if not Silent then if gSoundEffectsDF then g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN', x, y); for i := 0 to 9 do begin - j := Random(17)-8; // -8 .. 8 - g_Weapon_gun(x, y+j, xd, yd+j, IfThen(i mod 2 <> 0, 1, 0), 3, SpawnerUID, i=0); + j := 0; k := 0; + if ABS(x-xd) >= ABS(y-yd) then j := Random(17) - 8 else k := Random(17) - 8; // -8 .. 8 + g_Weapon_gun(x+k, y+j, xd+k, yd+j, IfThen(i mod 2 <> 0, 1, 0), 3, SpawnerUID, i=0); end; end; procedure g_Weapon_dshotgun(x, y, xd, yd: Integer; SpawnerUID: Word; Silent: Boolean = False); var - a, i, j: Integer; + a, i, j, k: Integer; begin if not Silent then g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN2', x, y); @@ -2093,8 +2164,9 @@ begin if gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF] then a := 25 else a := 20; for i := 0 to a do begin - j := Random(41)-20; // -20 .. 20 - g_Weapon_gun(x, y+j, xd, yd+j, IfThen(i mod 3 <> 0, 0, 1), 3, SpawnerUID, i=0); + j := 0; k := 0; + if ABS(x-xd) >= ABS(y-yd) then j := Random(41) - 20 else k := Random(41) - 20; // -20 .. 20 + g_Weapon_gun(x+k, y+j, xd+k, yd+j, IfThen(i mod 3 <> 0, 0, 1), 3, SpawnerUID, i=0); end; end; @@ -2205,19 +2277,17 @@ begin // Â âîäå øëåéô - ïóçûðè, â âîçäóõå øëåéô - äûì: if WordBool(st and MOVE_INWATER) then - g_GFX_Bubbles(Obj.X+(Obj.Rect.Width div 2), - Obj.Y+(Obj.Rect.Height div 2), - 1+Random(3), 16, 16) - else - if g_Frames_Get(_id, 'FRAMES_SMOKE') then - begin - Anim := TAnimation.Create(_id, False, 3); - Anim.Alpha := 150; - g_GFX_OnceAnim(Obj.X-14+Random(9), - Obj.Y+(Obj.Rect.Height div 2)-20+Random(9), - Anim, ONCEANIM_SMOKE); - Anim.Free(); - end; + begin + g_Game_Effect_Bubbles(cx, cy, 1+Random(3), 16, 16); + end + else if g_Frames_Get(_id, 'FRAMES_SMOKE') then + begin + Anim := TAnimation.Create(_id, False, 3); + Anim.Alpha := 150; + g_GFX_OnceAnim(Obj.X-14+Random(9), cy-20+Random(9), + Anim, ONCEANIM_SMOKE); + Anim.Free(); + end; // Ïîïàëè â êîãî-òî èëè â ñòåíó: if WordBool(st and (MOVE_HITWALL or MOVE_HITLAND or MOVE_HITCEIL)) or @@ -2340,7 +2410,8 @@ begin end; end else - g_GFX_Bubbles(cx, cy, 1+Random(3), 16, 16); + g_Game_Effect_Bubbles(cx, cy, 1+Random(3), 16, 16); + ShotType := 0; Continue; end; @@ -2542,6 +2613,12 @@ begin p.X := Obj.Rect.Width div 2; p.Y := Obj.Rect.Height div 2; + if Shots[i].ShotType = WEAPON_BFG then + begin + DEC(fX, 6); + DEC(fY, 7); + end; + if Animation <> nil then begin if (Shots[i].ShotType = WEAPON_BARON_FIRE) or