X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_weapons.pas;h=79f6f2566ae93038ec519b1f4e2726f1c8036de3;hb=52c1edc4aba4aa850742200a391845a91f3451ef;hp=97d127a46519fbf1a9c9589247cd468047e43b8b;hpb=1bddfaf7b6421f1659a6f211dfdb1dfaef5d5173;p=d2df-sdl.git diff --git a/src/game/g_weapons.pas b/src/game/g_weapons.pas index 97d127a..79f6f25 100644 --- a/src/game/g_weapons.pas +++ b/src/game/g_weapons.pas @@ -2,8 +2,7 @@ * * 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, either version 3 of the License, or - * (at your option) any later version. + * 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 @@ -20,7 +19,7 @@ unit g_weapons; interface uses - SysUtils, Classes, + SysUtils, Classes, mempool, g_textures, g_basic, e_graphics, g_phys, xprofiler; @@ -73,6 +72,7 @@ procedure g_Weapon_dshotgun(x, y, xd, yd: Integer; SpawnerUID: Word; Silent: Boo function g_Weapon_Explode(X, Y: Integer; rad: Integer; SpawnerUID: Word): Boolean; procedure g_Weapon_BFG9000(X, Y: Integer; SpawnerUID: Word); +procedure g_Weapon_PreUpdate(); procedure g_Weapon_Update(); procedure g_Weapon_Draw(); function g_Weapon_Danger(UID: Word; X, Y: Integer; Width, Height: Word; Time: Byte): Boolean; @@ -462,12 +462,12 @@ begin if (t <> HIT_FLAME) or (m.FFireTime = 0) or (vx <> 0) or (vy <> 0) then Result := m.Damage(d, vx, vy, SpawnerUID, t) else - Result := True; + Result := (gLMSRespawn = LMS_RESPAWN_NONE); // don't hit monsters when it's warmup time if t = HIT_FLAME then m.CatchFire(SpawnerUID); end else - Result := True; + Result := (gLMSRespawn = LMS_RESPAWN_NONE); // don't hit monsters when it's warmup time end; @@ -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; @@ -738,6 +738,8 @@ begin end; end; + Shots[find_id].Obj.oldX := X; + Shots[find_id].Obj.oldY := Y; Shots[find_id].Obj.X := X; Shots[find_id].Obj.Y := Y; Shots[find_id].Obj.Vel.X := XV; @@ -763,6 +765,8 @@ begin if a = 0 then a := 1; + Shots[i].Obj.oldX := x; + Shots[i].Obj.oldY := y; Shots[i].Obj.X := x; Shots[i].Obj.Y := y; Shots[i].Obj.Vel.X := (xd*s) div a; @@ -872,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; @@ -1046,7 +1050,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; @@ -1117,6 +1121,7 @@ begin g_Sound_CreateWADEx('SOUND_WEAPON_FIRECGUN', GameWAD+':SOUNDS\FIRECGUN'); g_Sound_CreateWADEx('SOUND_WEAPON_FIREBFG', GameWAD+':SOUNDS\FIREBFG'); g_Sound_CreateWADEx('SOUND_FIRE', GameWAD+':SOUNDS\FIRE'); + g_Sound_CreateWADEx('SOUND_IGNITE', GameWAD+':SOUNDS\IGNITE'); g_Sound_CreateWADEx('SOUND_WEAPON_STARTFIREBFG', GameWAD+':SOUNDS\STARTFIREBFG'); g_Sound_CreateWADEx('SOUND_WEAPON_EXPLODEROCKET', GameWAD+':SOUNDS\EXPLODEROCKET'); g_Sound_CreateWADEx('SOUND_WEAPON_EXPLODEBFG', GameWAD+':SOUNDS\EXPLODEBFG'); @@ -1126,6 +1131,9 @@ begin g_Sound_CreateWADEx('SOUND_WEAPON_FIREBALL', GameWAD+':SOUNDS\FIREBALL'); g_Sound_CreateWADEx('SOUND_WEAPON_EXPLODEBALL', GameWAD+':SOUNDS\EXPLODEBALL'); g_Sound_CreateWADEx('SOUND_WEAPON_FIREREV', GameWAD+':SOUNDS\FIREREV'); + g_Sound_CreateWADEx('SOUND_WEAPON_FLAMEON', GameWAD+':SOUNDS\STARTFLM'); + g_Sound_CreateWADEx('SOUND_WEAPON_FLAMEOFF', GameWAD+':SOUNDS\STOPFLM'); + g_Sound_CreateWADEx('SOUND_WEAPON_FLAMEWORK', GameWAD+':SOUNDS\WORKFLM'); g_Sound_CreateWADEx('SOUND_PLAYER_JETFLY', GameWAD+':SOUNDS\WORKJETPACK'); g_Sound_CreateWADEx('SOUND_PLAYER_JETON', GameWAD+':SOUNDS\STARTJETPACK'); g_Sound_CreateWADEx('SOUND_PLAYER_JETOFF', GameWAD+':SOUNDS\STOPJETPACK'); @@ -1183,6 +1191,7 @@ begin g_Sound_Delete('SOUND_WEAPON_FIRECGUN'); g_Sound_Delete('SOUND_WEAPON_FIREBFG'); g_Sound_Delete('SOUND_FIRE'); + g_Sound_Delete('SOUND_IGNITE'); g_Sound_Delete('SOUND_WEAPON_STARTFIREBFG'); g_Sound_Delete('SOUND_WEAPON_EXPLODEROCKET'); g_Sound_Delete('SOUND_WEAPON_EXPLODEBFG'); @@ -1192,6 +1201,9 @@ begin g_Sound_Delete('SOUND_WEAPON_FIREBALL'); g_Sound_Delete('SOUND_WEAPON_EXPLODEBALL'); g_Sound_Delete('SOUND_WEAPON_FIREREV'); + g_Sound_Delete('SOUND_WEAPON_FLAMEON'); + g_Sound_Delete('SOUND_WEAPON_FLAMEOFF'); + g_Sound_Delete('SOUND_WEAPON_FLAMEWORK'); g_Sound_Delete('SOUND_PLAYER_JETFLY'); g_Sound_Delete('SOUND_PLAYER_JETON'); g_Sound_Delete('SOUND_PLAYER_JETOFF'); @@ -1440,13 +1452,12 @@ var end; end; - function sqchecker (mon: TMonster; tag: Integer): Boolean; + procedure sqchecker (mon: TMonster); var mx, my, mw, mh: Integer; inx, iny: Integer; distSq: Integer; begin - result := false; // don't stop mon.getMapBox(mx, my, mw, mh); if lineAABBIntersects(x0, y0, x2, y2, mx, my, mw, mh, inx, iny) then begin @@ -1468,6 +1479,8 @@ var {$IF DEFINED(D2F_DEBUG)} stt: UInt64; {$ENDIF} + mit: PMonster; + it: TMonsterGrid.Iter; begin (* if not gwep_debug_fast_trace then @@ -1522,7 +1535,11 @@ begin if playerPossibleHit() then exit; // instant hit // collect monsters - g_Mons_AlongLine(x, y, x2, y2, sqchecker); + //g_Mons_AlongLine(x, y, x2, y2, sqchecker); + + it := monsGrid.forEachAlongLine(x, y, x2, y2, -1); + for mit in it do sqchecker(mit^); + it.release(); // here, we collected all monsters and players in `wgunHitHeap` and `wgunHitTime` // also, if `wallWasHit` is `true`, then `wallHitX` and `wallHitY` contains spark coords @@ -2081,6 +2098,19 @@ begin end; end; +procedure g_Weapon_PreUpdate(); +var + i: Integer; +begin + if Shots = nil then Exit; + for i := 0 to High(Shots) do + if Shots[i].ShotType <> 0 then + begin + Shots[i].Obj.oldX := Shots[i].Obj.X; + Shots[i].Obj.oldY := Shots[i].Obj.Y; + end; +end; + procedure g_Weapon_Update(); var i, a, h, cx, cy, oldvx, oldvy, tf: Integer; @@ -2146,7 +2176,7 @@ begin if Stopped = 0 then begin - st := g_Obj_Move(@Obj, False, spl); + st := g_Obj_Move_Projectile(@Obj, False, spl); end else begin @@ -2333,7 +2363,7 @@ begin Stopped := MOVE_HITCEIL; end; - a := IfThen(Stopped = 0, 3, 1); + a := IfThen(Stopped = 0, 10, 1); // Åñëè â êîãî-òî ïîïàëè if g_Weapon_Hit(@Obj, a, SpawnerUID, HIT_FLAME, False) <> 0 then begin @@ -2489,7 +2519,7 @@ end; procedure g_Weapon_Draw(); var - i: Integer; + i, fX, fY: Integer; a: SmallInt; p: TDFPoint; begin @@ -2508,6 +2538,7 @@ begin else a := 0; + Obj.lerp(gLerpFactor, fX, fY); p.X := Obj.Rect.Width div 2; p.Y := Obj.Rect.Height div 2; @@ -2516,16 +2547,16 @@ begin if (Shots[i].ShotType = WEAPON_BARON_FIRE) or (Shots[i].ShotType = WEAPON_MANCUB_FIRE) or (Shots[i].ShotType = WEAPON_SKEL_FIRE) then - Animation.DrawEx(Obj.X, Obj.Y, TMirrorType.None, p, a) + Animation.DrawEx(fX, fY, TMirrorType.None, p, a) else - Animation.Draw(Obj.X, Obj.Y, TMirrorType.None); + Animation.Draw(fX, fY, TMirrorType.None); end else if TextureID <> 0 then begin if (Shots[i].ShotType = WEAPON_ROCKETLAUNCHER) then - e_DrawAdv(TextureID, Obj.X, Obj.Y, 0, True, False, a, @p, TMirrorType.None) + e_DrawAdv(TextureID, fX, fY, 0, True, False, a, @p, TMirrorType.None) else if (Shots[i].ShotType <> WEAPON_FLAMETHROWER) then - e_Draw(TextureID, Obj.X, Obj.Y, 0, True, False); + e_Draw(TextureID, fX, fY, 0, True, False); end; if g_debug_Frames then