X-Git-Url: http://deadsoftware.ru/gitweb?p=d2df-sdl.git;a=blobdiff_plain;f=src%2Fgame%2Fg_triggers.pas;h=64e87c6679d3249581d15ba0eb1dac13b9276e10;hp=4aca319356ce70040c524a93dbd1681de2c85c57;hb=abda6900c041e39944de6a49aa088a60c170715e;hpb=94a927ca673a2d8af4b8449d434f3c70f38b11c1 diff --git a/src/game/g_triggers.pas b/src/game/g_triggers.pas index 4aca319..64e87c6 100644 --- a/src/game/g_triggers.pas +++ b/src/game/g_triggers.pas @@ -1,9 +1,8 @@ -(* Copyright (C) DooM 2D:Forever Developers +(* Copyright (C) Doom 2D: Forever Developers * * 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,12 +19,10 @@ interface uses SysUtils, Variants, Classes, - MAPDEF, e_graphics, g_basic, g_sound, + MAPDEF, g_basic, g_sound, xdynrec, hashtable, exoma; type - THashStrVariant = specialize THashBase; - TActivator = record UID: Word; TimeOut: Word; @@ -81,7 +78,7 @@ type function trigCenter (): TDFPoint; inline; end; -function g_Triggers_Create(Trigger: TTrigger; trec: TDynRecord; forceInternalIndex: Integer=-1): DWORD; +function g_Triggers_Create (aTrigger: TTrigger; trec: TDynRecord; forceInternalIndex: Integer=-1): DWORD; procedure g_Triggers_Update(); procedure g_Triggers_Press(ID: DWORD; ActivateType: Byte; ActivateUID: Word = 0); function g_Triggers_PressR(X, Y: Integer; Width, Height: Word; UID: Word; @@ -106,9 +103,9 @@ implementation uses Math, - g_player, g_map, g_panel, g_gfx, g_game, g_textures, + g_player, g_map, g_panel, g_gfx, g_game, r_gfx, g_console, g_monsters, g_items, g_phys, g_weapons, - wadreader, g_main, e_log, g_language, + wadreader, e_log, g_language, e_res, g_options, g_net, g_netmsg, utils, xparser, xstreams; const @@ -237,7 +234,7 @@ begin if (Length(afldname) > 4) and (afldname[1] = 'u') and (afldname[2] = 's') and (afldname[3] = 'e') and (afldname[4] = 'r') then begin - if (me.userVars = nil) then me.userVars := THashStrVariant.Create(hsihash, hsiequ); + if (me.userVars = nil) then me.userVars := THashStrVariant.Create(); me.userVars.put(afldname, aval); exit; end; @@ -594,17 +591,17 @@ begin if (gLifts[PanelID].PanelType = PANEL_LIFTUP) or (gLifts[PanelID].PanelType = PANEL_LIFTDOWN) then begin case d of - 0: t := 0; - 1: t := 1; - else t := IfThen(gLifts[PanelID].LiftType = 1, 0, 1); + 0: t := LIFTTYPE_UP; + 1: t := LIFTTYPE_DOWN; + else t := IfThen(gLifts[PanelID].LiftType = LIFTTYPE_DOWN, LIFTTYPE_UP, LIFTTYPE_DOWN); end end else if (gLifts[PanelID].PanelType = PANEL_LIFTLEFT) or (gLifts[PanelID].PanelType = PANEL_LIFTRIGHT) then begin case d of - 0: t := 2; - 1: t := 3; - else t := IfThen(gLifts[PanelID].LiftType = 2, 3, 2); + 0: t := LIFTTYPE_LEFT; + 1: t := LIFTTYPE_RIGHT; + else t := IfThen(gLifts[PanelID].LiftType = LIFTTYPE_LEFT, LIFTTYPE_RIGHT, LIFTTYPE_LEFT); end; end; @@ -667,11 +664,8 @@ function tr_SpawnShot (ShotType: Integer; wx, wy, dx, dy: Integer; ShotSound: Bo var snd: string; Projectile: Boolean; - TextureID: DWORD; - Anim: TAnimation; begin result := -1; - TextureID := DWORD(-1); snd := 'SOUND_WEAPON_FIREROCKET'; Projectile := true; @@ -782,13 +776,7 @@ begin TRIGGER_SHOT_EXPL: begin - if g_Frames_Get(TextureID, 'FRAMES_EXPLODE_ROCKET') then - begin - Anim := TAnimation.Create(TextureID, False, 6); - Anim.Blending := False; - g_GFX_OnceAnim(wx-64, wy-64, Anim); - Anim.Free(); - end; + r_GFX_OnceAnim(R_GFX_EXPLODE_ROCKET, wx - 64, wy - 64); Projectile := False; g_Weapon_Explode(wx, wy, 60, 0); snd := 'SOUND_WEAPON_EXPLODEROCKET'; @@ -796,18 +784,18 @@ begin TRIGGER_SHOT_BFGEXPL: begin - if g_Frames_Get(TextureID, 'FRAMES_EXPLODE_BFG') then - begin - Anim := TAnimation.Create(TextureID, False, 6); - Anim.Blending := False; - g_GFX_OnceAnim(wx-64, wy-64, Anim); - Anim.Free(); - end; + r_GFX_OnceAnim(R_GFX_EXPLODE_BFG, wx - 64, wy - 64); Projectile := False; g_Weapon_BFG9000(wx, wy, 0); snd := 'SOUND_WEAPON_EXPLODEBFG'; end; + TRIGGER_SHOT_FLAME: + begin + g_Weapon_flame(wx, wy, dx, dy, 0, -1, True); + snd := 'SOUND_GAME_BURNING'; + end; + else exit; end; @@ -849,7 +837,7 @@ begin dx += Random(tgcAccuracy)-Random(tgcAccuracy); dy += Random(tgcAccuracy)-Random(tgcAccuracy); - tr_SpawnShot(tgcShotType, wx, wy, dx, dy, not tgcQuiet, TargetUID); + tr_SpawnShot(tgcShotType, wx, wy, dx, dy, tgcShotSound, TargetUID); end else begin @@ -863,9 +851,6 @@ end; procedure tr_MakeEffect (X, Y, VX, VY: Integer; T, ST, CR, CG, CB: Byte; Silent, Send: Boolean); -var - FramesID: DWORD; - Anim: TAnimation; begin if T = TRIGGER_EFFECT_PARTICLE then begin @@ -889,33 +874,18 @@ begin begin case ST of EFFECT_TELEPORT: begin - if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then - begin - Anim := TAnimation.Create(FramesID, False, 3); - if not Silent then g_Sound_PlayExAt('SOUND_GAME_TELEPORT', X, Y); - g_GFX_OnceAnim(X-32, Y-32, Anim); - Anim.Free(); - end; + if not Silent then g_Sound_PlayExAt('SOUND_GAME_TELEPORT', X, Y); + r_GFX_OnceAnim(R_GFX_TELEPORT_FAST, X - 32, Y - 32); if Send and g_Game_IsServer and g_Game_IsNet then MH_SEND_Effect(X, Y, Byte(not Silent), NET_GFX_TELE); end; EFFECT_RESPAWN: begin - if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then - begin - Anim := TAnimation.Create(FramesID, False, 4); - if not Silent then g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', X, Y); - g_GFX_OnceAnim(X-16, Y-16, Anim); - Anim.Free(); - end; + if not Silent then g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', X, Y); + r_GFX_OnceAnim(R_GFX_ITEM_RESPAWN, X - 16, Y - 16); if Send and g_Game_IsServer and g_Game_IsNet then MH_SEND_Effect(X-16, Y-16, Byte(not Silent), NET_GFX_RESPAWN); end; EFFECT_FIRE: begin - if g_Frames_Get(FramesID, 'FRAMES_FIRE') then - begin - Anim := TAnimation.Create(FramesID, False, 4); - if not Silent then g_Sound_PlayExAt('SOUND_FIRE', X, Y); - g_GFX_OnceAnim(X-32, Y-128, Anim); - Anim.Free(); - end; + if not Silent then g_Sound_PlayExAt('SOUND_FIRE', X, Y); + r_GFX_OnceAnim(R_GFX_FIRE, X - 32, Y - 128); if Send and g_Game_IsServer and g_Game_IsNet then MH_SEND_Effect(X-32, Y-128, Byte(not Silent), NET_GFX_FIRE); end; end; @@ -1170,8 +1140,6 @@ var iid: LongWord; coolDown: Boolean; pAngle: Real; - FramesID: DWORD; - Anim: TAnimation; UIDType: Byte; TargetUID: Word; it: PItem; @@ -1221,7 +1189,7 @@ begin if not Trigger.Enabled then exit; if (Trigger.TimeOut <> 0) and (actType <> ACTIVATE_CUSTOM) then exit; - if (gLMSRespawn = LMS_RESPAWN_WARMUP) then exit; + if (gLMSRespawn > LMS_RESPAWN_NONE) then exit; if (Trigger.exoCheck <> nil) then begin @@ -1346,11 +1314,13 @@ begin begin Enabled := False; Result := True; - if gLMSRespawn = LMS_RESPAWN_NONE then + p := g_Player_Get(ActivateUID); + p.GetSecret(); + Inc(gCoopSecretsFound); + if g_Game_IsNet then begin - g_Player_Get(ActivateUID).GetSecret(); - Inc(gCoopSecretsFound); - if g_Game_IsNet then MH_SEND_GameStats(); + MH_SEND_GameStats(); + MH_SEND_GameEvent(NET_EV_SECRET, p.UID, ''); end; end; @@ -1463,7 +1433,7 @@ begin for k := 1 to tgcMonsCount do begin if (actType = ACTIVATE_CUSTOM) and (tgcDelay > 0) then - SpawnCooldown := tgcDelay; + SpawnCooldown := -1; // Çàäåðæêà âûñòàâèòñÿ ìîíñòðîì ïðè óíè÷òîæåíèè if (tgcMax > 0) and (SpawnedCount >= tgcMax) then Break; @@ -1493,50 +1463,41 @@ begin gMonstersSpawned[High(gMonstersSpawned)] := mon.UID; end; - if tgcMax > 0 then - begin - mon.SpawnTrigger := ID; - Inc(SpawnedCount); - end; + mon.SpawnTrigger := ID; + if tgcMax > 0 then Inc(SpawnedCount); case tgcEffect of EFFECT_TELEPORT: begin - if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then - begin - Anim := TAnimation.Create(FramesID, False, 3); - g_Sound_PlayExAt('SOUND_GAME_TELEPORT', tgcTX, tgcTY); - 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; + g_Sound_PlayExAt('SOUND_GAME_TELEPORT', tgcTX, tgcTY); + r_GFX_OnceAnim( + R_GFX_TELEPORT_FAST, + 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 + ); if g_Game_IsServer and g_Game_IsNet then 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 - if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then - begin - Anim := TAnimation.Create(FramesID, False, 4); - g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', tgcTX, tgcTY); - 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; + g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', tgcTX, tgcTY); + r_GFX_OnceAnim( + R_GFX_ITEM_RESPAWN, + 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 + ); if g_Game_IsServer and g_Game_IsNet then 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 - if g_Frames_Get(FramesID, 'FRAMES_FIRE') then - begin - Anim := TAnimation.Create(FramesID, False, 4); - g_Sound_PlayExAt('SOUND_FIRE', tgcTX, tgcTY); - 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; + g_Sound_PlayExAt('SOUND_FIRE', tgcTX, tgcTY); + r_GFX_OnceAnim( + R_GFX_FIRE, + 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 + ); if g_Game_IsServer and g_Game_IsNet then 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, @@ -1578,7 +1539,7 @@ begin for k := 1 to tgcItemCount do begin if (actType = ACTIVATE_CUSTOM) and (tgcDelay > 0) then - SpawnCooldown := tgcDelay; + SpawnCooldown := -1; // Çàäåðæêà âûñòàâèòñÿ èòåìîì ïðè óíè÷òîæåíèè if (tgcMax > 0) and (SpawnedCount >= tgcMax) then Break; @@ -1587,24 +1548,19 @@ begin Result := True; - if tgcMax > 0 then - begin - it := g_Items_ByIdx(iid); - it.SpawnTrigger := ID; - Inc(SpawnedCount); - end; + it := g_Items_ByIdx(iid); + it.SpawnTrigger := ID; + if tgcMax > 0 then Inc(SpawnedCount); case tgcEffect 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', tgcTX, tgcTY); - 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; + g_Sound_PlayExAt('SOUND_GAME_TELEPORT', tgcTX, tgcTY); + r_GFX_OnceAnim( + R_GFX_TELEPORT_FAST, + 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 + ); if g_Game_IsServer and g_Game_IsNet then 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, @@ -1612,14 +1568,12 @@ begin 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', tgcTX, tgcTY); - 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; + g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', tgcTX, tgcTY); + r_GFX_OnceAnim( + R_GFX_ITEM_RESPAWN, + 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 + ); if g_Game_IsServer and g_Game_IsNet then 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, @@ -1627,14 +1581,12 @@ begin 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', tgcTX, tgcTY); - 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; + g_Sound_PlayExAt('SOUND_FIRE', tgcTX, tgcTY); + r_GFX_OnceAnim( + R_GFX_FIRE, + 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 + ); if g_Game_IsServer and g_Game_IsNet then 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, @@ -2103,7 +2055,14 @@ begin // Íàíîñèì óðîí èãðîêó if (TriggerType = TRIGGER_DAMAGE) and (tgcAmount > 0) then - p.Damage(tgcAmount, 0, 0, 0, HIT_SOME); + begin + // Êèñëîòíûé óðîí íå íàíîñèòñÿ êîãäà åñòü êîñòþì + // "Âîäÿíîé" óðîí íå íàíîñèòñÿ êîãäà åñòü êèñëîðîä + if not (((tgcKind = HIT_ACID) and (p.FMegaRulez[MR_SUIT] > gTime)) or + ((tgcKind = HIT_WATER) and (p.Air > 0))) then + p.Damage(tgcAmount, 0, 0, 0, tgcKind); + if (tgcKind = HIT_FLAME) then p.CatchFire(0); + end; // Ëå÷èì èãðîêà if (TriggerType = TRIGGER_HEALTH) and (tgcAmount > 0) then @@ -2123,7 +2082,10 @@ begin // Íàíîñèì óðîí ìîíñòðó if (TriggerType = TRIGGER_DAMAGE) and (tgcAmount > 0) then - m.Damage(tgcAmount, 0, 0, 0, HIT_SOME); + begin + m.Damage(tgcAmount, 0, 0, 0, tgcKind); + if (tgcKind = HIT_FLAME) then m.CatchFire(0); + end; // Ëå÷èì ìîíñòðà if (TriggerType = TRIGGER_HEALTH) and (tgcAmount > 0) then @@ -2304,6 +2266,7 @@ begin Dec(idx); end; TimeOut := tgcWait; + result := true; end; end; end; @@ -2315,53 +2278,45 @@ begin end; -function g_Triggers_CreateWithMapIndex (Trigger: TTrigger; arridx, mapidx: Integer): DWORD; +function g_Triggers_CreateWithMapIndex (aTrigger: TTrigger; arridx, mapidx: Integer): DWORD; var triggers: TDynField; begin triggers := gCurrentMap['trigger']; if (triggers = nil) then raise Exception.Create('LOAD: map has no triggers'); if (mapidx < 0) or (mapidx >= triggers.count) then raise Exception.Create('LOAD: invalid map trigger index'); - //Trigger.trigDataRec := triggers.itemAt[mapidx]; - //if (Trigger.trigDataRec = nil) then raise Exception.Create('LOAD: internal error in trigger loader'); - //Trigger.mapId := Trigger.trigDataRec.id; - Trigger.mapIndex := mapidx; - { - if (Trigger.trigDataRec.trigRec <> nil) then - begin - Trigger.trigDataRec := Trigger.trigDataRec.trigRec.clone(nil); - end - else - begin - Trigger.trigDataRec := nil; - end; - } - result := g_Triggers_Create(Trigger, triggers.itemAt[mapidx], arridx); + aTrigger.mapIndex := mapidx; + result := g_Triggers_Create(aTrigger, triggers.itemAt[mapidx], arridx); end; -function g_Triggers_Create(Trigger: TTrigger; trec: TDynRecord; forceInternalIndex: Integer=-1): DWORD; +function g_Triggers_Create (aTrigger: TTrigger; trec: TDynRecord; forceInternalIndex: Integer=-1): DWORD; var find_id: DWORD; - fn, mapw: AnsiString; + fn: AnsiString; f, olen: Integer; + ptg: PTrigger; begin if (tgscope = nil) then tgscope := TTrigScope.Create(); if (tgclist = nil) then tgclist := TMyConstList.Create(); // Íå ñîçäàâàòü âûõîä, åñëè èãðà áåç âûõîäà - if (Trigger.TriggerType = TRIGGER_EXIT) and + if (aTrigger.TriggerType = TRIGGER_EXIT) and (not LongBool(gGameSettings.Options and GAME_OPTION_ALLOWEXIT)) then - Trigger.TriggerType := TRIGGER_NONE; + begin + aTrigger.TriggerType := TRIGGER_NONE; + end; // Åñëè ìîíñòðû çàïðåùåíû, îòìåíÿåì òðèããåð - if (Trigger.TriggerType = TRIGGER_SPAWNMONSTER) and + if (aTrigger.TriggerType = TRIGGER_SPAWNMONSTER) and (not LongBool(gGameSettings.Options and GAME_OPTION_MONSTERS)) and (gGameSettings.GameType <> GT_SINGLE) then - Trigger.TriggerType := TRIGGER_NONE; + begin + aTrigger.TriggerType := TRIGGER_NONE; + end; // Ñ÷èòàåì êîëè÷åñòâî ñåêðåòîâ íà êàðòå - if Trigger.TriggerType = TRIGGER_SECRET then gSecretsCount += 1; + if (aTrigger.TriggerType = TRIGGER_SECRET) then gSecretsCount += 1; if (forceInternalIndex < 0) then begin @@ -2399,37 +2354,35 @@ begin gTriggers[f].userVars := nil; find_id := DWORD(forceInternalIndex); end; - gTriggers[find_id] := Trigger; + gTriggers[find_id] := aTrigger; + ptg := @gTriggers[find_id]; - Trigger.mapId := trec.id; + ptg.mapId := trec.id; // clone trigger data if (trec.trigRec = nil) then begin - gTriggers[find_id].trigDataRec := nil; + ptg.trigDataRec := nil; //HACK! - if (gTriggers[find_id].TriggerType <> TRIGGER_SECRET) then + if (ptg.TriggerType <> TRIGGER_SECRET) then begin - e_LogWritefln('trigger of type %s has no triggerdata; wtf?!', [gTriggers[find_id].TriggerType], MSG_WARNING); + e_LogWritefln('trigger of type %s has no triggerdata; wtf?!', [ptg.TriggerType], TMsgType.Warning); end; end else begin - gTriggers[find_id].trigDataRec := trec.trigRec.clone(nil); + ptg.trigDataRec := trec.trigRec.clone(nil); end; - with gTriggers[find_id] do + with ptg^ do begin ID := find_id; // if this type of trigger exists both on the client and on the server // use an uniform numeration - if Trigger.TriggerType = TRIGGER_SOUND then + ClientID := 0; + if (ptg.TriggerType = TRIGGER_SOUND) then begin Inc(gTriggerClientID); ClientID := gTriggerClientID; - end - else - begin - ClientID := 0; end; TimeOut := 0; ActivateUID := 0; @@ -2445,97 +2398,88 @@ begin end; // update cached trigger variables - trigUpdateCacheData(gTriggers[find_id], gTriggers[find_id].trigDataRec); + trigUpdateCacheData(ptg^, ptg.trigDataRec); - gTriggers[find_id].userVars := nil; //THashStrVariant.Create(hsihash, hsiequ); + ptg.userVars := nil; try - gTriggers[find_id].exoThink := TExprBase.parseStatList(tgclist, VarToStr(trec.user['exoma_think'])); + ptg.exoThink := TExprBase.parseStatList(tgclist, VarToStr(trec.user['exoma_think'])); except on e: TExomaParseException do begin conwritefln('*** ERROR parsing exoma_think (%s,%s): %s [%s]', [e.tokLine, e.tokCol, e.message, VarToStr(trec.user['exoma_think'])]); - gTriggers[find_id].exoThink := nil; + ptg.exoThink := nil; end; else raise; end; try - gTriggers[find_id].exoCheck := TExprBase.parse(tgclist, VarToStr(trec.user['exoma_check'])); + ptg.exoCheck := TExprBase.parse(tgclist, VarToStr(trec.user['exoma_check'])); except on e: TExomaParseException do begin conwritefln('*** ERROR parsing exoma_check (%s,%s): %s [%s]', [e.tokLine, e.tokCol, e.message, VarToStr(trec.user['exoma_check'])]); - gTriggers[find_id].exoCheck := nil; + ptg.exoCheck := nil; end; else raise; end; try - gTriggers[find_id].exoAction := TExprBase.parseStatList(tgclist, VarToStr(trec.user['exoma_action'])); + ptg.exoAction := TExprBase.parseStatList(tgclist, VarToStr(trec.user['exoma_action'])); except on e: TExomaParseException do begin conwritefln('*** ERROR parsing exoma_action (%s,%s): %s [%s]', [e.tokLine, e.tokCol, e.message, VarToStr(trec.user['exoma_action'])]); - gTriggers[find_id].exoAction := nil; + ptg.exoAction := nil; end; else raise; end; try - gTriggers[find_id].exoInit := TExprBase.parseStatList(tgclist, VarToStr(trec.user['exoma_init'])); + ptg.exoInit := TExprBase.parseStatList(tgclist, VarToStr(trec.user['exoma_init'])); except on e: TExomaParseException do begin conwritefln('*** ERROR parsing exoma_init (%s,%s): %s [%s]', [e.tokLine, e.tokCol, e.message, VarToStr(trec.user['exoma_init'])]); - gTriggers[find_id].exoInit := nil; + ptg.exoInit := nil; end; else raise; end; - if (forceInternalIndex < 0) and (gTriggers[find_id].exoInit <> nil) then + if (forceInternalIndex < 0) and (ptg.exoInit <> nil) then begin //conwritefln('executing trigger init: [%s]', [gTriggers[find_id].exoInit.toString()]); try - tgscope.me := @gTriggers[find_id]; - gTriggers[find_id].exoInit.value(tgscope); + tgscope.me := ptg; + ptg.exoInit.value(tgscope); tgscope.me := nil; except tgscope.me := nil; - conwritefln('*** trigger exoactivate error: %s', [gTriggers[find_id].exoInit.toString()]); + conwritefln('*** trigger exoactivate error: %s', [ptg.exoInit.toString()]); exit; end; end; // Çàãðóæàåì çâóê, åñëè ýòî òðèããåð "Çâóê" - if (Trigger.TriggerType = TRIGGER_SOUND) and (Trigger.tgcSoundName <> '') then + if (ptg.TriggerType = TRIGGER_SOUND) and (ptg.tgcSoundName <> '') then begin // Åùå íåò òàêîãî çâóêà - if not g_Sound_Exists(Trigger.tgcSoundName) then + if not g_Sound_Exists(ptg.tgcSoundName) then begin - fn := g_ExtractWadName(Trigger.tgcSoundName); - if fn = '' then - begin // Çâóê â ôàéëå ñ êàðòîé - mapw := g_ExtractWadName(gMapInfo.Map); - fn := mapw+':'+g_ExtractFilePathName(Trigger.tgcSoundName); - end - else // Çâóê â îòäåëüíîì ôàéëå + fn := e_GetResourcePath(WadDirs, ptg.tgcSoundName, g_ExtractWadName(gMapInfo.Map)); + //e_LogWritefln('loading trigger sound ''%s''', [fn]); + if not g_Sound_CreateWADEx(ptg.tgcSoundName, fn) then begin - fn := GameDir + '/wads/' + Trigger.tgcSoundName; - end; - - if not g_Sound_CreateWADEx(Trigger.tgcSoundName, fn) then - begin - g_FatalError(Format(_lc[I_GAME_ERROR_TR_SOUND], [fn, Trigger.tgcSoundName])); + g_FatalError(Format(_lc[I_GAME_ERROR_TR_SOUND], [fn, ptg.tgcSoundName])); end; end; // Ñîçäàåì îáúåêò çâóêà - with gTriggers[find_id] do + with ptg^ do begin Sound := TPlayableSound.Create(); - if not Sound.SetByName(Trigger.tgcSoundName) then + if not Sound.SetByName(ptg.tgcSoundName) then begin Sound.Free(); Sound := nil; @@ -2544,41 +2488,30 @@ begin end; // Çàãðóæàåì ìóçûêó, åñëè ýòî òðèããåð "Ìóçûêà" - if (Trigger.TriggerType = TRIGGER_MUSIC) and (Trigger.tgcMusicName <> '') then + if (ptg.TriggerType = TRIGGER_MUSIC) and (ptg.tgcMusicName <> '') then begin // Åùå íåò òàêîé ìóçûêè - if not g_Sound_Exists(Trigger.tgcMusicName) then + if not g_Sound_Exists(ptg.tgcMusicName) then begin - fn := g_ExtractWadName(Trigger.tgcMusicName); - - if fn = '' then - begin // Ìóçûêà â ôàéëå ñ êàðòîé - mapw := g_ExtractWadName(gMapInfo.Map); - fn := mapw+':'+g_ExtractFilePathName(Trigger.tgcMusicName); - end - else // Ìóçûêà â ôàéëå ñ êàðòîé - begin - fn := GameDir+'/wads/'+Trigger.tgcMusicName; - end; - - if not g_Sound_CreateWADEx(Trigger.tgcMusicName, fn, True) then + fn := e_GetResourcePath(WadDirs, ptg.tgcMusicName, g_ExtractWadName(gMapInfo.Map)); + if not g_Sound_CreateWADEx(ptg.tgcMusicName, fn, True) then begin - g_FatalError(Format(_lc[I_GAME_ERROR_TR_SOUND], [fn, Trigger.tgcMusicName])); + g_FatalError(Format(_lc[I_GAME_ERROR_TR_SOUND], [fn, ptg.tgcMusicName])); end; end; end; // Çàãðóæàåì äàííûå òðèããåðà "Òóðåëü" - if Trigger.TriggerType = TRIGGER_SHOT then + if (ptg.TriggerType = TRIGGER_SHOT) then begin - with gTriggers[find_id] do + with ptg^ do begin ShotPanelTime := 0; ShotSightTime := 0; ShotSightTimeout := 0; ShotSightTarget := 0; ShotSightTargetN := 0; - ShotAmmoCount := Trigger.tgcAmmo; + ShotAmmoCount := ptg.tgcAmmo; ShotReloadTime := 0; end; end; @@ -2615,8 +2548,9 @@ var begin if (tgMonsList = nil) then tgMonsList := TSimpleMonsterList.Create(); - if gTriggers = nil then - Exit; + if gTriggers = nil then Exit; + if gLMSRespawn > LMS_RESPAWN_NONE then Exit; // don't update triggers at all + SetLength(Affected, 0); for a := 0 to High(gTriggers) do @@ -2702,17 +2636,14 @@ begin begin if (SoundPlayCount > 0) and (not Sound.IsPlaying()) then begin - if tgcPlayCount > 0 then SoundPlayCount -= 1; // Åñëè 0 - èãðàåì çâóê áåñêîíå÷íî + if tgcPlayCount > 0 then Dec(SoundPlayCount); (* looped sound if zero *) if tgcLocal then - begin - Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), tgcVolume/255.0); - end + Sound.PlayVolumeAtRect(X, Y, Width, Height, tgcVolume / 255.0) else - begin - Sound.PlayPanVolume((tgcPan-127.0)/128.0, tgcVolume/255.0); - end; - if Sound.IsPlaying() and g_Game_IsNet and g_Game_IsServer then MH_SEND_TriggerSound(gTriggers[a]); - end; + Sound.PlayPanVolume((tgcPan - 127.0) / 128.0, tgcVolume / 255.0); + if Sound.IsPlaying() and g_Game_IsNet and g_Game_IsServer then + MH_SEND_TriggerSound(gTriggers[a]) + end end; // Òðèããåð "Ëîâóøêà" - ïîðà îòêðûâàòü @@ -3072,11 +3003,20 @@ end; procedure g_Triggers_DecreaseSpawner(ID: DWORD); begin if (gTriggers <> nil) then - if gTriggers[ID].SpawnedCount > 0 then - Dec(gTriggers[ID].SpawnedCount); + begin + if gTriggers[ID].tgcMax > 0 then + begin + if gTriggers[ID].SpawnedCount > 0 then + Dec(gTriggers[ID].SpawnedCount); + end; + if gTriggers[ID].tgcDelay > 0 then + begin + if gTriggers[ID].SpawnCooldown < 0 then + gTriggers[ID].SpawnCooldown := gTriggers[ID].tgcDelay; + end; + end; end; - procedure g_Triggers_Free (); var a: Integer; @@ -3347,7 +3287,7 @@ begin if (uvcount < 0) or (uvcount > 1024*1024) then raise XStreamError.Create('invalid number of user vars in trigger'); if (uvcount > 0) then begin - gTriggers[i].userVars := THashStrVariant.Create(hsihash, hsiequ); + gTriggers[i].userVars := THashStrVariant.Create(); vv := Unassigned; while (uvcount > 0) do begin