X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_monsters.pas;h=fbb75a56f1929a1b0b66cc734f6aa29f522287fb;hb=55f201758f237cac6c889e98572e6eda7c4067fc;hp=3301dd4c61263cdd719bb977c4bf813637f42f86;hpb=e979719019322a78e7fded8fd96130c18cf31972;p=d2df-sdl.git diff --git a/src/game/g_monsters.pas b/src/game/g_monsters.pas index 3301dd4..fbb75a5 100644 --- a/src/game/g_monsters.pas +++ b/src/game/g_monsters.pas @@ -81,12 +81,16 @@ type tx, ty: Integer; FStartID: Integer; FObj: TObj; - FBloodRed: Byte; - FBloodGreen: Byte; - FBloodBlue: Byte; - FBloodKind: Byte; - FShellTimer: Integer; - FShellType: Byte; + {$IFDEF ENABLE_GFX} + FBloodRed: Byte; + FBloodGreen: Byte; + FBloodBlue: Byte; + FBloodKind: Byte; + {$ENDIF} + {$IFDEF ENABLE_SHELLS} + FShellTimer: Integer; + FShellType: Byte; + {$ENDIF} FFirePainTime: Integer; FFireAttacker: Word; vilefire: TAnimationState; @@ -521,10 +525,19 @@ var implementation uses - {$IFNDEF HEADLESS} + {$IFDEF ENABLE_MENU} g_menu, {$ENDIF} - e_log, g_sound, g_gfx, g_player, g_game, + {$IFDEF ENABLE_GFX} + g_gfx, + {$ENDIF} + {$IFDEF ENABLE_GIBS} + g_gibs, + {$ENDIF} + {$IFDEF ENABLE_SHELLS} + g_shells, + {$ENDIF} + e_log, g_sound, g_player, g_game, g_weapons, g_triggers, g_items, g_options, g_console, g_map, Math, wadreader, g_language, g_netmsg, idpool, utils, xstreams; @@ -1583,7 +1596,9 @@ begin FDieTriggers := nil; FWaitAttackAnim := False; FChainFire := False; - FShellTimer := -1; + {$IFDEF ENABLE_SHELLS} + FShellTimer := -1; + {$ENDIF} FState := MONSTATE_SLEEP; FCurAnim := ANIM_SLEEP; @@ -1620,7 +1635,9 @@ begin FChainFire := False; FStartID := aID; FNoRespawn := False; - FShellTimer := -1; + {$IFDEF ENABLE_SHELLS} + FShellTimer := -1; + {$ENDIF} FBehaviour := BH_NORMAL; FFireTime := 0; FFirePainTime := 0; @@ -1633,6 +1650,7 @@ begin mplatCheckFrameId := 0; mNeedSend := false; +{$IFDEF ENABLE_GFX} if FMonsterType in [MONSTER_ROBO, MONSTER_BARREL] then FBloodKind := BLOOD_SPARKS else @@ -1655,6 +1673,7 @@ begin FBloodGreen := 0; FBloodBlue := 0; end; +{$ENDIF} SetLength(FAnim, Length(ANIMTABLE)); for a := ANIM_SLEEP to ANIM_PAIN do @@ -1663,7 +1682,7 @@ begin FAnim[a, TDirection.D_LEFT] := TAnimationState.Create(ANIMTABLE[a].loop, MONSTER_ANIMTABLE[MonsterType].AnimSpeed[a], MONSTER_ANIMTABLE[MonsterType].AnimCount[a]); end; if MonsterType = MONSTER_VILE then - vilefire := TAnimationState.Create(True, 2, 0); // !!! len + vilefire := TAnimationState.Create(True, 2, 8); end; function TMonster.Damage(aDamage: Word; VelX, VelY: Integer; SpawnerUID: Word; t: Byte): Boolean; @@ -1888,6 +1907,7 @@ end; procedure TMonster.MakeBloodSimple(Count: Word); begin +{$IFDEF ENABLE_GFX} g_GFX_Blood(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2)+8, FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), Count div 2, 3, -1, 16, (FObj.Rect.Height*2 div 3), @@ -1896,14 +1916,17 @@ begin FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), Count div 2, -3, -1, 16, (FObj.Rect.Height*2) div 3, FBloodRed, FBloodGreen, FBloodBlue, FBloodKind); +{$ENDIF} end; procedure TMonster.MakeBloodVector(Count: Word; VelX, VelY: Integer); begin +{$IFDEF ENABLE_GFX} g_GFX_Blood(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), Count, VelX, VelY, 16, (FObj.Rect.Height*2) div 3, FBloodRed, FBloodGreen, FBloodBlue, FBloodKind); +{$ENDIF} end; procedure TMonster.Push(vx, vy: Integer); @@ -1987,12 +2010,13 @@ begin if not silent then begin g_Sound_PlayExAt('SOUND_GAME_TELEPORT', Obj.X, Obj.Y); +{$IFDEF ENABLE_GFX} g_GFX_QueueEffect( R_GFX_TELEPORT, FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2)-32, FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2)-32 ); - +{$ENDIF} if g_Game_IsServer and g_Game_IsNet then MH_SEND_Effect(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2)-32, FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2)-32, 1, @@ -2022,12 +2046,13 @@ begin // Эффект телепорта в точке назначения: if not silent then begin +{$IFDEF ENABLE_GFX} g_GFX_QueueEffect( R_GFX_TELEPORT, FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2)-32, FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2)-32 ); - +{$ENDIF} if g_Game_IsServer and g_Game_IsNet then MH_SEND_Effect(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2)-32, FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2)-32, 0, @@ -2157,15 +2182,43 @@ begin if WordBool(st and MOVE_INWATER) and (Random(32) = 0) then case FMonsterType of MONSTER_FISH: - if Random(4) = 0 then - g_GFX_Bubbles(FObj.X+FObj.Rect.X + Random(FObj.Rect.Width), - FObj.Y+FObj.Rect.Y + Random(4), 1, 0, 0); + begin + {$IFDEF ENABLE_GFX} + if Random(4) = 0 then + begin + g_GFX_Bubbles( + FObj.X + FObj.Rect.X + Random(FObj.Rect.Width), + FObj.Y + FObj.Rect.Y + Random(4), + 1, + 0, + 0 + ); + end; + {$ENDIF} + end; MONSTER_ROBO, MONSTER_BARREL: - g_GFX_Bubbles(FObj.X+FObj.Rect.X + Random(FObj.Rect.Width), - FObj.Y+FObj.Rect.Y + Random(4), 1, 0, 0); - else begin - g_GFX_Bubbles(FObj.X+FObj.Rect.X + Random(FObj.Rect.Width-4), - FObj.Y+FObj.Rect.Y + Random(4), 5, 4, 4); + begin + {$IFDEF ENABLE_GFX} + g_GFX_Bubbles( + FObj.X + FObj.Rect.X + Random(FObj.Rect.Width), + FObj.Y + FObj.Rect.Y + Random(4), + 1, + 0, + 0 + ); + {$ENDIF} + end; + else + begin + {$IFDEF ENABLE_GFX} + g_GFX_Bubbles( + FObj.X + FObj.Rect.X + Random(FObj.Rect.Width - 4), + FObj.Y+FObj.Rect.Y + Random(4), + 5, + 4, + 4 + ); + {$ENDIF} if Random(2) = 0 then g_Sound_PlayExAt('SOUND_GAME_BUBBLE1', FObj.X, FObj.Y) else @@ -2199,25 +2252,35 @@ begin // Таймер - ждем после потери цели: FTargetTime := FTargetTime + 1; -// Гильзы +{$IFDEF ENABLE_SHELLS} + // Гильзы if FShellTimer > -1 then + begin if FShellTimer = 0 then begin if FShellType = SHELL_SHELL then - g_Player_CreateShell(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), + begin + g_Shells_Create(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), GameVelX, GameVelY-2, SHELL_SHELL) + end else if FShellType = SHELL_DBLSHELL then begin - g_Player_CreateShell(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), + g_Shells_Create(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), GameVelX-1, GameVelY-2, SHELL_SHELL); - g_Player_CreateShell(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), + g_Shells_Create(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), GameVelX+1, GameVelY-2, SHELL_SHELL); end; FShellTimer := -1; - end else Dec(FShellTimer); + end + else + begin + Dec(FShellTimer); + end; + end; +{$ENDIF} // Пробуем увернуться от летящей пули: if fall then @@ -2482,29 +2545,31 @@ begin end else // "Наземные" монстры begin - // Возможно, пинаем куски: - if (FObj.Vel.X <> 0) and (gGibs <> nil) then - begin - b := Abs(FObj.Vel.X); - if b > 1 then b := b * (Random(8 div b) + 1); - for a := 0 to High(gGibs) do + {$IFDEF ENABLE_GIBS} + // Возможно, пинаем куски: + if (FObj.Vel.X <> 0) and (gGibs <> nil) then begin - if gGibs[a].alive and - g_Obj_Collide(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y+FObj.Rect.Height-4, - FObj.Rect.Width, 8, @gGibs[a].Obj) and (Random(3) = 0) then + b := Abs(FObj.Vel.X); + if b > 1 then b := b * (Random(8 div b) + 1); + for a := 0 to High(gGibs) do begin - // Пинаем куски - if FObj.Vel.X < 0 then + if gGibs[a].alive and + g_Obj_Collide(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y+FObj.Rect.Height-4, + FObj.Rect.Width, 8, @gGibs[a].Obj) and (Random(3) = 0) then begin - g_Obj_PushA(@gGibs[a].Obj, b, Random(61)+120); // налево - end - else - begin - g_Obj_PushA(@gGibs[a].Obj, b, Random(61)); // направо + // Пинаем куски + if FObj.Vel.X < 0 then + begin + g_Obj_PushA(@gGibs[a].Obj, b, Random(61)+120); // налево + end + else + begin + g_Obj_PushA(@gGibs[a].Obj, b, Random(61)); // направо + end; end; end; end; - end; + {$ENDIF} // Боссы могут пинать трупы: if (FMonsterType in [MONSTER_CYBER, MONSTER_SPIDER, MONSTER_ROBO]) and (FObj.Vel.X <> 0) and (gCorpses <> nil) then @@ -2896,20 +2961,26 @@ _end: begin g_Sound_PlayExAt('SOUND_WEAPON_FIREPISTOL', wx, wy); g_Weapon_gun(wx, wy, tx, ty, 1, 3, FUID, True); - g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_BULLET); + {$ENDIF} end; MONSTER_SERG: begin g_Weapon_shotgun(wx, wy, tx, ty, FUID); if not gSoundEffectsDF then g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN', wx, wy); - FShellTimer := 10; - FShellType := SHELL_SHELL; + {$IFDEF ENABLE_SHELLS} + FShellTimer := 10; + FShellType := SHELL_SHELL; + {$ENDIF} end; MONSTER_MAN: begin g_Weapon_dshotgun(wx, wy, tx, ty, FUID); - FShellTimer := 13; - FShellType := SHELL_DBLSHELL; + {$IFDEF ENABLE_SHELLS} + FShellTimer := 13; + FShellType := SHELL_DBLSHELL; + {$ENDIF} FAmmo := -36; end; MONSTER_CYBER: @@ -2923,13 +2994,17 @@ _end: begin g_Weapon_mgun(wx, wy, tx, ty, FUID); if not gSoundEffectsDF then g_Sound_PlayExAt('SOUND_WEAPON_FIRECGUN', wx, wy); - g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_BULLET); + {$ENDIF} end; MONSTER_SPIDER: begin g_Weapon_mgun(wx, wy, tx, ty, FUID); if not gSoundEffectsDF then g_Sound_PlayExAt('SOUND_WEAPON_FIRECGUN', wx, wy); - g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_SHELL); + {$ENDIF} end; MONSTER_BSP: g_Weapon_aplasma(wx, wy, tx, ty, FUID); @@ -3118,15 +3193,43 @@ begin if WordBool(st and MOVE_INWATER) and (Random(32) = 0) then case FMonsterType of MONSTER_FISH: - if Random(4) = 0 then - g_GFX_Bubbles(FObj.X+FObj.Rect.X + Random(FObj.Rect.Width), - FObj.Y+FObj.Rect.Y + Random(4), 1, 0, 0); + begin + {$IFDEF ENABLE_GFX} + if Random(4) = 0 then + begin + g_GFX_Bubbles( + FObj.X + FObj.Rect.X + Random(FObj.Rect.Width), + FObj.Y + FObj.Rect.Y + Random(4), + 1, + 0, + 0 + ); + end; + {$ENDIF} + end; MONSTER_ROBO, MONSTER_BARREL: - g_GFX_Bubbles(FObj.X+FObj.Rect.X + Random(FObj.Rect.Width), - FObj.Y+FObj.Rect.Y + Random(4), 1, 0, 0); - else begin - g_GFX_Bubbles(FObj.X+FObj.Rect.X + Random(FObj.Rect.Width-4), - FObj.Y+FObj.Rect.Y + Random(4), 5, 4, 4); + begin + {$IFDEF ENABLE_GFX} + g_GFX_Bubbles( + FObj.X + FObj.Rect.X + Random(FObj.Rect.Width), + FObj.Y + FObj.Rect.Y + Random(4), + 1, + 0, + 0 + ); + {$ENDIF} + end; + else + begin + {$IFDEF ENABLE_GFX} + g_GFX_Bubbles( + FObj.X + FObj.Rect.X + Random(FObj.Rect.Width - 4), + FObj.Y + FObj.Rect.Y + Random(4), + 5, + 4, + 4 + ); + {$ENDIF} if Random(2) = 0 then g_Sound_PlayExAt('SOUND_GAME_BUBBLE1', FObj.X, FObj.Y) else @@ -3160,24 +3263,34 @@ begin // Таймер - ждем после потери цели: FTargetTime := FTargetTime + 1; +{$IFDEF ENABLE_SHELLS} if FShellTimer > -1 then + begin if FShellTimer = 0 then begin if FShellType = SHELL_SHELL then - g_Player_CreateShell(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), + begin + g_Shells_Create(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), GameVelX, GameVelY-2, SHELL_SHELL) + end else if FShellType = SHELL_DBLSHELL then begin - g_Player_CreateShell(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), + g_Shells_Create(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), GameVelX-1, GameVelY-2, SHELL_SHELL); - g_Player_CreateShell(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), + g_Shells_Create(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2), FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2), GameVelX+1, GameVelY-2, SHELL_SHELL); end; FShellTimer := -1; - end else Dec(FShellTimer); + end + else + begin + Dec(FShellTimer); + end; + end; +{$ENDIF} // Пробуем увернуться от летящей пули: if fall then @@ -3331,30 +3444,32 @@ begin end else // "Наземные" монстры begin - // Возможно, пинаем куски: - if (FObj.Vel.X <> 0) and (gGibs <> nil) then - begin - b := Abs(FObj.Vel.X); - if b > 1 then b := b * (Random(8 div b) + 1); - for a := 0 to High(gGibs) do + {$IFDEF ENBALE_GIBS} + // Возможно, пинаем куски: + if (FObj.Vel.X <> 0) and (gGibs <> nil) then begin - if gGibs[a].alive and - g_Obj_Collide(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y+FObj.Rect.Height-4, - FObj.Rect.Width, 8, @gGibs[a].Obj) and (Random(3) = 0) then + b := Abs(FObj.Vel.X); + if b > 1 then b := b * (Random(8 div b) + 1); + for a := 0 to High(gGibs) do begin - // Пинаем куски - if FObj.Vel.X < 0 then - begin - g_Obj_PushA(@gGibs[a].Obj, b, Random(61)+120); // налево - end - else + if gGibs[a].alive and + g_Obj_Collide(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y+FObj.Rect.Height-4, + FObj.Rect.Width, 8, @gGibs[a].Obj) and (Random(3) = 0) then begin - g_Obj_PushA(@gGibs[a].Obj, b, Random(61)); // направо + // Пинаем куски + if FObj.Vel.X < 0 then + begin + g_Obj_PushA(@gGibs[a].Obj, b, Random(61)+120); // налево + end + else + begin + g_Obj_PushA(@gGibs[a].Obj, b, Random(61)); // направо + end; + positionChanged(); // this updates spatial accelerators end; - positionChanged(); // this updates spatial accelerators end; end; - end; + {$ENDIF} // Боссы могут пинать трупы: if (FMonsterType in [MONSTER_CYBER, MONSTER_SPIDER, MONSTER_ROBO]) and (FObj.Vel.X <> 0) and (gCorpses <> nil) then @@ -3717,24 +3832,32 @@ begin MONSTER_ZOMBY: begin g_Sound_PlayExAt('SOUND_WEAPON_FIREPISTOL', wx, wy); - g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_BULLET); + {$ENDIF} end; MONSTER_SERG: begin g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN', wx, wy); - FShellTimer := 10; - FShellType := SHELL_SHELL; + {$IFDEF ENABLE_SHELLS} + FShellTimer := 10; + FShellType := SHELL_SHELL; + {$ENDIF} end; MONSTER_MAN: begin g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN2', wx, wy); - FShellTimer := 13; - FShellType := SHELL_DBLSHELL; + {$IFDEF ENABLE_SHELLS} + FShellTimer := 13; + FShellType := SHELL_DBLSHELL; + {$ENDIF} end; MONSTER_CGUN, MONSTER_SPIDER: begin g_Sound_PlayExAt('SOUND_WEAPON_FIRECGUN', wx, wy); - g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET); + {$IFDEF ENABLE_SHELLS} + g_Shells_Create(wx, wy, 0, -2, SHELL_BULLET); + {$ENDIF} end; MONSTER_IMP: g_Weapon_ball1(wx, wy, atx, aty, FUID); @@ -4140,7 +4263,7 @@ begin anim := (vilefire <> nil); utils.writeBool(st, anim); // Если есть - сохраняем: - if anim then vilefire.SaveState(st); + if anim then vilefire.SaveState(st, 0, False); // Анимации for i := ANIM_SLEEP to ANIM_PAIN do begin @@ -4148,12 +4271,12 @@ begin anim := (FAnim[i, TDirection.D_LEFT] <> nil); utils.writeBool(st, anim); // Если есть - сохраняем - if anim then FAnim[i, TDirection.D_LEFT].SaveState(st); + if anim then FAnim[i, TDirection.D_LEFT].SaveState(st, 0, False); // Есть ли правая анимация anim := (FAnim[i, TDirection.D_RIGHT] <> nil); utils.writeBool(st, anim); // Если есть - сохраняем - if anim then FAnim[i, TDirection.D_RIGHT].SaveState(st); + if anim then FAnim[i, TDirection.D_RIGHT].SaveState(st, 0, False); end; end; @@ -4161,8 +4284,8 @@ end; procedure TMonster.LoadState (st: TStream); var i: Integer; - b: Byte; - anim: Boolean; + b, alpha: Byte; + anim, blending: Boolean; begin assert(st <> nil); @@ -4222,7 +4345,7 @@ begin if anim then begin Assert(vilefire <> nil, 'TMonster.LoadState: no vilefire anim'); - vilefire.LoadState(st); + vilefire.LoadState(st, alpha, blending); end; // Анимации for i := ANIM_SLEEP to ANIM_PAIN do @@ -4233,7 +4356,7 @@ begin if anim then begin Assert(FAnim[i, TDirection.D_LEFT] <> nil, 'TMonster.LoadState: no '+IntToStr(i)+'_left anim'); - FAnim[i, TDirection.D_LEFT].LoadState(st); + FAnim[i, TDirection.D_LEFT].LoadState(st, alpha, blending); end; // Есть ли правая анимация anim := utils.readBool(st); @@ -4241,7 +4364,7 @@ begin if anim then begin Assert(FAnim[i, TDirection.D_RIGHT] <> nil, 'TMonster.LoadState: no '+IntToStr(i)+'_right anim'); - FAnim[i, TDirection.D_RIGHT].LoadState(st); + FAnim[i, TDirection.D_RIGHT].LoadState(st, alpha, blending); end; end; end; @@ -4287,17 +4410,20 @@ begin end; procedure TMonster.OnFireFlame(Times: DWORD = 1); - var i: DWORD; x, y: Integer; + {$IFDEF ENABLE_GFX} + var i: DWORD; x, y: Integer; + {$ENDIF} begin - if (Random(10) = 1) and (Times = 1) then - Exit; - - for i := 1 to Times do - begin - x := Obj.X + Obj.Rect.X + Random(Obj.Rect.Width + Times * 2) - (R_GFX_FLAME_WIDTH div 2); - y := Obj.Y + 8 + Random(8 + Times * 2) + IfThen(FState = MONSTATE_DEAD, 16, 0); - g_GFX_QueueEffect(R_GFX_FLAME, x, y); - end; + {$IFDEF ENABLE_GFX} + if (Random(10) = 1) and (Times = 1) then + Exit; + for i := 1 to Times do + begin + x := Obj.X + Obj.Rect.X + Random(Obj.Rect.Width + Times * 2) - (R_GFX_FLAME_WIDTH div 2); + y := Obj.Y + 8 + Random(8 + Times * 2) + IfThen(FState = MONSTATE_DEAD, 16, 0); + g_GFX_QueueEffect(R_GFX_FLAME, x, y); + end; + {$ENDIF} end;