World of Might and Magic  0.2.0
Open reimplementation of Might and Magic 6 7 8 game engine
Indoor.cpp
См. документацию.
2 
3 #include <algorithm>
4 
5 #include "Engine/Engine.h"
6 #include "Engine/Events.h"
7 #include "Engine/LOD.h"
9 #include "Engine/Time.h"
10 #include "Engine/ZlibWrapper.h"
11 #include "Engine/stru367.h"
12 
14 
19 #include "Engine/Graphics/stru10.h"
20 #include "Engine/Graphics/stru9.h"
21 
22 #include "Engine/Objects/Actor.h"
23 #include "Engine/Objects/Chest.h"
26 
28 
29 #include "GUI/GUIProgressBar.h"
30 #include "GUI/GUIWindow.h"
31 #include "GUI/UI/UIStatusBar.h"
32 
34 
35 #include "Platform/Api.h"
36 
37 #include "../OurMath.h"
38 #include "../Party.h"
39 #include "../stru123.h"
40 #include "DecorationList.h"
41 #include "Level/Decoration.h"
42 #include "Lights.h"
43 #include "Outdoor.h"
44 #include "Overlays.h"
45 #include "ParticleEngine.h"
46 #include "Sprites.h"
47 #include "Viewport.h"
48 
51 
53 
54 LightsData Lights; // stru_F8AD28
59 std::array<stru352, 480> stru_F83B80;
60 
61 unsigned __int16 pDoorSoundIDsByLocationID[78] = {
62  300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
63  300, 300, 300, 404, 302, 306, 308, 304, 308, 302, 400, 302, 300,
64  308, 308, 306, 308, 308, 304, 300, 404, 406, 300, 400, 406, 404,
65  306, 302, 408, 304, 300, 300, 300, 300, 300, 300, 300, 300, 300,
66  300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 404, 304,
67  400, 300, 300, 404, 304, 400, 300, 300, 404, 304, 400, 300, 300};
68 
69 std::array<const char *, 11> _4E6BDC_loc_names = {
70  "mdt12.blv", "d18.blv", "mdt14.blv", "d37.blv",
71  "mdk01.blv", "mdt01.blv", "mdr01.blv", "mdt10.blv",
72  "mdt09.blv", "mdt15.blv", "mdt11.blv"};
73 
75  memcpy(&this->pFacePlane, &data->pFacePlane, sizeof(this->pFacePlane));
76  memcpy(&this->pFacePlane_old, &data->pFacePlane_old,
77  sizeof(this->pFacePlane_old));
78  this->zCalc1 = data->zCalc1;
79  this->zCalc2 = data->zCalc2;
80  this->zCalc3 = data->zCalc3;
81  this->uAttributes = data->uAttributes;
82  this->pVertexIDs = data->pVertexIDs;
86  this->pVertexUIDs = data->pVertexUIDs;
87  this->pVertexVIDs = data->pVertexVIDs;
88  this->uFaceExtraID = data->uFaceExtraID;
89  // unsigned __int16 uBitmapID;
90  this->uSectorID = data->uSectorID;
91  this->uBackSectorID = data->uBackSectorID;
92  memcpy(&this->pBounding, &data->pBounding, sizeof(this->pBounding));
93  this->uPolygonType = (PolygonType)data->uPolygonType;
94  this->uNumVertices = data->uNumVertices;
95  this->field_5E = data->field_5E;
96  this->field_5F = data->field_5F;
97 
98  return true;
99 }
100 
101 //----- (0043F39E) --------------------------------------------------------
103  int TorchLightPower; // eax@4
104  unsigned int v7; // ebx@8
105  BLVSector *v8; // esi@8
106 
109  // uNumMobileLightsApplied = 0;
113 
114  if (!_4D864C_force_sw_render_rules || !engine->config->TorchlightEffect()) { // lightspot around party
115  TorchLightPower = 800;
116  if (pParty->TorchlightActive()) {
117  // max is 800 * torchlight
118  // min is 800
119  int MinTorch = TorchLightPower;
120  int MaxTorch = TorchLightPower * pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uPower;
121 
122  // TorchLightPower *= pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uPower; // 2,3,4
123  int ran = rand();
124  int mod = ((ran - (RAND_MAX * .4)) / 200);
125  TorchLightPower = (pParty->TorchLightLastIntensity + mod);
126 
127  // clamp
128  if (TorchLightPower < MinTorch)
129  TorchLightPower = MinTorch;
130  if (TorchLightPower > MaxTorch)
131  TorchLightPower = MaxTorch;
132  }
133 
134  pParty->TorchLightLastIntensity = TorchLightPower;
135 
136  // double nexLightIntensity(lastIntensity)
137  // return clamp(0, 1, lastIntensity + (rand() - .3) / 100)
138 
142  floorf(pParty->flt_TorchlightColorR + 0.5f),
143  floorf(pParty->flt_TorchlightColorG + 0.5f),
145  }
146 
150 
151  for (uint i = 0; i < pBspRenderer->uNumVisibleNotEmptySectors; ++i) {
154 
155  for (uint j = 0; j < v8->uNumDecorations; ++j)
157  }
159  // engine->PrepareBloodsplats();
160 }
161 
162 //----- (004407D9) --------------------------------------------------------
165 
168  pIndoorCameraD3D->debug_flags |= BLV_RENDER_DRAW_SW_OUTLINES;
170  pIndoorCameraD3D->debug_flags |= BLV_RENDER_DRAW_D3D_OUTLINES;
171 
172  // v2 = a2;
173  // this->field_0_timer_ = a2->field_0_timer;
174  // this->uFlags = a2->uFlags;
175  // this->vPartyPos.x = a2->vPosition.x;
176  // this->vPartyPos.y = a2->vPosition.y;
177  // this->vPartyPos.z = a2->vPosition.z;
178  // v4 = this->vPartyPos.z;
179  // v5 = this->vPartyPos.y;
180  // this->sPartyRotY = a2->sRotationY;
181  // v6 = this->vPartyPos.x;
182  // this->sPartyRotX = a2->sRotationX;
186  this->uPartySectorID = v7;
187  if (!v7) {
188  __debugbreak(); // shouldnt happen, please provide savegame
189  /*v8 = this->vPartyPos.z;
190  this->vPartyPos.x = pParty->vPosition.x;
191  v9 = pParty->vPosition.y;
192  v10 = this->vPartyPos.x;
193  this->vPartyPos.y = pParty->vPosition.y;*/
194  // this->uPartySectorID = pIndoor->GetSector(
195  // pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
196  }
197  // if ( render->pRenderD3D )
198  {
199  this->fov = pViewport->field_of_view;
200 
205 
206  this->uViewportWidth = uViewportZ - uViewportX + 1;
207  this->uViewportHeight = uViewportW - uViewportY + 1;
208  this->uViewportCenterX = (uViewportZ + uViewportX) / 2;
209  this->uViewportCenterY = (uViewportY + uViewportW) / 2;
210  }
211  /*else
212  {
213  __debugbreak(); // no sw
214 
215  }*/
216  // v27 = (unsigned int)(signed __int64)((double)this->uViewportWidth * 0.5
217  // / tan((double)(v2->fov_deg >>
218  // 1) * 0.01745329)
219  // + 0.5) << 16;
220  extern float _calc_fov(int viewport_width, int angle_degree);
222  this->bsp_fov_rad_inv = fixpoint_div(1 << 16, this->bsp_fov_rad);
223  this->uTargetWidth = window->GetWidth();
224  this->uTargetHeight = window->GetHeight();
225  this->pTargetZBuffer = render->pActiveZBuffer;
226  this->field_8C = 0;
227  this->field_84 = 0;
228  this->uNumFacesRenderedThisFrame = 0;
229  this->field_88 = 0;
230  pBLVRenderParams->field_90 = 64;
232 }
233 
234 //----- (00440B44) --------------------------------------------------------
235 void IndoorLocation::ExecDraw(bool bD3D) {
236  if (bD3D) {
237  // pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
238 
239  for (uint i = 0; i < pBspRenderer->num_faces; ++i) {
241  .viewing_portal_id == -1)
243  nullptr, 4, nullptr);
244  else
249  4,
251  .pPortalBounding);
252  }
253  } else {
254  for (uint j = 0; j < pBspRenderer->num_faces; ++j) {
255  __debugbreak(); // no SW
256  // pBLVRenderParams->field_7C =
257  // &pBspRenderer->nodes[pBspRenderer->faces[j].uNodeID].PortalScreenData;
258  // IndoorLocation::ExecDraw_sw(pBspRenderer->faces[j].uFaceID);
259  }
260  }
261 }
262 
263 /*
264 //----- (00440BED) --------------------------------------------------------
265 void sub_440BED(IndoorLocation_drawstru *_this)
266 {
267  unsigned __int16 *v1; // edi@7
268  BspRenderer_stru0 *v2; // esi@8
269  int v3; // ecx@9
270  unsigned int v4; // edx@9
271  short *v5; // eax@10
272  signed int v6; // [sp+8h] [bp-8h]@7
273  int v7; // [sp+Ch] [bp-4h]@8
274  short *v8;
275 
276  PrepareDrawLists_BLV(_this);
277  if (pBLVRenderParams->uPartySectorID)
278  IndoorLocation::ExecDraw(render->pRenderD3D != 0);
279  render->DrawBillboardList_BLV();
280 
281  if ( !render->pRenderD3D )
282  {
283  if (pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_D3D_OUTLINES)
284  pBspRenderer->DrawFaceOutlines();
285  if (pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_SW_OUTLINES)
286  {
287  v1 = pBLVRenderParams->pRenderTarget;
288  v7 = 0;
289  for(int i=0; i < pBspRenderer->num_nodes; i++)
290  {
291  BspRenderer_stru0 *pNode = &pBspRenderer->nodes[i];
292  v4 = render->uTargetSurfacePitch *
293 pNode->PortalScreenData._viewport_space_y; if (
294 pNode->PortalScreenData._viewport_space_y <=
295 pNode->PortalScreenData._viewport_space_w )
296  {
297  //v5 = (char
298 *)&pBspRenderer->nodes[0].field_C.array_3D8[pNode->field_C._viewport_space_y +
299 v7]; v5 =
300 &pNode->PortalScreenData.viewport_right_side[pNode->PortalScreenData._viewport_space_y];
301  v8 =
302 &pNode->PortalScreenData.viewport_left_side[pNode->PortalScreenData._viewport_space_y];
303  do
304  {
305  v1[v4 + *v8] = 255;
306  ++pNode->PortalScreenData._viewport_space_y;
307  v1[v4 + *v5] = 255;
308  v4 += render->uTargetSurfacePitch;
309  ++v5;
310  ++v8;
311  }
312  while ( pNode->PortalScreenData._viewport_space_y <=
313 pNode->PortalScreenData._viewport_space_w );
314  }
315  }
316  }
317  }
318 }
319 */
320 
321 //----- (00441BD4) --------------------------------------------------------
323  // int v0; // eax@1
324  // IndoorLocation_drawstru _this; // [sp+0h] [bp-4Ch]@5
325  // int v2; // [sp+44h] [bp-8h]@5
326  // int v3; // [sp+48h] [bp-4h]@5
327 
328  /*_this.uFlags = 0;
329  if (viewparams->draw_sw_outlines)
330  _this.uFlags |= BLV_RENDER_DRAW_SW_OUTLINES;
331  if (viewparams->draw_d3d_outlines)
332  _this.uFlags |= BLV_RENDER_DRAW_D3D_OUTLINES;
333 
334  _this.uFlags |= BLV_RENDER_DRAW_SW_OUTLINES;
335  _this.uFlags |= BLV_RENDER_DRAW_D3D_OUTLINES;
336 
337  _this.field_0_timer = pEventTimer->uTotalGameTimeElapsed;
338  //_this.fov_deg = 65;
339  //_this.vPosition.x = pParty->vPosition.x -
340  fixpoint_mul(stru_5C6E00->Cos(pParty->sRotationY),
341  pParty->y_rotation_granularity);
342  //_this.vPosition.y = pParty->vPosition.y -
343  fixpoint_mul(stru_5C6E00->Sin(pParty->sRotationY),
344  pParty->y_rotation_granularity);
345  //_this.vPosition.z = pParty->vPosition.z + pParty->sEyelevel;
346  //_this.sRotationX = pParty->sRotationX;
347  //_this.sRotationY = pParty->sRotationY;
348  _this.uViewportX = pViewport->uScreen_TL_X;
349  _this.uViewportY = pViewport->uScreen_TL_Y;
350  _this.uViewportZ = pViewport->uScreen_BR_X;
351  _this.uViewportW = pViewport->uScreen_BR_Y;
352  _this.field_3C = pViewport->field_30;
353 
354  _this.uTargetWidth = 640;
355  _this.uTargetHeight = 480;
356  _this.pTargetZ = render->pActiveZBuffer;*/
357 
358  // sub_440BED(&_this); -- inlined
359  //{
362  ExecDraw(true /*render->pRenderD3D != 0*/);
363  render->DrawBillboardList_BLV();
364  //}
365 
366  pParty->uFlags &= ~2;
367  engine->DrawParticles();
369 }
370 
371 //----- (004C0EF2) --------------------------------------------------------
373  this->pFacePlane_old.vNormal.x = face->pFacePlane.vNormal.x;
374  this->pFacePlane_old.vNormal.y = face->pFacePlane.vNormal.y;
375  this->pFacePlane_old.vNormal.z = face->pFacePlane.vNormal.z;
376  this->pFacePlane_old.dist = face->pFacePlane.dist;
377  this->pFacePlane.vNormal.x =
378  (double)(face->pFacePlane.vNormal.x & 0xFFFF) * 0.000015259022 +
379  (double)(face->pFacePlane.vNormal.x >> 16);
380  this->pFacePlane.vNormal.y =
381  (double)(face->pFacePlane.vNormal.y & 0xFFFF) * 0.000015259022 +
382  (double)(face->pFacePlane.vNormal.y >> 16);
383  this->pFacePlane.vNormal.z =
384  (double)(face->pFacePlane.vNormal.z & 0xFFFF) * 0.000015259022 +
385  (double)(face->pFacePlane.vNormal.z >> 16);
386  this->pFacePlane.dist =
387  (double)(face->pFacePlane.dist & 0xFFFF) * 0.000015259022 +
388  (double)(face->pFacePlane.dist >> 16);
389  this->uAttributes = face->uAttributes;
390  this->pBounding.x1 = face->pBoundingBox.x1;
391  this->pBounding.y1 = face->pBoundingBox.y1;
392  this->pBounding.z1 = face->pBoundingBox.z1;
393  this->pBounding.x2 = face->pBoundingBox.x2;
394  this->pBounding.y2 = face->pBoundingBox.y2;
395  this->pBounding.z2 = face->pBoundingBox.z2;
396  this->zCalc1 = face->zCalc1;
397  this->zCalc2 = face->zCalc2;
398  this->zCalc3 = face->zCalc3;
402  this->uPolygonType = (PolygonType)face->uPolygonType;
403  this->uNumVertices = face->uNumVertices;
404  this->resource = face->resource;
405  this->pVertexIDs = face->pVertexIDs;
406 }
407 
408 //----- (004B0A25) --------------------------------------------------------
409 void IndoorLocation::ExecDraw_d3d(unsigned int uFaceID,
411  unsigned int uNumVertices,
412  RenderVertexSoft *pPortalBounding) {
413  int ColourMask; // ebx@25
414  // IDirect3DTexture2 *v27; // eax@42
415  unsigned int uNumVerticesa; // [sp+24h] [bp-4h]@17
416  int LightLevel; // [sp+34h] [bp+Ch]@25
417 
418  if (uFaceID >= pIndoor->uNumFaces)
419  return;
420 
421  static RenderVertexSoft static_vertices_buff_in[64]; // buff in
422  static RenderVertexSoft static_vertices_calc_out[64]; // buff out - calc portal shape
423 
424  static stru154 FacePlaneHolder; // idb
425 
426 
427  BLVFace *pFace = &pIndoor->pFaces[uFaceID];
428  if (pFace->uNumVertices < 3) return;
429 
430  if (pFace->Invisible()) {
431  return;
432  }
433 
435  pFace->uAttributes |= FACE_RENDERED;
436 
437  if (!pFace->GetTexture()) {
438  return;
439  }
440 
441  if (!pIndoorCameraD3D->IsCulled(pFace)) {
442  uNumVerticesa = pFace->uNumVertices;
443 
444  // copy to buff in
445  for (uint i = 0; i < pFace->uNumVertices; ++i) {
446  static_vertices_buff_in[i].vWorldPosition.x =
447  pIndoor->pVertices[pFace->pVertexIDs[i]].x;
448  static_vertices_buff_in[i].vWorldPosition.y =
449  pIndoor->pVertices[pFace->pVertexIDs[i]].y;
450  static_vertices_buff_in[i].vWorldPosition.z =
451  pIndoor->pVertices[pFace->pVertexIDs[i]].z;
452  static_vertices_buff_in[i].u = (signed short)pFace->pVertexUIDs[i];
453  static_vertices_buff_in[i].v = (signed short)pFace->pVertexVIDs[i];
454  }
455 
456  // 498377 always true - appears to be anothe function to clip vertices to portal planes??
457  if (!pVertices || (engine->pStru9Instance->_498377(
458  pPortalBounding, 4, pVertices,
459  static_vertices_buff_in, &uNumVerticesa),
460  uNumVerticesa)) {
461  if (pIndoorCameraD3D->CalcPortalShape( // clips vertices to the frustum planes
462  static_vertices_buff_in, &uNumVerticesa,
463  static_vertices_calc_out,
465  false, 0) != 1 || uNumVerticesa) {
466  LightLevel = HEXRAYS_SHIWORD(Lights.uCurrentAmbientLightLevel);
467  ColourMask =
468  (248 -
469  (HEXRAYS_SHIWORD(Lights.uCurrentAmbientLightLevel) << 3)) |
470  (((248 - (HEXRAYS_SHIWORD(Lights.uCurrentAmbientLightLevel)
471  << 3)) |
472  ((248 - (HEXRAYS_SHIWORD(Lights.uCurrentAmbientLightLevel)
473  << 3))
474  << 8))
475  << 8);
476 
477  FaceFlowTextureOffset(uFaceID);
478 
479 
480  // if (uFaceID == 2215 && pFace->uAttributes & FACE_OUTLINED) __debugbreak();
481  // ToDo: restore this
482  // if (pFace->uAttributes & FACE_OUTLINED) {
484  //}
485 
486  // if (Lights.uNumLightsApplied > 0) __debugbreak();
487 
489 
490  pIndoorCameraD3D->ViewTransfrom_OffsetUV(static_vertices_calc_out, uNumVerticesa, array_507D30, &Lights);
491 
492  pIndoorCameraD3D->Project(array_507D30, uNumVerticesa, 0);
493 
496  FacePlaneHolder.face_plane.vNormal.x =
497  pFace->pFacePlane.vNormal.x;
498  FacePlaneHolder.polygonType = pFace->uPolygonType;
499  FacePlaneHolder.face_plane.vNormal.y =
500  pFace->pFacePlane.vNormal.y;
501  FacePlaneHolder.face_plane.vNormal.z =
502  pFace->pFacePlane.vNormal.z;
503  FacePlaneHolder.face_plane.dist = pFace->pFacePlane.dist;
504  }
505 
506  if (Lights.uNumLightsApplied > 0 && !pFace->Indoor_sky()) // for torchlight(для света факелов)
507  // if (pFace->uAttributes & FACE_OUTLINED) {
508  lightmap_builder->ApplyLights(&Lights, &FacePlaneHolder, uNumVerticesa, array_507D30, pVertices, 0);
509  //}
510 
511  // bool LightmapBuilder::ApplyLights(LightsData *pLights, stru154 *a3, unsigned int uNumVertices,
512  // RenderVertexSoft *VertexRenderList, IndoorCameraD3D_Vec4 *a6, char uClipFlag) {
513 
514  if (decal_builder->uNumDecals > 0) // blood draw
515  decal_builder->ApplyDecals(LightLevel, 1, &FacePlaneHolder,
516  uNumVerticesa, array_507D30,
517  pVertices, 0, pFace->uSectorID);
518 
519  Texture *face_texture = pFace->GetTexture();
520  if (pFace->Fluid()) {
521  // if (pFace->uBitmapID == render->hd_water_tile_id)
522  // v27 =
523  // pBitmaps_LOD->pHardwareTextures[render->pHDWaterBitmapIDs[render->hd_water_current_frame]];
524  // else
525  {
526  face_texture = (Texture *)pFace->resource;
527  // auto v24 = GetTickCount() / 4;
528  // auto v25 = v24 - stru_5C6E00->uIntegerHalfPi;
529  uint eightSeconds = OS_GetTime() % 8000;
530  float angle = (eightSeconds / 8000.0f) * 2 * 3.1415f;
531 
532  // animte lava back and forth
533  for (uint i = 0; i < uNumVerticesa; ++i)
534  // array_507D30[i].v +=
535  // (double)(pBitmaps_LOD->pTextures[pFace->uBitmapID].uHeightMinus1
536  // & (unsigned int)(stru_5C6E00->SinCos(v25) >> 8));
537  array_507D30[i].v +=
538  (face_texture->GetHeight() - 1) * cosf(angle);
539  }
540  } else if (pFace->IsTextureFrameTable()) {
541  face_texture = pTextureFrameTable->GetFrameTexture(
543  } else {
544  ColourMask = 0xFF808080;
545  // v27 = pBitmaps_LOD->pHardwareTextures[pFace->uBitmapID];
546  }
547 
548  if (pFace->Indoor_sky()) {
549  render->DrawIndoorSky(uNumVerticesa, uFaceID);
550  } else {
551  // if (pFace->uAttributes & FACE_OUTLINED) {
552  render->DrawIndoorPolygon(uNumVerticesa, pFace, PID(OBJECT_BModel, uFaceID), ColourMask, 0);
553  //}
554  }
555  return;
556  }
557  }
558  }
559 }
560 
561 //----- (004B0E07) --------------------------------------------------------
562 unsigned int FaceFlowTextureOffset(unsigned int uFaceID) { // time texture offset
565 
566  unsigned int offset = OS_GetTime() >> 3;
567 
568  if (pIndoor->pFaces[uFaceID].uAttributes & FACE_FLOW_DIAGONAL) {
569  Lights.pDeltaUV[1] -= offset & (((Texture *)pIndoor->pFaces[uFaceID].resource)->GetHeight() - 1); // pBitmaps_LOD->GetTexture(pIndoor->pFaces[uFaceID].uBitmapID)->uHeightMinus1;
570  } else if (pIndoor->pFaces[uFaceID].uAttributes & FACE_FLOW_VERTICAL) {
571  Lights.pDeltaUV[1] += offset & (((Texture *)pIndoor->pFaces[uFaceID].resource)->GetHeight() - 1); // pBitmaps_LOD->GetTexture(pIndoor->pFaces[uFaceID].uBitmapID)->uHeightMinus1;
572  }
573 
574  if (pIndoor->pFaces[uFaceID].uAttributes & FACE_FLOW_HORIZONTAL) {
575  Lights.pDeltaUV[0] -= offset & (((Texture *)pIndoor->pFaces[uFaceID].resource)->GetWidth() - 1); // pBitmaps_LOD->GetTexture(pIndoor->pFaces[uFaceID].uBitmapID)->uWidthMinus1;
576  } else if (pIndoor->pFaces[uFaceID].uAttributes & FACE_DONT_CACHE_TEXTURE) {
577  Lights.pDeltaUV[0] += offset & (((Texture *)pIndoor->pFaces[uFaceID].resource)->GetWidth() - 1); // pBitmaps_LOD->GetTexture(pIndoor->pFaces[uFaceID].uBitmapID)->uWidthMinus1;
578  }
579 
580  return offset;
581 }
582 
583 //----- (004B0EA8) --------------------------------------------------------
584 void BspRenderer::AddFaceToRenderList_d3d(unsigned int node_id,
585  unsigned int uFaceID) {
586  unsigned __int16 pTransitionSector; // ax@11
587  int v9; // edx@15
588  char v29; // al@48
589 
591  // v39 = &pIndoor->pFaces[uFaceID];
592 
593  BLVFace *pFace = &pIndoor->pFaces[uFaceID];
594 
595  if (!pFace->Portal()) {
596  if (num_faces < 1000) {
597  faces[num_faces].uFaceID = uFaceID;
598  faces[num_faces++].uNodeID = node_id;
599  }
600  return;
601  }
602 
603  // portals are invisible faces marking the transition between sectors
604 
605  if (nodes[node_id].uFaceID == uFaceID) return;
606  if (!node_id &&
608  pFace->pBounding.x1 -
609  16 && // we are probably standing at the portal plane
610  pIndoorCameraD3D->vPartyPos.x <= pFace->pBounding.x2 + 16 &&
611  pIndoorCameraD3D->vPartyPos.y >= pFace->pBounding.y1 - 16 &&
612  pIndoorCameraD3D->vPartyPos.y <= pFace->pBounding.y2 + 16 &&
613  pIndoorCameraD3D->vPartyPos.z >= pFace->pBounding.z1 - 16 &&
614  pIndoorCameraD3D->vPartyPos.z <= pFace->pBounding.z2 + 16) {
615  if (abs(pFace->pFacePlane_old.dist +
617  pFace->pFacePlane_old.vNormal.x +
619  pFace->pFacePlane_old.vNormal.y +
621  pFace->pFacePlane_old.vNormal.z) <=
622  589824) { // we sure are standing at the portal plane
623  pTransitionSector = pFace->uSectorID;
624  if (nodes[0].uSectorID == pTransitionSector) // draw back sector
625  pTransitionSector = pFace->uBackSectorID;
626  nodes[num_nodes].uSectorID = pTransitionSector;
627  nodes[num_nodes].uFaceID = uFaceID;
636  return;
637  }
638  }
639 
640  v9 = pFace->pFacePlane_old.vNormal.x *
641  (pIndoor->pVertices[pFace->pVertexIDs[0]].x -
643  pFace->pFacePlane_old.vNormal.y *
644  (pIndoor->pVertices[pFace->pVertexIDs[0]].y -
646  pFace->pFacePlane_old.vNormal.z *
647  (pIndoor->pVertices[pFace->pVertexIDs[0]].z -
649  if (nodes[node_id].uSectorID != pFace->uSectorID) v9 = -v9;
650  if (v9 >= 0) return;
651 
652  // check number of verts of portal is seen by camera
653  int num_vertices = GetPortalScreenCoord(uFaceID);
654  if (num_vertices < 2) return;
655 
656  int face_min_screenspace_x = PortalFace._screen_space_x[0],
657  face_max_screenspace_x = PortalFace._screen_space_x[0];
658  int face_min_screenspace_y = PortalFace._screen_space_y[0],
659  face_max_screenspace_y = PortalFace._screen_space_y[0];
660  for (uint i = 1; i < num_vertices; ++i) {
661  if (face_min_screenspace_x > PortalFace._screen_space_x[i])
662  face_min_screenspace_x = PortalFace._screen_space_x[i];
663  if (face_max_screenspace_x < PortalFace._screen_space_x[i])
664  face_max_screenspace_x = PortalFace._screen_space_x[i];
665 
666  if (face_min_screenspace_y > PortalFace._screen_space_y[i])
667  face_min_screenspace_y = PortalFace._screen_space_y[i];
668  if (face_max_screenspace_y < PortalFace._screen_space_y[i])
669  face_max_screenspace_y = PortalFace._screen_space_y[i];
670  }
671  // _screen_space_x = 719, 568, 493
672  // savegame: qw , 0Bh and 0x1D4h
673  // problem here when standing near/on portal, condition is false because of
674  // face_min_screenspace_x > p->uViewportZ
675  if (face_max_screenspace_x >= nodes[node_id].uViewportX &&
676  face_min_screenspace_x <= nodes[node_id].uViewportZ &&
677  face_max_screenspace_y >= nodes[node_id].uViewportY &&
678  face_min_screenspace_y <= nodes[node_id].uViewportW &&
679  PortalFrustrum(num_vertices, &nodes[num_nodes].PortalScreenData,
680  &nodes[node_id].PortalScreenData, uFaceID)) {
681  // current portal visible through previous
682 
683  pTransitionSector = pFace->uSectorID;
684  if (nodes[node_id].uSectorID == pTransitionSector)
685  pTransitionSector = pFace->uBackSectorID;
686  nodes[num_nodes].uSectorID = pTransitionSector;
687  nodes[num_nodes].uFaceID = uFaceID;
692  v29 = false;
693  if (nodes[node_id].viewing_portal_id == -1) { // for first portal
694  v29 = engine->pStru10Instance->CalcPortalShape(
695  pFace, nodes[num_nodes].std__vector_0007AC,
696  nodes[num_nodes].pPortalBounding);
697  } else { // for next portals
698  static RenderVertexSoft static_subAddFaceToRenderList_d3d_stru_F7AA08[64];
699  static RenderVertexSoft static_subAddFaceToRenderList_d3d_stru_F79E08[64];
700 
701  for (uint k = 0; k < pFace->uNumVertices; ++k) {
702  static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.x =
703  pIndoor->pVertices[pFace->pVertexIDs[k]].x;
704  static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.y =
705  pIndoor->pVertices[pFace->pVertexIDs[k]].y;
706  static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.z =
707  pIndoor->pVertices[pFace->pVertexIDs[k]].z;
708  }
709 
710  unsigned int pNewNumVertices = pFace->uNumVertices;
712  static_subAddFaceToRenderList_d3d_stru_F7AA08, &pNewNumVertices,
713  static_subAddFaceToRenderList_d3d_stru_F79E08,
714  nodes[node_id].std__vector_0007AC, 4, 0, 0);
715 
716  v29 = engine->pStru10Instance->_49C5DA(
717  pFace, static_subAddFaceToRenderList_d3d_stru_F79E08,
718  &pNewNumVertices, nodes[num_nodes].std__vector_0007AC,
719  nodes[num_nodes].pPortalBounding);
720  }
721 
722  if (1) {
723  assert(num_nodes < 150);
724 
725  // add portal sector to drawing list
726 
727  nodes[num_nodes].viewing_portal_id = uFaceID;
729  }
730 
731  if (pIndoorCameraD3D->debug_flags & BLV_RENDER_DRAW_SW_OUTLINES)
733  // pIndoorCameraD3D->DebugDrawPortal(pFace);
734  }
735 }
736 
737 //----- (004AE5BA) --------------------------------------------------------
739  if (this->IsTextureFrameTable())
741  (int)this->resource, pBLVRenderParams->field_0_timer_);
742  else
743  return (Texture *)this->resource;
744 }
745 
746 void BLVFace::SetTexture(const String &filename) {
747  if (this->IsTextureFrameTable()) {
748  this->resource =
749  (void *)pTextureFrameTable->FindTextureByName(filename.c_str());
750  if (this->resource != (void *)-1) {
751  return;
752  }
753 
755  }
756 
757  this->resource = assets->GetBitmap(filename);
758 }
759 
760 //----- (00498B15) --------------------------------------------------------
762  free(this->ptr_0002B4_doors_ddata);
763  this->ptr_0002B4_doors_ddata = NULL;
764 
765  free(this->ptr_0002B0_sector_rdata);
766  this->ptr_0002B0_sector_rdata = NULL;
767 
768  free(this->ptr_0002B8_sector_lrdata);
769  this->ptr_0002B8_sector_lrdata = NULL;
770 
771  free(this->pLFaces);
772  this->pLFaces = NULL;
773 
774  free(this->pSpawnPoints);
775  this->pSpawnPoints = NULL;
776 
777  this->uNumSectors = 0;
778  this->uNumFaces = 0;
779  this->uNumVertices = 0;
780  this->uNumNodes = 0;
781  this->uNumDoors = 0;
782  this->uNumLights = 0;
783 
784  free(this->pVertices);
785  this->pVertices = NULL;
786 
787  free(this->pFaces);
788  this->pFaces = NULL;
789 
790  free(this->pFaceExtras);
791  this->pFaceExtras = NULL;
792 
793  free(this->pSectors);
794  this->pSectors = NULL;
795 
796  free(this->pLights);
797  this->pLights = NULL;
798 
799  free(this->pDoors);
800  this->pDoors = NULL;
801 
802  free(this->pNodes);
803  this->pNodes = NULL;
804 
805  free(this->pMapOutlines);
806  this->pMapOutlines = NULL;
807 
808  this->bLoaded = 0;
809 }
810 
811 //----- (00498C45) --------------------------------------------------------
813  pVertices = (Vec3_short_ *)malloc(15000 * sizeof(Vec3_short_)); // 0x15F90u
814  pFaces = (BLVFace *)malloc(10000 * sizeof(BLVFace)); // 0xEA600u
815  pFaceExtras =
816  (BLVFaceExtra *)malloc(5000 * sizeof(BLVFaceExtra)); // 0x2BF20u
817  pSectors = (BLVSector *)malloc(512 * sizeof(BLVSector)); // 0xE800u
818  pLights = (BLVLightMM7 *)malloc(400 * sizeof(BLVLightMM7)); // 0x1900u
819  pDoors = (BLVDoor *)malloc(200 * sizeof(BLVDoor)); // 0x3E80u
820  pNodes = (BSPNode *)malloc(5000 * sizeof(BSPNode)); // 0x9C40u
821  pMapOutlines = (BLVMapOutlines *)malloc(sizeof(BLVMapOutlines)); // 0x14824u
822  if (pVertices && pFaces && pFaceExtras && pSectors && pLights && pDoors &&
823  pNodes && pMapOutlines) {
824  memset(pVertices, 0, 15000 * sizeof(Vec3_short_));
825  memset(pFaces, 0, 10000 * sizeof(BLVFace));
826  memset(pFaceExtras, 0, 5000 * sizeof(BLVFaceExtra));
827  memset(pSectors, 0, 512 * sizeof(BLVSector));
828  memset(pLights, 0, 400 * sizeof(BLVLightMM7));
829  memset(pDoors, 0, 200 * sizeof(BLVDoor));
830  memset(pNodes, 0, 5000 * sizeof(BSPNode));
831  memset(pMapOutlines, 0, sizeof(BLVMapOutlines));
832  return true;
833  } else {
834  return false;
835  }
836 }
837 
838 //----- (00444810) --------------------------------------------------------
839 unsigned int IndoorLocation::GetLocationIndex(const char *Str1) {
840  for (uint i = 0; i < 11; ++i)
841  if (!_stricmp(Str1, _4E6BDC_loc_names[i])) return i + 1;
842  return 0;
843 }
844 
845 //----- (004488F7) --------------------------------------------------------
846 void IndoorLocation::ToggleLight(signed int sLightID, unsigned int bToggle) {
848  (sLightID <= pIndoor->uNumLights - 1) && (sLightID >= 0)) {
849  if (bToggle)
850  pIndoor->pLights[sLightID].uAtributes &= 0xFFFFFFF7;
851  else
852  pIndoor->pLights[sLightID].uAtributes |= 8;
853  pParty->uFlags |= 2;
854  }
855 }
856 
857 //----- (00498E0A) --------------------------------------------------------
858 bool IndoorLocation::Load(const String &filename, int num_days_played,
859  int respawn_interval_days, char *pDest) {
860  decal_builder->Reset(0);
861 
863 
864  if (bLoaded) {
865  log->Warning(L"BLV is already loaded");
866  return true;
867  }
868 
869  auto blv_filename = String(filename);
870  blv_filename.replace(blv_filename.length() - 4, 4, ".blv");
871 
872  this->filename = String(filename);
873  if (!pGames_LOD->DoesContainerExist(blv_filename)) {
874  Error("Unable to find %s in Games.LOD", blv_filename.c_str());
875  }
876 
877  Release();
878  if (!Alloc())
879  return false;
880 
881  size_t blv_size = 0;
882  void *rawData = pGames_LOD->LoadCompressed(blv_filename, &blv_size);
883  char *pData = (char*)rawData;
884 
885  bLoaded = true;
886 
888 
889  memcpy(&blv, pData, sizeof(BLVHeader));
890  pData += sizeof(BLVHeader);
891  memcpy(&uNumVertices, pData, 4);
892  pData += 4;
893  memcpy(pVertices, pData, uNumVertices * sizeof(Vec3_short_));
894 
896 
897  memcpy(&uNumFaces, pData += uNumVertices * sizeof(Vec3_short_), 4);
898  pData += 4;
899 
901 
902  // memcpy(pFaces, pData, uNumFaces * sizeof(BLVFace));
903  auto face_data = (BLVFace_MM7 *)pData;
904  pFaces = new BLVFace[uNumFaces];
905  for (unsigned int i = 0; i < uNumFaces; ++i) {
906  pFaces[i].Deserialize(face_data);
907  face_data++;
908  }
909 
910  pLFaces = (unsigned __int16 *)malloc(blv.uFaces_fdata_Size);
911  memcpy(pLFaces, pData += uNumFaces * sizeof(BLVFace_MM7),
913 
914  for (uint i = 0, j = 0; i < uNumFaces; ++i) {
915  BLVFace *pFace = &pFaces[i];
916 
917  pFace->pVertexIDs = &pLFaces[j];
918 
919  j += pFace->uNumVertices + 1;
920  pFace->pXInterceptDisplacements = (short *)(&pLFaces[j]);
921 
922  j += pFace->uNumVertices + 1;
923  pFace->pYInterceptDisplacements = (short *)(&pLFaces[j]);
924 
925  j += pFace->uNumVertices + 1;
926  pFace->pZInterceptDisplacements = (short *)(&pLFaces[j]);
927 
928  j += pFace->uNumVertices + 1;
929  pFace->pVertexUIDs = (__int16 *)(&pLFaces[j]);
930 
931  j += pFace->uNumVertices + 1;
932  pFace->pVertexVIDs = (__int16 *)(&pLFaces[j]);
933 
934  j += pFace->uNumVertices + 1;
935  }
936 
938 
939  pData += blv.uFaces_fdata_Size;
940 
941  for (uint i = 0; i < uNumFaces; ++i) {
942  BLVFace *pFace = &pFaces[i];
943 
944  char pTexName[16];
945  strncpy(pTexName, pData, 10);
946  pData += 10;
947 
948  pFace->SetTexture(String(pTexName));
949  }
950 
952 
953  memcpy(&uNumFaceExtras, pData, 4);
954  memcpy(pFaceExtras, pData += 4, uNumFaceExtras * sizeof(BLVFaceExtra));
955  pData += uNumFaceExtras * sizeof(BLVFaceExtra);
956 
958 
959  // v108 = (char *)v107 + 36 * uNumFaceExtras;
960  // v245 = 0;
961  // *(int *)((char *)&uSourceLen + 1) = 0;
962  for (uint i = 0; i < uNumFaceExtras; ++i) {
963  char pTexName[32];
964  strncpy(pTexName, pData, 10);
965  pData += 10;
966 
967  if (!strcmp(pTexName, ""))
969  else
971  pBitmaps_LOD->LoadTexture(pTexName);
972  }
973 
974  for (uint i = 0; i < uNumFaces; ++i) {
975  BLVFace *pFace = &pFaces[i];
976  BLVFaceExtra *pFaceExtra = &pFaceExtras[pFace->uFaceExtraID];
977 
978  if (pFaceExtra->uEventID) {
979  if (pFaceExtra->HasEventint())
980  pFace->uAttributes |= FACE_HAS_EVENT;
981  else
982  pFace->uAttributes &= ~FACE_HAS_EVENT;
983  }
984  }
985 
987 
988  memcpy(&uNumSectors, pData, 4);
989  memcpy(pSectors, pData + 4, uNumSectors * sizeof(BLVSector));
990  pData += 4 + uNumSectors * sizeof(BLVSector);
991 
993 
995  (unsigned short *)malloc(blv.uSector_rdata_Size); //, "L.RData");
997  pData += blv.uSector_rdata_Size;
998 
999  for (uint i = 0, j = 0; i < uNumSectors; ++i) {
1000  BLVSector *pSector = &pSectors[i];
1001 
1002  pSector->pFloors = &ptr_0002B0_sector_rdata[j];
1003  j += pSector->uNumFloors;
1004 
1005  pSector->pWalls = &ptr_0002B0_sector_rdata[j];
1006  j += pSector->uNumWalls;
1007 
1008  pSector->pCeilings = &ptr_0002B0_sector_rdata[j];
1009  j += pSector->uNumCeilings;
1010 
1011  pSector->pFluids = &ptr_0002B0_sector_rdata[j];
1012  j += pSector->uNumFluids;
1013 
1014  pSector->pPortals = &ptr_0002B0_sector_rdata[j];
1015  j += pSector->uNumPortals;
1016 
1017  pSector->pFaceIDs = &ptr_0002B0_sector_rdata[j];
1018  j += pSector->uNumFaces;
1019 
1020  pSector->pCogs = &ptr_0002B0_sector_rdata[j];
1021  j += pSector->uNumCogs;
1022 
1023  pSector->pDecorationIDs = &ptr_0002B0_sector_rdata[j];
1024  j += pSector->uNumDecorations;
1025 
1026  pSector->pMarkers = &ptr_0002B0_sector_rdata[j];
1027  j += pSector->uNumMarkers;
1028  }
1029 
1031  (unsigned __int16 *)malloc(blv.uSector_lrdata_Size); //, "L.RLData");
1033  pData += blv.uSector_lrdata_Size;
1034 
1036 
1037  for (uint i = 0, j = 0; i < uNumSectors; ++i) {
1039  j += pSectors[i].uNumLights;
1040  }
1041 
1043 
1044  memcpy(&uNumDoors, pData, 4);
1045  pData += 4;
1046 
1049 
1050  memcpy(&uNumLevelDecorations, pData, 4);
1051  memcpy(pLevelDecorations.data(), pData + 4,
1053  pData += 4 + uNumLevelDecorations * sizeof(LevelDecoration);
1054 
1055  for (uint i = 0; i < uNumLevelDecorations; ++i) {
1056  pLevelDecorations[i].uDecorationDescID =
1058 
1059  pData += 32;
1060  }
1061 
1063 
1064  memcpy(&uNumLights, pData, 4);
1065  memcpy(pLights, pData + 4, uNumLights * sizeof(BLVLightMM7));
1066  pData += 4 + uNumLights * sizeof(BLVLightMM7);
1067 
1070 
1071  memcpy(&uNumNodes, pData, 4);
1072  memcpy(pNodes, pData + 4, uNumNodes * sizeof(BSPNode));
1073  pData += 4 + uNumNodes * sizeof(BSPNode);
1074 
1077 
1078  memcpy(&uNumSpawnPoints, pData, 4);
1080  memcpy(pSpawnPoints, pData + 4, uNumSpawnPoints * sizeof(SpawnPointMM7));
1081  pData += 4 + uNumSpawnPoints * sizeof(SpawnPointMM7);
1082 
1085 
1086  memcpy(&pMapOutlines->uNumOutlines, pData, 4);
1087  memcpy(pMapOutlines->pOutlines, pData + 4, pMapOutlines->uNumOutlines * sizeof(BLVMapOutline));
1088  free(rawData);
1089 
1090  String dlv_filename = String(filename);
1091  dlv_filename.replace(dlv_filename.length() - 4, 4, ".dlv");
1092 
1093  bool bResetSpawn = false;
1094  size_t dlv_size = 0;
1095  rawData = pNew_LOD->LoadCompressed(dlv_filename, &dlv_size);
1096  if (rawData != nullptr) {
1097  pData = (char*)rawData;
1098  memcpy(&dlv, pData, sizeof(DDM_DLV_Header));
1099  pData += sizeof(DDM_DLV_Header);
1100  } else {
1101  bResetSpawn = true;
1102  }
1103 
1104  if (dlv.uNumFacesInBModels > 0) {
1105  if (dlv.uNumDecorations > 0) {
1106  if (dlv.uNumFacesInBModels != uNumFaces ||
1108  bResetSpawn = true;
1109  }
1110  }
1111 
1112  if (dword_6BE364_game_settings_1 & GAME_SETTINGS_2000) {
1113  respawn_interval_days = 0x1BAF800;
1114  }
1115 
1116  bool bRespawnLocation = false;
1117  if (num_days_played - dlv.uLastRepawnDay >= respawn_interval_days &&
1118  (pCurrentMapName != "d29.dlv")) {
1119  bRespawnLocation = true;
1120  }
1121 
1122  char SavedOutlines[875];
1123  if (bResetSpawn || (bRespawnLocation || !dlv.uLastRepawnDay)) {
1124  if (bResetSpawn) {
1125  memset(SavedOutlines, 0, 875);
1126  } else if (bRespawnLocation || !dlv.uLastRepawnDay) {
1127  memcpy(SavedOutlines, pData, 875);
1128  }
1129 
1130  dlv.uLastRepawnDay = num_days_played;
1131  if (!bResetSpawn) ++dlv.uNumRespawns;
1132  *(int *)pDest = 1;
1133 
1134  pData = (char*)pGames_LOD->LoadCompressed(dlv_filename);
1135  pData += sizeof(DDM_DLV_Header);
1136  } else {
1137  *(int*)pDest = 0;
1138  }
1139 
1140  memcpy(_visible_outlines, pData, 875);
1141  pData += 875;
1142 
1143  if (*(int *)pDest) memcpy(_visible_outlines, SavedOutlines, 875);
1144 
1145  for (uint i = 0; i < pMapOutlines->uNumOutlines; ++i) {
1146  BLVMapOutline *pVertex = &pMapOutlines->pOutlines[i];
1147  if ((unsigned __int8)(1 << (7 - i % 8)) & _visible_outlines[i / 8])
1148  pVertex->uFlags |= 1;
1149  }
1150 
1151  for (uint i = 0; i < uNumFaces; ++i) {
1152  BLVFace *pFace = &pFaces[i];
1153  BLVFaceExtra *pFaceExtra = &pFaceExtras[pFace->uFaceExtraID];
1154 
1155  memcpy(&pFace->uAttributes, pData, 4);
1156  pData += 4;
1157 
1158  if (pFaceExtra->uEventID) {
1159  if (pFaceExtra->HasEventint())
1160  pFace->uAttributes |= FACE_HAS_EVENT;
1161  else
1162  pFace->uAttributes &= ~FACE_HAS_EVENT;
1163  }
1164  }
1165 
1167 
1168  for (uint i = 0; i < uNumLevelDecorations; ++i) {
1169  memcpy(&pLevelDecorations[i].uFlags, pData, 2);
1170  pData += 2;
1171  }
1172 
1174 
1175  memcpy(&uNumActors, pData, 4);
1176  memcpy(&pActors, pData + 4, uNumActors * sizeof(Actor));
1177  pData += 4 + uNumActors * sizeof(Actor);
1178 
1181 
1182  memcpy(&uNumSpriteObjects, pData, 4);
1183  memcpy(pSpriteObjects.data(), pData + 4,
1184  uNumSpriteObjects * sizeof(SpriteObject));
1185  pData += 4 + uNumSpriteObjects * sizeof(SpriteObject);
1186 
1188 
1189  for (uint i = 0; i < uNumSpriteObjects; ++i) {
1190  if (pSpriteObjects[i].containing_item.uItemID && !(pSpriteObjects[i].uAttributes & 0x0100)) {
1191  pSpriteObjects[i].uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[pSpriteObjects[i].containing_item.uItemID].uSpriteID;
1192  pSpriteObjects[i].uObjectDescID = pObjectList->ObjectIDByItemID(pSpriteObjects[i].uType);
1193  }
1194  }
1195 
1197 
1198  pData = ChestsDeserialize(pData);
1199 
1202 
1203  memcpy(pDoors, pData, 0x3E80);
1204  pData += 0x3E80;
1205 
1206  // v201 = (const char *)blv.uDoors_ddata_Size;
1207  // v200 = (size_t)ptr_0002B4_doors_ddata;
1208  // v170 = malloc(ptr_0002B4_doors_ddata, blv.uDoors_ddata_Size, "L.DData");
1209  // v171 = blv.uDoors_ddata_Size;
1210  ptr_0002B4_doors_ddata = (uint16_t*)malloc(blv.uDoors_ddata_Size); //, "L.DData");
1211  if (ptr_0002B4_doors_ddata == nullptr) {
1212  log->Warning(L"Malloc error");
1213  Error("Malloc"); // is this recoverable
1214  }
1215 
1217  pData += blv.uDoors_ddata_Size;
1218 
1219  // Src = (BLVFace *)((char *)Src + v171);
1220  // v172 = 0;
1221  // v245 = 0;
1222  // if (uNumDoors > 0)
1223  for (uint i = 0, j = 0; i < uNumDoors; ++i) {
1224  BLVDoor *pDoor = &pDoors[i];
1225 
1226  pDoor->pVertexIDs = &ptr_0002B4_doors_ddata[j];
1227  j += pDoor->uNumVertices;
1228 
1229  pDoor->pFaceIDs = &ptr_0002B4_doors_ddata[j];
1230  j += pDoor->uNumFaces;
1231 
1232  pDoor->pSectorIDs = &ptr_0002B4_doors_ddata[j];
1233  j += pDoor->field_48;
1234 
1235  pDoor->pDeltaUs = (short *)(&ptr_0002B4_doors_ddata[j]);
1236  j += pDoor->uNumFaces;
1237 
1238  pDoor->pDeltaVs = (short *)(&ptr_0002B4_doors_ddata[j]);
1239  j += pDoor->uNumFaces;
1240 
1241  pDoor->pXOffsets = &ptr_0002B4_doors_ddata[j];
1242  j += pDoor->uNumOffsets;
1243 
1244  pDoor->pYOffsets = &ptr_0002B4_doors_ddata[j];
1245  j += pDoor->uNumOffsets;
1246 
1247  pDoor->pZOffsets = &ptr_0002B4_doors_ddata[j];
1248  j += pDoor->uNumOffsets;
1249  }
1250  // v190 = 0;
1251  // v245 = 0;
1252  for (uint i = 0; i < uNumDoors; ++i) {
1253  BLVDoor *pDoor = &pDoors[i];
1254 
1255  for (uint j = 0; j < pDoor->uNumFaces; ++j) {
1256  BLVFace *pFace = &pFaces[pDoor->pFaceIDs[j]];
1257  BLVFaceExtra *pFaceExtra = &pFaceExtras[pFace->uFaceExtraID];
1258 
1259  pDoor->pDeltaUs[j] = pFaceExtra->sTextureDeltaU;
1260  pDoor->pDeltaVs[j] = pFaceExtra->sTextureDeltaV;
1261  }
1262  }
1263 
1265 
1266  memcpy(&stru_5E4C90_MapPersistVars, pData, 0xC8);
1267  pData += 0xC8;
1268 
1270 
1271  memcpy(&stru1, pData, 0x38u);
1272  pData += 0x38;
1273 
1274  free(rawData);
1275 
1276  return 0;
1277 }
1278 
1279 int IndoorLocation::GetSector(int sX, int sY, int sZ) {
1280  // sx = partyx..
1281 
1282  int v25; // edx@21
1283  int v26; // ebx@23
1284 
1285  int pSectorID; // ebx@40
1286  int v39; // eax@41
1287  int FoundFaceStore[50]; // [sp+Ch] [bp-108h]@1
1288  bool Vert2AboveParty; // [sp+ECh] [bp-28h]@19
1289 
1290  int v53; // [sp+F8h] [bp-1Ch]@10
1291  int VertsPassChecks; // [sp+FCh] [bp-18h]@16
1292 
1293 
1294  FoundFaceStore[0] = 0;
1295 
1296  int NumFoundFaceStore = 0;
1297 
1298  if (uNumSectors < 2) return 0;
1299 
1300  for (uint i = 1; i < uNumSectors; ++i) {
1301  BLVSector *pSector = &pSectors[i];
1302 
1303  if (pSector->pBounding.x1 > sX || pSector->pBounding.x2 < sX ||
1304  pSector->pBounding.y1 > sY || pSector->pBounding.y2 < sY ||
1305  pSector->pBounding.z1 - 64 > sZ || pSector->pBounding.z2 + 64 < sZ)
1306  continue; // outside sector
1307 
1308  // logger->Warning(L"Sector[%u]", i);
1309  int FloorsAndPortals = pSector->uNumFloors + pSector->uNumPortals;
1310  if (!FloorsAndPortals) continue;
1311 
1312  for (uint j = 0; j < FloorsAndPortals; ++j) {
1313  uint uFaceID;
1314  if (j < pSector->uNumFloors)
1315  uFaceID = pSector->pFloors[j];
1316  else
1317  uFaceID = pSector->pPortals[j - pSector->uNumFloors];
1318 
1319  BLVFace *pFace = &pFaces[uFaceID];
1320  if (pFace->uPolygonType != POLYGON_Floor &&
1322  continue;
1323 
1324  VertsPassChecks = 0;
1325  Vert2AboveParty = pVertices[pFace->pVertexIDs[0]].y >= sY;
1326 
1327  for (uint k = 1; k <= pFace->uNumVertices; k++) {
1328  bool Vert1AboveParty = Vert2AboveParty;
1329 
1330  if (VertsPassChecks >= 2) break;
1331 
1332  Vec3<int16_t> *v2 = &pVertices[pFace->pVertexIDs[k]];
1333  Vert2AboveParty = v2->y >= sY;
1334 
1335  if (Vert1AboveParty == Vert2AboveParty) continue;
1336 
1337  Vec3<int16_t> *v1 = &pVertices[pFace->pVertexIDs[k - 1]];
1338  v25 = v2->x >= sX ? 0 : 2;
1339  v26 = v25 | (v1->x < sX);
1340 
1341  if (v26 == 3) continue; // v1 and v2 less than x
1342 
1343  if (!v26) {
1344  ++VertsPassChecks; // both greater than x
1345  } else {
1346  if (v1->x >= v2->x) {
1347  /*int _a58;
1348  int _a59;
1349 
1350  v32 = v1->x - v2->x;
1351  LODWORD(v33) = v32 << 16;
1352  HIDWORD(v33) = v32 >> 16;*/
1353  // fixpoint_div(v1->x - v2->x, v1->y - v2->y);
1354  // _a58 = v33 / (v1->y - v2->y);
1355  // _a59 = fixpoint_mul(_a58, sY - v2->y);
1356  long long x_div_y =
1357  fixpoint_div(v1->x - v2->x, v1->y - v2->y);
1358  long long res = fixpoint_mul(
1359  x_div_y,
1360  sY - v2->y); // a / b * c - looks like projection
1361  if (res + v2->x > sX) ++VertsPassChecks;
1362  } else {
1363  long long x_div_y =
1364  fixpoint_div(v2->x - v1->x, v2->y - v1->y);
1365  long long res = fixpoint_mul(x_div_y, sY - v1->y);
1366 
1367  if (res + v1->x > sX) ++VertsPassChecks;
1368 
1369  /*int _a58;
1370  int _a59;
1371  auto v32 = v2->x - v1->x;
1372  LODWORD(v33) = v32 << 16;
1373  HIDWORD(v33) = v32 >> 16;
1374  _a58 = v33 / (v2->y - v1->y);
1375  _a59 = fixpoint_mul(_a58, sY - v1->y);
1376 
1377  if (_a59 + pVertices[k].x > sX)
1378  ++VertsPassChecks;*/
1379  }
1380  }
1381  }
1382 
1383  if (pFace->uNumVertices && VertsPassChecks == 1) FoundFaceStore[NumFoundFaceStore++] = uFaceID;
1384  }
1385  }
1386 
1387  // v4 = FoundFaceStore[0];
1388  if (NumFoundFaceStore == 1) return this->pFaces[/*v4*/FoundFaceStore[0]].uSectorID;
1389 
1390  if (!NumFoundFaceStore) return 0;
1391 
1392  // when multiple possibilities are found - cycle through and use the closer one to party
1393  pSectorID = 0;
1394  v53 = 0xFFFFFFu;
1395  if (NumFoundFaceStore > 0) {
1396  v39 = sY;
1397  for (int v37 = 0; v37 < NumFoundFaceStore; ++v37) {
1398  if (this->pFaces[FoundFaceStore[v37]].uPolygonType == POLYGON_Floor)
1399  v39 =
1400  sZ - this->pVertices[*this->pFaces[FoundFaceStore[v37]].pVertexIDs].z;
1401  if (this->pFaces[FoundFaceStore[v37]].uPolygonType ==
1403  v39 =
1404  sZ -
1405  ((fixpoint_mul(this->pFaces[FoundFaceStore[v37]].zCalc1, (sX << 16)) +
1406  fixpoint_mul(this->pFaces[FoundFaceStore[v37]].zCalc2, (sY << 16)) +
1407  this->pFaces[FoundFaceStore[v37]].zCalc3 + 0x8000) >>
1408  16);
1409  }
1410  if (v39 >= 0) {
1411  if (v39 < v53) {
1412  pSectorID = this->pFaces[FoundFaceStore[v37]].uSectorID;
1413  v53 = v39;
1414  }
1415  }
1416  }
1417  }
1418  return pSectorID;
1419 }
1420 
1421 //----- (00498A41) --------------------------------------------------------
1422 void BLVFace::_get_normals(Vec3_int_ *a2, Vec3_int_ *a3) {
1423  if (this->uPolygonType == POLYGON_VerticalWall) {
1424  a2->x = -this->pFacePlane_old.vNormal.y;
1425  a2->y = this->pFacePlane_old.vNormal.x;
1426  a2->z = 0;
1427 
1428  a3->x = 0;
1429  a3->y = 0;
1430  a3->z = 0xFFFF0000u;
1431 
1432  } else if (this->uPolygonType == POLYGON_Floor ||
1433  this->uPolygonType == POLYGON_Ceiling) {
1434  a2->x = 0x10000u;
1435  a2->y = 0;
1436  a2->z = 0;
1437 
1438  a3->x = 0;
1439  a3->y = 0xFFFF0000u;
1440  a3->z = 0;
1441 
1442  } else if (this->uPolygonType == POLYGON_InBetweenFloorAndWall ||
1444  if (abs(this->pFacePlane_old.vNormal.z) < 46441) {
1445  Vec3_float_ a1;
1446  a1.x = (double)-this->pFacePlane_old.vNormal.y;
1447  a1.y = (double)this->pFacePlane_old.vNormal.x;
1448  a1.z = 0.0;
1449  a1.Normalize();
1450 
1451  a2->x = (signed __int64)(a1.x * 65536.0);
1452  a2->y = (signed __int64)(a1.y * 65536.0);
1453  a2->z = 0;
1454 
1455  a3->y = 0;
1456  a3->z = 0xFFFF0000u;
1457  a3->x = 0;
1458 
1459  } else {
1460  a2->x = 0x10000u;
1461  a2->y = 0;
1462  a2->z = 0;
1463 
1464  a3->x = 0;
1465  a3->y = 0xFFFF0000u;
1466  a3->z = 0;
1467  }
1468  }
1469  // LABEL_12:
1470  if (this->uAttributes & FACE_UNKNOW3) {
1471  a2->x = -a2->x;
1472  a2->y = -a2->y;
1473  a2->z = -a2->z;
1474  }
1475  if (this->uAttributes & FACE_UNKNOW4) {
1476  a3->x = -a3->x;
1477  a3->y = -a3->y;
1478  a3->z = -a3->z;
1479  }
1480  return;
1481 }
1482 
1484  int event_index = 0;
1485  if ((uLevelEVT_NumEvents - 1) <= 0) {
1486  return false;
1487  }
1488  while (pLevelEVT_Index[event_index].uEventID != this->uEventID) {
1489  ++event_index;
1490  if (event_index >= (signed int)(uLevelEVT_NumEvents - 1)) return false;
1491  }
1492  _evt_raw *end_evt =
1493  (_evt_raw
1494  *)&pLevelEVT[pLevelEVT_Index[event_index + 1].uEventOffsetInEVT];
1495  _evt_raw *start_evt =
1496  (_evt_raw *)&pLevelEVT[pLevelEVT_Index[event_index].uEventOffsetInEVT];
1497  if ((end_evt->_e_type != EVENT_Exit) ||
1498  (start_evt->_e_type != EVENT_MouseOver)) {
1499  return false;
1500  } else {
1501  return true;
1502  }
1503 }
1504 
1505 //----- (0046F228) --------------------------------------------------------
1507  BLVFace *face; // ebx@24
1508  Vec3_short_ *v17; // esi@24
1509  int v18; // eax@24
1510  int v19; // edx@24
1511  signed int v20; // eax@24
1512  int v24; // esi@25
1513  int v25; // eax@25
1514  signed __int64 v27; // qtt@27
1515  BLVFaceExtra *v28; // esi@32
1516  int v32; // eax@34
1517  Vec3_short_ *v34; // eax@35
1518  int v35; // ecx@35
1519  int v36; // edx@35
1520  signed int v37; // eax@35
1521  signed int v38; // edx@35
1522  int v39; // eax@35
1523  int v40; // edx@35
1524  Vec3_short_ *v43; // edi@36
1525  int v57; // eax@58
1526  Vec3_int_ v67;
1527  Vec3_int_ v70;
1528  int v73; // [sp+20h] [bp-44h]@24
1529  int v75; // [sp+28h] [bp-3Ch]@36
1530  int v76; // [sp+2Ch] [bp-38h]@36
1531  int v77; // [sp+30h] [bp-34h]@36
1532  int v82; // [sp+44h] [bp-20h]@35
1533  int v83; // [sp+48h] [bp-1Ch]@34
1534  int v84; // [sp+4Ch] [bp-18h]@34
1535  SoundID eDoorSoundID; // [sp+54h] [bp-10h]@1
1536  int v88; // [sp+5Ch] [bp-8h]@18
1537  int v89; // [sp+60h] [bp-4h]@6
1538 
1539  eDoorSoundID = (SoundID)
1541  for (uint i = 0; i < pIndoor->uNumDoors; ++i) {
1542  BLVDoor *door = &pIndoor->pDoors[i];
1543  if (door->uState == BLVDoor::Closed || door->uState == BLVDoor::Open) {
1544  door->uAttributes &= 0xFFFFFFFDu; // ~0x2
1545  continue;
1546  }
1548  if (door->uState == BLVDoor::Opening) {
1549  v89 = (signed int)(door->uTimeSinceTriggered * door->uCloseSpeed) /
1550  128;
1551  if (v89 >= door->uMoveLength) {
1552  v89 = door->uMoveLength;
1553  door->uState = BLVDoor::Open;
1554  if (!(door->uAttributes & FACE_UNKNOW5) &&
1555  door->uNumVertices != 0)
1556  pAudioPlayer->PlaySound((SoundID)((int)eDoorSoundID + 1), PID(OBJECT_BLVDoor, i), 0, -1, 0, 0);
1557  // goto LABEL_18;
1558  } else if (!(door->uAttributes & FACE_UNKNOW5) &&
1559  door->uNumVertices) {
1560  pAudioPlayer->PlaySound(eDoorSoundID, PID(OBJECT_BLVDoor, i), 1,
1561  -1, 0, 0);
1562  }
1563  } else {
1564  signed int v5 =
1565  (signed int)(door->uTimeSinceTriggered * door->uOpenSpeed) /
1566  128;
1567  if (v5 >= door->uMoveLength) {
1568  v89 = 0;
1569  door->uState = BLVDoor::Closed;
1570  if (!(door->uAttributes & FACE_UNKNOW5) &&
1571  door->uNumVertices != 0)
1572  pAudioPlayer->PlaySound((SoundID)((int)eDoorSoundID + 1),
1573  PID(OBJECT_BLVDoor, i), 0, -1, 0, 0);
1574  // goto LABEL_18;
1575  } else {
1576  v89 = door->uMoveLength - v5;
1577  if (!(door->uAttributes & FACE_UNKNOW5) && door->uNumVertices)
1578  pAudioPlayer->PlaySound(eDoorSoundID,
1579  PID(OBJECT_BLVDoor, i), 1, -1, 0, 0);
1580  }
1581  }
1582 
1583  // LABEL_18:
1584  for (uint j = 0; j < door->uNumVertices; ++j) {
1585  pIndoor->pVertices[door->pVertexIDs[j]].x =
1586  fixpoint_mul(door->vDirection.x, v89) + door->pXOffsets[j];
1587  pIndoor->pVertices[door->pVertexIDs[j]].y =
1588  fixpoint_mul(door->vDirection.y, v89) + door->pYOffsets[j];
1589  pIndoor->pVertices[door->pVertexIDs[j]].z =
1590  fixpoint_mul(door->vDirection.z, v89) + door->pZOffsets[j];
1591  }
1592  for (v88 = 0; v88 < door->uNumFaces; ++v88) {
1593  face = &pIndoor->pFaces[door->pFaceIDs[v88]];
1594  v17 = &pIndoor->pVertices[face->pVertexIDs[0]];
1595  v18 = face->pFacePlane_old.vNormal.y;
1596  v73 = *(int *)&v17->x;
1597  v19 = face->pFacePlane_old.vNormal.z;
1598  v20 = -(v19 * (int)v17->z +
1599  (signed __int16)v73 * face->pFacePlane_old.vNormal.x +
1600  HEXRAYS_SHIWORD(v73) * v18);
1601  face->pFacePlane_old.dist = v20;
1602  face->pFacePlane.dist =
1603  -((double)v17->z * face->pFacePlane.vNormal.z +
1604  (double)v17->y * face->pFacePlane.vNormal.y +
1605  (double)v17->x * face->pFacePlane.vNormal.x);
1606  if (v19) {
1607  v24 = abs(v20 >> 15);
1608  v25 = abs(face->pFacePlane_old.vNormal.z);
1609  if (v24 > v25)
1610  Error(
1611  "Door Error\ndoor id: %i\nfacet no: %i\n\nOverflow "
1612  "dividing facet->d [%i] by facet->nz [%i]",
1613  door->uDoorID, door->pFaceIDs[v88],
1614  face->pFacePlane_old.dist,
1615  face->pFacePlane_old.vNormal.z);
1616  HEXRAYS_LODWORD(v27) = face->pFacePlane_old.dist << 16;
1617  HEXRAYS_HIDWORD(v27) = face->pFacePlane_old.dist >> 16;
1618  face->zCalc3 = -v27 / face->pFacePlane_old.vNormal.z;
1619  }
1620  // if ( face->uAttributes & FACE_TEXTURE_FLOW || render->pRenderD3D
1621  // )
1622  face->_get_normals(&v70, &v67);
1623  v28 = &pIndoor->pFaceExtras[face->uFaceExtraID];
1624  /*if ( !render->pRenderD3D )
1625  {
1626  if ( !(face->uAttributes & FACE_TEXTURE_FLOW) )
1627  continue;
1628  v83 = (unsigned __int64)(door->vDirection.x * (signed __int64)v70.x)
1629  >> 16; v85 = (unsigned __int64)(door->vDirection.y * (signed
1630  __int64)v70.y) >> 16; v84 = (unsigned __int64)(door->vDirection.z *
1631  (signed __int64)v70.z) >> 16; v29 = v89; v28->sTextureDeltaU =
1632  -((v83 + v85 + v84) * (signed __int64)v89) >> 16; v85 = (unsigned
1633  __int64)(door->vDirection.x * (signed __int64)v67.x) >> 16; v83 =
1634  (unsigned __int64)(door->vDirection.y * (signed __int64)v67.y) >>
1635  16; v84 = (unsigned __int64)(door->vDirection.z * (signed
1636  __int64)v67.z) >> 16; v31 = (v85 + v83 + v84) * (signed __int64)v29;
1637  v32 = v31 >> 16;
1638  v57 = -v32;
1639  v28->sTextureDeltaV = v57;
1640  v28->sTextureDeltaU += door->pDeltaUs[v88];
1641  v28->sTextureDeltaV = v57 + door->pDeltaVs[v88];
1642  continue;
1643  }*/
1644  v28->sTextureDeltaU = 0;
1645  v28->sTextureDeltaV = 0;
1646  v34 = &pIndoor->pVertices[face->pVertexIDs[0]];
1647  v35 = v34->z;
1648  v36 = v34->y;
1649  v82 = v34->x;
1650  v37 = v70.x * v82 + v70.y * v36 + v70.z * v35;
1651  v38 = v67.x * v82 + v67.y * v36 + v67.z * v35;
1652  v39 = v37 >> 16;
1653  *face->pVertexUIDs = v39;
1654  v40 = v38 >> 16;
1655  *face->pVertexVIDs = v40;
1656  v84 = v39;
1657  v82 = v40;
1658  for (uint j = 1; j < face->uNumVertices; ++j) {
1659  v43 = &pIndoor->pVertices[face->pVertexIDs[j]];
1660  v76 = ((__int64)v70.z * v43->z + (__int64)v70.x * v43->x +
1661  (__int64)v70.y * v43->y) >>
1662  16;
1663  v77 = ((__int64)v67.x * v43->x + (__int64)v67.y * v43->y +
1664  (__int64)v43->z * v67.z) >>
1665  16;
1666  if (v76 < v39) v39 = v76;
1667  if (v77 < v40) v40 = v77;
1668  if (v76 > v84) v84 = v76;
1669  if (v77 > v82) v82 = v77;
1670  face->pVertexUIDs[j] = v76;
1671  face->pVertexVIDs[j] = v77;
1672  }
1673  if (face->uAttributes & 0x00001000) {
1674  v28->sTextureDeltaU -= v39;
1675  } else {
1676  if (face->uAttributes & 0x8000) {
1677  if (face->resource) {
1678  // v28->sTextureDeltaU -= v84 +
1679  // pBitmaps_LOD->pTextures[face->uBitmapID].uTextureWidth;
1680  v28->sTextureDeltaU -=
1681  v84 + ((Texture *)face->resource)->GetWidth();
1682  }
1683  }
1684  }
1685  if (face->uAttributes & FACE_UNKNOW6) {
1686  v28->sTextureDeltaV -= v40;
1687  } else {
1688  if (face->uAttributes & FACE_INDOOR_DOOR) {
1689  v28->sTextureDeltaV -=
1690  v84 + ((Texture *)face->resource)->GetHeight();
1691  // if (face->uBitmapID != -1)
1692  // v28->sTextureDeltaV -= v82 +
1693  // pBitmaps_LOD->GetTexture(face->uBitmapID)->uTextureHeight;
1694  }
1695  }
1696  if (face->uAttributes & FACE_TEXTURE_FLOW) {
1697  v84 = fixpoint_mul(door->vDirection.x, v70.x);
1698  v82 = fixpoint_mul(door->vDirection.y, v70.y);
1699  v83 = fixpoint_mul(door->vDirection.z, v70.z);
1700  v75 = v84 + v82 + v83;
1701  v82 = fixpoint_mul(v75, v89);
1702  v28->sTextureDeltaU = -v82;
1703  v84 = fixpoint_mul(door->vDirection.x, v67.x);
1704  v82 = fixpoint_mul(door->vDirection.y, v67.y);
1705  v83 = fixpoint_mul(door->vDirection.z, v67.z);
1706  v75 = v84 + v82 + v83;
1707  v32 = fixpoint_mul(v75, v89);
1708  v57 = -v32;
1709  v28->sTextureDeltaV = v57;
1710  v28->sTextureDeltaU += door->pDeltaUs[v88];
1711  v28->sTextureDeltaV = v57 + door->pDeltaVs[v88];
1712  }
1713  }
1714  }
1715 }
1716 
1717 //----- (0046F90C) --------------------------------------------------------
1719  int v2; // edi@6
1720  int v3; // eax@6
1721  int v4; // eax@8
1722  __int16 v5; // ax@11
1723  signed int v6; // ebx@14
1724  signed __int64 v10; // qax@18
1725  int v22; // edi@46
1726  unsigned int v24; // eax@51
1727  int v27; // ST08_4@54
1728  int v28; // edi@54
1729  int v29; // eax@54
1730  int v30; // ecx@62
1731  int v31; // ebx@62
1732  int v32; // eax@62
1733  int v33; // eax@64
1734  int v37; // ebx@85
1735  int v44; // ecx@96
1736  int v45; // edi@101
1737  AIDirection v52; // [sp+0h] [bp-60h]@75
1738  AIDirection v53; // [sp+1Ch] [bp-44h]@116
1739  unsigned int uSectorID; // [sp+3Ch] [bp-24h]@6
1740  int v56; // [sp+40h] [bp-20h]@6
1741  unsigned int _this; // [sp+44h] [bp-1Ch]@51
1742  int v58; // [sp+48h] [bp-18h]@51
1743  int v59; // [sp+4Ch] [bp-14h]@8
1744  unsigned int uFaceID; // [sp+50h] [bp-10h]@6
1745  int v61; // [sp+54h] [bp-Ch]@14
1746  int v62; // [sp+58h] [bp-8h]@6
1747  unsigned int actor_id; // [sp+5Ch] [bp-4h]@1
1748 
1749  if (engine->config->no_actors)
1750  return; // uNumActors = 0;
1751 
1752  for (actor_id = 0; actor_id < uNumActors; actor_id++) {
1753  if (pActors[actor_id].uAIState == Removed ||
1754  pActors[actor_id].uAIState == Disabled ||
1755  pActors[actor_id].uAIState == Summoned ||
1756  !pActors[actor_id].uMovementSpeed)
1757  continue;
1758  uSectorID = pActors[actor_id].uSectorID;
1760  pActors[actor_id].vPosition.x, pActors[actor_id].vPosition.y,
1761  pActors[actor_id].vPosition.z, &uSectorID, &uFaceID);
1762  pActors[actor_id].uSectorID = uSectorID;
1763  v3 = pActors[actor_id].pMonsterInfo.uFlying;
1764  v56 = v2;
1765  v62 = v3;
1766  if (!pActors[actor_id].CanAct()) v62 = 0;
1767  v4 = pActors[actor_id].vPosition.z;
1768  v59 = 0;
1769  if (pActors[actor_id].vPosition.z > v2 + 1) v59 = 1;
1770  if (v2 <= -30000) {
1771  v5 = pIndoor->GetSector(pActors[actor_id].vPosition.x,
1772  pActors[actor_id].vPosition.y, v4);
1773  pActors[actor_id].uSectorID = v5;
1774  v56 = BLV_GetFloorLevel(
1775  pActors[actor_id].vPosition.x, pActors[actor_id].vPosition.y,
1776  pActors[actor_id].vPosition.z, v5, &uFaceID);
1777  if (!v5 || v56 == -30000) continue;
1778  }
1779  if (pActors[actor_id].uCurrentActionAnimation ==
1780  ANIM_Walking) { //монстр двигается
1781  v6 = pActors[actor_id].uMovementSpeed;
1782  if (pActors[actor_id].pActorBuffs[ACTOR_BUFF_SLOWED].Active()) {
1783  if (pActors[actor_id].pActorBuffs[ACTOR_BUFF_SLOWED].uPower)
1784  HEXRAYS_LODWORD(v10) = pActors[actor_id].uMovementSpeed /
1785  (unsigned __int16)pActors[actor_id]
1786  .pActorBuffs[ACTOR_BUFF_SLOWED]
1787  .uPower;
1788  else
1789  v10 = (signed __int64)((double)pActors[actor_id]
1790  .uMovementSpeed *
1791  0.5);
1792  v6 = v10;
1793  }
1794  if (pActors[actor_id].uAIState == Pursuing ||
1795  pActors[actor_id].uAIState == Fleeing)
1796  v6 *= 2;
1798  v6 = (signed __int64)((double)v6 *
1800  if (v6 > 1000) v6 = 1000;
1801  pActors[actor_id].vVelocity.x =
1802  fixpoint_mul(stru_5C6E00->Cos(pActors[actor_id].uYawAngle), v6);
1803  pActors[actor_id].vVelocity.y =
1804  fixpoint_mul(stru_5C6E00->Sin(pActors[actor_id].uYawAngle), v6);
1805  if (v62)
1806  pActors[actor_id].vVelocity.z = fixpoint_mul(
1807  stru_5C6E00->Sin(pActors[actor_id].uPitchAngle), v6);
1808  } else { // actor is not moving(актор не двигается)
1809  pActors[actor_id].vVelocity.x =
1810  fixpoint_mul(55000, pActors[actor_id].vVelocity.x);
1811  pActors[actor_id].vVelocity.y =
1812  fixpoint_mul(55000, pActors[actor_id].vVelocity.y);
1813  if (v62)
1814  pActors[actor_id].vVelocity.z =
1815  fixpoint_mul(55000, pActors[actor_id].vVelocity.z);
1816  }
1817  if (pActors[actor_id].vPosition.z <= v56) {
1818  pActors[actor_id].vPosition.z = v56 + 1;
1819  if (pIndoor->pFaces[uFaceID].uPolygonType == 3) {
1820  if (pActors[actor_id].vVelocity.z < 0)
1821  pActors[actor_id].vVelocity.z = 0;
1822  } else {
1823  if (pIndoor->pFaces[uFaceID].pFacePlane_old.vNormal.z < 45000)
1824  pActors[actor_id].vVelocity.z -=
1826  }
1827  } else {
1828  if (v59 && !v62)
1829  pActors[actor_id].vVelocity.z +=
1830  -8 * (short)pEventTimer->uTimeElapsed *
1832  }
1833  if (pActors[actor_id].vVelocity.x * pActors[actor_id].vVelocity.x +
1834  pActors[actor_id].vVelocity.y * pActors[actor_id].vVelocity.y +
1835  pActors[actor_id].vVelocity.z * pActors[actor_id].vVelocity.z >=
1836  400) {
1837  stru_721530.field_84 = -1;
1838  stru_721530.field_70 = 0;
1839  stru_721530.field_0 = 1;
1840  stru_721530.field_8_radius = pActors[actor_id].uActorRadius;
1841  stru_721530.prolly_normal_d = pActors[actor_id].uActorRadius;
1842  stru_721530.height = pActors[actor_id].uActorHeight;
1843  v22 = 0;
1844  for (uSectorID = 0; uSectorID < 100; uSectorID++) {
1845  stru_721530.position.x = pActors[actor_id].vPosition.x;
1847  stru_721530.position.y = pActors[actor_id].vPosition.y;
1849  stru_721530.normal.z = pActors[actor_id].vPosition.z +
1850  pActors[actor_id].uActorRadius + 1;
1851  stru_721530.position.z = pActors[actor_id].vPosition.z -
1852  pActors[actor_id].uActorRadius +
1853  stru_721530.height - 1;
1855  stru_721530.position.z = pActors[actor_id].vPosition.z +
1856  pActors[actor_id].uActorRadius + 1;
1857  stru_721530.velocity.x = pActors[actor_id].vVelocity.x;
1858  stru_721530.velocity.y = pActors[actor_id].vVelocity.y;
1859  stru_721530.velocity.z = pActors[actor_id].vVelocity.z;
1860  stru_721530.uSectorID = pActors[actor_id].uSectorID;
1861  if (!stru_721530.CalcMovementExtents(v22)) {
1862  v58 = 0;
1863  v24 = 8 * actor_id;
1864  HEXRAYS_LOBYTE(v24) = PID(OBJECT_Actor, actor_id);
1865  for (v61 = 0; v61 < 100; ++v61) {
1870  for (uint j = 0; j < ai_arrays_size; j++) {
1871  if (ai_near_actors_ids[j] != actor_id) {
1872  v27 = abs(
1873  pActors[ai_near_actors_ids[j]].vPosition.z -
1874  pActors[actor_id].vPosition.z);
1875  v28 = abs(
1876  pActors[ai_near_actors_ids[j]].vPosition.y -
1877  pActors[actor_id].vPosition.y);
1878  v29 = abs(
1879  pActors[ai_near_actors_ids[j]].vPosition.x -
1880  pActors[actor_id].vPosition.x);
1881  if (int_get_vector_length(v29, v28, v27) >=
1882  pActors[actor_id].uActorRadius +
1883  (signed int)
1885  .uActorRadius &&
1887  ai_near_actors_ids[j], 40))
1888  ++v58;
1889  }
1890  }
1891  if (_46F04E_collide_against_portals()) break;
1892  }
1893  v56 = v58 > 1;
1895  v30 = stru_721530.normal2.x;
1896  v31 = stru_721530.normal2.y;
1897  v32 = stru_721530.normal2.z -
1899  } else {
1900  v30 = pActors[actor_id].vPosition.x +
1903  v31 = pActors[actor_id].vPosition.y +
1906  v32 = pActors[actor_id].vPosition.z +
1909  }
1910  v33 = collide_against_floor(
1911  v30, v31, v32, &stru_721530.uSectorID, &uFaceID);
1912  if (pIndoor->pFaces[uFaceID].uAttributes &
1913  FACE_INDOOR_SKY &&
1914  pActors[actor_id].uAIState == Dead) {
1915  pActors[actor_id].uAIState = Removed;
1916  continue;
1917  }
1918  if (v59 || v62 ||
1919  !(pIndoor->pFaces[uFaceID].uAttributes &
1920  FACE_INDOOR_SKY)) {
1921  if (v33 == -30000) continue;
1922  if (pActors[actor_id].uCurrentActionAnimation != 1 ||
1923  v33 >= pActors[actor_id].vPosition.z - 100 || v59 ||
1924  v62) {
1926  pActors[actor_id].vPosition.x +=
1929  pActors[actor_id].vPosition.y +=
1932  pActors[actor_id].vPosition.z +=
1935  pActors[actor_id].uSectorID =
1936  (short)stru_721530.uSectorID;
1938  v37 = PID_ID(stru_721530.pid);
1939  if (PID_TYPE(stru_721530.pid) == OBJECT_Actor) {
1940  if (pParty->bTurnBasedModeOn &&
1943  pActors[actor_id].vVelocity.x =
1944  fixpoint_mul(58500, pActors[actor_id].vVelocity.x);
1945  pActors[actor_id].vVelocity.y =
1946  fixpoint_mul(58500, pActors[actor_id].vVelocity.y);
1947  pActors[actor_id].vVelocity.z =
1948  fixpoint_mul(
1949  58500,
1950  pActors[actor_id].vVelocity.z);
1951  v22 = 0;
1952  continue;
1953  }
1954  if (pActors[actor_id]
1955  .pMonsterInfo.uHostilityType) {
1956  if (!v56) {
1957  Actor::AI_Flee(actor_id,
1958  stru_721530.pid, v22,
1959  (AIDirection *)v22);
1960  pActors[actor_id]
1961  .vVelocity.x = fixpoint_mul(
1962  58500,
1963  pActors[actor_id].vVelocity.x);
1964  pActors[actor_id]
1965  .vVelocity.y = fixpoint_mul(
1966  58500,
1967  pActors[actor_id].vVelocity.y);
1968  pActors[actor_id]
1969  .vVelocity.z = fixpoint_mul(
1970  58500,
1971  pActors[actor_id].vVelocity.z);
1972  v22 = 0;
1973  continue;
1974  }
1975  } else {
1976  if (!v56) {
1977  if (!pActors[v37]
1978  .pMonsterInfo
1979  .uHostilityType) {
1981  actor_id, stru_721530.pid,
1982  v22, (AIDirection *)v22);
1983  pActors[actor_id].vVelocity.x =
1984  fixpoint_mul(
1985  58500,
1986  pActors[actor_id]
1987  .vVelocity.x);
1988  pActors[actor_id].vVelocity.y =
1989  fixpoint_mul(
1990  58500,
1991  pActors[actor_id]
1992  .vVelocity.y);
1993  pActors[actor_id].vVelocity.z =
1994  fixpoint_mul(
1995  58500,
1996  pActors[actor_id]
1997  .vVelocity.z);
1998  v22 = 0;
1999  continue;
2000  }
2001  Actor::AI_Flee(actor_id,
2002  stru_721530.pid, v22,
2003  (AIDirection *)v22);
2004  pActors[actor_id]
2005  .vVelocity.x = fixpoint_mul(
2006  58500,
2007  pActors[actor_id].vVelocity.x);
2008  pActors[actor_id]
2009  .vVelocity.y = fixpoint_mul(
2010  58500,
2011  pActors[actor_id].vVelocity.y);
2012  pActors[actor_id]
2013  .vVelocity.z = fixpoint_mul(
2014  58500,
2015  pActors[actor_id].vVelocity.z);
2016  v22 = 0;
2017  continue;
2018  }
2019  }
2020  Actor::AI_StandOrBored(actor_id, 4, v22,
2021  &v53);
2022  pActors[actor_id].vVelocity.x =
2023  fixpoint_mul(
2024  58500,
2025  pActors[actor_id].vVelocity.x);
2026  pActors[actor_id].vVelocity.y =
2027  fixpoint_mul(
2028  58500,
2029  pActors[actor_id].vVelocity.y);
2030  pActors[actor_id].vVelocity.z =
2031  fixpoint_mul(
2032  58500,
2033  pActors[actor_id].vVelocity.z);
2034  v22 = 0;
2035  continue;
2036  }
2037  if (PID_TYPE(stru_721530.pid) ==
2038  OBJECT_Player) {
2039  if (pActors[actor_id].GetActorsRelation(
2040  0)) {
2041  // v51 =
2042  // __OFSUB__(HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime),
2043  // v22); v49 =
2044  // HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime)
2045  // == v22; v50 =
2046  // HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime)
2047  // - v22 < 0;
2048  pActors[actor_id].vVelocity.y = 0;
2049  pActors[actor_id].vVelocity.x = 0;
2050  if (pParty
2051  ->pPartyBuffs
2053  .Active()) {
2054  pParty
2055  ->pPartyBuffs
2057  .Reset();
2058  }
2059 
2061  pActors[actor_id].vVelocity.x =
2062  fixpoint_mul(
2063  58500,
2064  pActors[actor_id].vVelocity.x);
2065  pActors[actor_id].vVelocity.y =
2066  fixpoint_mul(
2067  58500,
2068  pActors[actor_id].vVelocity.y);
2069  pActors[actor_id].vVelocity.z =
2070  fixpoint_mul(
2071  58500,
2072  pActors[actor_id].vVelocity.z);
2073  continue;
2074  }
2075  Actor::AI_FaceObject(actor_id,
2076  stru_721530.pid, v22,
2077  (AIDirection *)v22);
2078  pActors[actor_id].vVelocity.x =
2079  fixpoint_mul(
2080  58500,
2081  pActors[actor_id].vVelocity.x);
2082  pActors[actor_id].vVelocity.y =
2083  fixpoint_mul(
2084  58500,
2085  pActors[actor_id].vVelocity.y);
2086  pActors[actor_id].vVelocity.z =
2087  fixpoint_mul(
2088  58500,
2089  pActors[actor_id].vVelocity.z);
2090  v22 = 0;
2091  continue;
2092  }
2093  if (PID_TYPE(stru_721530.pid) ==
2095  _this = integer_sqrt(
2096  pActors[actor_id].vVelocity.x *
2097  pActors[actor_id].vVelocity.x +
2098  pActors[actor_id].vVelocity.y *
2099  pActors[actor_id].vVelocity.y);
2100  v45 = stru_5C6E00->Atan2(
2101  pActors[actor_id].vPosition.x -
2102  pLevelDecorations[v37].vPosition.x,
2103  pActors[actor_id].vPosition.y -
2104  pLevelDecorations[v37].vPosition.y);
2105  pActors[actor_id].vVelocity.x =
2107  _this);
2108  pActors[actor_id].vVelocity.y =
2110  _this);
2111  pActors[actor_id].vVelocity.x =
2112  fixpoint_mul(
2113  58500,
2114  pActors[actor_id].vVelocity.x);
2115  pActors[actor_id].vVelocity.y =
2116  fixpoint_mul(
2117  58500,
2118  pActors[actor_id].vVelocity.y);
2119  pActors[actor_id].vVelocity.z =
2120  fixpoint_mul(
2121  58500,
2122  pActors[actor_id].vVelocity.z);
2123  v22 = 0;
2124  continue;
2125  }
2126  if (PID_TYPE(stru_721530.pid) ==
2127  OBJECT_BModel) {
2129  if (pIndoor->pFaces[v37].uPolygonType ==
2130  3) {
2131  pActors[actor_id].vVelocity.z = 0;
2132  pActors[actor_id].vPosition.z =
2133  pIndoor
2134  ->pVertices[*pIndoor
2135  ->pFaces[v37]
2136  .pVertexIDs]
2137  .z +
2138  1;
2139  if (pActors[actor_id].vVelocity.x *
2140  pActors[actor_id]
2141  .vVelocity.x +
2142  pActors[actor_id].vVelocity.y *
2143  pActors[actor_id]
2144  .vVelocity.y <
2145  400) {
2146  pActors[actor_id].vVelocity.y = 0;
2147  pActors[actor_id].vVelocity.x = 0;
2148  pActors[actor_id]
2149  .vVelocity.x = fixpoint_mul(
2150  58500,
2151  pActors[actor_id].vVelocity.x);
2152  pActors[actor_id]
2153  .vVelocity.y = fixpoint_mul(
2154  58500,
2155  pActors[actor_id].vVelocity.y);
2156  pActors[actor_id]
2157  .vVelocity.z = fixpoint_mul(
2158  58500,
2159  pActors[actor_id].vVelocity.z);
2160  v22 = 0;
2161  continue;
2162  }
2163  } else {
2164  v61 = abs(pIndoor->pFaces[v37]
2166  .vNormal.x *
2167  pActors[actor_id]
2168  .vVelocity.x +
2169  pIndoor->pFaces[v37]
2171  .vNormal.y *
2172  pActors[actor_id]
2173  .vVelocity.y +
2174  pIndoor->pFaces[v37]
2176  .vNormal.z *
2177  pActors[actor_id]
2178  .vVelocity.z) >>
2179  16;
2180  if ((stru_721530.speed >> 3) > v61)
2181  v61 = stru_721530.speed >> 3;
2182  pActors[actor_id].vVelocity.x +=
2183  fixpoint_mul(
2184  v61,
2185  pIndoor->pFaces[v37]
2186  .pFacePlane_old.vNormal.x);
2187  pActors[actor_id].vVelocity.y +=
2188  fixpoint_mul(
2189  v61,
2190  pIndoor->pFaces[v37]
2191  .pFacePlane_old.vNormal.y);
2192  pActors[actor_id].vVelocity.z +=
2193  fixpoint_mul(
2194  v61,
2195  pIndoor->pFaces[v37]
2196  .pFacePlane_old.vNormal.z);
2197  if (pIndoor->pFaces[v37].uPolygonType !=
2198  4 &&
2199  pIndoor->pFaces[v37].uPolygonType !=
2200  3) {
2202  ((pIndoor->pFaces[v37]
2203  .pFacePlane_old.dist +
2204  pIndoor->pFaces[v37]
2206  .vNormal.z *
2207  pActors[actor_id]
2208  .vPosition.z +
2209  pIndoor->pFaces[v37]
2211  .vNormal.y *
2212  pActors[actor_id]
2213  .vPosition.y +
2214  pIndoor->pFaces[v37]
2216  .vNormal.x *
2217  pActors[actor_id]
2218  .vPosition.x) >>
2219  16);
2220  if (v44 > 0) {
2221  pActors[actor_id].vPosition.x +=
2222  fixpoint_mul(
2223  v44,
2224  pIndoor->pFaces[v37]
2226  .vNormal.x);
2227  pActors[actor_id].vPosition.y +=
2228  fixpoint_mul(
2229  v44,
2230  pIndoor->pFaces[v37]
2232  .vNormal.y);
2233  pActors[actor_id].vPosition.z +=
2234  fixpoint_mul(
2235  v44,
2236  pIndoor->pFaces[v37]
2238  .vNormal.z);
2239  }
2240  pActors[actor_id]
2241  .uYawAngle = stru_5C6E00->Atan2(
2242  pActors[actor_id].vVelocity.x,
2243  pActors[actor_id].vVelocity.y);
2244  }
2245  }
2246  if (pIndoor->pFaces[v37].uAttributes &
2247  FACE_UNKNOW1)
2249  pIndoor
2250  ->pFaceExtras[pIndoor
2251  ->pFaces[v37]
2252  .uFaceExtraID]
2253  .uEventID,
2254  0, 1);
2255  }
2256  pActors[actor_id].vVelocity.x = fixpoint_mul(
2257  58500, pActors[actor_id].vVelocity.x);
2258  pActors[actor_id].vVelocity.y = fixpoint_mul(
2259  58500, pActors[actor_id].vVelocity.y);
2260  pActors[actor_id].vVelocity.z = fixpoint_mul(
2261  58500, pActors[actor_id].vVelocity.z);
2262  v22 = 0;
2263  continue;
2264  } else {
2265  pActors[actor_id].vPosition.x =
2266  (short)stru_721530.normal2.x;
2267  pActors[actor_id].vPosition.y =
2268  (short)stru_721530.normal2.y;
2269  pActors[actor_id].vPosition.z =
2270  (short)stru_721530.normal2.z -
2271  (short)stru_721530.prolly_normal_d - 1;
2272  pActors[actor_id].uSectorID =
2273  (short)stru_721530.uSectorID;
2274  // goto LABEL_123;
2275  break;
2276  }
2277 
2278  } else if (pActors[actor_id].vPosition.x & 1) {
2279  pActors[actor_id].uYawAngle += 100;
2280  } else {
2281  pActors[actor_id].uYawAngle -= 100;
2282  }
2283  } else {
2284  if (pParty->bTurnBasedModeOn &&
2287  continue;
2288  if (!pActors[actor_id].pMonsterInfo.uHostilityType ||
2289  v56 != v22) {
2290  Actor::AI_StandOrBored(actor_id, 4, v22, &v52);
2291  continue;
2292  }
2293  }
2294  }
2295  }
2296  } else {
2297  pActors[actor_id].vVelocity.z = 0;
2298  pActors[actor_id].vVelocity.y = 0;
2299  pActors[actor_id].vVelocity.x = 0;
2300  if (pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_SKY) {
2301  if (pActors[actor_id].uAIState == Dead)
2302  pActors[actor_id].uAIState = Removed;
2303  }
2304  }
2305  // LABEL_123:
2306  }
2307 }
2308 
2309 //----- (00460A78) --------------------------------------------------------
2310 void PrepareToLoadBLV(unsigned int bLoading) {
2311  unsigned int respawn_interval; // ebx@1
2312  unsigned int map_id; // eax@8
2313  MapInfo *map_info; // edi@9
2314  int v4; // eax@11
2315  char v28; // zf@81
2316  signed int v30; // edi@94
2317  int v34[4]; // [sp+3E8h] [bp-2Ch]@96
2318  int v35; // [sp+3F8h] [bp-1Ch]@1
2319  int v38; // [sp+404h] [bp-10h]@1
2320  int pDest; // [sp+40Ch] [bp-8h]@1
2321 
2322  respawn_interval = 0;
2324  bNoNPCHiring = false;
2325  pDest = 1;
2327 
2328  engine->SetUnderwater(
2330 
2331  if ((pCurrentMapName == "out15.odm") || (pCurrentMapName == "d23.blv")) {
2332  bNoNPCHiring = true;
2333  }
2340  if (map_id) {
2341  map_info = &pMapStats->pInfos[map_id];
2342  respawn_interval = pMapStats->pInfos[map_id].uRespawnIntervalDays;
2343  v38 = GetAlertStatus();
2344  } else {
2345  map_info = (MapInfo *)bLoading;
2346  }
2348 
2351  respawn_interval, (char *)&pDest) -
2352  1;
2353  if (!v4) Error("Unable to open %s", pCurrentMapName.c_str());
2354 
2355  if (v4 == 1) Error("File %s is not a BLV File", pCurrentMapName.c_str());
2356 
2357  if (v4 == 2) Error("Attempt to open new level before clearing old");
2358  if (v4 == 3) Error("Out of memory loading indoor level");
2359  if (!(dword_6BE364_game_settings_1 & GAME_SETTINGS_2000)) {
2362  }
2363  dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_2000;
2364  if (!map_id) pDest = 0;
2365  if (pDest == 1) {
2366  for (uint i = 0; i < pIndoor->uNumSpawnPoints; ++i) {
2367  auto spawn = pIndoor->pSpawnPoints + i;
2368  if (spawn->IsMonsterSpawn())
2369  SpawnEncounter(map_info, spawn, 0, 0, 0);
2370  else
2371  map_info->SpawnRandomTreasure(spawn);
2372  }
2374  }
2375 
2376  for (uint i = 0; i < pIndoor->uNumDoors; ++i) {
2377  if (pIndoor->pDoors[i].uAttributes & 0x01) {
2379  pIndoor->pDoors[i].uTimeSinceTriggered = 15360;
2380  pIndoor->pDoors[i].uAttributes = 2;
2381  }
2382 
2383  if (pIndoor->pDoors[i].uState == BLVDoor::Closed) {
2385  pIndoor->pDoors[i].uTimeSinceTriggered = 15360;
2386  pIndoor->pDoors[i].uAttributes = 2;
2387  } else if (pIndoor->pDoors[i].uState == BLVDoor::Open) {
2389  pIndoor->pDoors[i].uTimeSinceTriggered = 15360;
2390  pIndoor->pDoors[i].uAttributes = 2;
2391  }
2392  }
2393 
2394  /*for (uint i = 0; i < pIndoor->uNumFaces; ++i)
2395  {
2396  if (pIndoor->pFaces[i].uBitmapID != -1)
2397  pBitmaps_LOD->pTextures[pIndoor->pFaces[i].uBitmapID].palette_id2 =
2398  pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[pIndoor->pFaces[i].uBitmapID].palette_id1);
2399  }*/
2400 
2402 
2403  v35 = 0;
2404  for (uint i = 0; i < uNumLevelDecorations; ++i) {
2406 
2407  DecorationDesc *decoration = pDecorationList->GetDecoration(pLevelDecorations[i].uDecorationDescID);
2408 
2409  if (decoration->uSoundID && _6807E0_num_decorations_with_sounds_6807B8 < 9) {
2410  // pSoundList->LoadSound(decoration->uSoundID, 0);
2412  }
2413 
2414  if (!(pLevelDecorations[i].uFlags & LEVEL_DECORATION_INVISIBLE)) {
2415  if (!decoration->DontDraw()) {
2416  if (decoration->uLightRadius) {
2417  unsigned char r = 255, g = 255, b = 255;
2418  if (/*render->pRenderD3D*/ true &&
2419  render->config->is_using_colored_lights) {
2420  r = decoration->uColoredLightRed;
2421  g = decoration->uColoredLightGreen;
2422  b = decoration->uColoredLightBlue;
2423  }
2425  pLevelDecorations[i].vPosition.x,
2426  pLevelDecorations[i].vPosition.y,
2427  pLevelDecorations[i].vPosition.z +
2428  decoration->uDecorationHeight,
2429  decoration->uLightRadius, r, g, b, _4E94D0_light_type);
2430  }
2431  }
2432  }
2433 
2434  if (!pLevelDecorations[i].uEventID) {
2435  if (pLevelDecorations[i].IsInteractive()) {
2436  if (v35 < 124) {
2437  pLevelDecorations[i]._idx_in_stru123 = v35 + 75;
2439  pLevelDecorations[i].uFlags |=
2441  v35++;
2442  }
2443  }
2444  }
2445  }
2446 
2448 
2449  for (uint i = 0; i < uNumSpriteObjects; ++i) {
2450  if (pSpriteObjects[i].uObjectDescID) {
2451  if (pSpriteObjects[i].containing_item.uItemID) {
2452  if (pSpriteObjects[i].containing_item.uItemID != 220 &&
2453  pItemsTable
2454  ->pItems[pSpriteObjects[i].containing_item.uItemID]
2455  .uEquipType == EQUIP_POTION &&
2456  !pSpriteObjects[i].containing_item.uEnchantmentType)
2457  pSpriteObjects[i].containing_item.uEnchantmentType =
2458  rand() % 15 + 5;
2460  &pSpriteObjects[i].containing_item);
2461  }
2462  }
2463  }
2464 
2465  // INDOOR initialize actors
2466  v38 = 0;
2467 
2468  for (uint i = 0; i < uNumActors; ++i) {
2469  if (pActors[i].uAttributes & ACTOR_UNKNOW7) {
2470  if (!map_id) {
2471  pActors[i].pMonsterInfo.field_3E = 19;
2472  pActors[i].uAttributes |= ACTOR_UNKNOW11;
2473  continue;
2474  }
2475  v28 = v38 == 0;
2476  } else {
2477  v28 = v38 == 1;
2478  }
2479 
2480  if (!v28) {
2481  pActors[i].PrepareSprites(0);
2482  pActors[i].pMonsterInfo.uHostilityType =
2484  if (pActors[i].pMonsterInfo.field_3E != 11 &&
2485  pActors[i].pMonsterInfo.field_3E != 19 &&
2486  (!pActors[i].sCurrentHP || !pActors[i].pMonsterInfo.uHP)) {
2487  pActors[i].pMonsterInfo.field_3E = 5;
2488  pActors[i].UpdateAnimation();
2489  }
2490  } else {
2491  pActors[i].pMonsterInfo.field_3E = 19;
2492  pActors[i].uAttributes |= ACTOR_UNKNOW11;
2493  }
2494  }
2495 
2497 
2498  // Party to start position
2499  Actor this_;
2500  this_.pMonsterInfo.uID = 45;
2501  this_.PrepareSprites(0);
2502  if (!bLoading) {
2503  pParty->sRotationX = 0;
2504  pParty->sRotationY = 0;
2505  pParty->vPosition.z = 0;
2506  pParty->vPosition.y = 0;
2507  pParty->vPosition.x = 0;
2508  pParty->uFallStartY = 0;
2509  pParty->uFallSpeed = 0;
2511  }
2512  viewparams->_443365();
2513  PlayLevelMusic();
2514  if (!bLoading) {
2515  v30 = 0;
2516  for (uint pl_id = 1; pl_id <= 4; ++pl_id) {
2517  if (pPlayers[pl_id]->CanAct()) v34[v30++] = pl_id;
2518  }
2519  if (v30) {
2520  if (pDest) {
2523  uSpeakingCharacter = v34[rand() % v30];
2524  }
2525  }
2526  }
2527 }
2528 
2529 //----- (0046CEC3) --------------------------------------------------------
2530 int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID,
2531  unsigned int *pFaceID) {
2532  int v13; // ecx@13
2533  signed int v14; // ebx@14
2534  int v15; // eax@16
2535  int v21; // eax@27
2536  signed int v28; // eax@45
2537  int v29; // ebx@47
2538  int v38; // edx@62
2539  bool v47; // [sp+24h] [bp-1Ch]@43
2540  bool current_vertices_Y; // [sp+28h] [bp-18h]@10
2541  bool v49; // [sp+28h] [bp-18h]@41
2542  bool next_vertices_Y; // [sp+2Ch] [bp-14h]@12
2543  int number_hits; // [sp+30h] [bp-10h]@10
2544  int v54; // [sp+30h] [bp-10h]@41
2545  int v55; // [sp+34h] [bp-Ch]@1
2546 
2547  static int blv_floor_id[50]; // 00721200
2548  static int blv_floor_level[50]; // 007212C8
2549 
2550  static __int16 blv_floor_face_vert_coord_Y[104]; // word_721390_ys
2551  static __int16 blv_floor_face_vert_coord_X[104]; // word_721460_xs
2552 
2553  BLVSector *pSector = &pIndoor->pSectors[uSectorID];
2554  v55 = 0;
2555  for (uint i = 0; i < pSector->uNumFloors; ++i) {
2556  BLVFace *pFloor = &pIndoor->pFaces[pSector->pFloors[i]];
2557  if (pFloor->Ethereal()) continue;
2558 
2559  assert(pFloor->uNumVertices);
2560  if (x <= pFloor->pBounding.x2 && x >= pFloor->pBounding.x1 &&
2561  y <= pFloor->pBounding.y2 && y >= pFloor->pBounding.y1) {
2562  for (uint j = 0; j < pFloor->uNumVertices; ++j) {
2563  blv_floor_face_vert_coord_X[2 * j] =
2564  pFloor->pXInterceptDisplacements[j] +
2565  pIndoor->pVertices[pFloor->pVertexIDs[j]].x;
2566  blv_floor_face_vert_coord_X[2 * j + 1] =
2567  pFloor->pXInterceptDisplacements[j] +
2568  pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].x;
2569  blv_floor_face_vert_coord_Y[2 * j] =
2570  pFloor->pYInterceptDisplacements[j] +
2571  pIndoor->pVertices[pFloor->pVertexIDs[j]].y;
2572  blv_floor_face_vert_coord_Y[2 * j + 1] =
2573  pFloor->pYInterceptDisplacements[j] +
2574  pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].y;
2575  }
2576  blv_floor_face_vert_coord_X[2 * pFloor->uNumVertices] =
2577  blv_floor_face_vert_coord_X[0];
2578  blv_floor_face_vert_coord_Y[2 * pFloor->uNumVertices] =
2579  blv_floor_face_vert_coord_Y[0];
2580 
2581  next_vertices_Y = blv_floor_face_vert_coord_Y[0] >= y;
2582  number_hits = 0;
2583 
2584  for (uint j = 0; j < 2 * pFloor->uNumVertices; ++j) {
2585  if (number_hits >= 2) break;
2586 
2587  current_vertices_Y = next_vertices_Y;
2588  next_vertices_Y = blv_floor_face_vert_coord_Y[j + 1] >= y;
2589 
2590  v13 = i;
2591  if (current_vertices_Y == next_vertices_Y) continue;
2592 
2593  v14 = blv_floor_face_vert_coord_X[j + 1] >= x ? 0 : 2;
2594  v15 = v14 | (blv_floor_face_vert_coord_X[j] < x);
2595 
2596  if (v15 == 3) {
2597  continue;
2598  } else if (!v15) {
2599  ++number_hits;
2600  } else {
2601  long long a_div_b =
2602  fixpoint_div(y - blv_floor_face_vert_coord_Y[j],
2603  blv_floor_face_vert_coord_Y[j + 1] -
2604  blv_floor_face_vert_coord_Y[j]);
2605  long long res = fixpoint_mul(
2606  (signed int)blv_floor_face_vert_coord_X[j + 1] -
2607  (signed int)blv_floor_face_vert_coord_X[j],
2608  a_div_b);
2609 
2610  if (res + blv_floor_face_vert_coord_X[j] >= x)
2611  ++number_hits;
2612  }
2613  }
2614 
2615  if (number_hits == 1) {
2616  if (v55 >= 50) break;
2617  if (pFloor->uPolygonType == POLYGON_Floor ||
2618  pFloor->uPolygonType == POLYGON_Ceiling)
2619  v21 = pIndoor->pVertices[pFloor->pVertexIDs[0]].z;
2620  else
2621  v21 = fixpoint_mul(pFloor->zCalc1, x) +
2622  fixpoint_mul(pFloor->zCalc2, y) +
2623  (short)(pFloor->zCalc3 >> 16);
2624  blv_floor_level[v55] = v21;
2625  blv_floor_id[v55] = pSector->pFloors[i];
2626  v55++;
2627  }
2628  }
2629  }
2630 
2631  if (pSector->field_0 & 8) {
2632  for (uint i = 0; i < pSector->uNumPortals; ++i) {
2633  BLVFace *portal = &pIndoor->pFaces[pSector->pPortals[i]];
2634  if (portal->uPolygonType != POLYGON_Floor) continue;
2635 
2636  if (!portal->uNumVertices) continue;
2637 
2638  if (x <= portal->pBounding.x2 && x >= portal->pBounding.x1 &&
2639  y <= portal->pBounding.y2 && y >= portal->pBounding.y1) {
2640  for (uint j = 0; j < portal->uNumVertices; ++j) {
2641  blv_floor_face_vert_coord_X[2 * j] =
2642  portal->pXInterceptDisplacements[j] +
2643  pIndoor->pVertices[portal->pVertexIDs[j]].x;
2644  blv_floor_face_vert_coord_X[2 * j + 1] =
2645  portal->pXInterceptDisplacements[j + 1] +
2646  pIndoor->pVertices[portal->pVertexIDs[j + 1]].x;
2647  blv_floor_face_vert_coord_Y[2 * j] =
2648  portal->pYInterceptDisplacements[j] +
2649  pIndoor->pVertices[portal->pVertexIDs[j]].y;
2650  blv_floor_face_vert_coord_Y[2 * j + 1] =
2651  portal->pYInterceptDisplacements[j + 1] +
2652  pIndoor->pVertices[portal->pVertexIDs[j + 1]].y;
2653  }
2654  blv_floor_face_vert_coord_X[2 * portal->uNumVertices] =
2655  blv_floor_face_vert_coord_X[0];
2656  blv_floor_face_vert_coord_Y[2 * portal->uNumVertices] =
2657  blv_floor_face_vert_coord_Y[0];
2658  v54 = 0;
2659  v47 = blv_floor_face_vert_coord_Y[0] >= y;
2660 
2661  for (uint j = 0; j < 2 * portal->uNumVertices; ++j) {
2662  v49 = v47;
2663  if (v54 >= 2) break;
2664  v47 = blv_floor_face_vert_coord_Y[j + 1] >= y;
2665  if (v49 != v47) {
2666  v28 = blv_floor_face_vert_coord_X[j + 1] >= x ? 0 : 2;
2667  v29 = v28 | (blv_floor_face_vert_coord_X[j] < x);
2668  if (v29 != 3) {
2669  if (!v29) {
2670  ++v54;
2671  } else {
2672  long long a_div_b = fixpoint_div(
2673  y - blv_floor_face_vert_coord_Y[j],
2674  blv_floor_face_vert_coord_Y[j + 1] -
2675  blv_floor_face_vert_coord_Y[j]);
2676  long long res = fixpoint_mul(
2677  blv_floor_face_vert_coord_X[j + 1] -
2678  blv_floor_face_vert_coord_X[j],
2679  a_div_b);
2680  if (res + blv_floor_face_vert_coord_X[j] >= x)
2681  ++v54;
2682  }
2683  }
2684  }
2685  }
2686  if (v54 == 1) {
2687  if (v55 >= 50) break;
2688  blv_floor_level[v55] = -29000;
2689  blv_floor_id[v55] = pSector->pPortals[i];
2690  v55++;
2691  }
2692  }
2693  }
2694  }
2695  if (v55 == 1) {
2696  *pFaceID = blv_floor_id[0];
2697  if (blv_floor_level[0] <= -29000) __debugbreak();
2698  return blv_floor_level[0];
2699  }
2700  if (!v55) return -30000;
2701  *pFaceID = blv_floor_id[0];
2702  // result = blv_floor_level[0];
2703 
2704  /*for ( v35 = 1; v35 < v55; ++v35 )
2705  {
2706  if ( blv_floor_level[0] <= z + 5 )
2707  {
2708  if ( blv_floor_level[v35] >= blv_floor_level[0] || blv_floor_level[v35]
2709  > z + 5 ) continue; blv_floor_level[0] = blv_floor_level[v35]; *pFaceID =
2710  blv_floor_id[v35]; continue;
2711  }
2712  if ( blv_floor_level[v35] < blv_floor_level[0] )
2713  {
2714  blv_floor_level[0] = blv_floor_level[v35];
2715  *pFaceID = blv_floor_id[v35];
2716  }
2717  }*/
2718 
2719  int result = blv_floor_level[0];
2720  for (uint i = 1; i < v55; ++i) {
2721  v38 = blv_floor_level[i];
2722  if (result <= z + 5) {
2723  if (v38 > result && v38 <= z + 5) {
2724  result = blv_floor_level[i];
2725  if (blv_floor_level[i] <= -29000) __debugbreak();
2726  *pFaceID = blv_floor_id[i];
2727  }
2728  } else if (v38 < result) {
2729  result = blv_floor_level[i];
2730  if (blv_floor_level[i] < -29000) __debugbreak(); // crashes here when <=
2731  *pFaceID = blv_floor_id[i];
2732  }
2733  }
2734 
2735  return result;
2736 }
2737 
2738 //----- (0043FDED) --------------------------------------------------------
2739 void IndoorLocation::PrepareActorRenderList_BLV() { // combines this with outdoorlocation ??
2740  unsigned int v4; // eax@5
2741  int v6; // esi@5
2742  int v8; // eax@10
2743  SpriteFrame *v9; // eax@16
2744  int v12; // ecx@28
2745  __int16 v41; // [sp+3Ch] [bp-18h]@18
2746  // int z; // [sp+48h] [bp-Ch]@32
2747  // signed int y; // [sp+4Ch] [bp-8h]@32
2748  // int x; // [sp+50h] [bp-4h]@32
2749 
2750  for (uint i = 0; i < uNumActors; ++i) {
2751  if (pActors[i].uAIState == Removed || pActors[i].uAIState == Disabled)
2752  continue;
2753 
2754  v4 = stru_5C6E00->Atan2(
2755  pActors[i].vPosition.x - pIndoorCameraD3D->vPartyPos.x,
2756  pActors[i].vPosition.y - pIndoorCameraD3D->vPartyPos.y);
2757  v6 = ((signed int)(pActors[i].uYawAngle +
2758  ((signed int)stru_5C6E00->uIntegerPi >> 3) - v4 +
2759  stru_5C6E00->uIntegerPi) >>
2760  8) &
2761  7;
2762  v8 = pActors[i].uCurrentActionTime;
2763  if (pParty->bTurnBasedModeOn) {
2764  if (pActors[i].uCurrentActionAnimation == 1)
2765  v8 = i * 32 + pMiscTimer->uTotalGameTimeElapsed;
2766  } else {
2767  if (pActors[i].uCurrentActionAnimation == 1)
2768  v8 = i * 32 + pBLVRenderParams->field_0_timer_;
2769  }
2770  if (pActors[i].pActorBuffs[ACTOR_BUFF_STONED].Active() ||
2771  pActors[i].pActorBuffs[ACTOR_BUFF_PARALYZED].Active())
2772  v8 = 0;
2773 
2774  if (pActors[i].uAIState == Resurrected)
2776  pActors[i].pSpriteIDs[pActors[i].uCurrentActionAnimation], v8);
2777  else
2779  pActors[i].pSpriteIDs[pActors[i].uCurrentActionAnimation], v8);
2780 
2781  if (v9->icon_name == "null") continue;
2782 
2783  v41 = 0;
2784  if (v9->uFlags & 2) v41 = 2;
2785  if (v9->uFlags & 0x40000) v41 |= 0x40;
2786  if (v9->uFlags & 0x20000) v41 |= 0x80;
2787  if ((256 << v6) & v9->uFlags) v41 |= 4;
2788  if (v9->uGlowRadius) {
2790  pActors[i].vPosition.x, pActors[i].vPosition.y,
2791  pActors[i].vPosition.z, pActors[i].uSectorID, v9->uGlowRadius,
2792  0xFFu, 0xFFu, 0xFFu, _4E94D3_light_type);
2793  }
2794 
2795  for (v12 = 0; v12 < pBspRenderer->uNumVisibleNotEmptySectors; ++v12) {
2796  if (pBspRenderer
2797  ->pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v12] ==
2798  pActors[i].uSectorID) {
2799  int view_x = 0;
2800  int view_y = 0;
2801  int view_z = 0;
2802  bool visible = pIndoorCameraD3D->ViewClip(
2803  pActors[i].vPosition.x, pActors[i].vPosition.y,
2804  pActors[i].vPosition.z, &view_x, &view_y, &view_z);
2805  if (visible) {
2806  if (abs(view_x) >= abs(view_y)) {
2807  int projected_x = 0;
2808  int projected_y = 0;
2809  pIndoorCameraD3D->Project(view_x, view_y, view_z,
2810  &projected_x, &projected_y);
2811 
2812  if (uNumBillboardsToDraw >= 500) break;
2815 
2816  pActors[i].uAttributes |= ACTOR_VISIBLE;
2818  .hwsprite = v9->hw_sprites[v6];
2819 
2820  // error catching
2821  if (v9->hw_sprites[v6]->texture->GetHeight() == 0 || v9->hw_sprites[v6]->texture->GetWidth() == 0)
2822  __debugbreak();
2823 
2825  .uPalette = v9->uPaletteIndex;
2827 
2830 
2831  auto _v18_over_x =
2833  floorf(pIndoorCameraD3D->fov_x + 0.5f)) /
2834  fixed::FromInt(view_x);
2837 
2838  if (pActors[i].pActorBuffs[ACTOR_BUFF_MASS_DISTORTION].Active()) {
2841  } else if (pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].Active() &&
2842  pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uPower > 0) {
2844  1.0f / pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uPower *
2846  }
2847 
2858  ->pMonsters[pActors[i].pMonsterInfo.uID - 1].sTintColor;
2859 
2860  if (pActors[i].pActorBuffs[ACTOR_BUFF_STONED].Active()) {
2862  .field_1E |= 0x100;
2863  }
2864  }
2865  }
2866  }
2867  }
2868  }
2869 }
2870 
2872  unsigned int v6; // eax@12
2873 
2874  for (uint i = 0; i < uNumSpriteObjects; ++i) {
2875  if (pSpriteObjects[i].uObjectDescID) {
2876  if (pSpriteObjects[i].HasSprite()) {
2877  if ((pSpriteObjects[i].uType < 1000 ||
2878  pSpriteObjects[i].uType >= 10000) &&
2879  (pSpriteObjects[i].uType < 500 ||
2880  pSpriteObjects[i].uType >= 600) &&
2881  (pSpriteObjects[i].uType < 811 ||
2882  pSpriteObjects[i].uType >= 815) ||
2884  SpriteFrame *v4 = pSpriteObjects[i].GetSpriteFrame();
2885  int a6 = v4->uGlowRadius * pSpriteObjects[i].field_22_glow_radius_multiplier;
2886  v6 = stru_5C6E00->Atan2(pSpriteObjects[i].vPosition.x - pIndoorCameraD3D->vPartyPos.x,
2887  pSpriteObjects[i].vPosition.y - pIndoorCameraD3D->vPartyPos.y);
2888  int v7 = pSpriteObjects[i].uFacing;
2889  int v9 = ((int)(stru_5C6E00->uIntegerPi + ((int)stru_5C6E00->uIntegerPi >> 3) + v7 - v6) >> 8) & 7;
2890 
2892  // error catching
2893  if (v4->hw_sprites[v9]->texture->GetHeight() == 0 || v4->hw_sprites[v9]->texture->GetWidth() == 0)
2894  __debugbreak();
2895 
2896  // centre sprite on coords
2897  int modz = pSpriteObjects[i].vPosition.z;
2898  if (v4->uFlags & 0x20)
2899  modz -= (int)(fixpoint_mul(v4->scale._internal, v4->hw_sprites[v9]->uBufferHeight) / 2);
2900 
2901  int16_t v34 = 0;
2902  if (v4->uFlags & 2) v34 = 2;
2903  if (v4->uFlags & 0x40000) v34 |= 0x40;
2904  if (v4->uFlags & 0x20000) v34 |= 0x80;
2905  // v11 = (int *)(256 << v9);
2906  if ((256 << v9) & v4->uFlags) v34 |= 4;
2907  if (a6) {
2909  pSpriteObjects[i].vPosition.x,
2910  pSpriteObjects[i].vPosition.y,
2911  pSpriteObjects[i].vPosition.z,
2912  pSpriteObjects[i].uSectorID, a6,
2913  pSpriteObjects[i].GetParticleTrailColorR(),
2914  pSpriteObjects[i].GetParticleTrailColorG(),
2915  pSpriteObjects[i].GetParticleTrailColorB(),
2917  }
2918 
2919  int view_x = 0;
2920  int view_y = 0;
2921  int view_z = 0;
2922 
2923  bool visible = pIndoorCameraD3D->ViewClip(pSpriteObjects[i].vPosition.x,
2924  pSpriteObjects[i].vPosition.y,
2925  modz,
2926  &view_x, &view_y, &view_z);
2927 
2928  view_x -= 0.005;
2929 
2930 
2931  if (visible) {
2932  int projected_x = 0;
2933  int projected_y = 0;
2934  pIndoorCameraD3D->Project(view_x, view_y, view_z, &projected_x, &projected_y);
2935 
2936  assert(uNumBillboardsToDraw < 499);
2939 
2940  pSpriteObjects[i].uAttributes |= 1;
2943  // if ( render->pRenderD3D )
2944  {
2948  v4->scale.GetFloat() * (int)floorf(pIndoorCameraD3D->fov_x + 0.5f) / view_x;
2950  v4->scale.GetFloat() * (int)floorf(pIndoorCameraD3D->fov_x + 0.5f) / view_x;
2951  }
2952 
2963  }
2964  }
2965  }
2966  }
2967  }
2968 }
2969 
2970 void AddBspNodeToRenderList(unsigned int node_id) {
2971  BLVSector *pSector = &pIndoor->pSectors[pBspRenderer->nodes[node_id].uSectorID];
2972  // if ( render->pRenderD3D )
2973  {
2974  for (uint i = 0; i < pSector->uNumNonBSPFaces; ++i)
2975  // logger->Warning(L"Non-BSP face: %X", v3->pFaceIDs[v2]);
2976  pBspRenderer->AddFaceToRenderList_d3d(node_id, pSector->pFaceIDs[i]); // рекурсия\recursion
2977  }
2978  /*else
2979  {
2980  for (uint i = 0; i < pSector->uNumNonBSPFaces; ++i)
2981  pBspRenderer->AddFaceToRenderList_sw(node_id, pSector->pFaceIDs[i]);
2982  }*/
2983  if (pSector->field_0 & 0x10) sub_4406BC(node_id, pSector->uFirstBSPNode);
2984 }
2985 
2986 //----- (004406BC) --------------------------------------------------------
2987 void sub_4406BC(unsigned int node_id, unsigned int uFirstNode) {
2988  BLVSector *pSector; // esi@2
2989  BSPNode *pNode; // edi@2
2990  BLVFace *pFace; // eax@2
2991  int v5; // ecx@2
2992  __int16 v6; // ax@6
2993  int v7; // ebp@10
2994  int v8; // ebx@10
2995  __int16 v9; // di@18
2996  BspRenderer_stru0 *node; // [sp+18h] [bp-4h]@1
2997 
2998  // logger->Warning(L"sub_4406BC(%u, %u)", a1, uFirstNode);
2999 
3000  // v10 = a1;
3001  node = &pBspRenderer->nodes[node_id];
3002  while (1) {
3003  pSector = &pIndoor->pSectors[node->uSectorID];
3004  pNode = &pIndoor->pNodes[uFirstNode];
3005  pFace = &pIndoor->pFaces[pSector->pFaceIDs[pNode->uCoplanarOffset]];
3006  v5 = pFace->pFacePlane_old.dist +
3010  pFace->pFacePlane_old.vNormal.z; // plane equation
3011  if (pFace->Portal() && pFace->uSectorID != node->uSectorID) v5 = -v5;
3012  // v11 = v5 > 0;
3013  if (v5 <= 0)
3014  v6 = pNode->uFront;
3015  else
3016  v6 = pNode->uBack;
3017  if (v6 != -1) sub_4406BC(node_id, v6);
3018  v7 = pNode->uCoplanarOffset;
3019  v8 = v7 + pNode->uCoplanarSize;
3020 
3021  // logger->Warning(L"Node %u: %X to %X (%hX)", uFirstNode, v7, v8,
3022  // v2->pFaceIDs[v7]);
3023 
3024  // if ( render->pRenderD3D )
3025  {
3026  while (v7 < v8)
3028  pSector->pFaceIDs[v7++]);
3029  }
3030  /*else
3031  {
3032  while ( v7 < v8 )
3033  pBspRenderer->AddFaceToRenderList_sw(node_id,
3034  pSector->pFaceIDs[v7++]);
3035  }*/
3036  v9 = v5 > 0 ? pNode->uFront : pNode->uBack;
3037  if (v9 == -1) break;
3038  uFirstNode = v9;
3039  }
3040 }
3041 
3042 void IndoorLocation::PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID) {
3043  unsigned int v8; // edi@5
3044  int v9; // edi@5
3045  int v10; // eax@7
3046  SpriteFrame *v11; // eax@7
3047  Particle_sw particle; // [sp+Ch] [bp-A0h]@3
3048  int v30; // [sp+8Ch] [bp-20h]@7
3049 
3050  if (pLevelDecorations[uDecorationID].uFlags & LEVEL_DECORATION_INVISIBLE)
3051  return;
3052 
3053  DecorationDesc *decoration = pDecorationList->GetDecoration(pLevelDecorations[uDecorationID].uDecorationDescID);
3054 
3055  if (decoration->uFlags & DECORATION_DESC_EMITS_FIRE) {
3056  memset(&particle, 0, sizeof(particle)); // fire, like at the Pit's tavern
3057  particle.type =
3059  particle.uDiffuse = 0xFF3C1E;
3060  particle.x = (double)pLevelDecorations[uDecorationID].vPosition.x;
3061  particle.y = (double)pLevelDecorations[uDecorationID].vPosition.y;
3062  particle.z = (double)pLevelDecorations[uDecorationID].vPosition.z;
3063  particle.r = 0.0;
3064  particle.g = 0.0;
3065  particle.b = 0.0;
3066  particle.particle_size = 1.0;
3067  particle.timeToLive = (rand() & 0x80) + 128;
3068  particle.texture = spell_fx_renderer->effpar01;
3069  particle_engine->AddParticle(&particle);
3070  return;
3071  }
3072 
3073  if (decoration->uFlags & DECORATION_DESC_DONT_DRAW) {
3074  return;
3075  }
3076 
3077  v8 = pLevelDecorations[uDecorationID].field_10_y_rot +
3078  ((signed int)stru_5C6E00->uIntegerPi >> 3) -
3079  stru_5C6E00->Atan2(pLevelDecorations[uDecorationID].vPosition.x -
3081  pLevelDecorations[uDecorationID].vPosition.y -
3083  v9 = ((signed int)(stru_5C6E00->uIntegerPi + v8) >> 8) & 7;
3084  int v37 = pBLVRenderParams->field_0_timer_;
3086  v10 = abs(pLevelDecorations[uDecorationID].vPosition.x +
3087  pLevelDecorations[uDecorationID].vPosition.y);
3088  v11 = pSpriteFrameTable->GetFrame(decoration->uSpriteID, v37 + v10);
3089 
3090  // error catching
3091  if (v11->icon_name == "null") __debugbreak();
3092 
3093  v30 = 0;
3094  if (v11->uFlags & 2) v30 = 2;
3095  if (v11->uFlags & 0x40000) v30 |= 0x40;
3096  if (v11->uFlags & 0x20000) v30 |= 0x80;
3097  if ((256 << v9) & v11->uFlags) v30 |= 4;
3098 
3099  int view_x = 0;
3100  int view_y = 0;
3101  int view_z = 0;
3102  bool visible =
3103  pIndoorCameraD3D->ViewClip(pLevelDecorations[uDecorationID].vPosition.x,
3104  pLevelDecorations[uDecorationID].vPosition.y,
3105  pLevelDecorations[uDecorationID].vPosition.z,
3106  &view_x, &view_y, &view_z);
3107 
3108  if (visible) {
3109  if (abs(view_x) >= abs(view_y)) {
3110  int projected_x = 0;
3111  int projected_y = 0;
3112  pIndoorCameraD3D->Project(view_x, view_y, view_z, &projected_x,
3113  &projected_y);
3114 
3115  assert(uNumBillboardsToDraw < 500);
3118 
3120  v11->hw_sprites[v9];
3121 
3122  if (v11->hw_sprites[v9]->texture->GetHeight() == 0 || v11->hw_sprites[v9]->texture->GetWidth() == 0)
3123  __debugbreak();
3124 
3126  v11->uPaletteIndex;
3128  uSectorID;
3129 
3138  pLevelDecorations[uDecorationID].vPosition.x;
3140  pLevelDecorations[uDecorationID].vPosition.y;
3142  pLevelDecorations[uDecorationID].vPosition.z;
3144  projected_x;
3146  projected_y;
3148  view_x;
3150  PID(OBJECT_Decoration, uDecorationID);
3151 
3154  }
3155  }
3156 }
3157 
3158 //----- (0043F953) --------------------------------------------------------
3160  pBspRenderer->num_faces = 0;
3161 
3171  pBspRenderer->nodes[0].uFaceID = -1;
3173  pBspRenderer->num_nodes = 1;
3175  }
3176 
3178 }
3179 
3180 //----- (0043F9E1) --------------------------------------------------------
3182  __int16 z, int w) {
3183  _viewport_space_y = y;
3184  _viewport_space_w = w;
3185 
3186  for (uint i = 0; i < window->GetHeight(); ++i) {
3187  if (i < y || i > w) {
3188  viewport_left_side[i] = window->GetWidth();
3189  viewport_right_side[i] = -1;
3190  } else {
3191  viewport_left_side[i] = x;
3192  viewport_right_side[i] = z;
3193  }
3194  }
3195 }
3196 //----- (0048653D) --------------------------------------------------------
3197 
3198 
3199 bool sub_407A1C(int x, int y, int z, Vec3_int_ v) {
3200  unsigned int v4; // esi@1
3201  int dist_y; // edi@2
3202  int dist_z; // ebx@2
3203  int dist_x; // esi@2
3204  int v9; // ecx@2
3205  int v10; // eax@2
3206  int v12; // eax@4
3207  int v17; // ST34_4@25
3208  int v18; // ST38_4@25
3209  int v19; // eax@25
3210  char v20; // zf@25
3211  int v21; // ebx@25
3212  int v23; // edi@26
3213  int v24; // ST34_4@30
3214  int v32; // ecx@37
3215  int v33; // eax@37
3216  int v35; // eax@39
3217  int v40; // ebx@60
3218  int v42; // edi@61
3219  int v49; // ecx@73
3220  int v50; // eax@73
3221  int v51; // edx@75
3222  int v52; // ecx@75
3223  int v53; // eax@75
3224  int v59; // eax@90
3225  BLVFace *face; // esi@91
3226  int v63; // ST34_4@98
3227  int v64; // ST30_4@98
3228  int v65; // eax@98
3229  int v66; // ebx@98
3230  int v68; // edi@99
3231  int v69; // ST2C_4@103
3232  int v77; // ecx@111
3233  int v78; // eax@111
3234  int v79; // edx@113
3235  int v80; // ecx@113
3236  int v81; // eax@113
3237  int v87; // ecx@128
3238  int v91; // ebx@136
3239  int v93; // edi@137
3240  Vec3_int_ v97; // [sp-18h] [bp-94h]@1
3241  int v107; // [sp+10h] [bp-6Ch]@98
3242  int v108; // [sp+10h] [bp-6Ch]@104
3243  int v109; // [sp+18h] [bp-64h]@25
3244  int v110; // [sp+18h] [bp-64h]@31
3245  int v113; // [sp+20h] [bp-5Ch]@1
3246  int v114; // [sp+24h] [bp-58h]@1
3247  int v119; // [sp+34h] [bp-48h]@75
3248  int v120; // [sp+34h] [bp-48h]@113
3249  int v121; // [sp+38h] [bp-44h]@4
3250  int v122; // [sp+38h] [bp-44h]@39
3251  int v123; // [sp+38h] [bp-44h]@76
3252  int v124; // [sp+38h] [bp-44h]@114
3253  int v125; // [sp+3Ch] [bp-40h]@4
3254  int v126; // [sp+3Ch] [bp-40h]@39
3255  int v127; // [sp+3Ch] [bp-40h]@77
3256  int v128; // [sp+3Ch] [bp-40h]@115
3257  int v129; // [sp+40h] [bp-3Ch]@11
3258  int v130; // [sp+40h] [bp-3Ch]@46
3259  int v131; // [sp+40h] [bp-3Ch]@78
3260  int v132; // [sp+40h] [bp-3Ch]@116
3261  int v133; // [sp+44h] [bp-38h]@10
3262  int v134; // [sp+44h] [bp-38h]@45
3263  int v135; // [sp+44h] [bp-38h]@81
3264  int v136; // [sp+44h] [bp-38h]@119
3265  int v137; // [sp+48h] [bp-34h]@7
3266  int v138; // [sp+48h] [bp-34h]@42
3267  int v139; // [sp+48h] [bp-34h]@82
3268  int v140; // [sp+48h] [bp-34h]@120
3269  int v141; // [sp+4Ch] [bp-30h]@6
3270  int v142; // [sp+4Ch] [bp-30h]@41
3271  int v143; // [sp+4Ch] [bp-30h]@75
3272  int v144; // [sp+4Ch] [bp-30h]@113
3273  int v145; // [sp+50h] [bp-2Ch]@5
3274  int v146; // [sp+50h] [bp-2Ch]@40
3275  int v149; // [sp+54h] [bp-28h]@4
3276  int v150; // [sp+54h] [bp-28h]@39
3277  int sDepthb; // [sp+58h] [bp-24h]@90
3278  int a5b; // [sp+5Ch] [bp-20h]@83
3279  int a5c; // [sp+5Ch] [bp-20h]@121
3280  int v162; // [sp+60h] [bp-1Ch]@128
3281  int outz; // [sp+64h] [bp-18h]@2
3282  int outx; // [sp+68h] [bp-14h]@2
3283  int outy; // [sp+6Ch] [bp-10h]@2
3284  int sZ; // [sp+70h] [bp-Ch]@2
3285  int sX; // [sp+74h] [bp-8h]@2
3286  int sY; // [sp+78h] [bp-4h]@2
3287  // 8bytes unused
3288  int ya; // [sp+84h] [bp+8h]@60
3289  int yb; // [sp+84h] [bp+8h]@136
3290  int ve; // [sp+88h] [bp+Ch]@60
3291  int va; // [sp+88h] [bp+Ch]@60
3292  int vb; // [sp+88h] [bp+Ch]@66
3293  int vf; // [sp+88h] [bp+Ch]@136
3294  int vc; // [sp+88h] [bp+Ch]@136
3295  int vd; // [sp+88h] [bp+Ch]@142
3296  int v_4; // [sp+8Ch] [bp+10h]@60
3297  int v_4a; // [sp+8Ch] [bp+10h]@65
3298  int v_4b; // [sp+8Ch] [bp+10h]@136
3299  int v_4c; // [sp+8Ch] [bp+10h]@141
3300 
3301  // __debugbreak();срабатывает при стрельбе огненным шаром
3302  // triggered by fireball
3303 
3304  v4 = stru_5C6E00->Atan2(v.x - x, v.y - y);
3305 
3306  v113 = 0;
3307  v114 = 0;
3308 
3309  v97.z = z;
3310  v97.x = x;
3311  v97.y = y;
3312 
3314  Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &sX,
3315  &sY, &sZ);
3316  Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v, &outx,
3317  &outy, &outz);
3318  dist_y = outy - sY;
3319  dist_z = outz - sZ;
3320  dist_x = outx - sX;
3321  v49 = integer_sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z);
3322  v50 = 65536;
3323  if (v49) v50 = 65536 / v49;
3324  v51 = outx;
3325  v143 = dist_x * v50;
3326  v52 = dist_y * v50;
3327  v53 = dist_z * v50;
3328 
3329  v123 = std::max(outx, sX);
3330  v119 = std::min(outx, sX);
3331 
3332  v131 = std::max(outy, sY);
3333  v127 = std::min(outy, sY);
3334 
3335  v139 = std::max(outz, sZ);
3336  v135 = std::min(outz, sZ);
3337 
3338  for (a5b = 0; a5b < 2; a5b++) {
3339  if (a5b)
3340  v59 = pIndoor->GetSector(sX, sY, sZ);
3341  else
3342  v59 = pIndoor->GetSector(outx, outy, outz);
3343  // v60 = pIndoor->pSectors;
3344  // v61 = 116 * v59;
3345  // i = 116 * v59;
3346  // for (sDepthb = 0; *(__int16 *)((char
3347  // *)&pIndoor->pSectors->uNumWalls + v61)
3348  // + 2 * *(__int16 *)((char *)&pIndoor->pSectors->uNumFloors + v61);
3349  // ++sDepthb)
3350  for (sDepthb = 0; sDepthb < pIndoor->pSectors[v59].uNumFaces;
3351  ++sDepthb) {
3352  face =
3353  &pIndoor
3354  ->pFaces[pIndoor->pSectors[v59]
3355  .pFaceIDs[sDepthb]]; // face =
3356  // &pIndoor->pFaces[*(__int16
3357  // *)((char
3358  // *)&pIndoor->pSectors->pWalls
3359  // + v61)[sDepthb]]
3360  v63 = fixpoint_mul(v143, face->pFacePlane_old.vNormal.x);
3361  v64 = fixpoint_mul(v53, face->pFacePlane_old.vNormal.z);
3362  v65 = fixpoint_mul(v52, face->pFacePlane_old.vNormal.y);
3363  v20 = v63 + v64 + v65 == 0;
3364  v66 = v63 + v64 + v65;
3365  v107 = v63 + v64 + v65;
3366  if (face->Portal() || v119 > face->pBounding.x2 ||
3367  v123 < face->pBounding.x1 || v127 > face->pBounding.y2 ||
3368  v131 < face->pBounding.y1 || v135 > face->pBounding.z2 ||
3369  v139 < face->pBounding.z1 || v20)
3370  continue;
3371  v68 = -(face->pFacePlane_old.dist +
3372  sX * face->pFacePlane_old.vNormal.x +
3373  sY * face->pFacePlane_old.vNormal.y +
3374  sZ * face->pFacePlane_old.vNormal.z);
3375  if (v66 <= 0) {
3376  if (face->pFacePlane_old.dist +
3377  sX * face->pFacePlane_old.vNormal.x +
3378  sY * face->pFacePlane_old.vNormal.y +
3379  sZ * face->pFacePlane_old.vNormal.z <
3380  0)
3381  continue;
3382  } else {
3383  if (face->pFacePlane_old.dist +
3384  sX * face->pFacePlane_old.vNormal.x +
3385  sY * face->pFacePlane_old.vNormal.y +
3386  sZ * face->pFacePlane_old.vNormal.z >
3387  0)
3388  continue;
3389  }
3390  v69 = abs(-(face->pFacePlane_old.dist +
3391  sX * face->pFacePlane_old.vNormal.x +
3392  sY * face->pFacePlane_old.vNormal.y +
3393  sZ * face->pFacePlane_old.vNormal.z)) >>
3394  14;
3395  if (v69 <= abs(v66)) {
3396  // LODWORD(v70) = v68 << 16;
3397  // HIDWORD(v70) = v68 >> 16;
3398  // v71 = v70 / v107;
3399  // v108 = v70 / v107;
3400  v108 = fixpoint_div(v68, v107);
3401  if (v108 >= 0) {
3402  if (sub_4075DB(
3403  sX + ((signed int)(fixpoint_mul(v108, v143) +
3404  0x8000) >>
3405  16),
3406  sY + ((signed int)(fixpoint_mul(v108, v52) +
3407  0x8000) >>
3408  16),
3409  sZ + ((signed int)(fixpoint_mul(v108, v53) +
3410  0x8000) >>
3411  16),
3412  face)) {
3413  v114 = 1;
3414  break;
3415  }
3416  }
3417  }
3418  }
3419  }
3420 
3421  Vec3_int_::Rotate(32, v4 - stru_5C6E00->uIntegerHalfPi, 0, v97, &sX,
3422  &sY, &sZ);
3423  Vec3_int_::Rotate(32, v4 - stru_5C6E00->uIntegerHalfPi, 0, v, &outx,
3424  &outy, &outz);
3425  dist_y = outy - sY;
3426  dist_z = outz - sZ;
3427  dist_x = outx - sX;
3428  v77 = integer_sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z);
3429  v78 = 65536;
3430  if (v77) v78 = 65536 / v77;
3431  v79 = outx;
3432  v144 = dist_x * v78;
3433  v80 = dist_y * v78;
3434  v81 = dist_z * v78;
3435 
3436  v120 = std::max(outx, sX);
3437  v124 = std::min(outx, sX);
3438 
3439  v132 = std::max(outy, sY);
3440  v128 = std::min(outy, sY);
3441 
3442  v140 = std::max(outz, sZ);
3443  v136 = std::min(outz, sZ);
3444 
3445  for (a5c = 0; a5c < 2; a5c++) {
3446  if (v113) return !v114 || !v113;
3447  if (a5c) {
3448  v87 = pIndoor->GetSector(sX, sY, sZ);
3449  } else {
3450  v87 = pIndoor->GetSector(outx, outy, outz);
3451  }
3452  for (v162 = 0; v162 < pIndoor->pSectors[v87].uNumFaces; v162++) {
3453  face = &pIndoor->pFaces[pIndoor->pSectors[v87].pFaceIDs[v162]];
3454  yb = fixpoint_mul(v144, face->pFacePlane_old.vNormal.x);
3455  v_4b = fixpoint_mul(v80, face->pFacePlane_old.vNormal.y);
3456  vf = fixpoint_mul(v81, face->pFacePlane_old.vNormal.z);
3457  v20 = yb + vf + v_4b == 0;
3458  v91 = yb + vf + v_4b;
3459  vc = yb + vf + v_4b;
3460  if (face->Portal() || v120 > face->pBounding.x2 ||
3461  v124 < face->pBounding.x1 || v128 > face->pBounding.y2 ||
3462  v132 < face->pBounding.y1 || v136 > face->pBounding.z2 ||
3463  v140 < face->pBounding.z1 || v20)
3464  continue;
3465  v93 = -(face->pFacePlane_old.dist +
3466  sX * face->pFacePlane_old.vNormal.x +
3467  sY * face->pFacePlane_old.vNormal.y +
3468  sZ * face->pFacePlane_old.vNormal.z);
3469  if (v91 <= 0) {
3470  if (face->pFacePlane_old.dist +
3471  sX * face->pFacePlane_old.vNormal.x +
3472  sY * face->pFacePlane_old.vNormal.y +
3473  sZ * face->pFacePlane_old.vNormal.z <
3474  0)
3475  continue;
3476  } else {
3477  if (face->pFacePlane_old.dist +
3478  sX * face->pFacePlane_old.vNormal.x +
3479  sY * face->pFacePlane_old.vNormal.y +
3480  sZ * face->pFacePlane_old.vNormal.z >
3481  0)
3482  continue;
3483  }
3484  v_4c = abs(-(face->pFacePlane_old.dist +
3485  sX * face->pFacePlane_old.vNormal.x +
3486  sY * face->pFacePlane_old.vNormal.y +
3487  sZ * face->pFacePlane_old.vNormal.z)) >>
3488  14;
3489  if (v_4c <= abs(v91)) {
3490  vd = fixpoint_div(v93, vc);
3491  if (vd >= 0) {
3492  if (sub_4075DB(
3493  sX + ((signed int)(fixpoint_mul(vd, v144) +
3494  0x8000) >>
3495  16),
3496  sY + ((signed int)(fixpoint_mul(vd, v80) +
3497  0x8000) >>
3498  16),
3499  sZ + ((signed int)(fixpoint_mul(vd, v81) +
3500  0x8000) >>
3501  16),
3502  face)) {
3503  v113 = 1;
3504  break;
3505  }
3506  }
3507  }
3508  }
3509  }
3510  } else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) {
3511  Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &sX,
3512  &sY, &sZ);
3513  Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v, &outx,
3514  &outy, &outz);
3515  dist_y = outy - sY;
3516  dist_z = outz - sZ;
3517  dist_x = outx - sX;
3518  v9 = integer_sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z);
3519  v10 = 65536;
3520  if (v9) v10 = 65536 / v9;
3521  v125 = dist_x * v10;
3522  v12 = dist_z * v10;
3523  v121 = dist_y * v10;
3524 
3525  v145 = std::max(outx, sX);
3526  v149 = std::min(outx, sX);
3527 
3528  v137 = std::max(outy, sY);
3529  v141 = std::min(outy, sY);
3530 
3531  v129 = std::max(outz, sZ);
3532  v133 = std::min(outz, sZ);
3533 
3534  for (BSPModel &model : pOutdoor->pBModels) {
3535  if (sub_4088E9(sX, sY, outx, outy, model.vPosition.x,
3536  model.vPosition.y) <= model.sBoundingRadius + 128) {
3537  for (ODMFace &face : model.pFaces) {
3538  v17 = fixpoint_mul(v125, face.pFacePlane.vNormal.x);
3539  v18 = fixpoint_mul(v121, face.pFacePlane.vNormal.y);
3540  v19 = fixpoint_mul(v12, face.pFacePlane.vNormal.z);
3541  v20 = v17 + v18 + v19 == 0;
3542  v21 = v17 + v18 + v19;
3543  v109 = v17 + v18 + v19;
3544  if (v149 > face.pBoundingBox.x2 ||
3545  v145 < face.pBoundingBox.x1 ||
3546  v141 > face.pBoundingBox.y2 ||
3547  v137 < face.pBoundingBox.y1 ||
3548  v133 > face.pBoundingBox.z2 ||
3549  v129 < face.pBoundingBox.z1 || v20)
3550  continue;
3551  v23 = -(face.pFacePlane.dist +
3552  sX * face.pFacePlane.vNormal.x +
3553  sY * face.pFacePlane.vNormal.y +
3554  sZ * face.pFacePlane.vNormal.z);
3555  if (v21 <= 0) {
3556  if (face.pFacePlane.dist +
3557  sX * face.pFacePlane.vNormal.x +
3558  sY * face.pFacePlane.vNormal.y +
3559  sZ * face.pFacePlane.vNormal.z <
3560  0)
3561  continue;
3562  } else {
3563  if (face.pFacePlane.dist +
3564  sX * face.pFacePlane.vNormal.x +
3565  sY * face.pFacePlane.vNormal.y +
3566  sZ * face.pFacePlane.vNormal.z >
3567  0)
3568  continue;
3569  }
3570  v24 = abs(-(face.pFacePlane.dist +
3571  sX * face.pFacePlane.vNormal.x +
3572  sY * face.pFacePlane.vNormal.y +
3573  sZ * face.pFacePlane.vNormal.z)) >>
3574  14;
3575  if (v24 <= abs(v21)) {
3576  v110 = fixpoint_div(v23, v109);
3577  if (v110 >= 0) {
3578  if (sub_4077F1(
3579  sX +
3580  ((signed int)(fixpoint_mul(v110, v125) +
3581  0x8000) >>
3582  16),
3583  sY +
3584  ((signed int)(fixpoint_mul(v110, v121) +
3585  0x8000) >>
3586  16),
3587  sZ + ((signed int)(fixpoint_mul(v110, v12) +
3588  0x8000) >>
3589  16),
3590  &face, &model.pVertices)) {
3591  v114 = 1;
3592  break;
3593  }
3594  }
3595  }
3596  }
3597  }
3598  }
3599 
3600  Vec3_int_::Rotate(32, v4 - stru_5C6E00->uIntegerHalfPi, 0, v97, &sX,
3601  &sY, &sZ);
3602  Vec3_int_::Rotate(32, v4 - stru_5C6E00->uIntegerHalfPi, 0, v, &outx,
3603  &outy, &outz);
3604  dist_y = outy - sY;
3605  dist_z = outz - sZ;
3606  dist_x = outx - sX;
3607  v32 = integer_sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z);
3608  v33 = 65536;
3609  if (v32) v33 = 65536 / v32;
3610  v126 = dist_x * v33;
3611  v35 = dist_z * v33;
3612  v122 = dist_y * v33;
3613 
3614  v146 = std::max(outx, sX);
3615  v150 = std::min(outx, sX);
3616 
3617  v138 = std::max(outy, sY);
3618  v142 = std::min(outy, sY);
3619 
3620  v130 = std::max(outz, sZ);
3621  v134 = std::min(outz, sZ);
3622 
3623  for (BSPModel &model : pOutdoor->pBModels) {
3624  if (sub_4088E9(sX, sY, outx, outy, model.vPosition.x,
3625  model.vPosition.y) <= model.sBoundingRadius + 128) {
3626  for (ODMFace &face : model.pFaces) {
3627  ya = fixpoint_mul(v126, face.pFacePlane.vNormal.x);
3628  ve = fixpoint_mul(v122, face.pFacePlane.vNormal.y);
3629  v_4 = fixpoint_mul(v35, face.pFacePlane.vNormal.z);
3630  v20 = ya + ve + v_4 == 0;
3631  v40 = ya + ve + v_4;
3632  va = ya + ve + v_4;
3633  if (v150 > face.pBoundingBox.x2 ||
3634  v146 < face.pBoundingBox.x1 ||
3635  v142 > face.pBoundingBox.y2 ||
3636  v138 < face.pBoundingBox.y1 ||
3637  v134 > face.pBoundingBox.z2 ||
3638  v130 < face.pBoundingBox.z1 || v20)
3639  continue;
3640  v42 = -(face.pFacePlane.dist +
3641  sX * face.pFacePlane.vNormal.x +
3642  sY * face.pFacePlane.vNormal.y +
3643  sZ * face.pFacePlane.vNormal.z);
3644  if (v40 <= 0) {
3645  if (face.pFacePlane.dist +
3646  sX * face.pFacePlane.vNormal.x +
3647  sY * face.pFacePlane.vNormal.y +
3648  sZ * face.pFacePlane.vNormal.z <
3649  0)
3650  continue;
3651  } else {
3652  if (face.pFacePlane.dist +
3653  sX * face.pFacePlane.vNormal.x +
3654  sY * face.pFacePlane.vNormal.y +
3655  sZ * face.pFacePlane.vNormal.z >
3656  0)
3657  continue;
3658  }
3659  v_4a = abs(-(face.pFacePlane.dist +
3660  sX * face.pFacePlane.vNormal.x +
3661  sY * face.pFacePlane.vNormal.y +
3662  sZ * face.pFacePlane.vNormal.z)) >>
3663  14;
3664  if (v_4a <= abs(v40)) {
3665  // LODWORD(v43) = v42 << 16;
3666  // HIDWORD(v43) = v42 >> 16;
3667  // vb = v43 / va;
3668  vb = fixpoint_div(v42, va);
3669  if (vb >= 0) {
3670  if (sub_4077F1(sX + ((int)(fixpoint_mul(vb, v126) +
3671  0x8000) >>
3672  16),
3673  sY + ((int)(fixpoint_mul(vb, v122) +
3674  0x8000) >>
3675  16),
3676  sZ + ((int)(fixpoint_mul(vb, v35) +
3677  0x8000) >>
3678  16),
3679  &face, &model.pVertices)) {
3680  v113 = 1;
3681  break;
3682  }
3683  }
3684  }
3685  }
3686  }
3687  }
3688  }
3689  return !v114 || !v113;
3690 }
3691 
3693  // int v6; // ebx@3
3694 
3696  for (uint i = 0; i < num_nodes; ++i) {
3697  // if (!uNumVisibleNotEmptySectors)
3698  //{
3699  // pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++]
3700  // = nodes[i].uSectorID; continue;
3701  //}
3702  // v6 = 0;
3703  // while (pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v6] !=
3704  // nodes[i].uSectorID )
3705  for (uint j = 0; j < uNumVisibleNotEmptySectors; j++) {
3706  // ++v6;
3708  nodes[i].uSectorID)
3709  break;
3710  }
3713  }
3714 }
3715 
3716 char DoInteractionWithTopmostZObject(int a1, int a2) {
3717  uint32_t v17 = PID_ID(a1);
3718  switch (PID_TYPE(a1)) {
3719  case OBJECT_Item: { // take the item
3720  if (pSpriteObjects[v17].IsUnpickable() || v17 >= 1000 || !pSpriteObjects[v17].uObjectDescID) {
3721  return 1;
3722  }
3723 
3724  extern void ItemInteraction(unsigned int item_id);
3725  ItemInteraction(v17);
3726  break;
3727  }
3728 
3729  case OBJECT_Actor:
3730  if (pActors[v17].uAIState == Dying || pActors[v17].uAIState == Summoned)
3731  return 1;
3732  if (pActors[v17].uAIState == Dead) {
3733  pActors[v17].LootActor();
3734  } else {
3735  extern bool ActorInteraction(unsigned int id);
3736  ActorInteraction(v17);
3737  }
3738  break;
3739 
3740  case OBJECT_Decoration:
3741  extern void DecorationInteraction(unsigned int id, unsigned int pid);
3742  DecorationInteraction(v17, a1);
3743  break;
3744 
3745  default:
3746  logger->Warning(L"Warning: Invalid ID reached!");
3747  return 1;
3748 
3749  case OBJECT_BModel:
3751  int bmodel_id = a1 >> 9;
3752  int face_id = v17 & 0x3F;
3753  if (bmodel_id >= pOutdoor->pBModels.size()) {
3754  return 1;
3755  }
3756  if (pOutdoor->pBModels[bmodel_id].pFaces[face_id].uAttributes & FACE_HAS_EVENT ||
3757  pOutdoor->pBModels[bmodel_id].pFaces[face_id].sCogTriggeredID == 0)
3758  return 1;
3759  EventProcessor((int16_t)pOutdoor->pBModels[bmodel_id].pFaces[face_id].sCogTriggeredID,
3760  a1, 1);
3761  } else {
3762  if (!(pIndoor->pFaces[v17].uAttributes & FACE_CLICKABLE)) {
3764  return 1;
3765  }
3766  if (pIndoor->pFaces[v17].uAttributes & FACE_HAS_EVENT ||
3768  return 1;
3771  a1, 1);
3772  }
3773  return 0;
3774  break;
3775  }
3776  return 0;
3777 }
3778 //----- (0046BDF1) --------------------------------------------------------
3780  UpdateObjects();
3782  UpdateActors_BLV();
3783  BLV_UpdateDoors();
3785 }
3786 //----- (00424829) --------------------------------------------------------
3787 // Finds out if current portal can be seen through the previous portal
3788 bool PortalFrustrum(int pNumVertices,
3789  BspRenderer_PortalViewportData *far_portal,
3790  BspRenderer_PortalViewportData *near_portal, int uFaceID) {
3791  int min_y; // esi@5
3792  int max_y; // edx@5
3793  int current_ID; // eax@12
3794  int v13; // eax@22
3795  int v15; // ecx@29
3796  int v18; // eax@39
3797  int v19; // eax@44
3798  int v20; // ecx@44
3799  int v22; // edi@46
3800  int v24; // edx@48
3801  int v26; // eax@55
3802  int v29; // edx@57
3803  int v31; // eax@64
3804  __int16 v36; // dx@67
3805  __int16 v38; // dx@67
3806  int v46; // edx@87
3807  int v49; // esi@93
3808  int v53 = 0; // [sp+Ch] [bp-34h]@44
3809  int v54 = 0; // [sp+10h] [bp-30h]@0
3810  int min_y_ID2; // [sp+14h] [bp-2Ch]@12
3811  int v59; // [sp+14h] [bp-2Ch]@87
3812  int v61; // [sp+1Ch] [bp-24h]@29
3813  int v62; // [sp+20h] [bp-20h]@0
3814  signed int direction1; // [sp+24h] [bp-1Ch]@3
3815  signed int direction2; // [sp+28h] [bp-18h]@3
3816  int min_y_ID; // [sp+2Ch] [bp-14h]@5
3817  int v69; // [sp+34h] [bp-Ch]@29
3818  int v70; // [sp+34h] [bp-Ch]@46
3819 
3820  if (pNumVertices <= 1) return false;
3821  min_y = PortalFace._screen_space_y[0];
3822  min_y_ID = 0;
3823  max_y = PortalFace._screen_space_y[0];
3824  // face direction(направление фейса)
3825  if (!PortalFace.direction) {
3826  direction1 = 1;
3827  direction2 = -1;
3828  } else {
3829  direction1 = -1;
3830  direction2 = 1;
3831  }
3832 
3833  // get min and max y for portal(дать минимальное и максимальное значение y
3834  // для портала)
3835  for (uint i = 1; i < pNumVertices; ++i) {
3836  if (PortalFace._screen_space_y[i] < min_y) {
3837  min_y_ID = i;
3838  min_y = PortalFace._screen_space_y[i];
3839  } else if (PortalFace._screen_space_y[i] > max_y) {
3840  max_y = PortalFace._screen_space_y[i];
3841  }
3842  }
3843  if (max_y == min_y) return false;
3844 
3845  //*****************************************************************************************************************************
3846  far_portal->_viewport_space_y = min_y;
3847  far_portal->_viewport_space_w = max_y;
3848  current_ID = min_y_ID;
3849  min_y_ID2 = min_y_ID;
3850 
3851  for (uint i = 0; i < pNumVertices; ++i) {
3852  current_ID += direction2;
3853  if (current_ID < pNumVertices) {
3854  if (current_ID < 0) current_ID += pNumVertices;
3855  } else {
3856  current_ID -= pNumVertices;
3857  }
3858  if (PortalFace._screen_space_y[current_ID] <=
3859  PortalFace._screen_space_y[min_y_ID]) { // определение минимальной у
3860  min_y_ID2 = current_ID;
3861  min_y_ID = current_ID;
3862  }
3863  if (PortalFace._screen_space_y[current_ID] == max_y) break;
3864  }
3865 
3866  v13 = min_y_ID2 + direction2;
3867  if (v13 < pNumVertices) {
3868  if (v13 < 0) v13 += pNumVertices;
3869  } else {
3870  v13 -= pNumVertices;
3871  }
3872  if (PortalFace._screen_space_y[v13] !=
3873  PortalFace._screen_space_y[min_y_ID2]) {
3874  v62 = PortalFace._screen_space_x[min_y_ID2] << 16;
3875  v54 = ((PortalFace._screen_space_x[v13] -
3876  PortalFace._screen_space_x[min_y_ID2])
3877  << 16) /
3878  (PortalFace._screen_space_y[v13] -
3879  PortalFace._screen_space_y[min_y_ID2]);
3880  far_portal->viewport_left_side[min_y] =
3881  (short)PortalFace._screen_space_x[min_y_ID2];
3882  }
3883  //****************************************************************************************************************************************
3884  //
3885  v15 = min_y_ID;
3886  v61 = min_y_ID;
3887  for (v69 = 0; v69 < pNumVertices; ++v69) {
3888  v15 += direction1;
3889  if (v15 < pNumVertices) {
3890  if (v15 < 0) v15 += pNumVertices;
3891  } else {
3892  v15 -= pNumVertices;
3893  }
3894  if (PortalFace._screen_space_y[v15] <=
3895  PortalFace._screen_space_y[min_y_ID]) {
3896  v61 = v15;
3897  min_y_ID = v15;
3898  }
3899  if (PortalFace._screen_space_y[v15] == max_y) break;
3900  }
3901  v18 = direction1 + v61;
3902  if (v18 < pNumVertices) {
3903  if (v18 < 0) v18 += pNumVertices;
3904  } else {
3905  v18 -= pNumVertices;
3906  }
3907  v19 = v18;
3908  v20 = v61;
3910  v61 = PortalFace._screen_space_x[v20] << 16;
3911  v53 =
3913  << 16) /
3915  far_portal->viewport_right_side[max_y] =
3916  (short)PortalFace._screen_space_x[v20];
3917  }
3918  //****************************************************************************************************************************************
3919  v22 = min_y;
3920  if (min_y <= max_y) {
3921  for (v70 = min_y; v70 <= max_y; ++v70) {
3922  v24 = v13;
3923  if (v22 >= PortalFace._screen_space_y[v13] && v22 != max_y) {
3924  v13 = direction2 + v13;
3925  if (v13 < pNumVertices) {
3926  if (v13 < 0) v13 += pNumVertices;
3927  } else {
3928  v13 -= pNumVertices;
3929  }
3930  v26 = v13;
3931  if (PortalFace._screen_space_y[v26] -
3933  0) {
3934  v54 = ((PortalFace._screen_space_x[v26] -
3936  << 16) /
3937  (PortalFace._screen_space_y[v26] -
3939  v62 = PortalFace._screen_space_x[v24] << 16;
3940  }
3941  }
3942  v29 = v18;
3943  if (v70 >= PortalFace._screen_space_y[v18] && v70 != max_y) {
3944  v18 += direction1;
3945  if (v18 < pNumVertices) {
3946  if (v18 < 0) v18 += pNumVertices;
3947  } else {
3948  v18 -= pNumVertices;
3949  }
3950  v31 = v18;
3951  if (PortalFace._screen_space_y[v31] -
3953  0) {
3954  v53 = ((PortalFace._screen_space_x[v31] -
3956  << 16) /
3957  (PortalFace._screen_space_y[v31] -
3959  v61 = PortalFace._screen_space_x[v29] << 16;
3960  }
3961  }
3962  far_portal->viewport_left_side[v70] = HEXRAYS_HIWORD(v62);
3963  far_portal->viewport_right_side[v70] = HEXRAYS_HIWORD(v61);
3964  if (far_portal->viewport_left_side[v70] >
3965  far_portal->viewport_right_side[v70]) {
3966  v36 = far_portal->viewport_left_side[v70] ^
3967  far_portal->viewport_right_side[v70];
3968  // v37 = far_portal->viewport_right_side[v70];
3969  far_portal->viewport_left_side[v70] = v36;
3970  v38 = far_portal->viewport_right_side[v70] ^ v36;
3971  far_portal->viewport_left_side[v70] ^= v38;
3972  far_portal->viewport_right_side[v70] = v38;
3973  }
3974  v62 += v54;
3975  v22 = v70 + 1;
3976  v61 += v53;
3977  }
3978  }
3979  //*****************************************************************************************************************************
3980  // check portals coordinates and determine max, min(проверка координат
3981  // порталов и определение макс, мин-ой у)
3982  if (max_y < near_portal->_viewport_space_y) return false;
3983  if (min_y > near_portal->_viewport_space_w) return false;
3984  if (min_y < near_portal->_viewport_space_y)
3985  min_y = near_portal->_viewport_space_y;
3986  if (max_y > near_portal->_viewport_space_w)
3987  max_y = near_portal->_viewport_space_w;
3988  if (min_y <= max_y) {
3989  for (min_y; min_y <= max_y; ++min_y) {
3990  if (far_portal->viewport_right_side[min_y] >=
3991  near_portal->viewport_left_side[min_y] &&
3992  far_portal->viewport_left_side[min_y] <=
3993  near_portal->viewport_right_side[min_y])
3994  break;
3995  }
3996  }
3997  if (max_y < min_y) return false;
3998  for (max_y; max_y >= min_y; --max_y) {
3999  if (far_portal->viewport_right_side[max_y] >=
4000  near_portal->viewport_left_side[max_y] &&
4001  far_portal->viewport_left_side[max_y] <=
4002  near_portal->viewport_right_side[max_y])
4003  break;
4004  }
4005  if (min_y >= max_y) return false;
4006  //*************************************************************************************************************************************
4007  v59 = min_y;
4008  for (v46 = max_y - min_y + 1; v46; --v46) {
4009  if (far_portal->viewport_left_side[v59] <
4010  near_portal->viewport_left_side[v59])
4011  far_portal->viewport_left_side[v59] =
4012  near_portal->viewport_left_side[v59];
4013  if (far_portal->viewport_right_side[v59] >
4014  near_portal->viewport_right_side[v59])
4015  far_portal->viewport_right_side[v59] =
4016  near_portal->viewport_right_side[v59];
4017  ++v59;
4018  }
4019  far_portal->_viewport_space_y = min_y;
4020  far_portal->_viewport_space_w = max_y;
4021  far_portal->_viewport_space_x = far_portal->viewport_left_side[min_y];
4022  far_portal->_viewport_space_z = far_portal->viewport_right_side[min_y];
4023  far_portal->_viewport_x_minID = min_y;
4024  far_portal->_viewport_z_maxID = min_y;
4025  v49 = min_y + 1;
4026  if (v49 <= max_y) {
4027  for (v49; v49 <= max_y; ++v49) {
4028  if (far_portal->viewport_left_side[v49] <
4029  far_portal->_viewport_space_x) {
4030  far_portal->_viewport_space_x =
4031  far_portal->viewport_left_side[v49];
4032  far_portal->_viewport_x_minID = v49;
4033  }
4034  if (far_portal->viewport_right_side[v49] >
4035  far_portal->_viewport_space_z) {
4036  far_portal->_viewport_space_z =
4037  far_portal->viewport_right_side[v49];
4038  far_portal->_viewport_z_maxID = v49;
4039  }
4040  }
4041  }
4042  return true;
4043 }
4044 
4045 int GetPortalScreenCoord(unsigned int uFaceID) {
4046  BLVFace *pFace; // ebx@1
4047  int pNextVertices; // edx@11
4048  int t; // ST28_4@12
4049  int pScreenX; // eax@22
4050  int pScreenY; // eax@27
4051  int left_num_vertices; // edi@31
4052  int right_num_vertices; // ebx@41
4053  int top_num_vertices; // edi@51
4054  int bottom_num_vertices; // ebx@61
4055  bool current_vertices_flag; // [sp+18h] [bp-10h]@9
4056  int depth_num_vertices; // [sp+1Ch] [bp-Ch]@9
4057  bool next_vertices_flag; // [sp+20h] [bp-8h]@10
4058 
4059  //Доп инфо "Программирование трёхмерных игр для windows" Ламот стр 910
4060 
4061  pFace = &pIndoor->pFaces[uFaceID];
4062  memset(&PortalFace, 0, sizeof(stru367));
4063 
4064  // get direction the face(определение направленности
4065  // фейса)*********************************************************************************
4066  if (pFace->pFacePlane_old.vNormal.x *
4067  (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].x -
4069  pFace->pFacePlane_old.vNormal.y *
4070  (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].y -
4072  pFace->pFacePlane_old.vNormal.z *
4073  (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].z -
4075  0) {
4076  PortalFace.direction = true;
4077  } else {
4078  PortalFace.direction = false;
4079  if (!(pFace->Portal())) return 0;
4080  }
4081  //*****************************************************************************************************************************************
4082  // transform to camera coordinates (генерация/конвертирование в координаты
4083  // пространства камеры)
4084 
4085  if ((signed int)pFace->uNumVertices > 0) {
4086  for (uint i = 0; i < pFace->uNumVertices; ++i) {
4088  pIndoor->pVertices[pFace->pVertexIDs[i]].x,
4089  pIndoor->pVertices[pFace->pVertexIDs[i]].y,
4090  pIndoor->pVertices[pFace->pVertexIDs[i]].z,
4093  (fixed *)&PortalFace._view_transformed_y[i + 3], false); // xyz wrong order?
4094 
4095  /*pIndoorCameraD3D->ViewClip(pIndoor->pVertices[pFace->pVertexIDs[i]].x,
4096  pIndoor->pVertices[pFace->pVertexIDs[i]].y,
4097  pIndoor->pVertices[pFace->pVertexIDs[i]].z,
4098  &PortalFace._view_transformed_z[i + 3],
4099  &PortalFace._view_transformed_x[i + 3],
4100  &PortalFace._view_transformed_y[i + 3], true);*/
4101  }
4102  }
4103 
4104  //*****************************************************************************************************************************************
4105  // check vertices for the nearest plane(проверка вершин есть ли в области за
4106  // ближайшей плоскостью)
4107  if (pFace->uNumVertices <= 0) return 0;
4108  bool bFound = false;
4109  for (uint i = 0; i < pFace->uNumVertices; ++i) {
4110  if (PortalFace._view_transformed_z[i + 3] >=
4111  0x80000) { // 8.0(0x80000) 0x196A9FF >=0x80000
4112  bFound = true;
4113  break;
4114  }
4115  }
4116  if (!bFound) return 0;
4117  //*****************************************************************************************************************************************
4118  // check for near clip plane(проверка по ближней границе)
4119  //
4120  // v0 v1
4121  // ._________________.
4122  // / \
4123  // / \
4124  // v5. . v2
4125  // | |
4126  // | |
4127  // | |
4128  // ---------------------------- 8.0(near_clip)
4129  // | |
4130  // ._______________________.
4131  // v4 v3
4132  depth_num_vertices = 0;
4139  current_vertices_flag =
4140  PortalFace._view_transformed_z[3] >= 0x80000; // 524288
4141  if (pFace->uNumVertices >= 1) {
4142  for (uint i = 1; i <= pFace->uNumVertices; ++i) {
4143  next_vertices_flag = PortalFace._view_transformed_z[i + 3] >=
4144  0x80000; // 524288;// 8.0
4145  if (current_vertices_flag ^
4146  next_vertices_flag) { // current or next vertex is near-clipped /
4147  // или текущая или следующая вершина за
4148  // ближней границей - v5
4149  if (next_vertices_flag) { // next vertex is near-clipped /
4150  // следующая вершина за ближней
4151  // границей
4152  // t = near_clip - v4.z / v5.z - v4.z
4153  t = fixpoint_div(
4154  0x80000 - PortalFace._view_transformed_z[i + 2],
4157  // New_x = (v5.x - v4.x)*t + v4.x
4158  PortalFace._view_transformed_x[depth_num_vertices] =
4160  fixpoint_mul(t,
4163  // New_y = (v5.y - v4.y)*t + v4.y
4164  PortalFace._view_transformed_y[depth_num_vertices] =
4166  fixpoint_mul(t,
4169  // New_z = 8.0(0x80000)
4170  PortalFace._view_transformed_z[depth_num_vertices] =
4171  0x80000; // 524288
4172 
4173  // test new code
4174  auto _t =
4175  (fixed::FromInt(8) -
4179  auto _x =
4181  _t *
4184  auto _y =
4186  _t *
4189  auto _z = fixed::FromInt(8);
4190 
4191  assert(_t._internal == t);
4192  assert(_x._internal ==
4193  PortalFace._view_transformed_x[depth_num_vertices]);
4194  assert(_y._internal ==
4195  PortalFace._view_transformed_y[depth_num_vertices]);
4196  assert(_z._internal ==
4197  PortalFace._view_transformed_z[depth_num_vertices]);
4198  } else { // current vertex is near-clipped / текущая вершина за
4199  // ближней границей
4200  // t = near_clip - v1.z / v0.z - v1.z
4201  t = fixpoint_div(
4202  524288 - PortalFace._view_transformed_z[i + 3],
4205  // New_x = (v0.x - v1.x)*t + v1.x
4206  PortalFace._view_transformed_x[depth_num_vertices] =
4208  fixpoint_mul(t,
4211  // New_y = (v0.x - v1.y)*t + v1.y
4212  PortalFace._view_transformed_y[depth_num_vertices] =
4214  fixpoint_mul(t,
4217  // New_z = 8.0(0x80000)
4218  PortalFace._view_transformed_z[depth_num_vertices] =
4219  0x80000; // 524288
4220 
4221  // test new code
4222  auto _t =
4223  (fixed::FromInt(8) -
4227  auto _x =
4229  _t *
4232  auto _y =
4234  _t *
4237  auto _z = fixed::FromInt(8);
4238 
4239  // test new projection against old
4240  // assert(_t._internal == t);
4241  // assert(_x._internal ==
4242  // PortalFace._view_transformed_x[depth_num_vertices]);
4243  // assert(_y._internal ==
4244  // PortalFace._view_transformed_y[depth_num_vertices]);
4245  // assert(_z._internal ==
4246  // PortalFace._view_transformed_z[depth_num_vertices]);
4247  }
4248  depth_num_vertices++;
4249  }
4250  if (next_vertices_flag) { //если следующая вершина за ближней
4251  //границей
4252  pNextVertices = depth_num_vertices++;
4253  PortalFace._view_transformed_z[pNextVertices] =
4255  PortalFace._view_transformed_x[pNextVertices] =
4257  PortalFace._view_transformed_y[pNextVertices] =
4259  }
4260  current_vertices_flag = next_vertices_flag;
4261  }
4262  }
4263 
4264  //результат: нет моргания на границе портала(когда проходим сквозь портал)
4265  //************************************************************************************************************************************
4266  // convertion in screen coordinates(конвертирование в координаты экрана)
4267  PortalFace._view_transformed_z[depth_num_vertices] =
4269  PortalFace._view_transformed_x[depth_num_vertices] =
4271  PortalFace._view_transformed_y[depth_num_vertices] =
4273  for (uint i = 0; i < depth_num_vertices; ++i) {
4274  if ((abs(PortalFace._view_transformed_x[i]) >> 13) <=
4275  abs(PortalFace._view_transformed_z[i])) {
4278  } else {
4279  if (PortalFace._view_transformed_x[i] >= 0) {
4280  if (PortalFace._view_transformed_z[i] >= 0)
4281  pScreenX = 0x400000; // 64.0
4282  else
4283  pScreenX = 0xFFC00000; // -63.0
4284  } else {
4285  if (PortalFace._view_transformed_z[i] >= 0)
4286  pScreenX = 0xFFC00000; // -63.0
4287  else
4288  pScreenX = 0x400000; // 64.0
4289  }
4290  }
4291 
4292  if ((abs(PortalFace._view_transformed_y[i]) >> 13) <=
4293  abs(PortalFace._view_transformed_z[i])) {
4296  } else {
4297  if (PortalFace._view_transformed_y[i] >= 0) {
4298  if (PortalFace._view_transformed_z[i] >= 0)
4299  pScreenY = 0x400000; // 64.0
4300  else
4301  pScreenY = 0xFFC00000; // -63.0
4302  } else {
4303  if (PortalFace._view_transformed_z[i] >= 0)
4304  pScreenY = 0xFFC00000; // -63.0
4305  else
4306  pScreenY = 0x400000; // 64.0
4307  }
4308  }
4309  PortalFace._screen_space_x[i + 12] =
4311  fixpoint_mul(HEXRAYS_SHIWORD(pBLVRenderParams->bsp_fov_rad),
4312  pScreenX);
4313  PortalFace._screen_space_y[i + 12] =
4315  fixpoint_mul(HEXRAYS_SHIWORD(pBLVRenderParams->bsp_fov_rad),
4316  pScreenY);
4317 
4318  // test new projection against old
4319  auto _x =
4322  .GetInt();
4323  auto _y =
4326  .GetInt();
4327  // assert(PortalFace._screen_space_x[i + 12] == _x);
4328  // assert(PortalFace._screen_space_y[i + 12] == _y);
4329  }
4330  // результат: при повороте камеры, когда граница портала сдвигается к краю
4331  // экрана, портал остается прозрачным(видимым)
4332 
4333  //******************************************************************************************************************************************
4334  // координаты как в Ида-базе игры так и в данном проекте перевёрнутые,т.е.
4335  // портал который в правой части экрана имеет экранные координаты которые для
4336  // левой части экрана. Например, x(оригинал) = 8, у нас х =
4337  // 468(противоположный край экрана), точно также и с у.
4338  // coordinates (original and here) are flipped horizontaly, e.g. portal on
4339  // right side of the screen x(original) = 8 becomes x = 468 (opposite side
4340  // of the screen). the same holds true for y
4341  //
4342  // check for left_clip plane(порверка по левой границе)
4343  left_num_vertices = 0;
4344  PortalFace._screen_space_x[depth_num_vertices + 12] =
4346  PortalFace._screen_space_y[depth_num_vertices + 12] =
4348  current_vertices_flag = PortalFace._screen_space_x[12] >=
4349  (signed int)pBLVRenderParams->uViewportX; // 8.0
4350  if (depth_num_vertices < 1) return 0;
4351  for (uint i = 1; i <= depth_num_vertices; ++i) {
4352  next_vertices_flag = PortalFace._screen_space_x[i + 12] >=
4353  (signed int)pBLVRenderParams->uViewportX;
4354  if (current_vertices_flag ^ next_vertices_flag) {
4355  if (next_vertices_flag) {
4356  // t = left_clip - v0.x / v1.x - v0.x
4358  PortalFace._screen_space_x[i + 11],
4359  PortalFace._screen_space_x[i + 12] -
4360  PortalFace._screen_space_x[i + 11]);
4361  // New_y = (v1.y - v0.y)*t + v0.y
4362  PortalFace._screen_space_y[left_num_vertices + 9] =
4363  PortalFace._screen_space_y[i + 11] +
4365  PortalFace._screen_space_y[i + 11]));
4366  // New_x = left_clip
4367  PortalFace._screen_space_x[left_num_vertices + 9] =
4369 
4375  auto _y =
4377  _t * (fixed::FromInt(PortalFace._screen_space_y[i + 12]) -
4379 
4380  // assert(_t._internal == t);
4381  // assert(_x.GetInt() ==
4382  // PortalFace._screen_space_x[left_num_vertices + 9]);
4383  // assert(_y.GetInt() ==
4384  // PortalFace._screen_space_y[left_num_vertices + 9]);
4385  } else {
4386  // t = left_clip - v1.x / v0.x - v1.x
4388  PortalFace._screen_space_x[i + 12],
4389  PortalFace._screen_space_x[i + 11] -
4390  PortalFace._screen_space_x[i + 12]);
4391  // New_y = (v0.y - v1.y)*t + v1.y
4392  PortalFace._screen_space_y[left_num_vertices + 9] =
4393  PortalFace._screen_space_y[i + 12] +
4395  PortalFace._screen_space_y[i + 12]));
4396  // New_x = left_clip
4397  PortalFace._screen_space_x[left_num_vertices + 9] =
4399 
4405  auto _y =
4407  _t * (fixed::FromInt(PortalFace._screen_space_y[i + 11]) -
4409 
4410  // test new projection against old
4411  // assert(_t._internal == t);
4412  // assert(_x.GetInt() ==
4413  // PortalFace._screen_space_x[left_num_vertices + 9]);
4414  // assert(_y.GetInt() ==
4415  // PortalFace._screen_space_y[left_num_vertices + 9]);
4416  }
4417  left_num_vertices++;
4418  }
4419  if (next_vertices_flag) {
4420  pNextVertices = left_num_vertices++;
4421  PortalFace._screen_space_x[pNextVertices + 9] =
4422  PortalFace._screen_space_x[i + 12];
4423  PortalFace._screen_space_y[pNextVertices + 9] =
4424  PortalFace._screen_space_y[i + 12];
4425  }
4426  current_vertices_flag = next_vertices_flag;
4427  }
4428  //*********************************************************************************************************************************
4429  // for right_clip plane(проверка по правой плоскости)
4430  right_num_vertices = 0;
4431  PortalFace._screen_space_x[left_num_vertices + 9] =
4433  PortalFace._screen_space_y[left_num_vertices + 9] =
4435  current_vertices_flag = PortalFace._screen_space_x[9] <=
4436  (signed int)pBLVRenderParams->uViewportZ; // 468.0
4437  if (left_num_vertices < 1) return 0;
4438  for (uint i = 1; i <= left_num_vertices; ++i) {
4439  next_vertices_flag = PortalFace._screen_space_x[i + 9] <=
4440  (signed int)pBLVRenderParams->uViewportZ;
4441  if (current_vertices_flag ^ next_vertices_flag) {
4442  if (next_vertices_flag) {
4443  // t = right_clip - v1.x / v0.x - v1.x
4445  PortalFace._screen_space_x[i + 8],
4446  PortalFace._screen_space_x[i + 9] -
4447  PortalFace._screen_space_x[i + 8]);
4448  // New_y = (v0.y - v1.y)*t + v1.y
4449  PortalFace._screen_space_y[right_num_vertices + 6] =
4451  PortalFace._screen_space_y[i + 8]),
4452  t) +
4453  PortalFace._screen_space_y[i + 8];
4454  // New_x = right_clip
4455  PortalFace._screen_space_x[right_num_vertices + 6] =
4457  } else {
4458  // t = right_clip - v0.x / v1.x - v0.x
4460  PortalFace._screen_space_x[i + 9],
4461  PortalFace._screen_space_x[i + 8] -
4462  PortalFace._screen_space_x[i + 9]);
4463  // New_y = (v1.y - v0.y)*t + v0.y
4464  PortalFace._screen_space_y[right_num_vertices + 6] =
4466  PortalFace._screen_space_y[i + 9]),
4467  t) +
4468  PortalFace._screen_space_y[i + 9];
4469  // New_x = right_clip
4470  PortalFace._screen_space_x[right_num_vertices + 6] =
4472  }
4473  right_num_vertices++;
4474  }
4475  if (next_vertices_flag) {
4476  pNextVertices = right_num_vertices++;
4477  PortalFace._screen_space_x[pNextVertices + 6] =
4478  PortalFace._screen_space_x[i + 9];
4479  PortalFace._screen_space_y[pNextVertices + 6] =
4480  PortalFace._screen_space_y[i + 9];
4481  }
4482  current_vertices_flag = next_vertices_flag;
4483  }
4484  //************************************************************************************************************************************
4485  // for top clip plane
4486  top_num_vertices = 0;
4487  PortalFace._screen_space_x[right_num_vertices + 6] =
4489  PortalFace._screen_space_y[right_num_vertices + 6] =
4491 
4492  current_vertices_flag = PortalFace._screen_space_y[6] >=
4493  (signed int)pBLVRenderParams->uViewportY; // 8.0
4494  if (right_num_vertices < 1) return 0;
4495  for (uint i = 1; i <= right_num_vertices; ++i) {
4496  next_vertices_flag = PortalFace._screen_space_y[i + 6] >=
4497  (signed int)pBLVRenderParams->uViewportY;
4498  if (current_vertices_flag ^ next_vertices_flag) {
4499  if (next_vertices_flag) {
4501  PortalFace._screen_space_y[i + 5],
4502  PortalFace._screen_space_y[i + 6] -
4503  PortalFace._screen_space_y[i + 5]);
4504  PortalFace._screen_space_x[top_num_vertices + 3] =
4505  ((signed int)((PortalFace._screen_space_x[i + 6] -
4506  PortalFace._screen_space_x[i + 5]) *
4507  t) >>
4508  16) +
4509  PortalFace._screen_space_x[i + 5];
4510  PortalFace._screen_space_y[top_num_vertices + 3] =
4512  } else {
4514  PortalFace._screen_space_y[i + 6],
4515  PortalFace._screen_space_y[i + 5] -
4516  PortalFace._screen_space_y[i + 6]);
4517  PortalFace._screen_space_x[top_num_vertices + 3] =
4519  PortalFace._screen_space_x[i + 6]),
4520  t) +
4521  PortalFace._screen_space_x[i + 6];
4522  PortalFace._screen_space_y[top_num_vertices + 3] =
4524  }
4525  top_num_vertices++;
4526  }
4527  current_vertices_flag = next_vertices_flag;
4528  if (next_vertices_flag) {
4529  pNextVertices = top_num_vertices++;
4530  PortalFace._screen_space_x[pNextVertices + 3] =
4531  PortalFace._screen_space_x[i + 6];
4532  PortalFace._screen_space_y[pNextVertices + 3] =
4533  PortalFace._screen_space_y[i + 6];
4534  }
4535  }
4536  //**********************************************************************************************************************************
4537  // for bottom_clip plane(проверка по нижней плоскости)
4538  bottom_num_vertices = 0;
4539  PortalFace._screen_space_x[top_num_vertices + 3] =
4541  PortalFace._screen_space_y[top_num_vertices + 3] =
4543  current_vertices_flag = PortalFace._screen_space_y[3] <=
4544  (signed int)pBLVRenderParams->uViewportW; // 351.0
4545  if (top_num_vertices < 1) return 0;
4546  for (uint i = 1; i <= top_num_vertices; ++i) {
4547  next_vertices_flag = PortalFace._screen_space_y[i + 3] <=
4548  (signed int)pBLVRenderParams->uViewportW;
4549  if (current_vertices_flag ^ next_vertices_flag) {
4550  if (next_vertices_flag) {
4552  PortalFace._screen_space_y[i + 2],
4553  PortalFace._screen_space_y[i + 3] -
4554  PortalFace._screen_space_y[i + 2]);
4555  PortalFace._screen_space_x[bottom_num_vertices] =
4557  PortalFace._screen_space_x[i + 2]),
4558  t) +
4559  PortalFace._screen_space_x[i + 2];
4560  PortalFace._screen_space_y[bottom_num_vertices] =
4562  } else {
4564  PortalFace._screen_space_y[i + 3],
4565  PortalFace._screen_space_y[i + 2] -
4566  PortalFace._screen_space_y[i + 3]);
4567  PortalFace._screen_space_x[bottom_num_vertices] =
4569  PortalFace._screen_space_x[i + 3]),
4570  t) +
4571  PortalFace._screen_space_x[i + 3];
4572  PortalFace._screen_space_y[bottom_num_vertices] =
4574  }
4575  bottom_num_vertices++;
4576  }
4577  if (next_vertices_flag) {
4578  pNextVertices = bottom_num_vertices++;
4579  PortalFace._screen_space_x[pNextVertices] =
4580  PortalFace._screen_space_x[i + 3];
4581  PortalFace._screen_space_y[pNextVertices] =
4582  PortalFace._screen_space_y[i + 3];
4583  }
4584  current_vertices_flag = next_vertices_flag;
4585  }
4586  //***************************************************************************************************************************************
4587 
4588  if (!bottom_num_vertices) return 0;
4589  PortalFace._screen_space_x[bottom_num_vertices] =
4591  PortalFace._screen_space_y[bottom_num_vertices] =
4593  // check for software(проверка для софтвар)
4594  /*if ( !render->pRenderD3D && bottom_num_vertices > 3 )
4595  {
4596  PortalFace._screen_space_x[bottom_num_vertices + 1] =
4597  PortalFace._screen_space_x[1];
4598  PortalFace._screen_space_y[bottom_num_vertices + 1] =
4599  PortalFace._screen_space_y[1]; thisf = PortalFace.direction == true ? 1 : -
4600  1; if ( bottom_num_vertices > 0 )
4601  {
4602  v62 = 1;
4603  v71 = 1;
4604  do
4605  {
4606  v63 = v62 - 1;
4607  v64 = v62 + 1;
4608  v80 = v62 + 1;
4609  if ( v62 - 1 >= bottom_num_vertices )
4610  v63 -= bottom_num_vertices;
4611  if ( v62 >= bottom_num_vertices )
4612  v62 -= bottom_num_vertices;
4613  if ( v64 >= bottom_num_vertices )
4614  v64 -= bottom_num_vertices;
4615  if ( thisf * ((PortalFace._screen_space_y[v64] -
4616  PortalFace._screen_space_y[v63])
4617  * (PortalFace._screen_space_x[v62] -
4618  PortalFace._screen_space_x[v63])
4619  - (PortalFace._screen_space_y[v62] -
4620  PortalFace._screen_space_y[v63])
4621  * (PortalFace._screen_space_x[v64] -
4622  PortalFace._screen_space_x[v63])) < 0 )
4623  {
4624  v62 = v80;
4625  v71 = v80;
4626  }
4627  else
4628  {
4629  v62 = v71;
4630  v65 = v71;
4631  if ( v71 < bottom_num_vertices || (v65 = v71 - bottom_num_vertices,
4632  v71 - bottom_num_vertices < bottom_num_vertices) )
4633  {
4634  memcpy(&PortalFace._screen_space_y[v65],
4635  &PortalFace._screen_space_y[v65 + 1], 4 * ((unsigned int)(4 *
4636  (bottom_num_vertices - v65)) >> 2));
4637  memcpy(&PortalFace._screen_space_x[v65],
4638  &PortalFace._screen_space_x[v65 + 1], 4 * ((unsigned int)(4 *
4639  (bottom_num_vertices - v65)) >> 2));
4640  }
4641  --bottom_num_vertices;
4642  }
4643  }
4644  while ( v62 - 1 < bottom_num_vertices );
4645  }
4646  PortalFace._screen_space_x[bottom_num_vertices] =
4647  PortalFace._screen_space_x[0];
4648  PortalFace._screen_space_y[bottom_num_vertices] =
4649  PortalFace._screen_space_y[0];
4650  }*/
4651  return bottom_num_vertices;
4652 }
4653 
4654 //----- (00472866) --------------------------------------------------------
4655 void BLV_ProcessPartyActions() { // could this be combined with odm process actions?
4656  int v1; // ebx@1
4657  int v2; // edi@1
4658  double v10; // st7@27
4659  int new_party_z; // esi@96
4660  int v38; // eax@96
4661  int v39; // ecx@106
4662  int v40; // eax@106
4663  int v42; // eax@120
4664  BLVFace *pFace; // esi@126
4665  int v46; // ecx@133
4666  int v52; // eax@140
4667  int v54; // ebx@146
4668  unsigned int uFaceEvent; // [sp+14h] [bp-4Ch]@1
4669  bool party_running_flag; // [sp+1Ch] [bp-44h]@1
4670  bool bFeatherFall; // [sp+24h] [bp-3Ch]@15
4671  unsigned int uSectorID; // [sp+28h] [bp-38h]@1
4672  bool party_walking_flag; // [sp+2Ch] [bp-34h]@1
4673  unsigned int uFaceID; // [sp+30h] [bp-30h]@1
4674  int v80; // [sp+34h] [bp-2Ch]@1
4675  int v82; // [sp+3Ch] [bp-24h]@47
4676  int _view_angle; // [sp+40h] [bp-20h]@47
4677  bool hovering; // [sp+44h] [bp-1Ch]@1
4678  int new_party_y; // [sp+48h] [bp-18h]@1
4679  int new_party_x; // [sp+4Ch] [bp-14h]@1
4680  int party_z; // [sp+50h] [bp-10h]@1
4681  int angle; // [sp+5Ch] [bp-4h]@47
4682 
4683  uFaceEvent = 0;
4684  // v89 = pParty->uFallSpeed;
4685  v1 = 0;
4686  v2 = 0;
4687  new_party_x = pParty->vPosition.x;
4688  new_party_y = pParty->vPosition.y;
4689  party_z = pParty->vPosition.z;
4690  uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y,
4691  pParty->vPosition.z);
4692  party_running_flag = false;
4693  party_walking_flag = false;
4694  hovering = false;
4695 
4696  uFaceID = -1;
4697  int floor_level =
4698  collide_against_floor(new_party_x, new_party_y, party_z + 40,
4699  &uSectorID, &uFaceID); //получить высоту пола
4700 
4701  if (pParty->bFlying) { // отключить полёт
4702  pParty->bFlying = false;
4703  if (pParty->FlyActive())
4705  ->pOverlays[pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID - 1]
4706  .field_E |= 1;
4707  }
4708 
4709  if (floor_level == -30000 || uFaceID == -1) {
4710  floor_level = collide_against_floor_approximate(
4711  new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID);
4712  if (floor_level == -30000 || uFaceID == -1) {
4713  __debugbreak(); // level built with errors
4718  return;
4719  }
4720  }
4721 
4725  if (!pParty->bTurnBasedModeOn) {
4726  static int dword_720CDC = 0;
4727 
4728  int v67 = OS_GetTime() / 500;
4729  if (dword_720CDC != v67) {
4733  if (dword_4F8580[0] > 60) dword_4F8580[0] = 1;
4734 
4735  dword_720CDC = v67;
4736  }
4737  }
4738 
4739  int fall_start;
4740  /*
4741  if (!pParty->FeatherFallActive())// не активно падение пера
4742  {
4743  bFeatherFall = false;
4744  if (!pParty->pPlayers[0].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) &&
4745  // grants feather fall
4746  !pParty->pPlayers[1].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) &&
4747  !pParty->pPlayers[2].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) &&
4748  !pParty->pPlayers[3].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT))
4749  {
4750  fall_start = pParty->uFallStartY;
4751  }
4752  else// was missing
4753  {
4754  fall_start = floor_level;
4755  bFeatherFall = true;
4756  pParty->uFallStartY = floor_level;
4757  }
4758  }
4759  else// активно падение пера
4760  {
4761  fall_start = floor_level;
4762  bFeatherFall = true;
4763  pParty->uFallStartY = floor_level;
4764  }
4765 
4766  Reworked condition below
4767  */
4768  if (pParty->FeatherFallActive() ||
4769  pParty->pPlayers[0].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) ||
4770  pParty->pPlayers[1].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) ||
4771  pParty->pPlayers[2].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) ||
4772  pParty->pPlayers[3].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT)) {
4773  fall_start = floor_level;
4774  bFeatherFall = true;
4775  pParty->uFallStartY = floor_level;
4776  } else {
4777  bFeatherFall = false;
4778  fall_start = pParty->uFallStartY;
4779  }
4780 
4781  if (fall_start - party_z > 512 && !bFeatherFall &&
4782  party_z <= floor_level + 1) { // повреждение от падения с высоты
4783  assert(~pParty->uFlags & PARTY_FLAGS_1_LANDING); // why land in indoor?
4786  } else {
4787  for (uint i = 0; i < 4; ++i) { // receive falling damage
4788  if (!pParty->pPlayers[i].HasEnchantedItemEquipped(72) &&
4790  EQUIP_BOOTS)) {
4791  pParty->pPlayers[i].ReceiveDamage(
4792  (pParty->uFallStartY - party_z) *
4793  (0.1f * pParty->pPlayers[i].GetMaxHealth()) / 256,
4794  DMGT_PHISYCAL);
4795  v10 = (double)(20 - pParty->pPlayers[i].GetParameterBonus(
4796  pParty->pPlayers[i]
4797  .GetActualEndurance())) *
4798  flt_6BE3A4_debug_recmod1 * 2.133333333333333;
4799  pParty->pPlayers[i].SetRecoveryTime((signed __int64)v10);
4800  }
4801  }
4802  }
4803  }
4804 
4805  if (party_z > floor_level + 1) hovering = true;
4806 
4807  bool not_high_fall = false;
4808 
4809  if (party_z - floor_level <= 32) {
4810  pParty->uFallStartY = party_z;
4811  not_high_fall = true;
4812  }
4813 
4814  if (!engine->config->NoWalkSound() && pParty->walk_sound_timer) { //таймеры для звуков передвижения
4817  else
4818  pParty->walk_sound_timer = 0;
4819  }
4820 
4821  if (party_z <= floor_level + 1) { // группа ниже уровня пола
4822  party_z = floor_level + 1;
4823  pParty->uFallStartY = floor_level + 1;
4824 
4825  if (!hovering && pParty->floor_face_pid != uFaceID) { // не парящие и
4826  if (pIndoor->pFaces[uFaceID].uAttributes & FACE_PRESSURE_PLATE)
4827  uFaceEvent =
4829  .uEventID;
4830  }
4831  }
4832  if (!hovering) pParty->floor_face_pid = uFaceID;
4833 
4834  bool on_water = false;
4835  if (pIndoor->pFaces[uFaceID].Fluid()) // на воде
4836  on_water = true;
4837 
4838  // v81 = pParty->uWalkSpeed;
4839  angle = pParty->sRotationY;
4840  _view_angle = pParty->sRotationX;
4841  v82 =
4842  (unsigned __int64)(pEventTimer->dt_in_some_format *
4843  (signed __int64)((signed int)(pParty
4844  ->y_rotation_speed *
4845  stru_5C6E00
4846  ->uIntegerPi) /
4847  180)) >>
4848  16;
4849  while (pPartyActionQueue->uNumActions) {
4850  switch (pPartyActionQueue->Next()) {
4851  case PARTY_TurnLeft:
4852  if (engine->config->turn_speed > 0)
4853  angle = stru_5C6E00->uDoublePiMask & (angle + engine->config->turn_speed);
4854  else
4856  break;
4857  case PARTY_TurnRight:
4858  if (engine->config->turn_speed > 0)
4859  angle = stru_5C6E00->uDoublePiMask & (angle - engine->config->turn_speed);
4860  else
4862  break;
4863 
4864  case PARTY_FastTurnLeft:
4865  if (engine->config->turn_speed > 0)
4866  angle = stru_5C6E00->uDoublePiMask & (angle + engine->config->turn_speed);
4867  else
4868  angle = stru_5C6E00->uDoublePiMask & (angle + (int)(2.0f * fTurnSpeedMultiplier * (double)v82));
4869  break;
4870 
4871  case PARTY_FastTurnRight:
4872  if (engine->config->turn_speed > 0)
4873  angle = stru_5C6E00->uDoublePiMask & (angle - engine->config->turn_speed);
4874  else
4875  angle = stru_5C6E00->uDoublePiMask & (angle - (int)(2.0f * fTurnSpeedMultiplier * (double)v82));
4876  break;
4877 
4878  case PARTY_StrafeLeft:
4881  party_walking_flag = true;
4882  break;
4883  case PARTY_StrafeRight:
4886  party_walking_flag = true;
4887  break;
4888  case PARTY_WalkForward:
4891  party_walking_flag = true;
4892  break;
4893  case PARTY_WalkBackward:
4896  party_walking_flag = true;
4897  break;
4898  case PARTY_RunForward: //Бег вперёд
4901  party_running_flag = true;
4902  break;
4903  case PARTY_RunBackward:
4906  party_running_flag = true;
4907  break;
4908  case PARTY_LookDown:
4909  _view_angle += (signed __int64)(flt_6BE150_look_up_down_dangle * 25.0);
4910  if (_view_angle > 128)
4911  _view_angle = 128;
4912  if (uActiveCharacter)
4914  break;
4915  case PARTY_LookUp:
4916  _view_angle += (signed __int64)(flt_6BE150_look_up_down_dangle * -25.0);
4917  if (_view_angle < -128)
4918  _view_angle = -128;
4919  if (uActiveCharacter)
4921  break;
4922  case PARTY_CenterView:
4923  _view_angle = 0;
4924  break;
4925  case PARTY_Jump:
4926  if ((!hovering ||
4927  party_z <= floor_level + 6 && pParty->uFallSpeed <= 0) &&
4928  pParty->field_24) {
4929  hovering = true;
4930  pParty->uFallSpeed += pParty->field_24 * 96;
4931  }
4932  break;
4933  default:
4934  break;
4935  }
4936  }
4937  pParty->sRotationY = angle;
4938  pParty->sRotationX = _view_angle;
4939  if (hovering) { // парящие
4941  GetGravityStrength(); // расчёт скорости падения
4942  if (hovering && pParty->uFallSpeed <= 0) {
4943  if (pParty->uFallSpeed < -500 && !pParty->bFlying) {
4944  for (uint pl = 1; pl <= 4; pl++) {
4945  if (!pPlayers[pl]->HasEnchantedItemEquipped(72) &&
4946  !pPlayers[pl]->WearsItem(ITEM_ARTIFACT_HERMES_SANDALS,
4947  EQUIP_BOOTS)) // was 8
4948  pPlayers[pl]->PlayEmotion(CHARACTER_EXPRESSION_SCARED,
4949  0);
4950  }
4951  }
4952  } else {
4953  pParty->uFallStartY = party_z;
4954  }
4955  } else { // не парящие
4956  if (pIndoor->pFaces[uFaceID].pFacePlane_old.vNormal.z < 0x8000) {
4957  pParty->uFallSpeed -=
4959  pParty->uFallStartY = party_z;
4960  } else {
4962  pParty->uFallSpeed = 0;
4963  pParty->uFallStartY = party_z;
4964  }
4965  }
4966  if (v2 * v2 + v1 * v1 < 400) {
4967  v1 = 0;
4968  v2 = 0;
4969  }
4970 
4971  stru_721530.field_84 = -1;
4972  stru_721530.field_70 = 0;
4975  stru_721530.field_0 = 1;
4977  for (uint i = 0; i < 100; i++) {
4978  new_party_z = party_z;
4979  stru_721530.position.x = new_party_x;
4980  stru_721530.position.y = new_party_y;
4981  stru_721530.position.z = stru_721530.height + party_z + 1;
4982 
4983  stru_721530.normal.x = new_party_x;
4984  stru_721530.normal.y = new_party_y;
4985  stru_721530.normal.z = stru_721530.prolly_normal_d + party_z + 1;
4986 
4987  stru_721530.velocity.x = v2;
4988  stru_721530.velocity.y = v1;
4990 
4991  stru_721530.uSectorID = uSectorID;
4992  v38 = 0;
4994  v38 = 13312;
4995  }
4996  if (stru_721530.CalcMovementExtents(v38)) break;
4997  for (uint j = 0; j < 100; ++j) {
4999  _46E0B2_collide_against_decorations(); //столкновения с декором
5000  for (v80 = 0; v80 < (signed int)uNumActors; ++v80)
5002  v80, 0); //столкновения с монстрами
5003  if (_46F04E_collide_against_portals()) //столкновения с порталами
5004  break;
5005  }
5007  v39 = stru_721530.normal2.x;
5008  uSectorID = stru_721530.normal2.y;
5010  } else {
5011  v39 = new_party_x +
5013  uSectorID = new_party_y + fixpoint_mul(stru_721530.field_7C,
5015  v40 = new_party_z +
5017  }
5018  v42 = collide_against_floor(v39, uSectorID, v40 + 40,
5019  &stru_721530.uSectorID, &uFaceID);
5020  if (v42 == -30000 || v42 - new_party_z > 128) return;
5021  if (stru_721530.field_7C >= stru_721530.field_6C) { // ???
5022  new_party_x = stru_721530.normal2.x;
5023  new_party_y = stru_721530.normal2.y;
5024  new_party_z =
5026  break;
5027  }
5028  new_party_x +=
5030  new_party_y +=
5032  uSectorID = stru_721530.uSectorID;
5034  unsigned long long v87 =
5035  new_party_z +
5037  if (PID_TYPE(stru_721530.pid) ==
5038  OBJECT_Actor) { // invis break on actor collision / при
5039  // столкновении с монстром
5040  if (pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Active()) {
5042  }
5043  viewparams->bRedrawGameUI = true;
5044  } else if (PID_TYPE(stru_721530.pid) ==
5045  OBJECT_Decoration) { // decoration collision / при
5046  // столкновении с декорацией
5047  v54 = stru_5C6E00->Atan2(
5048  new_party_x -
5049  pLevelDecorations[stru_721530.pid >> 3].vPosition.x,
5050  new_party_y -
5051  pLevelDecorations[stru_721530.pid >> 3].vPosition.y);
5052  v2 = fixpoint_mul(stru_5C6E00->Cos(v54),
5053  integer_sqrt(v2 * v2 + v1 * v1));
5054  v1 = fixpoint_mul(stru_5C6E00->Sin(v54),
5055  integer_sqrt(v2 * v2 + v1 * v1));
5056  } else if (PID_TYPE(stru_721530.pid) ==
5057  OBJECT_BModel) { // при столкновении с bmodel
5058  pFace = &pIndoor->pFaces[(signed int)stru_721530.pid >> 3];
5059  if (pFace->uPolygonType == POLYGON_Floor) { // если bmodel - пол
5060  if (pParty->uFallSpeed < 0) pParty->uFallSpeed = 0;
5061  v87 = pIndoor->pVertices[*pFace->pVertexIDs].z + 1;
5062  if (pParty->uFallStartY - v87 < 512) pParty->uFallStartY = v87;
5063  if (v2 * v2 + v1 * v1 < 400) {
5064  v1 = 0;
5065  v2 = 0;
5066  }
5067  if (pParty->floor_face_pid != PID_ID(stru_721530.pid) &&
5068  pFace->Pressure_Plate())
5069  uFaceEvent =
5071  } else { // если не пол
5072  v46 = pParty->uFallSpeed * pFace->pFacePlane_old.vNormal.z;
5073  if (pFace->uPolygonType !=
5074  POLYGON_InBetweenFloorAndWall) { // полез на холм
5075  v80 = abs(v1 * pFace->pFacePlane_old.vNormal.y + v46 +
5076  v2 * pFace->pFacePlane_old.vNormal.x) >>
5077  16;
5078  if ((stru_721530.speed >> 3) > v80)
5079  v80 = stru_721530.speed >> 3;
5080  v2 += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.x);
5081  v1 += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.y);
5082  pParty->uFallSpeed +=
5083  fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.z);
5084  // v80 = pFace->pFacePlane_old.vNormal.y;
5086  ((pFace->pFacePlane_old.dist +
5087  v87 * pFace->pFacePlane_old.vNormal.z +
5088  new_party_y * pFace->pFacePlane_old.vNormal.y +
5089  new_party_x * pFace->pFacePlane_old.vNormal.x) >>
5090  16);
5091  if (v52 > 0) {
5092  new_party_x +=
5093  fixpoint_mul(v52, pFace->pFacePlane_old.vNormal.x);
5094  new_party_y +=
5095  fixpoint_mul(v52, pFace->pFacePlane_old.vNormal.y);
5096  v87 +=
5097  fixpoint_mul(v52, pFace->pFacePlane_old.vNormal.z);
5098  }
5099  if (pParty->floor_face_pid != PID_ID(stru_721530.pid) &&
5100  pFace->Pressure_Plate())
5101  uFaceEvent =
5103  }
5105  v80 = abs(v1 * pFace->pFacePlane_old.vNormal.y + v46 +
5106  v2 * pFace->pFacePlane_old.vNormal.x) >>
5107  16;
5108  if ((stru_721530.speed >> 3) > v80)
5109  v80 = stru_721530.speed >> 3;
5110  v2 += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.x);
5111  v1 += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.y);
5112  pParty->uFallSpeed +=
5113  fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.z);
5114  if (v2 * v2 + v1 * v1 >= 400) {
5115  if (pParty->floor_face_pid != PID_ID(stru_721530.pid) &&
5116  pFace->Pressure_Plate())
5117  uFaceEvent =
5119  .uEventID;
5120  } else {
5121  v2 = 0;
5122  v1 = 0;
5123  pParty->uFallSpeed = 0;
5124  }
5125  }
5126  }
5127  }
5128  v2 = fixpoint_mul(58500, v2);
5129  v1 = fixpoint_mul(58500, v1);
5131  }
5132 
5133  // //Воспроизведение звуков ходьбы/бега-------------------------
5134  uint pX_ = abs(pParty->vPosition.x - new_party_x);
5135  uint pY_ = abs(pParty->vPosition.y - new_party_y);
5136  uint pZ_ = abs(pParty->vPosition.z - new_party_z);
5137  if (!engine->config->NoWalkSound() && pParty->walk_sound_timer <= 0) {
5138  pAudioPlayer->StopAll(804); // stop sound
5139  if (party_running_flag &&
5140  (!hovering || not_high_fall)) { // Бег и (не прыжок или не высокое падение )
5141  if (integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 16) {
5142  if (on_water)
5143  pAudioPlayer->PlaySound(SOUND_RunWaterIndoor, 804, 1, -1, 0, 0);
5144  else if (pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_CARPET) //по ковру
5145  pAudioPlayer->PlaySound(SOUND_RunCarpet, -1 /*804*/, 1, -1, 0, 0);
5146  else
5147  pAudioPlayer->PlaySound(SOUND_RunWood, -1 /*804*/, 1, -1, 0, 0);
5148  pParty->walk_sound_timer = 96; // 64
5149  }
5150  } else if (party_walking_flag &&
5151  (!hovering || not_high_fall)) { // Ходьба и (не прыжок или не
5152  // высокое падение)
5153  if (integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 8) {
5154  if (on_water)
5155  pAudioPlayer->PlaySound(SOUND_WalkWaterIndoor, 804, 1, -1, 0, 0);
5156  else if (pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_CARPET) //по ковру
5157  pAudioPlayer->PlaySound(SOUND_WalkCarpet, -1 /*804*/, 1, -1, 0, 0);
5158  else
5159  pAudioPlayer->PlaySound(SOUND_WalkWood, -1 /*804*/, 1, -1, 0, 0);
5160  pParty->walk_sound_timer = 144; // 64
5161  }
5162  }
5163  }
5164  if (integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) <
5165  8) //отключить звук ходьбы при остановке
5166  pAudioPlayer->StopAll(804);
5167  //-------------------------------------------------------------
5168  if (!hovering || !not_high_fall)
5170  else
5173  pParty->vPosition.x = new_party_x;
5174  pParty->vPosition.z = new_party_z;
5175  pParty->vPosition.y = new_party_y;
5176  // pParty->uFallSpeed = v89;
5177  if (!hovering && pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_LAVA)
5178  pParty->uFlags |= PARTY_FLAGS_1_BURNING; // 0x200
5179  if (uFaceEvent) EventProcessor(uFaceEvent, 0, 1);
5180 }
5181 
5182 //----- (00449A49) --------------------------------------------------------
5183 void Door_switch_animation(unsigned int uDoorID, int a2) {
5184  int old_state; // eax@1
5185  signed int door_id; // esi@2
5186 
5187  if (!pIndoor->pDoors) return;
5188  for (door_id = 0; door_id < 200; ++door_id) {
5189  if (pIndoor->pDoors[door_id].uDoorID == uDoorID) break;
5190  }
5191  if (door_id >= 200) {
5192  Error("Unable to find Door ID: %i!", uDoorID);
5193  }
5194  old_state = pIndoor->pDoors[door_id].uState;
5195  // old_state: 0 - в нижнем положении/закрыто
5196  // 2 - в верхнем положении/открыто,
5197  // a2: 1 - открыть
5198  // 2 - опустить/поднять
5199  if (a2 == 2) {
5200  if (pIndoor->pDoors[door_id].uState == BLVDoor::Closing ||
5201  pIndoor->pDoors[door_id].uState == BLVDoor::Opening)
5202  return;
5203  if (pIndoor->pDoors[door_id].uState) {
5204  if (pIndoor->pDoors[door_id].uState != BLVDoor::Closed &&
5205  pIndoor->pDoors[door_id].uState != BLVDoor::Closing) {
5206  pIndoor->pDoors[door_id].uState = BLVDoor::Closing;
5207  if (old_state == BLVDoor::Open) {
5208  pIndoor->pDoors[door_id].uTimeSinceTriggered = 0;
5209  return;
5210  }
5211  if (pIndoor->pDoors[door_id].uTimeSinceTriggered != 15360) {
5212  pIndoor->pDoors[door_id].uTimeSinceTriggered =
5213  (pIndoor->pDoors[door_id].uMoveLength << 7) /
5214  pIndoor->pDoors[door_id].uOpenSpeed -
5215  ((signed int)(pIndoor->pDoors[door_id]
5217  pIndoor->pDoors[door_id].uCloseSpeed) /
5218  128
5219  << 7) /
5220  pIndoor->pDoors[door_id].uOpenSpeed;
5221  return;
5222  }
5223  pIndoor->pDoors[door_id].uTimeSinceTriggered = 15360;
5224  }
5225  return;
5226  }
5227  } else {
5228  if (a2 == 0) {
5229  if (pIndoor->pDoors[door_id].uState != BLVDoor::Closed &&
5230  pIndoor->pDoors[door_id].uState != BLVDoor::Closing) {
5231  pIndoor->pDoors[door_id].uState = BLVDoor::Closing;
5232  if (old_state == BLVDoor::Open) {
5233  pIndoor->pDoors[door_id].uTimeSinceTriggered = 0;
5234  return;
5235  }
5236  if (pIndoor->pDoors[door_id].uTimeSinceTriggered != 15360) {
5237  pIndoor->pDoors[door_id].uTimeSinceTriggered =
5238  (pIndoor->pDoors[door_id].uMoveLength << 7) /
5239  pIndoor->pDoors[door_id].uOpenSpeed -
5240  ((signed int)(pIndoor->pDoors[door_id]
5242  pIndoor->pDoors[door_id].uCloseSpeed) /
5243  128
5244  << 7) /
5245  pIndoor->pDoors[door_id].uOpenSpeed;
5246  return;
5247  }
5248  pIndoor->pDoors[door_id].uTimeSinceTriggered = 15360;
5249  }
5250  return;
5251  }
5252  if (a2 != 1) return;
5253  }
5254  if (old_state != BLVDoor::Open && old_state != BLVDoor::Opening) {
5255  pIndoor->pDoors[door_id].uState = BLVDoor::Opening;
5256  if (old_state == BLVDoor::Closed) {
5257  pIndoor->pDoors[door_id].uTimeSinceTriggered = 0;
5258  return;
5259  }
5260  if (pIndoor->pDoors[door_id].uTimeSinceTriggered != 15360) {
5261  pIndoor->pDoors[door_id].uTimeSinceTriggered =
5262  (pIndoor->pDoors[door_id].uMoveLength << 7) /
5263  pIndoor->pDoors[door_id].uCloseSpeed -
5264  ((signed int)(pIndoor->pDoors[door_id].uTimeSinceTriggered *
5265  pIndoor->pDoors[door_id].uOpenSpeed) /
5266  128
5267  << 7) /
5268  pIndoor->pDoors[door_id].uCloseSpeed;
5269  return;
5270  }
5271  pIndoor->pDoors[door_id].uTimeSinceTriggered = 15360;
5272  }
5273  return;
5274 }
5275 
5276 //----- (004088E9) --------------------------------------------------------
5277 int sub_4088E9(int x1, int y1, int x2, int y2, int x3, int y3) {
5278  signed int result; // eax@1
5279 
5280  result =
5281  integer_sqrt(abs(x2 - x1) * abs(x2 - x1) + abs(y2 - y1) * abs(y2 - y1));
5282  if (result)
5283  result = abs(((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / result);
5284  return result;
5285 }
5286 
5288  int result;
5289 
5292  else
5294 
5295  return result;
5296 }
5297 
5299  int result = 0; // eax@8
5300  int v6; // edi@11
5301  int v7; // ebx@11
5302  int v9; // ebx@12
5303  int v10; // eax@12
5304  char v11 = 0; // zf@16
5305  int v12; // edi@20
5306  int v13; // eax@20
5307  int v14; // ebx@20
5308  int v15; // eax@20
5309  int v16; // eax@20
5310  int v17; // eax@20
5311  int v18; // eax@21
5312  SpawnPointMM7 v19; // [sp+Ch] [bp-38h]@1
5313  int v22; // [sp+2Ch] [bp-18h]@3
5314  unsigned int uFaceID; // [sp+38h] [bp-Ch]@10
5315  int v26 = 0; // [sp+3Ch] [bp-8h]@11
5316  int v27; // [sp+40h] [bp-4h]@11
5317 
5318  if (!uNumActors) return 0;
5319 
5320  for (uint mon_id = 0; mon_id < uNumActors; ++mon_id) {
5321  if ((pActors[mon_id].pMonsterInfo.uID < 121 ||
5322  pActors[mon_id].pMonsterInfo.uID > 123) && // Dwarf FemaleC A-C
5323  (pActors[mon_id].pMonsterInfo.uID < 124 ||
5324  pActors[mon_id].pMonsterInfo.uID > 126) && // Dwarf MaleA A-C
5325  (pActors[mon_id].pMonsterInfo.uID < 133 ||
5326  pActors[mon_id].pMonsterInfo.uID > 135) && // Peasant Elf FemaleA A-C
5327  pActors[mon_id].CanAct()) {
5329  v22 = 0;
5330  uint face_id = 0;
5331  for (face_id; face_id < 100; ++face_id) {
5332  v6 = rand() % 1024 + 512;
5333  v7 = rand() % (signed int)stru_5C6E00->uIntegerDoublePi;
5334  v19.vPosition.x = pParty->vPosition.x + fixpoint_mul(stru_5C6E00->Cos(v7), v6);
5335  v19.uIndex = a2;
5336  v19.vPosition.y = fixpoint_mul(stru_5C6E00->Sin(v7), v6) + pParty->vPosition.y;
5337  v19.vPosition.z = pParty->vPosition.z;
5338  bool bInWater = false;
5339  v27 = 0;
5340  v19.vPosition.z = ODM_GetFloorLevel(
5341  v19.vPosition.x, v19.vPosition.y, pParty->vPosition.z,
5342  0, &bInWater, &v27, 0);
5343  for (BSPModel &model : pOutdoor->pBModels) {
5344  v9 = abs(v19.vPosition.y - model.vBoundingCenter.y);
5345  v10 = abs(v19.vPosition.x - model.vBoundingCenter.x);
5346  if (int_get_vector_length(v10, v9, 0) <
5347  model.sBoundingRadius + 256) {
5348  v22 = 1;
5349  break;
5350  }
5351  }
5352  if (v22) {
5353  v11 = face_id == 100;
5354  break;
5355  }
5356  }
5357  v11 = face_id == 100;
5358  } else if (uCurrentlyLoadedLevelType == LEVEL_Indoor) {
5359  v22 =
5361  pParty->vPosition.z);
5362  for (uint i = 0; i < 100; ++i) {
5363  v12 = rand() % 512 + 256;
5364  v13 = rand();
5365  v14 = v13 % (int)stru_5C6E00->uIntegerDoublePi;
5366  v15 = stru_5C6E00->Cos(v13 % (int)stru_5C6E00->uIntegerDoublePi);
5367  v19.vPosition.x = pParty->vPosition.x + fixpoint_mul(v15, v12);
5368  v16 = stru_5C6E00->Sin(v13 % (int)stru_5C6E00->uIntegerDoublePi);
5369  v19.vPosition.y = fixpoint_mul(v16, v12) + pParty->vPosition.y;
5370  v19.vPosition.z = pParty->vPosition.z;
5371  v19.uIndex = a2;
5372  v17 = pIndoor->GetSector(v19.vPosition.x, v19.vPosition.y, pParty->vPosition.z);
5373  if (v17 == v22) {
5374  v18 = BLV_GetFloorLevel(v19.vPosition.x, v19.vPosition.y,
5375  v19.vPosition.z, v17, &uFaceID);
5376  v19.vPosition.z = v18;
5377  if (v18 != -30000) {
5378  if (abs(v18 - pParty->vPosition.z) <= 1024) break;
5379  }
5380  }
5381  }
5382  v11 = v26 == 100;
5383  }
5384 
5385  if (v11) {
5386  result = 0;
5387  } else {
5388  SpawnEncounter(a1, &v19, 0, 0, 1);
5389  result = a2;
5390  }
5391  }
5392 
5393  // break;
5394  // v22 = v3->pMonsterInfo.uID - 1;
5395  // v4 = (signed __int64)((double)v22 * 0.3333333333333333);
5396  // if ( (int)v4 != 40 )
5397  //{
5398  // if ( (int)v4 != 41 && (int)v4 != 44 && v3->CanAct() )
5399  // break;
5400  //}
5401  // ++v2;
5402  // ++v3;
5403  // if ( v2 >= (signed int)uNumActors )
5404  // goto LABEL_8;
5405  }
5406  return result;
5407 }
5408 
5409 int sub_450521_ProllyDropItemAt(int ecx0, int a2, int a3, int a4, int a5, uint16_t a6) {
5410  SpriteObject a1;
5411  pItemsTable->GenerateItem(ecx0, a2, &a1.containing_item);
5414  a1.vPosition.x = a3;
5415  a1.vPosition.y = a4;
5416  a1.vPosition.z = a5;
5417  a1.uFacing = a6;
5418  a1.uAttributes = 0;
5419  a1.uSectorID = pIndoor->GetSector(a3, a4, a5);
5420  a1.uSpriteFrameID = 0;
5421  return a1.Create(0, 0, 0, 0);
5422 }
5423 
5424 bool sub_4075DB(int x, int y, int z, BLVFace *face) {
5425  int v8; // edi@2
5426  int v25; // eax@22
5427  bool result; // eax@25
5428  int a3a; // [sp+24h] [bp+8h]@14
5429  int a4a; // [sp+28h] [bp+Ch]@2
5430 
5431  std::array<int, 52> dword_4F5CC8_ys; // idb
5432  std::array<int, 52> dword_4F5D98_xs; // idb
5433 
5434  if (face->uAttributes & FACE_XY_PLANE) {
5435  a4a = x;
5436  v8 = y;
5437  for (int i = 0; i < face->uNumVertices; i++) {
5438  dword_4F5D98_xs[i] = pIndoor->pVertices[face->pVertexIDs[i]].x;
5439  dword_4F5CC8_ys[i] = pIndoor->pVertices[face->pVertexIDs[i]].y;
5440  }
5441  } else {
5442  v8 = z;
5443  if (face->uAttributes & FACE_XZ_PLANE) {
5444  a4a = x;
5445  for (int i = 0; i < face->uNumVertices; i++) {
5446  dword_4F5D98_xs[i] = pIndoor->pVertices[face->pVertexIDs[i]].x;
5447  dword_4F5CC8_ys[i] = pIndoor->pVertices[face->pVertexIDs[i]].z;
5448  }
5449  } else {
5450  a4a = y;
5451  for (int i = 0; i < face->uNumVertices; i++) {
5452  dword_4F5D98_xs[i] = pIndoor->pVertices[face->pVertexIDs[i]].y;
5453  dword_4F5CC8_ys[i] = pIndoor->pVertices[face->pVertexIDs[i]].z;
5454  }
5455  }
5456  }
5457  a3a = 0;
5458  dword_4F5D98_xs[face->uNumVertices] = dword_4F5D98_xs[0];
5459  dword_4F5CC8_ys[face->uNumVertices] = dword_4F5CC8_ys[0];
5460  for (int i = 0; i < face->uNumVertices && a3a < 2; i++) {
5461  if ((dword_4F5CC8_ys[i] >= v8) ^ (dword_4F5CC8_ys[i + 1] >= v8)) {
5462  // if( dword_4F5D98_xs[i + 1] >= a4a || dword_4F5D98_xs[i] >= a4a)
5463  if (!(dword_4F5D98_xs[i + 1] >= a4a && dword_4F5D98_xs[i] < a4a)) {
5464  if ((dword_4F5D98_xs[i + 1] < a4a && dword_4F5D98_xs[i] >= a4a)) {
5465  ++a3a;
5466  // || (v25 = dword_4F5D98_xs[i + 1] -
5467  // dword_4F5D98_xs[i],LODWORD(v26) = v25 << 16, HIDWORD(v26) =
5468  // v25 >> 16, dword_4F5D98_xs[i] + ((signed int)(((unsigned
5469  // __int64)(v26 / (dword_4F5CC4_ys[i + 2] - dword_4F5CC4_ys[i +
5470  // 1])* ((v8 - dword_4F5CC4_ys[i + 1]) << 16)) >> 16)
5471  // + 32768) >> 16) >= a4a) )
5472  } else {
5473  v25 = fixpoint_div(dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i],
5474  dword_4F5CC8_ys[i + 1] - dword_4F5CC8_ys[i]);
5475  if (dword_4F5D98_xs[i] + (fixpoint_mul(v25, (v8 - dword_4F5CC8_ys[i]) << 16) + 0x8000 >> 16) >= a4a)
5476  ++a3a;
5477  }
5478  }
5479  }
5480  }
5481  result = 1;
5482  if (a3a != 1) result = 0;
5483  return result;
5484 }
5485 
5486 bool sub_4077F1(int a1, int a2, int a3, ODMFace *face, BSPVertexBuffer *a5) {
5487  int a4a; // [sp+28h] [bp+Ch]@2
5488  int a5a; // [sp+2Ch] [bp+10h]@14
5489 
5490  std::array<int, 52> dword_4F5B24_ys; // idb
5491  std::array<int, 52> dword_4F5BF4_xs; // idb
5492 
5493  // __debugbreak(); // срабатывает при нападении стрекозавров с огнём
5494 
5495  if (face->uAttributes & FACE_XY_PLANE) {
5496  a4a = a1;
5497  a3 = a2;
5498  for (int i = 0; i < face->uNumVertices; i++) {
5499  dword_4F5BF4_xs[i + 1] = a5->pVertices[face->pVertexIDs[i]].x;
5500  dword_4F5B24_ys[i + 1] = a5->pVertices[face->pVertexIDs[i]].y;
5501  }
5502  } else {
5503  if (face->uAttributes & FACE_XY_PLANE) {
5504  a4a = a1;
5505  for (int i = 0; i < face->uNumVertices; i++) {
5506  dword_4F5BF4_xs[i + 1] = a5->pVertices[face->pVertexIDs[i]].x;
5507  dword_4F5B24_ys[i + 1] = a5->pVertices[face->pVertexIDs[i]].z;
5508  }
5509  } else {
5510  a4a = a2;
5511  for (int i = 0; i < face->uNumVertices; i++) {
5512  dword_4F5BF4_xs[i + 1] = a5->pVertices[face->pVertexIDs[i]].y;
5513  dword_4F5B24_ys[i + 1] = a5->pVertices[face->pVertexIDs[i]].z;
5514  }
5515  }
5516  }
5517  a5a = 0;
5518  dword_4F5BF4_xs[face->uNumVertices + 1] = dword_4F5BF4_xs[1];
5519  dword_4F5B24_ys[face->uNumVertices + 1] = dword_4F5B24_ys[1];
5520  for (int i = 0; i < face->uNumVertices; i++) {
5521  if (a5a >= 2) break;
5522  if ((dword_4F5B24_ys[i + 1] >= a3) ^ (dword_4F5B24_ys[i + 2] >= a3)) {
5523  if (dword_4F5BF4_xs[i + 2] >= a4a || dword_4F5BF4_xs[i] >= a4a) {
5524  if (dword_4F5BF4_xs[i + 2] >= a4a &&
5525  dword_4F5BF4_xs[i + 1] >= a4a) {
5526  ++a5a;
5527  } else {
5528  // v23 = (__int64)(dword_4F5BF4_xs[i + 2] -
5529  // dword_4F5BF4_xs[i + 1]) << 16;
5530  __int64 _a =
5531  dword_4F5B24_ys[i + 2] - dword_4F5B24_ys[i + 1];
5532  __int64 _b = (__int64)(a3 - dword_4F5B24_ys[i + 1]) << 16;
5533 
5534  if (dword_4F5BF4_xs[i + 1] +
5535  ((((((__int64)(dword_4F5BF4_xs[i + 2] -
5536  dword_4F5BF4_xs[i + 1])
5537  << 16) /
5538  _a * _b) >>
5539  16) +
5540  0x8000) >>
5541  16) >=
5542  a4a)
5543  ++a5a;
5544  }
5545  }
5546  }
5547  }
5548 
5549  if (a5a != 1) return false;
5550  return true;
5551 }
5552 
5553 //----- (0049B04D) --------------------------------------------------------
5555  Vec3_float_ OutPlaneNorm;
5556  float OutPlaneDist;
5557 
5558  OutPlaneNorm.x = 0.0;
5559  OutPlaneNorm.y = 0.0;
5560  OutPlaneNorm.z = 0.0;
5561  GetFacePlane(a2, a3, &OutPlaneNorm, &OutPlaneDist);
5562 
5563  if (fabsf(a2->pFacePlane.vNormal.z) < 1e-6f)
5565  else if (fabsf(a2->pFacePlane.vNormal.x) < 1e-6f &&
5566  fabsf(a2->pFacePlane.vNormal.y) < 1e-6f)
5568  else
5570 
5571  face_plane.vNormal.x = OutPlaneNorm.x;
5572  face_plane.vNormal.y = OutPlaneNorm.y;
5573  face_plane.vNormal.z = OutPlaneNorm.z;
5574  face_plane.dist = OutPlaneDist;
5575 }
5576 
5577 //----- (0049B0C9) --------------------------------------------------------
5578 void stru154::ClassifyPolygon(Vec3_float_ *pNormal, float dist) {
5579  if (fabsf(pNormal->z) < 1e-6f)
5581  else if (fabsf(pNormal->x) < 1e-6f && fabsf(pNormal->y) < 1e-6f)
5583  else
5585 
5586  face_plane.vNormal.x = pNormal->x;
5587  face_plane.dist = dist;
5588  face_plane.vNormal.y = pNormal->y;
5589  face_plane.vNormal.z = pNormal->z;
5590 }
5591 
5592 //----- (0049B13D) --------------------------------------------------------
5594  Vec3_float_ *pOutNormal, float *pOutDist) {
5595  Vec3_float_ *v19; // eax@3
5596  Vec3_float_ v2; // [sp+4h] [bp-64h]@3
5597  float v26; // [sp+1Ch] [bp-4Ch]@3
5598  float v27; // [sp+20h] [bp-48h]@3
5599  float v28; // [sp+24h] [bp-44h]@3
5600  Vec3_float_ v1; // [sp+40h] [bp-28h]@1
5601  Vec3_float_ v38; // [sp+58h] [bp-10h]@3
5602 
5603  v1.x = 0.0;
5604  v1.y = 0.0;
5605  v1.z = 0.0;
5606 
5607  if (pFace->uNumVertices >= 2) {
5608  for (int i = 0; i < pFace->uNumVertices - 2; i++) {
5609  v1.x = pVertices->pVertices[pFace->pVertexIDs[i + 1]].x -
5610  pVertices->pVertices[pFace->pVertexIDs[i]].x;
5611  v1.y = pVertices->pVertices[pFace->pVertexIDs[i + 1]].y -
5612  pVertices->pVertices[pFace->pVertexIDs[i]].y;
5613  v1.z = pVertices->pVertices[pFace->pVertexIDs[i + 1]].z -
5614  pVertices->pVertices[pFace->pVertexIDs[i]].z;
5615 
5616  v26 = pVertices->pVertices[pFace->pVertexIDs[i + 2]].x -
5617  pVertices->pVertices[pFace->pVertexIDs[i + 1]].x;
5618  v27 = pVertices->pVertices[pFace->pVertexIDs[i + 2]].y -
5619  pVertices->pVertices[pFace->pVertexIDs[i + 1]].y;
5620  v28 = pVertices->pVertices[pFace->pVertexIDs[i + 2]].z -
5621  pVertices->pVertices[pFace->pVertexIDs[i + 1]].z;
5622 
5623  v19 = Vec3_float_::Cross(&v1, &v2, v26, v27, v28);
5624  v38.x = v19->x;
5625  v38.y = v19->y;
5626  v38.z = v19->z;
5627  if (v38.x != 0.0 || v38.y != 0.0 || v38.z != 0.0) {
5628  v38.Normalize();
5629 
5630  pOutNormal->x = v38.x;
5631  pOutNormal->y = v38.y;
5632  pOutNormal->z = v38.z;
5633 
5634  *pOutDist =
5635  -(pVertices->pVertices[pFace->pVertexIDs[i]].x * v38.x +
5636  pVertices->pVertices[pFace->pVertexIDs[i]].y * v38.y +
5637  pVertices->pVertices[pFace->pVertexIDs[i]].z * v38.z);
5638  return;
5639  }
5640  }
5641  }
5642 
5643  pOutNormal->x = (double)(pFace->pFacePlane.vNormal.x & 0xFFFF) / 65535.0f +
5644  (double)(pFace->pFacePlane.vNormal.x >> 16);
5645  pOutNormal->y = (double)(pFace->pFacePlane.vNormal.y & 0xFFFF) / 65535.0f +
5646  (double)(pFace->pFacePlane.vNormal.y >> 16);
5647  pOutNormal->z = (double)(pFace->pFacePlane.vNormal.z & 0xFFFF) / 65535.0f +
5648  (double)(pFace->pFacePlane.vNormal.z >> 16);
5649  *pOutDist = (double)(pFace->pFacePlane.dist & 0xFFFF) / 65535.0f +
5650  (double)(pFace->pFacePlane.dist >> 16);
5651 }
5652 
5653 //----- (0043F515) --------------------------------------------------------
5655  for (uint i = 0; i < uNumBillboardsToDraw; ++i) {
5656  if (pBillboardRenderList[i].field_1E & 2 ||
5658  !pBillboardRenderList[i].uIndoorSectorID)
5660  else
5663  }
5664 }
5665 
5666 //----- (0047272C) --------------------------------------------------------
5668  unsigned int *pSectorID,
5669  unsigned int *pFaceID) {
5670  int result; // eax@1
5671 
5672  *pSectorID = pIndoor->GetSector(x - 2, y, z + 40);
5673  result = collide_against_floor(x - 2, y, z + 40, pSectorID, pFaceID);
5674  if (result == -30000 || !*pSectorID) {
5675  *pSectorID = pIndoor->GetSector(x + 2, y, z + 40);
5676  result = collide_against_floor(x + 2, y, z + 40, pSectorID, pFaceID);
5677  if (result == -30000 || !*pSectorID) {
5678  *pSectorID = pIndoor->GetSector(x, y - 2, z + 40);
5679  result =
5680  collide_against_floor(x, y - 2, z + 40, pSectorID, pFaceID);
5681  if (result == -30000 || !*pSectorID) {
5682  *pSectorID = pIndoor->GetSector(x, y + 2, z + 40);
5683  result =
5684  collide_against_floor(x, y + 2, z + 40, pSectorID, pFaceID);
5685  if (result == -30000 || !*pSectorID) {
5686  *pSectorID = pIndoor->GetSector(x, y, z + 140);
5687  result = collide_against_floor(x, y, z + 140, pSectorID,
5688  pFaceID);
5689  }
5690  }
5691  }
5692  }
5693  return result;
5694 }
5695 
5696 //----- (0047050A) --------------------------------------------------------
5698  int v7; // eax@1
5699  signed int result; // eax@4
5700  int v17; // eax@5
5701  int v18; // eax@7
5702  int v21; // eax@9
5703  int v22; // eax@11
5704 
5705  int speed = 1 | integer_sqrt(this->velocity.z * this->velocity.z +
5706  this->velocity.y * this->velocity.y +
5707  this->velocity.x * this->velocity.x);
5708 
5709  this->direction.x = 65536 / speed * this->velocity.x;
5710  this->direction.y = 65536 / speed * this->velocity.y;
5711  this->direction.z = 65536 / speed * this->velocity.z;
5712 
5713  this->speed = speed;
5714  this->inv_speed = 65536 / speed;
5715 
5716  if (dt)
5717  v7 = dt;
5718  else
5720 
5721  // v8 = fixpoint_mul(v7, speed) - this->field_70; // speed * dt - something
5722  this->field_6C = fixpoint_mul(v7, speed) - this->field_70;
5723  if (this->field_6C > 0) {
5724  // v10 = fixpoint_mul(v8, this->direction.x) + this->normal.x;
5725  this->field_4C =
5726  fixpoint_mul(this->field_6C, this->direction.x) + this->normal.x;
5727  this->normal2.x =
5728  fixpoint_mul(this->field_6C, this->direction.x) + this->normal.x;
5729  // v11 = fixpoint_mul(this->field_6C, this->direction.y) +
5730  // this->normal.y;
5731  this->field_50 =
5732  fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y;
5733  this->normal2.y =
5734  fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y;
5735  this->normal2.z =
5736  fixpoint_mul(this->field_6C, this->direction.z) + this->normal.z;
5737  // v12 = this->position.z;
5738  // v13 = this->normal.x;
5739  // v14 = this->normal2.x;
5740  // v15 = this->prolly_normal_d;
5741  // v16 = this->position.z + fixpoint_mul(this->field_6C,
5742  // this->direction.z); v28 = this->position.z +
5743  // fixpoint_mul(this->field_6C, this->direction.z);
5744  this->field_54 =
5745  this->position.z + fixpoint_mul(this->field_6C, this->direction.z);
5746  v17 = this->normal.x;
5747  if (v17 >= this->normal2.x) v17 = this->normal2.x;
5748  this->sMaxX = v17 - this->prolly_normal_d;
5749  v18 = this->prolly_normal_d + this->normal.x;
5750  if (this->normal.x <= this->normal2.x)
5751  v18 = this->prolly_normal_d + this->normal2.x;
5752  // v19 = this->normal.y;
5753  // v20 = this->normal2.y;
5754  this->sMinX = v18;
5755  v21 = this->normal.y;
5756  if (v21 >= this->normal2.y) v21 = this->normal2.y;
5757  this->sMaxY = v21 - this->prolly_normal_d;
5758  v22 = this->prolly_normal_d + this->normal.y;
5759  if (this->normal.y <= this->normal2.y)
5760  v22 = this->normal2.y + this->prolly_normal_d;
5761  // v23 = this->normal2.z;
5762  this->sMinY = v22;
5763  // v24 = this->normal.z;
5764  if (this->normal.z >= this->normal2.z)
5765  this->sMaxZ = this->normal2.z - this->prolly_normal_d;
5766  else
5767  this->sMaxZ = this->normal.z - this->prolly_normal_d;
5768  // this->sMaxZ = v25;
5769  // v26 = this->field_8_radius;
5770  if (this->position.z <=
5771  this->position.z + fixpoint_mul(this->field_6C, this->direction.z))
5772  this->sMinZ = (this->position.z +
5773  fixpoint_mul(this->field_6C, this->direction.z)) +
5774  this->field_8_radius;
5775  else
5776  this->sMinZ = this->position.z + this->field_8_radius;
5777  this->pid = 0;
5778  this->field_80 = -1;
5779  this->field_88 = -1;
5780  // this->sMinZ = v27;
5781  this->field_7C = 0xFFFFFFu;
5782  result = 0;
5783  } else {
5784  result = 1;
5785  }
5786  return result;
5787 }
stru141_actor_collision_object::field_50
int field_50
Definition: Indoor.h:163
BspRenderer
Definition: Indoor.h:800
BLVFace::uPolygonType
PolygonType uPolygonType
Definition: Indoor.h:487
SpriteFrameTable::GetFrameBy_x
SpriteFrame * GetFrameBy_x(unsigned int uSpriteID, signed int a3)
Definition: Sprites.cpp:304
uint16_t
unsigned __int16 uint16_t
Definition: SDL_config.h:37
SpriteObject
Definition: SpriteObject.h:189
PARTY_FLAGS_1_FALLING
@ PARTY_FLAGS_1_FALLING
Definition: Party.h:58
LightsData::pDeltaUV
int pDeltaUV[2]
Definition: Indoor.h:25
BspRenderer_stru0::uViewportY
uint16_t uViewportY
Definition: Indoor.h:778
IndoorCameraD3D::CalcPortalShape
bool CalcPortalShape(struct RenderVertexSoft *a1, unsigned int *pOutNumVertices, struct RenderVertexSoft *pVertices, IndoorCameraD3D_Vec4 *a4, signed int uNumVertices, char a6, int _unused)
Definition: IndoorCameraD3D.cpp:697
BLVFace_MM7::pBounding
struct BBox_short_ pBounding
Definition: LegacyImages.h:56
TE_MOVEMENT
@ TE_MOVEMENT
Definition: TurnEngine.h:22
DecorationDesc_mm6::DontDraw
bool DontDraw()
Definition: DecorationList.h:29
LightsStack_StationaryLight_::uNumLightsActive
unsigned int uNumLightsActive
Definition: Lights.h:65
IndoorLocation
Definition: Indoor.h:576
stru367::_screen_space_y
std::array< int, 60 > _screen_space_y
Definition: stru367.h:14
IndoorLocation::bLoaded
unsigned int bLoaded
Definition: Indoor.h:624
Particle_sw::z
float z
Definition: ParticleEngine.h:22
fWalkSpeedMultiplier
float fWalkSpeedMultiplier
Definition: mm7_data.cpp:706
Vec3_float_
Definition: VectorTypes.h:74
ParticleEngine.h
BLVHeader::uSector_lrdata_Size
unsigned int uSector_lrdata_Size
Definition: Indoor.h:332
TE_ATTACK
@ TE_ATTACK
Definition: TurnEngine.h:21
stru141_actor_collision_object::field_88
int field_88
Definition: Indoor.h:175
BLVFace::Portal
bool Portal() const
Definition: Indoor.h:448
uNumActors
size_t uNumActors
Definition: Actor.cpp:39
DMGT_PHISYCAL
@ DMGT_PHISYCAL
Definition: Items.h:15
Party::vPosition
Vec3_int_ vPosition
Definition: Party.h:250
BLVDoor::Closed
@ Closed
Definition: Indoor.h:380
IndoorLocation::uNumFaceExtras
unsigned int uNumFaceExtras
Definition: Indoor.h:631
BSPModel::pVertices
struct BSPVertexBuffer pVertices
Definition: BSPModel.h:189
IndoorLocation::uNumSectors
int uNumSectors
Definition: Indoor.h:633
sub_407A1C
bool sub_407A1C(int x, int y, int z, Vec3_int_ v)
Definition: Indoor.cpp:3199
face
GLenum GLuint GLint GLenum face
Definition: SDL_opengl_glext.h:3022
pNew_LOD
LOD::WriteableFile * pNew_LOD
Definition: LOD.cpp:24
stru154
Definition: Indoor.h:229
int_get_vector_length
uint32_t int_get_vector_length(int32_t x, int32_t y, int32_t z)
Definition: VectorTypes.cpp:8
IndoorLocation::filename
String filename
Definition: Indoor.h:622
SpriteFrame::hw_sprites
Sprite * hw_sprites[8]
Definition: Sprites.h:46
BspRenderer_PortalViewportData
Definition: Indoor.h:750
array_507D30
RenderVertexSoft array_507D30[50]
Definition: RenderOpenGL.cpp:58
pLevelDecorations
std::array< LevelDecoration, 3000 > pLevelDecorations
Definition: Decoration.cpp:8
stru193_math::uIntegerDoublePi
static const unsigned int uIntegerDoublePi
Definition: OurMath.h:90
BLV_UpdateDoors
void BLV_UpdateDoors()
Definition: Indoor.cpp:1506
DecorationDesc_mm6::uFlags
int16_t uFlags
Definition: DecorationList.h:44
RenderBillboard::hwsprite
Sprite * hwsprite
Definition: IRender.h:32
Party::uFallSpeed
int uFallSpeed
Definition: Party.h:259
uSpeakingCharacter
int uSpeakingCharacter
Definition: mm7_data.cpp:764
BspRenderer::uNumVisibleNotEmptySectors
unsigned int uNumVisibleNotEmptySectors
Definition: Indoor.h:818
Dying
@ Dying
Definition: Actor.h:79
BLVDoor::pZOffsets
uint16_t * pZOffsets
Definition: Indoor.h:400
int16_t
signed __int16 int16_t
Definition: SDL_config.h:36
BLVFace_MM7::uPolygonType
uint8_t uPolygonType
Definition: LegacyImages.h:57
Viewport.h
Particle_sw::b
float b
Definition: ParticleEngine.h:25
ODMFace::zCalc1
int zCalc1
Definition: BSPModel.h:132
BLVFace::uNumVertices
uint8_t uNumVertices
Definition: Indoor.h:488
Timer::uTimeElapsed
unsigned int uTimeElapsed
Definition: Time.h:133
stru141_actor_collision_object
Definition: Indoor.h:148
TrailParticleGenerator::UpdateParticles
void UpdateParticles()
Definition: ParticleEngine.cpp:37
SpriteObject::uFacing
unsigned __int16 uFacing
Definition: SpriteObject.h:220
Party::field_24
int field_24
Definition: Party.h:245
BLVFace_MM7::zCalc1
int zCalc1
Definition: LegacyImages.h:42
v
const GLdouble * v
Definition: SDL_opengl.h:2064
BLVFaceExtra
Definition: Indoor.h:496
BLVFaceExtra::HasEventint
bool HasEventint()
Definition: Indoor.cpp:1483
MapStats::pInfos
MapInfo pInfos[77]
Definition: MapInfo.h:79
stru141_actor_collision_object::field_6C
int field_6C
Definition: Indoor.h:168
BLVSector::pCeilings
uint16_t * pCeilings
Definition: Indoor.h:532
LOD.h
Image::GetHeight
unsigned int GetHeight()
Definition: Image.cpp:230
BLVDoor::pDeltaVs
int16_t * pDeltaVs
Definition: Indoor.h:397
ODMFace::pYInterceptDisplacements
int16_t pYInterceptDisplacements[20]
Definition: BSPModel.h:140
DecorationList::GetDecoration
DecorationDesc * GetDecoration(unsigned int index)
Definition: DecorationList.h:65
Party::GetPlayingTime
GameTime & GetPlayingTime()
Definition: Party.h:230
RenderBillboard::screen_space_x
int16_t screen_space_x
Definition: IRender.h:39
EVENT_Exit
@ EVENT_Exit
Definition: Events.h:61
TextureFrameTable::FindTextureByName
int FindTextureByName(const char *Str2)
Definition: Image.cpp:136
stru193_math::uDoublePiMask
static const unsigned int uDoublePiMask
Definition: OurMath.h:91
fixed::Raw
static fixed Raw(int value)
Definition: OurMath.h:31
Actor::AI_StandOrBored
static void AI_StandOrBored(unsigned int uActorID, signed int uObjID, int uActionLength, struct AIDirection *a4)
Definition: Actor.cpp:1100
GameTime::GetDays
int GetDays() const
Definition: Time.h:32
BLVFace::pFacePlane_old
struct Plane_int_ pFacePlane_old
Definition: Indoor.h:471
PARTY_StrafeLeft
@ PARTY_StrafeLeft
Definition: Party.h:98
Lights
LightsData Lights
Definition: Indoor.cpp:54
PrepareToLoadBLV
void PrepareToLoadBLV(unsigned int bLoading)
Definition: Indoor.cpp:2310
Vec2::x
T x
Definition: VectorTypes.h:12
TeleportToStartingPoint
void TeleportToStartingPoint(MapStartPoint point)
Definition: MapInfo.cpp:308
SpriteFrame::uGlowRadius
int uGlowRadius
Definition: Sprites.h:49
DecorationList.h
fTurnSpeedMultiplier
float fTurnSpeedMultiplier
Definition: mm7_data.cpp:708
pTextureFrameTable
struct TextureFrameTable * pTextureFrameTable
Definition: Image.cpp:20
_4E6BDC_loc_names
std::array< const char *, 11 > _4E6BDC_loc_names
Definition: Indoor.cpp:69
SpriteFrame::icon_name
String icon_name
Definition: Sprites.h:43
BspRenderer::num_faces
unsigned int num_faces
Definition: Indoor.h:812
SPEECH_63
@ SPEECH_63
Definition: Player.h:109
stru337
Definition: Indoor.h:200
BSPModel::vPosition
Vec3_int_ vPosition
Definition: BSPModel.h:173
pSpriteFrameTable
struct SpriteFrameTable * pSpriteFrameTable
Definition: Sprites.cpp:22
BspRenderer_PortalViewportData::viewport_right_side
int16_t viewport_right_side[480]
Definition: Indoor.h:760
IndoorLocation::pSectors
struct BLVSector * pSectors
Definition: Indoor.h:634
BLVSector::pWalls
uint16_t * pWalls
Definition: Indoor.h:529
CHARACTER_EXPRESSION_SCARED
@ CHARACTER_EXPRESSION_SCARED
Definition: Player.h:385
OutdoorLocation::pBModels
BSPModelList pBModels
Definition: Outdoor.h:119
pSpriteObjects
std::array< SpriteObject, MAX_SPRITE_OBJECTS > pSpriteObjects
Definition: SpriteObject.cpp:34
BLVFace_MM7::zCalc3
int zCalc3
Definition: LegacyImages.h:44
BspRenderer_stru0::PortalScreenData
BspRenderer_PortalViewportData PortalScreenData
Definition: Indoor.h:782
stru141_actor_collision_object::speed
int speed
Definition: Indoor.h:166
PARTY_LookDown
@ PARTY_LookDown
Definition: Party.h:103
IndoorLocation::ExecDraw
void ExecDraw(bool bD3D)
Definition: Indoor.cpp:235
BLVFace::pVertexIDs
uint16_t * pVertexIDs
Definition: Indoor.h:476
stru141_actor_collision_object::sMaxZ
int sMaxZ
Definition: Indoor.h:180
BLVDoor::pFaceIDs
uint16_t * pFaceIDs
Definition: Indoor.h:394
PARTY_FLAGS_1_BURNING
@ PARTY_FLAGS_1_BURNING
Definition: Party.h:63
RenderBillboard::uIndoorSectorID
int16_t uIndoorSectorID
Definition: IRender.h:34
LightmapBuilder::ApplyLights_IndoorFace
bool ApplyLights_IndoorFace(unsigned int uFaceID)
Definition: LightmapBuilder.cpp:261
DecorationDesc::uColoredLightRed
uint8_t uColoredLightRed
Definition: DecorationList.h:50
BSPNode::uCoplanarOffset
int16_t uCoplanarOffset
Definition: BSPModel.h:45
OBJECT_Item
@ OBJECT_Item
Definition: Actor.h:66
ai_arrays_size
int ai_arrays_size
Definition: mm7_data.cpp:503
Vec3_float_::x
float x
Definition: VectorTypes.h:89
uNumBillboardsToDraw
unsigned int uNumBillboardsToDraw
Definition: RenderOpenGL.cpp:55
ItemsTable::SetSpecialBonus
void SetSpecialBonus(ItemGen *pItem)
Definition: Items.cpp:472
stru141_actor_collision_object::uSectorID
unsigned int uSectorID
Definition: Indoor.h:170
BLVRenderParams::field_84
int field_84
Definition: Indoor.h:708
Party::sRotationX
int sRotationX
Definition: Party.h:252
BLVSector::pMarkers
uint16_t * pMarkers
Definition: Indoor.h:553
DecalBuilder::ApplyBloodsplatDecals_IndoorFace
bool ApplyBloodsplatDecals_IndoorFace(unsigned int uFaceID)
Definition: DecalBuilder.cpp:325
IndoorLocation::pSpawnPoints
struct SpawnPointMM7 * pSpawnPoints
Definition: Indoor.h:647
collide_against_floor_approximate
int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID)
Definition: Indoor.cpp:5667
LegacyImages.h
BspRenderer::AddFaceToRenderList_d3d
void AddFaceToRenderList_d3d(unsigned int node_id, unsigned int uFaceID)
Definition: Indoor.cpp:584
BLVRenderParams::field_0_timer_
int field_0_timer_
Definition: Indoor.h:675
_4E94D3_light_type
char _4E94D3_light_type
Definition: mm7_data.cpp:307
z
GLdouble GLdouble z
Definition: SDL_opengl_glext.h:407
BLVRenderParams::Reset
void Reset()
Definition: Indoor.cpp:163
FindBillboardsLightLevels_BLV
void FindBillboardsLightLevels_BLV()
Definition: Indoor.cpp:5654
pBLVRenderParams
BLVRenderParams * pBLVRenderParams
Definition: Indoor.cpp:50
Party::FeatherFallActive
bool FeatherFallActive()
Definition: Party.h:214
PlayerSpeechID
enum PlayerSpeech PlayerSpeechID
Definition: Player.cpp:48
RenderVertexSoft::u
float u
Definition: IRender.h:121
fixpoint_div
__int64 fixpoint_div(int a1, int a2)
Definition: OurMath.cpp:147
MapStats::GetMapInfo
MAP_TYPE GetMapInfo(const String &Str2)
Definition: MapInfo.cpp:225
GameUI_StatusBar_NothingHere
void GameUI_StatusBar_NothingHere()
Definition: UIStatusBar.cpp:57
BLVFace_MM7::pFacePlane
struct Plane_float_ pFacePlane
Definition: LegacyImages.h:40
DECORATION_DESC_DONT_DRAW
@ DECORATION_DESC_DONT_DRAW
Definition: DecorationList.h:11
Actor
Definition: Actor.h:151
BLVSector::pFluids
uint16_t * pFluids
Definition: Indoor.h:535
SpriteObject::uSectorID
__int16 uSectorID
Definition: SpriteObject.h:223
Party::TorchLightLastIntensity
float TorchLightLastIntensity
Definition: Party.h:328
AudioPlayer::PlaySound
void PlaySound(SoundID eSoundID, int pid, unsigned int uNumRepeats, int x, int y, int a7)
Definition: AudioPlayer.cpp:195
BspRenderer_stru0::pPortalBounding
RenderVertexSoft pPortalBounding[4]
Definition: Indoor.h:787
IndoorLocation::stru1
LocationTime_stru1 stru1
Definition: Indoor.h:649
BLVMapOutlines::uNumOutlines
int uNumOutlines
Definition: Indoor.h:569
POLYGON_InBetweenFloorAndWall
@ POLYGON_InBetweenFloorAndWall
Definition: Indoor.h:221
BBox_short_::x1
int16_t x1
Definition: VectorTypes.h:114
SpriteObject.h
MonsterInfo::Hostility_Friendly
@ Hostility_Friendly
Definition: Monsters.h:111
BLVFace::pXInterceptDisplacements
int16_t * pXInterceptDisplacements
Definition: Indoor.h:477
engine
std::shared_ptr< Engine > engine
Definition: Engine.cpp:130
IndoorLocation::pFaceExtras
struct BLVFaceExtra * pFaceExtras
Definition: Indoor.h:632
SpriteFrame::scale
fixed scale
Definition: Sprites.h:47
DecorationInteraction
void DecorationInteraction(unsigned int id, unsigned int pid)
Definition: Viewport.cpp:271
Texture
Definition: Texture.h:4
stru193_math::uIntegerHalfPi
static const unsigned int uIntegerHalfPi
Definition: OurMath.h:89
BSPVertexBuffer
Definition: BSPModel.h:51
RenderBillboard::dimming_level
uint16_t dimming_level
Definition: IRender.h:43
BLVFaceExtra::uEventID
uint16_t uEventID
Definition: Indoor.h:512
BSPModel::sBoundingRadius
int32_t sBoundingRadius
Definition: BSPModel.h:187
Actor::AI_FaceObject
static void AI_FaceObject(unsigned int uActorID, unsigned int uObjID, int UNUSED, struct AIDirection *Dir_In)
Definition: Actor.cpp:1072
ViewingParams::draw_d3d_outlines
int draw_d3d_outlines
Definition: Viewport.h:78
bNoNPCHiring
char bNoNPCHiring
Definition: mm7_data.cpp:720
BLVDoor::uMoveLength
int uMoveLength
Definition: Indoor.h:390
ODMFace::zCalc3
int zCalc3
Definition: BSPModel.h:134
BLVFace::FromODM
void FromODM(struct ODMFace *face)
Definition: Indoor.cpp:372
LOD::File::DoesContainerExist
bool DoesContainerExist(const String &filename)
Definition: LOD.cpp:833
BLVDoor::Opening
@ Opening
Definition: Indoor.h:381
BLVFace_MM7::uSectorID
uint16_t uSectorID
Definition: LegacyImages.h:54
Party::FlyActive
bool FlyActive()
Definition: Party.h:202
BspRenderer_stru0::uSectorID
uint16_t uSectorID
Definition: Indoor.h:776
BLVRenderParams::field_8C
int field_8C
Definition: Indoor.h:710
LEVEL_null
@ LEVEL_null
Definition: Indoor.h:285
Overlays.h
Vec3_float_::Cross
static Vec3_float_ * Cross(Vec3_float_ *v1, Vec3_float_ *pOut, float x, float y, float z)
Definition: VectorTypes.h:77
stru_F8A590
BspRenderer_PortalViewportData stru_F8A590
Definition: Indoor.cpp:56
Viewport::uScreen_TL_X
int uScreen_TL_X
Definition: Viewport.h:18
BLVSector::uNumFluids
uint16_t uNumFluids
Definition: Indoor.h:533
SPEECH_46
@ SPEECH_46
Definition: Player.h:92
PARTY_WalkForward
@ PARTY_WalkForward
Definition: Party.h:100
ObjectList::ObjectIDByItemID
unsigned int ObjectIDByItemID(unsigned int uItemID)
Definition: ObjectList.cpp:7
BBox_short_::y1
int16_t y1
Definition: VectorTypes.h:116
PaletteManager.h
LightmapBuilder.h
RenderBillboard::screen_space_z
int16_t screen_space_z
Definition: IRender.h:41
UpdateObjects
void UpdateObjects()
Definition: Render.cpp:4955
Party::flt_TorchlightColorR
float flt_TorchlightColorR
Definition: Party.h:325
BLVSector::uNumNonBSPFaces
uint16_t uNumNonBSPFaces
Definition: Indoor.h:540
stru141_actor_collision_object::normal
Vec3_int_ normal
Definition: Indoor.h:159
_evt_raw::_e_type
unsigned char _e_type
Definition: Events.h:26
BLVDoor::uOpenSpeed
int uOpenSpeed
Definition: Indoor.h:391
Party::pPlayers
std::array< Player, 4 > pPlayers
Definition: Party.h:310
BSPNode::uBack
int16_t uBack
Definition: BSPModel.h:44
RenderBillboard::world_z
int16_t world_z
Definition: IRender.h:38
RenderBillboard::fov_y
float fov_y
Definition: IRender.h:30
Sprite::uBufferHeight
int uBufferHeight
Definition: Sprites.h:32
BLVFace_MM7::pZInterceptDisplacements
int16_t * pZInterceptDisplacements
Definition: LegacyImages.h:49
fixpoint_from_int
int fixpoint_from_int(int lhv, int rhv)
Definition: OurMath.cpp:161
SpriteFrame::uPaletteIndex
int uPaletteIndex
Definition: Sprites.h:51
SpawnPointMM7
Definition: Indoor.h:304
stru9.h
ODMFace::uPolygonType
uint8_t uPolygonType
Definition: BSPModel.h:156
SpriteObject::uType
SPRITE_OBJECT_TYPE uType
Definition: SpriteObject.h:215
ACTOR_BUFF_SLOWED
@ ACTOR_BUFF_SLOWED
Definition: Actor.h:45
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:734
IndoorCameraD3D_Vec4
Definition: IndoorCameraD3D.h:32
SpellFxRenderer.h
BLVFace::ToggleIsTextureFrameTable
void ToggleIsTextureFrameTable()
Definition: Indoor.h:464
stru367::direction
bool direction
Definition: stru367.h:9
Particle_sw::r
float r
Definition: ParticleEngine.h:23
BLVDoor::uNumFaces
uint16_t uNumFaces
Definition: Indoor.h:402
IndoorLocation::uNumNodes
unsigned int uNumNodes
Definition: Indoor.h:639
POLYGON_Floor
@ POLYGON_Floor
Definition: Indoor.h:220
sub_4077F1
bool sub_4077F1(int a1, int a2, int a3, ODMFace *face, BSPVertexBuffer *a5)
Definition: Indoor.cpp:5486
IndoorLocation::pLights
struct BLVLightMM7 * pLights
Definition: Indoor.h:636
OBJECT_Decoration
@ OBJECT_Decoration
Definition: Actor.h:69
stru10.h
BLVFaceExtra::uAdditionalBitmapID
uint16_t uAdditionalBitmapID
Definition: Indoor.h:506
IndoorLocation::spell_fx_renderer
SpellFxRenderer * spell_fx_renderer
Definition: Indoor.h:655
BSPNode
Definition: BSPModel.h:42
Sprite::texture
Texture * texture
Definition: Sprites.h:28
BLVFace::IsTextureFrameTable
bool IsTextureFrameTable() const
Definition: Indoor.h:461
SOUND_RunWaterIndoor
@ SOUND_RunWaterIndoor
Definition: AudioPlayer.h:32
RenderBillboard::pSpriteFrame
SpriteFrame * pSpriteFrame
Definition: IRender.h:45
Vec3_float_::y
float y
Definition: VectorTypes.h:90
stru154::ClassifyPolygon
void ClassifyPolygon(struct Vec3_float_ *pNormal, float dist)
Definition: Indoor.cpp:5578
Vec3_float_::z
float z
Definition: VectorTypes.h:91
pPlayers
NZIArray< struct Player *, 5 > pPlayers
Definition: Player.cpp:46
x1
GLuint GLfloat GLfloat GLfloat x1
Definition: SDL_opengl_glext.h:8586
IndoorCameraD3D::ViewTransfrom_OffsetUV
void ViewTransfrom_OffsetUV(struct RenderVertexSoft *pVertices, unsigned int uNumVertices, struct RenderVertexSoft *pOutVertices, struct LightsData *a5)
Definition: IndoorCameraD3D.cpp:69
BLVMapOutline
Definition: Indoor.h:412
BLVHeader::uDoors_ddata_Size
unsigned int uDoors_ddata_Size
Definition: Indoor.h:333
DecorationList::GetDecorIdByName
uint16_t GetDecorIdByName(const char *pName)
Definition: DecorationList.cpp:60
TurnEngine.h
IndoorLocation::pLFaces
uint16_t * pLFaces
Definition: Indoor.h:642
SpriteObject::uSpriteFrameID
unsigned __int16 uSpriteFrameID
Definition: SpriteObject.h:224
BLVFace::Indoor_sky
bool Indoor_sky() const
Definition: Indoor.h:450
BBox_short_::z2
int16_t z2
Definition: VectorTypes.h:119
stru141_actor_collision_object::inv_speed
int inv_speed
Definition: Indoor.h:167
BLVRenderParams::bsp_fov_rad
int bsp_fov_rad
Definition: Indoor.h:692
pIndoor
IndoorLocation * pIndoor
Definition: Indoor.cpp:49
Actor::_46DF1A_collide_against_actor
static bool _46DF1A_collide_against_actor(int a1, int a2)
Definition: Actor.cpp:2699
BLVSector::pLights
uint16_t * pLights
Definition: Indoor.h:556
Chest.h
stru367::_screen_space_x
std::array< int, 60 > _screen_space_x
Definition: stru367.h:15
Engine.h
current_screen_type
enum CURRENT_SCREEN current_screen_type
Definition: GUIWindow.cpp:83
Lights.h
collide_against_floor
int collide_against_floor(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID)
Definition: Render.cpp:4711
Vec3_float_::Normalize
void Normalize()
Definition: VectorTypes.cpp:22
PARTY_BUFF_TORCHLIGHT
@ PARTY_BUFF_TORCHLIGHT
Definition: Party.h:87
Plane_float_::vNormal
struct Vec3_float_ vNormal
Definition: VectorTypes.h:136
UpdateActors_BLV
void UpdateActors_BLV()
Definition: Indoor.cpp:1718
Plane_int_::vNormal
Vec3_int_ vNormal
Definition: VectorTypes.h:107
pTurnEngine
struct stru262_TurnBased * pTurnEngine
Definition: TurnEngine.cpp:21
stru154::GetFacePlane
void GetFacePlane(struct ODMFace *pFace, struct BSPVertexBuffer *pVertices, struct Vec3_float_ *pOutNormal, float *pOutDist)
Definition: Indoor.cpp:5593
BLVSector::uNumWalls
uint16_t uNumWalls
Definition: Indoor.h:527
BspFace::uNodeID
uint16_t uNodeID
Definition: Indoor.h:794
Dead
@ Dead
Definition: Actor.h:80
SOUND_WalkWaterIndoor
@ SOUND_WalkWaterIndoor
Definition: AudioPlayer.h:54
Resurrected
@ Resurrected
Definition: Actor.h:91
ACTOR_BUFF_SHRINK
@ ACTOR_BUFF_SHRINK
Definition: Actor.h:41
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9435
pMapStats
struct MapStats * pMapStats
Definition: mm7_data.cpp:20
SpriteObject::uObjectDescID
unsigned __int16 uObjectDescID
Definition: SpriteObject.h:217
AIDirection
Definition: Actor.h:126
IndoorLocation::GetLocationIndex
static unsigned int GetLocationIndex(const char *Str1)
Definition: Indoor.cpp:839
Party::pPartyBuffs
std::array< SpellBuff, 20 > pPartyBuffs
Definition: Party.h:309
AudioPlayer::StopAll
void StopAll(int sample_id)
Definition: AudioPlayer.cpp:189
OBJECT_Actor
@ OBJECT_Actor
Definition: Actor.h:67
RenderBillboard::field_1E
int16_t field_1E
Definition: IRender.h:35
BLVSector::uNumFloors
uint16_t uNumFloors
Definition: Indoor.h:524
Events.h
Party::uFallStartY
int uFallStartY
Definition: Party.h:265
trail_particle_generator
TrailParticleGenerator trail_particle_generator
Definition: ParticleEngine.cpp:13
IndoorLocation::lightmap_builder
LightmapBuilder * lightmap_builder
Definition: Indoor.h:656
BLVRenderParams::uViewportZ
unsigned int uViewportZ
Definition: Indoor.h:698
fixed::FromInt
static fixed FromInt(int value)
Definition: OurMath.h:29
Party::uPartyHeight
unsigned int uPartyHeight
Definition: Party.h:237
Actor.h
ODMFace::pBoundingBox
struct BBox_short_ pBoundingBox
Definition: BSPModel.h:145
BLVFace_MM7::zCalc2
int zCalc2
Definition: LegacyImages.h:43
IndoorLocation::uNumDoors
int uNumDoors
Definition: Indoor.h:637
_4E94D0_light_type
char _4E94D0_light_type
Definition: mm7_data.cpp:305
pItemsTable
struct ItemsTable * pItemsTable
Definition: Items.cpp:37
Viewport::uScreen_TL_Y
int uScreen_TL_Y
Definition: Viewport.h:19
Particle_sw::type
unsigned int type
Definition: ParticleEngine.h:19
PARTY_FLAGS_1_LANDING
@ PARTY_FLAGS_1_LANDING
Definition: Party.h:62
GetAlertStatus
int GetAlertStatus()
Definition: Indoor.cpp:5287
MapInfo::SpawnRandomTreasure
int SpawnRandomTreasure(struct SpawnPointMM7 *a2)
Definition: MapInfo.cpp:240
EVENT_MouseOver
@ EVENT_MouseOver
Definition: Events.h:64
pVertices
struct RenderVertexD3D3 pVertices[50]
Definition: Render.cpp:50
OtherOverlayList::pOverlays
OtherOverlay pOverlays[50]
Definition: Overlays.h:36
y
EGLSurface EGLint EGLint y
Definition: SDL_egl.h:1596
DecalBuilder::Reset
void Reset(bool bPreserveBloodsplats)
Definition: DecalBuilder.cpp:58
Image::GetWidth
unsigned int GetWidth()
Definition: Image.cpp:217
IndoorLocation::Load
bool Load(const String &filename, int num_days_played, int respawn_interval_days, char *pDest)
Definition: Indoor.cpp:858
Viewport::uScreen_BR_Y
int uScreen_BR_Y
Definition: Viewport.h:21
PARTY_LookUp
@ PARTY_LookUp
Definition: Party.h:102
Door_switch_animation
void Door_switch_animation(unsigned int uDoorID, int a2)
Definition: Indoor.cpp:5183
BspRenderer_stru0::uViewportW
uint16_t uViewportW
Definition: Indoor.h:780
IndoorCameraD3D::vPartyPos
Vec3< int > vPartyPos
Definition: IndoorCameraD3D.h:253
BLV_UpdateUserInputAndOther
void BLV_UpdateUserInputAndOther()
Definition: Indoor.cpp:3779
BLVFace::Ethereal
bool Ethereal() const
Definition: Indoor.h:459
BLVSector::pBounding
BBox_short_ pBounding
Definition: Indoor.h:563
CURRENT_SCREEN::SCREEN_BRANCHLESS_NPC_DIALOG
@ SCREEN_BRANCHLESS_NPC_DIALOG
Plane_float_::dist
float dist
Definition: VectorTypes.h:137
sub_450521_ProllyDropItemAt
int sub_450521_ProllyDropItemAt(int ecx0, int a2, int a3, int a4, int a5, uint16_t a6)
Definition: Indoor.cpp:5409
AddBspNodeToRenderList
void AddBspNodeToRenderList(unsigned int node_id)
Definition: Indoor.cpp:2970
Vec2::y
T y
Definition: VectorTypes.h:13
BLVSector::pFaceIDs
uint16_t * pFaceIDs
Definition: Indoor.h:541
BLVDoor::pDeltaUs
int16_t * pDeltaUs
Definition: Indoor.h:396
BLVFace_MM7
Definition: LegacyImages.h:39
BspRenderer_PortalViewportData::_viewport_space_y
int _viewport_space_y
Definition: Indoor.h:753
stru141_actor_collision_object::field_0
int field_0
Definition: Indoor.h:151
stru367.h
SpriteObject::vPosition
struct Vec3_int_ vPosition
Definition: SpriteObject.h:218
DDM_DLV_Header::field_C_alert
int field_C_alert
Definition: Indoor.h:97
pParty
Party * pParty
Definition: Party.cpp:30
DDM_DLV_Header::uNumFacesInBModels
unsigned int uNumFacesInBModels
Definition: Indoor.h:98
IndoorLocation::log
Log * log
Definition: Indoor.h:653
RenderBillboard::fov_x
float fov_x
Definition: IRender.h:29
DDM_DLV_Header::uNumRespawns
int uNumRespawns
Definition: Indoor.h:94
flt_6BE3AC_debug_recmod1_x_1_6
float flt_6BE3AC_debug_recmod1_x_1_6
Definition: mm7_data.cpp:718
_46ED8A_collide_against_sprite_objects
void _46ED8A_collide_against_sprite_objects(unsigned int _this)
Definition: Render.cpp:4732
BLVDoor::pXOffsets
uint16_t * pXOffsets
Definition: Indoor.h:398
ODMFace::pVertexIDs
uint16_t pVertexIDs[20]
Definition: BSPModel.h:136
BspRenderer_PortalViewportData::_viewport_space_z
int _viewport_space_z
Definition: Indoor.h:756
IndoorLocation::uNumVertices
unsigned int uNumVertices
Definition: Indoor.h:627
IndoorLocation::pNodes
struct BSPNode * pNodes
Definition: Indoor.h:640
BspRenderer_stru0::uFaceID
uint16_t uFaceID
Definition: Indoor.h:783
IndoorLocation::uNumSpawnPoints
unsigned int uNumSpawnPoints
Definition: Indoor.h:646
stru141_actor_collision_object::field_8_radius
int field_8_radius
Definition: Indoor.h:153
BLVFace::zCalc3
int zCalc3
Definition: Indoor.h:474
BLVRenderParams::uViewportW
unsigned int uViewportW
Definition: Indoor.h:699
stru141_actor_collision_object::sMinY
int sMinY
Definition: Indoor.h:179
LEVEL_DECORATION_INVISIBLE
@ LEVEL_DECORATION_INVISIBLE
Definition: Decoration.h:14
RenderBillboard::uPalette
int16_t uPalette
Definition: IRender.h:33
BspRenderer::nodes
BspRenderer_stru0 nodes[150]
Definition: Indoor.h:817
Party::bFlying
unsigned int bFlying
Definition: Party.h:266
Party::flt_TorchlightColorB
float flt_TorchlightColorB
Definition: Party.h:327
LightsData::uCurrentAmbientLightLevel
unsigned int uCurrentAmbientLightLevel
Definition: Indoor.h:21
RenderBillboard::object_pid
uint16_t object_pid
Definition: IRender.h:42
ACTOR_BUFF_PARALYZED
@ ACTOR_BUFF_PARALYZED
Definition: Actor.h:44
GetGravityStrength
unsigned int GetGravityStrength()
Definition: Engine.cpp:1500
BspFace::uFaceID
uint16_t uFaceID
Definition: Indoor.h:793
ODMFace::pXInterceptDisplacements
int16_t pXInterceptDisplacements[20]
Definition: BSPModel.h:139
ACTOR_BUFF_MASS_DISTORTION
@ ACTOR_BUFF_MASS_DISTORTION
Definition: Actor.h:48
BLVHeader
Definition: Indoor.h:328
stru141_actor_collision_object::normal2
Vec3_int_ normal2
Definition: Indoor.h:161
ITEM_ARTIFACT_LADYS_ESCORT
@ ITEM_ARTIFACT_LADYS_ESCORT
Definition: Items.h:189
ZlibWrapper.h
ITEM_ARTIFACT_HERMES_SANDALS
@ ITEM_ARTIFACT_HERMES_SANDALS
Definition: Items.h:182
OBJECT_BModel
@ OBJECT_BModel
Definition: Actor.h:70
BLVFace::SetTexture
void SetTexture(const String &filename)
Definition: Indoor.cpp:746
BLVFace::pZInterceptDisplacements
int16_t * pZInterceptDisplacements
Definition: Indoor.h:479
BLVSector::pPortals
uint16_t * pPortals
Definition: Indoor.h:538
x
EGLSurface EGLint x
Definition: SDL_egl.h:1596
BspRenderer_stru0::uViewportX
uint16_t uViewportX
Definition: Indoor.h:777
BLVSector::uNumLights
uint16_t uNumLights
Definition: Indoor.h:554
DecorationDesc_mm6::uLightRadius
int16_t uLightRadius
Definition: DecorationList.h:42
BLVFace_MM7::pFacePlane_old
struct Plane_int_ pFacePlane_old
Definition: LegacyImages.h:41
_43F55F_get_billboard_light_level
int _43F55F_get_billboard_light_level(RenderBillboard *a1, int uBaseLightLevel)
Definition: Render.cpp:4211
stru367::_view_transformed_x
std::array< int, 60 > _view_transformed_x
Definition: stru367.h:11
Particle_sw::timeToLive
int timeToLive
Definition: ParticleEngine.h:27
BLVFace_MM7::pVertexIDs
uint16_t * pVertexIDs
Definition: LegacyImages.h:46
stru141_actor_collision_object::field_7C
int field_7C
Definition: Indoor.h:172
SpriteFrameTable::GetFrame
SpriteFrame * GetFrame(unsigned int uSpriteID, unsigned int uTime)
Definition: Sprites.cpp:277
pGameLoadingUI_ProgressBar
GUIProgressBar * pGameLoadingUI_ProgressBar
Definition: GUIProgressBar.cpp:14
viewparams
struct ViewingParams * viewparams
Definition: mm7_data.cpp:22
ItemsTable::GenerateItem
void GenerateItem(int treasure_level, unsigned int uTreasureType, ItemGen *pItem)
Definition: Items.cpp:680
OS_GetTime
unsigned int OS_GetTime()
Definition: Lin.cpp:12
Disabled
@ Disabled
Definition: Actor.h:94
PARTY_FastTurnRight
@ PARTY_FastTurnRight
Definition: Party.h:114
PlayLevelMusic
void PlayLevelMusic()
Definition: AudioPlayer.cpp:377
pLevelEVT
std::array< char, 9216 > pLevelEVT
Definition: Events.cpp:54
MonsterInfo::uID
uint16_t uID
Definition: Monsters.h:169
BLVFaceExtra::sTextureDeltaV
int16_t sTextureDeltaV
Definition: Indoor.h:510
Vec3
Definition: VectorTypes.h:26
stru367::_view_transformed_y
std::array< int, 60 > _view_transformed_y
Definition: stru367.h:12
BLVDoor
Definition: Indoor.h:378
PARTY_TurnRight
@ PARTY_TurnRight
Definition: Party.h:97
check_event_triggers
void check_event_triggers()
Definition: Events.cpp:1215
BBox_short_::y2
int16_t y2
Definition: VectorTypes.h:117
IndoorLocation::blv
struct BLVHeader blv
Definition: Indoor.h:626
BLVFace::uSectorID
uint16_t uSectorID
Definition: Indoor.h:484
Indoor.h
BLVLightMM7::uAtributes
int16_t uAtributes
Definition: Indoor.h:364
PortalFrustrum
bool PortalFrustrum(int pNumVertices, BspRenderer_PortalViewportData *far_portal, BspRenderer_PortalViewportData *near_portal, int uFaceID)
Definition: Indoor.cpp:3788
Viewport::uScreen_BR_X
int uScreen_BR_X
Definition: Viewport.h:20
BLVFace
Definition: Indoor.h:424
PARTY_CenterView
@ PARTY_CenterView
Definition: Party.h:104
ItemGen::uItemID
int uItemID
Definition: Items.h:326
BLVSector::uFirstBSPNode
int16_t uFirstBSPNode
Definition: Indoor.h:561
IndoorLocation::Draw
void Draw()
Definition: Indoor.cpp:322
PARTY_RunBackward
@ PARTY_RunBackward
Definition: Party.h:112
stru123::_decor_events
std::array< unsigned char, 125 > _decor_events
Definition: stru123.h:8
Timer::dt_in_some_format
int dt_in_some_format
Definition: Time.h:134
IndoorCameraD3D::ViewClip
bool ViewClip(int x, int y, int z, int *transformed_x, int *transformed_y, int *transformed_z, bool dont_show=false)
Definition: IndoorCameraD3D.cpp:172
fixed::_internal
int32_t _internal
Definition: OurMath.h:73
BLVMapOutline::uFlags
uint16_t uFlags
Definition: Indoor.h:418
BspRenderer::faces
BspFace faces[1000]
Definition: Indoor.h:814
v1
GLfloat GLfloat v1
Definition: SDL_opengl_glext.h:694
BLVFace::_get_normals
void _get_normals(Vec3_int_ *a2, Vec3_int_ *a3)
Definition: Indoor.cpp:1422
BLVFace::pVertexVIDs
int16_t * pVertexVIDs
Definition: Indoor.h:481
BLVFace::pFacePlane
struct Plane_float_ pFacePlane
Definition: Indoor.h:470
IndoorLocation::dlv
struct DDM_DLV_Header dlv
Definition: Indoor.h:648
Log::Warning
void Warning(const wchar_t *pFormat,...)
Definition: Log.cpp:28
BLVFace_MM7::uFaceExtraID
uint16_t uFaceExtraID
Definition: LegacyImages.h:52
DDM_DLV_Header::uNumDecorations
unsigned int uNumDecorations
Definition: Indoor.h:99
IndoorLocation::pMapOutlines
BLVMapOutlines * pMapOutlines
Definition: Indoor.h:641
IndoorCameraD3D::Project
void Project(int x, int y, int z, int *screenspace_x, int *screenspace_y)
Definition: IndoorCameraD3D.cpp:1137
LODFile_IconsBitmaps::LoadTexture
unsigned int LoadTexture(const char *pContainer, enum TEXTURE_TYPE uTextureType=TEXTURE_DEFAULT)
Definition: LOD.cpp:1185
stru141_actor_collision_object::field_70
int field_70
Definition: Indoor.h:169
BLVSector::uNumCogs
uint16_t uNumCogs
Definition: Indoor.h:545
DDM_DLV_Header::uLastRepawnDay
int uLastRepawnDay
Definition: Indoor.h:95
BLV_ProcessPartyActions
void BLV_ProcessPartyActions()
Definition: Indoor.cpp:4655
DecalBuilder::ApplyDecals
char ApplyDecals(int light_level, char a3, struct stru154 *a4, int a5, struct RenderVertexSoft *a6, struct IndoorCameraD3D_Vec4 *a7, char a8, unsigned int uSectorID)
Definition: DecalBuilder.cpp:67
fixpoint_mul
__int64 fixpoint_mul(int a1, int a2)
Definition: OurMath.cpp:138
stru141_actor_collision_object::height
int height
Definition: Indoor.h:154
pActors
std::array< Actor, 500 > pActors
Definition: Actor.cpp:38
BLVDoor::uState
State uState
Definition: Indoor.h:405
IndoorLocation::PrepareItemsRenderList_BLV
void PrepareItemsRenderList_BLV()
Definition: Indoor.cpp:2871
GUIProgressBar::Reset
void Reset(uint8_t uMaxProgress)
Definition: GUIProgressBar.cpp:78
Particle_sw
Definition: ParticleEngine.h:18
SPEECH_64
@ SPEECH_64
Definition: Player.h:110
BLVRenderParams::field_90
int field_90
Definition: Indoor.h:711
BLVRenderParams::uViewportCenterY
int uViewportCenterY
Definition: Indoor.h:705
uNumLevelDecorations
size_t uNumLevelDecorations
Definition: Decoration.cpp:9
window
EGLSurface EGLNativeWindowType * window
Definition: SDL_egl.h:1580
stru_F81018
stru337 stru_F81018
Definition: Indoor.cpp:55
BLVRenderParams::uViewportX
unsigned int uViewportX
Definition: Indoor.h:696
ActionQueue::Next
PartyAction Next()
Definition: Party.cpp:1204
Party::uFlags
unsigned int uFlags
Definition: Party.h:313
PrepareDrawLists_BLV
void PrepareDrawLists_BLV()
Definition: Indoor.cpp:102
f
GLfloat f
Definition: SDL_opengl_glext.h:1873
_46EF01_collision_chech_player
int _46EF01_collision_chech_player(int a1)
Definition: Render.cpp:4790
BLVFace_MM7::pVertexUIDs
int16_t * pVertexUIDs
Definition: LegacyImages.h:50
SpellFxRenderer::_4A806F_get_mass_distortion_value
float _4A806F_get_mass_distortion_value(struct Actor *pActor)
Definition: SpellFxRenderer.cpp:648
BLVFace_MM7::pYInterceptDisplacements
int16_t * pYInterceptDisplacements
Definition: LegacyImages.h:48
BspRenderer::pVisibleSectorIDs_toDrawDecorsActorsEtcFrom
uint16_t pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[6]
Definition: Indoor.h:819
EQUIP_POTION
@ EQUIP_POTION
Definition: Items.h:241
DECORATION_DESC_EMITS_FIRE
@ DECORATION_DESC_EMITS_FIRE
Definition: DecorationList.h:17
BLVFace::zCalc2
int zCalc2
Definition: Indoor.h:473
Party::uWalkSpeed
unsigned int uWalkSpeed
Definition: Party.h:243
DoInteractionWithTopmostZObject
char DoInteractionWithTopmostZObject(int a1, int a2)
Definition: Indoor.cpp:3716
BLVSector::uNumPortals
int16_t uNumPortals
Definition: Indoor.h:536
LEVEL_Outdoor
@ LEVEL_Outdoor
Definition: Indoor.h:287
Particle_sw::y
float y
Definition: ParticleEngine.h:21
DDM_DLV_Header
Definition: Indoor.h:82
Particle_sw::g
float g
Definition: ParticleEngine.h:24
BspRenderer::num_nodes
unsigned int num_nodes
Definition: Indoor.h:816
ODMFace::uNumVertices
uint8_t uNumVertices
Definition: BSPModel.h:155
BspRenderer_stru0
Definition: Indoor.h:767
stru154::GetFacePlaneAndClassify
void GetFacePlaneAndClassify(struct ODMFace *a2, struct BSPVertexBuffer *a3)
Definition: Indoor.cpp:5554
IndoorLocation::uNumFaces
unsigned int uNumFaces
Definition: Indoor.h:629
AssetsManager::GetBitmap
Texture * GetBitmap(const String &name)
Definition: AssetsManager.cpp:126
IndoorLocation::_visible_outlines
char _visible_outlines[875]
Definition: Indoor.h:650
pPartyActionQueue
struct ActionQueue * pPartyActionQueue
Definition: Party.cpp:32
BspRenderer_PortalViewportData::_viewport_space_x
int _viewport_space_x
Definition: Indoor.h:755
BLVSector::pFloors
uint16_t * pFloors
Definition: Indoor.h:526
MapInfo
Definition: MapInfo.h:35
BspRenderer_PortalViewportData::_viewport_z_maxID
int _viewport_z_maxID
Definition: Indoor.h:758
BLVRenderParams::pTargetZBuffer
int * pTargetZBuffer
Definition: Indoor.h:701
pGames_LOD
LOD::File * pGames_LOD
Definition: LOD.cpp:25
TE_WAIT
@ TE_WAIT
Definition: TurnEngine.h:20
LevelDecoration
Definition: Decoration.h:20
pCurrentMapName
String pCurrentMapName
Definition: mm7_data.cpp:712
Removed
@ Removed
Definition: Actor.h:86
BLVFace::Invisible
bool Invisible() const
Definition: Indoor.h:444
PortalFace
stru367 PortalFace
Definition: mm7_data.cpp:564
DecalBuilder::uNumDecals
int uNumDecals
Definition: DecalBuilder.h:164
pPaletteManager
PaletteManager * pPaletteManager
Definition: PaletteManager.cpp:7
BLVDoor::uNumVertices
uint16_t uNumVertices
Definition: Indoor.h:401
stru141_actor_collision_object::sMaxX
int sMaxX
Definition: Indoor.h:176
BLVRenderParams::uNumFacesRenderedThisFrame
unsigned int uNumFacesRenderedThisFrame
Definition: Indoor.h:707
IndoorCameraD3D::fov_y
float fov_y
Definition: IndoorCameraD3D.h:193
pLevelEVT_Index
std::array< EventIndex, 4400 > pLevelEVT_Index
Definition: Events.cpp:55
stru141_actor_collision_object::sMinX
int sMinX
Definition: Indoor.h:177
BLVDoor::pSectorIDs
uint16_t * pSectorIDs
Definition: Indoor.h:395
ParticleEngine::AddParticle
void AddParticle(Particle_sw *a2)
Definition: ParticleEngine.cpp:65
BSPNode::uCoplanarSize
int16_t uCoplanarSize
Definition: BSPModel.h:46
BLVFace::uBackSectorID
int16_t uBackSectorID
Definition: Indoor.h:485
ViewingParams::_443365
void _443365()
Definition: Viewport.cpp:177
BspRenderer_PortalViewportData::_viewport_x_minID
int _viewport_x_minID
Definition: Indoor.h:757
SpriteObject::InitializeSpriteObjects
static void InitializeSpriteObjects()
Definition: SpriteObject.cpp:898
BLVFace::pBounding
struct BBox_short_ pBounding
Definition: Indoor.h:486
pMiscTimer
Timer * pMiscTimer
Definition: Time.cpp:7
stru154::face_plane
Plane_float_ face_plane
Definition: Indoor.h:243
stru141_actor_collision_object::sMaxY
int sMaxY
Definition: Indoor.h:178
t
GLdouble GLdouble t
Definition: SDL_opengl.h:2071
BspRenderer_PortalViewportData::viewport_left_side
int16_t viewport_left_side[480]
Definition: Indoor.h:759
BLVHeader::uFaces_fdata_Size
unsigned int uFaces_fdata_Size
Definition: Indoor.h:330
RenderBillboard::screenspace_projection_factor_y
float screenspace_projection_factor_y
Definition: IRender.h:28
SpellFxRenderer::RenderAsSprite
bool RenderAsSprite(struct SpriteObject *a2)
Definition: SpellFxRenderer.cpp:671
Outdoor.h
BLVSector::pCogs
uint16_t * pCogs
Definition: Indoor.h:547
OutdoorLocation::ddm
struct DDM_DLV_Header ddm
Definition: Outdoor.h:131
blv_prev_party_y
int blv_prev_party_y
Definition: mm7_data.cpp:739
BLVDoor::pVertexIDs
uint16_t * pVertexIDs
Definition: Indoor.h:393
LEVEL_Indoor
@ LEVEL_Indoor
Definition: Indoor.h:286
IndoorCameraD3D::ApplyViewTransform_TrueIfStillVisible_BLV
bool ApplyViewTransform_TrueIfStillVisible_BLV(int x, int y, int z, fixed *pOutX, fixed *pOutZ, fixed *pOutY, bool clip_plane_test)
Definition: IndoorCameraD3D.cpp:88
Plane_int_::dist
int dist
Definition: VectorTypes.h:108
_46E44E_collide_against_faces_and_portals
int _46E44E_collide_against_faces_and_portals(unsigned int b1)
Definition: Render.cpp:4350
BLVRenderParams::bsp_fov_rad_inv
int bsp_fov_rad_inv
Definition: Indoor.h:693
Viewport::field_of_view
int field_of_view
Definition: Viewport.h:30
_6807E0_num_decorations_with_sounds_6807B8
int _6807E0_num_decorations_with_sounds_6807B8
Definition: mm7_data.cpp:686
SpriteObject::Create
int Create(int yaw, int pitch, int a4, int a5)
Definition: SpriteObject.cpp:56
SpriteObject::containing_item
struct ItemGen containing_item
Definition: SpriteObject.h:227
PARTY_TurnLeft
@ PARTY_TurnLeft
Definition: Party.h:96
SOUND_RunCarpet
@ SOUND_RunCarpet
Definition: AudioPlayer.h:23
SPRITE_OBJECT_TYPE
SPRITE_OBJECT_TYPE
Definition: SpriteObject.h:5
RenderBillboard::screen_space_y
int16_t screen_space_y
Definition: IRender.h:40
AudioPlayer.h
OBJECT_Player
@ OBJECT_Player
Definition: Actor.h:68
Party::bTurnBasedModeOn
bool bTurnBasedModeOn
Definition: Party.h:305
pViewport
struct Viewport * pViewport
Definition: mm7_data.cpp:21
Summoned
@ Summoned
Definition: Actor.h:92
BLVRenderParams::uPartySectorID
int uPartySectorID
Definition: Indoor.h:681
PaletteManager::RecalculateAll
void RecalculateAll()
Definition: PaletteManager.cpp:784
BspRenderer_PortalViewportData::GetViewportData
void GetViewportData(int16_t x, int y, int16_t z, int w)
Definition: Indoor.cpp:3181
uNumDecorationsDrawnThisFrame
int uNumDecorationsDrawnThisFrame
Definition: RenderOpenGL.cpp:53
PARTY_BUFF_INVISIBILITY
@ PARTY_BUFF_INVISIBILITY
Definition: Party.h:82
BLVRenderParams::uViewportWidth
int uViewportWidth
Definition: Indoor.h:703
_4D864C_force_sw_render_rules
char _4D864C_force_sw_render_rules
Definition: mm7_data.cpp:208
BLVDoor::vDirection
Vec3_int_ vDirection
Definition: Indoor.h:389
LightsStack_MobileLight_::uNumLightsActive
unsigned int uNumLightsActive
Definition: Lights.h:88
OtherOverlay::field_E
int16_t field_E
Definition: Overlays.h:18
MonsterList::pMonsters
struct MonsterDesc * pMonsters
Definition: Monsters.h:237
BspRenderer_stru0::viewing_portal_id
unsigned int viewing_portal_id
Definition: Indoor.h:785
dword_4F8580
std::array< int, 182 > dword_4F8580
Definition: mm7_data.cpp:506
BLVFace::pYInterceptDisplacements
int16_t * pYInterceptDisplacements
Definition: Indoor.h:478
uNumSpriteObjects
size_t uNumSpriteObjects
Definition: SpriteObject.cpp:33
BLVFace::resource
void * resource
Definition: Indoor.h:483
BLVRenderParams::uTargetWidth
unsigned int uTargetWidth
Definition: Indoor.h:694
SOUND_WalkCarpet
@ SOUND_WalkCarpet
Definition: AudioPlayer.h:45
BLVFace::Pressure_Plate
bool Pressure_Plate() const
Definition: Indoor.h:456
LightsData
Definition: Indoor.h:16
stru367::_view_transformed_z
std::array< int, 48 > _view_transformed_z
Definition: stru367.h:13
LOD::File::LoadCompressed
void * LoadCompressed(const String &pContainer, size_t *data_size=nullptr)
Definition: LOD.cpp:965
ActionQueue::uNumActions
unsigned int uNumActions
Definition: Party.h:128
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1112
BLVRenderParams::field_94
int field_94
Definition: Indoor.h:712
stru193_math::Atan2
unsigned int Atan2(int x, int y)
Definition: OurMath.cpp:46
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
BLVMapOutlines::pOutlines
BLVMapOutline pOutlines[7000]
Definition: Indoor.h:570
pOtherOverlayList
struct OtherOverlayList * pOtherOverlayList
Definition: Overlays.cpp:19
BLVFaceExtra::sTextureDeltaU
int16_t sTextureDeltaU
Definition: Indoor.h:509
sub_4088E9
int sub_4088E9(int x1, int y1, int x2, int y2, int x3, int y3)
Definition: Indoor.cpp:5277
BLVRenderParams::uTargetHeight
unsigned int uTargetHeight
Definition: Indoor.h:695
sub_4406BC
void sub_4406BC(unsigned int node_id, unsigned int uFirstNode)
Definition: Indoor.cpp:2987
stru141_actor_collision_object::field_84
int field_84
Definition: Indoor.h:174
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
RenderBillboard::world_y
int16_t world_y
Definition: IRender.h:37
Party::field_14_radius
int field_14_radius
Definition: Party.h:241
x2
GLfixed GLfixed x2
Definition: SDL_opengl_glext.h:4586
ParticleType_8
@ ParticleType_8
Definition: ParticleEngine.h:9
stru141_actor_collision_object::prolly_normal_d
int prolly_normal_d
Definition: Indoor.h:152
Particle_sw::texture
Texture * texture
Definition: ParticleEngine.h:28
IndoorLocation::ptr_0002B0_sector_rdata
uint16_t * ptr_0002B0_sector_rdata
Definition: Indoor.h:643
IndoorLocation::decal_builder
DecalBuilder * decal_builder
Definition: Indoor.h:654
IndoorLocation::ptr_0002B4_doors_ddata
uint16_t * ptr_0002B4_doors_ddata
Definition: Indoor.h:644
blv_prev_party_x
int blv_prev_party_x
Definition: mm7_data.cpp:737
IndoorLocation::ptr_0002B8_sector_lrdata
uint16_t * ptr_0002B8_sector_lrdata
Definition: Indoor.h:645
BLVSector::pDecorationIDs
uint16_t * pDecorationIDs
Definition: Indoor.h:550
ACTOR_BUFF_STONED
@ ACTOR_BUFF_STONED
Definition: Actor.h:43
DecorationDesc_mm6::uSpriteID
uint16_t uSpriteID
Definition: DecorationList.h:43
pMonsterList
struct MonsterList * pMonsterList
Definition: Monsters.cpp:9
IndoorLocation::Release
void Release()
Definition: Indoor.cpp:761
BLVSector::uNumFaces
uint16_t uNumFaces
Definition: Indoor.h:539
flt_6BE150_look_up_down_dangle
float flt_6BE150_look_up_down_dangle
Definition: mm7_data.cpp:709
Texture.h
UIStatusBar.h
BLVDoor::pYOffsets
uint16_t * pYOffsets
Definition: Indoor.h:399
IndoorCameraD3D::IsCulled
bool IsCulled(struct BLVFace *pFace)
Definition: IndoorCameraD3D.cpp:128
DecorationDesc_mm6::uSoundID
int16_t uSoundID
Definition: DecorationList.h:45
IndoorCameraD3D::std__vector_000034_prolly_frustrum
IndoorCameraD3D_Vec4 std__vector_000034_prolly_frustrum[6]
Definition: IndoorCameraD3D.h:188
v2
GLfloat GLfloat GLfloat v2
Definition: SDL_opengl_glext.h:695
flt_6BE3A4_debug_recmod1
float flt_6BE3A4_debug_recmod1
Definition: mm7_data.cpp:716
SpriteFrame
Definition: Sprites.h:39
RenderVertexSoft::v
float v
Definition: IRender.h:122
BLVDoor::uNumOffsets
uint16_t uNumOffsets
Definition: Indoor.h:404
assets
AssetsManager * assets
Definition: AssetsManager.cpp:12
ANIM_Walking
@ ANIM_Walking
Definition: Actor.h:100
integer_sqrt
int integer_sqrt(int val)
Definition: OurMath.cpp:164
SOUND_RunWood
@ SOUND_RunWood
Definition: AudioPlayer.h:33
uint
unsigned int uint
Definition: MM7.h:4
BLVDoor::Closing
@ Closing
Definition: Indoor.h:383
sub_4075DB
bool sub_4075DB(int x, int y, int z, BLVFace *face)
Definition: Indoor.cpp:5424
stru141_actor_collision_object::field_54
int field_54
Definition: Indoor.h:164
uActiveCharacter
unsigned int uActiveCharacter
Definition: mm7_data.cpp:555
v3
GLfloat GLfloat GLfloat GLfloat v3
Definition: SDL_opengl_glext.h:696
pStationaryLightsStack
LightsStack_StationaryLight_ * pStationaryLightsStack
Definition: LightmapBuilder.cpp:11
__debugbreak
void __cdecl __debugbreak(void)
IndoorCameraD3D::debug_flags
int debug_flags
Definition: IndoorCameraD3D.h:255
Fleeing
@ Fleeing
Definition: Actor.h:82
_evt_raw
Definition: Events.h:20
Actor::AI_Flee
static void AI_Flee(unsigned int uActorID, signed int edx0, int uActionLength, struct AIDirection *a4)
Definition: Actor.cpp:2070
BLVFace::Fluid
bool Fluid() const
Definition: Indoor.h:449
stru141_actor_collision_object::field_80
int field_80
Definition: Indoor.h:173
DecorationDesc_mm6::uDecorationHeight
uint16_t uDecorationHeight
Definition: DecorationList.h:40
y1
GLfixed y1
Definition: SDL_opengl_glext.h:4586
uLevelEVT_NumEvents
signed int uLevelEVT_NumEvents
Definition: Events.cpp:51
fixed::GetFloat
float GetFloat() const
Definition: OurMath.h:37
LEVEL_TYPE
LEVEL_TYPE
Definition: Indoor.h:284
stru_F83B80
std::array< stru352, 480 > stru_F83B80
Definition: Indoor.cpp:59
BLVRenderParams::uViewportCenterX
int uViewportCenterX
Definition: Indoor.h:704
BSPModel::pFaces
std::vector< ODMFace > pFaces
Definition: BSPModel.h:190
RenderVertexSoft::vWorldPosition
Vec3_float_ vWorldPosition
Definition: IRender.h:116
BLVHeader::uSector_rdata_Size
unsigned int uSector_rdata_Size
Definition: Indoor.h:331
ODMFace
Definition: BSPModel.h:93
IndoorLocation::ToggleLight
void ToggleLight(signed int uLightID, unsigned int bToggle)
Definition: Indoor.cpp:846
stru154::polygonType
PolygonType polygonType
Definition: Indoor.h:244
stru141_actor_collision_object::direction
Vec3_int_ direction
Definition: Indoor.h:165
BSPModel::vBoundingCenter
Vec3_int_ vBoundingCenter
Definition: BSPModel.h:186
PARTY_BUFF_FLY
@ PARTY_BUFF_FLY
Definition: Party.h:78
OBJECT_BLVDoor
@ OBJECT_BLVDoor
Definition: Actor.h:65
pBitmaps_LOD
LODFile_IconsBitmaps * pBitmaps_LOD
Definition: LOD.cpp:16
BLVDoor::uAttributes
unsigned int uAttributes
Definition: Indoor.h:386
_45063B_spawn_some_monster
int _45063B_spawn_some_monster(MapInfo *a1, int a2)
Definition: Indoor.cpp:5298
GetPortalScreenCoord
int GetPortalScreenCoord(unsigned int uFaceID)
Definition: Indoor.cpp:4045
y2
GLfixed GLfixed GLfixed y2
Definition: SDL_opengl_glext.h:4586
DecorationList::InitializeDecorationSprite
void InitializeDecorationSprite(unsigned int uDecID)
Definition: DecorationList.cpp:45
Particle_sw::particle_size
float particle_size
Definition: ParticleEngine.h:30
uNumSpritesDrawnThisFrame
int uNumSpritesDrawnThisFrame
Definition: RenderOpenGL.cpp:56
SpawnPointMM7::vPosition
Vec3_int_ vPosition
Definition: Indoor.h:314
ParticleType_Rotating
@ ParticleType_Rotating
Definition: ParticleEngine.h:8
stru193_math::Cos
int Cos(int angle)
Definition: OurMath.cpp:28
ChestsDeserialize
char * ChestsDeserialize(char *pData)
Definition: Chest.cpp:500
IndoorLocation::particle_engine
ParticleEngine * particle_engine
Definition: Indoor.h:657
Party::TorchlightActive
bool TorchlightActive()
Definition: Party.h:199
Decoration.h
ODMFace::uAttributes
uint32_t uAttributes
Definition: BSPModel.h:135
stru_5C6E00
struct stru193_math * stru_5C6E00
Definition: mm7_data.cpp:19
ODM_GetFloorLevel
int ODM_GetFloorLevel(int X, signed int Y, int Z, int __unused, bool *pIsOnWater, int *bmodel_pid, int bWaterWalk)
Definition: Outdoor.cpp:1877
Party::walk_sound_timer
int walk_sound_timer
Definition: Party.h:263
BLVSector::uNumMarkers
uint16_t uNumMarkers
Definition: Indoor.h:551
BLVFace::GetTexture
Texture * GetTexture()
Definition: Indoor.cpp:738
angle
GLfloat angle
Definition: SDL_opengl_glext.h:6100
ViewingParams::bRedrawGameUI
int bRedrawGameUI
Definition: Viewport.h:74
BLVLightMM7
Definition: Indoor.h:357
ActorInteraction
bool ActorInteraction(unsigned int id)
Definition: Viewport.cpp:250
ODMFace::pFacePlane
struct Plane_int_ pFacePlane
Definition: BSPModel.h:131
BSPVertexBuffer::pVertices
Vec3_int_ * pVertices
Definition: BSPModel.h:53
dword_6BE364_game_settings_1
int dword_6BE364_game_settings_1
Definition: mm7_data.cpp:714
IndoorLocation::pVertices
struct Vec3_short_ * pVertices
Definition: Indoor.h:628
stru367
Definition: stru367.h:8
DecorationDesc
Definition: DecorationList.h:49
Particle_sw::x
float x
Definition: ParticleEngine.h:20
BLVRenderParams::field_88
int field_88
Definition: Indoor.h:709
SoundID
SoundID
Definition: AudioPlayer.h:10
BLVSector::uNumCeilings
uint16_t uNumCeilings
Definition: Indoor.h:530
LightsData::uNumLightsApplied
unsigned int uNumLightsApplied
Definition: Indoor.h:39
pBillboardRenderList
RenderBillboard pBillboardRenderList[500]
Definition: RenderOpenGL.cpp:54
EventProcessor
void EventProcessor(int uEventID, int targetObj, int canShowMessages, int entry_line)
Definition: Events.cpp:260
BLVRenderParams::fov
int fov
Definition: Indoor.h:700
PARTY_Jump
@ PARTY_Jump
Definition: Party.h:107
uCurrentlyLoadedLevelType
LEVEL_TYPE uCurrentlyLoadedLevelType
Definition: Indoor.cpp:52
POLYGON_InBetweenCeilingAndWall
@ POLYGON_InBetweenCeilingAndWall
Definition: Indoor.h:223
IndoorCameraD3D::fov_x
float fov_x
Definition: IndoorCameraD3D.h:192
stru_721530
stru141_actor_collision_object stru_721530
Definition: Indoor.cpp:58
Is_out15odm_underwater
char Is_out15odm_underwater()
Definition: Outdoor.cpp:3377
ODMFace::zCalc2
int zCalc2
Definition: BSPModel.h:133
blv_prev_party_z
int blv_prev_party_z
Definition: mm7_data.cpp:738
LightmapBuilder::ApplyLights
bool ApplyLights(struct LightsData *a2, struct stru154 *a3, unsigned int uNumVertices, struct RenderVertexSoft *a5, struct IndoorCameraD3D_Vec4 *, char uClipFlag)
Definition: LightmapBuilder.cpp:494
IndoorLocation::GetSector
int GetSector(int sX, int sY, int sZ)
Definition: Indoor.cpp:1279
IndoorLocation::pFaces
struct BLVFace * pFaces
Definition: Indoor.h:630
uLevel_StartingPointType
MapStartPoint uLevel_StartingPointType
Definition: Outdoor.cpp:46
FaceFlowTextureOffset
unsigned int FaceFlowTextureOffset(unsigned int uFaceID)
Definition: Indoor.cpp:562
RenderBillboard::screenspace_projection_factor_x
float screenspace_projection_factor_x
Definition: IRender.h:27
stru193_math::Sin
int Sin(int angle)
Definition: OurMath.cpp:133
LightsStack_StationaryLight_::AddLight
bool AddLight(int16_t x, int16_t y, int16_t z, int16_t a5, unsigned char r, unsigned char g, unsigned char b, char uLightType)
Definition: LightsStack.cpp:30
ViewingParams::draw_sw_outlines
int draw_sw_outlines
Definition: Viewport.h:77
IndoorLocation::uNumLights
int uNumLights
Definition: Indoor.h:635
pAudioPlayer
AudioPlayer * pAudioPlayer
Definition: AudioPlayer.cpp:20
BBox_short_::x2
int16_t x2
Definition: VectorTypes.h:115
BSPNode::uFront
int16_t uFront
Definition: BSPModel.h:43
SpawnEncounter
void SpawnEncounter(MapInfo *pMapInfo, SpawnPointMM7 *spawn, int a3, int a4, int a5)
Definition: Actor.cpp:5063
BLVDoor::field_48
int16_t field_48
Definition: Indoor.h:403
stru141_actor_collision_object::CalcMovementExtents
int CalcMovementExtents(int a2)
Definition: Indoor.cpp:5697
_calc_fov
float _calc_fov(int viewport_width, int angle_degree)
Definition: IndoorCameraD3D.cpp:17
BSPModel
Definition: BSPModel.h:163
fixed
Definition: OurMath.h:21
GUIWindow.h
BLVSector
Definition: Indoor.h:522
RenderVertexSoft
Definition: IRender.h:113
ParticleType_Bitmap
@ ParticleType_Bitmap
Definition: ParticleEngine.h:12
Party::floor_face_pid
int floor_face_pid
Definition: Party.h:262
BLVRenderParams::uViewportHeight
int uViewportHeight
Definition: Indoor.h:702
ObjectList.h
offset
GLintptr offset
Definition: SDL_opengl_glext.h:541
logger
Log * logger
Definition: IocContainer.cpp:47
PlayerSpeech
PlayerSpeech
Definition: Player.h:46
BLVFace_MM7::uBackSectorID
int16_t uBackSectorID
Definition: LegacyImages.h:55
pMobileLightsStack
LightsStack_MobileLight_ * pMobileLightsStack
Definition: LightmapBuilder.cpp:14
Actor::PrepareSprites
void PrepareSprites(char load_sounds_if_bit1_set)
Definition: Actor.cpp:2481
stru_5E4C90_MapPersistVars
stru123 stru_5E4C90_MapPersistVars
Definition: mm7_data.cpp:23
BspRenderer::MakeVisibleSectorList
void MakeVisibleSectorList()
Definition: Indoor.cpp:3692
BLVDoor::uDoorID
unsigned int uDoorID
Definition: Indoor.h:387
stru141_actor_collision_object::field_4C
int field_4C
Definition: Indoor.h:162
res
GLuint res
Definition: SDL_opengl_glext.h:7940
RespawnGlobalDecorations
void RespawnGlobalDecorations()
Definition: DecorationList.cpp:70
DecorationDesc::uColoredLightBlue
uint8_t uColoredLightBlue
Definition: DecorationList.h:52
BLVFace_MM7::uAttributes
unsigned int uAttributes
Definition: LegacyImages.h:45
LightmapBuilder::StationaryLightsCount
unsigned int StationaryLightsCount
Definition: LightmapBuilder.h:83
pOutdoor
OutdoorLocation * pOutdoor
Definition: Outdoor.cpp:48
SOUND_WalkWood
@ SOUND_WalkWood
Definition: AudioPlayer.h:55
BspRenderer_PortalViewportData::_viewport_space_w
int _viewport_space_w
Definition: Indoor.h:754
GUIProgressBar::Progress
void Progress()
Definition: GUIProgressBar.cpp:83
BLVSector::field_0
int32_t field_0
Definition: Indoor.h:523
PaletteManager::pPalette_tintColor
unsigned char pPalette_tintColor[3]
Definition: PaletteManager.h:36
MapInfo::uRespawnIntervalDays
unsigned int uRespawnIntervalDays
Definition: MapInfo.h:45
SpawnPointMM7::uIndex
uint16_t uIndex
Definition: Indoor.h:317
pDoorSoundIDsByLocationID
unsigned __int16 pDoorSoundIDsByLocationID[78]
Definition: Indoor.cpp:61
BLVFace_MM7::pXInterceptDisplacements
int16_t * pXInterceptDisplacements
Definition: LegacyImages.h:47
_A750D8_player_speech_timer
int64_t _A750D8_player_speech_timer
Definition: mm7_data.cpp:763
IndoorLocation::PrepareDecorationsRenderList_BLV
void PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID)
Definition: Indoor.cpp:3042
SpriteObject::uAttributes
unsigned __int16 uAttributes
Definition: SpriteObject.h:222
BBox_short_::z1
int16_t z1
Definition: VectorTypes.h:118
BLVSector::uNumDecorations
uint16_t uNumDecorations
Definition: Indoor.h:548
IndoorLocation::ExecDraw_d3d
void ExecDraw_d3d(unsigned int uFaceID, struct IndoorCameraD3D_Vec4 *pVertices, unsigned int uNumVertices, struct RenderVertexSoft *pPortalBounding)
Definition: Indoor.cpp:409
pIndoorCameraD3D
IndoorCameraD3D * pIndoorCameraD3D
Definition: IndoorCameraD3D.cpp:21
_46E0B2_collide_against_decorations
void _46E0B2_collide_against_decorations()
Definition: Render.cpp:4855
Actor::pMonsterInfo
struct MonsterInfo pMonsterInfo
Definition: Actor.h:292
ai_near_actors_ids
std::array< unsigned int, 500 > ai_near_actors_ids
Definition: mm7_data.cpp:505
g
GLboolean GLboolean g
Definition: SDL_opengl_glext.h:1112
stru141_actor_collision_object::position
Vec3_int_ position
Definition: Indoor.h:160
_6807B8_level_decorations_ids
std::array< int, 777 > _6807B8_level_decorations_ids
Definition: mm7_data.cpp:685
_46F04E_collide_against_portals
int _46F04E_collide_against_portals()
Definition: Render.cpp:4895
IndoorLocation::Alloc
bool Alloc()
Definition: Indoor.cpp:812
GUIProgressBar.h
PARTY_WalkBackward
@ PARTY_WalkBackward
Definition: Party.h:101
MonsterDesc::sTintColor
unsigned int sTintColor
Definition: Monsters.h:218
uint32_t
unsigned __int32 uint32_t
Definition: SDL_config.h:39
BLVRenderParams::uViewportY
unsigned int uViewportY
Definition: Indoor.h:697
PARTY_FastTurnLeft
@ PARTY_FastTurnLeft
Definition: Party.h:113
IndoorCameraD3D::PrepareAndDrawDebugOutline
void PrepareAndDrawDebugOutline(struct BLVFace *pFace, unsigned int uDiffuse)
Definition: IndoorCameraD3D.cpp:445
BLVMapOutlines
Definition: Indoor.h:568
stru141_actor_collision_object::velocity
Vec3_int_ velocity
Definition: Indoor.h:158
BspRenderer_stru0::uViewportZ
uint16_t uViewportZ
Definition: Indoor.h:779
IndoorLocation::PrepareActorRenderList_BLV
void PrepareActorRenderList_BLV()
Definition: Indoor.cpp:2739
ItemInteraction
void ItemInteraction(unsigned int item_id)
Definition: Viewport.cpp:224
BLV_GetFloorLevel
int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID)
Definition: Indoor.cpp:2530
Party::sRotationY
int sRotationY
Definition: Party.h:251
BLVDoor::Open
@ Open
Definition: Indoor.h:382
stru262_TurnBased::turn_stage
int turn_stage
Definition: TurnEngine.h:75
Timer::uTotalGameTimeElapsed
unsigned int uTotalGameTimeElapsed
Definition: Time.h:135
stru193_math::uIntegerPi
static const unsigned int uIntegerPi
Definition: OurMath.h:88
DecalBuilder.h
EQUIP_BOOTS
@ EQUIP_BOOTS
Definition: Items.h:236
IndoorLocation::pDoors
struct BLVDoor * pDoors
Definition: Indoor.h:638
String
std::string String
Definition: Strings.h:10
PrepareBspRenderList_BLV
void PrepareBspRenderList_BLV()
Definition: Indoor.cpp:3159
ODMFace::pZInterceptDisplacements
int16_t pZInterceptDisplacements[20]
Definition: BSPModel.h:141
LightsStack_MobileLight_::AddLight
bool AddLight(int16_t x, int16_t y, int16_t z, int16_t uSectorID, int uRadius, uint8_t r, uint8_t g, uint8_t b, char a10)
Definition: LightsStack.cpp:6
POLYGON_Ceiling
@ POLYGON_Ceiling
Definition: Indoor.h:222
pEventTimer
Timer * pEventTimer
Definition: Time.cpp:8
PARTY_RunForward
@ PARTY_RunForward
Definition: Party.h:111
PolygonType
PolygonType
Definition: Indoor.h:216
Pursuing
@ Pursuing
Definition: Actor.h:81
BLVFace::uAttributes
unsigned int uAttributes
Definition: Indoor.h:475
Sprites.h
BLVFace::pVertexUIDs
int16_t * pVertexUIDs
Definition: Indoor.h:480
RenderBillboard::world_x
int16_t world_x
Definition: IRender.h:36
DecorationDesc::uColoredLightGreen
uint8_t uColoredLightGreen
Definition: DecorationList.h:51
SpriteFrame::uFlags
int uFlags
Definition: Sprites.h:48
Actor::InitializeActors
static void InitializeActors()
Definition: Actor.cpp:3334
dword_6BE13C_uCurrentlyLoadedLocationID
int dword_6BE13C_uCurrentlyLoadedLocationID
Definition: mm7_data.cpp:705
Vec3::z
T z
Definition: VectorTypes.h:27
pObjectList
struct ObjectList * pObjectList
Definition: ObjectList.cpp:5
BLVFace_MM7::pVertexVIDs
int16_t * pVertexVIDs
Definition: LegacyImages.h:51
RenderBillboard::sTintColor
unsigned int sTintColor
Definition: IRender.h:44
BLVDoor::uTimeSinceTriggered
unsigned int uTimeSinceTriggered
Definition: Indoor.h:388
ItemsTable::pItems
NZIArray< ItemDesc, 800 > pItems
Definition: Items.h:460
Party::flt_TorchlightColorG
float flt_TorchlightColorG
Definition: Party.h:326
PARTY_StrafeRight
@ PARTY_StrafeRight
Definition: Party.h:99
Api.h
pDecorationList
struct DecorationList * pDecorationList
Definition: DecorationList.cpp:11
fBackwardWalkSpeedMultiplier
float fBackwardWalkSpeedMultiplier
Definition: mm7_data.cpp:707
BLVDoor::uCloseSpeed
int uCloseSpeed
Definition: Indoor.h:392
stru141_actor_collision_object::pid
unsigned int pid
Definition: Indoor.h:171
BLVFace::uFaceExtraID
uint16_t uFaceExtraID
Definition: Indoor.h:482
BLVRenderParams
Definition: Indoor.h:665
POLYGON_VerticalWall
@ POLYGON_VerticalWall
Definition: Indoor.h:218
Time.h
BLVFace::zCalc1
int zCalc1
Definition: Indoor.h:472
BspRenderer_stru0::std__vector_0007AC
IndoorCameraD3D_Vec4 std__vector_0007AC[4]
Definition: Indoor.h:786
BLVFace::Deserialize
bool Deserialize(struct BLVFace_MM7 *)
Definition: Indoor.cpp:74
TextureFrameTable::GetFrameTexture
Texture * GetFrameTexture(int uFrameID, int time)
Definition: Image.cpp:146
pBspRenderer
BspRenderer * pBspRenderer
Definition: Indoor.cpp:57
SpellFxRenderer::effpar01
Texture * effpar01
Definition: SpellFxRenderer.h:166
stru141_actor_collision_object::sMinZ
int sMinZ
Definition: Indoor.h:181
Particle_sw::uDiffuse
unsigned int uDiffuse
Definition: ParticleEngine.h:26
render
std::shared_ptr< IRender > render
Definition: RenderOpenGL.cpp:52