index 83714cbdd0ec333d5f9a581bfd35c78aae655fd5..ac28f340a08b8fcd694d0aee764a53a32b086c4c 100644 (file)
--- a/src/game/g_monsters.pas
+++ b/src/game/g_monsters.pas
*
* 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
MONSTATE_REVIVE = 10;
MONSTATE_RUNOUT = 11;
+ MON_BURN_TIME = 100;
+
{ in mapdef now
BH_NORMAL = 0;
BH_KILLER = 1;
function AnimIsReverse: Boolean;
function shoot(o: PObj; immediately: Boolean): Boolean;
function kick(o: PObj): Boolean;
- procedure CatchFire(Attacker: Word);
+ procedure CatchFire(Attacker: Word; Timeout: Integer = MON_BURN_TIME);
procedure OnFireFlame(Times: DWORD = 1);
procedure positionChanged (); //WARNING! call this after monster position was changed, or coldet will not work right!
begin
Result := False;
+// Ìîíñòð ñòàòè÷åí ïîêà èäåò warmup
+ if (gLMSRespawn > LMS_RESPAWN_NONE) then exit;
+
// Óìèðàåò, óìåð èëè âîñêðåøàåòñÿ => óðîí äåëàòü íåêîìó:
if (FState = MONSTATE_DEAD) or (FState = MONSTATE_DIE) or (FState = MONSTATE_REVIVE) then
Exit;
Exit;
end;
+// Àð÷è íå ãîðÿò, ÷åðåïà óæå ãîðÿò
+ if (t = HIT_FLAME) and (FMonsterType in [MONSTER_VILE, MONSTER_SOUL]) then
+ begin
+ // Ïðîñíóòüñÿ âñå-òàêè ñòîèò
+ if FState = MONSTATE_SLEEP then
+ SetState(MONSTATE_GO);
+ Exit;
+ end;
+
// Ëîâóøêà óáèâàåò ñðàçó:
if t = HIT_TRAP then
FHealth := -100;
o, co: TObj;
fall: Boolean;
mon: TMonster;
+ mit: PMonster;
+ it: TMonsterGrid.Iter;
label
_end;
begin
fall := True;
+// Ìîíñòð ñòàòè÷åí ïîêà èäåò warmup
+ if (gLMSRespawn > LMS_RESPAWN_NONE) then exit;
+
// Ðûáû "ëåòàþò" òîëüêî â âîäå:
if FMonsterType = MONSTER_FISH then
if g_Obj_CollidePanel(@FObj, 0, 0, PANEL_WATER or PANEL_ACID1 or PANEL_ACID2) then
st := g_Obj_Move(@FObj, fall, True, True);
positionChanged(); // this updates spatial accelerators
-// Åñëè ãîðèì - ïîäæèãàåì äðóãèõ ìîíñòðîâ:
+// Åñëè ãîðèì - ïîäæèãàåì äðóãèõ ìîíñòðîâ, íî íå íà 100 òèêîâ êàæäûé ðàç:
if FFireTime > 0 then
- for a := 0 to High(gMonsters) do
- if (gMonsters[a] <> nil) and (gMonsters[a].alive) and
- (gMonsters[a].FUID <> FUID) and
- g_Obj_Collide(@FObj, @gMonsters[a].Obj) then
- gMonsters[a].CatchFire(FFireAttacker);
+ begin
+ it := monsGrid.forEachInAABB(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y, FObj.Rect.Width, FObj.Rect.Height);
+ for mit in it do
+ if mit.UID <> FUID then
+ mit.CatchFire(FFireAttacker, FFireTime);
+ end;
// Âûëåòåë çà êàðòó - óäàëÿåì è çàïóñêàåì òðèããåðû:
if WordBool(st and MOVE_FALLOUT) or (FObj.X < -1000) or
sx := 0; // SHUT UP COMPILER
sy := 0;
fall := True;
+
+// Ìîíñòð ñòàòè÷åí ïîêà èäåò warmup
+ if (gLMSRespawn > LMS_RESPAWN_NONE) then exit;
+
// Ðûáû "ëåòàþò" òîëüêî â âîäå:
if FMonsterType = MONSTER_FISH then
if g_Obj_CollidePanel(@FObj, 0, 0, PANEL_WATER or PANEL_ACID1 or PANEL_ACID2) then
SetLength(FDieTriggers, 0);
end;
-procedure TMonster.CatchFire(Attacker: Word);
+procedure TMonster.CatchFire(Attacker: Word; Timeout: Integer = MON_BURN_TIME);
begin
+ if FMonsterType in [MONSTER_SOUL, MONSTER_VILE] then
+ exit; // àð÷è íå ãîðÿò, ÷åðåïà óæå ãîðÿò
+ if Timeout <= 0 then exit;
+ if g_Obj_CollidePanel(@FObj, 0, 0, PANEL_WATER or PANEL_ACID1 or PANEL_ACID2) then
+ exit; // íå ïîäãîðàåì â âîäå íà âñÿêèé ñëó÷àé
if FFireTime <= 0 then
g_Sound_PlayExAt('SOUND_IGNITE', FObj.X, FObj.Y);
- FFireTime := 100;
+ FFireTime := Timeout;
FFireAttacker := Attacker;
if g_Game_IsNet and g_Game_IsServer then MH_SEND_MonsterState(FUID);
end;