X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_monsters.pas;h=690626078d17713d17936ec942a69007ca21ae1d;hb=2f523bed7d04e657b2ce4e69eaf05aee6a81fb4c;hp=cc4926a3135a2a5a97cfa4a3e06e71907eea6008;hpb=2257ac7163318bab560e4351f2b139c9ca4ed9e5;p=d2df-sdl.git diff --git a/src/game/g_monsters.pas b/src/game/g_monsters.pas index cc4926a..6906260 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 @@ -77,6 +77,7 @@ type FShellTimer: Integer; FShellType: Byte; FFirePainTime: Integer; + FFireAttacker: Word; vilefire: TAnimation; FDieTriggers: Array of Integer; @@ -99,12 +100,12 @@ 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(); procedure ClientUpdate(); - procedure ClientAttack(wx, wy, tx, ty: Integer); + procedure ClientAttack(wx, wy, atx, aty: Integer); procedure SetDeadAnim; procedure Draw(); procedure WakeUp(); @@ -124,9 +125,11 @@ type function AnimIsReverse: Boolean; function shoot(o: PObj; immediately: Boolean): Boolean; function kick(o: PObj): Boolean; - procedure CatchFire(); + procedure CatchFire(Attacker: Word); procedure OnFireFlame(Times: DWORD = 1); + procedure positionChanged (); //WARNING! call this after monster position was changed, or coldet will not work right! + property MonsterType: Byte read FMonsterType; property MonsterHealth: Integer read FHealth write FHealth; property MonsterAmmo: Integer read FAmmo write FAmmo; @@ -1446,6 +1449,8 @@ begin FState := STATE_SLEEP; FCurAnim := ANIM_SLEEP; + positionChanged(); // this updates spatial accelerators + if g_Game_IsNet and g_Game_IsServer then begin MH_SEND_MonsterPos(FUID); @@ -1484,6 +1489,7 @@ begin FBehaviour := BH_NORMAL; FFireTime := 0; FFirePainTime := 0; + FFireAttacker := 0; if FMonsterType in [MONSTER_ROBO, MONSTER_BARREL] then FBloodKind := BLOOD_SPARKS @@ -1572,7 +1578,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; @@ -1602,15 +1608,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 @@ -1621,8 +1627,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) @@ -1682,8 +1688,9 @@ begin it := g_Items_Create(FObj.X + (FObj.Rect.Width div 2), FObj.Y + (FObj.Rect.Height div 2), c, True, False); - g_Obj_Push(@gItems[it].Obj, (FObj.Vel.X div 2)-3+Random(7), - (FObj.Vel.Y div 2)-Random(4)); + g_Obj_Push(g_ItemObjByIdx(it), (FObj.Vel.X div 2)-3+Random(7), + (FObj.Vel.Y div 2)-Random(4)); + positionChanged(); // this updates spatial accelerators if g_Game_IsServer and g_Game_IsNet then MH_SEND_ItemSpawn(True, it); end; @@ -2020,6 +2027,7 @@ begin if gTime mod (GAME_TICK*2) <> 0 then begin g_Obj_Move(@FObj, fall, True, True); + positionChanged(); // this updates spatial accelerators Exit; end; @@ -2030,6 +2038,7 @@ begin // Äâèãàåìñÿ: st := g_Obj_Move(@FObj, fall, True, True); + positionChanged(); // this updates spatial accelerators // Âûëåòåë çà êàðòó - óäàëÿåì è çàïóñêàåì òðèããåðû: if WordBool(st and MOVE_FALLOUT) or (FObj.X < -1000) or @@ -2063,7 +2072,7 @@ begin if (FState <> STATE_DIE) and (FState <> STATE_DEAD) then if FFirePainTime = 0 then begin - Damage(5, 0, 0, 0, HIT_FLAME); + Damage(5, FFireAttacker, 0, 0, HIT_FLAME); FFirePainTime := 18; end else @@ -2419,14 +2428,23 @@ begin 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 gGibs[a].Live 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 // Ïèíàåì êóñêè if FObj.Vel.X < 0 then - g_Obj_PushA(@gGibs[a].Obj, b, Random(61)+120) // íàëåâî + 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; + end; end; // Áîññû ìîãóò ïèíàòü òðóïû: if (FMonsterType in [MONSTER_CYBER, MONSTER_SPIDER, MONSTER_ROBO]) and @@ -2977,6 +2995,7 @@ begin if gTime mod (GAME_TICK*2) <> 0 then begin g_Obj_Move(@FObj, fall, True, True); + positionChanged(); // this updates spatial accelerators Exit; end; @@ -2987,6 +3006,7 @@ begin // Äâèãàåìñÿ: st := g_Obj_Move(@FObj, fall, True, True); + positionChanged(); // this updates spatial accelerators // Âûëåòåë çà êàðòó - óäàëÿåì è çàïóñêàåì òðèããåðû: if WordBool(st and MOVE_FALLOUT) or (FObj.X < -1000) or @@ -3240,14 +3260,23 @@ begin 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 gGibs[a].Live 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 // Ïèíàåì êóñêè if FObj.Vel.X < 0 then - g_Obj_PushA(@gGibs[a].Obj, b, Random(61)+120) // íàëåâî + 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; + end; end; // Áîññû ìîãóò ïèíàòü òðóïû: if (FMonsterType in [MONSTER_CYBER, MONSTER_SPIDER, MONSTER_ROBO]) and @@ -3605,7 +3634,7 @@ _end: FAnim[FCurAnim, FDirection].Update(); end; -procedure TMonster.ClientAttack(wx, wy, tx, ty: Integer); +procedure TMonster.ClientAttack(wx, wy, atx, aty: Integer); begin case FMonsterType of MONSTER_ZOMBY: @@ -3631,21 +3660,21 @@ begin g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET); end; MONSTER_IMP: - g_Weapon_ball1(wx, wy, tx, ty, FUID); + g_Weapon_ball1(wx, wy, atx, aty, FUID); MONSTER_CYBER: - g_Weapon_rocket(wx, wy, tx, ty, FUID); + g_Weapon_rocket(wx, wy, atx, aty, FUID); MONSTER_SKEL: - g_Weapon_revf(wx, wy, tx, ty, FUID, FTargetUID); + g_Weapon_revf(wx, wy, atx, aty, FUID, FTargetUID); MONSTER_BSP: - g_Weapon_aplasma(wx, wy, tx, ty, FUID); + g_Weapon_aplasma(wx, wy, atx, aty, FUID); MONSTER_ROBO: - g_Weapon_plasma(wx, wy, tx, ty, FUID); + g_Weapon_plasma(wx, wy, atx, aty, FUID); MONSTER_MANCUB: - g_Weapon_manfire(wx, wy, tx, ty, FUID); + g_Weapon_manfire(wx, wy, atx, aty, FUID); MONSTER_BARON, MONSTER_KNIGHT: - g_Weapon_ball7(wx, wy, tx, ty, FUID); + g_Weapon_ball7(wx, wy, atx, aty, FUID); MONSTER_CACO: - g_Weapon_ball2(wx, wy, tx, ty, FUID); + g_Weapon_ball2(wx, wy, atx, aty, FUID); end; end; @@ -4180,9 +4209,10 @@ begin SetLength(FDieTriggers, 0); end; -procedure TMonster.CatchFire(); +procedure TMonster.CatchFire(Attacker: Word); begin - FFireTime := 360; + FFireTime := 100; + FFireAttacker := Attacker; if g_Game_IsNet and g_Game_IsServer then MH_SEND_MonsterState(FUID); end; @@ -4208,4 +4238,9 @@ begin end; end; +//WARNING! call this after monster position was changed, or coldet will not work right! +procedure TMonster.positionChanged (); +begin +end; + end.