index 85563aa8ec40597b94a4d030022cedc89544d1b4..27846f4421f4d34f484698a0a2771fb67fbf5ca4 100644 (file)
--- a/src/game/g_monsters.pas
+++ b/src/game/g_monsters.pas
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*)
-{$MODE DELPHI}
+{$INCLUDE g_amodes.inc}
unit g_monsters;
interface
FPain: Integer;
FSleep: Integer;
FPainSound: Boolean;
+ FPainTicks: Integer;
FWaitAttackAnim: Boolean;
FChainFire: Boolean;
tx, ty: Integer;
FBloodKind: Byte;
FShellTimer: Integer;
FShellType: Byte;
+ FFirePainTime: Integer;
+ FFireAttacker: Word;
vilefire: TAnimation;
FDieTriggers: Array of Integer;
public
FNoRespawn: Boolean;
+ FFireTime: Integer;
constructor Create(MonsterType: Byte; aID: Integer; ForcedUID: Integer = -1);
destructor Destroy(); override;
function Live(): Boolean;
procedure SetHealth(aH: Integer);
procedure Push(vx, vy: Integer);
- function Damage(Damage: Word; VelX, VelY: Integer; SpawnerUID: Word; t: Byte): Boolean;
+ function Damage(aDamage: Word; VelX, VelY: Integer; SpawnerUID: Word; t: Byte): Boolean;
function Heal(Value: Word): Boolean;
procedure BFGHit();
procedure Update();
function AnimIsReverse: Boolean;
function shoot(o: PObj; immediately: Boolean): Boolean;
function kick(o: PObj): Boolean;
+ procedure CatchFire(Attacker: Word);
+ procedure OnFireFlame(Times: DWORD = 1);
property MonsterType: Byte read FMonsterType;
property MonsterHealth: Integer read FHealth write FHealth;
Exit;
FPainSound := True;
+ FPainTicks := 20;
case FMonsterType of
MONSTER_IMP, MONSTER_ZOMBY, MONSTER_SERG,
g_Sound_PlayExAt('SOUND_MONSTER_PAIN', FObj.X, FObj.Y);
MONSTER_SOUL, MONSTER_BARON, MONSTER_CACO,
MONSTER_KNIGHT, MONSTER_DEMON, MONSTER_SPIDER,
- MONSTER_CYBER:
+ MONSTER_BSP, MONSTER_CYBER:
g_Sound_PlayExAt('SOUND_MONSTER_PAIN2', FObj.X, FObj.Y);
MONSTER_VILE:
g_Sound_PlayExAt('SOUND_MONSTER_VILE_PAIN', FObj.X, FObj.Y);
FNoRespawn := False;
FShellTimer := -1;
FBehaviour := BH_NORMAL;
+ FFireTime := 0;
+ FFirePainTime := 0;
+ FFireAttacker := 0;
if FMonsterType in [MONSTER_ROBO, MONSTER_BARREL] then
FBloodKind := BLOOD_SPARKS
vilefire := nil;
end;
-function TMonster.Damage(Damage: Word; VelX, VelY: Integer; SpawnerUID: Word; t: Byte): Boolean;
+function TMonster.Damage(aDamage: Word; VelX, VelY: Integer; SpawnerUID: Word; t: Byte): Boolean;
var
c, it: Integer;
p: TPlayer;
// Ðîáîòó óðîíà íåò:
if FMonsterType = MONSTER_ROBO then
- Damage := 0;
+ aDamage := 0;
// Íàíîñèì óðîí:
- if g_Game_IsServer then Dec(FHealth, Damage);
+ if g_Game_IsServer then Dec(FHealth, aDamage);
// Óñèëèâàåì áîëü ìîíñòðà îò óðîíà:
if FPain = 0 then
FPain := 3;
- FPain := FPain+Damage;
+ FPain := FPain+aDamage;
// Åñëè áîëü ñóùåñòâåííàÿ, òî ìåíÿåì ñîñòîÿíèå íà áîëåâîå:
if FState <> STATE_PAIN then
// Åñëè ðàçðåøåíà êðîâü - ñîçäàåì áðûçãè êðîâè:
if (gBloodCount > 0) then
begin
- c := Min(Damage, 200);
- c := c*gBloodCount - (Damage div 4) + Random(c div 2);
+ c := Min(aDamage, 200);
+ c := c*gBloodCount - (aDamage div 4) + Random(c div 2);
if (VelX = 0) and (VelY = 0) then
MakeBloodSimple(c)
Exit;
end;
- FPainSound := False;
+ if FPainTicks > 0 then
+ Dec(FPainTicks)
+ else
+ FPainSound := False;
// Äâèãàåìñÿ:
st := g_Obj_Move(@FObj, fall, True, True);
if (FState = STATE_DIE) or (FState = STATE_DEAD) then
FObj.Vel.X := z_dec(FObj.Vel.X, 1);
+ if FFireTime > 0 then
+ begin
+ if WordBool(st and MOVE_INWATER) then
+ FFireTime := 0
+ else
+ begin
+ OnFireFlame(1);
+ FFireTime := FFireTime - 1;
+ if (FState <> STATE_DIE) and (FState <> STATE_DEAD) then
+ if FFirePainTime = 0 then
+ begin
+ Damage(5, FFireAttacker, 0, 0, HIT_FLAME);
+ FFirePainTime := 18;
+ end
+ else
+ FFirePainTime := FFirePainTime - 1;
+ end;
+ end;
+
// Ìåðòâûé íè÷åãî íå äåëàåò:
if (FState = STATE_DEAD) then
goto _end;
FPain := MONSTERTABLE[FMonsterType].Pain;
if gSoundEffectsDF then PainSound();
end;
+ if (not gSoundEffectsDF) and (FPain >= MONSTERTABLE[FMonsterType].MinPain) then
+ PainSound();
// Ñíèæàåì áîëü ñî âðåìåíåì:
FPain := FPain - 5;
Exit;
end;
- FPainSound := False;
+ if FPainTicks > 0 then
+ Dec(FPainTicks)
+ else
+ FPainSound := False;
// Äâèãàåìñÿ:
st := g_Obj_Move(@FObj, fall, True, True);
if (FState = STATE_DIE) or (FState = STATE_DEAD) then
FObj.Vel.X := z_dec(FObj.Vel.X, 1);
+ if FFireTime > 0 then
+ begin
+ if WordBool(st and MOVE_INWATER) then
+ FFireTime := 0
+ else
+ begin
+ OnFireFlame(1);
+ FFireTime := FFireTime - 1;
+ end;
+ end;
+
// Ìåðòâûé íè÷åãî íå äåëàåò:
if (FState = STATE_DEAD) then
goto _end;
if FPain >= MONSTERTABLE[FMonsterType].Pain then
begin
FPain := MONSTERTABLE[FMonsterType].Pain;
- PainSound();
+ if gSoundEffectsDF then PainSound();
end;
+ if (not gSoundEffectsDF) and (FPain >= MONSTERTABLE[FMonsterType].MinPain) then
+ PainSound();
// Ñíèæàåì áîëü ñî âðåìåíåì:
FPain := FPain - 5;
SetLength(FDieTriggers, 0);
end;
+procedure TMonster.CatchFire(Attacker: Word);
+begin
+ FFireTime := 100;
+ FFireAttacker := Attacker;
+ if g_Game_IsNet and g_Game_IsServer then
+ MH_SEND_MonsterState(FUID);
+end;
+
+procedure TMonster.OnFireFlame(Times: DWORD = 1);
+var
+ id, i: DWORD;
+ Anim: TAnimation;
+begin
+ if (Random(10) = 1) and (Times = 1) then
+ Exit;
+
+ if g_Frames_Get(id, 'FRAMES_FLAME') then
+ begin
+ for i := 1 to Times do
+ begin
+ Anim := TAnimation.Create(id, False, 3);
+ Anim.Alpha := 0;
+ g_GFX_OnceAnim(Obj.X+Obj.Rect.X+Random(Obj.Rect.Width+Times*2)-(Anim.Width div 2),
+ Obj.Y+8+Random(8+Times*2)+IfThen(FState = STATE_DEAD, 16, 0), Anim, ONCEANIM_SMOKE);
+ Anim.Free();
+ end;
+ end;
+end;
+
end.