diff --git a/src/game/g_weapons.pas b/src/game/g_weapons.pas
index 3585ef2b4d136f148003fcc717d9a172bc28f4e6..2cdfe87a09935a9dac8cebba83412243a47ed6cf 100644 (file)
--- a/src/game/g_weapons.pas
+++ b/src/game/g_weapons.pas
end;
procedure CheckTrap(ID: DWORD; dm: Integer; t: Byte);
+
var
a, b, c, d, i1, i2: Integer;
pl, mn: WArray;
+
+ 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, mn)) and (i2 < 1023) then //FIXME
+ begin
+ i2 += 1;
+ mn[i2] := monidx;
+ end;
+ end;
+
begin
if (gWater = nil) or (WaterMap = nil) then Exit;
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);
end;
if i1 <> -1 then
if i2 <> -1 then
for d := 0 to i2 do
- gMonsters[mn[d]].Damage(dm, 0, 0, Shots[ID].SpawnerUID, t);
+ g_Mons_ByIdx(mn[d]).Damage(dm, 0, 0, Shots[ID].SpawnerUID, t);
end;
pl := nil;
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);
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 <> nil) and 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;
+
var
i, h: Integer;
begin
if Result <> 0 then Exit;
- h := High(gMonsters);
+ if g_Mons_ForEach(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 <> nil) and (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;
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();
+ g_Mons_ForEach(monsCheck);
end;
function g_Weapon_CreateShot(I: Integer; ShotType: Byte; Spawner, TargetUID: Word; X, Y, XV, YV: Integer): LongWord;
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
end;
end;
end;
- function MonsterHit(): Boolean;
- var
- i: Integer;
+
+ function monsCheckHit (monidx: Integer; mon: TMonster): Boolean;
begin
- Result := False;
- h := High(gMonsters);
+ result := false; // don't stop
+ if (mon <> nil) and 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);
+ end;
+ result := True;
+ end;
+ end;
+ end;
- 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
- if t <> HIT_FLAME then
- gMonsters[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);
- Result := True;
- break;
- end;
+ function MonsterHit(): Boolean;
+ begin
+ result := g_Mons_ForEach(monsCheckHit);
end;
+
begin
Result := 0;
function g_Weapon_Explode(X, Y: Integer; rad: Integer; SpawnerUID: Word): Boolean;
var
- i, h, r, dx, dy, m, mm: Integer;
+ r: Integer;
+
+ function monsExCheck (monidx: Integer; mon: TMonster): Boolean;
+ var
+ dx, dy, mm: Integer;
+ begin
+ result := false; // don't stop
+ if mon <> nil then
+ begin
+ with mon 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 mon.Live then
+ HitMonster(mon, ((mon.Obj.Rect.Width div 4)*10*(rad-mm)) div rad,
+ 0, 0, SpawnerUID, HIT_ROCKET);
+
+ mon.Push((dx*7) div mm, (dy*7) div mm);
+ end;
+ end;
+ end;
+ end;
+
+var
+ i, h, dx, dy, m, mm: Integer;
_angle: SmallInt;
+
begin
Result := False;
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);
+ g_Mons_ForEach(monsExCheck);
- gMonsters[i].Push((dx*7) div mm, (dy*7) div mm);
- end;
- end;
h := High(gCorpses);
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;