X-Git-Url: http://deadsoftware.ru/gitweb?p=d2df-sdl.git;a=blobdiff_plain;f=src%2Fgame%2Fg_monsters.pas;h=e37e2e448b5115c204097f6c81c5467e5e01d5ae;hp=81829c6aea292a657ef5f86d3bfbb02b759cb62c;hb=2b4061ae07fe1bf12d49fc1213d7eb3e9e34ccb6;hpb=5472594f32e33da0c66606ec9eebc8f798ef6b54 diff --git a/src/game/g_monsters.pas b/src/game/g_monsters.pas index 81829c6..e37e2e4 100644 --- a/src/game/g_monsters.pas +++ b/src/game/g_monsters.pas @@ -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; @@ -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; @@ -310,9 +316,9 @@ const AnimDeltaRight: ((X: 0; Y: -4), (X: 0; Y: -4), (X: -3; Y: -1), (X: -4; Y: -1), (X: 1; Y: -4), (X: 1; Y: -4), (X: 0; Y: -4)); AnimDeltaLeft: ((X: 0; Y: -4), (X: 0; Y: -4), (X: -3; Y: -1), (X: -4; Y: -1), (X: 1; Y: -4), (X: 1; Y: -4), (X: 0; Y: -4))), - (LeftAnim: True; wX: 70; wY: 73; AnimSpeed:(3, 3, 3, 3, 3, 0, 3); //CYBER - AnimDeltaRight: ((X: 2; Y: -6), (X: 2; Y: -6), (X: -3; Y: -4), (X: -3; Y: -4), (X: 25; Y: -6), (X: 25; Y: -6), (X: -2; Y: -6)); - AnimDeltaLeft: ((X: 3; Y: -3), (X: 3; Y: -3), (X: -3; Y: -4), (X: -3; Y: -4), (X:-26; Y: -3), (X:-26; Y: -3), (X: 1; Y: -3))), + (LeftAnim: True; wX: 70; wY: 73; AnimSpeed:(3, 3, 3, 3, 3, 4, 3); //CYBER + AnimDeltaRight: ((X: 2; Y: -6), (X: 2; Y: -6), (X: -3; Y: -4), (X: -3; Y: -4), (X: 25; Y: -6), (X: 0; Y: -6), (X: -2; Y: -6)); + AnimDeltaLeft: ((X: 3; Y: -3), (X: 3; Y: -3), (X: -3; Y: -4), (X: -3; Y: -4), (X:-26; Y: -3), (X:-1; Y: -3), (X: 1; Y: -3))), (LeftAnim: True; wX: 32; wY: 32; AnimSpeed:(3, 2, 2, 2, 1, 0, 4); //CGUN AnimDeltaRight: ((X: -1; Y: -2), (X: -1; Y: -2), (X: -2; Y: 0), (X: -2; Y: 0), (X: 0; Y: -3), (X: 0; Y: -3), (X: -1; Y: -2)); @@ -658,6 +664,8 @@ begin g_Frames_CreateWAD(nil, 'FRAMES_MONSTER_CYBER_PAIN_L', GameWAD+':MTEXTURES\CYBER_PAIN_L', 128, 128, 1); g_Frames_CreateWAD(nil, 'FRAMES_MONSTER_CYBER_ATTACK', GameWAD+':MTEXTURES\CYBER_ATTACK', 128, 128, 2); g_Frames_CreateWAD(nil, 'FRAMES_MONSTER_CYBER_ATTACK_L', GameWAD+':MTEXTURES\CYBER_ATTACK_L', 128, 128, 2); + g_Frames_CreateWAD(nil, 'FRAMES_MONSTER_CYBER_ATTACK2', GameWAD+':MTEXTURES\CYBER_ATTACK2', 128, 128, 2); + g_Frames_CreateWAD(nil, 'FRAMES_MONSTER_CYBER_ATTACK2_L', GameWAD+':MTEXTURES\CYBER_ATTACK2_L', 128, 128, 2); g_Frames_CreateWAD(nil, 'FRAMES_MONSTER_CYBER_DIE', GameWAD+':MTEXTURES\CYBER_DIE', 128, 128, 9); g_Game_SetLoadingText(_lc[I_LOAD_MONSTER_SOUNDS], 0, False); @@ -874,6 +882,8 @@ begin g_Frames_DeleteByName('FRAMES_MONSTER_CYBER_PAIN_L'); g_Frames_DeleteByName('FRAMES_MONSTER_CYBER_ATTACK'); g_Frames_DeleteByName('FRAMES_MONSTER_CYBER_ATTACK_L'); + g_Frames_DeleteByName('FRAMES_MONSTER_CYBER_ATTACK2'); + g_Frames_DeleteByName('FRAMES_MONSTER_CYBER_ATTACK2_L'); g_Frames_DeleteByName('FRAMES_MONSTER_CYBER_DIE'); g_Sound_Delete('SOUND_MONSTER_BARREL_DIE'); @@ -1264,6 +1274,7 @@ begin Exit; FPainSound := True; + FPainTicks := 20; case FMonsterType of MONSTER_IMP, MONSTER_ZOMBY, MONSTER_SERG, @@ -1271,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); @@ -1472,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 @@ -2011,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); @@ -2037,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; @@ -2134,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; @@ -2258,8 +2296,11 @@ begin if g_Obj_Collide(@FObj, @o) and (FTargetUID <> 0) then begin FTargetTime := 0; - if kick(@o) then - goto _end; + if (FMonsterType <> MONSTER_CYBER) or (Random(2) = 0) then + begin + if kick(@o) then + goto _end; + end; end; // Ðàññòîÿíèå äî öåëè: @@ -2718,13 +2759,13 @@ _end: if g_Weapon_Hit(@FObj, 10, FUID, HIT_SOME) <> 0 then g_Sound_PlayExAt('SOUND_MONSTER_FISH_ATTACK', FObj.X, FObj.Y); - MONSTER_SKEL, MONSTER_ROBO: - // Ðîáîò èëè ñêåëåò ñèëüíî ïèíàþòñÿ: + MONSTER_SKEL, MONSTER_ROBO, MONSTER_CYBER: + // Ðîáîò, êèáåð èëè ñêåëåò ñèëüíî ïèíàþòñÿ: if FCurAnim = ANIM_ATTACK2 then begin o := FObj; - o.Vel.X := IfThen(FDirection = D_RIGHT, 1, -1)*50; - if g_Weapon_Hit(@o, 50, FUID, HIT_SOME) <> 0 then + o.Vel.X := IfThen(FDirection = D_RIGHT, 1, -1)*IfThen(FMonsterType = MONSTER_CYBER, 60, 50); + if g_Weapon_Hit(@o, IfThen(FMonsterType = MONSTER_CYBER, 33, 50), FUID, HIT_SOME) <> 0 then g_Sound_PlayExAt('SOUND_MONSTER_SKEL_HIT', FObj.X, FObj.Y); end; @@ -2941,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); @@ -2960,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; @@ -3046,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; @@ -3471,13 +3528,13 @@ _end: MONSTER_FISH: g_Weapon_Hit(@FObj, 10, FUID, HIT_SOME); - MONSTER_SKEL, MONSTER_ROBO: - // Ðîáîò èëè ñêåëåò ñèëüíî ïèíàþòñÿ: + MONSTER_SKEL, MONSTER_ROBO, MONSTER_CYBER: + // Ðîáîò, êèáåð èëè ñêåëåò ñèëüíî ïèíàþòñÿ: if FCurAnim = ANIM_ATTACK2 then begin o := FObj; - o.Vel.X := IfThen(FDirection = D_RIGHT, 1, -1)*50; - g_Weapon_Hit(@o, 50, FUID, HIT_SOME); + o.Vel.X := IfThen(FDirection = D_RIGHT, 1, -1)*IfThen(FMonsterType = MONSTER_CYBER, 60, 50); + g_Weapon_Hit(@o, IfThen(FMonsterType = MONSTER_CYBER, 33, 50), FUID, HIT_SOME); end; MONSTER_VILE: @@ -3768,13 +3825,7 @@ begin g_Sound_PlayExAt('SOUND_MONSTER_IMP_ATTACK', FObj.X, FObj.Y); Result := True; end; - MONSTER_SKEL: - begin - SetState(STATE_ATTACK, ANIM_ATTACK2); - g_Sound_PlayExAt('SOUND_MONSTER_SKEL_ATTACK', FObj.X, FObj.Y); - Result := True; - end; - MONSTER_ROBO: + MONSTER_SKEL, MONSTER_ROBO, MONSTER_CYBER: begin SetState(STATE_ATTACK, ANIM_ATTACK2); g_Sound_PlayExAt('SOUND_MONSTER_SKEL_ATTACK', FObj.X, FObj.Y); @@ -4131,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.