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