X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_map.pas;h=a73434b9b8c6632bd41dbe63a194dd5376885def;hb=6a553cae9dbb5171d17826cfd19dd0a0b7c0ed8c;hp=0543abe30aa620cb0506c08d8e2c480dc06a0356;hpb=c9a3e1f751cfbf8645a4e75b43204151a5eb962f;p=d2df-sdl.git diff --git a/src/game/g_map.pas b/src/game/g_map.pas index 0543abe..a73434b 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -172,6 +172,9 @@ var function panelTypeToTag (panelType: Word): Integer; // returns GridTagXXX +function g_Map_traceToNearestWall (x0, y0, x1, y1: Integer; hitx: PInteger=nil; hity: PInteger=nil): Integer; + + implementation uses @@ -281,6 +284,74 @@ begin end; +// wall index in `gWalls` or -1 +function g_Map_traceToNearestWall (x0, y0, x1, y1: Integer; hitx: PInteger=nil; hity: PInteger=nil): Integer; +var + maxDistSq: Single; + + function sqchecker (pan: TPanel; var ray: Ray2D): Single; + var + aabb: AABB2D; + tmin: Single; + begin + result := -666.0; // invalid + if not pan.Enabled then exit; + aabb := AABB2D.CreateWH(pan.X, pan.Y, pan.Width, pan.Height); + if not aabb.valid then exit; + if aabb.intersects(ray, @tmin) then + begin + //if (tmin*tmin > maxDistSq) then exit; + if (tmin >= 0.0) then + begin + //e_WriteLog(Format('sqchecker(%d,%d,%d,%d): panel #%d (%d,%d)-(%d,%d); tmin=%f', [x0, y0, x1, y1, pan.arrIdx, pan.X, pan.Y, pan.Width, pan.Height, tmin]), MSG_NOTIFY); + //if (tmin < 0.0) then tmin := 0.0; + result := tmin; + end; + end; + end; + +var + qr: TDynAABBTreeMap.TSegmentQueryResult; + ray: Ray2D; + hxf, hyf: Single; + hx, hy: Integer; +begin + result := -1; + if (mapTree = nil) then exit; + maxDistSq := (x1-x0)*(x1-x0)+(y1-y0)*(y1-y0); + if mapTree.segmentQuery(qr, x0, y0, x1, y1, sqchecker, (GridTagWall or GridTagDoor)) then + begin + if (qr.flesh <> nil) and (qr.time*qr.time <= maxDistSq) then + begin + result := qr.flesh.arrIdx; + if (hitx <> nil) or (hity <> nil) then + begin + ray := Ray2D.Create(x0, y0, x1, y1); + hxf := ray.origX+ray.dirX*qr.time; + hyf := ray.origY+ray.dirY*qr.time; + while true do + begin + hx := trunc(hxf); + hy := trunc(hyf); + if (hx >= qr.flesh.X) and (hy >= qr.flesh.Y) and (hx < qr.flesh.X+qr.flesh.Width) and (hy < qr.flesh.Y+qr.flesh.Height) then + begin + // go back a little + hxf -= ray.dirX; + hyf -= ray.dirY; + end + else + begin + break; + end; + end; + if (hitx <> nil) then hitx^ := hx; + if (hity <> nil) then hity^ := hy; + end; + end; + end; +end; + + function g_Map_IsSpecialTexture(Texture: String): Boolean; begin Result := (Texture = TEXTURE_NAME_WATER) or @@ -935,45 +1006,52 @@ end; procedure CreateMonster(monster: TMonsterRec_1); var - a, i: Integer; + a: Integer; + mon: TMonster; begin if g_Game_IsClient then Exit; if (gGameSettings.GameType = GT_SINGLE) or LongBool(gGameSettings.Options and GAME_OPTION_MONSTERS) then begin - i := g_Monsters_Create(monster.MonsterType, monster.X, monster.Y, - TDirection(monster.Direction)); + mon := g_Monsters_Create(monster.MonsterType, monster.X, monster.Y, TDirection(monster.Direction)); if gTriggers <> nil then + begin for a := 0 to High(gTriggers) do - if gTriggers[a].TriggerType in [TRIGGER_PRESS, - TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then - if (gTriggers[a].Data.MonsterID-1) = gMonsters[i].StartID then - gMonsters[i].AddTrigger(a); + begin + if gTriggers[a].TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then + begin + if (gTriggers[a].Data.MonsterID-1) = mon.StartID then mon.AddTrigger(a); + end; + end; + end; - if monster.MonsterType <> MONSTER_BARREL then - Inc(gTotalMonsters); + if monster.MonsterType <> MONSTER_BARREL then Inc(gTotalMonsters); end; end; procedure g_Map_ReAdd_DieTriggers(); -var - i, a: Integer; -begin - if g_Game_IsClient then Exit; - for i := 0 to High(gMonsters) do - if gMonsters[i] <> nil then + function monsDieTrig (mon: TMonster): Boolean; + var + a: Integer; + begin + result := false; // don't stop + mon.ClearTriggers(); + for a := 0 to High(gTriggers) do + begin + if gTriggers[a].TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then begin - gMonsters[i].ClearTriggers(); - - for a := 0 to High(gTriggers) do - if gTriggers[a].TriggerType in [TRIGGER_PRESS, - TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then - if (gTriggers[a].Data.MonsterID-1) = gMonsters[i].StartID then - gMonsters[i].AddTrigger(a); + if (gTriggers[a].Data.MonsterID-1) = mon.StartID then mon.AddTrigger(a); end; + end; + end; + +begin + if g_Game_IsClient then Exit; + + g_Mons_ForEach(monsDieTrig); end; function extractWadName(resourceName: string): string; @@ -1026,7 +1104,7 @@ var mapX1: Integer = -$3fffffff; mapY1: Integer = -$3fffffff; - procedure calcBoundingBox (var panels: TPanelArray); + procedure calcBoundingBox (constref panels: TPanelArray); var idx: Integer; pan: TPanel; @@ -1043,7 +1121,7 @@ var end; end; - procedure addPanelsToGrid (var panels: TPanelArray; tag: Integer); + procedure addPanelsToGrid (constref panels: TPanelArray; tag: Integer); var idx: Integer; pan: TPanel; @@ -1890,7 +1968,7 @@ end; // old algo procedure g_Map_DrawPanels (PanelType: Word); - procedure DrawPanels (var panels: TPanelArray; drawDoors: Boolean=False); + procedure DrawPanels (constref panels: TPanelArray; drawDoors: Boolean=False); var idx: Integer; begin @@ -2094,7 +2172,7 @@ function g_Map_CollideLiquid_TextureOld(X, Y: Integer; Width, Height: Word): DWO var texid: DWORD; - function checkPanels (var panels: TPanelArray): Boolean; + function checkPanels (constref panels: TPanelArray): Boolean; var a: Integer; begin