X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_weapons.pas;h=9fde2f50cd63e93be392051a3dfd29760f286562;hb=10c770e6551f77ef4382930e7800ab93ea3e4047;hp=0c8788129a170f7def99259fbbe97c1e43e92ce2;hpb=20cbf5c1dd17b4fde0968bb6583d1c91914d5e49;p=d2df-sdl.git diff --git a/src/game/g_weapons.pas b/src/game/g_weapons.pas index 0c87881..9fde2f5 100644 --- a/src/game/g_weapons.pas +++ b/src/game/g_weapons.pas @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *) -{$MODE DELPHI} +{$INCLUDE ../shared/a_modes.inc} unit g_weapons; interface @@ -45,8 +45,11 @@ type TextureID: DWORD; Timeout: DWORD; Stopped: Byte; + + procedure positionChanged (); //WARNING! call this after monster position was changed, or coldet will not work right! end; + var Shots: array of TShot = nil; LastShotID: Integer = 0; @@ -88,6 +91,8 @@ procedure g_Weapon_DestroyShot(I: Integer; X, Y: Integer; Loud: Boolean = True); procedure g_Weapon_SaveState(var Mem: TBinMemoryWriter); procedure g_Weapon_LoadState(var Mem: TBinMemoryReader); +procedure g_Weapon_AddDynLights(); + const WEAPON_KASTET = 0; WEAPON_SAW = 1; @@ -114,7 +119,7 @@ const implementation uses - Math, g_map, g_player, g_gfx, g_sound, g_main, + Math, g_map, g_player, g_gfx, g_sound, g_main, g_panel, g_console, SysUtils, g_options, g_game, g_triggers, MAPDEF, e_log, g_monsters, g_saveload, g_language, g_netmsg; @@ -143,7 +148,7 @@ const SHOT_FLAME_WIDTH = 4; SHOT_FLAME_HEIGHT = 4; - SHOT_FLAME_LIFETIME = 180; + SHOT_FLAME_LIFETIME = 180; SHOT_SIGNATURE = $544F4853; // 'SHOT' @@ -238,68 +243,97 @@ begin WaterArray := nil; end; + +var + chkTrap_pl: array [0..256] of Integer; + chkTrap_mn: array [0..65535] of TMonster; + procedure CheckTrap(ID: DWORD; dm: Integer; t: Byte); var - a, b, c, d, i1, i2: Integer; - pl, mn: WArray; + //a, b, c, d, i1, i2: Integer; + //chkTrap_pl, chkTrap_mn: WArray; + plaCount: Integer = 0; + mnaCount: Integer = 0; + frameId: DWord; + + { + function monsWaterCheck (monidx: Integer; mon: TMonster): Boolean; + begin + result := false; // don't stop + if mon.Live and mon.Collide(gWater[WaterMap[a][c]]) and (not InWArray(monidx, chkTrap_mn)) and (i2 < 1023) then //FIXME + begin + i2 += 1; + chkTrap_mn[i2] := monidx; + end; + end; + } + + function monsWaterCheck (monidx: Integer; mon: TMonster): Boolean; + begin + result := false; // don't stop + if (mon.trapCheckFrameId <> frameId) then + begin + mon.trapCheckFrameId := frameId; + chkTrap_mn[mnaCount] := mon; + Inc(mnaCount); + end; + end; + +var + a, b, c, d, f: Integer; + pan: TPanel; begin if (gWater = nil) or (WaterMap = nil) then Exit; - i1 := -1; - i2 := -1; + frameId := g_Mons_getNewTrapFrameId(); + + //i1 := -1; + //i2 := -1; - SetLength(pl, 1024); - SetLength(mn, 1024); - for d := 0 to 1023 do pl[d] := $FFFF; - for d := 0 to 1023 do mn[d] := $FFFF; + //SetLength(chkTrap_pl, 1024); + //SetLength(chkTrap_mn, 1024); + //for d := 0 to 1023 do chkTrap_pl[d] := $FFFF; + //for d := 0 to 1023 do chkTrap_mn[d] := $FFFF; for a := 0 to High(WaterMap) do + begin for b := 0 to High(WaterMap[a]) do begin - if not g_Obj_Collide(gWater[WaterMap[a][b]].X, gWater[WaterMap[a][b]].Y, - gWater[WaterMap[a][b]].Width, gWater[WaterMap[a][b]].Height, - @Shots[ID].Obj) then Continue; + pan := gWater[WaterMap[a][b]]; + if not g_Obj_Collide(pan.X, pan.Y, pan.Width, pan.Height, @Shots[ID].Obj) then continue; for c := 0 to High(WaterMap[a]) do begin - if gPlayers <> nil then + pan := gWater[WaterMap[a][c]]; + for d := 0 to High(gPlayers) do begin - for d := 0 to High(gPlayers) do - if (gPlayers[d] <> nil) and (gPlayers[d].Live) then - if gPlayers[d].Collide(gWater[WaterMap[a][c]]) then - if not InWArray(d, pl) then - if i1 < 1023 then - begin - i1 := i1+1; - pl[i1] := d; - end; + if (gPlayers[d] <> nil) and (gPlayers[d].Live) then + begin + if gPlayers[d].Collide(pan) then + begin + f := 0; + while (f < plaCount) and (chkTrap_pl[f] <> d) do Inc(f); + if (f = plaCount) then + begin + chkTrap_pl[plaCount] := d; + Inc(plaCount); + if (plaCount = Length(chkTrap_pl)) then break; + end; + end; + end; end; - if gMonsters <> nil then - begin - for d := 0 to High(gMonsters) do - if (gMonsters[d] <> nil) and (gMonsters[d].Live) then - if gMonsters[d].Collide(gWater[WaterMap[a][c]]) then - if not InWArray(d, mn) then - if i2 < 1023 then - begin - i2 := i2+1; - mn[i2] := d; - end; - end; + //g_Mons_ForEach(monsWaterCheck); + g_Mons_ForEachAtAlive(pan.X, pan.Y, pan.Width, pan.Height, monsWaterCheck); end; - if i1 <> -1 then - for d := 0 to i1 do - gPlayers[pl[d]].Damage(dm, Shots[ID].SpawnerUID, 0, 0, t); - - if i2 <> -1 then - for d := 0 to i2 do - gMonsters[mn[d]].Damage(dm, 0, 0, Shots[ID].SpawnerUID, t); + for f := 0 to plaCount-1 do gPlayers[chkTrap_pl[f]].Damage(dm, Shots[ID].SpawnerUID, 0, 0, t); + for f := 0 to mnaCount-1 do chkTrap_mn[f].Damage(dm, 0, 0, Shots[ID].SpawnerUID, t); end; + end; - pl := nil; - mn := nil; + //chkTrap_pl := nil; + //chkTrap_mn := nil; end; function HitMonster(m: TMonster; d: Integer; vx, vy: Integer; SpawnerUID: Word; t: Byte): Boolean; @@ -312,9 +346,9 @@ begin tt := g_GetUIDType(SpawnerUID); if tt = UID_MONSTER then begin - mon := g_Monsters_Get(SpawnerUID); + mon := g_Monsters_ByUID(SpawnerUID); if mon <> nil then - mt := g_Monsters_Get(SpawnerUID).MonsterType + mt := g_Monsters_ByUID(SpawnerUID).MonsterType else mt := 0; end @@ -372,7 +406,7 @@ begin if (p.UID = SpawnerUID) and (t <> HIT_ROCKET) and (t <> HIT_ELECTRO) then Exit; - if g_Game_IsServer then + if g_Game_IsServer then begin if (t <> HIT_FLAME) or (p.FFireTime = 0) or (vx <> 0) or (vy <> 0) then p.Damage(d, SpawnerUID, vx, vy, t); @@ -385,6 +419,30 @@ end; function GunHit(X, Y: Integer; vx, vy: Integer; dmg: Integer; SpawnerUID: Word; AllowPush: Boolean): Byte; + + {function monsCheck (monidx: Integer; mon: TMonster): Boolean; + begin + result := false; // don't stop + if mon.Live and mon.Collide(X, Y) then + begin + if HitMonster(mon, dmg, vx*10, vy*10-3, SpawnerUID, HIT_SOME) then + begin + if AllowPush then mon.Push(vx, vy); + result := true; + end; + end; + end;} + + function monsCheck (monidx: Integer; mon: TMonster): Boolean; + begin + result := false; // don't stop + if HitMonster(mon, dmg, vx*10, vy*10-3, SpawnerUID, HIT_SOME) then + begin + if AllowPush then mon.Push(vx, vy); + result := true; + end; + end; + var i, h: Integer; begin @@ -403,20 +461,30 @@ begin if Result <> 0 then Exit; - h := High(gMonsters); + //if g_Mons_ForEach(monsCheck) then result := 2; + if g_Mons_ForEachAtAlive(X, Y, 1, 1, monsCheck) then result := 2; +end; - if h <> -1 then - for i := 0 to h do - if (gMonsters[i] <> nil) and gMonsters[i].Live and gMonsters[i].Collide(X, Y) then - if HitMonster(gMonsters[i], dmg, vx*10, vy*10-3, SpawnerUID, HIT_SOME) then +procedure g_Weapon_BFG9000(X, Y: Integer; SpawnerUID: Word); + + function monsCheck (monidx: Integer; mon: TMonster): Boolean; + begin + result := false; // don't stop + if (mon.Live) and (mon.UID <> SpawnerUID) then + begin + with mon do + begin + if (g_PatchLength(X, Y, Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2), + Obj.Y+Obj.Rect.Y+(Obj.Rect.Height div 2)) <= SHOT_BFG_RADIUS) and + 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 - if AllowPush then gMonsters[i].Push(vx, vy); - Result := 2; - Exit; + if HitMonster(mon, 50, 0, 0, SpawnerUID, HIT_SOME) then mon.BFGHit(); end; -end; + end; + end; + end; -procedure g_Weapon_BFG9000(X, Y: Integer; SpawnerUID: Word); var i, h: Integer; st: Byte; @@ -465,17 +533,8 @@ begin gPlayers[i].BFGHit(); end; - h := High(gMonsters); - - if h <> -1 then - for i := 0 to h do - if (gMonsters[i] <> nil) and (gMonsters[i].Live) and (gMonsters[i].UID <> SpawnerUID) then - with gMonsters[i] do - if (g_PatchLength(X, Y, Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2), - Obj.Y+Obj.Rect.Y+(Obj.Rect.Height div 2)) <= SHOT_BFG_RADIUS) and - 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 - if HitMonster(gMonsters[i], 50, 0, 0, SpawnerUID, HIT_SOME) then gMonsters[i].BFGHit(); + //FIXME + g_Mons_ForEach(monsCheck); end; function g_Weapon_CreateShot(I: Integer; ShotType: Byte; Spawner, TargetUID: Word; X, Y, XV, YV: Integer): LongWord; @@ -553,7 +612,7 @@ begin ShotType := WEAPON_FLAMETHROWER; Animation := nil; TextureID := 0; - Stopped := 0; + g_Frames_Get(TextureID, 'FRAMES_FLAME'); end; end; @@ -662,6 +721,10 @@ begin Shots[find_id].Obj.Accel.X := 0; Shots[find_id].Obj.Accel.Y := 0; Shots[find_id].SpawnerUID := Spawner; + if (ShotType = WEAPON_FLAMETHROWER) and (XV = 0) and (YV = 0) then + Shots[find_id].Stopped := 255 + else + Shots[find_id].Stopped := 0; Result := find_id; end; @@ -682,9 +745,10 @@ begin Shots[i].Obj.Vel.Y := (yd*s) div a; Shots[i].Obj.Accel.X := 0; Shots[i].Obj.Accel.Y := 0; + Shots[i].Stopped := 0; if Shots[i].ShotType in [WEAPON_ROCKETLAUNCHER, WEAPON_BFG] then Shots[i].Timeout := 900 // ~25 sec - else + else begin if Shots[i].ShotType = WEAPON_FLAMETHROWER then Shots[i].Timeout := SHOT_FLAME_LIFETIME @@ -720,8 +784,9 @@ var if ChkTeam then if HitPlayer(gPlayers[i], d, obj^.Vel.X, obj^.Vel.Y, SpawnerUID, t) then begin - gPlayers[i].Push((obj^.Vel.X+obj^.Accel.X)*IfThen(t = HIT_BFG, 8, 1) div 4, - (obj^.Vel.Y+obj^.Accel.Y)*IfThen(t = HIT_BFG, 8, 1) div 4); + if t <> HIT_FLAME then + gPlayers[i].Push((obj^.Vel.X+obj^.Accel.X)*IfThen(t = HIT_BFG, 8, 1) div 4, + (obj^.Vel.Y+obj^.Accel.Y)*IfThen(t = HIT_BFG, 8, 1) div 4); if t = HIT_BFG then g_Game_DelayEvent(DE_BFGHIT, 1000, SpawnerUID); Result := True; @@ -729,24 +794,46 @@ var end; end; end; - function MonsterHit(): Boolean; - var - i: Integer; - begin - Result := False; - h := High(gMonsters); - if h <> -1 then - for i := 0 to h do - if (gMonsters[i] <> nil) and gMonsters[i].Live and g_Obj_Collide(obj, @gMonsters[i].Obj) then - if HitMonster(gMonsters[i], d, obj^.Vel.X, obj^.Vel.Y, SpawnerUID, t) then - begin - gMonsters[i].Push((obj^.Vel.X+obj^.Accel.X)*IfThen(t = HIT_BFG, 8, 1) div 4, + { + function monsCheckHit (monidx: Integer; mon: TMonster): Boolean; + begin + result := false; // don't stop + if mon.Live and g_Obj_Collide(obj, @mon.Obj) then + begin + if HitMonster(mon, d, obj^.Vel.X, obj^.Vel.Y, SpawnerUID, t) then + begin + if (t <> HIT_FLAME) then + begin + mon.Push((obj^.Vel.X+obj^.Accel.X)*IfThen(t = HIT_BFG, 8, 1) div 4, (obj^.Vel.Y+obj^.Accel.Y)*IfThen(t = HIT_BFG, 8, 1) div 4); - Result := True; - break; - end; + end; + result := True; + end; + end; + end; + } + + function monsCheckHit (monidx: Integer; mon: TMonster): Boolean; + begin + result := false; // don't stop + if HitMonster(mon, d, obj.Vel.X, obj.Vel.Y, SpawnerUID, t) then + begin + if (t <> HIT_FLAME) then + begin + mon.Push((obj.Vel.X+obj.Accel.X)*IfThen(t = HIT_BFG, 8, 1) div 4, + (obj.Vel.Y+obj.Accel.Y)*IfThen(t = HIT_BFG, 8, 1) div 4); + end; + result := true; + end; + end; + + function MonsterHit(): Boolean; + begin + //result := g_Mons_ForEach(monsCheckHit); + result := g_Mons_ForEachAtAlive(obj.X+obj.Rect.X, obj.Y+obj.Rect.Y, obj.Rect.Width, obj.Rect.Height, monsCheckHit); end; + begin Result := 0; @@ -835,17 +922,50 @@ begin case g_GetUIDType(UID) of UID_PLAYER: Result := HitPlayer(g_Player_Get(UID), d, 0, 0, SpawnerUID, t); - UID_MONSTER: Result := HitMonster(g_Monsters_Get(UID), d, 0, 0, SpawnerUID, t); + UID_MONSTER: Result := HitMonster(g_Monsters_ByUID(UID), d, 0, 0, SpawnerUID, t); else Exit; end; end; function g_Weapon_Explode(X, Y: Integer; rad: Integer; SpawnerUID: Word): Boolean; var - i, h, r, dx, dy, m, mm: Integer; + r: Integer; // squared radius + + function monsExCheck (monidx: Integer; mon: TMonster): Boolean; + var + dx, dy, mm: Integer; + begin + result := false; // don't stop + begin + dx := mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2)-X; + dy := mon.Obj.Y+mon.Obj.Rect.Y+(mon.Obj.Rect.Height div 2)-Y; + + if dx > 1000 then dx := 1000; + if dy > 1000 then dy := 1000; + + if (dx*dx+dy*dy < r) then + begin + //m := PointToRect(X, Y, Obj.X+Obj.Rect.X, Obj.Y+Obj.Rect.Y, Obj.Rect.Width, Obj.Rect.Height); + //e_WriteLog(Format('explo monster #%d: x=%d; y=%d; rad=%d; dx=%d; dy=%d', [monidx, X, Y, rad, dx, dy]), MSG_NOTIFY); + + mm := Max(abs(dx), abs(dy)); + if mm = 0 then mm := 1; + + if mon.Live then + begin + HitMonster(mon, ((mon.Obj.Rect.Width div 4)*10*(rad-mm)) div rad, 0, 0, SpawnerUID, HIT_ROCKET); + end; + + mon.Push((dx*7) div mm, (dy*7) div mm); + end; + end; + end; + +var + i, h, dx, dy, m, mm: Integer; _angle: SmallInt; begin - Result := False; + result := false; g_Triggers_PressC(X, Y, rad, SpawnerUID, ACTIVATE_SHOT); @@ -877,34 +997,8 @@ begin end; end; - h := High(gMonsters); - - if h <> -1 then - for i := 0 to h do - if gMonsters[i] <> nil then - with gMonsters[i] do - begin - dx := Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2)-X; - dy := Obj.Y+Obj.Rect.Y+(Obj.Rect.Height div 2)-Y; - - if dx > 1000 then dx := 1000; - if dy > 1000 then dy := 1000; - - if dx*dx+dy*dy < r then - begin - //m := PointToRect(X, Y, Obj.X+Obj.Rect.X, Obj.Y+Obj.Rect.Y, - // Obj.Rect.Width, Obj.Rect.Height); - - mm := Max(abs(dx), abs(dy)); - if mm = 0 then mm := 1; - - if gMonsters[i].Live then - HitMonster(gMonsters[i], ((gMonsters[i].Obj.Rect.Width div 4)*10*(rad-mm)) div rad, - 0, 0, SpawnerUID, HIT_ROCKET); - - gMonsters[i].Push((dx*7) div mm, (dy*7) div mm); - end; - end; + //g_Mons_ForEach(monsExCheck); + g_Mons_ForEachAt(X-(rad+32), Y-(rad+32), (rad+32)*2, (rad+32)*2, monsExCheck); h := High(gCorpses); @@ -952,6 +1046,7 @@ begin Obj.Y+Obj.Rect.Y+(Obj.Rect.Height div 2), X, Y); g_Obj_PushA(@Obj, Round(15*(rad-m)/rad), _angle); + positionChanged(); // this updates spatial accelerators end; end; end; @@ -1349,7 +1444,7 @@ end; procedure g_Weapon_flame(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False); var - find_id, FramesID: DWORD; + find_id: DWORD; dx, dy: Integer; begin if WID < 0 then @@ -1377,7 +1472,7 @@ begin triggers := nil; Animation := nil; TextureID := 0; - Stopped := 0; + g_Frames_Get(TextureID, 'FRAMES_FLAME'); end; Shots[find_id].SpawnerUID := SpawnerUID; @@ -1532,7 +1627,7 @@ begin throw(find_id, x+dx, y+dy, xd+dx, yd+dy, 16); triggers := nil; - + g_Frames_Get(FramesID, 'FRAMES_WEAPON_BSPFIRE'); Animation := TAnimation.Create(FramesID, True, 4); end; @@ -1706,6 +1801,7 @@ var o: TObj; spl: Boolean; Loud: Boolean; + tcx, tcy: Integer; begin if Shots = nil then Exit; @@ -1723,7 +1819,7 @@ begin oldvx := Obj.Vel.X; oldvy := Obj.Vel.Y; // Àêòèâèðîâàòü òðèããåðû ïî ïóòè (êðîìå óæå àêòèâèðîâàííûõ): - if g_Game_IsServer then + if (Stopped = 0) and g_Game_IsServer then t := g_Triggers_PressR(Obj.X, Obj.Y, Obj.Rect.Width, Obj.Rect.Height, SpawnerUID, ACTIVATE_SHOT, triggers) else @@ -1757,7 +1853,15 @@ begin (ShotType <> WEAPON_BSP_FIRE) and (ShotType <> WEAPON_FLAMETHROWER); - st := g_Obj_Move(@Obj, False, spl); + if Stopped = 0 then + begin + st := g_Obj_Move(@Obj, False, spl); + end + else + begin + st := 0; + end; + positionChanged(); // this updates spatial accelerators if WordBool(st and MOVE_FALLOUT) or (Obj.X < -1000) or (Obj.X > gMapInfo.Width+1000) or (Obj.Y < -1000) then @@ -1811,6 +1915,7 @@ begin Anim := TAnimation.Create(TextureID, False, 8); Anim.Blending := False; g_GFX_OnceAnim((Obj.X+32)-58, (Obj.Y+8)-36, Anim); + g_DynLightExplosion((Obj.X+32), (Obj.Y+8), 64, 1, 0, 0); Anim.Free(); end; end @@ -1821,6 +1926,7 @@ begin Anim := TAnimation.Create(TextureID, False, 6); Anim.Blending := False; g_GFX_OnceAnim(cx-64, cy-64, Anim); + g_DynLightExplosion(cx, cy, 64, 1, 0, 0); Anim.Free(); end; end; @@ -1878,6 +1984,7 @@ begin Anim.Blending := False; g_GFX_OnceAnim(cx-16, cy-16, Anim); Anim.Free(); + g_DynLightExplosion(cx, cy, 32, 0, 0.5, 0.5); end; g_Sound_PlayExAt('SOUND_WEAPON_EXPLODEPLASMA', Obj.X, Obj.Y); @@ -1903,8 +2010,10 @@ begin begin Anim := TAnimation.Create(_id, False, 3); Anim.Alpha := 0; - g_GFX_OnceAnim(cx-4+Random(8)-(Anim.Width div 2), - cy-4+Random(8)-(Anim.Height div 2), + tcx := Random(8); + tcy := Random(8); + g_GFX_OnceAnim(cx-4+tcx-(Anim.Width div 2), + cy-4+tcy-(Anim.Height div 2), Anim, ONCEANIM_SMOKE); Anim.Free(); end; @@ -1948,25 +2057,19 @@ begin else tf := 3; - if (gTime mod tf = 0) and g_Frames_Get(_id, 'FRAMES_FLAME') then + if (gTime mod tf = 0) then begin - Anim := TAnimation.Create(_id, False, 2 + Random(2)); + Anim := TAnimation.Create(TextureID, False, 2 + Random(2)); Anim.Alpha := 0; case Stopped of - 0: g_GFX_OnceAnim(cx-4+Random(8)-(Anim.Width div 2), - cy-4+Random(8)-(Anim.Height div 2), - Anim, ONCEANIM_SMOKE); - MOVE_HITWALL: g_GFX_OnceAnim(cx-4+Random(8)-(Anim.Width div 2), - cy-12+Random(24)-(Anim.Height div 2), - Anim, ONCEANIM_SMOKE); - MOVE_HITLAND: g_GFX_OnceAnim(cx-12+Random(24)-(Anim.Width div 2), - cy-10+Random(8)-(Anim.Height div 2), - Anim, ONCEANIM_SMOKE); - MOVE_HITCEIL: g_GFX_OnceAnim(cx-12+Random(24)-(Anim.Width div 2), - cy+6+Random(8)-(Anim.Height div 2), - Anim, ONCEANIM_SMOKE); + MOVE_HITWALL: begin tcx := cx-4+Random(8); tcy := cy-12+Random(24); end; + MOVE_HITLAND: begin tcx := cx-12+Random(24); tcy := cy-10+Random(8); end; + MOVE_HITCEIL: begin tcx := cx-12+Random(24); tcy := cy+6+Random(8); end; + else begin tcx := cx-4+Random(8); tcy := cy-4+Random(8); end; end; + g_GFX_OnceAnim(tcx-(Anim.Width div 2), tcy-(Anim.Height div 2), Anim, ONCEANIM_SMOKE); Anim.Free(); + //g_DynLightExplosion(tcx, tcy, 1, 1, 0.8, 0.3); end; end; @@ -1996,6 +2099,7 @@ begin Anim.Blending := False; g_GFX_OnceAnim(cx-64, cy-64, Anim); Anim.Free(); + g_DynLightExplosion(cx, cy, 96, 0, 1, 0); end; g_Sound_PlayExAt('SOUND_WEAPON_EXPLODEBFG', Obj.X, Obj.Y); @@ -2129,7 +2233,7 @@ begin begin if (Shots[i].ShotType = WEAPON_ROCKETLAUNCHER) then e_DrawAdv(TextureID, Obj.X, Obj.Y, 0, True, False, a, @p, M_NONE) - else + else if (Shots[i].ShotType <> WEAPON_FLAMETHROWER) then e_Draw(TextureID, Obj.X, Obj.Y, 0, True, False); end; @@ -2420,4 +2524,42 @@ begin end; end; + +procedure g_Weapon_AddDynLights(); +var + i: Integer; +begin + if Shots = nil then Exit; + for i := 0 to High(Shots) do + begin + if Shots[i].ShotType = 0 then continue; + if (Shots[i].ShotType = WEAPON_ROCKETLAUNCHER) or + (Shots[i].ShotType = WEAPON_BARON_FIRE) or + (Shots[i].ShotType = WEAPON_MANCUB_FIRE) or + (Shots[i].ShotType = WEAPON_SKEL_FIRE) or + (Shots[i].ShotType = WEAPON_IMP_FIRE) or + (Shots[i].ShotType = WEAPON_CACO_FIRE) or + (Shots[i].ShotType = WEAPON_MANCUB_FIRE) or + (Shots[i].ShotType = WEAPON_BSP_FIRE) or + (Shots[i].ShotType = WEAPON_PLASMA) or + (Shots[i].ShotType = WEAPON_BFG) or + (Shots[i].ShotType = WEAPON_FLAMETHROWER) or + false then + begin + if (Shots[i].ShotType = WEAPON_PLASMA) then + g_AddDynLight(Shots[i].Obj.X+(Shots[i].Obj.Rect.Width div 2), Shots[i].Obj.Y+(Shots[i].Obj.Rect.Height div 2), 128, 0, 0.3, 1, 0.4) + else if (Shots[i].ShotType = WEAPON_BFG) then + g_AddDynLight(Shots[i].Obj.X+(Shots[i].Obj.Rect.Width div 2), Shots[i].Obj.Y+(Shots[i].Obj.Rect.Height div 2), 128, 0, 1, 0, 0.5) + else if (Shots[i].ShotType = WEAPON_FLAMETHROWER) then + g_AddDynLight(Shots[i].Obj.X+(Shots[i].Obj.Rect.Width div 2), Shots[i].Obj.Y+(Shots[i].Obj.Rect.Height div 2), 42, 1, 0.8, 0, 0.4) + else + g_AddDynLight(Shots[i].Obj.X+(Shots[i].Obj.Rect.Width div 2), Shots[i].Obj.Y+(Shots[i].Obj.Rect.Height div 2), 128, 1, 0, 0, 0.4); + end; + end; +end; + + +procedure TShot.positionChanged (); begin end; + + end.