World of Might and Magic  0.2.0
Open reimplementation of Might and Magic 6 7 8 game engine
Указатель Классы Пространства имен Файлы Функции Переменные Определения типов Перечисления Элементы перечислений Друзья Группы Страницы
Файл Outdoor.h

См. исходные тексты.

Классы

struct  ODMHeader
 
struct  OutdoorLocationTileType
 
struct  DMap
 
struct  OutdoorLocationTerrain
 
struct  OutdoorLocation
 

Функции

void ODM_UpdateUserInputAndOther ()
 
int ODM_GetFloorLevel (int X, signed int Y, int Z, int, bool *pOnWater, int *bmodel_pid, int bWaterWalk)
 
int GetCeilingHeight (int Party_X, signed int Party_Y, int Party_ZHeight, int pFaceID)
 
void ODM_GetTerrainNormalAt (int pos_x, int pos_z, Vec3_int_ *out)
 
void UpdateActors_ODM ()
 
void ODM_ProcessPartyActions ()
 
char Is_out15odm_underwater ()
 
void SetUnderwaterFog ()
 
void ODM_Project (unsigned int uNumVertices)
 
void sub_487DA9 ()
 
void ODM_LoadAndInitialize (const String &pLevelFilename, struct ODMRenderParams *thisa)
 
unsigned int GetLevelFogColor ()
 
int sub_47C3D7_get_fog_specular (int a1, int a2, float a3)
 
unsigned int WorldPosToGridCellX (int)
 
unsigned int WorldPosToGridCellZ (int)
 
int GridCellToWorldPosX (int)
 
int GridCellToWorldPosZ (int)
 
void sub_481ED9_MessWithODMRenderParams ()
 
bool IsTerrainSlopeTooHigh (int pos_x, int pos_y)
 
int GetTerrainHeightsAroundParty2 (int a1, int a2, bool *a3, int a4)
 

Переменные

OutdoorLocationpOutdoor
 

Функции

◆ ODM_UpdateUserInputAndOther()

void ODM_UpdateUserInputAndOther ( )

См. определение в файле Outdoor.cpp строка 2115

2115  {
2116  bool v0; // eax@5
2117  char pOut[32]; // [sp+8h] [bp-20h]@5
2118 
2119  UpdateObjects();
2121  if (pParty->vPosition.x < -22528 || pParty->vPosition.x > 22528 ||
2122  pParty->vPosition.y < -22528 || pParty->vPosition.y > 22528) {
2125  pParty->vPosition.y, pOut, 32);
2126  if (!engine->IsUnderwater() && (pParty->uFlags & (PARTY_FLAGS_1_STANDING_ON_WATER |
2127  PARTY_FLAGS_1_FALLING | 0x04) ||
2128  pParty->uFlags & 0x0200 || pParty->bFlying) ||
2129  !v0) {
2130  if (pParty->vPosition.x < -22528) pParty->vPosition.x = -22528;
2131  if (pParty->vPosition.x > 22528) pParty->vPosition.x = 22528;
2132  if (pParty->vPosition.y < -22528) pParty->vPosition.y = -22528;
2133  if (pParty->vPosition.y > 22528) pParty->vPosition.y = 22528;
2134  } else {
2135  pAudioPlayer->StopChannels(-1, -1);
2136  pDialogueWindow = new GUIWindow_Travel(); // TravelUI_Load();
2137  }
2138  }
2139  UpdateActors_ODM();
2141 }

Перекрестные ссылки Party::bFlying, check_event_triggers(), engine, OutdoorLocation::GetTravelDestination(), OutdoorLocation::level_filename, ODM_ProcessPartyActions(), PARTY_FLAGS_1_FALLING, PARTY_FLAGS_1_STANDING_ON_WATER, pAudioPlayer, pCurrentMapName, pDialogueWindow, pOutdoor, pParty, AudioPlayer::StopChannels(), Party::uFlags, UpdateActors_ODM(), UpdateObjects() и Party::vPosition.

Используется в UpdateUserInput_and_MapSpecificStuff().

+ Граф вызовов:
+ Граф вызова функции:

◆ ODM_GetFloorLevel()

int ODM_GetFloorLevel ( int  X,
signed int  Y,
int  Z,
int  ,
bool *  pOnWater,
int *  bmodel_pid,
int  bWaterWalk 
)

См. определение в файле Outdoor.cpp строка 1877

1878  {
1879  int v18; // edx@26
1880  int v19; // eax@28
1881  int v22; // edx@30
1882  __int64 v23; // qtt@30
1883  int v24; // eax@36
1884  int v25; // ecx@38
1885  int current_floor_level; // ecx@43
1886  int v29; // edx@44
1887  int v39; // [sp+20h] [bp-20h]@9
1888  bool current_vertices_Y; // [sp+30h] [bp-10h]@22
1889  bool next_vertices_Y; // [sp+34h] [bp-Ch]@24
1890  int number_hits; // [sp+58h] [bp+18h]@22
1891  int next_floor_level; // [sp+58h] [bp+18h]@43
1892 
1893  int v46 = 1;
1894  current_BModel_id[0] = -1;
1895  current_Face_id[0] = -1;
1896  odm_floor_level[0] =
1897  GetTerrainHeightsAroundParty2(X, Y, pIsOnWater, bWaterWalk);
1898 
1899  for (BSPModel &model : pOutdoor->pBModels) {
1900  if (X <= model.sMaxX && X >= model.sMinX && Y <= model.sMaxY &&
1901  Y >= model.sMinY) {
1902  if (!model.pFaces.empty()) {
1903  v39 = 0;
1904  for (ODMFace &face : model.pFaces) {
1905  if (face.Ethereal()) {
1906  continue;
1907  }
1908  if ((face.uPolygonType == POLYGON_Floor ||
1909  face.uPolygonType == POLYGON_InBetweenFloorAndWall) &&
1910  X <= face.pBoundingBox.x2 &&
1911  X >= face.pBoundingBox.x1 &&
1912  Y <= face.pBoundingBox.y2 &&
1913  Y >= face.pBoundingBox.y1) {
1914  for (uint i = 0; i < face.uNumVertices; ++i) {
1916  face.pXInterceptDisplacements[i] +
1917  model.pVertices.pVertices[face.pVertexIDs[i]].x;
1919  face.pYInterceptDisplacements[i] +
1920  model.pVertices.pVertices[face.pVertexIDs[i]].y;
1921  odm_floor_face_vert_coord_X[2 * i + 1] =
1922  face.pXInterceptDisplacements[i] +
1923  model.pVertices
1924  .pVertices[face.pVertexIDs[i + 1]]
1925  .x;
1926  odm_floor_face_vert_coord_Y[2 * i + 1] =
1927  face.pYInterceptDisplacements[i] +
1928  model.pVertices
1929  .pVertices[face.pVertexIDs[i + 1]]
1930  .y;
1931  }
1932  odm_floor_face_vert_coord_X[2 * face.uNumVertices] =
1934  odm_floor_face_vert_coord_Y[2 * face.uNumVertices] =
1936 
1937  current_vertices_Y =
1939  number_hits = 0;
1940  if (2 * face.uNumVertices > 0) {
1941  for (int i = 0; i < 2 * face.uNumVertices; ++i) {
1942  if (number_hits >= 2) break;
1943  // v36 = odm_floor_face_vert_coord_Y[i + 1];
1944  next_vertices_Y =
1945  odm_floor_face_vert_coord_Y[i + 1] >= Y;
1946  if (current_vertices_Y !=
1947  next_vertices_Y) { // проверка по Y
1948  v18 =
1949  odm_floor_face_vert_coord_X[i + 1] >= X
1950  ? 0
1951  : 2;
1952  v19 = v18 |
1953  (odm_floor_face_vert_coord_X[i] < X);
1954  if (v19 != 3) {
1955  if (!v19) {
1956  ++number_hits;
1957  } else {
1958  HEXRAYS_LODWORD(v23) =
1959  (Y -
1961  << 16;
1962  HEXRAYS_HIDWORD(v23) =
1964  [i]) >>
1965  16;
1966  v22 =
1968  [i + 1] -
1970  [i]) *
1971  v23 /
1973  [i + 1] -
1975  [i])) >>
1976  16) +
1978  [i]);
1979  if (v22 >= X) ++number_hits;
1980  }
1981  }
1982  }
1983  current_vertices_Y = next_vertices_Y;
1984  }
1985  if (number_hits == 1) {
1986  if (v46 >= 20) break;
1987  if (face.uPolygonType == POLYGON_Floor) {
1988  v24 = model.pVertices
1989  .pVertices[face.pVertexIDs[0]]
1990  .z;
1991  } else {
1992  int a = fixpoint_mul(face.zCalc1, X);
1993  int b = fixpoint_mul(face.zCalc2, Y);
1994  int c = ((int64_t)face.zCalc3 >> 16);
1995  v24 = a + b + c;
1996  }
1997  v25 = v46++;
1998  odm_floor_level[v25] = v24;
1999  current_BModel_id[v25] = model.index;
2000  current_Face_id[v25] = face.index;
2001  }
2002  }
2003  }
2004  }
2005  }
2006  }
2007  }
2008  if (v46 == 1) {
2009  *bmodel_pid = 0;
2010  return odm_floor_level[0];
2011  }
2012  current_floor_level = 0;
2013  v29 = 0;
2014  if (v46 <= 1) {
2015  *bmodel_pid = 0;
2016  } else {
2017  current_floor_level = odm_floor_level[0];
2018  for (uint i = 1; i < v46; ++i) {
2019  next_floor_level = odm_floor_level[i];
2020  if (current_floor_level <= Z + 5) {
2021  if (next_floor_level >= current_floor_level &&
2022  next_floor_level <= Z + 5) {
2023  current_floor_level = next_floor_level;
2024  v29 = i;
2025  }
2026  } else if (next_floor_level < current_floor_level) {
2027  current_floor_level = next_floor_level;
2028  v29 = i;
2029  }
2030  }
2031  if (!v29)
2032  *bmodel_pid = 0;
2033  else
2034  *bmodel_pid = current_Face_id[v29] | (current_BModel_id[v29] << 6);
2035  }
2036  if (v29) {
2037  *pIsOnWater = false;
2039  .pFaces[current_Face_id[v29]]
2040  .Fluid())
2041  *pIsOnWater = true;
2042  }
2043  if (odm_floor_level[v29] >= odm_floor_level[0])
2044  odm_floor_level[0] = odm_floor_level[v29];
2045  return odm_floor_level[0];
2046 }

Перекрестные ссылки current_BModel_id, current_Face_id, fixpoint_mul(), GetTerrainHeightsAroundParty2(), BSPModel::index, odm_floor_face_vert_coord_X, odm_floor_face_vert_coord_Y, odm_floor_level, OutdoorLocation::pBModels, BSPModel::pFaces, POLYGON_Floor, POLYGON_InBetweenFloorAndWall, pOutdoor, BSPVertexBuffer::pVertices, BSPModel::pVertices, BSPModel::sMaxY, BSPModel::sMinX и BSPModel::sMinY.

Используется в _45063B_spawn_some_monster(), Engine::DrawGUI(), OutdoorLocation::GetNumFoodRequiredToRestInCurrentPos(), ODM_ProcessPartyActions(), UpdateActors_ODM() и SpriteObject::UpdateObject_fn0_ODM().

+ Граф вызовов:
+ Граф вызова функции:

◆ GetCeilingHeight()

int GetCeilingHeight ( int  Party_X,
signed int  Party_Y,
int  Party_ZHeight,
int  pFaceID 
)

См. определение в файле Outdoor.cpp строка 3254

3255  {
3256  int v13; // eax@25
3257  int v14; // edx@27
3258  int v16; // ST18_4@29
3259  int v17; // edx@29
3260  int64_t v18; // qtt@29
3261  int v19; // eax@35
3262  int v20; // ecx@37
3263  int v22; // ebx@42
3264  int v27; // [sp+10h] [bp-34h]@21
3265  bool v34; // [sp+30h] [bp-14h]@21
3266  bool v35; // [sp+34h] [bp-10h]@23
3267  int v37; // [sp+38h] [bp-Ch]@21
3268  int v38; // [sp+38h] [bp-Ch]@42
3269  int v39; // [sp+3Ch] [bp-8h]@1
3270 
3271  dword_720ED0[0] = -1;
3272  dword_720E80[0] = -1;
3273  v39 = 1;
3274  ceiling_height_level[0] = 10000; //нет потолка
3275  for (BSPModel &model : pOutdoor->pBModels) {
3276  if (Party_X <= model.sMaxX && Party_X >= model.sMinX &&
3277  Party_Y <= model.sMaxY && Party_Y >= model.sMinY) {
3278  for (ODMFace &face : model.pFaces) {
3279  if ((face.uPolygonType == POLYGON_Ceiling ||
3280  face.uPolygonType == POLYGON_InBetweenCeilingAndWall) &&
3281  !face.Ethereal() && Party_X <= face.pBoundingBox.x2 &&
3282  Party_X >= face.pBoundingBox.x1 &&
3283  Party_Y <= face.pBoundingBox.y2 &&
3284  Party_Y >= face.pBoundingBox.y1) {
3285  for (uint v = 0; v < face.uNumVertices; v++) {
3286  word_720DB0_xs[2 * v] =
3287  face.pXInterceptDisplacements[v] +
3288  (short)model.pVertices.pVertices[face.pVertexIDs[v]]
3289  .x;
3290  word_720CE0_ys[2 * v] =
3291  face.pXInterceptDisplacements[v] +
3292  (short)model.pVertices.pVertices[face.pVertexIDs[v]]
3293  .y;
3294  word_720DB0_xs[2 * v + 1] =
3295  face.pXInterceptDisplacements[v] +
3296  (short)model.pVertices
3297  .pVertices[face.pVertexIDs[v + 1]]
3298  .x;
3299  word_720CE0_ys[2 * v + 1] =
3300  face.pXInterceptDisplacements[v] +
3301  (short)model.pVertices
3302  .pVertices[face.pVertexIDs[v + 1]]
3303  .y;
3304  }
3305  v27 = 2 * face.uNumVertices;
3306  word_720DB0_xs[2 * face.uNumVertices] = word_720DB0_xs[0];
3307  word_720CE0_ys[2 * face.uNumVertices] = word_720CE0_ys[0];
3308  v34 = word_720CE0_ys[0] >= Party_Y;
3309  v37 = 0;
3310  for (uint v = 0; v < v27; ++v) {
3311  if (v37 >= 2) break;
3312  v35 = word_720CE0_ys[v + 1] >= Party_Y;
3313  if (v34 != v35) {
3314  v13 = word_720DB0_xs[v + 1] >= Party_X ? 0 : 2;
3315  v14 = v13 | (word_720DB0_xs[v] < Party_X);
3316  if (v14 != 3) {
3317  if (!v14 ||
3318  (v16 = word_720CE0_ys[v + 1] -
3319  word_720CE0_ys[v],
3320  v17 = Party_Y - word_720CE0_ys[v],
3321  HEXRAYS_LODWORD(v18) = v17 << 16,
3322  HEXRAYS_HIDWORD(v18) = v17 >> 16,
3323  (int)(((uint64_t)(
3324  ((int)word_720DB0_xs[v + 1] -
3325  (int)word_720DB0_xs[v]) *
3326  v18 / v16) >>
3327  16) +
3328  word_720DB0_xs[v]) >= Party_X))
3329  ++v37;
3330  }
3331  }
3332  v34 = v35;
3333  }
3334  if (v37 == 1) {
3335  if (v39 >= 20) break;
3336  if (face.uPolygonType == POLYGON_Ceiling)
3337  v19 =
3338  model.pVertices.pVertices[face.pVertexIDs[0]].z;
3339  else
3340  v19 = fixpoint_mul(face.zCalc1, Party_X) +
3341  fixpoint_mul(face.zCalc2, Party_Y) +
3342  HEXRAYS_HIWORD(face.zCalc3);
3343  v20 = v39++;
3344  ceiling_height_level[v20] = v19;
3345  dword_720ED0[v20] = model.index;
3346  dword_720E80[v20] = face.index;
3347  }
3348  }
3349  }
3350  }
3351  }
3352 
3353  if (!v39) {
3354  pFaceID = 0;
3355  return ceiling_height_level[0];
3356  }
3357  v22 = 0;
3358  for (v38 = 0; v38 < v39; ++v38) {
3360  v22 = v38;
3361  else if (ceiling_height_level[v38] < ceiling_height_level[0] &&
3362  ceiling_height_level[0] > Party_ZHeight + 15)
3363  v22 = v38;
3364  else if (ceiling_height_level[v38] > ceiling_height_level[0] &&
3365  ceiling_height_level[v38] <= Party_ZHeight + 15)
3366  v22 = v38;
3367  }
3368  if (v22) {
3369  *(int *)pFaceID = dword_720E80[v22] | (dword_720ED0[v22] << 6);
3370  return ceiling_height_level[v22]; //если есть преграда
3371  }
3372  pFaceID = 0;
3373  return ceiling_height_level[v22]; // нет никакой преграды
3374 }

Перекрестные ссылки ceiling_height_level, dword_720E80, dword_720ED0, fixpoint_mul(), BSPModel::index, OutdoorLocation::pBModels, BSPModel::pFaces, POLYGON_Ceiling, POLYGON_InBetweenCeilingAndWall, pOutdoor, BSPVertexBuffer::pVertices, BSPModel::pVertices, BSPModel::sMinX, BSPModel::sMinY, word_720CE0_ys и word_720DB0_xs.

Используется в ODM_ProcessPartyActions().

+ Граф вызовов:
+ Граф вызова функции:

◆ ODM_GetTerrainNormalAt()

void ODM_GetTerrainNormalAt ( int  pos_x,
int  pos_z,
Vec3_int_ *  out 
)

См. определение в файле Outdoor.cpp строка 2052

2052  {
2053  uint grid_x = WorldPosToGridCellX(pos_x);
2054  uint grid_z = WorldPosToGridCellZ(pos_z) - 1;
2055 
2056  int grid_pos_x1 = GridCellToWorldPosX(grid_x);
2057  int grid_pos_x2 = GridCellToWorldPosX(grid_x + 1);
2058  int grid_pos_z1 = GridCellToWorldPosZ(grid_z);
2059  int grid_pos_z2 = GridCellToWorldPosZ(grid_z + 1);
2060 
2061  int x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z);
2062  int x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z);
2063  int x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1);
2064  int x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1);
2065 
2066  float side1_dx, side1_dy, side1_dz, side2_dx, side2_dy, side2_dz;
2067 
2068  int dx = abs(pos_x - grid_pos_x1), dz = abs(grid_pos_z1 - pos_z);
2069  if (dz >= dx) {
2070  side2_dx = (double)(grid_pos_x2 - grid_pos_x1);
2071  side2_dz =
2072  0.0; // (double)(grid_pos_z2 - grid_pos_z2); // bug? z2 - z2
2073  side2_dy = (double)(x2z2_y - x1z2_y);
2074 
2075  side1_dx = 0.0; // (double)(grid_pos_x1 - grid_pos_x1);
2076  side1_dz = (double)(grid_pos_z1 - grid_pos_z2); // z1 - z2 yes
2077  side1_dy = (double)(x1z1_y - x1z2_y);
2078  // logger->Warning(L"%S %S %u\n", __FILE__, __FUNCTION__, __LINE__);
2079  /* |\
2080  side1 | \
2081  |____\
2082  side 2 */
2083  } else {
2084  side2_dx = (double)(grid_pos_x1 - grid_pos_x2);
2085  side2_dz = 0.0; // (double)(grid_pos_z1 - grid_pos_z1);
2086  side2_dy = (double)(x1z1_y - x2z1_y);
2087 
2088  side1_dx = 0.0; // (double)(grid_pos_x2 - grid_pos_x1);
2089  side1_dz = (double)(grid_pos_z2 - grid_pos_z1);
2090  side1_dy = (double)(x2z2_y - x2z1_y);
2091  /* side 2
2092  _____
2093  \ |
2094  \ | side 1
2095  \| */
2096  }
2097 
2098  float nx = side1_dy * side2_dz - side1_dz * side2_dy;
2099  float ny = side1_dx * side2_dy - side1_dy * side2_dx;
2100  float nz = side1_dz * side2_dx - side1_dx * side2_dz;
2101 
2102  float mag = sqrt(nx * nx + ny * ny + nz * nz);
2103  if (fabsf(mag) < 1e-6f) {
2104  out->y = 0;
2105  out->x = 0;
2106  out->z = 65536;
2107  } else {
2108  float invmag = 1.0 / mag;
2109  out->x = invmag * nx * 65536.0;
2110  out->y = invmag * ny * 65536.0;
2111  out->z = invmag * nz * 65536.0;
2112  }
2113 }

Перекрестные ссылки OutdoorLocation::DoGetHeightOnTerrain(), GridCellToWorldPosX(), GridCellToWorldPosZ(), pOutdoor, WorldPosToGridCellX() и WorldPosToGridCellZ().

Используется в ODM_ProcessPartyActions(), UpdateActors_ODM() и SpriteObject::UpdateObject_fn0_ODM().

+ Граф вызовов:
+ Граф вызова функции:

◆ UpdateActors_ODM()

void UpdateActors_ODM ( )

См. определение в файле Outdoor.cpp строка 3393

3393  {
3394  if (engine->config->no_actors)
3395  return; // uNumActors = 0;
3396 
3397  for (unsigned int Actor_ITR = 0; Actor_ITR < uNumActors; ++Actor_ITR) {
3398  if (pActors[Actor_ITR].uAIState == Removed || pActors[Actor_ITR].uAIState == Disabled ||
3399  pActors[Actor_ITR].uAIState == Summoned || !pActors[Actor_ITR].uMovementSpeed)
3400  continue;
3401 
3402  bool Water_Walk = MonsterStats::BelongsToSupertype(pActors[Actor_ITR].pMonsterInfo.uID,
3404 
3405  pActors[Actor_ITR].uSectorID = 0;
3406 
3407  bool uIsFlying = pActors[Actor_ITR].pMonsterInfo.uFlying;
3408  if (!pActors[Actor_ITR].CanAct()) uIsFlying = 0;
3409 
3410  bool Slope_High = IsTerrainSlopeTooHigh(pActors[Actor_ITR].vPosition.x,
3411  pActors[Actor_ITR].vPosition.y);
3412  unsigned int Model_On_PID = 0;
3413  bool uIsOnWater = false;
3414  int Floor_Level = ODM_GetFloorLevel(
3415  pActors[Actor_ITR].vPosition.x, pActors[Actor_ITR].vPosition.y,
3416  pActors[Actor_ITR].vPosition.z, pActors[Actor_ITR].uActorHeight, &uIsOnWater,
3417  (int *)&Model_On_PID, Water_Walk);
3418  bool Actor_On_Terrain = Model_On_PID == 0;
3419 
3420  bool uIsAboveFloor = (pActors[Actor_ITR].vPosition.z > (Floor_Level + 1));
3421 
3422  if (pActors[Actor_ITR].uAIState == Dead && uIsOnWater && !uIsAboveFloor) {
3423  pActors[Actor_ITR].uAIState = Removed;
3424  continue;
3425  }
3426 
3427  // MOVEMENT
3428  if (pActors[Actor_ITR].uCurrentActionAnimation == ANIM_Walking) {
3429  signed int Actor_Speed = pActors[Actor_ITR].uMovementSpeed;
3430  if (pActors[Actor_ITR].pActorBuffs[ACTOR_BUFF_SLOWED].Active())
3431  Actor_Speed = (int64_t)((double)Actor_Speed * 0.5);
3432  if (pActors[Actor_ITR].uAIState == Fleeing ||
3433  pActors[Actor_ITR].uAIState == Pursuing)
3434  Actor_Speed *= 2;
3436  Actor_Speed *= flt_6BE3AC_debug_recmod1_x_1_6;
3437  }
3438  if (Actor_Speed > 1000) Actor_Speed = 1000;
3439 
3440  pActors[Actor_ITR].vVelocity.x =
3441  fixpoint_mul(stru_5C6E00->Cos(pActors[Actor_ITR].uYawAngle), Actor_Speed);
3442  pActors[Actor_ITR].vVelocity.y =
3443  fixpoint_mul(stru_5C6E00->Sin(pActors[Actor_ITR].uYawAngle), Actor_Speed);
3444  if (uIsFlying) {
3445  pActors[Actor_ITR].vVelocity.z = fixpoint_mul(
3446  stru_5C6E00->Sin(pActors[Actor_ITR].uPitchAngle), Actor_Speed);
3447  }
3448  } else {
3449  pActors[Actor_ITR].vVelocity.x =
3450  fixpoint_mul(55000, pActors[Actor_ITR].vVelocity.x);
3451  pActors[Actor_ITR].vVelocity.y =
3452  fixpoint_mul(55000, pActors[Actor_ITR].vVelocity.y);
3453  if (uIsFlying)
3454  pActors[Actor_ITR].vVelocity.z =
3455  fixpoint_mul(55000, pActors[Actor_ITR].vVelocity.z);
3456  }
3457 
3458  // BELOW FLOOR - POP UPWARDS
3459  if (pActors[Actor_ITR].vPosition.z < Floor_Level) {
3460  pActors[Actor_ITR].vPosition.z = Floor_Level;
3461  pActors[Actor_ITR].vVelocity.z = uIsFlying != 0 ? 0x14 : 0;
3462  }
3463  // GRAVITY
3464  if (!uIsAboveFloor || uIsFlying) {
3465  if (Slope_High && !uIsAboveFloor && Actor_On_Terrain) {
3466  Vec3_int_ Terrain_Norm;
3467  pActors[Actor_ITR].vPosition.z = Floor_Level;
3468  ODM_GetTerrainNormalAt(pActors[Actor_ITR].vPosition.x,
3469  pActors[Actor_ITR].vPosition.y, &Terrain_Norm);
3470  uint16_t Gravity = GetGravityStrength();
3471 
3472  pActors[Actor_ITR].vVelocity.z +=
3473  -16 * (short)pEventTimer->uTimeElapsed * Gravity;
3474  int v73 = abs(Terrain_Norm.x * pActors[Actor_ITR].vVelocity.x +
3475  Terrain_Norm.z * pActors[Actor_ITR].vVelocity.z +
3476  Terrain_Norm.y * pActors[Actor_ITR].vVelocity.y) >> 15;
3477 
3478  pActors[Actor_ITR].vVelocity.x += fixpoint_mul(v73, Terrain_Norm.x);
3479  pActors[Actor_ITR].vVelocity.y += fixpoint_mul(v73, Terrain_Norm.y);
3480  pActors[Actor_ITR].uYawAngle -= 32;
3481  // pActors[Actor_ITR].vVelocity.z += fixpoint_mul(v73, Terrain_Norm.z);
3482  }
3483  } else {
3484  pActors[Actor_ITR].vVelocity.z -=
3486  }
3487 
3488  // ARMAGEDDON PANIC
3489  if (pParty->armageddon_timer != 0 && pActors[Actor_ITR].CanAct()) {
3490  pActors[Actor_ITR].vVelocity.x += rand() % 100 - 50;
3491  pActors[Actor_ITR].vVelocity.y += rand() % 100 - 50;
3492  pActors[Actor_ITR].vVelocity.z += rand() % 100 - 20;
3493  pActors[Actor_ITR].uAIState = Stunned;
3494  pActors[Actor_ITR].uYawAngle += rand() % 32 - 16;
3495  pActors[Actor_ITR].UpdateAnimation();
3496  }
3497 
3498  // MOVING TOO SLOW
3499  if (pActors[Actor_ITR].vVelocity.x * pActors[Actor_ITR].vVelocity.x +
3500  pActors[Actor_ITR].vVelocity.y * pActors[Actor_ITR].vVelocity.y <
3501  400 &&
3502  Slope_High == 0) {
3503  pActors[Actor_ITR].vVelocity.y = 0;
3504  pActors[Actor_ITR].vVelocity.x = 0;
3505  }
3506 
3507 
3508  // COLLISIONS
3509  signed int Act_Radius = pActors[Actor_ITR].uActorRadius;
3510  if (!uIsFlying)
3511  Act_Radius = 40;
3512 
3513 
3514  stru_721530.field_0 = 1;
3515  stru_721530.field_84 = -1;
3516  stru_721530.field_8_radius = Act_Radius;
3517  stru_721530.prolly_normal_d = Act_Radius;
3518  stru_721530.height = pActors[Actor_ITR].uActorHeight;
3519  stru_721530.field_70 = 0;
3520 
3521  for (Model_On_PID = 0; Model_On_PID < 100; ++Model_On_PID) {
3522  stru_721530.position.x = pActors[Actor_ITR].vPosition.x;
3524  stru_721530.position.y = pActors[Actor_ITR].vPosition.y;
3526  int Act_Z_Pos = pActors[Actor_ITR].vPosition.z;
3527  stru_721530.normal.z = Act_Z_Pos + Act_Radius + 1;
3528  stru_721530.position.z = Act_Z_Pos - Act_Radius + stru_721530.height - 1;
3530  stru_721530.position.z = Act_Z_Pos + Act_Radius + 1;
3531  stru_721530.velocity.x = pActors[Actor_ITR].vVelocity.x;
3532  stru_721530.uSectorID = 0;
3533  stru_721530.velocity.y = pActors[Actor_ITR].vVelocity.y;
3534  stru_721530.velocity.z = pActors[Actor_ITR].vVelocity.z;
3535  if (stru_721530.CalcMovementExtents(0)) break;
3537  _46E26D_collide_against_sprites(WorldPosToGridCellX(pActors[Actor_ITR].vPosition.x), WorldPosToGridCellZ(pActors[Actor_ITR].vPosition.y));
3540  int v31 = 0;
3541  signed int i;
3542  for (i = 0; v31 < ai_arrays_size; ++v31) {
3543  unsigned int v33 = ai_near_actors_ids[v31];
3544  if (v33 != Actor_ITR && Actor::_46DF1A_collide_against_actor(v33, 40))
3545  ++i;
3546  }
3547  int v71 = i > 1;
3549  Slope_High =
3551  // v34 = 0;
3552  int v35 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
3553  bool bOnWater = false;
3554  int Splash_Model_On;
3555  int Splash_Floor = ODM_GetFloorLevel(
3558  pActors[Actor_ITR].uActorHeight, &bOnWater, &Splash_Model_On, 0);
3559  if (uIsOnWater) {
3560  if (v35 < Splash_Floor + 60) {
3561  if (pActors[Actor_ITR].uAIState == Dead ||
3562  pActors[Actor_ITR].uAIState == Dying ||
3563  pActors[Actor_ITR].uAIState == Removed ||
3564  pActors[Actor_ITR].uAIState == Disabled) {
3565  int Splash_Z = Floor_Level + 60;
3566  if (Splash_Model_On)
3567  Splash_Z = Splash_Floor + 30;
3568 
3570  pActors[Actor_ITR].vPosition.x, pActors[Actor_ITR].vPosition.y,
3571  Splash_Z);
3572  pActors[Actor_ITR].uAIState = Removed;
3573  return;
3574  }
3575  }
3576  }
3578  pActors[Actor_ITR].vPosition.x = (short)stru_721530.normal2.x;
3579  pActors[Actor_ITR].vPosition.y = (short)stru_721530.normal2.y;
3580  pActors[Actor_ITR].vPosition.z = (short)stru_721530.normal2.z -
3581  (short)stru_721530.prolly_normal_d -
3582  1;
3583  break;
3584  }
3585 
3586  pActors[Actor_ITR].vPosition.x +=
3588 
3589  pActors[Actor_ITR].vPosition.y +=
3591 
3592  pActors[Actor_ITR].vPosition.z +=
3595  unsigned int v39 = PID_ID(stru_721530.pid);
3596  int Angle_To_Decor;
3597  signed int Coll_Speed;
3598  switch (PID_TYPE(stru_721530.pid)) {
3599  case OBJECT_Actor:
3602  // if(pParty->bTurnBasedModeOn)
3603  // v34 = 0;
3604  if (pActors[Actor_ITR].pMonsterInfo.uHostilityType) {
3605  if (v71 == 0)
3606  Actor::AI_Flee(Actor_ITR, stru_721530.pid, 0,
3607  (AIDirection *)0);
3608  else
3609  Actor::AI_StandOrBored(Actor_ITR, 4, 0,
3610  (AIDirection *)0);
3611  } else if (v71) {
3612  Actor::AI_StandOrBored(Actor_ITR, 4, 0, (AIDirection *)0);
3613  } else if (pActors[v39].pMonsterInfo.uHostilityType ==
3615  Actor::AI_Flee(Actor_ITR, stru_721530.pid, 0,
3616  (AIDirection *)0);
3617  } else {
3618  Actor::AI_FaceObject(Actor_ITR, stru_721530.pid, 0,
3619  (AIDirection *)0);
3620  }
3621  }
3622  break;
3623  case OBJECT_Player:
3624  if (!pActors[Actor_ITR].GetActorsRelation(0)) {
3625  Actor::AI_FaceObject(Actor_ITR, stru_721530.pid, 0,
3626  (AIDirection *)0);
3627  break;
3628  }
3629 
3630  pActors[Actor_ITR].vVelocity.y = 0;
3631  pActors[Actor_ITR].vVelocity.x = 0;
3632 
3633  if (pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Active()) {
3635  }
3637  break;
3638  case OBJECT_Decoration:
3639  Coll_Speed = integer_sqrt(
3640  pActors[Actor_ITR].vVelocity.x * pActors[Actor_ITR].vVelocity.x +
3641  pActors[Actor_ITR].vVelocity.y * pActors[Actor_ITR].vVelocity.y);
3642  Angle_To_Decor = stru_5C6E00->Atan2(
3643  pActors[Actor_ITR].vPosition.x -
3644  pLevelDecorations[v39].vPosition.x,
3645  pActors[Actor_ITR].vPosition.y -
3646  pLevelDecorations[v39].vPosition.y);
3647 
3648  pActors[Actor_ITR].vVelocity.x =
3649  fixpoint_mul(stru_5C6E00->Cos(Angle_To_Decor), Coll_Speed);
3650  pActors[Actor_ITR].vVelocity.y =
3651  fixpoint_mul(stru_5C6E00->Sin(Angle_To_Decor), Coll_Speed);
3652  break;
3653  case OBJECT_BModel:
3655  .pFaces[v39 & 0x3F];
3656  if (!face->Ethereal()) {
3657  if (face->uPolygonType == 3) {
3658  pActors[Actor_ITR].vVelocity.z = 0;
3659  pActors[Actor_ITR].vPosition.z =
3660  (short)pOutdoor->pBModels[stru_721530.pid >> 9]
3661  .pVertices.pVertices[face->pVertexIDs[0]]
3662  .z +
3663  1;
3664  if (pActors[Actor_ITR].vVelocity.x *
3665  pActors[Actor_ITR].vVelocity.x +
3666  pActors[Actor_ITR].vVelocity.y *
3667  pActors[Actor_ITR].vVelocity.y <
3668  400) {
3669  pActors[Actor_ITR].vVelocity.y = 0;
3670  pActors[Actor_ITR].vVelocity.x = 0;
3671  }
3672  } else {
3673  int v72b = abs(face->pFacePlane.vNormal.y *
3674  pActors[Actor_ITR].vVelocity.y +
3675  face->pFacePlane.vNormal.z *
3676  pActors[Actor_ITR].vVelocity.z +
3677  face->pFacePlane.vNormal.x *
3678  pActors[Actor_ITR].vVelocity.x) >>
3679  16;
3680  if ((stru_721530.speed >> 3) > v72b)
3681  v72b = stru_721530.speed >> 3;
3682 
3683  pActors[Actor_ITR].vVelocity.x +=
3684  fixpoint_mul(v72b, face->pFacePlane.vNormal.x);
3685  pActors[Actor_ITR].vVelocity.y +=
3686  fixpoint_mul(v72b, face->pFacePlane.vNormal.y);
3687  pActors[Actor_ITR].vVelocity.z +=
3688  fixpoint_mul(v72b, face->pFacePlane.vNormal.z);
3689  if (face->uPolygonType != 4) {
3690  int v46 = stru_721530.prolly_normal_d -
3691  ((face->pFacePlane.dist +
3692  face->pFacePlane.vNormal.x *
3693  pActors[Actor_ITR].vPosition.x +
3694  face->pFacePlane.vNormal.y *
3695  pActors[Actor_ITR].vPosition.y +
3696  face->pFacePlane.vNormal.z *
3697  pActors[Actor_ITR].vPosition.z) >>
3698  16);
3699  if (v46 > 0) {
3700  pActors[Actor_ITR].vPosition.x += fixpoint_mul(
3701  v46, face->pFacePlane.vNormal.x);
3702  pActors[Actor_ITR].vPosition.y += fixpoint_mul(
3703  v46, face->pFacePlane.vNormal.y);
3704  pActors[Actor_ITR].vPosition.z += fixpoint_mul(
3705  v46, face->pFacePlane.vNormal.z);
3706  }
3707  pActors[Actor_ITR].uYawAngle = stru_5C6E00->Atan2(
3708  pActors[Actor_ITR].vVelocity.x,
3709  pActors[Actor_ITR].vVelocity.y);
3710  }
3711  }
3712  }
3713  break;
3714  }
3715 
3716  pActors[Actor_ITR].vVelocity.x =
3717  fixpoint_mul(58500, pActors[Actor_ITR].vVelocity.x);
3718  pActors[Actor_ITR].vVelocity.y =
3719  fixpoint_mul(58500, pActors[Actor_ITR].vVelocity.y);
3720  pActors[Actor_ITR].vVelocity.z =
3721  fixpoint_mul(58500, pActors[Actor_ITR].vVelocity.z);
3722 
3723  Act_Radius = stru_721530.prolly_normal_d;
3724  }
3725 
3726  // WATER TILE CHECKING
3727  if (!Water_Walk) {
3728  // tile on (1) tile heading (2)
3729  unsigned int Tile_1_Land = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(
3730  WorldPosToGridCellX(pActors[Actor_ITR].vPosition.x),
3731  WorldPosToGridCellZ(pActors[Actor_ITR].vPosition.y) - 1) >>
3732  1) & 1;
3733  unsigned int Tile_2_Land = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(
3734  WorldPosToGridCellX(pActors[Actor_ITR].vPosition.x +
3735  pActors[Actor_ITR].vVelocity.x),
3736  WorldPosToGridCellZ(pActors[Actor_ITR].vPosition.y +
3737  pActors[Actor_ITR].vVelocity.y) - 1) >>
3738  1) & 1;
3739 
3740  if (!uIsFlying && Tile_1_Land && !Tile_2_Land) {
3741  // approaching water - turn away
3742  if (pActors[Actor_ITR].CanAct()) {
3743  pActors[Actor_ITR].uYawAngle -= 32;
3744  pActors[Actor_ITR].uCurrentActionTime = 0;
3745  pActors[Actor_ITR].uCurrentActionLength = 128;
3746  pActors[Actor_ITR].uAIState = Fleeing;
3747  }
3748  }
3749  if (!uIsFlying && Tile_1_Land == 0 && !uIsAboveFloor && Actor_On_Terrain) {
3750  // on water and shouldnt be
3751  unsigned int Tile_Test_Land = 0; // reset land found
3752  int Grid_X = WorldPosToGridCellX(pActors[Actor_ITR].vPosition.x);
3753  int Grid_Z = WorldPosToGridCellZ(pActors[Actor_ITR].vPosition.y);
3754  for (int i = Grid_X - 1; i <= Grid_X + 1; i++) {
3755  // scan surrounding cells for land
3756  for (int j = Grid_Z - 1; j <= Grid_Z + 1; j++) {
3757  Tile_Test_Land = ((unsigned int)~pOutdoor->
3758  ActuallyGetSomeOtherTileInfo(i, j - 1) >> 1) & 1;
3759  if (Tile_Test_Land) { // found land
3760  int target_x = GridCellToWorldPosX(i);
3761  int target_y = GridCellToWorldPosZ(j - 1);
3762  if (pActors[Actor_ITR].CanAct()) { // head to land
3763  pActors[Actor_ITR].uYawAngle = stru_5C6E00->Atan2(target_x -
3764  pActors[Actor_ITR].vPosition.x, target_y -
3765  pActors[Actor_ITR].vPosition.y);
3766  pActors[Actor_ITR].uCurrentActionTime = 0;
3767  pActors[Actor_ITR].uCurrentActionLength = 128;
3768  pActors[Actor_ITR].uAIState = Fleeing;
3769  break;
3770  }
3771  }
3772  }
3773  if (Tile_Test_Land) { // break out nested loop
3774  break;
3775  }
3776  }
3777  if (!Tile_Test_Land) {
3778  // no land found so drowning damage
3779  // pActors[Actor_ITR].sCurrentHP -= 1;
3780  // logger->Warning(L"DROWNING");
3781  }
3782  }
3783  }
3784  }
3785 }

Перекрестные ссылки Actor::_46DF1A_collide_against_actor(), _46E26D_collide_against_sprites(), _46E889_collide_against_bmodels(), _46ED8A_collide_against_sprite_objects(), _46EF01_collision_chech_player(), ACTOR_BUFF_SLOWED, OutdoorLocation::ActuallyGetSomeOtherTileInfo(), ai_arrays_size, Actor::AI_FaceObject(), Actor::AI_Flee(), ai_near_actors_ids, Actor::AI_StandOrBored(), ANIM_Walking, Party::armageddon_timer, stru193_math::Atan2(), MonsterStats::BelongsToSupertype(), ViewingParams::bRedrawGameUI, Party::bTurnBasedModeOn, stru141_actor_collision_object::CalcMovementExtents(), stru193_math::Cos(), SpriteObject::Create_Splash_Object(), Dead, stru141_actor_collision_object::direction, Disabled, Dying, engine, stru141_actor_collision_object::field_0, stru141_actor_collision_object::field_6C, stru141_actor_collision_object::field_70, stru141_actor_collision_object::field_7C, stru141_actor_collision_object::field_84, stru141_actor_collision_object::field_8_radius, fixpoint_mul(), Fleeing, flt_6BE3AC_debug_recmod1_x_1_6, GetGravityStrength(), GridCellToWorldPosX(), GridCellToWorldPosZ(), stru141_actor_collision_object::height, MonsterInfo::Hostility_Friendly, integer_sqrt(), IsTerrainSlopeTooHigh(), MONSTER_SUPERTYPE_WATER_ELEMENTAL, stru141_actor_collision_object::normal, stru141_actor_collision_object::normal2, OBJECT_Actor, OBJECT_BModel, OBJECT_Decoration, OBJECT_Player, ODM_GetFloorLevel(), ODM_GetTerrainNormalAt(), pActors, PARTY_BUFF_INVISIBILITY, OutdoorLocation::pBModels, pEventTimer, stru141_actor_collision_object::pid, pLevelDecorations, stru141_actor_collision_object::position, pOutdoor, pParty, Party::pPartyBuffs, stru141_actor_collision_object::prolly_normal_d, pTurnEngine, Pursuing, Removed, stru193_math::Sin(), stru141_actor_collision_object::speed, stru_5C6E00, stru_721530, Stunned, Summoned, TE_ATTACK, TE_MOVEMENT, TE_WAIT, stru262_TurnBased::turn_stage, uNumActors, stru141_actor_collision_object::uSectorID, Timer::uTimeElapsed, stru141_actor_collision_object::velocity, viewparams, WorldPosToGridCellX() и WorldPosToGridCellZ().

Используется в ODM_UpdateUserInputAndOther().

+ Граф вызовов:
+ Граф вызова функции:

◆ ODM_ProcessPartyActions()

void ODM_ProcessPartyActions ( )

См. определение в файле Outdoor.cpp строка 2221

2221  {
2222  int v1; // edi@1
2223  int v2; // ebx@1
2224  int floor_level; // eax@14
2225  int v34; // esi@143
2226  int v35; // esi@147
2227  int v36; // eax@155
2228  int v40; // esi@162
2229  bool v42; // eax@180
2230  signed int v43; // ecx@184
2231  signed int v44; // edx@184
2232  int v45; // ecx@200
2233  BSPModel *pModel; // eax@203
2234  bool pModel_;
2235  ODMFace *pODMFace; // esi@203
2236  int v48; // eax@203
2237  int v54; // eax@215
2238  int v55; // eax@217
2239  unsigned int v66; // esi@263
2240  signed int v68; // ecx@263
2241  int v69; // eax@263
2242  bool v77; // edx@297
2243  bool v78; // ecx@303
2244  int v79; // ecx@314
2245  __int16 v80; // dx@317
2246  int pTerrainHeight; // eax@321
2247  int v87; // [sp-20h] [bp-B4h]@248
2248  int v97; // [sp+Ch] [bp-88h]@180
2249  Vec3_int_ v98;
2250  bool not_high_fall; // [sp+1Ch] [bp-78h]@33
2251  int v102; // [sp+20h] [bp-74h]@1
2252  int trigger_id = 0; // [sp+24h] [bp-70h]@1
2253  bool bFeatherFall; // [sp+28h] [bp-6Ch]@4
2254  int bonus;
2255  int on_ground; // [sp+2Ch] [bp-68h]@24
2256  bool bWaterWalk; // [sp+30h] [bp-64h]@1
2257  int ceiling_height; // [sp+3Ch] [bp-58h]@28
2258  int v110; // [sp+40h] [bp-54h]@180
2259  int v111; // [sp+44h] [bp-50h]@14
2260  bool hovering; // [sp+48h] [bp-4Ch]@1
2261  int v113; // [sp+4Ch] [bp-48h]@1
2262  bool party_running_flag; // [sp+50h] [bp-44h]@1
2263  int _walk_speed; // [sp+54h] [bp-40h]@48
2264  int pX; // [sp+58h] [bp-3Ch]@1
2265  int pY; // [sp+5Ch] [bp-38h]@1
2266  int party_new_Z; // [sp+74h] [bp-20h]@1
2267  int v118; // [sp+60h] [bp-34h]@1
2268  int _angle_x; // [sp+68h] [bp-2Ch]@48
2269  unsigned int v122; // [sp+70h] [bp-24h]@180
2270 
2271  bool party_walking_flag; // [sp+78h] [bp-1Ch]@1
2272  int _angle_y; // [sp+7Ch] [bp-18h]@48
2273  int v128; // [sp+88h] [bp-Ch]@1
2274  int v129; // [sp+8Ch] [bp-8h]@92
2275 
2276  v1 = 0;
2277  v2 = 0;
2278  // *(float *)&v128 = 0.0;
2279  int fall_speed = pParty->uFallSpeed;
2280  v128 = 0;
2281  v129 = 0;
2282 
2283  pX = pParty->vPosition.x;
2284  pY = pParty->vPosition.y;
2285  party_new_Z = pParty->vPosition.z;
2286 
2287  v113 = pParty->field_6F0;
2288  hovering = false;
2289  bool partyAtHighSlope =
2291  party_running_flag = false;
2292  party_walking_flag = false;
2293  v102 = 0;
2294  pModel_ = false;
2295  bWaterWalk = false;
2296  //************************************
2297  //Проверка падение пера
2298  if (!pParty->FeatherFallActive()) {
2299  bFeatherFall = false;
2300  for (int i = 0; i < 4; ++i)
2301  if (pParty->pPlayers[i].WearsItemAnyWhere(
2302  ITEM_ARTIFACT_LADYS_ESCORT)) { // seems like flying boots
2303  bFeatherFall = true;
2304  break;
2305  }
2306  } else {
2307  bFeatherFall = true;
2308  }
2309  //************************************
2310  //Проверка хождения по воде
2312  if (pParty->WaterWalkActive()) {
2313  bWaterWalk = true;
2315  [20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID +
2316  119] |= 1;
2317  if (!(pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags & 1) &&
2318  pParty->pPlayers
2319  [pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uCaster - 1]
2320  .sMana <= 0)
2321  bWaterWalk = false;
2322  }
2323  //*************************************
2324  //определение уровня пола
2325  int bmodel_standing_on_pid; //данные 3D model'и
2326  bool is_on_water = false; //на воду
2327  floor_level =
2328  ODM_GetFloorLevel(pX, pY, party_new_Z, pParty->uPartyHeight,
2329  &is_on_water, &bmodel_standing_on_pid, bWaterWalk);
2330  int is_not_on_bmodel = bmodel_standing_on_pid == 0; //не на 3D model
2331 
2332  v111 = floor_level; //???
2333  //************************************
2334  //определение высоты падения
2335  if (bFeatherFall) //падение пера
2336  pParty->uFallStartY = floor_level;
2337  else
2338  floor_level = pParty->uFallStartY;
2339  //*************************************
2340  //падение на 3D Model
2341  if (floor_level - party_new_Z > 512 && !bFeatherFall &&
2342  party_new_Z <= v111 + 1) {
2345  } else {
2346  for (int i = 0; i < 4; ++i) { // receive falling damage
2347  if (!pParty->pPlayers[i].HasEnchantedItemEquipped(72) &&
2349  EQUIP_BOOTS)) {
2350  pParty->pPlayers[i].ReceiveDamage(
2351  (int)((pParty->uFallStartY - party_new_Z) *
2352  (uint64_t)(pParty->pPlayers[i]
2353  .GetMaxHealth() /
2354  10)) /
2355  256,
2356  DMGT_PHISYCAL);
2357  bonus = 20 - pParty->pPlayers[i].GetParameterBonus(
2358  pParty->pPlayers[i].GetActualEndurance());
2359  pParty->pPlayers[i].SetRecoveryTime(
2360  (signed __int64)((double)bonus *
2362  2.133333333333333));
2363  }
2364  }
2365  }
2366  }
2367  //*********************************
2368  //определение высоты потолка
2369  ceiling_height = -1;
2370  if (pParty->bFlying) //в полёте
2371  ceiling_height =
2372  GetCeilingHeight(pX, pY, party_new_Z + pParty->uPartyHeight,
2373  (int)&v102); //высота потолка
2374  // v107 = bmodel_standing_on_pid == 0;
2375  on_ground = v111 + 1; //на земле
2376  //**************************************
2377 
2378  if (party_new_Z <= on_ground) { //полёт: посадка
2379  ceiling_height = -1;
2380  pParty->bFlying = false;
2381  } else {
2382  hovering = true;
2383  }
2384  not_high_fall = party_new_Z - v111 <= 32;
2385  //****************************************
2386  // timer update(обновить таймер звука ходьбы)
2387  if (!engine->config->NoWalkSound() && pParty->walk_sound_timer) {
2390  else
2391  pParty->walk_sound_timer = 0;
2392  }
2393 
2394  //****************************************
2395  // check if we should be flying
2396  if (!engine->IsUnderwater() && !pParty->pPartyBuffs[PARTY_BUFF_FLY].Active())
2397  pParty->bFlying = false;
2398 
2399  //*****************************************
2400  // установить на чём стоит группа
2401  if (!hovering) { // не в воздухе
2402  if (pParty->floor_face_pid !=
2403  PID(OBJECT_BModel, bmodel_standing_on_pid)) {
2404  if (bmodel_standing_on_pid) {
2405  int BModel_id = bmodel_standing_on_pid >> 6;
2406  if (BModel_id < pOutdoor->pBModels.size()) {
2407  int face_id = bmodel_standing_on_pid & 0x3F;
2408  if (pOutdoor->pBModels[BModel_id]
2409  .pFaces[face_id]
2410  .uAttributes &
2411  FACE_PRESSURE_PLATE) {
2413  PID(OBJECT_BModel, bmodel_standing_on_pid);
2414  trigger_id =
2415  pOutdoor->pBModels[BModel_id]
2416  .pFaces[face_id]
2417  .sCogTriggeredID; // EVT, панель имеет событие
2418  }
2419  }
2420  }
2421  }
2423  PID(OBJECT_BModel, bmodel_standing_on_pid); // 6 - на земле
2424  }
2425  //***********************************************
2426  _walk_speed = pParty->uWalkSpeed;
2427  _angle_y = pParty->sRotationY;
2428  _angle_x = pParty->sRotationX;
2429  // v126 = pEventTimer->dt_in_some_format;
2430  /*v119 = (Player **)((unsigned __int64)(pEventTimer->dt_in_some_format
2431  * (signed __int64)((signed
2432  int)(pParty->field_20_prolly_turn_speed
2433  *
2434  stru_5C6E00->uIntegerPi) / 180)) >> 16);*/
2435  __int64 dturn =
2436  (unsigned __int64)(pEventTimer->dt_in_some_format *
2437  (signed __int64)((signed int)(pParty
2438  ->y_rotation_speed *
2439  stru_5C6E00
2440  ->uIntegerPi) /
2441  180)) >>
2442  16;
2443  while (pPartyActionQueue->uNumActions) {
2444  switch (pPartyActionQueue->Next()) {
2445  case PARTY_FlyUp: //полёт вверх
2446  {
2447  if (!pParty->FlyActive() && !engine->IsUnderwater()) break;
2448 
2449  pParty->bFlying = false;
2450  if (engine->IsUnderwater() ||
2451  pParty->pPartyBuffs[PARTY_BUFF_FLY].uFlags & 1 ||
2452  (pParty->pPlayers
2453  [pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1]
2454  .sMana > 0 || engine->config->debug_all_magic)) {
2455  if (pParty->vPosition.z < engine->config->max_flight_height || hovering) {
2456  party_new_Z += 30;
2457  v113 += 30;
2458  pParty->bFlying = true;
2459  if (party_new_Z > engine->config->max_flight_height) {
2460  party_new_Z = engine->config->max_flight_height;
2461  v113 = engine->config->max_flight_height;
2462  }
2463  v1 = 0;
2464  v2 = 0;
2465  fall_speed = 0;
2466  *(float *)&v128 = 0.0;
2467  if (v102 && party_new_Z < ceiling_height &&
2468  (signed int)(pParty->uPartyHeight + party_new_Z) >=
2469  ceiling_height) { // столкновение с потолком
2470  pParty->field_6E0 = 0;
2471  pParty->field_6E4 = 0;
2474  pParty->vPosition.z =
2475  ceiling_height - pParty->uPartyHeight - 31;
2476  pParty->field_6F0 = party_new_Z;
2477  pParty->bFlying = false;
2478  party_new_Z =
2479  ceiling_height - pParty->uPartyHeight - 31;
2480  v113 = pParty->field_6F0;
2481  }
2482  pParty->uFallSpeed = 0;
2483  pModel_ = true;
2484  }
2485  }
2486  } break;
2487 
2488  case PARTY_FlyDown: //полёт вниз
2489  if (pParty->FlyActive() || engine->IsUnderwater()) {
2490  pParty->bFlying = false;
2491  if (engine->IsUnderwater() ||
2492  pParty->pPartyBuffs[PARTY_BUFF_FLY].uFlags & 1 ||
2493  pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1].sMana > 0) {
2494  // *(int *)&pParty->pArtifactsFound[6972 *
2495  // pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster + 10] > 0 )
2496  party_new_Z -= 30;
2497  v113 -= 30;
2498  pParty->uFallSpeed = 0;
2499  fall_speed = 0;
2500  pParty->bFlying = true;
2501  pModel_ = true;
2502  if (party_new_Z <= v111) {
2503  pParty->bFlying = false;
2505  }
2506  }
2507  }
2508  break;
2509 
2510  case PARTY_TurnLeft: //поворот влево
2511  if (engine->config->turn_speed > 0)
2512  _angle_y += engine->config->turn_speed; // descrete turn
2513  else
2514  _angle_y += dturn * fTurnSpeedMultiplier; // time-based smooth turn
2515 
2516  _angle_y &= stru_5C6E00->uDoublePiMask;
2517  break;
2518 
2519  case PARTY_TurnRight: //поворот вправо
2520  if (engine->config->turn_speed > 0)
2521  _angle_y -= engine->config->turn_speed;
2522  else
2523  _angle_y -= dturn * fTurnSpeedMultiplier;
2524 
2525  _angle_y &= stru_5C6E00->uDoublePiMask;
2526  break;
2527 
2528  case PARTY_FastTurnLeft: //быстрый поворот влево
2529  if (engine->config->turn_speed > 0)
2530  _angle_y += engine->config->turn_speed;
2531  else
2532  _angle_y += 2.0f * fTurnSpeedMultiplier * (double)dturn;
2533 
2534  _angle_y &= stru_5C6E00->uDoublePiMask;
2535  break;
2536 
2537  case PARTY_FastTurnRight: //быстрый поворот вправо
2538  if (engine->config->turn_speed > 0)
2539  _angle_y -= engine->config->turn_speed;
2540  else
2541  _angle_y -= 2.0f * fTurnSpeedMultiplier * (double)dturn;
2542 
2543  _angle_y &= stru_5C6E00->uDoublePiMask;
2544  break;
2545 
2546  case PARTY_StrafeLeft: //хождение боком в влево
2547  {
2548  *(float *)&v128 = pParty->uWalkSpeed;
2549 
2550  float sin_y = sinf(2 * pi_double * _angle_y / 2048.0);
2551  int dx = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
2552  v2 -= 3 * dx / 4;
2553 
2554  float cos_y = cosf(2 * pi_double * _angle_y / 2048.0);
2555  int dy = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
2556  v1 += 3 * dy / 4;
2557 
2558  v128 = v1;
2559  party_walking_flag = true;
2560  } break;
2561 
2562  case PARTY_StrafeRight: //хождение боком в вправо
2563  {
2564  *(float *)&v128 = pParty->uWalkSpeed;
2565 
2566  float sin_y = sinf(2 * pi_double * _angle_y / 2048.0);
2567  int dx = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
2568  v2 += 3 * dx / 4;
2569 
2570  float cos_y = cosf(2 * pi_double * _angle_y / 2048.0);
2571  int dy = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
2572  v1 -= 3 * dy / 4;
2573 
2574  v128 = v1;
2575  party_walking_flag = true;
2576  } break;
2577 
2578  case PARTY_WalkForward: // идти вперёд
2579  {
2580  *(float *)&v128 = _walk_speed;
2581 
2582  float sin_y = sinf(2 * pi_double * _angle_y / 2048.0),
2583  cos_y = cosf(2 * pi_double * _angle_y / 2048.0);
2584 
2585  int dx = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
2586  int dy = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
2587 
2588  if (engine->config->debug_turbo_speed) {
2589  v2 += dx * 12;
2590  v1 += dy * 12;
2591  } else {
2592  v2 += dx;
2593  v1 += dy;
2594  }
2595 
2596  v128 = v1;
2597  party_walking_flag = true;
2598  } break;
2599 
2600  case PARTY_RunForward: //бежать вперёд
2601  {
2602  *(float *)&v128 = _walk_speed;
2603 
2604  float sin_y = sinf(2 * pi_double * _angle_y / 2048.0);
2605  float cos_y = cosf(2 * pi_double * _angle_y / 2048.0);
2606 
2607  int dx = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
2608  int dy = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
2609 
2610  if (pParty->bFlying) { // лететь вперёд
2611  v2 += 4 * dx;
2612  v1 += 4 * dy;
2613 
2614  v128 = v1;
2615  } else if (partyAtHighSlope &&
2616  !bmodel_standing_on_pid) { // сбегание со склона
2617  v2 += dx;
2618  v1 += dy;
2619 
2620  v128 = v1;
2621  party_walking_flag = true;
2622  } else {
2623  /*v2 += (unsigned __int64)(stru_5C6E00->Cos(_angle_y)
2624  * (signed __int64)(signed int)(2 *
2625  (unsigned __int64)(signed __int64)((double)_walk_speed *
2626  fWalkSpeedMultiplier))) >> 16; v1 += (unsigned
2627  __int64)((signed int)stru_5C6E00->Sin(_angle_y)
2628  * (signed __int64)(signed int)(2 *
2629  (unsigned __int64)(signed __int64)((double)_walk_speed *
2630  fWalkSpeedMultiplier))) >> 16;*/
2631  if (engine->config->debug_turbo_speed) {
2632  v2 += dx * 12;
2633  v1 += dy * 12;
2634  } else {
2635  v2 += 2 * dx;
2636  v1 += 2 * dy;
2637  }
2638 
2639  v128 = v1;
2640  party_running_flag = true;
2641  }
2642  } break;
2643 
2644  case PARTY_WalkBackward: { // идти назад
2645  *(float *)&v128 = _walk_speed;
2646 
2647  float sin_y = sinf(2 * pi_double * _angle_y / 2048.0);
2648  float cos_y = cosf(2 * pi_double * _angle_y / 2048.0);
2649 
2650  int dx = cos_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier;
2651  v2 -= dx;
2652 
2653  int dy =
2655  v1 -= dy;
2656 
2657  v128 = v1;
2658  party_walking_flag = true;
2659  } break;
2660 
2661  case PARTY_RunBackward: //бежать назад
2662  {
2663  float sin_y = sinf(2 * pi_double * _angle_y / 2048.0);
2664  float cos_y = cosf(2 * pi_double * _angle_y / 2048.0);
2665 
2666  int dx =
2668  int dy =
2670 
2671  if (pParty->bFlying) {
2672  v2 -= 4 * dx;
2673  v1 -= 4 * dy;
2674  v128 = v1;
2675  } else {
2676  v2 -= dx;
2677  v1 -= dy;
2678 
2679  v128 = v1;
2680  party_walking_flag = true;
2681  }
2682  } break;
2683 
2684  case PARTY_CenterView: //смотреть прямо
2685  _angle_x = 0;
2686  break;
2687 
2688  case PARTY_LookDown: //смотреть вниз
2689  _angle_x +=
2690  (signed __int64)(flt_6BE150_look_up_down_dangle * 25.0);
2691  if (_angle_x > 128) _angle_x = 128;
2692  if (uActiveCharacter)
2693  pPlayers[uActiveCharacter]->PlaySound(SPEECH_63, 0);
2694  break;
2695 
2696  case PARTY_LookUp: //смотреть вверх
2697  _angle_x +=
2698  (signed __int64)(flt_6BE150_look_up_down_dangle * -25.0);
2699  if (_angle_x < -128) _angle_x = -128;
2700  if (uActiveCharacter)
2701  pPlayers[uActiveCharacter]->PlaySound(SPEECH_64, 0);
2702  break;
2703 
2704  case PARTY_Jump: //прыжок
2705  if ((!partyAtHighSlope || bmodel_standing_on_pid) &&
2706  !hovering && pParty->field_24 && !(pParty->uFlags & 4) &&
2707  !(pParty->uFlags & 0x200)) {
2708  // v126 = pParty->field_24 << 6;
2709  hovering = true;
2710  fall_speed += pParty->field_24 * 96;
2711  }
2712  break;
2713 
2714  case PARTY_Land: //приземление(клавиша Home)
2715  if (pParty->bFlying) {
2717  pParty->uFallSpeed = 0;
2718  }
2719  pParty->bFlying = false;
2721  break;
2722 
2723  default:
2724  assert(false);
2725  }
2726  }
2727 
2728  pParty->sRotationY = _angle_y;
2729  pParty->sRotationX = _angle_x;
2730  //-------------------------------------------
2731  if (pParty->bFlying) {
2732  v129 = fixpoint_mul(4, stru_5C6E00->Cos(OS_GetTime()));
2733  party_new_Z = v113 + v129;
2734  if (pModel_) party_new_Z = v113;
2735  if (pParty->FlyActive())
2737  [20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] &=
2738  0xFE;
2739  pParty->uFallStartY = party_new_Z;
2740  } else if (party_new_Z < v111) {
2741  if (is_on_water && fall_speed)
2742  SpriteObject::Create_Splash_Object(pX, pY, v111);
2743  fall_speed = 0;
2744  party_new_Z = v111;
2745  pParty->uFallStartY = v111;
2746  v113 = party_new_Z;
2747  if (pParty->FlyActive())
2749  [20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] |=
2750  1;
2751  } else {
2752  v113 = party_new_Z;
2753  if (pParty->FlyActive())
2755  [20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] |=
2756  1;
2757  }
2758  //------------------------------------------
2759  if (hovering && !pParty->bFlying) { // расчёт скорости падения
2760  // v33 = -(pEventTimer->uTimeElapsed * GetGravityStrength());
2761  v34 = fall_speed +
2763  fall_speed += (-(pEventTimer->uTimeElapsed * GetGravityStrength())
2764  << 1); // y(t) = 2*gt
2765  } else if (!partyAtHighSlope) {
2766  v34 = fall_speed;
2767  } else if (!hovering) {
2768  if (!bmodel_standing_on_pid) {
2769  // rolling down the hill
2770  // how it's done: you get a little bit pushed in the air along
2771  // terrain normal, getting in the air and falling to the gravity,
2772  // gradually sliding downwards. nice trick
2773  party_new_Z = v111;
2774  ODM_GetTerrainNormalAt(pX, pY, &v98);
2775  v35 = fall_speed +
2777  v129 = abs(v2 * v98.x + v1 * v98.y + v35 * v98.z) >> 16;
2778  v2 += fixpoint_mul(v129, v98.x);
2779  v1 += fixpoint_mul(v129, v98.y);
2780  v34 = v35 + fixpoint_mul(v129, v98.z);
2781  v128 = v1;
2782  fall_speed = v34;
2783  }
2784  } else {
2785  v34 = fall_speed;
2786  }
2787 
2788  if (hovering) { // блок для крика падения
2789  if (!engine->IsUnderwater() && v34 <= 0) {
2790  if (v34 < -500 && !pParty->bFlying &&
2791  pParty->vPosition.z - v111 > 1000 &&
2792  !pParty->FeatherFallActive()) { // falling scream
2793  for (int i = 0; i < 4; ++i) {
2794  if (!pParty->pPlayers[i].HasEnchantedItemEquipped(72) &&
2795  !pParty->pPlayers[i].WearsItem(
2797  pParty->pPlayers[i].CanAct())
2798  pParty->pPlayers[i].PlaySound(SPEECH_Falling_scream,
2799  0); //крик падения
2800  }
2801  }
2802  }
2803  } else {
2804  pParty->uFallStartY = party_new_Z;
2805  }
2806 
2807  if (v2 * v2 + v1 * v1 < 400 && !partyAtHighSlope) {
2808  *(float *)&v128 = 0.0;
2809  v2 = 0;
2810  }
2811  //--(столкновения)-------------------------------------------------------------------
2812  stru_721530.field_84 = -1;
2813  stru_721530.field_70 = 0;
2816  stru_721530.field_0 = 1;
2818  for (uint i = 0; i < 100; i++) {
2819  stru_721530.position.x = pX;
2820  stru_721530.position.y = pY;
2821  stru_721530.position.z = stru_721530.height + party_new_Z + 1;
2822 
2823  stru_721530.normal.x = pX;
2824  stru_721530.normal.y = pY;
2825  stru_721530.normal.z = stru_721530.prolly_normal_d + party_new_Z + 1;
2826 
2827  stru_721530.velocity.x = v2;
2828  stru_721530.velocity.y = v128;
2829  stru_721530.velocity.z = fall_speed;
2830 
2831  stru_721530.uSectorID = 0;
2832  v36 = 0;
2834  v36 = 13312;
2835  }
2836  if (stru_721530.CalcMovementExtents(v36)) break;
2838  // v37 = WorldPosToGridCellZ(pParty->vPosition.y);
2839  // v38 = WorldPosToGridCellX(pParty->vPosition.x);
2844  for (uint actor_id = 0; actor_id < (signed int)uNumActors; ++actor_id)
2847  _angle_x = stru_721530.normal2.x;
2848  _angle_y = stru_721530.normal2.y;
2850  } else {
2851  _angle_x = pX + fixpoint_mul(stru_721530.field_7C,
2853  _angle_y = pY + fixpoint_mul(stru_721530.field_7C,
2855  // pModel = (BSPModel *)fixpoint_mul(stru_721530.field_7C,
2856  // stru_721530.direction.z);
2858  party_new_Z;
2859  }
2860  v122 = v40;
2861  ODM_GetFloorLevel(_angle_x, _angle_y, v40, pParty->uPartyHeight,
2862  &is_on_water, &bmodel_standing_on_pid, 0);
2863  v129 = ODM_GetFloorLevel(_angle_x, pY, v40, pParty->uPartyHeight,
2864  &is_on_water, &v97, 0);
2865  int v119 = ODM_GetFloorLevel(pX, _angle_y, v40, pParty->uPartyHeight,
2866  &is_on_water, &v110, 0);
2867  bool v42_ = (BSPModel *)IsTerrainSlopeTooHigh(_angle_x, pY);
2868  v42 = IsTerrainSlopeTooHigh(pX, _angle_y);
2869  is_not_on_bmodel = false;
2870  // v118 = v42;
2871  if (!v97 && !v110 && !bmodel_standing_on_pid) is_not_on_bmodel = true;
2872  v43 = 1;
2873  v44 = 1;
2874  if (engine->IsUnderwater() || !is_not_on_bmodel) {
2875  pX = _angle_x;
2876  if (v43) pY = _angle_y;
2877  } else {
2878  if (v42_ && v129 > party_new_Z) v44 = 0;
2879  if (v42 && v119 > party_new_Z) v43 = 0;
2880  if (v44) {
2881  pX = _angle_x;
2882  if (v43) pY = _angle_y;
2883  } else if (v43) {
2884  pY = _angle_y;
2885  } else {
2886  int new_ = ODM_GetFloorLevel(_angle_x, _angle_y, v40,
2887  pParty->uPartyHeight, &is_on_water,
2888  &bmodel_standing_on_pid, 0);
2889  if (IsTerrainSlopeTooHigh(_angle_x, _angle_y) &&
2890  new_ <= party_new_Z) {
2891  v43 = 1;
2892  pX = _angle_x;
2893  if (v43) pY = _angle_y;
2894  }
2895  }
2896  }
2898  if (!is_not_on_bmodel) {
2899  pX = stru_721530.normal2.x;
2900  pY = stru_721530.normal2.y;
2901  }
2902  party_new_Z =
2904  break;
2905  }
2907  pX = _angle_x;
2908  pY = _angle_y;
2909  v45 = stru_721530.pid;
2910  party_new_Z = v40;
2911 
2912  if (PID_TYPE(stru_721530.pid) == OBJECT_Actor) {
2913  if (pParty->Invisible())
2915  viewparams->bRedrawGameUI = true;
2916  }
2917 
2918  if (PID_TYPE(stru_721530.pid) == OBJECT_Decoration) {
2919  v129 = stru_5C6E00->Atan2(
2920  _angle_x - pLevelDecorations[(signed int)stru_721530.pid >> 3]
2921  .vPosition.x,
2922  _angle_y - pLevelDecorations[(signed int)stru_721530.pid >> 3]
2923  .vPosition.y);
2924  v2 = fixpoint_mul(stru_5C6E00->Cos(v129),
2925  integer_sqrt(v2 * v2 + v128 * v128));
2926  v122 = fixpoint_mul(stru_5C6E00->Sin(v129),
2927  integer_sqrt(v2 * v2 + v128 * v128));
2928  v128 = fixpoint_mul(stru_5C6E00->Sin(v129),
2929  integer_sqrt(v2 * v2 + v128 * v128));
2930  }
2931 
2932  if (PID_TYPE(stru_721530.pid) == OBJECT_BModel) {
2933  pParty->bFlying = false;
2934  pModel = &pOutdoor->pBModels[(signed int)stru_721530.pid >> 9];
2935  pODMFace =
2936  &pModel->pFaces[((signed int)stru_721530.pid >> 3) & 0x3F];
2937  v48 = pODMFace->pBoundingBox.z2 - pODMFace->pBoundingBox.z1;
2938  v129 = v48 <= 32;
2939  v119 = pODMFace->pFacePlane.vNormal.z < 46378;
2940  if (engine->IsUnderwater())
2941  v119 = 0;
2942  if (pODMFace->uPolygonType == POLYGON_Floor) {
2943  if (fall_speed < 0) fall_speed = 0;
2944  party_new_Z =
2945  pModel->pVertices.pVertices[pODMFace->pVertexIDs[0]].z + 1;
2946  if (v2 * v2 + v128 * v128 < 400) {
2947  v2 = 0;
2948  *(float *)&v128 = 0.0;
2949  }
2950  if (pParty->floor_face_pid != v45 &&
2951  pODMFace->Pressure_Plate()) {
2952  pParty->floor_face_pid = v45;
2953  trigger_id =
2954  pODMFace->sCogTriggeredID; // this one triggers tour
2955  // events??
2956  }
2957  }
2958  if (!v129 &&
2960  v119)) { // упёрся в столб
2961  v118 = abs(v128 * pODMFace->pFacePlane.vNormal.y +
2962  fall_speed * pODMFace->pFacePlane.vNormal.z +
2963  v2 * pODMFace->pFacePlane.vNormal.x) >>
2964  16;
2965  if ((stru_721530.speed >> 3) > v118)
2966  v118 = stru_721530.speed >> 3;
2967  v2 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.x);
2968  v128 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.y);
2969  v54 = 0;
2970  if (!v119)
2971  v54 = fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.z);
2972  pParty->uFallSpeed += v54;
2973  v55 =
2975  ((signed int)(pODMFace->pFacePlane.dist +
2976  v122 * pODMFace->pFacePlane.vNormal.z +
2977  _angle_y * pODMFace->pFacePlane.vNormal.y +
2978  _angle_x * pODMFace->pFacePlane.vNormal.x) >>
2979  16);
2980  if (v55 > 0) {
2981  pX = _angle_x +
2982  fixpoint_mul(pODMFace->pFacePlane.vNormal.x, v55);
2983  pY = _angle_y +
2984  fixpoint_mul(pODMFace->pFacePlane.vNormal.y, v55);
2985  if (!v119)
2986  party_new_Z =
2987  v122 +
2988  fixpoint_mul(pODMFace->pFacePlane.vNormal.z, v55);
2989  }
2991  pODMFace->Pressure_Plate()) {
2993  trigger_id = pODMFace->sCogTriggeredID; //
2994  }
2995  }
2996  if (pODMFace->uPolygonType == POLYGON_InBetweenFloorAndWall) {
2997  v118 = abs(v128 * pODMFace->pFacePlane.vNormal.y +
2998  fall_speed * pODMFace->pFacePlane.vNormal.z +
2999  v2 * pODMFace->pFacePlane.vNormal.x) >>
3000  16;
3001  if ((stru_721530.speed >> 3) > v118)
3002  v118 = stru_721530.speed >> 3;
3003  v2 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.x);
3004  v128 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.y);
3005  fall_speed +=
3006  fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.z);
3007  if (v2 * v2 + v128 * v128 >= 400) {
3009  pODMFace->Pressure_Plate()) {
3011  trigger_id = pODMFace->sCogTriggeredID; //
3012  }
3013  } else {
3014  v2 = 0;
3015  fall_speed = 0;
3016  *(float *)&v128 = 0.0;
3017  }
3018  }
3019  }
3020  v2 = fixpoint_mul(58500, v2);
3021  v128 = fixpoint_mul(58500, v128);
3022  v122 = fixpoint_mul(58500, v122);
3023  fall_speed = fixpoint_mul(58500, fall_speed);
3024  }
3025 
3026  //Воспроизведение звуков ходьбы/бега------------------------
3027  uint pX_ = abs(pParty->vPosition.x - pX);
3028  uint pY_ = abs(pParty->vPosition.y - pY);
3029  uint pZ_ = abs(pParty->vPosition.z - party_new_Z);
3030  if (!engine->config->NoWalkSound() && pParty->walk_sound_timer <= 0) {
3031  pAudioPlayer->StopAll(804); // stop sound
3032  if (party_running_flag && (!hovering || not_high_fall)) {
3033  if (integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 16) {
3034  if (!is_not_on_bmodel &&
3036  .pFaces[(pParty->floor_face_pid >> 3) & 0x3F].Visible()) {
3037  pAudioPlayer->PlaySound(SOUND_RunWood, -1 /*804*/, 1, -1, 0, 0); //бег на 3D Modelи
3038  } else {
3041  WorldPosToGridCellZ(pParty->vPosition.y) - 1, 1);
3042  pAudioPlayer->PlaySound((SoundID)v87, -1 /*804*/, 1, -1, 0, 0); //бег по земле 56
3043  }
3044  pParty->walk_sound_timer = 96; // таймер для бега
3045  }
3046  } else if (party_walking_flag && (!hovering || not_high_fall)) {
3047  if (integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 8) {
3048  if (!is_not_on_bmodel &&
3050  .pFaces[(pParty->floor_face_pid >> 3) & 0x3F].Visible()) {
3051  pAudioPlayer->PlaySound(SOUND_WalkWood, -1 /*804*/, 1, -1, 0, 0); // хождение на 3D Modelи
3052  } else {
3055  WorldPosToGridCellZ(pParty->vPosition.y) - 1, 0);
3056  pAudioPlayer->PlaySound((SoundID)v87, -1 /*804*/, 1, -1, 0, 0); // хождение по земле
3057  }
3058  pParty->walk_sound_timer = 144; // таймер для ходьбы
3059  }
3060  }
3061  }
3062 
3063  if (integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) < 8) //отключить звук ходьбы при остановке
3064  pAudioPlayer->StopAll(804);
3065  //------------------------------------------------------------------------
3066  if (!hovering || !not_high_fall) // или не высокое падение
3068  else
3070  int pMap_X = WorldPosToGridCellX(pParty->vPosition.x);
3071  int pMap_Y = WorldPosToGridCellZ(pParty->vPosition.y) - 1;
3072  unsigned int v114_a = WorldPosToGridCellX(pX);
3073  v66 = WorldPosToGridCellZ(pY) - 1;
3074  unsigned int v122_a = (~(unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(pMap_X, pMap_Y) / 2) & 1;
3075  v122 = (~(unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(v114_a, pMap_Y) / 2) & 1;
3076  v69 = (~(unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(pMap_X, v66) / 2) & 1;
3077 
3078  //-(обновление координат группы)---------------------------------------
3079  v68 = 0;
3080  if (v114_a == pMap_X && v66 == pMap_Y && v122 && v69) v68 = 1;
3081  if (!is_not_on_bmodel) // на bmodel,и
3082  v68 = 1;
3083  if (v68) {
3084  pParty->vPosition.x = pX;
3085  pParty->vPosition.y = pY;
3086  pParty->vPosition.z = party_new_Z;
3087  pParty->field_6F0 = v113;
3088  pParty->uFallSpeed = fall_speed;
3089  if (party_new_Z > 8160) { // ограничение высоты
3090  party_new_Z = 8160;
3091  pParty->uFallStartY = 8160;
3092  pParty->vPosition.z = 8160;
3093  }
3094 
3095  if (!trigger_id //падение на землю
3096  || (EventProcessor(trigger_id, 0, 1), pParty->vPosition.x == pX) &&
3097  pParty->vPosition.y == pY &&
3098  pParty->vPosition.z == party_new_Z) {
3099  if (pParty->vPosition.z < v111) {
3100  pParty->uFallSpeed = 0;
3101  // v73 = v105;
3102  pParty->vPosition.z = on_ground;
3103  if (pParty->uFallStartY - party_new_Z > 512 && !bFeatherFall &&
3104  party_new_Z <= on_ground &&
3105  !engine->IsUnderwater()) { // Fall to the ground(падение на землю с
3106  // высоты)
3109  } else {
3110  for (uint i = 1; i <= 4; ++i) {
3111  pPlayers[i]->ReceiveDamage(
3112  (int)((pParty->uFallStartY -
3113  party_new_Z) *
3114  (uint64_t)((double)pPlayers[i]->GetMaxHealth() * 0.1)) /
3115  256,
3116  DMGT_PHISYCAL);
3117  v110 = 20 - pPlayers[i]->GetParameterBonus(
3118  pPlayers[i]->GetActualEndurance());
3119  pPlayers[i]->SetRecoveryTime(
3120  (signed __int64)((double)v110 *
3122  2.133333333333333));
3123  }
3124  // v73 = pParty->vPosition.z;
3125  }
3126  }
3127  pParty->uFallStartY = party_new_Z;
3128  }
3129  if (v102 && pParty->vPosition.z < ceiling_height) {
3130  if ((signed int)(pParty->uPartyHeight + pParty->vPosition.z) >=
3131  ceiling_height) {
3132  pParty->vPosition.z =
3133  ceiling_height - pParty->uPartyHeight - 1;
3134  pParty->field_6F0 =
3135  ceiling_height - pParty->uPartyHeight - 1;
3136  }
3137  }
3138  pParty->uFlags &= ~0x204;
3139  }
3140  return;
3141  }
3142  //-----------------------------------------------------------------
3143  // v76 = pParty->bFlying;
3144  if (pParty->bFlying || !not_high_fall || bWaterWalk ||
3145  !v122_a) // полёт или высокое падение или хождение по воде или
3146  v77 = 1;
3147  else
3148  v77 = v122 != 0;
3149  bool party_drowning_flag = false;
3150  if (!pParty->bFlying && not_high_fall &&
3151  !bWaterWalk) { // не полёт и не высокое падение и не хождение по воде
3152  if (v122_a) {
3153  v78 = v69 != 0;
3154  } else {
3155  party_drowning_flag = true; //утопление
3156  v78 = true;
3157  }
3158  } else {
3159  v78 = true;
3160  }
3161 
3162  if (v77) pParty->vPosition.x = pX;
3163  if (v78) pParty->vPosition.y = pY;
3164 
3165  if (v78 || v77) {
3166  if (bWaterWalk) {
3168  // v79 = 20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID
3169  // + 6180178;
3170  // *(short *)&stru_5E4C90._decor_events[20 *
3171  // pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID + 119] |=
3172  // 1u;
3173  v79 =
3175  [20 *
3177  119];
3178  *(short *)v79 |= 1;
3179  if (!v122 || !v69) {
3180  if (!pParty->bFlying) {
3181  v80 = *(short *)v79;
3183  *(short *)v79 = v80 & 0xFFFE;
3184  }
3185  }
3186  }
3187  } else if (!engine->config->NoWalkSound() && pParty->walk_sound_timer <= 0) {
3188  pAudioPlayer->StopAll(804);
3189  pParty->walk_sound_timer = 64;
3190  }
3191 
3192  // v81 = pZ;
3193  // v82 = pZ;
3194  pParty->vPosition.z = party_new_Z;
3195  if (party_new_Z > 8160) { // опять ограничение высоты
3196  // v82 = 8160;
3197  pParty->uFallStartY = 8160;
3198  pParty->vPosition.z = 8160;
3199  }
3200  HEXRAYS_LOWORD(pParty->uFlags) &= 0xFDFBu;
3201  pParty->uFallSpeed = fall_speed;
3202  pParty->field_6F0 = v113;
3203  if (party_drowning_flag) { // группа тонет
3204  bool onWater = false;
3205  pTerrainHeight = GetTerrainHeightsAroundParty2(pParty->vPosition.x, pParty->vPosition.y, &onWater, 1);
3206  if (pParty->vPosition.z <= pTerrainHeight + 1) { //положение группы всегда +1
3208  }
3209  }
3210 
3211  if (!trigger_id //падение на воду
3212  ||
3213  (EventProcessor(trigger_id, 0, 1), pParty->vPosition.x == pX) &&
3214  pParty->vPosition.y == pY && pParty->vPosition.z == party_new_Z) {
3215  if (pParty->vPosition.z < v111) {
3216  // v82 = on_ground;
3217  pParty->uFallSpeed = 0;
3218  pParty->vPosition.z = on_ground;
3219  if (pParty->uFallStartY - party_new_Z > 512 && !bFeatherFall &&
3220  party_new_Z <= on_ground &&
3221  !engine->IsUnderwater()) { // Fall to the water(падение на воду с высоты)
3224  } else {
3225  for (uint i = 1; i <= 4; ++i) {
3226  v110 = pPlayers[i]->GetMaxHealth();
3227  pPlayers[i]->ReceiveDamage(
3228  (int)((pParty->uFallStartY - party_new_Z) *
3229  (uint64_t)((double)v110 * 0.1)) / 256,
3230  DMGT_PHISYCAL);
3231  v110 = 20 - pPlayers[i]->GetParameterBonus(
3232  pPlayers[i]->GetActualEndurance());
3233  pPlayers[i]->SetRecoveryTime(
3234  (signed __int64)((double)v110 *
3236  2.133333333333333));
3237  }
3238  // v82 = pParty->vPosition.z;
3239  }
3240  }
3241  pParty->uFallStartY = party_new_Z;
3242  }
3243  if (v102 && pParty->vPosition.z < ceiling_height &&
3244  (signed int)(pParty->uPartyHeight + pParty->vPosition.z) >=
3245  ceiling_height) {
3246  pParty->vPosition.z =
3247  pParty->vPosition.z + pParty->uPartyHeight - ceiling_height + 1;
3248  pParty->field_6F0 =
3249  pParty->vPosition.z + pParty->uPartyHeight - ceiling_height + 1;
3250  }
3251  }
3252 }

Перекрестные ссылки Actor::_46DF1A_collide_against_actor(), _46E26D_collide_against_sprites(), _46E889_collide_against_bmodels(), _46ED8A_collide_against_sprite_objects(), stru123::_decor_events, OutdoorLocation::ActuallyGetSomeOtherTileInfo(), stru193_math::Atan2(), Party::bFlying, ViewingParams::bRedrawGameUI, Party::bTurnBasedModeOn, stru141_actor_collision_object::CalcMovementExtents(), stru193_math::Cos(), SpriteObject::Create_Splash_Object(), stru141_actor_collision_object::direction, Plane_int_::dist, DMGT_PHISYCAL, Timer::dt_in_some_format, engine, EQUIP_BOOTS, EventProcessor(), fBackwardWalkSpeedMultiplier, Party::FeatherFallActive(), stru141_actor_collision_object::field_0, Party::field_14_radius, Party::field_24, stru141_actor_collision_object::field_6C, Party::field_6E0, Party::field_6E4, Party::field_6F0, stru141_actor_collision_object::field_70, stru141_actor_collision_object::field_7C, stru141_actor_collision_object::field_84, stru141_actor_collision_object::field_8_radius, fixpoint_mul(), Party::floor_face_pid, flt_6BE150_look_up_down_dangle, flt_6BE3A4_debug_recmod1, Party::FlyActive(), fTurnSpeedMultiplier, fWalkSpeedMultiplier, GetCeilingHeight(), GetGravityStrength(), OutdoorLocation::GetSoundIdByPosition(), GetTerrainHeightsAroundParty2(), stru141_actor_collision_object::height, integer_sqrt(), Party::Invisible(), IsTerrainSlopeTooHigh(), ITEM_ARTIFACT_HERMES_SANDALS, ITEM_ARTIFACT_LADYS_ESCORT, ActionQueue::Next(), stru141_actor_collision_object::normal, stru141_actor_collision_object::normal2, OBJECT_Actor, OBJECT_BModel, OBJECT_Decoration, ODM_GetFloorLevel(), ODM_GetTerrainNormalAt(), OS_GetTime(), PARTY_BUFF_FLY, PARTY_BUFF_INVISIBILITY, PARTY_BUFF_WATER_WALK, PARTY_CenterView, PARTY_FastTurnLeft, PARTY_FastTurnRight, PARTY_FLAGS_1_FALLING, PARTY_FLAGS_1_LANDING, PARTY_FLAGS_1_STANDING_ON_WATER, PARTY_FLAGS_1_WATER_DAMAGE, PARTY_FlyDown, PARTY_FlyUp, PARTY_Jump, PARTY_Land, PARTY_LookDown, PARTY_LookUp, PARTY_RunBackward, PARTY_RunForward, PARTY_StrafeLeft, PARTY_StrafeRight, PARTY_TurnLeft, PARTY_TurnRight, PARTY_WalkBackward, PARTY_WalkForward, pAudioPlayer, OutdoorLocation::pBModels, ODMFace::pBoundingBox, pEventTimer, ODMFace::pFacePlane, BSPModel::pFaces, stru141_actor_collision_object::pid, AudioPlayer::PlaySound(), pLevelDecorations, POLYGON_Floor, POLYGON_InBetweenFloorAndWall, stru141_actor_collision_object::position, pOutdoor, pParty, pPartyActionQueue, Party::pPartyBuffs, pPlayers, Party::pPlayers, ODMFace::Pressure_Plate(), stru141_actor_collision_object::prolly_normal_d, pTurnEngine, ODMFace::pVertexIDs, BSPVertexBuffer::pVertices, BSPModel::pVertices, ODMFace::sCogTriggeredID, stru193_math::Sin(), SOUND_RunWood, SOUND_WalkWood, SPEECH_63, SPEECH_64, SPEECH_Falling_scream, stru141_actor_collision_object::speed, Party::sRotationX, Party::sRotationY, AudioPlayer::StopAll(), stru_5C6E00, stru_5E4C90_MapPersistVars, stru_721530, TE_MOVEMENT, stru262_TurnBased::turn_stage, uActiveCharacter, stru193_math::uDoublePiMask, Party::uFallSpeed, Party::uFallStartY, Party::uFlags, ActionQueue::uNumActions, uNumActors, Party::uPartyHeight, ODMFace::uPolygonType, stru141_actor_collision_object::uSectorID, Timer::uTimeElapsed, Party::uWalkSpeed, stru141_actor_collision_object::velocity, viewparams, Plane_int_::vNormal, Party::vPosition, Party::walk_sound_timer, Party::WaterWalkActive(), WorldPosToGridCellX(), WorldPosToGridCellZ(), BBox_short_::z1 и BBox_short_::z2.

Используется в ODM_UpdateUserInputAndOther().

+ Граф вызовов:
+ Граф вызова функции:

◆ Is_out15odm_underwater()

char Is_out15odm_underwater ( )

См. определение в файле Outdoor.cpp строка 3377

3377  {
3378  return (pCurrentMapName == "out15.odm");
3379 }

Перекрестные ссылки pCurrentMapName.

Используется в DoPrepareWorld(), Application::Game::EventLoop(), OutdoorLocation::Initialize(), PrepareToLoadBLV() и OutdoorLocation::SetFog().

+ Граф вызова функции:

◆ SetUnderwaterFog()

void SetUnderwaterFog ( )

См. определение в файле Outdoor.cpp строка 3382

3382  {
3383  day_fogrange_1 = 50;
3384  day_fogrange_2 = 5000;
3385 }

Перекрестные ссылки day_fogrange_1 и day_fogrange_2.

Используется в OutdoorLocation::Initialize() и OutdoorLocation::SetFog().

+ Граф вызова функции:

◆ ODM_Project()

void ODM_Project ( unsigned int  uNumVertices)

См. определение в файле Outdoor.cpp строка 2180

2180  {
2181  for (uint i = 0; i < uNumVertices; i++) {
2182  memcpy(&VertexRenderList[i], &array_507D30[i],
2183  sizeof(VertexRenderList[i]));
2185  (double)pViewport->uScreenCenterX -
2186  ((double)pODMRenderParams->int_fov_rad * array_507D30[i]._rhw) *
2187  array_507D30[i].vWorldViewPosition.y;
2189  (double)pViewport->uScreenCenterY -
2190  ((double)pODMRenderParams->int_fov_rad * array_507D30[i]._rhw) *
2192  }
2193 }

Перекрестные ссылки RenderVertexSoft::_rhw, array_507D30, ODMRenderParams::int_fov_rad, pODMRenderParams, pViewport, Viewport::uScreenCenterX, Viewport::uScreenCenterY, VertexRenderList, RenderVertexSoft::vWorldViewPosition, RenderVertexSoft::vWorldViewProjX, RenderVertexSoft::vWorldViewProjY и Vec3_float_::z.

Используется в Render::DrawBuildingsD3D().

+ Граф вызова функции:

◆ sub_487DA9()

void sub_487DA9 ( )

См. определение в файле Outdoor.cpp строка 3388

3388  {
3389  // for (int i = 0; i < 20000; ++i) array_77EC08[i].field_108 = 0;
3390 }

◆ ODM_LoadAndInitialize()

void ODM_LoadAndInitialize ( const String pLevelFilename,
struct ODMRenderParams thisa 
)

См. определение в файле Outdoor.cpp строка 3788

3788  {
3789  MapInfo *v4; // edi@4
3790  // size_t v7; // eax@19
3791 
3792  // thisa->AllocSoftwareDrawBuffers();
3794  pWeather->bRenderSnow = false;
3795  render->ClearZBuffer(0, 479);
3796  // thisa = (ODMRenderParams *)1;
3797  GetAlertStatus();
3800  unsigned int respawn_interval = 0;
3801  if (v2) {
3802  v4 = &pMapStats->pInfos[v2];
3803  respawn_interval = v4->uRespawnIntervalDays;
3804  } else {
3805  v4 = (MapInfo*)1;
3806  }
3807  day_attrib &= ~DAY_ATTRIB_FOG;
3809  int v;
3810  pOutdoor->Initialize(pFilename, pParty->GetPlayingTime().GetDays() + 1, respawn_interval, &v);
3811  if (!(dword_6BE364_game_settings_1 & GAME_SETTINGS_2000)) {
3814  }
3815  dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_2000;
3816  // v5 = 0;
3817  if (!v2) v = 0;
3818  if (v == 1) {
3819  // v13 = 0;
3820  for (uint i = 0; i < pOutdoor->uNumSpawnPoints; ++i) {
3821  SpawnPointMM7 *spawn = pOutdoor->pSpawnPoints + i;
3822 
3823  if (spawn->IsMonsterSpawn())
3824  SpawnEncounter(v4, spawn, 0, 0, 0);
3825  else
3826  v4->SpawnRandomTreasure(spawn);
3827  }
3829  }
3833  pOutdoor->MessWithLUN();
3834  pOutdoor->level_filename = pFilename;
3835  pWeather->Initialize();
3838  // pODMRenderParams->RotationToInts();
3840 
3841  float fov_rad;
3842  float fov_rad_inv;
3843  //----- (0042394D) --------------------------------------------------------
3844  // void IndoorCamera::Initialize(int degFov, unsigned int uViewportWidth,
3845  // unsigned int uViewportHeight)
3846  {
3847  // pIndoorCamera->Initialize(65, viewparams->uScreen_BttmR_X -
3848  // viewparams->uScreen_topL_X + 1,
3849  // viewparams->uScreen_BttmR_Y -
3850  // viewparams->uScreen_topL_Y + 1);
3851 
3852  int uViewportWidth =
3854 
3855  extern float _calc_fov(int viewport_width, int angle_degree);
3856  fov_rad = _calc_fov(uViewportWidth, 65);
3857  fov_rad_inv = 65536.0 / fov_rad;
3858  }
3859  pODMRenderParams->int_fov_rad = (signed __int64)fov_rad;
3860  pODMRenderParams->int_fov_rad_inv = (signed __int64)fov_rad_inv;
3861 
3862  for (int i = 0; i < 20000; ++i) {
3863  array_77EC08[i].ptr_38 = &SkyBillboard;
3864 
3865  array_77EC08[i].ptr_48 = nullptr;
3866  }
3867 
3869 }

Перекрестные ссылки _A750D8_player_speech_timer, _calc_fov(), OutdoorLocation::ArrangeSpriteObjects(), array_77EC08, Weather::bRenderSnow, day_attrib, dword_6BE13C_uCurrentlyLoadedLocationID, dword_6BE364_game_settings_1, GetAlertStatus(), GameTime::GetDays(), MapStats::GetMapInfo(), Party::GetPlayingTime(), OutdoorLocation::InitalizeActors(), Weather::Initialize(), ODMRenderParams::Initialize(), OutdoorLocation::Initialize(), Actor::InitializeActors(), SpriteObject::InitializeSpriteObjects(), ODMRenderParams::int_fov_rad, ODMRenderParams::int_fov_rad_inv, SpawnPointMM7::IsMonsterSpawn(), OutdoorLocation::level_filename, OutdoorLocation::MessWithLUN(), MM7Initialization(), pCurrentMapName, pIndoorCameraD3D, MapStats::pInfos, pMapStats, pODMRenderParams, pOutdoor, pParty, OutdoorLocation::PrepareDecorations(), OutdoorLocation::pSpawnPoints, pWeather, render, RespawnGlobalDecorations(), SkyBillboard, SpawnEncounter(), MapInfo::SpawnRandomTreasure(), IndoorCameraD3D::sRotationX, Party::sRotationX, IndoorCameraD3D::sRotationY, Party::sRotationY, OutdoorLocation::uNumSpawnPoints, OutdoorLocation::UpdateSunlightVectors(), MapInfo::uRespawnIntervalDays, ViewingParams::uScreen_BttmR_X, ViewingParams::uScreen_topL_X и viewparams.

Используется в PrepareToLoadODM().

+ Граф вызовов:
+ Граф вызова функции:

◆ GetLevelFogColor()

unsigned int GetLevelFogColor ( )

См. определение в файле Outdoor.cpp строка 3871

3871  {
3872  if (engine->IsUnderwater()) {
3873  return 0xFF258F5C;
3874  }
3875 
3876  if (day_attrib & DAY_ATTRIB_FOG) {
3877  if (pWeather->bNight) { // night-time fog
3878  if (false) {
3879  logger->Warning(
3880  L"decompilation can be inaccurate, please send savegame to "
3881  L"Nomad");
3882  __debugbreak();
3883  }
3884  int v2 = -(pWeather->bNight != 1);
3885  return (v2 & 0xE0E0E1) - 0xE0E0E1;
3886  } else {
3887  __int64 v1 = (__int64)((1.0 - pOutdoor->fFogDensity) * 200.0 +
3888  pOutdoor->fFogDensity * 31.0);
3889  return v1 |
3890  (((unsigned int)v1 | (((unsigned int)v1 | 0xFFFFFF00) << 8))
3891  << 8);
3892  }
3893  }
3894 
3895  return 0;
3896 }

Перекрестные ссылки __debugbreak(), Weather::bNight, day_attrib, engine, OutdoorLocation::fFogDensity, logger, pOutdoor, pWeather и Log::Warning().

Используется в Engine::_44EEA7(), Render::BeginSceneD3D(), RenderOpenGL::DoRenderBillboards_D3D(), Render::DoRenderBillboards_D3D(), Render::DrawPolygon(), Render::DrawTerrainPolygon(), RenderOpenGL::SetBillboardBlendOptions() и Render::SetBillboardBlendOptions().

+ Граф вызовов:
+ Граф вызова функции:

◆ sub_47C3D7_get_fog_specular()

int sub_47C3D7_get_fog_specular ( int  a1,
int  a2,
float  a3 
)

См. определение в файле Outdoor.cpp строка 3898

3898  {
3899  int v7;
3900 
3901  int v3 = pWeather->bNight;
3902  if (engine->IsUnderwater())
3903  v3 = 0;
3904  if (pParty->armageddon_timer ||
3905  !(day_attrib & DAY_ATTRIB_FOG) && !engine->IsUnderwater())
3906  return 0xFF000000;
3907  if (v3) {
3908  if (a3 < (double)day_fogrange_1) {
3909  v7 = 0;
3910  if (a3 == 0.0) v7 = 216;
3911  if (a2) v7 = 248;
3912  return (-1 - v7) << 24;
3913  } else {
3914  if (a3 > (double)day_fogrange_2) {
3915  v7 = 216;
3916  if (a3 == 0.0) v7 = 216;
3917  if (a2) v7 = 248;
3918  return (-1 - v7) << 24;
3919  }
3920  v7 = (signed __int64)((a3 - (double)day_fogrange_1) /
3921  ((double)day_fogrange_2 -
3922  (double)day_fogrange_1) *
3923  216.0);
3924  }
3925  } else {
3926  if (a3 < (double)day_fogrange_1) {
3927  v7 = 0;
3928  if (a3 == 0.0) v7 = 216;
3929  if (a2) v7 = 248;
3930  return (-1 - v7) << 24;
3931  } else {
3932  if (a3 > (double)day_fogrange_2) {
3933  v7 = 216;
3934  if (a3 == 0.0) v7 = 216;
3935  if (a2) v7 = 248;
3936  return (-1 - v7) << 24;
3937  } else {
3938  v7 =
3939  floorf(((a3 - (double)day_fogrange_1) * 216.0 /
3940  ((double)day_fogrange_2 - (double)day_fogrange_1)) +
3941  0.5f);
3942  }
3943  }
3944  }
3945  if (v7 > 216) {
3946  v7 = 216;
3947  } else {
3948  if (a3 == 0.0) v7 = 216;
3949  }
3950  if (a2) v7 = 248;
3951  return (-1 - v7) << 24;
3952 }

Перекрестные ссылки Party::armageddon_timer, Weather::bNight, day_attrib, day_fogrange_1, day_fogrange_2, engine, pParty и pWeather.

Используется в Render::DrawOutdoorSkyPolygon(), RenderOpenGL::DrawPolygon(), Render::DrawPolygon(), Render::DrawTerrainPolygon() и RenderBase::TransformBillboard().

+ Граф вызова функции:

◆ WorldPosToGridCellX()

unsigned int WorldPosToGridCellX ( int  )

См. определение в файле Outdoor.cpp строка 3955

3955  {
3956  return (sWorldPosX >> 9) +
3957  64; // sar is in original exe, resulting -880 / 512 = -1
3958  // and -880 sar 9 = -2
3959 }

Используется в OutdoorLocation::ExecDraw(), OutdoorLocation::GetNumFoodRequiredToRestInCurrentPos(), OutdoorLocation::GetSomeOtherTileInfo(), GetTerrainHeightsAroundParty2(), OutdoorLocation::GetTile(), IsTerrainSlopeTooHigh(), ODM_GetTerrainNormalAt(), ODM_ProcessPartyActions(), RenderOpenGL::RenderTerrainD3D(), UpdateActors_ODM() и SpriteObject::UpdateObject_fn0_ODM().

+ Граф вызова функции:

◆ WorldPosToGridCellZ()

unsigned int WorldPosToGridCellZ ( int  )

См. определение в файле Outdoor.cpp строка 3962

3962  {
3963  return 64 - (sWorldPosZ >>
3964  9); // sar is in original exe, resulting -880 / 512 = -1
3965  // and -880 sar 9 = -2
3966 }

Используется в OutdoorLocation::ExecDraw(), OutdoorLocation::GetNumFoodRequiredToRestInCurrentPos(), OutdoorLocation::GetSomeOtherTileInfo(), GetTerrainHeightsAroundParty2(), OutdoorLocation::GetTile(), IsTerrainSlopeTooHigh(), ODM_GetTerrainNormalAt(), ODM_ProcessPartyActions(), RenderOpenGL::RenderTerrainD3D(), UpdateActors_ODM() и SpriteObject::UpdateObject_fn0_ODM().

+ Граф вызова функции:

◆ GridCellToWorldPosX()

int GridCellToWorldPosX ( int  )

См. определение в файле Outdoor.cpp строка 3969

3969 { return (a1 - 64) << 9; }

Используется в GetTerrainHeightsAroundParty2(), IsTerrainSlopeTooHigh(), ODM_GetTerrainNormalAt() и UpdateActors_ODM().

+ Граф вызова функции:

◆ GridCellToWorldPosZ()

int GridCellToWorldPosZ ( int  )

См. определение в файле Outdoor.cpp строка 3972

3972 { return (64 - a1) << 9; }

Используется в GetTerrainHeightsAroundParty2(), IsTerrainSlopeTooHigh(), ODM_GetTerrainNormalAt() и UpdateActors_ODM().

+ Граф вызова функции:

◆ sub_481ED9_MessWithODMRenderParams()

void sub_481ED9_MessWithODMRenderParams ( )

◆ IsTerrainSlopeTooHigh()

bool IsTerrainSlopeTooHigh ( int  pos_x,
int  pos_y 
)

См. определение в файле Outdoor.cpp строка 3976

3976  {
3977  // unsigned int v2; // ebx@1
3978  // unsigned int v3; // edi@1
3979  // int v4; // eax@1
3980  // int v6; // esi@5
3981  // int v7; // ecx@6
3982  // int v8; // edx@6
3983  // int v9; // eax@6
3984  // int y_min; // esi@10
3985  // int v11; // [sp+14h] [bp-8h]@1
3986  // int v12; // [sp+18h] [bp-4h]@1
3987 
3988  // v12 = a1;
3989  // v11 = a2;
3990  unsigned int grid_x = WorldPosToGridCellX(pos_x);
3991  unsigned int grid_z = WorldPosToGridCellZ(pos_z) - 1;
3992 
3993  int party_grid_x1 = GridCellToWorldPosX(grid_x);
3994  // dword_76D56C_terrain_cell_world_pos_around_party_x =
3995  // GridCellToWorldPosX(grid_x + 1);
3996  // dword_76D570_terrain_cell_world_pos_around_party_x =
3997  // GridCellToWorldPosX(grid_x + 1);
3998  // dword_76D574_terrain_cell_world_pos_around_party_x =
3999  // GridCellToWorldPosX(grid_x);
4000  int party_grid_z1 = GridCellToWorldPosZ(grid_z);
4001  // dword_76D55C_terrain_cell_world_pos_around_party_z =
4002  // GridCellToWorldPosZ(grid_z);
4003  // dword_76D560_terrain_cell_world_pos_around_party_z =
4004  // GridCellToWorldPosZ(grid_z + 1);
4005  // dword_76D564_terrain_cell_world_pos_around_party_z =
4006  // GridCellToWorldPosZ(grid_z + 1);
4007  int party_x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z);
4008  int party_x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z);
4009  int party_x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1);
4010  int party_x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1);
4011  // dword_76D554_terrain_cell_world_pos_around_party_y = v4;
4012  if (party_x1z1_y == party_x2z1_y && party_x2z1_y == party_x2z2_y &&
4013  party_x2z2_y == party_x1z2_y)
4014  return false;
4015 
4016  int dx = abs(pos_x - party_grid_x1), dz = abs(party_grid_z1 - pos_z);
4017 
4018  int y1, y2, y3;
4019  if (dz >= dx) {
4020  y1 = party_x1z2_y;
4021  y2 = party_x2z2_y;
4022  y3 = party_x1z1_y;
4023  /* lower-left triangle
4024  y3 | \
4025  | \
4026  | \
4027  |______ \
4028  y1 y2 */
4029  } else {
4030  y1 = party_x2z1_y; // upper-right
4031  y2 = party_x1z1_y; // y2_______ y1
4032  y3 = party_x2z2_y; // \ |
4033  /* \ |
4034  \ |
4035  y3 */
4036  }
4037 
4038  int y_min = std::min(y1, std::min(y2, y3)); // не верно при подъёме на склон
4039  int y_max = std::max(y1, std::max(y2, y3));
4040  return (y_max - y_min) > 512;
4041 }

Перекрестные ссылки OutdoorLocation::DoGetHeightOnTerrain(), GridCellToWorldPosX(), GridCellToWorldPosZ(), pOutdoor, WorldPosToGridCellX() и WorldPosToGridCellZ().

Используется в ODM_ProcessPartyActions(), UpdateActors_ODM() и SpriteObject::UpdateObject_fn0_ODM().

+ Граф вызовов:
+ Граф вызова функции:

◆ GetTerrainHeightsAroundParty2()

int GetTerrainHeightsAroundParty2 ( int  a1,
int  a2,
bool *  a3,
int  a4 
)

См. определение в файле Outdoor.cpp строка 4044

4044  {
4045  // int result; // eax@9
4046  int v8; // ebx@11
4047  int v9; // eax@11
4048  int v10; // ecx@11
4049  int v13; // [sp+10h] [bp-8h]@11
4050  signed int v14; // [sp+14h] [bp-4h]@3
4051  int v15; // [sp+24h] [bp+Ch]@11
4052 
4053  unsigned int grid_x = WorldPosToGridCellX(a1);
4054  unsigned int grid_z = WorldPosToGridCellZ(a2) - 1;
4055 
4056  int grid_x1 = GridCellToWorldPosX(grid_x),
4057  grid_x2 = GridCellToWorldPosX(grid_x + 1);
4058  int grid_z1 = GridCellToWorldPosZ(grid_z),
4059  grid_z2 = GridCellToWorldPosZ(grid_z + 1);
4060 
4061  int y_x1z1 = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z),
4062  y_x2z1 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z),
4063  y_x2z2 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1),
4064  y_x1z2 = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1);
4065  // v4 = WorldPosToGridCellX(a1);
4066  // v5 = WorldPosToGridCellZ(v12) - 1;
4067  // dword_76D538_terrain_cell_world_pos_around_party_x =
4068  // GridCellToWorldPosX(v4);
4069  // dword_76D53C_terrain_cell_world_pos_around_party_x =
4070  // GridCellToWorldPosX(v4 + 1);
4071  // dword_76D540_terrain_cell_world_pos_around_party_x =
4072  // GridCellToWorldPosX(v4 + 1);
4073  // dword_76D544_terrain_cell_world_pos_around_party_x =
4074  // GridCellToWorldPosX(v4);
4075  // dword_76D528_terrain_cell_world_pos_around_party_z =
4076  // GridCellToWorldPosZ(v5);
4077  // dword_76D52C_terrain_cell_world_pos_around_party_z =
4078  // GridCellToWorldPosZ(v5);
4079  // dword_76D530_terrain_cell_world_pos_around_party_z =
4080  // GridCellToWorldPosZ(v5 + 1);
4081  // dword_76D534_terrain_cell_world_pos_around_party_z =
4082  // GridCellToWorldPosZ(v5 + 1);
4083  // dword_76D518_terrain_cell_world_pos_around_party_y =
4084  // pOutdoor->DoGetHeightOnTerrain(v4, v5);
4085  // dword_76D51C_terrain_cell_world_pos_around_party_y =
4086  // pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5);
4087  // dword_76D520_terrain_cell_world_pos_around_party_y =
4088  // pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5 + 1);
4089  // dword_76D524_terrain_cell_world_pos_around_party_y =
4090  // pOutdoor->DoGetHeightOnTerrain(v4, v5 + 1);
4091  *pIsOnWater = false;
4092  if (pOutdoor->ActuallyGetSomeOtherTileInfo(grid_x, grid_z) & 2)
4093  *pIsOnWater = true;
4094  v14 = 0;
4095  if (!bFloatAboveWater && *pIsOnWater) v14 = -60;
4096  if (y_x1z1 != y_x2z1 || y_x2z1 != y_x2z2 || y_x2z2 != y_x1z2) {
4097  if (abs(grid_z1 - a2) >= abs(a1 - grid_x1)) {
4098  v8 = y_x1z2;
4099  v9 = y_x2z2;
4100  v10 = y_x1z1;
4101  v15 = a1 - grid_x1;
4102  v13 = a2 - grid_z2;
4103  } else {
4104  v8 = y_x2z1;
4105  v9 = y_x1z1;
4106  v10 = y_x2z2;
4107  v15 = grid_x2 - a1;
4108  v13 = grid_z1 - a2;
4109  }
4110  return v14 + v8 + fixpoint_mul(v13, (v10 - v8) * 128) +
4111  fixpoint_mul(v15, (v9 - v8) * 128);
4112  } else {
4113  return y_x1z1;
4114  }
4115 }

Перекрестные ссылки OutdoorLocation::ActuallyGetSomeOtherTileInfo(), OutdoorLocation::DoGetHeightOnTerrain(), fixpoint_mul(), GridCellToWorldPosX(), GridCellToWorldPosZ(), pOutdoor, WorldPosToGridCellX() и WorldPosToGridCellZ().

Используется в CastSpellInfoHelpers::_427E01_cast_spell(), OutdoorLocation::ArrangeSpriteObjects(), Application::Game::EventLoop(), ODM_GetFloorLevel() и ODM_ProcessPartyActions().

+ Граф вызовов:
+ Граф вызова функции:

Переменные

◆ pOutdoor

OutdoorLocation* pOutdoor

См. определение в файле Outdoor.cpp строка 48

Используется в CastSpellInfoHelpers::_427E01_cast_spell(), _45063B_spawn_some_monster(), _46E26D_collide_against_sprites(), _46E889_collide_against_bmodels(), _494035_timed_effects__water_walking_damage__etc(), Player::AddVariable(), Actor::ApplyFineForKillingPeasant(), ArenaFight(), Player::CompareVariable(), Vis::DetermineFacetIntersection(), DoInteractionWithTopmostZObject(), OutdoorLocation::Draw(), Engine::Draw(), DrawBook_Map_sub(), RenderOpenGL::DrawBuildingsD3D(), Render::DrawBuildingsD3D(), Render::DrawIndoorSkyPolygon(), RenderOpenGL::DrawOutdoorSkyD3D(), Render::DrawOutdoorSkyD3D(), RenderOpenGL::DrawTerrainPolygon(), Application::Game::EventLoop(), OutdoorLocation::ExecDraw(), GameUI_GetMinimapHintText(), GameUI_WritePointedObjectStatusString(), GetActorTintColor(), GetAlertStatus(), GetCeilingHeight(), GetLevelFogColor(), GetMapBookHintText(), Party::GetPartyReputation(), GetTerrainHeightsAroundParty2(), IsTerrainSlopeTooHigh(), Render::MakeScreenshot(), Vis::ODM_CreateIntersectFacesVertexCoordList(), ODM_GetFloorLevel(), ODM_GetTerrainNormalAt(), ODM_LoadAndInitialize(), ODM_ProcessPartyActions(), ODM_UpdateUserInputAndOther(), Engine::OnGameViewportClick(), OnMapLoad(), Chest::Open(), Vis::PickOutdoorFaces_Keyboard(), Vis::PickOutdoorFaces_Mouse(), PrepareToLoadRestUI(), RenderOpenGL::RenderTerrainD3D(), Render::RenderTerrainD3D(), Engine::ResetCursor_Palettes_LODs_Level_Audio_SFT_Windows(), SaveGame(), OutdoorLocation::SetFog(), Player::SetVariable(), SpawnEncounter(), LightmapBuilder::StackLights_TerrainFace(), Actor::StealFrom(), sub_407A1C(), sub_44861E_set_texture_outdoor(), sub_44892E_set_faces_bit(), sub_4759C9(), sub_4B1447_party_fine(), Player::SubtractVariable(), TempleDialog(), TrainingDialog(), GUIWindow_Travel::Update(), UpdateActors_ODM() и SpriteObject::UpdateObject_fn0_ODM().

current_BModel_id
std::array< int, 20 > current_BModel_id
Definition: mm7_data.cpp:735
uint16_t
unsigned __int16 uint16_t
Definition: SDL_config.h:37
PARTY_FLAGS_1_FALLING
@ PARTY_FLAGS_1_FALLING
Definition: Party.h:58
TE_MOVEMENT
@ TE_MOVEMENT
Definition: TurnEngine.h:22
fWalkSpeedMultiplier
float fWalkSpeedMultiplier
Definition: mm7_data.cpp:706
TE_ATTACK
@ TE_ATTACK
Definition: TurnEngine.h:21
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
BSPModel::pVertices
struct BSPVertexBuffer pVertices
Definition: BSPModel.h:189
face
GLenum GLuint GLint GLenum face
Definition: SDL_opengl_glext.h:3022
OutdoorLocation::uNumSpawnPoints
unsigned int uNumSpawnPoints
Definition: Outdoor.h:129
odm_floor_face_vert_coord_X
std::array< __int16, 104 > odm_floor_face_vert_coord_X
Definition: mm7_data.cpp:733
array_507D30
RenderVertexSoft array_507D30[50]
Definition: RenderOpenGL.cpp:58
pLevelDecorations
std::array< LevelDecoration, 3000 > pLevelDecorations
Definition: Decoration.cpp:8
Party::uFallSpeed
int uFallSpeed
Definition: Party.h:259
Dying
@ Dying
Definition: Actor.h:79
ceiling_height_level
std::array< int, 20 > ceiling_height_level
Definition: mm7_data.cpp:731
Timer::uTimeElapsed
unsigned int uTimeElapsed
Definition: Time.h:133
Party::field_24
int field_24
Definition: Party.h:245
IndoorCameraD3D::sRotationY
int sRotationY
Definition: IndoorCameraD3D.h:247
v
const GLdouble * v
Definition: SDL_opengl.h:2064
OutdoorLocation::PrepareDecorations
bool PrepareDecorations()
Definition: Outdoor.cpp:1583
MapStats::pInfos
MapInfo pInfos[77]
Definition: MapInfo.h:79
stru141_actor_collision_object::field_6C
int field_6C
Definition: Indoor.h:168
Party::GetPlayingTime
GameTime & GetPlayingTime()
Definition: Party.h:230
stru193_math::uDoublePiMask
static const unsigned int uDoublePiMask
Definition: OurMath.h:91
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
PARTY_StrafeLeft
@ PARTY_StrafeLeft
Definition: Party.h:98
dword_720E80
std::array< int, 20 > dword_720E80
Definition: mm7_data.cpp:729
fTurnSpeedMultiplier
float fTurnSpeedMultiplier
Definition: mm7_data.cpp:708
SPEECH_63
@ SPEECH_63
Definition: Player.h:109
OutdoorLocation::pBModels
BSPModelList pBModels
Definition: Outdoor.h:119
stru141_actor_collision_object::speed
int speed
Definition: Indoor.h:166
PARTY_LookDown
@ PARTY_LookDown
Definition: Party.h:103
ai_arrays_size
int ai_arrays_size
Definition: mm7_data.cpp:503
BSPModel::index
unsigned int index
Definition: BSPModel.h:167
stru141_actor_collision_object::uSectorID
unsigned int uSectorID
Definition: Indoor.h:170
Weather::bRenderSnow
bool bRenderSnow
Definition: Weather.h:18
Party::sRotationX
int sRotationX
Definition: Party.h:252
day_fogrange_2
int day_fogrange_2
Definition: mm7_data.cpp:699
Party::FeatherFallActive
bool FeatherFallActive()
Definition: Party.h:214
MapStats::GetMapInfo
MAP_TYPE GetMapInfo(const String &Str2)
Definition: MapInfo.cpp:225
AudioPlayer::PlaySound
void PlaySound(SoundID eSoundID, int pid, unsigned int uNumRepeats, int x, int y, int a7)
Definition: AudioPlayer.cpp:195
POLYGON_InBetweenFloorAndWall
@ POLYGON_InBetweenFloorAndWall
Definition: Indoor.h:221
MonsterInfo::Hostility_Friendly
@ Hostility_Friendly
Definition: Monsters.h:111
day_attrib
int day_attrib
Definition: mm7_data.cpp:697
OutdoorLocation::MessWithLUN
void MessWithLUN()
Definition: Outdoor.cpp:389
WorldPosToGridCellX
unsigned int WorldPosToGridCellX(int sWorldPosX)
Definition: Outdoor.cpp:3955
engine
std::shared_ptr< Engine > engine
Definition: Engine.cpp:130
word_720CE0_ys
std::array< __int16, 777 > word_720CE0_ys
Definition: mm7_data.cpp:727
day_fogrange_1
int day_fogrange_1
Definition: mm7_data.cpp:698
Actor::AI_FaceObject
static void AI_FaceObject(unsigned int uActorID, unsigned int uObjID, int UNUSED, struct AIDirection *Dir_In)
Definition: Actor.cpp:1072
Party::FlyActive
bool FlyActive()
Definition: Party.h:202
PARTY_BUFF_WATER_WALK
@ PARTY_BUFF_WATER_WALK
Definition: Party.h:89
IndoorCameraD3D::sRotationX
int sRotationX
Definition: IndoorCameraD3D.h:248
PARTY_WalkForward
@ PARTY_WalkForward
Definition: Party.h:100
UpdateObjects
void UpdateObjects()
Definition: Render.cpp:4955
stru141_actor_collision_object::normal
Vec3_int_ normal
Definition: Indoor.h:159
int64_t
__int64 int64_t
Definition: alext.h:31
Party::pPlayers
std::array< Player, 4 > pPlayers
Definition: Party.h:310
ODMFace::sCogTriggeredID
int16_t sCogTriggeredID
Definition: BSPModel.h:147
SpawnPointMM7
Definition: Indoor.h:304
OutdoorLocation::fFogDensity
float fFogDensity
Definition: Outdoor.h:176
ODMFace::uPolygonType
uint8_t uPolygonType
Definition: BSPModel.h:156
ACTOR_BUFF_SLOWED
@ ACTOR_BUFF_SLOWED
Definition: Actor.h:45
POLYGON_Floor
@ POLYGON_Floor
Definition: Indoor.h:220
OBJECT_Decoration
@ OBJECT_Decoration
Definition: Actor.h:69
WorldPosToGridCellZ
unsigned int WorldPosToGridCellZ(int sWorldPosZ)
Definition: Outdoor.cpp:3962
Vec3_float_::z
float z
Definition: VectorTypes.h:91
uint64_t
unsigned __int64 uint64_t
Definition: alext.h:32
pPlayers
NZIArray< struct Player *, 5 > pPlayers
Definition: Player.cpp:46
RenderVertexSoft::vWorldViewProjY
float vWorldViewProjY
Definition: IRender.h:119
Party::field_6F0
int field_6F0
Definition: Party.h:261
BBox_short_::z2
int16_t z2
Definition: VectorTypes.h:119
GetCeilingHeight
int GetCeilingHeight(int Party_X, signed int Party_Y, int Party_ZHeight, int pFaceID)
Definition: Outdoor.cpp:3254
OutdoorLocation::UpdateSunlightVectors
void UpdateSunlightVectors()
Definition: Outdoor.cpp:429
SPEECH_Falling_scream
@ SPEECH_Falling_scream
Definition: Player.h:112
Actor::_46DF1A_collide_against_actor
static bool _46DF1A_collide_against_actor(int a1, int a2)
Definition: Actor.cpp:2699
Plane_int_::vNormal
Vec3_int_ vNormal
Definition: VectorTypes.h:107
pTurnEngine
struct stru262_TurnBased * pTurnEngine
Definition: TurnEngine.cpp:21
Dead
@ Dead
Definition: Actor.h:80
pMapStats
struct MapStats * pMapStats
Definition: mm7_data.cpp:20
AIDirection
Definition: Actor.h:126
Party::pPartyBuffs
std::array< SpellBuff, 20 > pPartyBuffs
Definition: Party.h:309
AudioPlayer::StopAll
void StopAll(int sample_id)
Definition: AudioPlayer.cpp:189
PARTY_FlyUp
@ PARTY_FlyUp
Definition: Party.h:108
OBJECT_Actor
@ OBJECT_Actor
Definition: Actor.h:67
Party::uFallStartY
int uFallStartY
Definition: Party.h:265
Party::uPartyHeight
unsigned int uPartyHeight
Definition: Party.h:237
ViewingParams::uScreen_BttmR_X
unsigned int uScreen_BttmR_X
Definition: Viewport.h:62
ODMFace::pBoundingBox
struct BBox_short_ pBoundingBox
Definition: BSPModel.h:145
ny
GLfixed ny
Definition: SDL_opengl_glext.h:4523
PARTY_FLAGS_1_STANDING_ON_WATER
@ PARTY_FLAGS_1_STANDING_ON_WATER
Definition: Party.h:61
GUIWindow_Travel
Definition: UITransition.h:5
RenderVertexSoft::vWorldViewPosition
Vec3_float_ vWorldViewPosition
Definition: IRender.h:117
PARTY_FLAGS_1_LANDING
@ PARTY_FLAGS_1_LANDING
Definition: Party.h:62
GetAlertStatus
int GetAlertStatus()
Definition: Indoor.cpp:5287
ODMRenderParams::int_fov_rad_inv
int int_fov_rad_inv
Definition: IRender.h:80
MapInfo::SpawnRandomTreasure
int SpawnRandomTreasure(struct SpawnPointMM7 *a2)
Definition: MapInfo.cpp:240
pWeather
Weather * pWeather
Definition: Weather.cpp:8
OutdoorLocation::ActuallyGetSomeOtherTileInfo
int ActuallyGetSomeOtherTileInfo(signed int uX, signed int uY)
Definition: Outdoor.cpp:1459
PARTY_LookUp
@ PARTY_LookUp
Definition: Party.h:102
BSPModel::sMinY
int32_t sMinY
Definition: BSPModel.h:175
stru141_actor_collision_object::field_0
int field_0
Definition: Indoor.h:151
ViewingParams::uScreen_topL_X
unsigned int uScreen_topL_X
Definition: Viewport.h:60
pParty
Party * pParty
Definition: Party.cpp:30
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
RenderVertexSoft::vWorldViewProjX
float vWorldViewProjX
Definition: IRender.h:118
ODMFace::pVertexIDs
uint16_t pVertexIDs[20]
Definition: BSPModel.h:136
PARTY_Land
@ PARTY_Land
Definition: Party.h:110
stru141_actor_collision_object::field_8_radius
int field_8_radius
Definition: Indoor.h:153
odm_floor_level
std::array< int, 20 > odm_floor_level
Definition: mm7_data.cpp:736
Party::bFlying
unsigned int bFlying
Definition: Party.h:266
nz
GLfixed GLfixed nz
Definition: SDL_opengl_glext.h:4523
GetGravityStrength
unsigned int GetGravityStrength()
Definition: Engine.cpp:1500
stru141_actor_collision_object::normal2
Vec3_int_ normal2
Definition: Indoor.h:161
ITEM_ARTIFACT_LADYS_ESCORT
@ ITEM_ARTIFACT_LADYS_ESCORT
Definition: Items.h:189
ITEM_ARTIFACT_HERMES_SANDALS
@ ITEM_ARTIFACT_HERMES_SANDALS
Definition: Items.h:182
OBJECT_BModel
@ OBJECT_BModel
Definition: Actor.h:70
ODM_GetTerrainNormalAt
void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out)
Definition: Outdoor.cpp:2052
stru141_actor_collision_object::field_7C
int field_7C
Definition: Indoor.h:172
viewparams
struct ViewingParams * viewparams
Definition: mm7_data.cpp:22
OS_GetTime
unsigned int OS_GetTime()
Definition: Lin.cpp:12
Disabled
@ Disabled
Definition: Actor.h:94
PARTY_FlyDown
@ PARTY_FlyDown
Definition: Party.h:109
PARTY_FastTurnRight
@ PARTY_FastTurnRight
Definition: Party.h:114
Weather::Initialize
void Initialize()
Definition: Weather.cpp:41
MM7Initialization
void MM7Initialization()
Definition: Engine.cpp:1287
_46E889_collide_against_bmodels
void _46E889_collide_against_bmodels(unsigned int ecx0)
Definition: Render.cpp:4516
PARTY_TurnRight
@ PARTY_TurnRight
Definition: Party.h:97
UpdateActors_ODM
void UpdateActors_ODM()
Definition: Outdoor.cpp:3393
check_event_triggers
void check_event_triggers()
Definition: Events.cpp:1215
PARTY_CenterView
@ PARTY_CenterView
Definition: Party.h:104
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
v1
GLfloat GLfloat v1
Definition: SDL_opengl_glext.h:694
Log::Warning
void Warning(const wchar_t *pFormat,...)
Definition: Log.cpp:28
stru141_actor_collision_object::field_70
int field_70
Definition: Indoor.h:169
AudioPlayer::StopChannels
void StopChannels(int uStartChannel, int uEndChannel)
Definition: AudioPlayer.cpp:331
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
nx
GLbyte nx
Definition: SDL_opengl_glext.h:5716
BSPModel::sMinX
int32_t sMinX
Definition: BSPModel.h:174
ODM_ProcessPartyActions
void ODM_ProcessPartyActions()
Definition: Outdoor.cpp:2221
SPEECH_64
@ SPEECH_64
Definition: Player.h:110
ActionQueue::Next
PartyAction Next()
Definition: Party.cpp:1204
Party::uFlags
unsigned int uFlags
Definition: Party.h:313
f
GLfloat f
Definition: SDL_opengl_glext.h:1873
_46EF01_collision_chech_player
int _46EF01_collision_chech_player(int a1)
Definition: Render.cpp:4790
Party::field_6E0
int field_6E0
Definition: Party.h:257
Party::uWalkSpeed
unsigned int uWalkSpeed
Definition: Party.h:243
Viewport::uScreenCenterY
int uScreenCenterY
Definition: Viewport.h:29
_46E26D_collide_against_sprites
void _46E26D_collide_against_sprites(int a1, int a2)
Definition: Sprites.cpp:447
PARTY_FLAGS_1_WATER_DAMAGE
@ PARTY_FLAGS_1_WATER_DAMAGE
Definition: Party.h:57
GridCellToWorldPosZ
int GridCellToWorldPosZ(int a1)
Definition: Outdoor.cpp:3972
pPartyActionQueue
struct ActionQueue * pPartyActionQueue
Definition: Party.cpp:32
MapInfo
Definition: MapInfo.h:35
TE_WAIT
@ TE_WAIT
Definition: TurnEngine.h:20
pCurrentMapName
String pCurrentMapName
Definition: mm7_data.cpp:712
Removed
@ Removed
Definition: Actor.h:86
GetTerrainHeightsAroundParty2
int GetTerrainHeightsAroundParty2(int a1, int a2, bool *pIsOnWater, int bFloatAboveWater)
Definition: Outdoor.cpp:4044
SpriteObject::InitializeSpriteObjects
static void InitializeSpriteObjects()
Definition: SpriteObject.cpp:898
Plane_int_::dist
int dist
Definition: VectorTypes.h:108
PARTY_TurnLeft
@ PARTY_TurnLeft
Definition: Party.h:96
ODMFace::Pressure_Plate
bool Pressure_Plate() const
Definition: BSPModel.h:111
OBJECT_Player
@ OBJECT_Player
Definition: Actor.h:68
SkyBillboard
SkyBillboardStruct SkyBillboard
Definition: Outdoor.cpp:51
Party::bTurnBasedModeOn
bool bTurnBasedModeOn
Definition: Party.h:305
pViewport
struct Viewport * pViewport
Definition: mm7_data.cpp:21
Summoned
@ Summoned
Definition: Actor.h:92
MonsterStats::BelongsToSupertype
static bool BelongsToSupertype(unsigned int uMonsterInfoID, enum MONSTER_SUPERTYPE eSupertype)
Definition: Monsters.cpp:1200
Party::field_6E4
int field_6E4
Definition: Party.h:258
OutdoorLocation::pSpawnPoints
struct SpawnPointMM7 * pSpawnPoints
Definition: Outdoor.h:130
PARTY_BUFF_INVISIBILITY
@ PARTY_BUFF_INVISIBILITY
Definition: Party.h:82
Weather::bNight
bool bNight
Definition: Weather.h:17
Party::armageddon_timer
int armageddon_timer
Definition: Party.h:320
BSPModel::sMaxY
int32_t sMaxY
Definition: BSPModel.h:178
GridCellToWorldPosX
int GridCellToWorldPosX(int a1)
Definition: Outdoor.cpp:3969
ActionQueue::uNumActions
unsigned int uNumActions
Definition: Party.h:128
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1112
odm_floor_face_vert_coord_Y
std::array< __int16, 104 > odm_floor_face_vert_coord_Y
Definition: mm7_data.cpp:732
stru193_math::Atan2
unsigned int Atan2(int x, int y)
Definition: OurMath.cpp:46
VertexRenderList
RenderVertexSoft VertexRenderList[50]
Definition: Render.cpp:52
stru141_actor_collision_object::field_84
int field_84
Definition: Indoor.h:174
pODMRenderParams
ODMRenderParams * pODMRenderParams
Definition: Outdoor.cpp:49
Party::field_14_radius
int field_14_radius
Definition: Party.h:241
stru141_actor_collision_object::prolly_normal_d
int prolly_normal_d
Definition: Indoor.h:152
Viewport::uScreenCenterX
int uScreenCenterX
Definition: Viewport.h:28
flt_6BE150_look_up_down_dangle
float flt_6BE150_look_up_down_dangle
Definition: mm7_data.cpp:709
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11096
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
ANIM_Walking
@ ANIM_Walking
Definition: Actor.h:100
integer_sqrt
int integer_sqrt(int val)
Definition: OurMath.cpp:164
RenderVertexSoft::_rhw
float _rhw
Definition: IRender.h:120
SOUND_RunWood
@ SOUND_RunWood
Definition: AudioPlayer.h:33
uint
unsigned int uint
Definition: MM7.h:4
array_77EC08
std::array< struct Polygon, 2000+18000 > array_77EC08
Definition: Outdoor.cpp:52
uActiveCharacter
unsigned int uActiveCharacter
Definition: mm7_data.cpp:555
v3
GLfloat GLfloat GLfloat GLfloat v3
Definition: SDL_opengl_glext.h:696
OutdoorLocation::InitalizeActors
bool InitalizeActors(int a1)
Definition: Outdoor.cpp:1641
__debugbreak
void __cdecl __debugbreak(void)
Fleeing
@ Fleeing
Definition: Actor.h:82
Actor::AI_Flee
static void AI_Flee(unsigned int uActorID, signed int edx0, int uActionLength, struct AIDirection *a4)
Definition: Actor.cpp:2070
y1
GLfixed y1
Definition: SDL_opengl_glext.h:4586
BSPModel::pFaces
std::vector< ODMFace > pFaces
Definition: BSPModel.h:190
current_Face_id
std::array< int, 20 > current_Face_id
Definition: mm7_data.cpp:734
ODMFace
Definition: BSPModel.h:93
stru141_actor_collision_object::direction
Vec3_int_ direction
Definition: Indoor.h:165
PARTY_BUFF_FLY
@ PARTY_BUFF_FLY
Definition: Party.h:78
OutdoorLocation::GetTravelDestination
bool GetTravelDestination(signed int sPartyX, signed int sPartyZ, char *pOut, signed int a5)
Definition: Outdoor.cpp:330
y2
GLfixed GLfixed GLfixed y2
Definition: SDL_opengl_glext.h:4586
stru193_math::Cos
int Cos(int angle)
Definition: OurMath.cpp:28
OutdoorLocation::GetSoundIdByPosition
int GetSoundIdByPosition(signed int X_pos, signed int Y_pos, int a4)
Definition: Outdoor.cpp:1482
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
ViewingParams::bRedrawGameUI
int bRedrawGameUI
Definition: Viewport.h:74
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
OutdoorLocation::level_filename
String level_filename
Definition: Outdoor.h:111
OutdoorLocation::Initialize
bool Initialize(const String &filename, int days_played, int respawn_interval_days, int *thisa)
Definition: Outdoor.cpp:246
SoundID
SoundID
Definition: AudioPlayer.h:10
EventProcessor
void EventProcessor(int uEventID, int targetObj, int canShowMessages, int entry_line)
Definition: Events.cpp:260
PARTY_Jump
@ PARTY_Jump
Definition: Party.h:107
POLYGON_InBetweenCeilingAndWall
@ POLYGON_InBetweenCeilingAndWall
Definition: Indoor.h:223
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1112
ODMRenderParams::int_fov_rad
int int_fov_rad
Definition: IRender.h:79
stru_721530
stru141_actor_collision_object stru_721530
Definition: Indoor.cpp:58
SpriteObject::Create_Splash_Object
static void Create_Splash_Object(int x, int y, int z)
Definition: SpriteObject.cpp:993
stru193_math::Sin
int Sin(int angle)
Definition: OurMath.cpp:133
pAudioPlayer
AudioPlayer * pAudioPlayer
Definition: AudioPlayer.cpp:20
v0
GLfloat v0
Definition: SDL_opengl_glext.h:693
SpawnEncounter
void SpawnEncounter(MapInfo *pMapInfo, SpawnPointMM7 *spawn, int a3, int a4, int a5)
Definition: Actor.cpp:5063
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
SpawnPointMM7::IsMonsterSpawn
bool IsMonsterSpawn() const
Definition: Indoor.h:321
Party::floor_face_pid
int floor_face_pid
Definition: Party.h:262
MONSTER_SUPERTYPE_WATER_ELEMENTAL
@ MONSTER_SUPERTYPE_WATER_ELEMENTAL
Definition: Monsters.h:74
logger
Log * logger
Definition: IocContainer.cpp:47
stru_5E4C90_MapPersistVars
stru123 stru_5E4C90_MapPersistVars
Definition: mm7_data.cpp:23
ODMRenderParams::Initialize
void Initialize()
Definition: Outdoor.cpp:2196
RespawnGlobalDecorations
void RespawnGlobalDecorations()
Definition: DecorationList.cpp:70
pDialogueWindow
GUIWindow * pDialogueWindow
Definition: GUIWindow.cpp:50
pOutdoor
OutdoorLocation * pOutdoor
Definition: Outdoor.cpp:48
SOUND_WalkWood
@ SOUND_WalkWood
Definition: AudioPlayer.h:55
dword_720ED0
std::array< int, 20 > dword_720ED0
Definition: mm7_data.cpp:730
MapInfo::uRespawnIntervalDays
unsigned int uRespawnIntervalDays
Definition: MapInfo.h:45
word_720DB0_xs
std::array< __int16, 777 > word_720DB0_xs
Definition: mm7_data.cpp:728
_A750D8_player_speech_timer
int64_t _A750D8_player_speech_timer
Definition: mm7_data.cpp:763
BBox_short_::z1
int16_t z1
Definition: VectorTypes.h:118
OutdoorLocation::ArrangeSpriteObjects
void ArrangeSpriteObjects()
Definition: Outdoor.cpp:1616
pIndoorCameraD3D
IndoorCameraD3D * pIndoorCameraD3D
Definition: IndoorCameraD3D.cpp:21
ai_near_actors_ids
std::array< unsigned int, 500 > ai_near_actors_ids
Definition: mm7_data.cpp:505
IsTerrainSlopeTooHigh
bool IsTerrainSlopeTooHigh(int pos_x, int pos_z)
Definition: Outdoor.cpp:3976
stru141_actor_collision_object::position
Vec3_int_ position
Definition: Indoor.h:160
OutdoorLocation::DoGetHeightOnTerrain
int DoGetHeightOnTerrain(signed int sX, signed int sZ)
Definition: Outdoor.cpp:1474
PARTY_WalkBackward
@ PARTY_WalkBackward
Definition: Party.h:101
PARTY_FastTurnLeft
@ PARTY_FastTurnLeft
Definition: Party.h:113
stru141_actor_collision_object::velocity
Vec3_int_ velocity
Definition: Indoor.h:158
Party::sRotationY
int sRotationY
Definition: Party.h:251
stru262_TurnBased::turn_stage
int turn_stage
Definition: TurnEngine.h:75
EQUIP_BOOTS
@ EQUIP_BOOTS
Definition: Items.h:236
POLYGON_Ceiling
@ POLYGON_Ceiling
Definition: Indoor.h:222
pEventTimer
Timer * pEventTimer
Definition: Time.cpp:8
PARTY_RunForward
@ PARTY_RunForward
Definition: Party.h:111
Pursuing
@ Pursuing
Definition: Actor.h:81
Stunned
@ Stunned
Definition: Actor.h:83
Actor::InitializeActors
static void InitializeActors()
Definition: Actor.cpp:3334
dword_6BE13C_uCurrentlyLoadedLocationID
int dword_6BE13C_uCurrentlyLoadedLocationID
Definition: mm7_data.cpp:705
Party::WaterWalkActive
bool WaterWalkActive()
Definition: Party.h:205
Party::Invisible
bool Invisible()
Definition: Party.h:217
PARTY_StrafeRight
@ PARTY_StrafeRight
Definition: Party.h:99
fBackwardWalkSpeedMultiplier
float fBackwardWalkSpeedMultiplier
Definition: mm7_data.cpp:707
stru141_actor_collision_object::pid
unsigned int pid
Definition: Indoor.h:171
render
std::shared_ptr< IRender > render
Definition: RenderOpenGL.cpp:52