X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_triggers.pas;h=4fefb5d34b612cda301c2ed28f1734235b8e8867;hb=829537fc7b2b29baaab7287e54fba2cdd8d00b5c;hp=46f6a34f6baef9e6205abccd7390dc7778fe2db5;hpb=56b6ed426ce4f88e1b95976031bbce6106020cbc;p=d2df-sdl.git diff --git a/src/game/g_triggers.pas b/src/game/g_triggers.pas index 46f6a34..4fefb5d 100644 --- a/src/game/g_triggers.pas +++ b/src/game/g_triggers.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_triggers; interface @@ -101,7 +101,7 @@ uses g_player, g_map, Math, g_gfx, g_game, g_textures, g_console, g_monsters, g_items, g_phys, g_weapons, wadreader, g_main, SysUtils, e_log, g_language, - g_options, g_net, g_netmsg, g_scripts; + g_options, g_net, g_netmsg; const TRIGGER_SIGNATURE = $52475254; // 'TRGR' @@ -144,7 +144,7 @@ begin with gWalls[PanelID] do begin if g_CollidePlayer(X, Y, Width, Height) or - g_CollideMonster(X, Y, Width, Height) then Exit; + g_Mons_IsAnyAliveAt(X, Y, Width, Height) then Exit; if not Enabled then begin @@ -181,7 +181,7 @@ begin with gWalls[gDoorMap[c, b]] do begin if g_CollidePlayer(X, Y, Width, Height) or - g_CollideMonster(X, Y, Width, Height) then Exit; + g_Mons_IsAnyAliveAt(X, Y, Width, Height) then Exit; end; if not NoSound then @@ -209,18 +209,36 @@ end; procedure tr_CloseTrap(PanelID: Integer; NoSound: Boolean; d2d: Boolean); var a, b, c: Integer; + wx, wy, wh, ww: Integer; + + function monsDamage (monidx: Integer; mon: TMonster): Boolean; + begin + result := false; // don't stop + if (mon <> nil) and mon.Live and g_Obj_Collide(wx, wy, ww, wh, @mon.Obj) then + begin + mon.Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP); + end; + end; + begin if PanelID = -1 then Exit; if not d2d then begin with gWalls[PanelID] do + begin if (not NoSound) and (not Enabled) then begin g_Sound_PlayExAt('SOUND_GAME_SWITCH1', X, Y); if g_Game_IsServer and g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_SWITCH1'); end; + end; + + wx := gWalls[PanelID].X; + wy := gWalls[PanelID].Y; + ww := gWalls[PanelID].Width; + wh := gWalls[PanelID].Height; with gWalls[PanelID] do begin @@ -230,11 +248,7 @@ begin gPlayers[a].Collide(X, Y, Width, Height) then gPlayers[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP); - if gMonsters <> nil then - for a := 0 to High(gMonsters) do - if (gMonsters[a] <> nil) and gMonsters[a].Live and - g_Obj_Collide(X, Y, Width, Height, @gMonsters[a].Obj) then - gMonsters[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP); + g_Mons_ForEach(monsDamage); if not Enabled then g_Map_EnableWall(PanelID); end; @@ -247,30 +261,41 @@ begin for a := 0 to High(gDoorMap) do begin for b := 0 to High(gDoorMap[a]) do + begin if gDoorMap[a, b] = DWORD(PanelID) then begin c := a; Break; end; + end; if c <> -1 then Break; end; if c = -1 then Exit; if not NoSound then + begin for b := 0 to High(gDoorMap[c]) do + begin if not gWalls[gDoorMap[c, b]].Enabled then begin with gWalls[PanelID] do begin g_Sound_PlayExAt('SOUND_GAME_SWITCH1', X, Y); - if g_Game_IsServer and g_Game_IsNet then - MH_SEND_Sound(X, Y, 'SOUND_GAME_SWITCH1'); + if g_Game_IsServer and g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_SWITCH1'); end; Break; end; + end; + end; for b := 0 to High(gDoorMap[c]) do + begin + wx := gWalls[gDoorMap[c, b]].X; + wy := gWalls[gDoorMap[c, b]].Y; + ww := gWalls[gDoorMap[c, b]].Width; + wh := gWalls[gDoorMap[c, b]].Height; + with gWalls[gDoorMap[c, b]] do begin if gPlayers <> nil then @@ -279,14 +304,18 @@ begin gPlayers[a].Collide(X, Y, Width, Height) then gPlayers[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP); + g_Mons_ForEach(monsDamage); + (* if gMonsters <> nil then for a := 0 to High(gMonsters) do if (gMonsters[a] <> nil) and gMonsters[a].Live and g_Obj_Collide(X, Y, Width, Height, @gMonsters[a].Obj) then gMonsters[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP); + *) if not Enabled then g_Map_EnableWall(gDoorMap[c, b]); end; + end; end; end; @@ -924,12 +953,29 @@ begin end; end; +function tr_ShotAimCheck(var Trigger: TTrigger; Obj: PObj): Boolean; +begin + result := false; + with Trigger do + begin + if TriggerType <> TRIGGER_SHOT then + Exit; + Result := (Data.ShotAim and TRIGGER_SHOT_AIM_ALLMAP > 0) + or g_Obj_Collide(X, Y, Width, Height, Obj); + if Result and (Data.ShotAim and TRIGGER_SHOT_AIM_TRACE > 0) then + Result := g_TraceVector(Data.ShotPos.X, + Data.ShotPos.Y, + Obj^.X + Obj^.Rect.X + (Obj^.Rect.Width div 2), + Obj^.Y + Obj^.Rect.Y + (Obj^.Rect.Height div 2)); + end; +end; + function ActivateTrigger(var Trigger: TTrigger; actType: Byte): Boolean; var animonce: Boolean; p: TPlayer; m: TMonster; - i, k, wx, wy, xd, yd: Integer; + idx, k, wx, wy, xd, yd: Integer; iid: LongWord; coolDown: Boolean; pAngle: Real; @@ -937,6 +983,45 @@ var Anim: TAnimation; UIDType: Byte; TargetUID: Word; + it: PItem; + mon: TMonster; + + function monsShotTarget (monidx: Integer; mon: TMonster): Boolean; + begin + result := false; // don't stop + if (mon <> nil) and mon.Live and tr_ShotAimCheck(Trigger, @(mon.Obj)) then + begin + xd := mon.GameX + mon.Obj.Rect.Width div 2; + yd := mon.GameY + mon.Obj.Rect.Height div 2; + TargetUID := mon.UID; + result := true; // stop + end; + end; + + function monsShotTargetMonPlr (monidx: Integer; mon: TMonster): Boolean; + begin + result := false; // don't stop + if (mon <> nil) and mon.Live and tr_ShotAimCheck(Trigger, @(mon.Obj)) then + begin + xd := mon.GameX + mon.Obj.Rect.Width div 2; + yd := mon.GameY + mon.Obj.Rect.Height div 2; + TargetUID := mon.UID; + result := true; // stop + end; + end; + + function monShotTargetPlrMon (monidx: Integer; mon: TMonster): Boolean; + begin + result := false; // don't stop + if (mon <> nil) and mon.Live and tr_ShotAimCheck(Trigger, @(mon.Obj)) then + begin + xd := mon.GameX + mon.Obj.Rect.Width div 2; + yd := mon.GameY + mon.Obj.Rect.Height div 2; + TargetUID := mon.UID; + result := true; // stop + end; + end; + begin Result := False; if g_Game_IsClient then @@ -1166,7 +1251,7 @@ begin if (Data.MonMax > 0) and (SpawnedCount >= Data.MonMax) then Break; - i := g_Monsters_Create(Data.MonType, + mon := g_Monsters_Create(Data.MonType, Data.MonPos.X, Data.MonPos.Y, TDirection(Data.MonDir), True); @@ -1174,27 +1259,27 @@ begin // Çäîðîâüå: if (Data.MonHealth > 0) then - gMonsters[i].SetHealth(Data.MonHealth); + mon.SetHealth(Data.MonHealth); // Óñòàíàâëèâàåì ïîâåäåíèå: - gMonsters[i].MonsterBehaviour := Data.MonBehav; - gMonsters[i].FNoRespawn := True; + mon.MonsterBehaviour := Data.MonBehav; + mon.FNoRespawn := True; if g_Game_IsNet then - MH_SEND_MonsterSpawn(gMonsters[i].UID); + MH_SEND_MonsterSpawn(mon.UID); // Èäåì èñêàòü öåëü, åñëè íàäî: if Data.MonActive then - gMonsters[i].WakeUp(); + mon.WakeUp(); if Data.MonType <> MONSTER_BARREL then Inc(gTotalMonsters); if g_Game_IsNet then begin SetLength(gMonstersSpawned, Length(gMonstersSpawned)+1); - gMonstersSpawned[High(gMonstersSpawned)] := gMonsters[i].UID; + gMonstersSpawned[High(gMonstersSpawned)] := mon.UID; end; if Data.MonMax > 0 then begin - gMonsters[i].SpawnTrigger := ID; + mon.SpawnTrigger := ID; Inc(SpawnedCount); end; @@ -1204,13 +1289,13 @@ begin begin Anim := TAnimation.Create(FramesID, False, 3); g_Sound_PlayExAt('SOUND_GAME_TELEPORT', Data.MonPos.X, Data.MonPos.Y); - g_GFX_OnceAnim(gMonsters[i].Obj.X+gMonsters[i].Obj.Rect.X+(gMonsters[i].Obj.Rect.Width div 2)-32, - gMonsters[i].Obj.Y+gMonsters[i].Obj.Rect.Y+(gMonsters[i].Obj.Rect.Height div 2)-32, Anim); + g_GFX_OnceAnim(mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2)-32, + mon.Obj.Y+mon.Obj.Rect.Y+(mon.Obj.Rect.Height div 2)-32, Anim); Anim.Free(); end; if g_Game_IsServer and g_Game_IsNet then - MH_SEND_Effect(gMonsters[i].Obj.X+gMonsters[i].Obj.Rect.X+(gMonsters[i].Obj.Rect.Width div 2)-32, - gMonsters[i].Obj.Y+gMonsters[i].Obj.Rect.Y+(gMonsters[i].Obj.Rect.Height div 2)-32, 1, + MH_SEND_Effect(mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2)-32, + mon.Obj.Y+mon.Obj.Rect.Y+(mon.Obj.Rect.Height div 2)-32, 1, NET_GFX_TELE); end; EFFECT_RESPAWN: begin @@ -1218,13 +1303,13 @@ begin begin Anim := TAnimation.Create(FramesID, False, 4); g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', Data.MonPos.X, Data.MonPos.Y); - g_GFX_OnceAnim(gMonsters[i].Obj.X+gMonsters[i].Obj.Rect.X+(gMonsters[i].Obj.Rect.Width div 2)-16, - gMonsters[i].Obj.Y+gMonsters[i].Obj.Rect.Y+(gMonsters[i].Obj.Rect.Height div 2)-16, Anim); + g_GFX_OnceAnim(mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2)-16, + mon.Obj.Y+mon.Obj.Rect.Y+(mon.Obj.Rect.Height div 2)-16, Anim); Anim.Free(); end; if g_Game_IsServer and g_Game_IsNet then - MH_SEND_Effect(gMonsters[i].Obj.X+gMonsters[i].Obj.Rect.X+(gMonsters[i].Obj.Rect.Width div 2)-16, - gMonsters[i].Obj.Y+gMonsters[i].Obj.Rect.Y+(gMonsters[i].Obj.Rect.Height div 2)-16, 1, + MH_SEND_Effect(mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2)-16, + mon.Obj.Y+mon.Obj.Rect.Y+(mon.Obj.Rect.Height div 2)-16, 1, NET_GFX_RESPAWN); end; EFFECT_FIRE: begin @@ -1232,13 +1317,13 @@ begin begin Anim := TAnimation.Create(FramesID, False, 4); g_Sound_PlayExAt('SOUND_FIRE', Data.MonPos.X, Data.MonPos.Y); - g_GFX_OnceAnim(gMonsters[i].Obj.X+gMonsters[i].Obj.Rect.X+(gMonsters[i].Obj.Rect.Width div 2)-32, - gMonsters[i].Obj.Y+gMonsters[i].Obj.Rect.Y+gMonsters[i].Obj.Rect.Height-128, Anim); + g_GFX_OnceAnim(mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2)-32, + mon.Obj.Y+mon.Obj.Rect.Y+mon.Obj.Rect.Height-128, Anim); Anim.Free(); end; if g_Game_IsServer and g_Game_IsNet then - MH_SEND_Effect(gMonsters[i].Obj.X+gMonsters[i].Obj.Rect.X+(gMonsters[i].Obj.Rect.Width div 2)-32, - gMonsters[i].Obj.Y+gMonsters[i].Obj.Rect.Y+gMonsters[i].Obj.Rect.Height-128, 1, + MH_SEND_Effect(mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2)-32, + mon.Obj.Y+mon.Obj.Rect.Y+mon.Obj.Rect.Height-128, 1, NET_GFX_FIRE); end; end; @@ -1288,51 +1373,55 @@ begin if Data.ItemMax > 0 then begin - gItems[iid].SpawnTrigger := ID; + it := g_Items_ByIdx(iid); + it.SpawnTrigger := ID; Inc(SpawnedCount); end; case Data.ItemEffect of EFFECT_TELEPORT: begin + it := g_Items_ByIdx(iid); if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then begin Anim := TAnimation.Create(FramesID, False, 3); g_Sound_PlayExAt('SOUND_GAME_TELEPORT', Data.ItemPos.X, Data.ItemPos.Y); - g_GFX_OnceAnim(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-32, - gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+(gItems[iid].Obj.Rect.Height div 2)-32, Anim); + g_GFX_OnceAnim(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-32, + it.Obj.Y+it.Obj.Rect.Y+(it.Obj.Rect.Height div 2)-32, Anim); Anim.Free(); end; if g_Game_IsServer and g_Game_IsNet then - MH_SEND_Effect(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-32, - gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+(gItems[iid].Obj.Rect.Height div 2)-32, 1, + MH_SEND_Effect(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-32, + it.Obj.Y+it.Obj.Rect.Y+(it.Obj.Rect.Height div 2)-32, 1, NET_GFX_TELE); end; EFFECT_RESPAWN: begin + it := g_Items_ByIdx(iid); if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then begin Anim := TAnimation.Create(FramesID, False, 4); g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', Data.ItemPos.X, Data.ItemPos.Y); - g_GFX_OnceAnim(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-16, - gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+(gItems[iid].Obj.Rect.Height div 2)-16, Anim); + g_GFX_OnceAnim(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-16, + it.Obj.Y+it.Obj.Rect.Y+(it.Obj.Rect.Height div 2)-16, Anim); Anim.Free(); end; if g_Game_IsServer and g_Game_IsNet then - MH_SEND_Effect(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-16, - gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+(gItems[iid].Obj.Rect.Height div 2)-16, 1, + MH_SEND_Effect(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-16, + it.Obj.Y+it.Obj.Rect.Y+(it.Obj.Rect.Height div 2)-16, 1, NET_GFX_RESPAWN); end; EFFECT_FIRE: begin + it := g_Items_ByIdx(iid); if g_Frames_Get(FramesID, 'FRAMES_FIRE') then begin Anim := TAnimation.Create(FramesID, False, 4); g_Sound_PlayExAt('SOUND_FIRE', Data.ItemPos.X, Data.ItemPos.Y); - g_GFX_OnceAnim(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-32, - gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+gItems[iid].Obj.Rect.Height-128, Anim); + g_GFX_OnceAnim(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-32, + it.Obj.Y+it.Obj.Rect.Y+it.Obj.Rect.Height-128, Anim); Anim.Free(); end; if g_Game_IsServer and g_Game_IsNet then - MH_SEND_Effect(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-32, - gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+gItems[iid].Obj.Rect.Height-128, 1, + MH_SEND_Effect(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-32, + it.Obj.Y+it.Obj.Rect.Y+it.Obj.Rect.Height-128, 1, NET_GFX_FIRE); end; end; @@ -1744,10 +1833,10 @@ begin if coolDown then begin // Âñïîìèíàåì, àêòèâèðîâàë ëè îí ìåíÿ ðàíüøå - for i := 0 to High(Activators) do - if Activators[i].UID = ActivateUID then + for idx := 0 to High(Activators) do + if Activators[idx].UID = ActivateUID then begin - k := i; + k := idx; Break; end; if k = -1 then @@ -1811,12 +1900,12 @@ begin end; // Íàçíà÷àåì âðåìÿ ñëåäóþùåãî âîçäåéñòâèÿ if TriggerType = TRIGGER_DAMAGE then - i := Data.DamageInterval + idx := Data.DamageInterval else - i := Data.HealInterval; + idx := Data.HealInterval; if coolDown then - if i > 0 then - Activators[k].TimeOut := i + if idx > 0 then + Activators[k].TimeOut := idx else Activators[k].TimeOut := 65535; end; @@ -1841,75 +1930,58 @@ begin case Data.ShotTarget of TRIGGER_SHOT_TARGET_MON: // monsters - if gMonsters <> nil then - for i := Low(gMonsters) to High(gMonsters) do - if (gMonsters[i] <> nil) and gMonsters[i].Live and - (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gMonsters[i].Obj))) then - begin - xd := gMonsters[i].GameX + gMonsters[i].Obj.Rect.Width div 2; - yd := gMonsters[i].GameY + gMonsters[i].Obj.Rect.Height div 2; - TargetUID := gMonsters[i].UID; - break; - end; + g_Mons_ForEach(monsShotTarget); TRIGGER_SHOT_TARGET_PLR: // players if gPlayers <> nil then - for i := Low(gPlayers) to High(gPlayers) do - if (gPlayers[i] <> nil) and gPlayers[i].Live and - (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gPlayers[i].Obj))) then + for idx := Low(gPlayers) to High(gPlayers) do + if (gPlayers[idx] <> nil) and gPlayers[idx].Live and + tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then begin - xd := gPlayers[i].GameX + PLAYER_RECT_CX; - yd := gPlayers[i].GameY + PLAYER_RECT_CY; - TargetUID := gPlayers[i].UID; + xd := gPlayers[idx].GameX + PLAYER_RECT_CX; + yd := gPlayers[idx].GameY + PLAYER_RECT_CY; + TargetUID := gPlayers[idx].UID; break; end; TRIGGER_SHOT_TARGET_RED: // red team if gPlayers <> nil then - for i := Low(gPlayers) to High(gPlayers) do - if (gPlayers[i] <> nil) and gPlayers[i].Live and - (gPlayers[i].Team = TEAM_RED) and - (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gPlayers[i].Obj))) then + for idx := Low(gPlayers) to High(gPlayers) do + if (gPlayers[idx] <> nil) and gPlayers[idx].Live and + (gPlayers[idx].Team = TEAM_RED) and + tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then begin - xd := gPlayers[i].GameX + PLAYER_RECT_CX; - yd := gPlayers[i].GameY + PLAYER_RECT_CY; - TargetUID := gPlayers[i].UID; + xd := gPlayers[idx].GameX + PLAYER_RECT_CX; + yd := gPlayers[idx].GameY + PLAYER_RECT_CY; + TargetUID := gPlayers[idx].UID; break; end; TRIGGER_SHOT_TARGET_BLUE: // blue team if gPlayers <> nil then - for i := Low(gPlayers) to High(gPlayers) do - if (gPlayers[i] <> nil) and gPlayers[i].Live and - (gPlayers[i].Team = TEAM_BLUE) and - (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gPlayers[i].Obj))) then + for idx := Low(gPlayers) to High(gPlayers) do + if (gPlayers[idx] <> nil) and gPlayers[idx].Live and + (gPlayers[idx].Team = TEAM_BLUE) and + tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then begin - xd := gPlayers[i].GameX + PLAYER_RECT_CX; - yd := gPlayers[i].GameY + PLAYER_RECT_CY; - TargetUID := gPlayers[i].UID; + xd := gPlayers[idx].GameX + PLAYER_RECT_CX; + yd := gPlayers[idx].GameY + PLAYER_RECT_CY; + TargetUID := gPlayers[idx].UID; break; end; TRIGGER_SHOT_TARGET_MONPLR: // monsters then players begin - if gMonsters <> nil then - for i := Low(gMonsters) to High(gMonsters) do - if (gMonsters[i] <> nil) and gMonsters[i].Live and - (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gMonsters[i].Obj))) then - begin - xd := gMonsters[i].GameX + gMonsters[i].Obj.Rect.Width div 2; - yd := gMonsters[i].GameY + gMonsters[i].Obj.Rect.Height div 2; - TargetUID := gMonsters[i].UID; - break; - end; + g_Mons_ForEach(monsShotTargetMonPlr); + if (TargetUID = 0) and (gPlayers <> nil) then - for i := Low(gPlayers) to High(gPlayers) do - if (gPlayers[i] <> nil) and gPlayers[i].Live and - (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gPlayers[i].Obj))) then + for idx := Low(gPlayers) to High(gPlayers) do + if (gPlayers[idx] <> nil) and gPlayers[idx].Live and + tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then begin - xd := gPlayers[i].GameX + PLAYER_RECT_CX; - yd := gPlayers[i].GameY + PLAYER_RECT_CY; - TargetUID := gPlayers[i].UID; + xd := gPlayers[idx].GameX + PLAYER_RECT_CX; + yd := gPlayers[idx].GameY + PLAYER_RECT_CY; + TargetUID := gPlayers[idx].UID; break; end; end; @@ -1917,31 +1989,27 @@ begin TRIGGER_SHOT_TARGET_PLRMON: // players then monsters begin if gPlayers <> nil then - for i := Low(gPlayers) to High(gPlayers) do - if (gPlayers[i] <> nil) and gPlayers[i].Live and - (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gPlayers[i].Obj))) then + for idx := Low(gPlayers) to High(gPlayers) do + if (gPlayers[idx] <> nil) and gPlayers[idx].Live and + tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then begin - xd := gPlayers[i].GameX + PLAYER_RECT_CX; - yd := gPlayers[i].GameY + PLAYER_RECT_CY; - TargetUID := gPlayers[i].UID; - break; - end; - if (TargetUID = 0) and (gMonsters <> nil) then - for i := Low(gMonsters) to High(gMonsters) do - if (gMonsters[i] <> nil) and gMonsters[i].Live and - (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gMonsters[i].Obj))) then - begin - xd := gMonsters[i].GameX + gMonsters[i].Obj.Rect.Width div 2; - yd := gMonsters[i].GameY + gMonsters[i].Obj.Rect.Height div 2; - TargetUID := gMonsters[i].UID; + xd := gPlayers[idx].GameX + PLAYER_RECT_CX; + yd := gPlayers[idx].GameY + PLAYER_RECT_CY; + TargetUID := gPlayers[idx].UID; break; end; + if TargetUID = 0 then g_Mons_ForEach(monShotTargetPlrMon); end; - else TargetUID := ActivateUID; + else begin + if (Data.ShotTarget <> TRIGGER_SHOT_TARGET_NONE) or + (Data.ShotType <> TRIGGER_SHOT_REV) then + TargetUID := ActivateUID; + end; end; - if (Data.ShotTarget = TRIGGER_SHOT_TARGET_NONE) or (TargetUID > 0) then + if (Data.ShotTarget = TRIGGER_SHOT_TARGET_NONE) or (TargetUID > 0) or + ((Data.ShotTarget > TRIGGER_SHOT_TARGET_NONE) and (TargetUID = 0)) then begin Result := True; if (Data.ShotIntSight = 0) or @@ -1964,9 +2032,9 @@ begin TRIGGER_EFFECT: begin - i := Data.FXCount; + idx := Data.FXCount; - while i > 0 do + while idx > 0 do begin case Data.FXPos of TRIGGER_EFFECT_POS_CENTER: @@ -1993,17 +2061,10 @@ begin tr_MakeEffect(wx, wy, xd, yd, Data.FXType, Data.FXSubType, Data.FXColorR, Data.FXColorG, Data.FXColorB, True, False); - Dec(i); + Dec(idx); end; TimeOut := Data.FXWait; end; - - TRIGGER_SCRIPT: - begin - g_Scripts_ProcExec(Data.SCRProc, [ID, ActivateUID, actType, Data.SCRArg], 'map'); - TimeOut := 0; - Result := True; - end; end; end; @@ -2134,6 +2195,24 @@ procedure g_Triggers_Update(); var a, b, i: Integer; Affected: array of Integer; + + {function monsNear (monidx: Integer; mon: TMonster): Boolean; + begin + result := false; // don't stop + if mon.Collide(gTriggers[a].X, gTriggers[a].Y, gTriggers[a].Width, gTriggers[a].Height) then + begin + gTriggers[a].ActivateUID := mon.UID; + ActivateTrigger(gTriggers[a], ACTIVATE_MONSTERCOLLIDE); + end; + end;} + + function monsNear (monidx: Integer; mon: TMonster): Boolean; + begin + result := false; // don't stop + gTriggers[a].ActivateUID := mon.UID; + ActivateTrigger(gTriggers[a], ACTIVATE_MONSTERCOLLIDE); + end; + begin if gTriggers = nil then Exit; @@ -2364,23 +2443,18 @@ begin ActivateTrigger(gTriggers[a], 0); end else begin - // "Ìîíñòð áëèçêî": + // "Ìîíñòð áëèçêî" if ByteBool(ActivateType and ACTIVATE_MONSTERCOLLIDE) and (TimeOut = 0) and (Keys = 0) then // Åñëè íå íóæíû êëþ÷è - if gMonsters <> nil then - for b := 0 to High(gMonsters) do - if (gMonsters[b] <> nil) then - with gMonsters[b] do - if Collide(X, Y, Width, Height) then - begin - gTriggers[a].ActivateUID := UID; - ActivateTrigger(gTriggers[a], ACTIVATE_MONSTERCOLLIDE); - end; + begin + //g_Mons_ForEach(monsNear); + g_Mons_ForEachAt(gTriggers[a].X, gTriggers[a].Y, gTriggers[a].Width, gTriggers[a].Height, monsNear); + end; - // "Ìîíñòðîâ íåò": + // "Ìîíñòðîâ íåò" if ByteBool(ActivateType and ACTIVATE_NOMONSTER) and (TimeOut = 0) and (Keys = 0) then - if not g_CollideMonster(X, Y, Width, Height) then + if not g_Mons_IsAnyAliveAt(X, Y, Width, Height) then begin gTriggers[a].ActivateUID := 0; ActivateTrigger(gTriggers[a], ACTIVATE_NOMONSTER);