X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_monsters.pas;h=229748d1e4b0a88165f9cb2319d6ed744b0b3f82;hb=4c4a0406b07cdfd5051e388e8b00f02e008ed140;hp=55a02104f4a56e602de638d507b13490936100cf;hpb=ae5dd5cd82a0c9548c27d2e646de1492e66d98df;p=d2df-sdl.git diff --git a/src/game/g_monsters.pas b/src/game/g_monsters.pas index 55a0210..229748d 100644 --- a/src/game/g_monsters.pas +++ b/src/game/g_monsters.pas @@ -20,7 +20,7 @@ interface uses g_basic, e_graphics, g_phys, g_textures, - g_saveload, BinEditor, g_panel; + g_saveload, BinEditor, g_panel, z_aabbtree; const MONSTATE_SLEEP = 0; @@ -90,6 +90,8 @@ type function findNewPrey(): Boolean; procedure ActivateTriggers(); + function getMapAABB (): AABB2D; inline; + public FNoRespawn: Boolean; FFireTime: Integer; @@ -158,6 +160,8 @@ type property GameAccelY: Integer read FObj.Accel.Y write FObj.Accel.Y; property GameDirection: TDirection read FDirection write FDirection; + property mapAABB: AABB2D read getMapAABB; + property StartID: Integer read FStartID; end; @@ -181,7 +185,7 @@ function g_Monsters_GetKilledBy (MonsterType: Byte): String; type - TEachMonsterCB = function (monidx: Integer; mon: TMonster): Boolean is nested; // return `true` to stop + TEachMonsterCB = function (mon: TMonster): Boolean is nested; // return `true` to stop // throws on invalid uid function g_Mons_ByIdx (uid: Integer): TMonster; inline; @@ -200,6 +204,12 @@ function g_Mons_ForEachAliveAt (x, y: Integer; width, height: Integer; cb: TEach function g_Mons_getNewTrapFrameId (): DWord; +type + TMonsAlongLineCB = function (mon: TMonster; dist: Single): Boolean is nested; + +function g_Mons_alongLine (x0, y0, x1, y1: Integer; cb: TMonsAlongLineCB): TMonster; + + var gmon_debug_use_sqaccel: Boolean = true; @@ -210,7 +220,7 @@ uses e_log, g_main, g_sound, g_gfx, g_player, g_game, g_weapons, g_triggers, MAPDEF, g_items, g_options, g_console, g_map, Math, SysUtils, g_menu, wadreader, - g_language, g_netmsg, z_aabbtree; + g_language, g_netmsg; // ////////////////////////////////////////////////////////////////////////// // @@ -218,6 +228,12 @@ var monCheckTrapLastFrameId: DWord; +function TMonster.getMapAABB (): AABB2D; inline; +begin + result := AABB2D.CreateWH(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y, FObj.Rect.Width, FObj.Rect.Height); +end; + + // ////////////////////////////////////////////////////////////////////////// // type TDynAABBTreeMonsBase = specialize TDynAABBTreeBase; @@ -231,7 +247,8 @@ begin result := false; if (flesh = nil) then raise Exception.Create('DynTree: trying to get dimensions of inexistant monsters'); if (flesh.Obj.Rect.Width < 1) or (flesh.Obj.Rect.Height < 1) then raise Exception.Create('DynTree: monster without size, wtf?!'); - aabb := AABB2D.CreateWH(flesh.Obj.X+flesh.Obj.Rect.X, flesh.Obj.Y+flesh.Obj.Rect.Y, flesh.Obj.Rect.Width, flesh.Obj.Rect.Height); + //aabb := AABB2D.CreateWH(flesh.Obj.X+flesh.Obj.Rect.X, flesh.Obj.Y+flesh.Obj.Rect.Y, flesh.Obj.Rect.Width, flesh.Obj.Rect.Height); + aabb := flesh.getMapAABB(); if not aabb.valid then raise Exception.Create('wutafuuuuuuu?!'); result := true; end; @@ -241,18 +258,48 @@ var monsTree: TDynAABBTreeMons = nil; +function g_Mons_alongLine (x0, y0, x1, y1: Integer; cb: TMonsAlongLineCB): TMonster; + + function sqchecker (mon: TMonster; var ray: Ray2D): Single; + var + aabb: AABB2D; + tmin: Single; + begin + result := -666.0; // invalid + aabb := mon.mapAABB; + if not aabb.valid then exit; + if aabb.intersects(ray, @tmin) then + begin + if (tmin <= 0.0) then tmin := 0.0; + result := tmin; + if cb(mon, tmin) then result := 0.0; // instant stop + end; + end; + +var + qr: TDynAABBTreeMons.TSegmentQueryResult; +begin + result := nil; + if not assigned(cb) then exit; + if monsTree.segmentQuery(qr, x0, y0, x1, y1, sqchecker) then + begin + if (qr.flesh <> nil) then result := qr.flesh; + end; +end; + + //WARNING! call this after monster position was changed, or coldet will not work right! procedure TMonster.positionChanged (); var x, y: Integer; begin - {$IF DEFINED(D2F_DEBUG)} + {$IF DEFINED(D2F_DEBUG_MONS_MOVE)} //e_WriteLog(Format('monster #%d(%u): pos=(%d,%d); rpos=(%d,%d)', [arrIdx, UID, FObj.X, FObj.Y, FObj.Rect.X, FObj.Rect.Y]), MSG_NOTIFY); {$ENDIF} if (treeNode = -1) then begin treeNode := monsTree.insertObject(self, 0); - {$IF DEFINED(D2F_DEBUG)} + {$IF DEFINED(D2F_DEBUG_MONS_MOVE)} monsTree.getNodeXY(treeNode, x, y); e_WriteLog(Format('monster #%d(%u): inserted into the tree; nodeid=%d; x=%d; y=%d', [arrIdx, UID, treeNode, x, y]), MSG_NOTIFY); {$ENDIF} @@ -261,7 +308,7 @@ begin begin monsTree.getNodeXY(treeNode, x, y); if (FObj.X+FObj.Rect.X = x) and (FObj.Y+FObj.Rect.Y = y) then exit; // nothing to do - {$IF DEFINED(D2F_DEBUG)}e_WriteLog(Format('monster #%d(%u): updating tree; nodeid=%d; x=%d; y=%d', [arrIdx, UID, treeNode, x, y]), MSG_NOTIFY);{$ENDIF} + {$IF DEFINED(D2F_DEBUG_MONS_MOVE)}e_WriteLog(Format('monster #%d(%u): updating tree; nodeid=%d; x=%d; y=%d', [arrIdx, UID, treeNode, x, y]), MSG_NOTIFY);{$ENDIF} {$IFDEF TRUE} monsTree.updateObject(treeNode); @@ -270,7 +317,7 @@ begin treeNode := monsTree.insertObject(self); {$ENDIF} - {$IF DEFINED(D2F_DEBUG)} + {$IF DEFINED(D2F_DEBUG_MONS_MOVE)} monsTree.getNodeXY(treeNode, x, y); e_WriteLog(Format('monster #%d(%u): updated tree; nodeid=%d; x=%d; y=%d', [arrIdx, UID, treeNode, x, y]), MSG_NOTIFY); {$ENDIF} @@ -573,6 +620,7 @@ begin Result := False; end; + function BehaviourDamage(SpawnerUID: Word; BH, SelfType: Byte): Boolean; var m: TMonster; @@ -602,6 +650,7 @@ begin end; end; + function canShoot(m: Byte): Boolean; begin Result := False; @@ -614,7 +663,8 @@ begin end; end; -function isCorpse(o: PObj; immediately: Boolean): Integer; + +function isCorpse (o: PObj; immediately: Boolean): Integer; function monsCollCheck (mon: TMonster; atag: Integer): Boolean; begin @@ -1932,7 +1982,7 @@ begin begin if monsTree.isValidId(treeNode) then begin - {$IF DEFINED(D2F_DEBUG)} + {$IF DEFINED(D2F_DEBUG_MONS_MOVE)} e_WriteLog(Format('monster #%d(%u): removed from tree; nodeid=%d', [arrIdx, UID, treeNode]), MSG_NOTIFY); {$ENDIF} monsTree.removeObject(treeNode); @@ -4447,7 +4497,7 @@ begin mon := gMonsters[idx]; if (mon <> nil) then begin - result := cb(idx, gMonsters[idx]); + result := cb(mon); if result then exit; end; end; @@ -4466,7 +4516,7 @@ begin mon := gMonsters[idx]; if (mon <> nil) and mon.Live then begin - result := cb(idx, gMonsters[idx]); + result := cb(mon); if result then exit; end; end; @@ -4513,7 +4563,7 @@ function g_Mons_ForEachAt (x, y: Integer; width, height: Integer; cb: TEachMonst function monsCollCheck (mon: TMonster; atag: Integer): Boolean; begin result := false; - if g_Obj_Collide(x, y, width, height, @mon.Obj) then result := cb(mon.arrIdx, mon); + if g_Obj_Collide(x, y, width, height, @mon.Obj) then result := cb(mon); end; var @@ -4535,7 +4585,7 @@ begin begin if g_Obj_Collide(x, y, width, height, @mon.Obj) then begin - result := cb(idx, mon); + result := cb(mon); if result then exit; end; end; @@ -4549,7 +4599,7 @@ function g_Mons_ForEachAliveAt (x, y: Integer; width, height: Integer; cb: TEach function monsCollCheck (mon: TMonster; atag: Integer): Boolean; begin result := false; - if mon.Live and g_Obj_Collide(x, y, width, height, @mon.Obj) then result := cb(mon.arrIdx, mon); + if mon.Live and g_Obj_Collide(x, y, width, height, @mon.Obj) then result := cb(mon); end; var @@ -4578,7 +4628,7 @@ begin begin if g_Obj_Collide(x, y, width, height, @mon.Obj) then begin - result := cb(idx, mon); + result := cb(mon); if result then exit; end; end;