X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_weapons.pas;h=182207f233740454ac355b5034c59625b78aea0b;hb=20114d602d19e4e913ea1a7c22f2031bd7f54677;hp=ca4630ed2023d55edc648994e9021a736d8b9b53;hpb=b79ddd98d923ee15f4bfd1db5111e669fc19964a;p=d2df-sdl.git diff --git a/src/game/g_weapons.pas b/src/game/g_weapons.pas index ca4630e..182207f 100644 --- a/src/game/g_weapons.pas +++ b/src/game/g_weapons.pas @@ -20,20 +20,9 @@ unit g_weapons; interface uses - g_textures, g_basic, e_graphics, g_phys, BinEditor, xprofiler; + SysUtils, Classes, + g_textures, g_basic, e_graphics, g_phys, xprofiler; -const - HIT_SOME = 0; - HIT_ROCKET = 1; - HIT_BFG = 2; - HIT_TRAP = 3; - HIT_FALL = 4; - HIT_WATER = 5; - HIT_ACID = 6; - HIT_ELECTRO = 7; - HIT_FLAME = 8; - HIT_SELF = 9; - HIT_DISCON = 10; type TShot = record @@ -89,8 +78,8 @@ procedure g_Weapon_Draw(); function g_Weapon_Danger(UID: Word; X, Y: Integer; Width, Height: Word; Time: Byte): Boolean; 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_SaveState (st: TStream); +procedure g_Weapon_LoadState (st: TStream); procedure g_Weapon_AddDynLights(); @@ -126,10 +115,10 @@ implementation uses Math, g_map, g_player, g_gfx, g_sound, g_main, g_panel, - g_console, SysUtils, g_options, g_game, + g_console, g_options, g_game, g_triggers, MAPDEF, e_log, g_monsters, g_saveload, g_language, g_netmsg, g_grid, - binheap, hashtable; + binheap, hashtable, utils, xstreams; type TWaterPanel = record @@ -338,7 +327,7 @@ var function monsWaterCheck (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 + if mon.alive 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; @@ -385,7 +374,7 @@ begin pan := gWater[WaterMap[a][c]]; for d := 0 to High(gPlayers) do begin - if (gPlayers[d] <> nil) and (gPlayers[d].Live) then + if (gPlayers[d] <> nil) and (gPlayers[d].alive) then begin if gPlayers[d].Collide(pan) then begin @@ -499,7 +488,7 @@ procedure g_Weapon_BFG9000(X, Y: Integer; SpawnerUID: Word); function monsCheck (mon: TMonster): Boolean; begin result := false; // don't stop - if (mon.Live) and (mon.UID <> SpawnerUID) then + if (mon.alive) and (mon.UID <> SpawnerUID) then begin with mon do begin @@ -547,7 +536,7 @@ begin if h <> -1 then for i := 0 to h do - if (gPlayers[i] <> nil) and (gPlayers[i].Live) and (gPlayers[i].UID <> SpawnerUID) then + if (gPlayers[i] <> nil) and (gPlayers[i].alive) and (gPlayers[i].UID <> SpawnerUID) then with gPlayers[i] do if (g_PatchLength(X, Y, GameX+PLAYER_RECT.X+(PLAYER_RECT.Width div 2), GameY+PLAYER_RECT.Y+(PLAYER_RECT.Height div 2)) <= SHOT_BFG_RADIUS) and @@ -802,7 +791,7 @@ var if h <> -1 then for i := 0 to h do - if (gPlayers[i] <> nil) and gPlayers[i].Live and g_Obj_Collide(obj, @gPlayers[i].Obj) then + if (gPlayers[i] <> nil) and gPlayers[i].alive and g_Obj_Collide(obj, @gPlayers[i].Obj) then begin ChkTeam := True; if (Team > 0) and (g_GetUIDType(SpawnerUID) = UID_PLAYER) then @@ -829,7 +818,7 @@ var function monsCheckHit (monidx: Integer; mon: TMonster): Boolean; begin result := false; // don't stop - if mon.Live and g_Obj_Collide(obj, @mon.Obj) then + if mon.alive and g_Obj_Collide(obj, @mon.Obj) then begin if HitMonster(mon, d, obj^.Vel.X, obj^.Vel.Y, SpawnerUID, t) then begin @@ -982,7 +971,7 @@ var mm := Max(abs(dx), abs(dy)); if mm = 0 then mm := 1; - if mon.Live then + if mon.alive then begin HitMonster(mon, ((mon.Obj.Rect.Width div 4)*10*(rad-mm)) div rad, 0, 0, SpawnerUID, HIT_ROCKET); end; @@ -1006,7 +995,7 @@ begin if h <> -1 then for i := 0 to h do - if (gPlayers[i] <> nil) and gPlayers[i].Live then + if (gPlayers[i] <> nil) and gPlayers[i].alive then with gPlayers[i] do begin dx := Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2)-X; @@ -1060,7 +1049,7 @@ begin if gAdvGibs and (h <> -1) then for i := 0 to h do - if gGibs[i].Live then + if gGibs[i].alive then with gGibs[i] do begin dx := Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2)-X; @@ -1234,7 +1223,7 @@ begin result := false; for i := 0 to High(gPlayers) do begin - if (gPlayers[i] <> nil) and gPlayers[i].Live and gPlayers[i].Collide(X, Y) then + if (gPlayers[i] <> nil) and gPlayers[i].alive and gPlayers[i].Collide(X, Y) then begin if HitPlayer(gPlayers[i], dmg, vx*10, vy*10-3, SpawnerUID, HIT_SOME) then begin @@ -1319,7 +1308,7 @@ begin //vy := (dy*10 div d)*yi; {$IF DEFINED(D2F_DEBUG)} - stt := curTimeMicro(); + stt := getTimeMicro(); {$ENDIF} xx := x; @@ -1350,7 +1339,7 @@ begin begin _collide := True; {$IF DEFINED(D2F_DEBUG)} - stt := curTimeMicro()-stt; + stt := getTimeMicro()-stt; e_WriteLog(Format('*** old trace time: %u microseconds', [LongWord(stt)]), MSG_NOTIFY); showTime := false; {$ENDIF} @@ -1370,7 +1359,7 @@ begin {$IF DEFINED(D2F_DEBUG)} if showTime then begin - stt := curTimeMicro()-stt; + stt := getTimeMicro()-stt; e_WriteLog(Format('*** old trace time: %u microseconds', [LongWord(stt)]), MSG_NOTIFY); end; {$ENDIF} @@ -1393,7 +1382,7 @@ var begin result := false; if (idx < 0) or (idx > High(gPlayers)) then exit; - if (gPlayers[idx] = nil) or not gPlayers[idx].Live then exit; + if (gPlayers[idx] = nil) or not gPlayers[idx].alive then exit; 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)} @@ -1426,7 +1415,7 @@ var for i := 0 to High(gPlayers) do begin plr := gPlayers[i]; - if (plr <> nil) and plr.Live then + if (plr <> nil) and plr.alive then begin plr.getMapBox(px, py, pw, ph); if lineAABBIntersects(x, y, x2, y2, px, py, pw, ph, inx, iny) then @@ -1509,10 +1498,10 @@ begin {$IF DEFINED(D2F_DEBUG)} e_WriteLog(Format('GUN TRACE: (%d,%d) to (%d,%d)', [x, y, x2, y2]), MSG_NOTIFY); - stt := curTimeMicro(); + stt := getTimeMicro(); {$ENDIF} - wallHitFlag := g_Map_traceToNearestWall(x, y, x2, y2, @wallHitX, @wallHitY); + wallHitFlag := (g_Map_traceToNearestWall(x, y, x2, y2, @wallHitX, @wallHitY) <> nil); if wallHitFlag then begin x2 := wallHitX; @@ -1563,7 +1552,7 @@ begin if wallHitFlag then begin {$IF DEFINED(D2F_DEBUG)} - stt := curTimeMicro()-stt; + stt := getTimeMicro()-stt; e_WriteLog(Format('*** new trace time: %u microseconds', [LongWord(stt)]), MSG_NOTIFY); {$ENDIF} g_GFX_Spark(wallHitX, wallHitY, 2+Random(2), 180+a, 0, 0); @@ -1572,7 +1561,7 @@ begin else begin {$IF DEFINED(D2F_DEBUG)} - stt := curTimeMicro()-stt; + stt := getTimeMicro()-stt; e_WriteLog(Format('*** new trace time: %u microseconds', [LongWord(stt)]), MSG_NOTIFY); {$ENDIF} end; @@ -2497,7 +2486,7 @@ procedure g_Weapon_Draw(); var i: Integer; a: SmallInt; - p: TPoint; + p: TDFPoint; begin if Shots = nil then Exit; @@ -2568,93 +2557,82 @@ begin end; end; -procedure g_Weapon_SaveState(var Mem: TBinMemoryWriter); +procedure g_Weapon_SaveState (st: TStream); var count, i, j: Integer; - dw: DWORD; begin -// Ñ÷èòàåì êîëè÷åñòâî ñóùåñòâóþùèõ ñíàðÿäîâ: + // Ñ÷èòàåì êîëè÷åñòâî ñóùåñòâóþùèõ ñíàðÿäîâ count := 0; - if Shots <> nil then - for i := 0 to High(Shots) do - if Shots[i].ShotType <> 0 then - count := count + 1; + for i := 0 to High(Shots) do if (Shots[i].ShotType <> 0) then Inc(count); - Mem := TBinMemoryWriter.Create((count+1) * 80); + // Êîëè÷åñòâî ñíàðÿäîâ + utils.WriteInt(st, count); -// Êîëè÷åñòâî ñíàðÿäîâ: - Mem.WriteInt(count); - - if count = 0 then - Exit; + if (count = 0) then exit; for i := 0 to High(Shots) do + begin if Shots[i].ShotType <> 0 then begin - // Ñèãíàòóðà ñíàðÿäà: - dw := SHOT_SIGNATURE; // 'SHOT' - Mem.WriteDWORD(dw); - // Òèï ñíàðÿäà: - Mem.WriteByte(Shots[i].ShotType); - // Öåëü: - Mem.WriteWord(Shots[i].Target); - // UID ñòðåëÿâøåãî: - Mem.WriteWord(Shots[i].SpawnerUID); - // Ðàçìåð ïîëÿ Triggers: - dw := Length(Shots[i].Triggers); - Mem.WriteDWORD(dw); - // Òðèããåðû, àêòèâèðîâàííûå âûñòðåëîì: - for j := 0 to Integer(dw)-1 do - Mem.WriteDWORD(Shots[i].Triggers[j]); - // Îáúåêò ñíàðÿäà: - Obj_SaveState(@Shots[i].Obj, Mem); - // Êîñòûëèíà åáàíàÿ: - Mem.WriteByte(Shots[i].Stopped); + // Ñèãíàòóðà ñíàðÿäà + utils.writeSign(st, 'SHOT'); + utils.writeInt(st, Byte(0)); // version + // Òèï ñíàðÿäà + utils.writeInt(st, Byte(Shots[i].ShotType)); + // Öåëü + utils.writeInt(st, Word(Shots[i].Target)); + // UID ñòðåëÿâøåãî + utils.writeInt(st, Word(Shots[i].SpawnerUID)); + // Ðàçìåð ïîëÿ Triggers + utils.writeInt(st, Integer(Length(Shots[i].Triggers))); + // Òðèããåðû, àêòèâèðîâàííûå âûñòðåëîì + for j := 0 to Length(Shots[i].Triggers)-1 do utils.writeInt(st, LongWord(Shots[i].Triggers[j])); + // Îáúåêò ñíàðÿäà + Obj_SaveState(st, @Shots[i].Obj); + // Êîñòûëèíà åáàíàÿ + utils.writeInt(st, Byte(Shots[i].Stopped)); end; + end; end; -procedure g_Weapon_LoadState(var Mem: TBinMemoryReader); +procedure g_Weapon_LoadState (st: TStream); var - count, i, j: Integer; - dw: DWORD; + count, tc, i, j: Integer; + dw: LongWord; begin - if Mem = nil then - Exit; + if (st = nil) then exit; -// Êîëè÷åñòâî ñíàðÿäîâ: - Mem.ReadInt(count); + // Êîëè÷åñòâî ñíàðÿäîâ + count := utils.readLongInt(st); + if (count < 0) or (count > 1024*1024) then raise XStreamError.Create('invalid shots counter'); SetLength(Shots, count); - if count = 0 then - Exit; + if (count = 0) then exit; for i := 0 to count-1 do begin - // Ñèãíàòóðà ñíàðÿäà: - Mem.ReadDWORD(dw); - if dw <> SHOT_SIGNATURE then // 'SHOT' - begin - raise EBinSizeError.Create('g_Weapons_LoadState: Wrong Shot Signature'); - end; - // Òèï ñíàðÿäà: - Mem.ReadByte(Shots[i].ShotType); - // Öåëü: - Mem.ReadWord(Shots[i].Target); - // UID ñòðåëÿâøåãî: - Mem.ReadWord(Shots[i].SpawnerUID); - // Ðàçìåð ïîëÿ Triggers: - Mem.ReadDWORD(dw); - SetLength(Shots[i].Triggers, dw); - // Òðèããåðû, àêòèâèðîâàííûå âûñòðåëîì: - for j := 0 to Integer(dw)-1 do - Mem.ReadDWORD(Shots[i].Triggers[j]); - // Îáúåêò ïðåäìåòà: - Obj_LoadState(@Shots[i].Obj, Mem); - // Êîñòûëèíà åáàíàÿ: - Mem.ReadByte(Shots[i].Stopped); - - // Óñòàíîâêà òåêñòóðû èëè àíèìàöèè: + // Ñèãíàòóðà ñíàðÿäà + if not utils.checkSign(st, 'SHOT') then raise XStreamError.Create('invalid shot signature'); + if (utils.readByte(st) <> 0) then raise XStreamError.Create('invalid shot version'); + // Òèï ñíàðÿäà: + Shots[i].ShotType := utils.readByte(st); + // Öåëü + Shots[i].Target := utils.readWord(st); + // UID ñòðåëÿâøåãî + Shots[i].SpawnerUID := utils.readWord(st); + // Ðàçìåð ïîëÿ Triggers + tc := utils.readLongInt(st); + if (tc < 0) or (tc > 1024*1024) then raise XStreamError.Create('invalid shot triggers counter'); + SetLength(Shots[i].Triggers, tc); + // Òðèããåðû, àêòèâèðîâàííûå âûñòðåëîì + for j := 0 to tc-1 do Shots[i].Triggers[j] := utils.readLongWord(st); + // Îáúåêò ïðåäìåòà + Obj_LoadState(@Shots[i].Obj, st); + // Êîñòûëèíà åáàíàÿ + Shots[i].Stopped := utils.readByte(st); + + // Óñòàíîâêà òåêñòóðû èëè àíèìàöèè Shots[i].TextureID := DWORD(-1); Shots[i].Animation := nil;