X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fgame%2Fg_monsters.pas;h=5ad20cc3ebca983fe4ec16bb848e2943e976ef36;hb=e604c9905feb1bef4a5e6e0ffb70e1c33b79d130;hp=85563aa8ec40597b94a4d030022cedc89544d1b4;hpb=62fcda7c1fb3a2153b49af4c5968ec3bdc65b97b;p=d2df-sdl.git diff --git a/src/game/g_monsters.pas b/src/game/g_monsters.pas index 85563aa..5ad20cc 100644 --- a/src/game/g_monsters.pas +++ b/src/game/g_monsters.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_monsters; interface @@ -64,6 +64,7 @@ type FPain: Integer; FSleep: Integer; FPainSound: Boolean; + FPainTicks: Integer; FWaitAttackAnim: Boolean; FChainFire: Boolean; tx, ty: Integer; @@ -75,6 +76,8 @@ type FBloodKind: Byte; FShellTimer: Integer; FShellType: Byte; + FFirePainTime: Integer; + FFireAttacker: Word; vilefire: TAnimation; FDieTriggers: Array of Integer; @@ -86,6 +89,7 @@ type public FNoRespawn: Boolean; + FFireTime: Integer; constructor Create(MonsterType: Byte; aID: Integer; ForcedUID: Integer = -1); destructor Destroy(); override; @@ -96,7 +100,7 @@ type 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(); @@ -121,6 +125,8 @@ type 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; @@ -1268,6 +1274,7 @@ begin Exit; FPainSound := True; + FPainTicks := 20; case FMonsterType of MONSTER_IMP, MONSTER_ZOMBY, MONSTER_SERG, @@ -1275,7 +1282,7 @@ begin 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); @@ -1476,6 +1483,9 @@ begin FNoRespawn := False; FShellTimer := -1; FBehaviour := BH_NORMAL; + FFireTime := 0; + FFirePainTime := 0; + FFireAttacker := 0; if FMonsterType in [MONSTER_ROBO, MONSTER_BARREL] then FBloodKind := BLOOD_SPARKS @@ -1564,7 +1574,7 @@ begin 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; @@ -1594,15 +1604,15 @@ begin // Ðîáîòó óðîíà íåò: 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 @@ -1613,8 +1623,8 @@ begin // Åñëè ðàçðåøåíà êðîâü - ñîçäàåì áðûçãè êðîâè: 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) @@ -2015,7 +2025,10 @@ begin Exit; end; - FPainSound := False; + if FPainTicks > 0 then + Dec(FPainTicks) + else + FPainSound := False; // Äâèãàåìñÿ: st := g_Obj_Move(@FObj, fall, True, True); @@ -2041,6 +2054,25 @@ begin 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; @@ -2138,6 +2170,8 @@ begin FPain := MONSTERTABLE[FMonsterType].Pain; if gSoundEffectsDF then PainSound(); end; + if (not gSoundEffectsDF) and (FPain >= MONSTERTABLE[FMonsterType].MinPain) then + PainSound(); // Ñíèæàåì áîëü ñî âðåìåíåì: FPain := FPain - 5; @@ -2948,7 +2982,10 @@ begin Exit; end; - FPainSound := False; + if FPainTicks > 0 then + Dec(FPainTicks) + else + FPainSound := False; // Äâèãàåìñÿ: st := g_Obj_Move(@FObj, fall, True, True); @@ -2967,6 +3004,17 @@ begin 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; @@ -3053,8 +3101,10 @@ begin 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; @@ -4132,4 +4182,33 @@ begin 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.