view mm7_3.cpp @ 212:9f349addbe00

Слияние
author Ritor1
date Sat, 16 Feb 2013 22:14:04 +0600
parents cd2077e24f95
children 809d3f71b73d
line wrap: on
line source

#include <assert.h>

#include "MapInfo.h"
#include "Game.h"
#include "GUIWindow.h"
#include "GUIFont.h"
#include "GUIButton.h"
#include "GUIProgressBar.h"
#include "Party.h"
#include "AudioPlayer.h"
#include "Outdoor.h"
#include "IndoorCamera.h"
#include "Overlays.h"
#include "Monsters.h"
#include "Arcomage.h"
#include "LOD.h"
#include "Actor.h"
#include "Allocator.h"
#include "Events.h"
#include "Viewport.h"
#include "FrameTableInc.h"
#include "Math.h"
#include "LayingItem.h"
#include "ObjectList.h"
#include "Chest.h"
#include "PaletteManager.h"
#include "DecorationList.h"
#include "SaveLoad.h"
#include "stru123.h"
#include "stru287.h"
#include "Time.h"
#include "IconFrameTable.h"
#include "TurnEngine.h"
#include "Awards.h"
#include "Autonotes.h"
#include "stru160.h"
#include "stru279.h"
#include "Weather.h"
#include "stru220.h"
#include "Events2D.h"
#include "stru176.h"
#include "stru159.h"
#include "stru298.h"
#include "texts.h"
#include "Log.h"

#include "mm7_data.h"








//----- (0046E44E) --------------------------------------------------------
int __thiscall _46E44E_collide_against_faces_and_portals(unsigned int b1)
{
  BLVSector *v1; // edi@1
  signed int v2; // ebx@1
  BLVFace *v3; // esi@2
  __int16 v4; // si@10
  int v5; // ecx@12
  unsigned __int8 v6; // sf@12
  unsigned __int8 v7; // of@12
  int result; // eax@14
  BLVSector *v9; // ebx@15
  int v10; // ecx@15
  int v11; // eax@16
  BLVFace *v12; // ebp@16
  int v13; // eax@24
  int v14; // esi@24
  int v15; // eax@24
  int v16; // edx@25
  int v17; // eax@29
  unsigned int v18; // eax@33
  int v19; // eax@35
  int v20; // edx@35
  int v21; // eax@35
  int v22; // ecx@36
  int v23; // eax@40
  unsigned int v24; // eax@44
  int a3; // [sp+10h] [bp-48h]@28
  int v26; // [sp+14h] [bp-44h]@15
  int i; // [sp+18h] [bp-40h]@1
  int a10; // [sp+1Ch] [bp-3Ch]@1
  int v29; // [sp+20h] [bp-38h]@14
  int v30; // [sp+24h] [bp-34h]@35
  int v31; // [sp+28h] [bp-30h]@24
  int v32; // [sp+2Ch] [bp-2Ch]@15
  int v33[10]; // [sp+30h] [bp-28h]@1

  v1 = &pIndoor->pSectors[stru_721530.uSectorID];
  v2 = 0;
  a10 = b1;
  v33[0] = stru_721530.uSectorID;
  for ( i = 1; v2 < v1->uNumPortals; ++v2 )
  {
    v3 = &pIndoor->pFaces[v1->pPortals[v2]];
    if ( stru_721530.sMaxX <= v3->pBounding.x2
      && stru_721530.sMinX >= v3->pBounding.x1
      && stru_721530.sMaxY <= v3->pBounding.y2
      && stru_721530.sMinY >= v3->pBounding.y1
      && stru_721530.sMaxZ <= v3->pBounding.z2
      && stru_721530.sMinZ >= v3->pBounding.z1
      && abs((v3->pFacePlane_old.dist
            + stru_721530.normal.x * v3->pFacePlane_old.vNormal.x
            + stru_721530.normal.y * v3->pFacePlane_old.vNormal.y
            + stru_721530.normal.z * v3->pFacePlane_old.vNormal.z) >> 16) <= stru_721530.field_6C + 16 )
    {
      v4 = v3->uSectorID == stru_721530.uSectorID ? v3->uBackSectorID : v3->uSectorID;
      v5 = i++;
      v7 = __OFSUB__(i, 10);
      v6 = i - 10 < 0;
      v33[v5] = v4;
      if ( !(v6 ^ v7) )
        break;
    }
  }
  result = 0;
  v29 = 0;
  if ( i > 0 )
  {
    while ( 1 )
    {
      v9 = &pIndoor->pSectors[v33[result]];
      v10 = 0;
      v32 = v9->uNumFloors + v9->field_C + v9->field_14;
      v26 = 0;
      if ( v32 > 0 )
        break;
LABEL_46:
      result = v29++ + 1;
      if ( v29 >= i )
        return result;
    }
    while ( 1 )
    {
      v11 = v9->pFloors[v10];
      v12 = &pIndoor->pFaces[v11];
      if ( v12->uAttributes & 1
        || stru_721530.sMaxX > v12->pBounding.x2
        || stru_721530.sMinX < v12->pBounding.x1
        || stru_721530.sMaxY > v12->pBounding.y2
        || stru_721530.sMinY < v12->pBounding.y1
        || stru_721530.sMaxZ > v12->pBounding.z2
        || stru_721530.sMinZ < v12->pBounding.z1
        || v11 == stru_721530.field_84 )
        goto LABEL_45;
      v13 = v12->pFacePlane_old.vNormal.y;
      v14 = v12->pFacePlane_old.dist;
      v31 = v13;
      v15 = (stru_721530.normal.x * v12->pFacePlane_old.vNormal.x
           + v14
           + stru_721530.normal.y * v13
           + stru_721530.normal.z * v12->pFacePlane_old.vNormal.z) >> 16;
      if ( v15 > 0 )
      {
        v16 = (stru_721530.normal2.y * v31
             + v12->pFacePlane_old.dist
             + stru_721530.normal2.z * v12->pFacePlane_old.vNormal.z
             + stru_721530.normal2.x * v12->pFacePlane_old.vNormal.x) >> 16;
        if ( v15 <= stru_721530.prolly_normal_d || v16 <= stru_721530.prolly_normal_d )
        {
          if ( v16 <= v15 )
          {
            a3 = stru_721530.field_6C;
            if ( sub_47531C(
                   stru_721530.prolly_normal_d,
                   &a3,
                   stru_721530.normal.x,
                   stru_721530.normal.y,
                   stru_721530.normal.z,
                   stru_721530.field_58.x,
                   stru_721530.field_58.y,
                   stru_721530.field_58.z,
                   v12,
                   a10) )
            {
              v17 = a3;
            }
            else
            {
              a3 = stru_721530.field_6C + stru_721530.prolly_normal_d;
              if ( !sub_475D85(&stru_721530.normal, &stru_721530.field_58, &a3, v12) )
                goto LABEL_34;
              v17 = a3 - stru_721530.prolly_normal_d;
              a3 -= stru_721530.prolly_normal_d;
            }
            if ( v17 < stru_721530.field_7C )
            {
              stru_721530.field_7C = v17;
              v18 = 8 * v9->pFloors[v26];
              LOBYTE(v18) = v18 | 6;
              stru_721530.uFaceID = v18;
            }
          }
        }
      }
LABEL_34:
      if ( !(stru_721530.field_0 & 1)
        || (v19 = v12->pFacePlane_old.vNormal.x,
            v20 = v12->pFacePlane_old.vNormal.y,
            v30 = v19,
            v21 = (stru_721530.field_34.x * v19
                 + v12->pFacePlane_old.dist
                 + stru_721530.field_34.y * v20
                 + stru_721530.field_34.z * v12->pFacePlane_old.vNormal.z) >> 16,
            v21 <= 0)
        || (v22 = (stru_721530.field_4C * v30
                 + v12->pFacePlane_old.dist
                 + stru_721530.field_50 * v20
                 + stru_721530.field_54 * v12->pFacePlane_old.vNormal.z) >> 16,
            v21 > stru_721530.prolly_normal_d)
        && v22 > stru_721530.prolly_normal_d
        || v22 > v21 )
        goto LABEL_45;
      a3 = stru_721530.field_6C;
      if ( sub_47531C(
             stru_721530.field_8,
             &a3,
             stru_721530.field_34.x,
             stru_721530.field_34.y,
             stru_721530.field_34.z,
             stru_721530.field_58.x,
             stru_721530.field_58.y,
             stru_721530.field_58.z,
             v12,
             a10) )
      {
        v23 = a3;
        goto LABEL_43;
      }
      a3 = stru_721530.field_6C + stru_721530.field_8;
      if ( sub_475D85(&stru_721530.field_34, &stru_721530.field_58, &a3, v12) )
      {
        v23 = a3 - stru_721530.prolly_normal_d;
        a3 -= stru_721530.prolly_normal_d;
LABEL_43:
        if ( v23 < stru_721530.field_7C )
        {
          stru_721530.field_7C = v23;
          v24 = 8 * v9->pFloors[v26];
          LOBYTE(v24) = v24 | 6;
          stru_721530.uFaceID = v24;
        }
      }
LABEL_45:
      v10 = v26++ + 1;
      if ( v26 >= v32 )
        goto LABEL_46;
    }
  }
  return result;
}
// 46E44E: using guessed type int var_28[10];

//----- (0046E889) --------------------------------------------------------
int __fastcall _46E889_collide_against_bmodels(unsigned int ecx0)
{
  int result; // eax@1
  BSPModel *v2; // ecx@3
  int v3; // ebx@9
  ODMFace *v4; // eax@11
  int v5; // edi@17
  int v6; // esi@17
  unsigned int v7; // ecx@17
  int v8; // eax@19
  int v9; // ecx@20
  int v10; // eax@24
  int v11; // ST18_4@25
  int v12; // ST1C_4@25
  int v13; // ST0C_4@25
  unsigned int v14; // eax@28
  int v15; // eax@30
  int v16; // ecx@31
  unsigned int v17; // eax@36
  int v18; // ST18_4@41
  int v19; // ST1C_4@41
  int v20; // ST0C_4@41
  int v21; // eax@42
  unsigned int v22; // eax@43
  //BLVFace f; // [sp+Ch] [bp-7Ch]@1
  int v24; // [sp+6Ch] [bp-1Ch]@9
  int a11; // [sp+70h] [bp-18h]@1
  unsigned int v26; // [sp+74h] [bp-14h]@2
  unsigned int v27; // [sp+78h] [bp-10h]@10
  BSPModel *v28; // [sp+7Ch] [bp-Ch]@3
  int a10; // [sp+80h] [bp-8h]@1
  int a2; // [sp+84h] [bp-4h]@23

  a11 = ecx0;

  BLVFace f; // [sp+Ch] [bp-7Ch]@1
  //BLVFace::BLVFace(&f);

  result = 0;
  a10 = 0;
  if ( (signed int)pOutdoor->uNumBModels > 0 )
  {
    v26 = 0;
    while ( 1 )
    {
      v2 = &pOutdoor->pBModels[v26 / 0xBC];
      v28 = &pOutdoor->pBModels[v26 / 0xBC];
      if ( stru_721530.sMaxX <= pOutdoor->pBModels[v26 / 0xBC].sMaxX )
      {
        if ( stru_721530.sMinX >= v2->sMinX )
        {
          if ( stru_721530.sMaxY <= v2->sMaxY )
          {
            if ( stru_721530.sMinY >= v2->sMinY )
            {
              if ( stru_721530.sMaxZ <= v2->sMaxZ )
              {
                if ( stru_721530.sMinZ >= v2->sMinZ )
                {
                  v3 = 0;
                  v24 = v2->uNumFaces;
                  if ( v24 > 0 )
                    break;
                }
              }
            }
          }
        }
      }
LABEL_39:
      ++a10;
      v26 += 188;
      result = a10;
      if ( a10 >= (signed int)pOutdoor->uNumBModels )
        return result;
    }
    v27 = 0;
    while ( 1 )
    {
      v4 = &v2->pFaces[v27 / 0x134];
      if ( stru_721530.sMaxX > v4->pBoundingBox.x2
        || stru_721530.sMinX < v4->pBoundingBox.x1
        || stru_721530.sMaxY > v4->pBoundingBox.y2
        || stru_721530.sMinY < v4->pBoundingBox.y1
        || stru_721530.sMaxZ > v4->pBoundingBox.z2
        || stru_721530.sMinZ < v4->pBoundingBox.z1 )
        goto LABEL_38;
      f.pFacePlane_old.vNormal.x = v4->pFacePlane.vNormal.x;
      f.pFacePlane_old.vNormal.y = v4->pFacePlane.vNormal.y;
      v5 = v4->pFacePlane.vNormal.z;
      f.pFacePlane_old.vNormal.z = v4->pFacePlane.vNormal.z;
      v6 = v4->pFacePlane.dist;
      f.pFacePlane_old.dist = v4->pFacePlane.dist;
      v7 = v4->uAttributes;
      f.uAttributes = v7;
      f.pBounding.x1 = v4->pBoundingBox.x1;
      f.pBounding.y1 = v4->pBoundingBox.y1;
      f.pBounding.z1 = v4->pBoundingBox.z1;
      f.pBounding.x2 = v4->pBoundingBox.x2;
      f.pBounding.y2 = v4->pBoundingBox.y2;
      f.pBounding.z2 = v4->pBoundingBox.z2;
      f.zCalc1 = v4->zCalc1;
      f.zCalc2 = v4->zCalc2;
      f.zCalc3 = v4->zCalc3;
      f.pXInterceptDisplacements = v4->pXInterceptDisplacements;
      f.pYInterceptDisplacements = v4->pYInterceptDisplacements;
      f.pZInterceptDisplacements = v4->pZInterceptDisplacements;
      f.uPolygonType = (PolygonType)v4->uPolygonType;
      f.uNumVertices = v4->uNumVertices;
      f.uBitmapID = v4->uTextureID;
      f.pVertexIDs = v4->pVertexIDs;
      if ( !(v7 & 0x20000000) )
      {
        if ( !(v7 & 1) )
          break;
      }
LABEL_37:
      v2 = v28;
LABEL_38:
      v27 += 308;
      ++v3;
      if ( v3 >= v24 )
        goto LABEL_39;
    }
    v8 = (v5 * stru_721530.normal.z
        + v6
        + f.pFacePlane_old.vNormal.y * stru_721530.normal.y
        + f.pFacePlane_old.vNormal.x * stru_721530.normal.x) >> 16;
    if ( v8 > 0 )
    {
      v9 = (v5 * stru_721530.normal2.z
          + v6
          + f.pFacePlane_old.vNormal.y * stru_721530.normal2.y
          + f.pFacePlane_old.vNormal.x * stru_721530.normal2.x) >> 16;
      if ( v8 <= stru_721530.prolly_normal_d || v9 <= stru_721530.prolly_normal_d )
      {
        if ( v9 <= v8 )
        {
          a2 = stru_721530.field_6C;
          if ( sub_4754BF(
                 stru_721530.prolly_normal_d,
                 &a2,
                 stru_721530.normal.x,
                 stru_721530.normal.y,
                 stru_721530.normal.z,
                 stru_721530.field_58.x,
                 stru_721530.field_58.y,
                 stru_721530.field_58.z,
                 &f,
                 a10,
                 a11) )
          {
            v10 = a2;
          }
          else
          {
            v11 = stru_721530.field_58.y;
            v12 = stru_721530.field_58.z;
            v13 = stru_721530.normal.y;
            a2 = stru_721530.prolly_normal_d + stru_721530.field_6C;
            if ( !sub_475F30(
                    &a2,
                    &f,
                    stru_721530.normal.x,
                    v13,
                    stru_721530.normal.z,
                    stru_721530.field_58.x,
                    v11,
                    v12,
                    a10) )
              goto LABEL_29;
            v10 = a2 - stru_721530.prolly_normal_d;
            a2 -= stru_721530.prolly_normal_d;
          }
          if ( v10 < stru_721530.field_7C )
          {
            stru_721530.field_7C = v10;
            v14 = 8 * (v3 | (a10 << 6));
            LOBYTE(v14) = v14 | 6;
            stru_721530.uFaceID = v14;
          }
        }
      }
    }
LABEL_29:
    if ( stru_721530.field_0 & 1 )
    {
      v15 = (f.pFacePlane_old.vNormal.z * stru_721530.field_34.z
           + f.pFacePlane_old.dist
           + f.pFacePlane_old.vNormal.y * stru_721530.field_34.y
           + f.pFacePlane_old.vNormal.x * stru_721530.field_34.x) >> 16;
      if ( v15 > 0 )
      {
        v16 = (f.pFacePlane_old.vNormal.z * stru_721530.field_54
             + f.pFacePlane_old.dist
             + f.pFacePlane_old.vNormal.y * stru_721530.field_50
             + f.pFacePlane_old.vNormal.x * stru_721530.field_4C) >> 16;
        if ( v15 <= stru_721530.prolly_normal_d || v16 <= stru_721530.prolly_normal_d )
        {
          if ( v16 <= v15 )
          {
            a2 = stru_721530.field_6C;
            if ( sub_4754BF(
                   stru_721530.field_8,
                   &a2,
                   stru_721530.field_34.x,
                   stru_721530.field_34.y,
                   stru_721530.field_34.z,
                   stru_721530.field_58.x,
                   stru_721530.field_58.y,
                   stru_721530.field_58.z,
                   &f,
                   a10,
                   a11) )
            {
              if ( a2 < stru_721530.field_7C )
              {
                stru_721530.field_7C = a2;
                v17 = 8 * (v3 | (a10 << 6));
                LOBYTE(v17) = v17 | 6;
                stru_721530.uFaceID = v17;
              }
            }
            else
            {
              v18 = stru_721530.field_58.y;
              v19 = stru_721530.field_58.z;
              v20 = stru_721530.field_34.y;
              a2 = stru_721530.field_6C + stru_721530.field_8;
              if ( sub_475F30(
                     &a2,
                     &f,
                     stru_721530.field_34.x,
                     v20,
                     stru_721530.field_34.z,
                     stru_721530.field_58.x,
                     v18,
                     v19,
                     a10) )
              {
                v2 = v28;
                v21 = a2 - stru_721530.prolly_normal_d;
                a2 -= stru_721530.prolly_normal_d;
                if ( a2 < stru_721530.field_7C )
                {
                  stru_721530.field_7C = v21;
                  v22 = 8 * (v3 | (a10 << 6));
                  LOBYTE(v22) = v22 | 6;
                  stru_721530.uFaceID = v22;
                }
                goto LABEL_38;
              }
            }
          }
        }
      }
    }
    goto LABEL_37;
  }
  return result;
}



//----- (0046ED1B) --------------------------------------------------------
int _46ED1B_collide_against_floor(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID)
{
  uint uFaceID = -1;
  int floor_level = _46CEC3_get_floor_level(x, y, z, *pSectorID, &uFaceID);

  if (floor_level != -30000 && floor_level <= z + 50)
  {
    *pFaceID = uFaceID;
    return floor_level;
  }

  uint uSectorID = pIndoor->GetSector(x, y, z);
  *pSectorID = uSectorID;

  floor_level = _46CEC3_get_floor_level(x, y, z, uSectorID, &uFaceID);
  if (uSectorID && floor_level != -30000)
    *pFaceID = uFaceID;
  else return -30000;
  return floor_level;
}

//----- (0046ED8A) --------------------------------------------------------
void __fastcall _46ED8A_collide_against_layingItems(unsigned int _this)
{
  int v1; // ebx@2
  ObjectDesc *v2; // edx@4
  int v3; // esi@5
  int v4; // ecx@5
  int v5; // eax@7
  int v6; // edi@9
  int v7; // edx@9
  int v8; // edi@11
  int v9; // ebx@11
  int v10; // ecx@12
  int v11; // esi@13
  signed int v12; // [sp+0h] [bp-14h]@1
  int v13; // [sp+4h] [bp-10h]@9
  char *v14; // [sp+8h] [bp-Ch]@2
  unsigned int v15; // [sp+10h] [bp-4h]@1

  v15 = 0;
  v12 = _this;
  if ( (signed int)uNumLayingItems > 0 )
  {
    v1 = (int)&pLayingItems[0].uObjectDescID;
    v14 = (char *)&pLayingItems[0].uObjectDescID;
    do
    {
      if ( *(short *)v1 )
      {
        v2 = &pObjectList->pObjects[*(short *)v1];
        if ( !(v2->uFlags & 2) )
        {
          v3 = v2->uRadius;
          v4 = *(int *)(v1 + 2);
          if ( stru_721530.sMaxX <= v4 + v3 )
          {
            if ( stru_721530.sMinX >= v4 - v3 )
            {
              v5 = *(int *)(v1 + 6);
              if ( stru_721530.sMaxY <= v5 + v3 )
              {
                if ( stru_721530.sMinY >= v5 - v3 )
                {
                  v6 = v2->uHeight;
                  v7 = *(int *)(v1 + 10);
                  v13 = v6;
                  if ( stru_721530.sMaxZ <= v7 + v6 )
                  {
                    if ( stru_721530.sMinZ >= v7 )
                    {
                      v8 = v4 - stru_721530.normal.x;
                      v9 = v5 - stru_721530.normal.y;
                      if ( abs(((v4 - stru_721530.normal.x) * stru_721530.field_58.y
                              - (v5 - stru_721530.normal.y) * stru_721530.field_58.x) >> 16) <= v3
                                                                                              + stru_721530.prolly_normal_d )
                      {
                        v10 = (v8 * stru_721530.field_58.x + v9 * stru_721530.field_58.y) >> 16;
                        if ( v10 > 0 )
                        {
                          v11 = stru_721530.normal.z
                              + ((unsigned __int64)(stru_721530.field_58.z * (signed __int64)v10) >> 16);
                          if ( v11 >= *(int *)(v14 + 10) - stru_721530.prolly_normal_d )
                          {
                            if ( v11 <= v13 + stru_721530.prolly_normal_d + *(int *)(v14 + 10) )
                            {
                              if ( v10 < stru_721530.field_7C )
                                sub_46DEF2(v12, v15);
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
      ++v15;
      v1 = (int)(v14 + 112);
      v14 += 112;
    }
    while ( (signed int)v15 < (signed int)uNumLayingItems );
  }
}

//----- (0046EF01) --------------------------------------------------------
int __thiscall _46EF01_collision_chech_player(int a1)
{
  int v1; // edx@1
  int result; // eax@1
  int v3; // ebx@7
  int v4; // esi@7
  int v5; // edi@8
  int v6; // ecx@9
  int v7; // edi@12
  int v8; // [sp+Ch] [bp-10h]@1
  unsigned int v9; // [sp+10h] [bp-Ch]@1
  int v10; // [sp+14h] [bp-8h]@7
  int v11; // [sp+18h] [bp-4h]@7

  v8 = a1;
  v1 = 2 * pParty->field_14;
  result = pParty->vPosition.x;
  v9 = pParty->uPartyHeight;
  if ( stru_721530.sMaxX <= pParty->vPosition.x + 2 * pParty->field_14 )
  {
    if ( stru_721530.sMinX >= pParty->vPosition.x - v1 )
    {
      if ( stru_721530.sMaxY <= pParty->vPosition.y + v1 )
      {
        if ( stru_721530.sMinY >= pParty->vPosition.y - v1 )
        {
          if ( stru_721530.sMaxZ <= (signed int)(pParty->vPosition.z + pParty->uPartyHeight) )
          {
            if ( stru_721530.sMinZ >= pParty->vPosition.z )
            {
              v3 = stru_721530.prolly_normal_d + v1;
              v11 = pParty->vPosition.x - stru_721530.normal.x;
              v4 = ((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.field_58.y
                  - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.field_58.x) >> 16;
              v10 = pParty->vPosition.y - stru_721530.normal.y;
              result = abs(((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.field_58.y
                          - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.field_58.x) >> 16);
              if ( result <= v3 )
              {
                result = v10 * stru_721530.field_58.y;
                v5 = (v10 * stru_721530.field_58.y + v11 * stru_721530.field_58.x) >> 16;
                if ( v5 > 0 )
                {
                  v6 = ((unsigned __int64)(stru_721530.field_58.z * (signed __int64)v5) >> 16) + stru_721530.normal.z;
                  result = pParty->vPosition.z;
                  if ( v6 >= pParty->vPosition.z )
                  {
                    result = v9 + pParty->vPosition.z;
                    if ( v6 <= (signed int)(v9 + pParty->vPosition.z) || v8 )
                    {
                      result = sub_452A9E(v3 * v3 - v4 * v4);
                      v7 = v5 - result;
                      if ( v7 < 0 )
                        v7 = 0;
                      if ( v7 < stru_721530.field_7C )
                      {
                        stru_721530.field_7C = v7;
                        stru_721530.uFaceID = 4;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  return result;
}

//----- (0046F04E) --------------------------------------------------------
signed int __cdecl _46F04E_collide_against_portals()
{
  BLVSector *v0; // ecx@1
  unsigned int v1; // eax@1
  int v2; // eax@2
  BLVFace *v3; // eax@3
  int v4; // ecx@9
  int v5; // edx@9
  signed int result; // eax@21
  BLVFace *v7; // eax@22
  signed int v8; // [sp+0h] [bp-14h]@1
  BLVSector *v9; // [sp+4h] [bp-10h]@1
  unsigned int v10; // [sp+8h] [bp-Ch]@1
  int a3; // [sp+Ch] [bp-8h]@13
  int v12; // [sp+10h] [bp-4h]@15

  v8 = 0;
  v0 = &pIndoor->pSectors[stru_721530.uSectorID];
  v1 = 0xFFFFFFu;
  v10 = 0xFFFFFFu;
  v9 = v0;
  if ( v0->uNumPortals > 0 )
  {
    do
    {
      v2 = v0->pPortals[v8];
      if ( v2 != stru_721530.field_80 )
      {
        v3 = &pIndoor->pFaces[v2];
        if ( stru_721530.sMaxX <= v3->pBounding.x2 )
        {
          if ( stru_721530.sMinX >= v3->pBounding.x1
            && stru_721530.sMaxY <= v3->pBounding.y2
            && stru_721530.sMinY >= v3->pBounding.y1
            && stru_721530.sMaxZ <= v3->pBounding.z2
            && stru_721530.sMinZ >= v3->pBounding.z1 )
          {
            v4 = (stru_721530.normal.x * v3->pFacePlane_old.vNormal.x
                + v3->pFacePlane_old.dist
                + stru_721530.normal.y * v3->pFacePlane_old.vNormal.y
                + stru_721530.normal.z * v3->pFacePlane_old.vNormal.z) >> 16;
            v5 = (stru_721530.normal2.z * v3->pFacePlane_old.vNormal.z
                + v3->pFacePlane_old.dist
                + stru_721530.normal2.x * v3->pFacePlane_old.vNormal.x
                + stru_721530.normal2.y * v3->pFacePlane_old.vNormal.y) >> 16;
            if ( (v4 < stru_721530.prolly_normal_d || v5 < stru_721530.prolly_normal_d)
              && (v4 > -stru_721530.prolly_normal_d || v5 > -stru_721530.prolly_normal_d)
              && (a3 = stru_721530.field_6C, sub_475D85(&stru_721530.normal, &stru_721530.field_58, &a3, v3))
              && a3 < (signed int)v10 )
            {
              v0 = v9;
              v10 = a3;
              v12 = v9->pPortals[v8];
            }
            else
            {
              v0 = v9;
            }
          }
        }
      }
      ++v8;
    }
    while ( v8 < v0->uNumPortals );
    v1 = v10;
  }
  if ( stru_721530.field_7C >= (signed int)v1 && (signed int)v1 <= stru_721530.field_6C )
  {
    stru_721530.field_80 = v12;
    v7 = &pIndoor->pFaces[v12];
    if ( v7->uSectorID == stru_721530.uSectorID )
      stru_721530.uSectorID = v7->uBackSectorID;
    else
      stru_721530.uSectorID = v7->uSectorID;
    stru_721530.field_7C = 268435455;
    result = 0;
  }
  else
  {
    result = 1;
  }
  return result;
}


//----- (0047050A) --------------------------------------------------------
int stru141::_47050A(int a2)
{
  stru141 *v2; // esi@1
  signed int v3; // eax@1
  int v4; // ecx@1
  int v5; // edx@1
  int v6; // edx@1
  int v7; // eax@1
  int v8; // eax@3
  signed int result; // eax@4
  int v10; // eax@5
  int v11; // eax@5
  int v12; // ebx@5
  int v13; // edx@5
  int v14; // edi@5
  int v15; // ecx@5
  int v16; // eax@5
  int v17; // eax@5
  int v18; // eax@7
  int v19; // edx@9
  int v20; // edi@9
  int v21; // eax@9
  int v22; // eax@11
  int v23; // edx@13
  int v24; // eax@13
  int v25; // eax@14
  int v26; // eax@16
  int v27; // eax@17
  int v28; // [sp+14h] [bp+8h]@5

  v2 = this;
  v3 = sub_452A9E(this->field_24 * this->field_24 + this->field_20 * this->field_20 + this->field_1C * this->field_1C);
  v4 = v3 | 1;
  v5 = v2->field_1C;
  v2->field_64 = v3 | 1;
  v2->field_58.x = 65536 / (v3 | 1) * v5;
  v2->field_58.y = 65536 / (v3 | 1) * v2->field_20;
  v6 = 65536 / (v3 | 1) * v2->field_24;
  v2->field_68 = 65536 / (v3 | 1);
  v7 = a2;
  v2->field_58.z = v6;
  if ( !a2 )
    v7 = pEventTimer->dt_in_some_format;
  v8 = ((unsigned __int64)(v7 * (signed __int64)v4) >> 16) - v2->field_70;
  v2->field_6C = v8;
  if ( v8 > 0 )
  {
    v10 = ((unsigned __int64)(v8 * (signed __int64)v2->field_58.x) >> 16) + v2->normal.x;
    v2->field_4C = v10;
    v2->normal2.x = v10;
    v11 = ((unsigned __int64)(v2->field_6C * (signed __int64)v2->field_58.y) >> 16) + v2->normal.y;
    v2->field_50 = v11;
    v2->normal2.y = v11;
    v2->normal2.z = ((unsigned __int64)(v2->field_6C * (signed __int64)v2->field_58.z) >> 16) + v2->normal.z;
    v12 = v2->field_34.z;
    v13 = v2->normal.x;
    v14 = v2->normal2.x;
    v15 = v2->prolly_normal_d;
    v16 = v12 + ((unsigned __int64)(v2->field_6C * (signed __int64)v2->field_58.z) >> 16);
    v28 = v16;
    v2->field_54 = v16;
    v17 = v13;
    if ( v13 >= v14 )
      v17 = v14;
    v2->sMaxX = v17 - v15;
    v18 = v15 + v13;
    if ( v13 <= v14 )
      v18 = v15 + v14;
    v19 = v2->normal.y;
    v20 = v2->normal2.y;
    v2->sMinX = v18;
    v21 = v19;
    if ( v19 >= v20 )
      v21 = v20;
    v2->sMaxY = v21 - v15;
    v22 = v15 + v19;
    if ( v19 <= v20 )
      v22 = v20 + v15;
    v23 = v2->normal2.z;
    v2->sMinY = v22;
    v24 = v2->normal.z;
    if ( v24 >= v23 )
      v25 = v23 - v15;
    else
      v25 = v24 - v15;
    v2->sMaxZ = v25;
    v26 = v2->field_8;
    if ( v12 <= v28 )
      v27 = v28 + v26;
    else
      v27 = v12 + v26;
    v2->uFaceID = 0;
    v2->field_80 = -1;
    v2->field_88 = -1;
    v2->sMinZ = v27;
    v2->field_7C = 0xFFFFFFu;
    result = 0;
  }
  else
  {
    result = 1;
  }
  return result;
}

//----- (004706C6) --------------------------------------------------------
void __cdecl UpdateActors_ODM()
{
  Actor *v0; // esi@2
  unsigned __int16 v1; // ax@2
  unsigned int v2; // ecx@6
  int v3; // ebx@6
  int v4; // eax@8
  int v5; // eax@10
  int v6; // ecx@10
  signed int v7; // ebx@10
  signed int v8; // ebx@17
  unsigned __int8 v9; // zf@17
  unsigned __int8 v10; // sf@17
  unsigned __int16 v11; // ax@21
  int v12; // eax@29
  unsigned __int64 v13; // qax@29
  int v14; // eax@30
  unsigned __int64 v15; // qax@30
  int v16; // eax@33
  int v17; // edi@34
  int v18; // edx@42
  int v19; // ecx@42
  __int16 v20; // ax@42
  int v21; // ebx@42
  int v22; // edi@42
  int v23; // ecx@42
  __int16 v24; // ax@42
  int v25; // eax@45
  signed int v26; // ecx@50
  int v27; // eax@52
  int v28; // eax@54
  signed int v29; // ebx@57
  signed int v30; // eax@57
  int v31; // edi@57
  signed int i; // ebx@57
  unsigned int v33; // ecx@58
  int v34; // ebx@64
  int v35; // edi@64
  int v36; // eax@64
  unsigned __int16 v37; // cx@66
  signed int v38; // edx@71
  signed int v39; // edi@71
  BSPModel *v40; // eax@75
  ODMFace *v41; // edi@75
  int v42; // ebx@76
  int v43; // ecx@77
  int v44; // edx@77
  __int16 v45; // dx@82
  int v46; // ecx@82
  signed int v47; // ebx@85
  int v48; // edi@85
  int v49; // edi@85
  int v50; // eax@85
  unsigned __int64 v51; // qax@85
  unsigned __int8 v52; // zf@87
  unsigned __int8 v53; // sf@87
  unsigned __int8 v54; // of@104
  int v55; // eax@107
  unsigned int v56; // edi@107
  int v57; // ST10_4@107
  unsigned int v58; // edi@107
  unsigned int v59; // ebx@107
  signed int v60; // eax@107
  int v61; // eax@124
  Vec3_int_ v62; // [sp+Ch] [bp-44h]@42
  int v63; // [sp+18h] [bp-38h]@64
  int v64; // [sp+1Ch] [bp-34h]@64
  int v65; // [sp+20h] [bp-30h]@2
  int v66; // [sp+24h] [bp-2Ch]@2
  bool v67; // [sp+28h] [bp-28h]@10
  unsigned int v68; // [sp+2Ch] [bp-24h]@10
  unsigned int v69; // [sp+30h] [bp-20h]@6
  unsigned int v70; // [sp+34h] [bp-1Ch]@10
  int v71; // [sp+38h] [bp-18h]@62
  int v72; // [sp+3Ch] [bp-14h]@10
  int v73; // [sp+40h] [bp-10h]@17
  int v74; // [sp+44h] [bp-Ch]@8
  unsigned int v75; // [sp+48h] [bp-8h]@1
  int v76; // [sp+4Ch] [bp-4h]@10

  v75 = 0;
  if ( (signed int)uNumActors <= 0 )
    return;
  do
  {
    v0 = &pActors[v75];
    v66 = v0->vPosition.x;
    v65 = v0->vPosition.y;
    v1 = v0->uAIState;
    if ( v1 == 11 || v1 == 19 || v1 == 17 || !v0->uMovementSpeed )
      goto LABEL_121;
    v2 = v0->pMonsterInfo.uID;
    v3 = 0;
    v69 = 0;
    if ( MonsterStats::BelongsToSupertype(v2, MONSTER_SUPERTYPE_WATER_ELEMENTAL) )
      v3 = 1;
    v4 = v0->pMonsterInfo.uFlying;
    v0->uSectorID = 0;
    v74 = v4;
    if ( !v0->CanAct() )
      v74 = 0;
    v70 = IsTerrainSlopeTooHigh(v0->vPosition.x, v0->vPosition.y);
    v5 = sub_46D49E_prolly_get_world_y_under_party(
           v0->vPosition.x,
           v0->vPosition.y,
           v0->vPosition.z,
           v0->uActorHeight,
           &v76,
           (int *)&v69,
           v3);
    v6 = v0->vPosition.z;
    v7 = v5;
    v68 = v5;
    v72 = 0;
    v67 = v69 == 0;
    if ( v6 > v5 + 1 )
      v72 = 1;
    if ( v0->uAIState == 5 && v76 && !v72 )
    {
      v0->uAIState = Removed;
      goto LABEL_121;
    }
    if ( v0->uCurrentActionAnimation == 1 )
    {
      v8 = v0->uMovementSpeed;
      v9 = HIDWORD(v0->pActorBuffs[7].uExpireTime) == 0;
      v10 = SHIDWORD(v0->pActorBuffs[7].uExpireTime) < 0;
      v73 = v0->uMovementSpeed;
      if ( !v10 && (!(v10 | v9) || LODWORD(v0->pActorBuffs[7].uExpireTime) > 0) )
      {
        v8 = (signed __int64)((double)v73 * 0.5);
        v73 = (signed __int64)((double)v73 * 0.5);
      }
      v11 = v0->uAIState;
      if ( v11 == 7 || v11 == 6 )
      {
        v8 *= 2;
        v73 = v8;
      }
      if ( pParty->bTurnBasedModeOn == 1 && pTurnEngine->field_4 == 1 )
        v8 = (signed __int64)((double)v73 * flt_6BE3AC_debug_recmod1_x_1_6);
      if ( v8 > 1000 )
        v8 = 1000;
      v12 = stru_5C6E00->SinCos(v0->uYawAngle);
      v69 = v12;
      v13 = v12 * (signed __int64)v8;
      v73 = v13 >> 16;
      v0->vVelocity.x = WORD1(v13);
      v69 = stru_5C6E00->SinCos(v0->uYawAngle - stru_5C6E00->uIntegerHalfPi);
      v73 = (unsigned __int64)((signed int)v69 * (signed __int64)v8) >> 16;
      v9 = v74 == 0;
      v0->vVelocity.y = v69 * v8 >> 16;
      if ( !v9 )
      {
        v14 = stru_5C6E00->SinCos(v0->uPitchAngle - stru_5C6E00->uIntegerHalfPi);
        v69 = v14;
        v15 = v14 * (signed __int64)v8;
        v73 = v15 >> 16;
        v0->vVelocity.z = WORD1(v15);
      }
      v7 = v68;
    }
    else
    {
      v73 = v0->vVelocity.x;
      v69 = 55000;
      v73 = (unsigned __int64)(55000i64 * v73) >> 16;
      v0->vVelocity.x = v73;
      v73 = v0->vVelocity.y;
      v73 = (unsigned __int64)((signed int)v69 * (signed __int64)v73) >> 16;
      v9 = v74 == 0;
      v0->vVelocity.y = v73;
      if ( !v9 )
      {
        v69 = 55000;
        v73 = v0->vVelocity.z;
        v73 = (unsigned __int64)(55000i64 * v73) >> 16;
        v0->vVelocity.z = v73;
      }
    }
    if ( v0->vPosition.z < v7 )
    {
      v16 = v74;
      v0->vPosition.z = v7;
      v0->vVelocity.z = v16 != 0 ? 0x14 : 0;
    }
    v17 = 0;
    if ( !v72 || v74 )
    {
      if ( v70 && !v72 && v67 )
      {
        v18 = v0->vPosition.y;
        v19 = v0->vPosition.x;
        v0->vPosition.z = v7;
        ODM_GetTerrainNormalAt(v19, v18, &v62);
        v20 = GetGravityStrength();
        v21 = v62.y;
        v22 = v62.z;
        v23 = v62.y * v0->vVelocity.y;
        v0->vVelocity.z += -8 * LOWORD(pEventTimer->uTimeElapsed) * v20;
        v73 = abs(v62.x * v0->vVelocity.x + v22 * v0->vVelocity.z + v23) >> 16;
        v72 = v21;
        v0->vVelocity.x += (unsigned int)(v73 * v62.x) >> 16;
        v72 = (unsigned __int64)(v73 * (signed __int64)v72) >> 16;
        v24 = v72;
        v72 = v22;
        v0->vVelocity.y += v24;
        v72 = (unsigned __int64)(v73 * (signed __int64)v72) >> 16;
        v0->vVelocity.z += v72;
        v17 = 0;
      }
    }
    else
    {
      v0->vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength();
    }
    if ( pParty->field_1613C != v17 && v0->CanAct() )
    {
      v0->vVelocity.x += rand() % 100 - 50;
      v0->vVelocity.y += rand() % 100 - 50;
      v0->vVelocity.z += rand() % 100 - 20;
      v25 = rand();
      v0->uAIState = Stunned;
      v0->uYawAngle += v25 % 32 - 16;
      v0->UpdateAnimation();
    }
    if ( v0->vVelocity.x * v0->vVelocity.x + v0->vVelocity.y * v0->vVelocity.y < 400 && v70 == v17 )
    {
      v0->vVelocity.y = v17;
      v0->vVelocity.x = v17;
    }
    v9 = v0->pMonsterInfo.uFlying == 0;
    stru_721530.field_0 = 1;
    if ( v9 )
      v26 = 40;
    else
      v26 = v0->uActorRadius;
    v27 = v0->uActorHeight;
    stru_721530.field_84 = -1;
    stru_721530.field_8 = v26;
    stru_721530.prolly_normal_d = v26;
    stru_721530.field_C = v27;
    stru_721530.field_70 = v17;
    v69 = v17;
    while ( 1 )
    {
      stru_721530.field_34.x = v0->vPosition.x;
      stru_721530.normal.x = stru_721530.field_34.x;
      stru_721530.field_34.y = v0->vPosition.y;
      stru_721530.normal.y = stru_721530.field_34.y;
      v28 = v0->vPosition.z;
      stru_721530.normal.z = v28 + v26 + 1;
      stru_721530.field_34.z = v28 - v26 + stru_721530.field_C - 1;
      if ( stru_721530.field_34.z < stru_721530.normal.z )
        stru_721530.field_34.z = v28 + v26 + 1;
      stru_721530.field_1C = v0->vVelocity.x;
      stru_721530.uSectorID = 0;
      stru_721530.field_20 = v0->vVelocity.y;
      stru_721530.field_24 = v0->vVelocity.z;
      if ( stru_721530._47050A(0) )
        break;
      _46E889_collide_against_bmodels(1u);
      v29 = WorldPosToGridCellZ(v0->vPosition.y);
      v30 = WorldPosToGridCellX(v0->vPosition.x);
      _46E26D_collide_against_sprites(v30, v29);
      _46EF01_collision_chech_player(0);
      _46ED8A_collide_against_layingItems(8 * v75 | 3);
      v31 = 0;
      for ( i = 0; v31 < ai_arrays_size; ++v31 )
      {
        v33 = ai_array_4F7DB0_actor_ids[v31];
        if ( v33 != v75 && _46DF1A_collide_against_actor(v33, 40) )
          ++i;
      }
      v71 = i > 1;
      if ( stru_721530.field_7C < stru_721530.field_6C )
        v70 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
      v34 = 0;
      v35 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
      v36 = sub_46D49E_prolly_get_world_y_under_party(
              stru_721530.normal2.x,
              stru_721530.normal2.y,
              stru_721530.normal2.z - stru_721530.prolly_normal_d - 1,
              v0->uActorHeight,
              (int *)&v63,
              &v64,
              0);
      if ( v76 )
      {
        if ( v35 < v36 + 60 )
        {
          v37 = v0->uAIState;
          if ( v37 == 5 || v37 == 4 || v37 == 11 || v37 == 19 )
          {
            if ( v64 )
              v61 = v36 + 30;
            else
              v61 = v68 + 60;
            sub_42F960_create_object(v0->vPosition.x, v0->vPosition.y, v61);
            v0->uAIState = Removed;
            return;
          }
        }
      }
      if ( stru_721530.field_7C >= stru_721530.field_6C )
      {
        v0->vPosition.x = LOWORD(stru_721530.normal2.x);
        v0->vPosition.y = LOWORD(stru_721530.normal2.y);
        v0->vPosition.z = LOWORD(stru_721530.normal2.z) - LOWORD(stru_721530.prolly_normal_d) - 1;
        break;
      }
      v72 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16;
      v0->vPosition.x += (unsigned int)(stru_721530.field_7C * stru_721530.field_58.x) >> 16;
      v72 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16;
      v0->vPosition.y += (unsigned int)(stru_721530.field_7C * stru_721530.field_58.y) >> 16;
      v72 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
      v38 = stru_721530.uFaceID;
      v0->vPosition.z += (unsigned int)(stru_721530.field_7C * stru_721530.field_58.z) >> 16;
      stru_721530.field_70 += stru_721530.field_7C;
      v39 = v38 >> 3;
      switch ( v38 & 7 )
      {
        case 3:
          if ( pParty->bTurnBasedModeOn != 1 )
            goto LABEL_97;
          if ( pTurnEngine->field_4 != 2 && pTurnEngine->field_4 != 3 )
          {
            v34 = 0;
LABEL_97:
            if ( v0->pMonsterInfo.uHostilityType )
            {
              if ( v71 == v34 )
                goto LABEL_99;
LABEL_101:
              Actor::_403F58(v75, 4, v34, (AIDirection *)v34);
              break;
            }
            if ( v71 != v34 )
              goto LABEL_101;
            if ( pActors[v39].pMonsterInfo.uHostilityType )
            {
LABEL_99:
              Actor::_402968(v75, v38, v34, (AIDirection *)v34);
              break;
            }
LABEL_103:
            Actor::FaceObject(v75, v38, v34, (AIDirection *)v34);
            break;
          }
          break;
        case 4:
          if ( !v0->GetActorsRelation(0) )
          {
            v38 = stru_721530.uFaceID;
            goto LABEL_103;
          }
          v52 = HIDWORD(pParty->pPartyBuffs[11].uExpireTime) == 0;
          v53 = SHIDWORD(pParty->pPartyBuffs[11].uExpireTime) < 0;
          v0->vVelocity.y = 0;
          v0->vVelocity.x = 0;
          if ( !v53 && (!(v53 | v52) || LODWORD(pParty->pPartyBuffs[11].uExpireTime) > 0) )
            pParty->pPartyBuffs[11].Reset();
          viewparams->bRedrawGameUI = 1;
          break;
        case 5:
          v47 = sub_452A9E(v0->vVelocity.x * v0->vVelocity.x + v0->vVelocity.y * v0->vVelocity.y);
          v48 = stru_5C6E00->Atan2(
                  v0->vPosition.x - pLevelDecorations[v39].vPosition.x,
                  v0->vPosition.y - pLevelDecorations[v39].vPosition.y);
          v71 = stru_5C6E00->SinCos(v48);
          v70 = (unsigned __int64)(v71 * (signed __int64)v47) >> 16;
          v49 = v48 - stru_5C6E00->uIntegerHalfPi;
          v0->vVelocity.x = (unsigned int)(v71 * v47) >> 16;
          v50 = stru_5C6E00->SinCos(v49);
          v71 = v50;
          v51 = v50 * (signed __int64)v47;
          v70 = v51 >> 16;
          v0->vVelocity.y = WORD1(v51);
          break;
        case 6:
          v40 = &pOutdoor->pBModels[v38 >> 9];
          v41 = &v40->pFaces[v39 & 0x3F];
          if ( !(BYTE3(v41->uAttributes) & 0x20) )
          {
            v42 = v41->uPolygonType;
            if ( v42 == 3 )
            {
              v43 = v0->vVelocity.y;
              v44 = v0->vVelocity.x;
              v0->vVelocity.z = 0;
              v0->vPosition.z = LOWORD(v40->pVertices.pVertices[v41->pVertexIDs[0]].z) + 1;
              if ( v44 * v44 + v43 * v43 < 400 )
              {
                v0->vVelocity.y = 0;
                v0->vVelocity.x = 0;
              }
            }
            else
            {
              v72 = abs(v41->pFacePlane.vNormal.y * v0->vVelocity.y + v41->pFacePlane.vNormal.z * v0->vVelocity.z
                                                                    + v41->pFacePlane.vNormal.x * v0->vVelocity.x) >> 16;
              if ( stru_721530.field_64 >> 3 > v72 )
                v72 = stru_721530.field_64 >> 3;
              v73 = v41->pFacePlane.vNormal.x;
              v73 = (unsigned __int64)(v72 * (signed __int64)v73) >> 16;
              v71 = v41->pFacePlane.vNormal.y;
              v71 = (unsigned __int64)(v72 * (signed __int64)v71) >> 16;
              v70 = v41->pFacePlane.vNormal.z;
              v70 = (unsigned __int64)(v72 * (signed __int64)(signed int)v70) >> 16;
              v0->vVelocity.x += v73;
              v0->vVelocity.y += v71;
              v0->vVelocity.z += v70;
              if ( v42 != 4 )
              {
                v45 = v0->vPosition.z;
                v46 = stru_721530.prolly_normal_d
                    - ((v41->pFacePlane.dist
                      + v41->pFacePlane.vNormal.x * v0->vPosition.x
                      + v41->pFacePlane.vNormal.y * v0->vPosition.y
                      + v41->pFacePlane.vNormal.z * v0->vPosition.z) >> 16);
                if ( v46 > 0 )
                {
                  v0->vPosition.x += (unsigned int)(v46 * v41->pFacePlane.vNormal.x) >> 16;
                  v0->vPosition.y += (unsigned int)(v46 * v41->pFacePlane.vNormal.y) >> 16;
                  v0->vPosition.z = v45 + ((unsigned int)(v46 * v41->pFacePlane.vNormal.z) >> 16);
                }
                v0->uYawAngle = stru_5C6E00->Atan2(v0->vVelocity.x, v0->vVelocity.y);
              }
            }
          }
          break;
      }
      v70 = v0->vVelocity.x;
      v71 = 58500;
      v70 = (unsigned __int64)(58500i64 * (signed int)v70) >> 16;
      v0->vVelocity.x = v70;
      v70 = v0->vVelocity.y;
      v70 = (unsigned __int64)(v71 * (signed __int64)(signed int)v70) >> 16;
      v71 = 58500;
      v0->vVelocity.y = v70;
      v70 = v0->vVelocity.z;
      v70 = (unsigned __int64)(v71 * (signed __int64)(signed int)v70) >> 16;
      ++v69;
      v54 = v69 < 100;
      v10 = (v69 - 100) < 0;
      v0->vVelocity.z = v70;
      if ( !(v10 ^ v54) )
        break;
      v26 = stru_721530.prolly_normal_d;
    }
    v69 = WorldPosToGridCellX(v66);
    v55 = WorldPosToGridCellZ(v65);
    v56 = v55 - 1;
    v57 = v0->vPosition.x;
    v71 = v55 - 1;
    v68 = WorldPosToGridCellX(v57);
    v70 = WorldPosToGridCellZ(v0->vPosition.y) - 1;
    v58 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(v69, v56) >> 1) & 1;
    v59 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(v68, v70) >> 1) & 1;
    v60 = 0;
    if ( v69 == v68 && v71 == v70 && v58 )
      v60 = 1;
    if ( !v67 )
      v60 = 1;
    if ( !v60 )
    {
      if ( MonsterStats::BelongsToSupertype(v0->pMonsterInfo.uID, MONSTER_SUPERTYPE_WATER_ELEMENTAL) )
      {
        v58 = v58 == 0;
        v59 = v59 == 0;
      }
      if ( !v74 && v58 && !v59 )
      {
        v0->vPosition.x = v66;
        v0->vPosition.y = v65;
        if ( v0->CanAct() )
        {
          v0->uYawAngle -= 32;
          v0->uCurrentActionTime = 0;
          v0->uCurrentActionLength = 128;
          v0->uAIState = Fleeing;
        }
      }
    }
LABEL_121:
    ++v75;
  }
  while ( (signed int)v75 < (signed int)uNumActors );
}



//----- (0047136C) --------------------------------------------------------
void LayingItem::UpdateObject_fn0_BLV(unsigned int uLayingItemID)
{
  LayingItem *v1; // esi@1
  ObjectDesc *v2; // edi@1
  int v3; // ST08_4@1
  __int16 v4; // ax@5
  __int16 v5; // ax@7
  BLVFace *v6; // ecx@11
  BLVFace *v7; // eax@11
  signed int v8; // ebx@12
  int v9; // ecx@16
  __int16 v10; // di@18
  char v11; // al@19
  int v12; // eax@25
  int v13; // eax@31
  int v14; // ebx@34
  signed int v15; // ebx@46
  BLVFace *v16; // edi@48
  int v17; // eax@50
  int v18; // eax@52
  int v19; // ecx@52
  Vec3_short_ *v20; // ecx@53
  int v21; // ecx@57
  __int16 v22; // ax@57
  int v23; // edi@62
  int v24; // edi@62
  int v25; // eax@62
  unsigned __int64 v26; // qax@62
  unsigned __int8 v27; // sf@64
  unsigned __int8 v28; // of@64
  __int16 v29; // di@67
  char v30; // al@68
  const char *v31; // [sp-8h] [bp-98h]@19
  const char *v32; // [sp-8h] [bp-98h]@68
  enum TEXTURE_TYPE v33; // [sp-4h] [bp-94h]@19
  enum TEXTURE_TYPE v34; // [sp-4h] [bp-94h]@68
  Particle_ Dst; // [sp+Ch] [bp-84h]@18
  unsigned int uLayingItemID_; // [sp+74h] [bp-1Ch]@1
  ObjectDesc *v37; // [sp+78h] [bp-18h]@1
  unsigned int uFaceID; // [sp+7Ch] [bp-14h]@4
  int v39; // [sp+80h] [bp-10h]@33
  Actor *v39b;
  int v40; // [sp+84h] [bp-Ch]@28
  int v41; // [sp+88h] [bp-8h]@34
  int v42; // [sp+8Ch] [bp-4h]@4

  uLayingItemID_ = uLayingItemID;
  v1 = &pLayingItems[uLayingItemID];
  v2 = &pObjectList->pObjects[v1->uObjectDescID];
  v3 = v1->vPosition.x;
  v37 = &pObjectList->pObjects[v1->uObjectDescID];
  if ( abs(v3) > 32767
    || abs(v1->vPosition.y) > 32767
    || abs(v1->vPosition.z) > 20000
    || (v42 = _46CEC3_get_floor_level(v1->vPosition.x, v1->vPosition.y, v1->vPosition.z, v1->uSectorID, &uFaceID),
        v42 <= -30000)
    && ((v4 = pIndoor->GetSector(v1->vPosition.x, v1->vPosition.y, v1->vPosition.z),
         (v1->uSectorID = v4) == 0)
     || (v42 = _46CEC3_get_floor_level(v1->vPosition.x, v1->vPosition.y, v1->vPosition.z, v4, &uFaceID), v42 == -30000)) )
  {
    LayingItem::_42F933(uLayingItemID_);
    return;
  }
  v5 = v2->uFlags;
  if ( v5 & 0x20 )
  {
LABEL_24:
    v8 = 0;
LABEL_25:
    stru_721530.field_0 = v8;
    uFaceID = v8;
    stru_721530.prolly_normal_d = v2->uRadius;
    v12 = v2->uHeight;
    stru_721530.field_84 = -1;
    stru_721530.field_C = v12;
    stru_721530.field_8 = v8;
    stru_721530.field_70 = v8;
    while ( 1 )
    {
      stru_721530.field_34.x = v1->vPosition.x;
      stru_721530.normal.x = stru_721530.field_34.x;
      stru_721530.field_34.y = v1->vPosition.y;
      stru_721530.normal.y = stru_721530.field_34.y;
      stru_721530.field_34.z = stru_721530.prolly_normal_d + v1->vPosition.z + 1;
      stru_721530.normal.z = stru_721530.field_34.z;
      stru_721530.field_1C = v1->vVelocity.x;
      stru_721530.field_20 = v1->vVelocity.y;
      stru_721530.field_24 = v1->vVelocity.z;
      stru_721530.uSectorID = v1->uSectorID;
      if ( stru_721530._47050A(v8) )
        return;
      v40 = v8;
      do
      {
        _46E44E_collide_against_faces_and_portals(0);
        _46E0B2_collide_against_decorations();
        if ( (v1->field_58 & 7) != OBJECT_Player)
          _46EF01_collision_chech_player(1);
        v13 = v1->field_58;
        v42 = v8;
        if ( (v13 & 7) == OBJECT_Actor)
        {
          if ( (signed int)uNumActors > v8 )
          {
            v39b = pActors;//[0].word_000086_some_monster_id;
            do
            {
              //v41 = pActors[v1->field_58 >> 3].pMonsterInfo.uID - 1;
              //v14 = (signed __int64)((double)v41 * 0.3333333333333333);
              //v41 = *(short *)(v39 - 38) - 1;
              //if ( v14 != (unsigned int)(signed __int64)((double)v41 * 0.3333333333333333) )
				if( pActors[v1->field_58 >> 3].pMonsterInfo.uID != v39b->pMonsterInfo.uID )
					//not sure: pMonsterList->pMonsters[v39b->word_000086_some_monster_id-1].uToHitRadius
					_46DF1A_collide_against_actor(v42, *((short *)&pMonsterList->pMonsters[v39b->word_000086_some_monster_id] - 73));
              ++v42;
              ++v39b;// += 836;
            }
            while ( v42 < (signed int)uNumActors );
            v8 = 0;
          }
        }
        else
        {
          if ( (signed int)uNumActors > v8 )
          {
            v39b = pActors;//[0].word_000086_some_monster_id;
            do
            {
              _46DF1A_collide_against_actor(v42++, *((short *)&pMonsterList->pMonsters[*(short *)v39b] - 73));
              ++v39b;
            }
            while ( v42 < (signed int)uNumActors );
          }
        }
        if ( _46F04E_collide_against_portals() )
          break;
        ++v40;
      }
      while ( v40 < 100 );
      if ( stru_721530.field_7C >= stru_721530.field_6C )
      {
        v1->vPosition.x = stru_721530.normal2.x;
        v1->vPosition.y = stru_721530.normal2.y;
        v1->vPosition.z = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
        v1->uSectorID = LOWORD(stru_721530.uSectorID);
        if ( !(HIBYTE(v2->uFlags) & 1) )
          return;
        memset(&Dst, v8, 0x68u);
        v29 = v2->uFlags;
        Dst.x = (double)v1->vPosition.x;
        Dst.y = (double)v1->vPosition.y;
        Dst.z = (double)v1->vPosition.z;
        Dst.flt_10 = 0.0;
        Dst.flt_14 = 0.0;
        Dst.flt_18 = 0.0;
        if ( v29 & 0x200 )
        {
          Dst.bFree = 1036;
          Dst.uDiffuse = 0xFF3C1Eu;
          v30 = rand();
          v34 = (TEXTURE_TYPE)v8;
          v32 = "effpar01";
        }
        else
        {
          if ( v29 & 0x400 )
            goto LABEL_70;
          Dst.bFree = 1032;
          Dst.uDiffuse = rand();
          v30 = rand();
          v34 = (TEXTURE_TYPE)v8;
          v32 = "effpar03";
        }
        Dst.timeToLive = (unsigned __int8)(v30 & 0x80) + 128;
        Dst.uTextureID = pBitmaps_LOD->LoadTexture(v32, v34);
        goto LABEL_71;
      }
      v40 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16;
      v1->vPosition.x += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16;
      v40 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16;
      v1->vPosition.y += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16;
      v40 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
      v1->vPosition.z += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
      v1->uSectorID = LOWORD(stru_721530.uSectorID);
      stru_721530.field_70 += stru_721530.field_7C;
      if ( v2->uFlags & 0x40 && !_46BFFA_check_object_intercept(uLayingItemID_, stru_721530.uFaceID) )
        return;
      v15 = (signed int)stru_721530.uFaceID >> 3;
      if ( (stru_721530.uFaceID & 7) == OBJECT_Decoration)
      {
        v40 = sub_452A9E(v1->vVelocity.x * v1->vVelocity.x + v1->vVelocity.y * v1->vVelocity.y);
        v23 = stru_5C6E00->Atan2(
                v1->vPosition.x - pLevelDecorations[v15].vPosition.x,
                v1->vPosition.y - pLevelDecorations[v15].vPosition.y);
        v42 = stru_5C6E00->SinCos(v23);
        v41 = (unsigned __int64)(v42 * (signed __int64)v40) >> 16;
        v24 = v23 - stru_5C6E00->uIntegerHalfPi;
        v1->vVelocity.x = (unsigned int)(v42 * v40) >> 16;
        v25 = stru_5C6E00->SinCos(v24);
        v42 = v25;
        v26 = v25 * (signed __int64)v40;
        v41 = v26 >> 16;
        v1->vVelocity.y = WORD1(v26);
      }
      else
      {
        if ( (stru_721530.uFaceID & 7) != OBJECT_BModel)
          goto LABEL_64;
        stru_721530.field_84 = (signed int)stru_721530.uFaceID >> 3;
        v16 = &pIndoor->pFaces[v15];
        if ( v16->uPolygonType != 3 )
        {
          v42 = abs(v16->pFacePlane_old.vNormal.x * v1->vVelocity.x + v16->pFacePlane_old.vNormal.z * v1->vVelocity.z
                                                                    + v16->pFacePlane_old.vNormal.y * v1->vVelocity.y) >> 16;
          if ( stru_721530.field_64 >> 3 > v42 )
            v42 = stru_721530.field_64 >> 3;
          v40 = v16->pFacePlane_old.vNormal.x;
          v40 = (unsigned __int64)(v42 * (signed __int64)v40) >> 16;
          v41 = v16->pFacePlane_old.vNormal.y;
          v41 = (unsigned __int64)(v42 * (signed __int64)v41) >> 16;
          v39 = v16->pFacePlane_old.vNormal.z;
          v39 = (unsigned __int64)(v42 * (signed __int64)v39) >> 16;
          v1->vVelocity.x += 2 * v40;
          v1->vVelocity.y += 2 * v41;
          if ( v16->pFacePlane_old.vNormal.z <= 32000 )
          {
            v22 = 2 * v39;
          }
          else
          {
            v21 = v39;
            v40 = 32000;
            v1->vVelocity.z += v39;
            v41 = (unsigned __int64)(v40 * (signed __int64)v21) >> 16;
            v22 = (unsigned int)(v40 * v21) >> 16;
          }
          v1->vVelocity.z += v22;
          goto LABEL_60;
        }
        if ( v37->uFlags & 0x80 )
        {
          v17 = -v1->vVelocity.z >> 1;
          v1->vVelocity.z = v17;
          if ( (signed __int16)v17 < 10 )
            v1->vVelocity.z = 0;
LABEL_60:
          if ( BYTE3(v16->uAttributes) & 0x10 )
            EventProcessor(pIndoor->pFaceExtras[v16->uFaceExtraID].uEventID, 0, 1);
          goto LABEL_63;
        }
        v18 = v1->vVelocity.y;
        v19 = v1->vVelocity.x;
        v1->vVelocity.z = 0;
        if ( v19 * v19 + v18 * v18 >= 400 )
          goto LABEL_60;
        v20 = pIndoor->pVertices;
        v1->vVelocity.z = 0;
        v1->vVelocity.y = 0;
        v1->vVelocity.x = 0;
        v1->vPosition.z = v20[*v16->pVertexIDs].z + 1;
      }
LABEL_63:
      v2 = v37;
LABEL_64:
      v41 = v1->vVelocity.x;
      v40 = 58500;
      v41 = (unsigned __int64)(58500i64 * v41) >> 16;
      v1->vVelocity.x = v41;
      v41 = v1->vVelocity.y;
      v41 = (unsigned __int64)(v40 * (signed __int64)v41) >> 16;
      v40 = 58500;
      v1->vVelocity.y = v41;
      v41 = v1->vVelocity.z;
      v41 = (unsigned __int64)(v40 * (signed __int64)v41) >> 16;
      ++uFaceID;
      v28 = __OFSUB__(uFaceID, 100);
      v27 = uFaceID - 100 < 0;
      v1->vVelocity.z = v41;
      if ( !(v27 ^ v28) )
        return;
      v8 = 0;
    }
  }
  if ( v42 <= v1->vPosition.z - 3 )
  {
    v1->vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength();
    goto LABEL_24;
  }
  if ( !(v5 & 0x40) || _46BFFA_check_object_intercept(uLayingItemID_, 0) )
  {
    v6 = pIndoor->pFaces;
    v1->vPosition.z = v42 + 1;
    v7 = &v6[uFaceID];
    if ( v7->uPolygonType == 3 )
    {
      v8 = 0;
      v1->vVelocity.z = 0;
    }
    else
    {
      if ( v7->pFacePlane_old.vNormal.z < 45000 )
        v1->vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength();
      v8 = 0;
    }
    v42 = v1->vVelocity.x;
    uFaceID = 58500;
    v42 = (unsigned __int64)(58500i64 * v42) >> 16;
    v1->vVelocity.x = v42;
    v42 = v1->vVelocity.y;
    v42 = (unsigned __int64)(uFaceID * (signed __int64)v42) >> 16;
    uFaceID = 58500;
    v1->vVelocity.y = v42;
    v42 = v1->vVelocity.z;
    v42 = (unsigned __int64)(uFaceID * (signed __int64)v42) >> 16;
    v9 = v1->vVelocity.x;
    v1->vVelocity.z = v42;
    if ( v9 * v9 + v1->vVelocity.y * v1->vVelocity.y < 400 )
    {
      v1->vVelocity.z = v8;
      v1->vVelocity.y = v8;
      v1->vVelocity.x = v8;
      if ( !(HIBYTE(v2->uFlags) & 1) )
        return;
      memset(&Dst, v8, 0x68u);
      v10 = v2->uFlags;
      Dst.x = (double)v1->vPosition.x;
      Dst.y = (double)v1->vPosition.y;
      Dst.z = (double)v1->vPosition.z;
      Dst.flt_10 = 0.0;
      Dst.flt_14 = 0.0;
      Dst.flt_18 = 0.0;
      if ( v10 & 0x200 )
      {
        Dst.bFree = 1036;
        Dst.uDiffuse = 0xFF3C1Eu;
        Dst.flt_28 = 1.0;
        v11 = rand();
        v33 = (TEXTURE_TYPE)v8;
        v31 = "effpar01";
      }
      else
      {
        if ( v10 & 0x400 )
        {
LABEL_70:
          Dst.bFree = 512;
          Dst.uDiffuse = rand();
          Dst.timeToLive = 64;
          Dst.uTextureID = v8;
LABEL_71:
          Dst.flt_28 = 1.0;
          goto LABEL_72;
        }
        Dst.bFree = 1032;
        Dst.uDiffuse = rand();
        Dst.flt_28 = 1.0;
        v11 = rand();
        v33 = (TEXTURE_TYPE)v8;
        v31 = "effpar03";
      }
      Dst.timeToLive = (unsigned __int8)(v11 & 0x80) + 128;
      Dst.uTextureID = pBitmaps_LOD->LoadTexture(v31, v33);
LABEL_72:
      pGame->pParticleEngine->AddParticle(&Dst);
      return;
    }
    goto LABEL_25;
  }
}
// 46DF1A: using guessed type int __fastcall 46DF1A_collide_against_actor(int, int);

//----- (00471C03) --------------------------------------------------------
void LayingItem::UpdateObject_fn0_ODM(unsigned int uLayingItemID)
{
  LayingItem *v1; // esi@1
  ObjectDesc *v2; // ebx@1
  signed int v3; // edx@1
  int v4; // ecx@1
  int v5; // ST04_4@1
  int v6; // eax@1
  int v7; // ecx@1
  int v8; // edi@1
  int v9; // eax@4
  __int16 v10; // ax@7
  int v11; // edx@11
  int v12; // ecx@11
  signed int v13; // edx@14
  signed int v14; // edx@16
  int v15; // eax@24
  int v16; // eax@25
  int v17; // ST10_4@25
  signed int v18; // eax@25
  signed int v19; // eax@28
  Actor *v20; // edi@31
  int v21; // eax@41
  int v22; // ecx@43
  __int16 v23; // bx@45
  char v24; // al@46
  signed int i; // edi@50
  int v26; // edi@52
  int v27; // eax@52
  __int16 v28; // cx@55
  int v29; // eax@55
  signed int v30; // edi@59
  BSPModel *v31; // ecx@61
  ODMFace *v32; // edi@61
  int v33; // eax@62
  int v34; // ecx@62
  int v35; // eax@63
  Actor *v36; // ecx@67
  __int16 v37; // ax@67
  int v38; // eax@72
  int v39; // eax@72
  unsigned __int64 v40; // qax@72
  int v41; // eax@72
  unsigned __int8 v42; // sf@74
  unsigned __int8 v43; // of@74
  int v44; // eax@77
  __int16 v45; // bx@81
  int v46; // eax@85
  const char *v47; // [sp-8h] [bp-B0h]@83
  enum TEXTURE_TYPE v48; // [sp-4h] [bp-ACh]@46
  int v49; // [sp+Ch] [bp-9Ch]@52
  int v50; // [sp+10h] [bp-98h]@52
  Vec3_int_ v51; // [sp+14h] [bp-94h]@11
  Particle_ Dst; // [sp+20h] [bp-88h]@45
  unsigned int uLayingItemID_; // [sp+88h] [bp-20h]@1
  int v54; // [sp+8Ch] [bp-1Ch]@1
  int v55; // [sp+90h] [bp-18h]@1
  int v56; // [sp+94h] [bp-14h]@11
  int v57; // [sp+98h] [bp-10h]@1
  int v58; // [sp+9Ch] [bp-Ch]@1
  int v59; // [sp+A0h] [bp-8h]@1
  Actor *v60; // [sp+A4h] [bp-4h]@11

  uLayingItemID_ = uLayingItemID;
  v1 = &pLayingItems[uLayingItemID];
  v58 = 0;
  v2 = &pObjectList->pObjects[v1->uObjectDescID];
  v57 = IsTerrainSlopeTooHigh(v1->vPosition.x, v1->vPosition.y);
  v3 = v1->vPosition.y;
  v4 = v1->vPosition.x;
  v5 = v2->uHeight;
  v55 = 0;
  v6 = sub_46D49E_prolly_get_world_y_under_party(v4, v3, v1->vPosition.z, v5, &v59, &v55, 0);
  v7 = v6;
  v54 = v6;
  v8 = v6 + 1;
  if ( v1->vPosition.z <= v6 + 1 )
  {
    if ( v59 )
    {
      v9 = v6 + 60;
      if ( v55 )
        v9 = v7 + 30;
      sub_42F960_create_object(v1->vPosition.x, v1->vPosition.y, v9);
      LayingItem::_42F933(uLayingItemID_);
      v7 = v54;
    }
  }
  else
  {
    v58 = 1;
  }
  v10 = v2->uFlags;
  if ( !(v10 & 0x20) )
  {
    if ( v58 )
    {
      v1->vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength();
      goto LABEL_13;
    }
    if ( v57 )
    {
      v11 = v1->vPosition.y;
      v12 = v1->vPosition.x;
      v1->vPosition.z = v8;
      ODM_GetTerrainNormalAt(v12, v11, &v51);
      v1->vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength();
      v56 = abs(v51.y * v1->vVelocity.y + v51.z * v1->vVelocity.z + v51.x * v1->vVelocity.x) >> 16;
      v60 = (Actor *)((unsigned __int64)(v56 * (signed __int64)v51.x) >> 16);
      v1->vVelocity.x += (unsigned int)(v56 * v51.x) >> 16;
      v60 = (Actor *)((unsigned __int64)(v56 * (signed __int64)v51.y) >> 16);
      v1->vVelocity.y += (unsigned int)(v56 * v51.y) >> 16;
      v60 = (Actor *)((unsigned __int64)(v56 * (signed __int64)v51.z) >> 16);
      v1->vVelocity.z += (unsigned int)(v56 * v51.z) >> 16;
LABEL_12:
      v7 = v54;
      goto LABEL_13;
    }
    if ( v10 & 0x40 )
    {
      if ( v1->vPosition.z < v7 )
        v1->vPosition.z = v8;
      if ( !_46BFFA_check_object_intercept(uLayingItemID_, 0) )
        return;
    }
    v1->vPosition.z = v8;
    if ( !(v2->uFlags & 0x80) || (v21 = -v1->vVelocity.z >> 1, v1->vVelocity.z = v21, (signed __int16)v21 < 10) )
      v1->vVelocity.z = 0;
    v60 = (Actor *)v1->vVelocity.x;
    v55 = 58500;
    v60 = (Actor *)((unsigned __int64)(58500i64 * (signed int)v60) >> 16);
    v1->vVelocity.x = (signed __int16)v60;
    v60 = (Actor *)v1->vVelocity.y;
    v60 = (Actor *)((unsigned __int64)(v55 * (signed __int64)(signed int)v60) >> 16);
    v55 = 58500;
    v1->vVelocity.y = (signed __int16)v60;
    v60 = (Actor *)v1->vVelocity.z;
    v60 = (Actor *)((unsigned __int64)(v55 * (signed __int64)(signed int)v60) >> 16);
    v22 = v1->vVelocity.x;
    v1->vVelocity.z = (signed __int16)v60;
    if ( v1->vVelocity.y * v1->vVelocity.y + v22 * v22 >= 400 )
      goto LABEL_12;
    v1->vVelocity.y = 0;
    v1->vVelocity.x = 0;
    if ( !(HIBYTE(v2->uFlags) & 1) )
      return;
    memset(&Dst, 0, 0x68u);
    v23 = v2->uFlags;
    Dst.x = (double)v1->vPosition.x;
    Dst.y = (double)v1->vPosition.y;
    Dst.z = (double)v1->vPosition.z;
    Dst.flt_10 = 0.0;
    Dst.flt_14 = 0.0;
    Dst.flt_18 = 0.0;
    if ( HIBYTE(v23) & 2 )
    {
      Dst.bFree = 1036;
      Dst.uDiffuse = 16727070;
      v24 = rand();
      v48 = (TEXTURE_TYPE)0;
LABEL_83:
      v47 = "effpar01";
    }
    else
    {
      if ( HIBYTE(v23) & 4 )
      {
        Dst.bFree = 512;
        Dst.uDiffuse = rand();
        Dst.timeToLive = 64;
        Dst.uTextureID = 0;
LABEL_89:
        Dst.flt_28 = 1.0;
        pGame->pParticleEngine->AddParticle(&Dst);
        return;
      }
      Dst.bFree = 1032;
      Dst.uDiffuse = rand();
      v24 = rand();
      v48 = (TEXTURE_TYPE)0;
LABEL_87:
      v47 = "effpar03";
    }
    Dst.timeToLive = (unsigned __int8)(v24 & 0x80) + 128;
    Dst.uTextureID = pBitmaps_LOD->LoadTexture(v47, v48);
    goto LABEL_89;
  }
LABEL_13:
  if ( v1->vPosition.z > v7
    && (v13 = v1->vPosition.x, v13 >= -32768)
    && v13 <= 32768
    && (v14 = v1->vPosition.y, v14 >= -32768)
    && v14 <= 32768
    && v1->vPosition.z <= 13000
    || !(v2->uFlags & 0x40) )
    goto LABEL_92;
  if ( v1->vPosition.z < v7 )
    v1->vPosition.z = v8;
  if ( _46BFFA_check_object_intercept(uLayingItemID_, 0) )
  {
LABEL_92:
    stru_721530.field_0 = 0;
    v55 = 0;
    stru_721530.prolly_normal_d = v2->uRadius;
    stru_721530.field_C = v2->uHeight;
    stru_721530.field_8 = 0;
    stru_721530.field_70 = 0;
    while ( 1 )
    {
      stru_721530.field_34.x = v1->vPosition.x;
      stru_721530.normal.x = stru_721530.field_34.x;
      v15 = v1->vPosition.y;
      stru_721530.uSectorID = 0;
      stru_721530.field_34.y = v15;
      stru_721530.normal.y = v15;
      stru_721530.field_34.z = v1->vPosition.z + stru_721530.prolly_normal_d + 1;
      stru_721530.normal.z = stru_721530.field_34.z;
      stru_721530.field_1C = v1->vVelocity.x;
      stru_721530.field_20 = v1->vVelocity.y;
      stru_721530.field_24 = v1->vVelocity.z;
      if ( stru_721530._47050A(0) )
        return;
      _46E889_collide_against_bmodels(0);
      v16 = WorldPosToGridCellZ(v1->vPosition.y);
      v17 = v1->vPosition.x;
      v58 = v16;
      v18 = WorldPosToGridCellX(v17);
      _46E26D_collide_against_sprites(v18, v58);
      if ( (v1->field_58 & 7) != OBJECT_Player)
        _46EF01_collision_chech_player(0);
      if ( (v1->field_58 & 7) == OBJECT_Actor)
      {
        v19 = v1->field_58 >> 3;
        if ( v19 >= 0 )
        {
          if ( v19 < (signed int)(uNumActors - 1) )
          {
            v56 = 0;
            if ( (signed int)uNumActors > 0 )
            {
              v60 = pActors;
              v20 = &pActors[v19];
              do
              {
                if ( v20->GetActorsRelation(v60) )
                  _46DF1A_collide_against_actor(v56, 0);
                ++v56;
                ++v60;
              }
              while ( v56 < (signed int)uNumActors );
            }
          }
        }
      }
      else
      {
        for ( i = 0; i < (signed int)uNumActors; ++i )
          _46DF1A_collide_against_actor(i, 0);
      }
      v26 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
      v27 = sub_46D49E_prolly_get_world_y_under_party(
              stru_721530.normal2.x,
              stru_721530.normal2.y,
              stru_721530.normal2.z - stru_721530.prolly_normal_d - 1,
              v2->uHeight,
              &v49,
              &v50,
              0);
      if ( v59 && v26 < v27 + 60 )
      {
        if ( v50 )
          v44 = v27 + 30;
        else
          v44 = v54 + 60;
        sub_42F960_create_object(v1->vPosition.x, v1->vPosition.y, v44);
        LayingItem::_42F933(uLayingItemID_);
        return;
      }
      if ( stru_721530.field_7C >= stru_721530.field_6C )
      {
        v1->vPosition.x = stru_721530.normal2.x;
        v1->vPosition.y = stru_721530.normal2.y;
        v1->vPosition.z = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
        v1->uSectorID = LOWORD(stru_721530.uSectorID);
        if ( !(HIBYTE(v2->uFlags) & 1) )
          return;
        memset(&Dst, 0, 0x68u);
        v45 = v2->uFlags;
        Dst.x = (double)v1->vPosition.x;
        Dst.y = (double)v1->vPosition.y;
        Dst.z = (double)v1->vPosition.z;
        Dst.flt_10 = 0.0;
        Dst.flt_14 = 0.0;
        Dst.flt_18 = 0.0;
        if ( HIBYTE(v45) & 2 )
        {
          Dst.bFree = 1036;
          Dst.uDiffuse = 16727070;
          v24 = rand();
          v48 = (TEXTURE_TYPE)0;
          goto LABEL_83;
        }
        if ( HIBYTE(v45) & 4 )
        {
          Dst.bFree = 512;
          v46 = rand();
          Dst.uTextureID = 0;
          Dst.uDiffuse = v46;
          Dst.timeToLive = 64;
          goto LABEL_89;
        }
        Dst.bFree = 1032;
        Dst.uDiffuse = rand();
        v24 = rand();
        v48 = (TEXTURE_TYPE)0;
        goto LABEL_87;
      }
      v60 = (Actor *)((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16);
      v1->vPosition.x += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16;
      v60 = (Actor *)((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16);
      v1->vPosition.y += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16;
      v60 = (Actor *)((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16);
      v28 = LOWORD(stru_721530.uSectorID);
      v1->vPosition.z += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
      v29 = v1->vPosition.z;
      v1->uSectorID = v28;
      stru_721530.field_70 += stru_721530.field_7C;
      if ( v2->uFlags & 0x40 )
      {
        if ( v29 < v54 )
          v1->vPosition.z = v54 + 1;
        if ( !_46BFFA_check_object_intercept(uLayingItemID_, stru_721530.uFaceID) )
          return;
      }
      v30 = (signed int)stru_721530.uFaceID >> 3;
      if ( (stru_721530.uFaceID & 7) == OBJECT_Decoration)
        break;
      if ( (stru_721530.uFaceID & 7) == OBJECT_BModel)
      {
        v31 = &pOutdoor->pBModels[(signed int)stru_721530.uFaceID >> 9];
        v32 = &v31->pFaces[v30 & 0x3F];
        if ( v32->uPolygonType != 3 )
        {
          v56 = abs(v32->pFacePlane.vNormal.z * v1->vVelocity.z + v32->pFacePlane.vNormal.y * v1->vVelocity.y
                                                                + v32->pFacePlane.vNormal.x * v1->vVelocity.x) >> 16;
          if ( stru_721530.field_64 >> 3 > v56 )
            v56 = stru_721530.field_64 >> 3;
          v57 = v32->pFacePlane.vNormal.x;
          v57 = (unsigned __int64)(v56 * (signed __int64)v57) >> 16;
          v58 = v32->pFacePlane.vNormal.y;
          v58 = (unsigned __int64)(v56 * (signed __int64)v58) >> 16;
          v60 = (Actor *)v32->pFacePlane.vNormal.z;
          v60 = (Actor *)((unsigned __int64)(v56 * (signed __int64)(signed int)v60) >> 16);
          v1->vVelocity.x += 2 * v57;
          v1->vVelocity.y += 2 * v58;
          if ( v32->pFacePlane.vNormal.z <= 32000 )
          {
            v37 = 2 * (short)v60;
          }
          else
          {
            v36 = v60;
            v57 = 32000;
            v1->vVelocity.z += (signed __int16)v60;
            v58 = (unsigned __int64)(v57 * (signed __int64)(signed int)v36) >> 16;
            v37 = (unsigned int)(v57 * (int)v36) >> 16;
          }
          v1->vVelocity.z += v37;
LABEL_70:
          if ( BYTE3(v32->uAttributes) & 0x10 )
            EventProcessor(v32->sCogTriggeredID, 0, 1);
          goto LABEL_74;
        }
        v33 = v31->pVertices.pVertices[v32->pVertexIDs[0]].z;
        v34 = v1->vVelocity.x;
        v1->vPosition.z = v33 + 1;
        if ( v1->vVelocity.y * v1->vVelocity.y + v34 * v34 >= 400 )
          goto LABEL_70;
        LOWORD(v35) = 0;
        v1->vVelocity.z = 0;
        v1->vVelocity.x = 0;
        goto LABEL_73;
      }
LABEL_74:
      v58 = v1->vVelocity.x;
      v57 = 58500;
      v58 = (unsigned __int64)(58500i64 * v58) >> 16;
      v1->vVelocity.x = v58;
      v58 = v1->vVelocity.y;
      v58 = (unsigned __int64)(v57 * (signed __int64)v58) >> 16;
      v57 = 58500;
      v1->vVelocity.y = v58;
      v58 = v1->vVelocity.z;
      v58 = (unsigned __int64)(v57 * (signed __int64)v58) >> 16;
      ++v55;
      v43 = __OFSUB__(v55, 100);
      v42 = v55 - 100 < 0;
      v1->vVelocity.z = v58;
      if ( !(v42 ^ v43) )
        return;
    }
    v57 = sub_452A9E(v1->vVelocity.y * v1->vVelocity.y + v1->vVelocity.x * v1->vVelocity.x);
    v38 = stru_5C6E00->Atan2(
            v1->vPosition.x - pLevelDecorations[v30].vPosition.x,
            v1->vPosition.y - pLevelDecorations[v30].vPosition.y);
    v56 = v38;
    v39 = stru_5C6E00->SinCos(v38);
    v60 = (Actor *)v39;
    v40 = v39 * (signed __int64)v57;
    v58 = v40 >> 16;
    v1->vVelocity.x = WORD1(v40);
    v41 = stru_5C6E00->SinCos(v56 - stru_5C6E00->uIntegerHalfPi);
    v60 = (Actor *)v41;
    v35 = (unsigned __int64)(v41 * (signed __int64)v57) >> 16;
    v58 = v35;
LABEL_73:
    v1->vVelocity.y = v35;
    goto LABEL_74;
  }
}



//----- (0047253E) --------------------------------------------------------
void UpdateObjects()
{
  unsigned int v0; // ebx@0
  //unsigned int v1; // edi@1
  char *v2; // esi@2
  //__int16 v3; // dx@5
  ObjectDesc *v4; // eax@5
  int v5; // ecx@6
  __int16 v6; // cx@7
  signed int v7; // eax@9
  __int16 v8; // cx@14
  __int16 v9; // dx@14
  unsigned int v10; // ecx@16
  signed int v11; // eax@17
  int v12; // edi@27
  int v13; // eax@27
  int v14; // ebx@27
  unsigned int v15; // ecx@27
  unsigned int v16; // edx@30
  unsigned int v17; // edx@32
  int v18; // [sp+4h] [bp-10h]@27
  int v19; // [sp+8h] [bp-Ch]@27
  //signed int v20; // [sp+10h] [bp-4h]@1

  //v1 = 0;
  //v20 = 0;
  for (uint i = 0; i < uNumLayingItems; ++i)
  {
    auto item = pLayingItems + i;
    v2 = (char *)&item->uSpriteFrameID;
    //do
    //{
      //LOWORD(v0) = item->uAttributes;
    if (item->uAttributes & 0x40)
      item->uAttributes &= 0xFFBF;
    else
    {
              //v3 = item->uObjectDescID;
      v4 = &pObjectList->pObjects[item->uObjectDescID];
      if (item->uAttributes)
      {
          v5 = *(int *)(v2 + 62) >> 3;
          *(int *)(v2 - 26) = pActors[v5].vPosition.x;
          *(int *)(v2 - 22) = pActors[v5].vPosition.y;
          *(int *)(v2 - 18) = pActors[v5].vPosition.z + pActors[v5].uActorHeight;
          if ( !item->uObjectDescID || (v6 = LOWORD(pEventTimer->uTimeElapsed) + *(short *)v2, *(short *)v2 = v6, !(v4->uFlags & 4)) )
            goto LABEL_36;
          if ( v6 >= 0 )
          {
            v7 = v4->uLifetime;
            if (item->uAttributes & 2)
              v7 = *((short *)v2 + 1);
            if ( v6 < v7 )
              goto LABEL_36;
          }
          goto LABEL_34;
      }

        if ( item->uObjectDescID )
        {
          v8 = LOWORD(pEventTimer->uTimeElapsed) + item->uSpriteFrameID;
          item->uSpriteFrameID = v8;
          v9 = v4->uFlags;
          if ( !(v9 & 4) )
            goto LABEL_22;
          if ( v8 < 0 )
          {
            v10 = i;
LABEL_35:
            LayingItem::_42F933(v10);
            goto LABEL_36;
          }
          v11 = v4->uLifetime;
          if ( item->uAttributes & 2 )
            v11 = *((short *)v2 + 1);
          if ( v8 < v11 )
          {
LABEL_22:
            if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
              LayingItem::UpdateObject_fn0_BLV(i);
            else
              LayingItem::UpdateObject_fn0_ODM(i);
            if ( pParty->bTurnBasedModeOn != 1 || !(*(v2 - 4) & 4) )
              goto LABEL_36;
            v12 = abs(pParty->vPosition.x - *(int *)(v2 - 26));
            v18 = abs(pParty->vPosition.y - *(int *)(v2 - 22));
            v19 = abs(pParty->vPosition.z - *(int *)(v2 - 18));
            v13 = v12;
            v14 = v18;
            v15 = v19;
            if ( v12 < v18 )
            {
              v13 = v18;
              v14 = v12;
            }
            if ( v13 < v19 )
            {
              v16 = v13;
              v13 = v19;
              v15 = v16;
            }
            if ( v14 < (signed int)v15 )
            {
              v17 = v15;
              v15 = v14;
              v14 = v17;
            }
            v0 = (unsigned int)(11 * v14) >> 5;
            if ( (signed int)(v0 + (v15 >> 2) + v13) <= 5120 )
              goto LABEL_36;
LABEL_34:
            v10 = i;
            goto LABEL_35;
          }
          v10 = i;
          if ( !(v9 & 0x40) )
            goto LABEL_35;
          _46BFFA_check_object_intercept(i, 8 * i | OBJECT_Item);
        }
    }
LABEL_36:
    ;
      //v2 += 112;
      //v1 = v20++ + 1;
    //}
    //while ( v20 < (signed int)uNumLayingItems );
  }
}

//----- (0047272C) --------------------------------------------------------
int _47272C_collide_agains_some_secotors_floors(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID)
{
  signed int v5; // ebx@1
  int result; // eax@1
  int v7; // [sp+10h] [bp-8h]@1
  signed int v8; // [sp+14h] [bp-4h]@1

  __debugbreak();
  v5 = x - 2;
  v7 = x;
  v8 = y;
  *pSectorID = pIndoor->GetSector(x - 2, y, z + 40);
  result = _46ED1B_collide_against_floor(v5, v8, z + 40, pSectorID, pFaceID);
  if ( result == -30000 || !*pSectorID )
  {
    *pSectorID = pIndoor->GetSector(v7 + 2, v8, z + 40);
    result = _46ED1B_collide_against_floor(v7 + 2, v8, z + 40, pSectorID, pFaceID);
    if ( result == -30000 || !*pSectorID )
    {
      *pSectorID = pIndoor->GetSector(v7, v8 - 2, z + 40);
      result = _46ED1B_collide_against_floor(v7, v8 - 2, z + 40, pSectorID, pFaceID);
      if ( result == -30000 || !*pSectorID )
      {
        *pSectorID = pIndoor->GetSector(v7, v8 + 2, z + 40);
        result = _46ED1B_collide_against_floor(v7, v8 + 2, z + 40, pSectorID, pFaceID);
        if ( result == -30000 || !*pSectorID )
        {
          *pSectorID = pIndoor->GetSector(v7, v8, z + 140);
          result = _46ED1B_collide_against_floor(v7, v8, z + 140, pSectorID, pFaceID);
        }
      }
    }
  }
  return result;
}

//----- (00472866) --------------------------------------------------------
void BLV_ProcessPartyActions()
{
  int v1; // ebx@1
  int v2; // edi@1
  int v6; // eax@18
  signed __int64 v8; // qax@27
  int v9; // eax@27
  double v10; // st7@27
  unsigned int v12; // eax@49
  double v13; // st7@50
  int v14; // eax@51
  signed __int64 v15; // qax@53
  double v16; // st7@54
  int v17; // eax@62
  double v18; // st7@62
  int v19; // ST40_4@62
  int v20; // eax@65
  double v21; // st7@65
  int v22; // ST40_4@65
  int v23; // eax@66
  double v24; // st7@66
  int v25; // ST40_4@66
  int v26; // eax@67
  double v27; // st7@67
  int v28; // ST40_4@67
  unsigned int v35; // eax@74
  int v36; // ecx@88
  int new_party_z; // esi@96
  int v38; // eax@96
  int v39; // ecx@106
  int v40; // eax@106
  Player **v41; // esi@113
  int v42; // eax@120
  signed int v43; // ecx@123
  BLVFace *v44; // esi@126
  PolygonType v45; // al@126
  int v46; // ecx@133
  char v47; // zf@133
  int v48; // eax@133
  int v49; // ST40_4@136
  int v50; // ST40_4@140
  int v51; // eax@140
  int v52; // eax@140
  signed int v53; // edi@146
  int v54; // ebx@146
  int v55; // ST30_4@146
  AudioPlayer *v56; // ecx@162
  SoundID v57; // [sp-20h] [bp-80h]@163
  signed int v58; // [sp-1Ch] [bp-7Ch]@161
  unsigned int v59; // [sp-18h] [bp-78h]@161
  signed int v60; // [sp-14h] [bp-74h]@161
  signed int v61; // [sp-10h] [bp-70h]@161
  int v62; // [sp-Ch] [bp-6Ch]@161
  int v63; // [sp-8h] [bp-68h]@75
  unsigned int v64; // [sp-8h] [bp-68h]@161
  int v65; // [sp-4h] [bp-64h]@75
  int v66; // [sp-4h] [bp-64h]@161
  int v68; // [sp+10h] [bp-50h]@45
  int v69; // [sp+10h] [bp-50h]@140
  unsigned int uFaceEvent; // [sp+14h] [bp-4Ch]@1
  signed int v71; // [sp+18h] [bp-48h]@1
  signed int v72; // [sp+1Ch] [bp-44h]@1
  signed int v73; // [sp+20h] [bp-40h]@100
  int v74; // [sp+20h] [bp-40h]@140
  bool bFeatherFall; // [sp+24h] [bp-3Ch]@15
  unsigned int uSectorID; // [sp+28h] [bp-38h]@1
  int v78; // [sp+2Ch] [bp-34h]@1
  unsigned int uFaceID; // [sp+30h] [bp-30h]@1
  int v80; // [sp+34h] [bp-2Ch]@1
  int v81; // [sp+38h] [bp-28h]@47
  int v82; // [sp+3Ch] [bp-24h]@47
  int _view_angle; // [sp+40h] [bp-20h]@47
  int bJumping; // [sp+44h] [bp-1Ch]@1
  int new_party_y; // [sp+48h] [bp-18h]@1
  int new_party_x; // [sp+4Ch] [bp-14h]@1
  int party_z; // [sp+50h] [bp-10h]@1
  int v89; // [sp+58h] [bp-8h]@1
  int angle; // [sp+5Ch] [bp-4h]@47

  uFaceEvent = 0;
  v89 = pParty->uFallSpeed;
  v1 = 0;
  new_party_y = pParty->vPosition.y;
  v2 = 0;
  new_party_x = pParty->vPosition.x;
  party_z = pParty->vPosition.z;
  uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
  v72 = 0;
  v78 = 0;
  v71 = 0;
  bJumping = 0;
  v80 = _46ED1B_collide_against_floor(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID);
  if ( pParty->bFlying )
  {
    pParty->bFlying = 0;
    __debugbreak();
    if (pParty->FlyActive())
      stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[7].uOverlayID + 119] |= 1u;// 005E4D58 pOtherOverlayList [negindexing]
  }
  if ( v80 == -30000 )
  {
    v80 = _47272C_collide_agains_some_secotors_floors(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID);
    if ( v80 == -30000 )
    {
      pParty->vPosition.x = blv_prev_party_x;
      pParty->vPosition.y = blv_prev_party_z;
      pParty->vPosition.z = blv_prev_party_y;
      pParty->uFallStartY = blv_prev_party_y;
      return;
    }
  }
  blv_prev_party_x = pParty->vPosition.x;
  blv_prev_party_z = pParty->vPosition.y;
  blv_prev_party_y = pParty->vPosition.z;
  if (!pParty->bTurnBasedModeOn)
  {
    auto v67 = GetTickCount() / 500;
    if (dword_720CDC != v67 )
    {
      dword_4F8580[3 * dword_4F8580[0] + 1] = pParty->vPosition.x;
      dword_4F8580[3 * dword_4F8580[0] + 2] = pParty->vPosition.y;
      dword_4F8580[3 * dword_4F8580[0]++ + 3] = pParty->vPosition.z;
      if ( dword_4F8580[0] > 60 )
        dword_4F8580[0] = 1;
    }
    dword_720CDC = v67;
  }
  if (!pParty->FeatherFallActive())
  {
    bFeatherFall = false;
    if (!pParty->pPlayers[0].WearsItem(536, 16) &&
        !pParty->pPlayers[1].WearsItem(536, 16) &&
        !pParty->pPlayers[2].WearsItem(536, 16) &&
        !pParty->pPlayers[3].WearsItem(536, 16))
    {
      v6 = pParty->uFallStartY;
    }
  }
  else
  {
    v6 = v80;
    bFeatherFall = true;
    pParty->uFallStartY = v80;
  }
LABEL_20:
  if ( v6 - party_z > 512 && !bFeatherFall && party_z <= v80 + 1 )
  {
    if ( BYTE1(pParty->uFlags) & 1 )
    {
      BYTE1(pParty->uFlags) &= 0xFEu;
    }
    else for (uint i = 0; i < 4; ++i)
    {                                      // receive falling damage
      auto pPlayer = pParty->pPlayers + i;
           
      if (!pPlayer->HasEnchantedItemEquipped(72) &&
          !pPlayer->WearsItem(529, 8))
      {
        v8 = (signed __int64)((double)pPlayer->GetMaxHealth() * 0.1);
        pPlayer->ReceiveDamage((pParty->uFallStartY - party_z) * (signed int)v8 / 256, 4);
        v9 = pPlayer->GetActualEndurance();
        v10 = (double)(20 - pPlayer->_48EA1B_get_static_effect(v9)) * flt_6BE3A4_debug_recmod1 * 2.133333333333333;
        pPlayer->SetRecoveryTime((signed __int64)v10);
      }
    }
  }
  if ( party_z > v80 + 1 )
    bJumping = 1;
  bFeatherFall = party_z - v80 <= 32;
  if ( party_z - v80 <= 32 )
    pParty->uFallStartY = party_z;
  if ( bWalkSound && pParty->field_6F8 > 0 )
    pParty->field_6F8 -= pEventTimer->uTimeElapsed;
  if ( party_z > v80 + 1 )
  {
LABEL_43:
    if ( bJumping )
      goto LABEL_45;
    goto LABEL_44;
  }
  party_z = v80 + 1;
  pParty->uFallStartY = v80 + 1;
  if ( bJumping )
    goto LABEL_45;
  if (pParty->field_6F4_packedid != uFaceID)
  {
    auto pFace = &pIndoor->pFaces[uFaceID];
    if (pFace->uAttributes & 0x04000000 )
    {
      uFaceEvent = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID;
      goto LABEL_43;
    }
  }
LABEL_44:
  pParty->field_6F4_packedid = uFaceID;
LABEL_45:
  v68 = uFaceID;
  if ( pIndoor->pFaces[uFaceID].uAttributes & 0x10 )
    v71 = 1;
  v81 = pParty->uWalkSpeed;
  angle = pParty->sRotationY;
  _view_angle = pParty->sRotationX;
  v82 = (unsigned __int64)(pEventTimer->dt_in_some_format
                         * (signed __int64)((signed int)(pParty->y_rotation_speed * stru_5C6E00->uIntegerPi)
                                          / 180)) >> 16;
LABEL_87:
  while ( pPartyActionQueue->uNumActions )
  {
    switch ( pPartyActionQueue->Next() )
    {
      case PARTY_TurnLeft:
        __debugbreak();
        v12 = uTurnSpeed;
        if ( uTurnSpeed )
          goto LABEL_58;
        v13 = (double)v82 * fTurnSpeedMultiplier;
        goto LABEL_51;
      case PARTY_TurnRight:
        __debugbreak();
        LODWORD(v15) = uTurnSpeed;
        if ( uTurnSpeed )
          goto LABEL_56;
        v16 = (double)v82 * fTurnSpeedMultiplier;
        goto LABEL_55;
      case PARTY_FastTurnLeft:
        v12 = uTurnSpeed;
        if ( uTurnSpeed )
        {
LABEL_58:
          v14 = angle + v12;
        }
        else
        {
          v13 = (fTurnSpeedMultiplier + fTurnSpeedMultiplier) * (double)v82;
LABEL_51:
          v14 = angle + (unsigned __int64)(signed __int64)v13;
        }
        angle = stru_5C6E00->uDoublePiMask & v14;
        goto LABEL_87;
      case PARTY_FastTurnRight:
        LODWORD(v15) = uTurnSpeed;
        if ( !uTurnSpeed )
        {
          v16 = (fTurnSpeedMultiplier + fTurnSpeedMultiplier) * (double)v82;
LABEL_55:
          v15 = (signed __int64)v16;
        }
LABEL_56:
        angle = stru_5C6E00->uDoublePiMask & (angle - v15);
        goto LABEL_87;
      case PARTY_StrafeLeft:
        __debugbreak();
        v17 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
        v18 = (double)v81;
        //v88 = v18;
        v78 = (unsigned __int64)(v17 * (signed __int64)((signed int)(signed __int64)(v18 * fWalkSpeedMultiplier) >> 1)) >> 16;
        v2 -= v78;
        v19 = stru_5C6E00->SinCos(angle);
        v78 = (unsigned __int64)(v19 * (signed __int64)((signed int)(signed __int64)(v18 * fWalkSpeedMultiplier) >> 1)) >> 16;
        goto LABEL_63;
      case PARTY_StrafeRight:
        __debugbreak();
        v20 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
        v21 = (double)v81;
        //v88 = v21;
        v78 = (unsigned __int64)(v20 * (signed __int64)((signed int)(signed __int64)(v21 * fWalkSpeedMultiplier) >> 1)) >> 16;
        v2 += v78;
        v22 = stru_5C6E00->SinCos(angle);
        v78 = (unsigned __int64)(v22 * (signed __int64)((signed int)(signed __int64)(v21 * fWalkSpeedMultiplier) >> 1)) >> 16;
        goto LABEL_68;
      case PARTY_WalkForward:
        __debugbreak();
        v23 = stru_5C6E00->SinCos(angle);
        v24 = (double)v81;
        //v88 = v24;
        v78 = (unsigned __int64)(v23 * (signed __int64)(signed int)(signed __int64)(v24 * fWalkSpeedMultiplier)) >> 16;
        v2 += v78;
        v25 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
        v78 = (unsigned __int64)(v25 * (signed __int64)(signed int)(signed __int64)(v24 * fWalkSpeedMultiplier)) >> 16;
LABEL_63:
        v1 += v78;
        goto LABEL_64;
      case PARTY_WalkBackward:
        __debugbreak();
        v26 = stru_5C6E00->SinCos(angle);
        v27 = (double)v81;
        //v88 = v27;
        v78 = (unsigned __int64)(v26
                               * (signed __int64)(signed int)(signed __int64)(v27 * fBackwardWalkSpeedMultiplier)) >> 16;
        v2 -= v78;
        v28 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
        v78 = (unsigned __int64)(v28
                               * (signed __int64)(signed int)(signed __int64)(v27 * fBackwardWalkSpeedMultiplier)) >> 16;
LABEL_68:
        v1 -= v78;
LABEL_64:
        v78 = 1;
        goto LABEL_87;
      case PARTY_RunForward:
        //v29 = stru_5C6E00->SinCos(angle);
        //v30 = (double)v81;
        //v88 = (double)v81;
        v2 += (unsigned __int64)(stru_5C6E00->SinCos(angle) * (signed __int64)(signed int)(2 * (unsigned __int64)(signed __int64)((double)v81 * fWalkSpeedMultiplier))) >> 16;
        //v31 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
        v1 += (unsigned __int64)(stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi) * (signed __int64)(signed int)(2 * (unsigned __int64)(signed __int64)((double)v81 * fWalkSpeedMultiplier))) >> 16;
        v72 = 1;
        goto LABEL_87;
      case PARTY_RunBackward:
        //v32 = stru_5C6E00->SinCos(angle);
        //v33 = (double)v81;
        //v88 = (double)v81;
        v2 -= (unsigned __int64)(stru_5C6E00->SinCos(angle) * (signed __int64)(signed int)(signed __int64)((double)v81 * fBackwardWalkSpeedMultiplier)) >> 16;
        //v34 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
        v1 -= (unsigned __int64)(stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi) * (signed __int64)(signed int)(signed __int64)((double)v81 * fBackwardWalkSpeedMultiplier)) >> 16;
//LABEL_70:
        v72 = 1;
        goto LABEL_87;
      case PARTY_LookUp:
        __debugbreak();
        _view_angle += (signed __int64)(flt_6BE150_look_up_down_dangle * 25.0);
        if ( _view_angle > 128 )
          _view_angle = 128;
        v35 = uActiveCharacter;
        if ( !uActiveCharacter )
          goto LABEL_87;
        v65 = 0;
        v63 = SPEECH_63;
        goto LABEL_76;
      case PARTY_LookDown:
        __debugbreak();
        _view_angle += (signed __int64)(flt_6BE150_look_up_down_dangle * -25.0);
        if ( _view_angle < -128 )
          _view_angle = -128;
        v35 = uActiveCharacter;
        if ( uActiveCharacter )
        {
          v65 = 0;
          v63 = SPEECH_64;
LABEL_76:
          pPlayers[v35]->PlaySound((PlayerSpeech)v63, v65);
        }
        break;
      case PARTY_CenterView:
        __debugbreak();
        _view_angle = 0;
        break;
      case PARTY_Jump:
        __debugbreak();
        if ( (!bJumping || party_z <= v80 + 6 && v89 <= 0) && pParty->field_24 )
        {
          bJumping = 1;
          v89 = (signed __int64)((double)(pParty->field_24 << 6) * 1.5 + (double)v89);
        }
        break;
      default:
        goto LABEL_87;
    }
  }
  v36 = 0;
  pParty->sRotationY = angle;
  pParty->sRotationX = _view_angle;
  if ( bJumping )
  {
    v89 += -2 * pEventTimer->uTimeElapsed * GetGravityStrength();
  }
  else
  {
    if ( pIndoor->pFaces[v68].pFacePlane_old.vNormal.z < 32768 )
    {
      v89 -= pEventTimer->uTimeElapsed * GetGravityStrength();
      goto LABEL_92;
    }
    if ( BYTE1(pParty->uFlags) & 1 )
      goto LABEL_92;
    v89 = 0;
  }
  if ( bJumping != v36 && v89 <= v36 )
  {
    if ( v89 < -500 && !pParty->bFlying )
    {
      v41 = &pPlayers[1];
      do
      {
        if ( !(*v41)->HasEnchantedItemEquipped(72) && !(*v41)->WearsItem(529, 8) )
          (*v41)->PlayEmotion(CHARACTER_EXPRESSION_46, 0);
        ++v41;
      }
      while ( (signed int)v41 <= (signed int)&pPlayers[4] );
    }
    goto LABEL_93;
  }
LABEL_92:
  pParty->uFallStartY = party_z;
LABEL_93:
  if ( v2 * v2 + v1 * v1 < 400 )
  {
    v1 = 0;
    v2 = 0;
  }
  stru_721530.field_84 = -1;
  stru_721530.field_70 = 0;
  stru_721530.prolly_normal_d = pParty->field_14;
  stru_721530.field_8 = pParty->field_14 >> 1;
  auto v83 = 0;
  stru_721530.field_0 = 1;
  stru_721530.field_C = pParty->uPartyHeight - 32;
  while ( 1 )
  {
    new_party_z = party_z;
    stru_721530.field_34.x = new_party_x;
    stru_721530.normal.x = new_party_x;
    stru_721530.field_1C = v2;
    stru_721530.field_34.y = new_party_y;
    stru_721530.normal.y = new_party_y;
    stru_721530.field_20 = v1;
    stru_721530.normal.z = stru_721530.prolly_normal_d + party_z + 1;
    stru_721530.field_34.z = stru_721530.field_C + party_z + 1;
    stru_721530.field_24 = v89;
    stru_721530.uSectorID = uSectorID;
    v38 = 0;
    if ( pParty->bTurnBasedModeOn == 1 && pTurnEngine->field_4 == 3 )
      v38 = 13312;
    if ( stru_721530._47050A(v38) )
      break;
    v73 = 0;
    do
    {
      _46E44E_collide_against_faces_and_portals(1u);
      _46E0B2_collide_against_decorations();
      for ( v80 = 0; v80 < (signed int)uNumActors; ++v80 )
        _46DF1A_collide_against_actor(v80, 0);
      if ( _46F04E_collide_against_portals() )
        break;
      ++v73;
    }
    while ( v73 < 100 );
    if ( stru_721530.field_7C >= stru_721530.field_6C )
    {
      v39 = stru_721530.normal2.x;
      uSectorID = stru_721530.normal2.y;
      v40 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
    }
    else
    {
      v39 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16) + new_party_x;
      uSectorID = new_party_y + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16);
      v40 = new_party_z + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16);
    }
    v42 = _46ED1B_collide_against_floor(v39, uSectorID, v40 + 40, &stru_721530.uSectorID, &uFaceID);
    if ( v42 == -30000 || v42 - new_party_z > 128 )
      return;
    if ( stru_721530.field_7C >= stru_721530.field_6C )
    {
      new_party_x = stru_721530.normal2.x;
      new_party_y = stru_721530.normal2.y;
      new_party_z = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
      break;
    }
    new_party_x += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16;
    new_party_y += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16;
    v43 = stru_721530.uFaceID;
    uSectorID = stru_721530.uSectorID;
    stru_721530.field_70 += stru_721530.field_7C;
    auto v87 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16) + new_party_z;
    if ( (stru_721530.uFaceID & 7) == OBJECT_Actor)
    {
      if ( SHIDWORD(pParty->pPartyBuffs[11].uExpireTime) >= 0
        && (SHIDWORD(pParty->pPartyBuffs[11].uExpireTime) > 0 || LODWORD(pParty->pPartyBuffs[11].uExpireTime)) )
        pParty->pPartyBuffs[11].Reset();
      viewparams->bRedrawGameUI = 1;
      goto LABEL_152;
    }
    if ( (stru_721530.uFaceID & 7) == OBJECT_Decoration)
    {
      v53 = sub_452A9E(v2 * v2 + v1 * v1);
      v80 = v53;
      v54 = stru_5C6E00->Atan2(
              new_party_x - pLevelDecorations[stru_721530.uFaceID >> 3].vPosition.x,
              new_party_y - pLevelDecorations[stru_721530.uFaceID >> 3].vPosition.y);
      v2 = (unsigned __int64)(stru_5C6E00->SinCos(v54) * (signed __int64)v53) >> 16;
      v55 = stru_5C6E00->SinCos(v54 - stru_5C6E00->uIntegerHalfPi);
      v1 = (unsigned __int64)(v55 * (signed __int64)v80) >> 16;
    }
    else
    {
      if ( (stru_721530.uFaceID & 7) == OBJECT_BModel)
      {
        v44 = &pIndoor->pFaces[(signed int)stru_721530.uFaceID >> 3];
        v45 = v44->uPolygonType;
        if ( v45 == 3 )
        {
          if ( v89 < 0 )
            v89 = 0;
          v87 = pIndoor->pVertices[*v44->pVertexIDs].z + 1;
          if ( pParty->uFallStartY - v87 < 512 )
            pParty->uFallStartY = v87;
          if ( v2 * v2 + v1 * v1 < 400 )
          {
            v1 = 0;
            v2 = 0;
          }
          goto LABEL_143;
        }
        v46 = v89 * v44->pFacePlane_old.vNormal.z;
        v47 = v45 == 4;
        v48 = v44->pFacePlane_old.vNormal.x;
        if ( !v47 )
        {
          v80 = abs(v1 * v44->pFacePlane_old.vNormal.y + v46 + v2 * v48) >> 16;
          if ( stru_721530.field_64 >> 3 > v80 )
            v80 = stru_721530.field_64 >> 3;
          v50 = (unsigned __int64)(v80 * (signed __int64)v44->pFacePlane_old.vNormal.x) >> 16;
          v81 = v44->pFacePlane_old.vNormal.y;
          v81 = (unsigned __int64)(v80 * (signed __int64)v81) >> 16;
          v82 = v44->pFacePlane_old.vNormal.z;
          v82 = (unsigned __int64)(v80 * (signed __int64)v82) >> 16;
          v2 += v50;
          v89 += v82;
          v74 = v44->pFacePlane_old.vNormal.z;
          v51 = v44->pFacePlane_old.vNormal.y;
          v69 = v44->pFacePlane_old.vNormal.x;
          v80 = v51;
          v1 += v81;
          v52 = stru_721530.prolly_normal_d - ((v44->pFacePlane_old.dist + v87 * v74 + new_party_y * v51 + new_party_x * v69) >> 16);
          if ( v52 > 0 )
          {
            new_party_x += v52 * v69 >> 16;
            new_party_y += v52 * v80 >> 16;
            v87 += v52 * v74 >> 16;
          }
LABEL_142:
          v43 = stru_721530.uFaceID;
LABEL_143:
          if ( pParty->field_6F4_packedid != v43 >> 3 && BYTE3(v44->uAttributes) & 4 )
            uFaceEvent = pIndoor->pFaceExtras[v44->uFaceExtraID].uEventID;
          goto LABEL_152;
        }
        v80 = abs(v1 * v44->pFacePlane_old.vNormal.y + v46 + v2 * v48) >> 16;
        if ( stru_721530.field_64 >> 3 > v80 )
          v80 = stru_721530.field_64 >> 3;
        v49 = (unsigned __int64)(v80 * (signed __int64)v44->pFacePlane_old.vNormal.x) >> 16;
        v81 = v44->pFacePlane_old.vNormal.y;
        v81 = (unsigned __int64)(v80 * (signed __int64)v81) >> 16;
        v82 = v44->pFacePlane_old.vNormal.z;
        v82 = (unsigned __int64)(v80 * (signed __int64)v82) >> 16;
        v2 += v49;
        v1 += v81;
        v89 += v82;
        if ( v2 * v2 + v1 * v1 >= 400 )
          goto LABEL_142;
        v2 = 0;
        v1 = 0;
        v89 = 0;
      }
    }
LABEL_152:
    v2 = (unsigned __int64)(58500i64 * v2) >> 16;
    v1 = (unsigned __int64)(58500i64 * v1) >> 16;
    ++v83;
    v89 = (unsigned __int64)(58500i64 * v89) >> 16;
    if ( v83 >= 100 )
    {
      new_party_z = v87;
      break;
    }
  }
  if ( bWalkSound && pParty->field_6F8 <= 0 )
  {
    if ( sub_452A9E((pParty->vPosition.x - new_party_x) * (pParty->vPosition.x - new_party_x) + (pParty->vPosition.y - new_party_y)
                                                                            * (pParty->vPosition.y - new_party_y)
                                                                            + (pParty->vPosition.z - new_party_z)
                                                                            * (pParty->vPosition.z - new_party_z)) <= 16 )
      goto LABEL_188;
    if ( v72 && (!bJumping || bFeatherFall) )
    {
      v66 = 0;
      v64 = 0;
      v62 = 0;
      v61 = 0;
      v60 = -1;
      v59 = 1;
      v58 = 804;
      if ( !v71 )
      {
        v56 = pAudioPlayer;
        if ( BYTE2(pIndoor->pFaces[uFaceID].uAttributes) & 0x20 )
          v57 = (SoundID)50;
        else
          v57 = (SoundID)64;
        goto LABEL_175;
      }
      v57 = (SoundID)63;
LABEL_174:
      v56 = pAudioPlayer;
      goto LABEL_175;
    }
    if ( v78 && (!bJumping || bFeatherFall) )
    {
      v66 = 0;
      v64 = 0;
      v62 = 0;
      v61 = 0;
      v60 = -1;
      v59 = 1;
      v58 = 804;
      if ( v71 )
      {
        v57 = (SoundID)102;
        goto LABEL_174;
      }
      v56 = pAudioPlayer;
      if ( BYTE2(pIndoor->pFaces[uFaceID].uAttributes) & 0x20 )
        v57 = (SoundID)89;
      else
        v57 = (SoundID)103;
LABEL_175:
      pAudioPlayer->PlaySound(v57, v58, v59, v60, v61, v62, v64, v66);
    }
    else
    {
LABEL_188:
      pAudioPlayer->_4AA258(804);
      pParty->field_6F8 = 64;
    }
  }
  if ( !bJumping || bFeatherFall )
    pParty->uFlags &= 0xFFFFFFF7u;
  else
    pParty->uFlags |= 8u;
  BYTE1(pParty->uFlags) &= 0xFDu;
  pParty->vPosition.x = new_party_x;
  pParty->vPosition.z = new_party_z;
  pParty->vPosition.y = new_party_y;
  pParty->uFallSpeed = v89;
  if ( !bJumping && BYTE3(pIndoor->pFaces[uFaceID].uAttributes) & 0x40 )
    BYTE1(pParty->uFlags) |= 2u;
  if (uFaceEvent)
    EventProcessor(uFaceEvent, 0, 1);
}


//----- (00473893) --------------------------------------------------------
void __cdecl ODM_ProcessPartyActions()
{
  //int _zero; // esi@1
  int v1; // edi@1
  int v2; // ebx@1
  int v3; // eax@14
  //Player **v4; // esi@21
  //int v5; // eax@24
  int v6; // esi@45
  ODMFace *v7; // ecx@45
  //unsigned int v8; // eax@71
  //double v9; // st7@72
  //signed __int64 v10; // qax@74
  //double v11; // st7@75
  //int v12; // ecx@77
  //int v13; // eax@84
  //double v14; // st7@84
  //int v15; // eax@87
  //double v16; // st7@87
  //int v17; // eax@88
  //double v18; // st7@88
  //int v19; // eax@89
  //double v20; // st7@89
  //int v21; // eax@92
  //double v22; // st7@92
  //int v23; // eax@96
  //double v24; // st7@96
  //int v25; // eax@97
  //double v26; // st7@97
  //int v27; // eax@98
  //double v28; // st7@98
  //signed __int64 v29; // qax@98
  //unsigned int v30; // eax@103
  int v31; // eax@130
  //int v32; // ecx@141
  signed int v33; // eax@143
  int v34; // esi@143
  int v35; // esi@147
  int v36; // eax@155
  signed int v37; // esi@159
  signed int v38; // eax@159
  signed int i; // esi@159
  int v40; // esi@162
  //Player **v41; // esi@172
  bool v42; // eax@180
  signed int v43; // ecx@184
  signed int v44; // edx@184
  int v45; // ecx@200
  BSPModel *v46; // eax@203
  ODMFace *v47; // esi@203
  int v48; // eax@203
  char v49; // zf@203
  char v50; // sf@203
  unsigned __int8 v51; // of@203
  int v52; // eax@203
  unsigned __int8 v53; // dl@205
  BSPModel *v54; // eax@215
  int v55; // eax@217
  signed int v56; // ebx@228
  int v57; // eax@228
  BSPModel *v58; // eax@228
  unsigned __int64 v59; // qax@228
  BSPModel *v60; // eax@228
  unsigned __int64 v61; // qax@228
  int v62; // eax@241
  signed int v63; // ST04_4@255
  signed int v64; // eax@255
  unsigned int v65; // ebx@263
  unsigned int v66; // esi@263
  int v67; // eax@263
  signed int v68; // ecx@263
  int v69; // eax@263
  int v70; // ebx@271
  int v71; // esi@271
  int v72; // edi@271
  int v73; // eax@271
  Player **v74; // esi@283
  int v75; // eax@284
  unsigned int v76; // edi@293
  bool v77; // edx@297
  bool v78; // ecx@303
  int v79; // ecx@314
  __int16 v80; // dx@317
  int v81; // ebx@318
  int v82; // ecx@318
  int v83; // eax@321
  Player **v84; // esi@333
  int v85; // eax@334
  int v86; // [sp-20h] [bp-B4h]@246
  int v87; // [sp-20h] [bp-B4h]@248
  signed int v88; // [sp-1Ch] [bp-B0h]@246
  unsigned int v89; // [sp-18h] [bp-ACh]@246
  signed int v90; // [sp-14h] [bp-A8h]@246
  signed int v91; // [sp-10h] [bp-A4h]@246
  int v92; // [sp-Ch] [bp-A0h]@246
  //int v93; // [sp-8h] [bp-9Ch]@104
  unsigned int v94; // [sp-8h] [bp-9Ch]@246
  //int v95; // [sp-4h] [bp-98h]@104
  int v96; // [sp-4h] [bp-98h]@246
  int v97; // [sp+Ch] [bp-88h]@180
  Vec3_int_ v98;
  //int v98; // [sp+10h] [bp-84h]@147
  //int v99; // [sp+14h] [bp-80h]@147
  //int v100; // [sp+18h] [bp-7Ch]@147
  bool v101; // [sp+1Ch] [bp-78h]@33
  int v102; // [sp+20h] [bp-74h]@1
  int v103; // [sp+24h] [bp-70h]@1
  int bFeatherFall; // [sp+28h] [bp-6Ch]@4
  int v105; // [sp+2Ch] [bp-68h]@24
  int bWaterWalk; // [sp+30h] [bp-64h]@1
  bool v107; // [sp+34h] [bp-60h]@30
  int v108; // [sp+38h] [bp-5Ch]@1
  int v109; // [sp+3Ch] [bp-58h]@28
  int v110; // [sp+40h] [bp-54h]@180
  int v111; // [sp+44h] [bp-50h]@14
  int bJumping; // [sp+48h] [bp-4Ch]@1
  int v113; // [sp+4Ch] [bp-48h]@1
  unsigned int v114; // [sp+50h] [bp-44h]@1
  int _walk_speed; // [sp+54h] [bp-40h]@48
  int v116; // [sp+58h] [bp-3Ch]@1
  int v117; // [sp+5Ch] [bp-38h]@1
  int v118; // [sp+60h] [bp-34h]@1
  //Player **v119; // [sp+64h] [bp-30h]@4
  int _angle_x; // [sp+68h] [bp-2Ch]@48
  int v121; // [sp+6Ch] [bp-28h]@1
  unsigned int v122; // [sp+70h] [bp-24h]@180
  int v123; // [sp+74h] [bp-20h]@1
  int v124; // [sp+78h] [bp-1Ch]@1
  int _angle_y; // [sp+7Ch] [bp-18h]@48
  int v126; // [sp+80h] [bp-14h]@48
  BSPModel *v127; // [sp+84h] [bp-10h]@1
  int v128; // [sp+88h] [bp-Ch]@1
  int v129; // [sp+8Ch] [bp-8h]@92
  int v130; // [sp+90h] [bp-4h]@14

  v121 = pParty->uFallSpeed;
  v123 = pParty->vPosition.z;
  v1 = 0;
  v103 = 0;
  v2 = 0;
  *(float *)&v128 = 0.0;
  v116 = pParty->vPosition.x;
  v117 = pParty->vPosition.y;
  v113 = pParty->field_6F0;
  bJumping = 0;
  auto partyAtHighSlope = IsTerrainSlopeTooHigh(pParty->vPosition.x, pParty->vPosition.y);
  v114 = 0;
  v124 = 0;
  v108 = 0;
  v102 = 0;
  v127 = 0;
  bWaterWalk = 0;
  if (!pParty->FeatherFallActive())
      //SHIDWORD(pParty->pPartyBuffs[5].uExpireTime) < 0
      //|| SHIDWORD(pParty->pPartyBuffs[5].uExpireTime) <= 0 && LODWORD(pParty->pPartyBuffs[5].uExpireTime) <= 0 )
  {
    bFeatherFall = 0;
    /*v119 = &pPlayers[1];
    while ( !(*v119)->WearsItem(536, 16) )
    {
      ++v119;
      if ( (signed int)v119 > (signed int)&pPlayers[4] )
        goto LABEL_9;
    }*/
    for (int i = 0; i < 4; ++i)
      if (pParty->pPlayers[i].WearsItem(536, 16))  // seems like flying boots
      {
        bFeatherFall = 1;
        break;
      }
  }
//  bFeatherFall = 1;
//LABEL_9:
  LOBYTE(pParty->uFlags) &= 0x7Fu;
  if (pParty->WaterWalkActive())
  {
    //LOBYTE(pParty->uFlags) &= 0x7Fu;
    bWaterWalk = 1;
    *(short *)&stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[18].uOverlayID + 119] |= 1u;
    if (!(pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags & 1) &&
		pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uCaster-1].sMana <= 0 )//*(int *)&pParty->pArtifactsFound[6972 * pParty->pPartyBuffs[18].uCaster + 10] <= 0 )
      bWaterWalk = 0;
  }
  v3 = sub_46D49E_prolly_get_world_y_under_party(v116, v117, v123, pParty->uPartyHeight, &v130, &v108, bWaterWalk);
  v111 = v3;
  if ( bFeatherFall )
    pParty->uFallStartY = v3;
  else
    v3 = pParty->uFallStartY;
  if ( v3 - v123 > 512 && !bFeatherFall && v123 <= v111 + 1 )
  {
    if (pParty->uFlags & PARTY_FLAGS_1_LANDING)
    {
      pParty->uFlags &= ~PARTY_FLAGS_1_LANDING;
    }
    else for (int _i = 0; _i < 4; ++_i)     // receive falling damage
    {
      auto player = pParty->pPlayers + _i;

      if ( !player->HasEnchantedItemEquipped(72) && !player->WearsItem(529, 8) )
      {
        player->ReceiveDamage(
            (signed int)((pParty->uFallStartY - v123) * (unsigned __int64)(player->GetMaxHealth() / 10)) / 256,
            4);
        v105 = 20 - player->_48EA1B_get_static_effect(player->GetActualEndurance());
        player->SetRecoveryTime((signed __int64)((double)v105 * flt_6BE3A4_debug_recmod1 * 2.133333333333333));
      }
      //}
      //while ( (signed int)v4 <= (signed int)&pPlayers[4] );
    }
  }
  v109 = -1;
  if ( pParty->bFlying )
    v109 = sub_46D8E3(v116, v117, v123 + pParty->uPartyHeight, (int)&v102);
  v107 = v108 == 0;
  v105 = v111 + 1;
  if ( v123 <= v111 + 1 )
  {
    v109 = -1;
    pParty->bFlying = false;
  }
  else
  {
    bJumping = 1;
  }
  v101 = v123 - v111 <= 32;
  if ( bWalkSound && pParty->field_6F8 > 0 )
    pParty->field_6F8 -= pEventTimer->uTimeElapsed;
  if (!bUnderwater
    && SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) <= 0
    && (SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) < 0 || LODWORD(pParty->pPartyBuffs[7].uExpireTime) <= 0) )
    pParty->bFlying = false;
  if (!bJumping)
  {
    if ( pParty->field_6F4_packedid != (8 * v108 | OBJECT_BModel) )
    {
      if (v108)
      {
        if ( v108 >> 6 < pOutdoor->uNumBModels )
        {
          v7 = pOutdoor->pBModels[v108 >> 6].pFaces;
          v6 = v108 & 0x3F;
          /*if ( *(char *)(v7->pFacePlane.vNormal.x + 308 * v6 + 31) & 4 )
          {
            pParty->field_6F4_packedid = 8 * v108 | OBJECT_BModel;
            v103 = *(short *)(v7->pFacePlane.vNormal.x + 308 * v6 + 292);
          }*/
		  if ( BYTE3(v7[v6].uAttributes) & 4 )
          {
            pParty->field_6F4_packedid = 8 * v108 | OBJECT_BModel;
            v103 = v7[v6].sCogTriggeredID;
          }
        }
      }
    }
    pParty->field_6F4_packedid = 8 * v108 | OBJECT_BModel;
  }
  _walk_speed = pParty->uWalkSpeed;
  _angle_y = pParty->sRotationY;
  _angle_x = pParty->sRotationX;
  v126 = pEventTimer->dt_in_some_format;
  /*v119 = (Player **)((unsigned __int64)(pEventTimer->dt_in_some_format
                                      * (signed __int64)((signed int)(pParty->field_20_prolly_turn_speed
                                                                    * stru_5C6E00->uIntegerPi)
                                                       / 180)) >> 16);*/
  __int64 dturn = (unsigned __int64)(pEventTimer->dt_in_some_format * (signed __int64)((signed int)(pParty->y_rotation_speed * stru_5C6E00->uIntegerPi) / 180)) >> 16;
  while (pPartyActionQueue->uNumActions)
  {
    switch (pPartyActionQueue->Next())
    {
      case PARTY_FlyUp:
      {
        if (!pParty->FlyActive() && !bUnderwater)
          break;

        pParty->bFlying = false;
        if (bUnderwater ||
            pParty->pPartyBuffs[PARTY_BUFF_FLY].uFlags & 1 ||
            pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1].sMana <= 0 )
          {
            if ( pParty->vPosition.z < 4000 || bJumping )
            {
              v123 += 30;
              v113 += 30;
              pParty->bFlying = 1;
              if ( v123 > 4000 )
              {
                v123 = 4000;
                v113 = 4000;
              }
              v1 = 0;
              v2 = 0;
              v121 = 0;
              *(float *)&v128 = 0.0;
              if ( v102 && v123 < v109 && (signed int)(pParty->uPartyHeight + v123) >= v109 )
              {
                pParty->field_6E0 = 0;
                pParty->field_6E4 = 0;
                pPartyActionQueue->uNumActions = 0;
                BYTE1(pParty->uFlags) |= 1u;
                pParty->vPosition.z = v109 - pParty->uPartyHeight - 31;
                pParty->field_6F0 = v123;
                pParty->bFlying = 0;
                v123 = v109 - pParty->uPartyHeight - 31;
                v113 = pParty->field_6F0;
              }
              pParty->uFallSpeed = 0;
              v127 = (BSPModel *)1;
            }
          }
      }
      break;

      case PARTY_FlyDown:
        if (pParty->FlyActive() || bUnderwater)
        {
          pParty->bFlying = 0;
          if ( bUnderwater
            || pParty->pPartyBuffs[7].uFlags & 1
            || pParty->pPlayers[pParty->pPartyBuffs[7].uCaster-1].sMana <= 0 )//*(int *)&pParty->pArtifactsFound[6972 * pParty->pPartyBuffs[7].uCaster + 10] > 0 )
          {
            v123 -= 30;
            v113 -= 30;
            pParty->uFallSpeed = 0;
            v121 = 0;
            pParty->bFlying = 1;
            v127 = (BSPModel *)1;
            if ( v123 <= v111 )
            {
              pParty->bFlying = 0;
              pPartyActionQueue->uNumActions = 0;
            }
          }
        }
        break;

      case PARTY_TurnLeft:
        if (uTurnSpeed)
          _angle_y += uTurnSpeed;   //descrete turn
        else
          _angle_y += dturn * fTurnSpeedMultiplier;  // time-based smooth turn

        _angle_y &= stru_5C6E00->uDoublePiMask;
      break;

      case PARTY_TurnRight:
        if (uTurnSpeed)
          _angle_y -= uTurnSpeed;
        else
          _angle_y -= dturn * fTurnSpeedMultiplier;

        _angle_y &= stru_5C6E00->uDoublePiMask;
      break;

      case PARTY_FastTurnLeft:
        if (uTurnSpeed)
          _angle_y += uTurnSpeed;
        else
          _angle_y += 2.0f * fTurnSpeedMultiplier * (double)dturn;

        _angle_y &= stru_5C6E00->uDoublePiMask;
      break;

      case PARTY_FastTurnRight:
        if (!uTurnSpeed)
          _angle_y -= 2.0f * fTurnSpeedMultiplier * (double)dturn;
        else
          _angle_y -= uTurnSpeed;

        _angle_y &= stru_5C6E00->uDoublePiMask;
      break;

      case PARTY_StrafeLeft:
      {
        *(float *)&v128 = pParty->uWalkSpeed;

        float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0);
        int dx = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
        v2 -= 3 * dx / 4;
        
        float cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0);
        int dy = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
        v1 += 3 * dy / 4;

        v128 = v1;
        v124 = 1;
      }
      break;

      case PARTY_StrafeRight:
      {
        *(float *)&v128 = pParty->uWalkSpeed;

        float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0);
        int dx = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
        v2 += 3 * dx / 4;
        
        float cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0);
        int dy = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
        v1 -= 3 * dy / 4;

        v128 = v1;
        v124 = 1;
      }
      break;

      case PARTY_WalkForward:
      {
        *(float *)&v128 = _walk_speed;

        float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0),
              cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0);

        int dx = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
        v2 += dx;
        
        int dy = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
        v1 += dy;

        v128 = v1;
        v124 = 1;
      }
      break;

      case PARTY_RunForward:
      {
        *(float *)&v128 = _walk_speed;

        float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0),
              cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0);

        int dx = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;        
        int dy = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;

        if (pParty->bFlying)
        {
          v2 += 4 * dx;
          v1 += 4 * dy;

          v128 = v1;
        }
        else if (partyAtHighSlope && !v108)
        {
          v2 += dx;
          v1 += dy;

          v128 = v1;
          v124 = 1;
        }
        else
        {
          v2 += 2 * dx;
          v1 += 2 * dy;
          
          v128 = v1;
          v114 = 1;
        }
      }
      break;


      case PARTY_WalkBackward:
      {
        *(float *)&v128 = _walk_speed;

        float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0),
              cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0);

        int dx = cos_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier;
        v2 -= dx;
        
        int dy = sin_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier;
        v1 -= dy;

        v128 = v1;
        v124 = 1;
      }
      break;


      case PARTY_RunBackward:
      {
        float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0),
              cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0);

        int dx = cos_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier;        
        int dy = sin_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier;

        if (pParty->bFlying)
        {
          v2 -= 4 * dx;
          v1 -= 4 * dy;
          v128 = v1;
        }
        else
        {
          v2 -= dx;
          v1 -= dy;

          v128 = v1;
          v124 = 1;
        }
      }
      break;

      
      case PARTY_CenterView:
        _angle_x = 0;
      break;

      case PARTY_LookUp:
        _angle_x += (signed __int64)(flt_6BE150_look_up_down_dangle * 25.0);
        if ( _angle_x > 128 )
          _angle_x = 128;
        if (uActiveCharacter)
          pPlayers[uActiveCharacter]->PlaySound(SPEECH_63, 0);
      break;

      case PARTY_LookDown:
        _angle_x += (signed __int64)(flt_6BE150_look_up_down_dangle * -25.0);
        if ( _angle_x < -128 )
          _angle_x = -128;
        if (uActiveCharacter)
          pPlayers[uActiveCharacter]->PlaySound(SPEECH_64, 0);
      break;

      case PARTY_Jump:
        if ( (!partyAtHighSlope || v108) && !bJumping && pParty->field_24 && !(pParty->uFlags & 4) && !(BYTE1(pParty->uFlags) & 2) )
        {
          v126 = pParty->field_24 << 6;
          bJumping = 1;
          v121 = (signed __int64)((double)(pParty->field_24 << 6) * 1.5 + (double)v121);
        }
      break;

      default:
        assert(false);

      case PARTY_Land:
        if (pParty->bFlying)
        {
          pParty->uFlags |= PARTY_FLAGS_1_LANDING;
          pParty->uFallSpeed = 0;
        }
        pParty->bFlying = false;
        pPartyActionQueue->uNumActions = 0;
      break;
    }
  }

LABEL_123:
  pParty->sRotationY = _angle_y;
  pParty->sRotationX = _angle_x;
  if ( v123 < v111 )
  {
    if ( pParty->bFlying )
    {
LABEL_130:
      v31 = GetTickCount();
      v126 = stru_5C6E00->SinCos(v31);
      v129 = (unsigned __int64)(4i64 * v126) >> 16;
      v123 = v113 + v129;
      if ( v127 )
        v123 = v113;
      if (pParty->FlyActive())
        stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[7].uOverlayID + 119] &= 0xFEu;
      pParty->uFallStartY = v123;
      goto LABEL_141;
    }
    if ( v130 && v121 )
      sub_42F960_create_object(v116, v117, v111);
    v121 = 0;
    v123 = v111;
    pParty->uFallStartY = v111;
  }
  if ( pParty->bFlying )
    goto LABEL_130;
  v113 = v123;
  if (pParty->FlyActive())
    stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[7].uOverlayID + 119] |= 1u;

LABEL_141:
  if (bJumping && !pParty->bFlying)
  {
    v33 = -(pEventTimer->uTimeElapsed * GetGravityStrength());
    v34 = v121 + 2 * v33;
    v121 += 2 * v33;
    goto LABEL_164;
  }
  if (!partyAtHighSlope)
  {
    v34 = v121;
    if (!bJumping)
      goto LABEL_150;
    goto LABEL_164;
  }
  if (!bJumping)
  {
    if ( v108 )
      goto LABEL_150;

    // rolling down the hill
    // how it's done: you get a little bit pushed in the air along terrain normal, getting in the air
    // and falling to the gravity, gradually sliding downwards. nice trick
    v123 = v111;
    ODM_GetTerrainNormalAt(v116, v117, &v98);
    v35 = v121 + -8 * pEventTimer->uTimeElapsed * GetGravityStrength();
    v129 = abs((signed __int64)v2 * v98.x + (signed __int64)v1 * v98.y + (signed __int64)v35 * v98.z) >> 16;
    v2 += (unsigned __int64)(v129 * (signed __int64)v98.x) >> 16;
    v1 += (unsigned __int64)(v129 * (signed __int64)v98.y) >> 16;
    v34 = v35 + ((unsigned __int64)(v129 * (signed __int64)v98.z) >> 16);
    v128 = v1;
    v121 = v34;
    if (!bJumping)
      goto LABEL_150;
    goto LABEL_164;
  }
  v34 = v121;

LABEL_164:
  if ( !bUnderwater && v34 <= 0)
  {
    if ( v34 < -500
      && !pParty->bFlying
      && pParty->vPosition.z - v111 > 1000
      && !pParty->FeatherFallActive())
    { // falling scream
      for (int i = 0; i < 4; ++i)
      {
        auto player = pParty->pPlayers + i;
        if (!player->HasEnchantedItemEquipped(72) && !player->WearsItem(529, 8) && player->CanAct())
          player->PlaySound(SPEECH_66, 0);
      }
    }
  }
  else
  {
LABEL_150:
  pParty->uFallStartY = v123;
  }

  if ( v2 * v2 + v1 * v1 < 400 && !partyAtHighSlope )
  {
    *(float *)&v128 = 0.0;
    v2 = 0;
  }
  stru_721530.field_84 = -1;
  stru_721530.field_70 = 0;
  stru_721530.prolly_normal_d = pParty->field_14;
  stru_721530.field_8 = pParty->field_14 >> 1;
  v126 = 0;
  stru_721530.field_0 = 1;
  stru_721530.field_C = pParty->uPartyHeight - 32;
  do
  {
    stru_721530.field_34.x = v116;
    stru_721530.normal.x = v116;
    stru_721530.field_1C = v2;
    stru_721530.field_34.y = v117;
    stru_721530.normal.y = v117;
    stru_721530.normal.z = stru_721530.prolly_normal_d + v123 + 1;
    stru_721530.field_34.z = stru_721530.field_C + v123 + 1;
    stru_721530.field_20 = v128;
    stru_721530.field_24 = v121;
    v36 = 0;
    stru_721530.uSectorID = 0;
    if ( pParty->bTurnBasedModeOn == 1 && pTurnEngine->field_4 == 3 )
      v36 = 13312;
    if ( stru_721530._47050A(v36) )
      break;
    _46E889_collide_against_bmodels(1u);
    v37 = WorldPosToGridCellZ(pParty->vPosition.y);
    v38 = WorldPosToGridCellX(pParty->vPosition.x);
    _46E26D_collide_against_sprites(v38, v37);
    _46ED8A_collide_against_layingItems(4u);
    for ( i = 0; i < (signed int)uNumActors; ++i )
      _46DF1A_collide_against_actor(i, 0);
    if ( stru_721530.field_7C >= stru_721530.field_6C )
    {
      _angle_x = stru_721530.normal2.x;
      _angle_y = stru_721530.normal2.y;
      v40 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
    }
    else
    {
      _angle_x = v116 + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16);
      _angle_y = v117 + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16);
      v127 = (BSPModel *)((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16);
      v40 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16) + v123;
    }
    v122 = v40;
    sub_46D49E_prolly_get_world_y_under_party(_angle_x, _angle_y, v40, pParty->uPartyHeight, &v130, &v108, 0);
    v129 = sub_46D49E_prolly_get_world_y_under_party(_angle_x, v117, v40, pParty->uPartyHeight, &v130, &v97, 0);
    auto v119 = sub_46D49E_prolly_get_world_y_under_party(
                        v116,
                        _angle_y,
                        v40,
                        pParty->uPartyHeight,
                        &v130,
                        &v110,
                        0);
    v127 = (BSPModel *)IsTerrainSlopeTooHigh(_angle_x, v117);
    v42 = IsTerrainSlopeTooHigh(v116, _angle_y);
    v107 = 0;
    v118 = v42;
    if ( !v97 && !v110 && !v108 )
      v107 = 1;
    v43 = 1;
    v44 = 1;
    if ( bUnderwater || !v107 )
      goto LABEL_197;
    if ( v127 && v129 > v123 )
      v44 = 0;
    if ( v118 && v119 > v123 )
      v43 = 0;
    if ( v44 )
      goto LABEL_197;
    if ( v43 )
      goto LABEL_198;
    v127 = (BSPModel *)sub_46D49E_prolly_get_world_y_under_party(
                         _angle_x,
                         _angle_y,
                         v40,
                         pParty->uPartyHeight,
                         &v130,
                         &v108,
                         0);
    if ( IsTerrainSlopeTooHigh(_angle_x, _angle_y) && (signed int)v127 <= v123 )
    {
      v43 = 1;
LABEL_197:
      v116 = _angle_x;
      if ( !v43 )
        goto LABEL_199;
LABEL_198:
      v117 = _angle_y;
    }
LABEL_199:
    if ( stru_721530.field_7C >= stru_721530.field_6C )
    {
      if ( !v107 )
      {
        v116 = stru_721530.normal2.x;
        v117 = stru_721530.normal2.y;
      }
      v123 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
      break;
    }
    stru_721530.field_70 += stru_721530.field_7C;
    v116 = _angle_x;
    v117 = _angle_y;
    v45 = stru_721530.uFaceID;
    v123 = v40;
    if ( (stru_721530.uFaceID & 7) == OBJECT_Actor)
    {
      if (pParty->Invisible())
        pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset();

      viewparams->bRedrawGameUI = 1;
      goto LABEL_234;
    }
    if ( (stru_721530.uFaceID & 7) == OBJECT_Decoration)
    {
      v56 = sub_452A9E(v2 * v2 + v128 * v128);
      v118 = v56;
      v57 = stru_5C6E00->Atan2(
              _angle_x - pLevelDecorations[(signed int)stru_721530.uFaceID >> 3].vPosition.x,
              _angle_y - pLevelDecorations[(signed int)stru_721530.uFaceID >> 3].vPosition.y);
      v129 = v57;
      v58 = (BSPModel *)stru_5C6E00->SinCos(v57);
      v127 = v58;
      v59 = (signed int)v58 * (signed __int64)v56;
      v122 = v59 >> 16;
      v2 = v59 >> 16;
      v60 = (BSPModel *)stru_5C6E00->SinCos(v129 - stru_5C6E00->uIntegerHalfPi);
      v127 = v60;
      v61 = (signed int)v60 * (signed __int64)v118;
      v122 = v61 >> 16;
      v128 = v61 >> 16;
    }
    else
    {
      if ( (stru_721530.uFaceID & 7) == OBJECT_BModel)
      {
        pParty->bFlying = 0;
        v46 = &pOutdoor->pBModels[(signed int)stru_721530.uFaceID >> 9];
        v127 = v46;
		v47 = &v46->pFaces[((signed int)stru_721530.uFaceID >> 3) & 0x3F];
        v48 = v47->pBoundingBox.z2 - v47->pBoundingBox.z1;
        v51 = __OFSUB__(v48, 32);
        v49 = v48 == 32;
        v50 = v48 - 32 < 0;
        v52 = v47->pFacePlane.vNormal.z;
        v129 = (unsigned __int8)(v50 ^ v51 | v49);
        v119 = v52 < 46378;
        if ( bUnderwater == 1 )
          v119 = 0;
        v53 = v47->uPolygonType;
        if ( v53 == 3 )
        {
          if ( v121 < 0 )
            v121 = 0;
          v123 = v127->pVertices.pVertices[v47->pVertexIDs[0]].z + 1;
          if ( v2 * v2 + v128 * v128 < 400 )
          {
            v2 = 0;
            *(float *)&v128 = 0.0;
          }
          goto LABEL_221;
        }
        if ( !v129 && (v53 != 4 || v119) )
        {
          v118 = abs(v128 * v47->pFacePlane.vNormal.y + v121 * v52 + v2 * v47->pFacePlane.vNormal.x) >> 16;
          if ( stru_721530.field_64 >> 3 > v118 )
            v118 = stru_721530.field_64 >> 3;
          v129 = v47->pFacePlane.vNormal.x;
          v129 = (unsigned __int64)(v118 * (signed __int64)v129) >> 16;
          _walk_speed = v47->pFacePlane.vNormal.y;
          _walk_speed = (unsigned __int64)(v118 * (signed __int64)_walk_speed) >> 16;
          v54 = 0;
          if ( !v119 )
          {
            v127 = (BSPModel *)v47->pFacePlane.vNormal.z;
            v127 = (BSPModel *)((unsigned __int64)(v118 * (signed __int64)(signed int)v127) >> 16);
            v54 = v127;
          }
          v121 += (int)v54;
          v128 += _walk_speed;
          v2 += v129;
          v55 = stru_721530.prolly_normal_d
              - ((signed int)(v47->pFacePlane.dist
                            + v122 * v47->pFacePlane.vNormal.z
                            + _angle_y * v47->pFacePlane.vNormal.y
                            + _angle_x * v47->pFacePlane.vNormal.x) >> 16);
          if ( v55 > 0 )
          {
            v116 = _angle_x + (v47->pFacePlane.vNormal.x * v55 >> 16);
            v117 = _angle_y + (v47->pFacePlane.vNormal.y * v55 >> 16);
            if ( !v119 )
              v123 = v122 + (v47->pFacePlane.vNormal.z * v55 >> 16);
          }
LABEL_220:
          v45 = stru_721530.uFaceID;
LABEL_221:
          if ( pParty->field_6F4_packedid != v45 && BYTE3(v47->uAttributes) & 4 )
          {
            pParty->field_6F4_packedid = v45;
            v103 = v47->sCogTriggeredID;
          }
          goto LABEL_234;
        }
        v118 = abs(v128 * v47->pFacePlane.vNormal.y + v121 * v52 + v2 * v47->pFacePlane.vNormal.x) >> 16;
        if ( stru_721530.field_64 >> 3 > v118 )
          v118 = stru_721530.field_64 >> 3;
        v122 = v47->pFacePlane.vNormal.x;
        v122 = (unsigned __int64)(v118 * (signed __int64)(signed int)v122) >> 16;
        v127 = (BSPModel *)v47->pFacePlane.vNormal.y;
        v127 = (BSPModel *)((unsigned __int64)(v118 * (signed __int64)(signed int)v127) >> 16);
        v129 = v47->pFacePlane.vNormal.z;
        v129 = (unsigned __int64)(v118 * (signed __int64)v129) >> 16;
        v121 += v129;
        v2 += v122;
        v128 += (int)v127;
        if ( v2 * v2 + v128 * v128 >= 400 )
          goto LABEL_220;
        v2 = 0;
        v121 = 0;
        *(float *)&v128 = 0.0;
      }
    }
LABEL_234:
    v2 = (unsigned __int64)(58500i64 * v2) >> 16;
    v127 = (BSPModel *)58500;
    v128 = (unsigned __int64)(58500i64 * v128) >> 16;
    v122 = (unsigned __int64)(58500i64 * v121) >> 16;
    ++v126;
    v121 = (unsigned __int64)(58500i64 * v121) >> 16;
  }
  while ( v126 < 100 );
  if ( bWalkSound && pParty->field_6F8 <= 0 )
  {
    v122 = abs(pParty->vPosition.x - v116);
    v126 = abs(pParty->vPosition.y - v117);
    v62 = abs(pParty->vPosition.z - v123);
    if ( sub_452A9E(v122 * v122 + v126 * v126 + v62 * v62) < 8 )
      goto LABEL_344;
    if ( v114 && (!bJumping || v101) )
    {
      if ( !v107
        && !(BYTE1(pOutdoor->pBModels[pParty->field_6F4_packedid >> 9].pFaces[(pParty->field_6F4_packedid >> 3) & 0x3F].uAttributes) & 0x20) )
      {
        v96 = 0;
        v94 = 0;
        v92 = 0;
        v91 = 0;
        v90 = -1;
        v89 = 1;
        v88 = 804;
        v87 = 64;
        goto LABEL_257;
      }
      v96 = 0;
      v94 = 0;
      v92 = 0;
      v91 = 0;
      v90 = -1;
      v89 = 1;
      v88 = 804;
      v86 = 1;
LABEL_255:
      v63 = WorldPosToGridCellZ(pParty->vPosition.y) - 1;
      v64 = WorldPosToGridCellX(pParty->vPosition.x);
      v87 = pOutdoor->_47EE49(v64, v63, v86);
      goto LABEL_257;
    }
    if ( v124 && (!bJumping || v101) )
    {
      if ( v107
        || BYTE1(pOutdoor->pBModels[pParty->field_6F4_packedid >> 9].pFaces[(pParty->field_6F4_packedid >> 3) & 0x3F].uAttributes) & 0x20 )
      {
        v96 = 0;
        v94 = 0;
        v92 = 0;
        v91 = 0;
        v90 = -1;
        v89 = 1;
        v88 = 804;
        v86 = 0;
        goto LABEL_255;
      }
      v96 = 0;
      v94 = 0;
      v92 = 0;
      v91 = 0;
      v90 = -1;
      v89 = 1;
      v88 = 804;
      v87 = 103;
LABEL_257:
      pAudioPlayer->PlaySound((SoundID)v87, v88, v89, v90, v91, v92, v94, v96);
    }
    else
    {
LABEL_344:
      pAudioPlayer->_4AA258(804);
      pParty->field_6F8 = 64;
    }
  }
  if ( !bJumping || v101 )
    pParty->uFlags &= 0xFFFFFFF7u;
  else
    pParty->uFlags |= 8u;
  v126 = WorldPosToGridCellX(pParty->vPosition.x);
  v65 = WorldPosToGridCellZ(pParty->vPosition.y) - 1;
  v114 = WorldPosToGridCellX(v116);
  v66 = WorldPosToGridCellZ(v117) - 1;
  v127 = (BSPModel *)(((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(v126, v65) >> 1) & 1);
  v122 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(v114, v65) >> 1) & 1;
  v67 = pOutdoor->ActuallyGetSomeOtherTileInfo(v126, v66);
  v68 = 0;
  v69 = ((unsigned int)~v67 >> 1) & 1;
  if ( v114 == v126 && v66 == v65 && v122 && v69 )
    v68 = 1;
  if ( !v107 )
    v68 = 1;
  if ( v68 )
  {
    v70 = v123;
    v71 = v116;
    v72 = v117;
    pParty->uFallSpeed = v121;
    v73 = v123;
    pParty->vPosition.x = v116;
    pParty->vPosition.y = v117;
    pParty->vPosition.z = v123;
    pParty->field_6F0 = v113;
    if ( v123 > 8160 )
    {
      v73 = 8160;
      pParty->uFallStartY = 8160;
      pParty->vPosition.z = 8160;
    }
    if ( !v103
      || (EventProcessor(v103, 0, 1), pParty->vPosition.x == v71)
      && pParty->vPosition.y == v72
      && (v73 = pParty->vPosition.z, pParty->vPosition.z == v70) )
    {
      if ( v73 < v111 )
      {
        pParty->uFallSpeed = 0;
        v73 = v105;
        pParty->vPosition.z = v105;
        if ( pParty->uFallStartY - v70 > 512 && !bFeatherFall && v70 <= v105 && !bUnderwater )
        {
          if ( pParty->uFlags & 0x100 )
          {
            BYTE1(pParty->uFlags) &= 0xFEu;
          }
          else
          {
            v74 = &pPlayers[1];
            do
            {
              v110 = (*v74)->GetMaxHealth();
              (*v74)->ReceiveDamage(
                (signed int)((pParty->uFallStartY - v70) * (unsigned __int64)(signed __int64)((double)v110 * 0.1)) / 256,
                4);
              v75 = (*v74)->GetActualEndurance();
              v110 = 20 - (*v74)->_48EA1B_get_static_effect(v75);
              (*v74)->SetRecoveryTime(
                (signed __int64)((double)v110 * flt_6BE3A4_debug_recmod1 * 2.133333333333333));
              ++v74;
            }
            while ( (signed int)v74 <= (signed int)&pPlayers[4] );
            v73 = pParty->vPosition.z;
          }
        }
        pParty->uFallStartY = v70;
      }
      if ( v102 && v73 < v109 )
      {
        if ( (signed int)(pParty->uPartyHeight + v73) >= v109 )
        {
          pParty->vPosition.z = v109 - pParty->uPartyHeight - 1;
          pParty->field_6F0 = v109 - pParty->uPartyHeight - 1;
        }
      }
      LOWORD(pParty->uFlags) &= 0xFDFBu;
    }
    return;
  }
  v76 = pParty->bFlying;
  if ( pParty->bFlying || v101 == 0 || bWaterWalk || !v127 )
    v77 = 1;
  else
    v77 = v122 != 0;
  v114 = 0;
  if ( !pParty->bFlying && v101 != 0 && !bWaterWalk )
  {
    if ( v127 )
    {
      v78 = v69 != 0;
      goto LABEL_306;
    }
    v114 = 1;
  }
  v78 = 1;
LABEL_306:
  if ( v77 )
  {
    pParty->vPosition.x = v116;
    if ( !v78 )
      goto LABEL_313;
    goto LABEL_312;
  }
  if ( v78 )
  {
LABEL_312:
    pParty->vPosition.y = v117;
LABEL_313:
    if ( bWaterWalk )
    {
      LOBYTE(pParty->uFlags) &= 0x7Fu;
      v79 = 20 * pParty->pPartyBuffs[18].uOverlayID + 6180178;
      *(short *)&stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[18].uOverlayID + 119] |= 1u;
      if ( !v122 || !v69 )
      {
        if ( !v76 )
        {
          v80 = *(short *)v79;
          LOBYTE(pParty->uFlags) |= 0x80u;
          *(short *)v79 = v80 & 0xFFFE;
        }
      }
    }
    goto LABEL_318;
  }
  if ( bWalkSound && pParty->field_6F8 <= 0 )
  {
    pAudioPlayer->_4AA258(804);
    pParty->field_6F8 = 64;
  }
LABEL_318:
  v81 = v123;
  v82 = v123;
  pParty->vPosition.z = v123;
  if ( v123 > 8160 )
  {
    v82 = 8160;
    pParty->uFallStartY = 8160;
    pParty->vPosition.z = 8160;
  }
  LOWORD(pParty->uFlags) &= 0xFDFBu;
  pParty->uFallSpeed = v121;
  pParty->field_6F0 = v113;
  if ( v114 )
  {
    v83 = GetTerrainHeightsAroundParty2(pParty->vPosition.x, pParty->vPosition.y, &v110, 1);
    v82 = pParty->vPosition.z;
    if ( pParty->vPosition.z <= v83 )
      pParty->uFlags |= 4u;
  }
  if ( !v103
    || (EventProcessor(v103, 0, 1), pParty->vPosition.x == v116)
    && pParty->vPosition.y == v117
    && (v82 = pParty->vPosition.z, pParty->vPosition.z == v81) )
  {
    if ( v82 < v111 )
    {
      v82 = v105;
      pParty->uFallSpeed = 0;
      pParty->vPosition.z = v105;
      if ( pParty->uFallStartY - v81 > 512 && !bFeatherFall && v81 <= v105 && !bUnderwater )
      {
        if ( pParty->uFlags & 0x100 )
        {
          BYTE1(pParty->uFlags) &= 0xFEu;
        }
        else
        {
          v84 = &pPlayers[1];
          do
          {
            v110 = (*v84)->GetMaxHealth();
            (*v84)->ReceiveDamage(
              (signed int)((pParty->uFallStartY - v81) * (unsigned __int64)(signed __int64)((double)v110 * 0.1)) / 256,
              4);
            v85 = (*v84)->GetActualEndurance();
            v110 = 20 - (*v84)->_48EA1B_get_static_effect(v85);
            (*v84)->SetRecoveryTime((signed __int64)((double)v110 * flt_6BE3A4_debug_recmod1 * 2.133333333333333));
            ++v84;
          }
          while ( (signed int)v84 <= (signed int)&pPlayers[4] );
          v82 = pParty->vPosition.z;
        }
      }
      pParty->uFallStartY = v81;
    }
    if ( v102 && v82 < v109 && (signed int)(pParty->uPartyHeight + v82) >= v109 )
    {
      pParty->vPosition.z = v82 + pParty->uPartyHeight - v109 + 1;
      pParty->field_6F0 = v82 + pParty->uPartyHeight - v109 + 1;
    }
  }
}

//----- (0047531C) --------------------------------------------------------
bool __fastcall sub_47531C(int a1, int *a2, int a3, int a4, int a5, int a6, int a7, int a8, BLVFace *a9, int a10)
{
  BLVFace *v10; // ebx@1
  int v11; // ST1C_4@3
  int v12; // edi@3
  int v13; // esi@3
  int v14; // edi@4
  signed __int64 v15; // qtt@6
  __int16 v16; // si@7
  int *v18; // [sp+Ch] [bp-Ch]@1
  int v19; // [sp+10h] [bp-8h]@1
  int a7a; // [sp+30h] [bp+18h]@7
  int a9b; // [sp+38h] [bp+20h]@3
  int a9a; // [sp+38h] [bp+20h]@3
  int a10b; // [sp+3Ch] [bp+24h]@3
  signed int a10a; // [sp+3Ch] [bp+24h]@4
  int a10c; // [sp+3Ch] [bp+24h]@5

  v10 = a9;
  v18 = a2;
  v19 = a1;
  if ( a10 && BYTE3(a9->uAttributes) & 0x20 )
    return 0;
  v11 = (unsigned __int64)(a6 * (signed __int64)a9->pFacePlane_old.vNormal.x) >> 16;
  a10b = (unsigned __int64)(a7 * (signed __int64)a9->pFacePlane_old.vNormal.y) >> 16;
  a9b = (unsigned __int64)(a8 * (signed __int64)a9->pFacePlane_old.vNormal.z) >> 16;
  v12 = v11 + a9b + a10b;
  a9a = v11 + a9b + a10b;
  v13 = (a1 << 16)
      - a3 * v10->pFacePlane_old.vNormal.x
      - a4 * v10->pFacePlane_old.vNormal.y
      - a5 * v10->pFacePlane_old.vNormal.z
      - v10->pFacePlane_old.dist;
  if ( abs((a1 << 16)
         - a3 * v10->pFacePlane_old.vNormal.x
         - a4 * v10->pFacePlane_old.vNormal.y
         - a5 * v10->pFacePlane_old.vNormal.z - v10->pFacePlane_old.dist) >= a1 << 16 )
  {
    a10c = abs(v13) >> 14;
    if ( a10c > abs(v12) )
      return 0;
    LODWORD(v15) = v13 << 16;
    HIDWORD(v15) = v13 >> 16;
    v14 = v19;
    a10a = v15 / a9a;
  }
  else
  {
    a10a = 0;
    v14 = abs(v13) >> 16;
  }
  v16 = a4 + ((unsigned int)((unsigned __int64)(a10a * (signed __int64)a7) >> 16) >> 16);
  LOWORD(a7a) = (short)a3
              + ((unsigned int)((unsigned __int64)(a10a * (signed __int64)a6) >> 16) >> 16)
              - ((unsigned int)(v14 * v10->pFacePlane_old.vNormal.x) >> 16);
  HIWORD(a7a) = v16 - ((unsigned int)(v14 * v10->pFacePlane_old.vNormal.y) >> 16);
  if ( !sub_475665(
          v10,
          a7a,
          (short)a5
        + ((unsigned int)((unsigned __int64)(a10a * (signed __int64)a8) >> 16) >> 16)
        - ((unsigned int)(v14 * v10->pFacePlane_old.vNormal.z) >> 16)) )
    return 0;
  *v18 = a10a >> 16;
  if ( a10a >> 16 < 0 )
    *v18 = 0;
  return 1;
}

//----- (004754BF) --------------------------------------------------------
bool __fastcall sub_4754BF(int a1, int *a2, int a3, int a4, int a5, int a6, int a7, int a8, BLVFace *a9, int a10, int a11)
{
  BLVFace *v11; // ebx@1
  int v12; // ST1C_4@3
  int v13; // edi@3
  int v14; // esi@3
  int v15; // edi@4
  signed __int64 v16; // qtt@6
  __int16 v17; // si@7
  int *v19; // [sp+Ch] [bp-Ch]@1
  int v20; // [sp+10h] [bp-8h]@1
  int a7a; // [sp+30h] [bp+18h]@7
  int a1b; // [sp+38h] [bp+20h]@3
  int a1a; // [sp+38h] [bp+20h]@3
  int a11b; // [sp+40h] [bp+28h]@3
  signed int a11a; // [sp+40h] [bp+28h]@4
  int a11c; // [sp+40h] [bp+28h]@5

  v11 = a9;
  v19 = a2;
  v20 = a1;
  if ( a11 && BYTE3(a9->uAttributes) & 0x20 )
    return 0;
  v12 = (unsigned __int64)(a6 * (signed __int64)a9->pFacePlane_old.vNormal.x) >> 16;
  a11b = (unsigned __int64)(a7 * (signed __int64)a9->pFacePlane_old.vNormal.y) >> 16;
  a1b = (unsigned __int64)(a8 * (signed __int64)a9->pFacePlane_old.vNormal.z) >> 16;
  v13 = v12 + a1b + a11b;
  a1a = v12 + a1b + a11b;
  v14 = (a1 << 16)
      - a3 * v11->pFacePlane_old.vNormal.x
      - a4 * v11->pFacePlane_old.vNormal.y
      - a5 * v11->pFacePlane_old.vNormal.z
      - v11->pFacePlane_old.dist;
  if ( abs((a1 << 16)
         - a3 * v11->pFacePlane_old.vNormal.x
         - a4 * v11->pFacePlane_old.vNormal.y
         - a5 * v11->pFacePlane_old.vNormal.z - v11->pFacePlane_old.dist) >= a1 << 16 )
  {
    a11c = abs(v14) >> 14;
    if ( a11c > abs(v13) )
      return 0;
    LODWORD(v16) = v14 << 16;
    HIDWORD(v16) = v14 >> 16;
    v15 = v20;
    a11a = v16 / a1a;
  }
  else
  {
    a11a = 0;
    v15 = abs(v14) >> 16;
  }
  v17 = a4 + ((unsigned int)((unsigned __int64)(a11a * (signed __int64)a7) >> 16) >> 16);
  LOWORD(a7a) = (short)a3
              + ((unsigned int)((unsigned __int64)(a11a * (signed __int64)a6) >> 16) >> 16)
              - ((unsigned int)(v15 * v11->pFacePlane_old.vNormal.x) >> 16);
  HIWORD(a7a) = v17 - ((unsigned int)(v15 * v11->pFacePlane_old.vNormal.y) >> 16);
  if ( !sub_4759C9(
          v11,
          a10,
          a7a,
          (short)a5
        + ((unsigned int)((unsigned __int64)(a11a * (signed __int64)a8) >> 16) >> 16)
        - ((unsigned int)(v15 * v11->pFacePlane_old.vNormal.z) >> 16)) )
    return 0;
  *v19 = a11a >> 16;
  if ( a11a >> 16 < 0 )
    *v19 = 0;
  return 1;
}



//----- (00475665) --------------------------------------------------------
signed int __thiscall sub_475665(BLVFace *_this, int a2, __int16 a3)
{
  unsigned int v3; // eax@1
  Vec3_short_ *v4; // edx@3
  signed int v5; // eax@4
  int v6; // esi@4
  signed int v7; // eax@7
  Vec3_short_ *v8; // edx@8
  signed int v9; // eax@9
  int v10; // esi@9
  signed int v11; // eax@11
  Vec3_short_ *v12; // edx@12
  signed int v13; // eax@13
  int v14; // esi@13
  int v15; // esi@14
  bool v16; // edi@14
  int v17; // ecx@16
  signed int v18; // edx@16
  int v19; // eax@17
  signed int v20; // ebx@18
  int v21; // edi@20
  signed int v22; // ST14_4@22
  signed __int64 v23; // qtt@22
  signed int result; // eax@25
  int v25; // [sp+14h] [bp-10h]@14
  int v26; // [sp+1Ch] [bp-8h]@2
  signed int v27; // [sp+20h] [bp-4h]@2
  signed int v28; // [sp+30h] [bp+Ch]@2
  signed int v29; // [sp+30h] [bp+Ch]@7
  signed int v30; // [sp+30h] [bp+Ch]@11
  signed int v31; // [sp+30h] [bp+Ch]@14

  v3 = _this->uAttributes;
  if ( BYTE1(v3) & 1 )
  {
    v28 = 0;
    v26 = (signed __int16)a2;
    v27 = SHIWORD(a2);
    if ( _this->uNumVertices )
    {
      v4 = pIndoor->pVertices;
      do
      {
        v5 = v28;
        v6 = 2 * v28;
        word_720C10_intercepts_xs[2 * v28] = _this->pXInterceptDisplacements[v28] + v4[_this->pVertexIDs[v28]].x;
        word_720B40_intercepts_zs[2 * v28] = _this->pYInterceptDisplacements[v5] + v4[_this->pVertexIDs[v5]].y;
        word_720C10_intercepts_xs[2 * v28++ + 1] = _this->pXInterceptDisplacements[v5 + 1]
                                                 + v4[_this->pVertexIDs[v5 + 1]].x;
        word_720B40_intercepts_zs[v6 + 1] = _this->pYInterceptDisplacements[v5 + 1] + v4[_this->pVertexIDs[v5 + 1]].y;
      }
      while ( v28 < _this->uNumVertices );
    }
  }
  else
  {
    if ( BYTE1(v3) & 2 )
    {
      v26 = (signed __int16)a2;
      v7 = a3;
      v29 = 0;
      v27 = v7;
      if ( _this->uNumVertices )
      {
        v8 = pIndoor->pVertices;
        do
        {
          v9 = v29;
          v10 = 2 * v29;
          word_720C10_intercepts_xs[2 * v29] = _this->pXInterceptDisplacements[v29] + v8[_this->pVertexIDs[v29]].x;
          word_720B40_intercepts_zs[2 * v29] = _this->pZInterceptDisplacements[v9] + v8[_this->pVertexIDs[v9]].z;
          word_720C10_intercepts_xs[2 * v29++ + 1] = _this->pXInterceptDisplacements[v9 + 1] + v8[_this->pVertexIDs[v9 + 1]].x;
          word_720B40_intercepts_zs[v10 + 1] = _this->pZInterceptDisplacements[v9 + 1] + v8[_this->pVertexIDs[v9 + 1]].z;
        }
        while ( v29 < _this->uNumVertices );
      }
    }
    else
    {
      v26 = SHIWORD(a2);
      v11 = a3;
      v30 = 0;
      v27 = v11;
      if ( _this->uNumVertices )
      {
        v12 = pIndoor->pVertices;
        do
        {
          v13 = v30;
          v14 = 2 * v30;
          word_720C10_intercepts_xs[2 * v30] = _this->pYInterceptDisplacements[v30] + v12[_this->pVertexIDs[v30]].y;
          word_720B40_intercepts_zs[2 * v30] = _this->pZInterceptDisplacements[v13] + v12[_this->pVertexIDs[v13]].z;
          word_720C10_intercepts_xs[2 * v30++ + 1] = _this->pYInterceptDisplacements[v13 + 1] + v12[_this->pVertexIDs[v13 + 1]].y;
          word_720B40_intercepts_zs[v14 + 1] = _this->pZInterceptDisplacements[v13 + 1] + v12[_this->pVertexIDs[v13 + 1]].z;
        }
        while ( v30 < _this->uNumVertices );
      }
    }
  }
  v15 = 2 * _this->uNumVertices;
  v31 = 0;
  word_720C10_intercepts_xs[2 * _this->uNumVertices] = word_720C10_intercepts_xs[0];
  word_720B40_intercepts_zs[v15] = word_720B40_intercepts_zs[0];
  v25 = 0;
  v16 = word_720B40_intercepts_zs[0] >= v27;
  if ( v15 <= 0 )
    goto LABEL_29;
  do
  {
    if ( v31 >= 2 )
      break;
    v17 = v25;
    v18 = word_720B40_intercepts_zs[v25 + 1];
    if ( v16 ^ v18 >= v27 )
    {
      v19 = word_720C10_intercepts_xs[v17 + 1];
      if ( v19 >= v26 )
        v20 = 0;
      else
        v20 = 2;
      v21 = v20 | word_720C10_intercepts_xs[v17] < v26;
      if ( v21 != 3 )
      {
        if ( !v21
          || (v22 = v19 - word_720C10_intercepts_xs[v17],
              LODWORD(v23) = v22 << 16,
              HIDWORD(v23) = v22 >> 16,
              word_720C10_intercepts_xs[v17]
            + ((signed int)(((unsigned __int64)(v23
                                              / (v18 - word_720B40_intercepts_zs[v17])
                                              * ((v27 - (signed int)word_720B40_intercepts_zs[v17]) << 16)) >> 16)
                          + 32768) >> 16) >= v26) )
          ++v31;
      }
    }
    ++v25;
    v16 = v18 >= v27;
  }
  while ( v25 < v15 );
  result = 1;
  if ( v31 != 1 )
LABEL_29:
    result = 0;
  return result;
}

//----- (004759C9) --------------------------------------------------------
bool __fastcall sub_4759C9(BLVFace *a1, int a2, int a3, __int16 a4)
{
  unsigned int v4; // eax@1
  int v5; // edx@4
  __int16 v6; // si@4
  int v7; // edx@9
  __int16 v8; // si@9
  int v9; // edx@13
  __int16 v10; // si@13
  int v11; // esi@14
  bool v12; // edi@14
  int v13; // ecx@16
  signed int v14; // edx@16
  int v15; // eax@17
  signed int v16; // ebx@18
  int v17; // edi@20
  signed int v18; // ST14_4@22
  signed __int64 v19; // qtt@22
  bool result; // eax@25
  int v21; // [sp+14h] [bp-10h]@14
  signed int v22; // [sp+18h] [bp-Ch]@1
  int v23; // [sp+1Ch] [bp-8h]@2
  signed int v24; // [sp+20h] [bp-4h]@2
  Vec3_int_ **a4a; // [sp+30h] [bp+Ch]@3
  Vec3_int_ **a4b; // [sp+30h] [bp+Ch]@8
  Vec3_int_ **a4c; // [sp+30h] [bp+Ch]@12
  signed int a4d; // [sp+30h] [bp+Ch]@14

  v4 = a1->uAttributes;
  v22 = 0;
  if ( BYTE1(v4) & 1 )
  {
    v23 = (signed __int16)a3;
    v24 = SHIWORD(a3);
    if ( a1->uNumVertices )
    {
      a4a = &pOutdoor->pBModels[a2].pVertices.pVertices;
      do
      {
        v5 = 2 * v22;
        word_720A70_intercepts_xs_plus_xs[2 * v22] = a1->pXInterceptDisplacements[v22] + LOWORD((*a4a)[a1->pVertexIDs[v22]].x);
        word_7209A0_intercepts_ys_plus_ys[2 * v22] = a1->pYInterceptDisplacements[v22] + LOWORD((*a4a)[a1->pVertexIDs[v22]].y);
        word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = a1->pXInterceptDisplacements[v22 + 1] + LOWORD((*a4a)[a1->pVertexIDs[v22 + 1]].x);
        word_7209A0_intercepts_ys_plus_ys[v5 + 1] = v6 = a1->pYInterceptDisplacements[v22 + 1] + LOWORD((*a4a)[a1->pVertexIDs[v22 + 1]].y);
        ++v22;
      }
      while ( v22 < a1->uNumVertices );
    }
  }
  else
  {
    if ( BYTE1(v4) & 2 )
    {
      v23 = (signed __int16)a3;
      v24 = a4;
      if ( a1->uNumVertices )
      {
        a4b = &pOutdoor->pBModels[a2].pVertices.pVertices;
        do
        {
          v7 = 2 * v22;
          word_720A70_intercepts_xs_plus_xs[2 * v22] = a1->pXInterceptDisplacements[v22] + LOWORD((*a4b)[a1->pVertexIDs[v22]].x);
          word_7209A0_intercepts_ys_plus_ys[2 * v22] = a1->pZInterceptDisplacements[v22] + LOWORD((*a4b)[a1->pVertexIDs[v22]].z);
          word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = a1->pXInterceptDisplacements[v22 + 1] + LOWORD((*a4b)[a1->pVertexIDs[v22 + 1]].x);
          word_7209A0_intercepts_ys_plus_ys[v7 + 1] = v8 = a1->pZInterceptDisplacements[v22 + 1] + LOWORD((*a4b)[a1->pVertexIDs[v22 + 1]].z);
          ++v22;
        }
        while ( v22 < a1->uNumVertices );
      }
    }
    else
    {
      v23 = SHIWORD(a3);
      v24 = a4;
      if ( a1->uNumVertices )
      {
        a4c = &pOutdoor->pBModels[a2].pVertices.pVertices;
        do
        {
          v9 = 2 * v22;
          word_720A70_intercepts_xs_plus_xs[2 * v22] = a1->pYInterceptDisplacements[v22] + LOWORD((*a4c)[a1->pVertexIDs[v22]].y);
          word_7209A0_intercepts_ys_plus_ys[2 * v22] = a1->pZInterceptDisplacements[v22] + LOWORD((*a4c)[a1->pVertexIDs[v22]].z);
          word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = a1->pYInterceptDisplacements[v22 + 1] + LOWORD((*a4c)[a1->pVertexIDs[v22 + 1]].y);
          word_7209A0_intercepts_ys_plus_ys[v9 + 1] = v10 = a1->pZInterceptDisplacements[v22 + 1] + LOWORD((*a4c)[a1->pVertexIDs[v22 + 1]].z);
          ++v22;
        }
        while ( v22 < a1->uNumVertices );
      }
    }
  }
  v11 = 2 * a1->uNumVertices;
  a4d = 0;
  word_720A70_intercepts_xs_plus_xs[2 * a1->uNumVertices] = word_720A70_intercepts_xs_plus_xs[0];
  word_7209A0_intercepts_ys_plus_ys[v11] = word_7209A0_intercepts_ys_plus_ys[0];
  v21 = 0;
  v12 = word_7209A0_intercepts_ys_plus_ys[0] >= v24;
  if ( v11 <= 0 )
    goto LABEL_29;
  do
  {
    if ( a4d >= 2 )
      break;
    v13 = v21;
    v14 = word_7209A0_intercepts_ys_plus_ys[v21 + 1];
    if ( v12 ^ v14 >= v24 )
    {
      v15 = word_720A70_intercepts_xs_plus_xs[v13 + 1];
      if ( v15 >= v23 )
        v16 = 0;
      else
        v16 = 2;
      v17 = v16 | word_720A70_intercepts_xs_plus_xs[v13] < v23;
      if ( v17 != 3 )
      {
        if ( !v17
          || (v18 = v15 - word_720A70_intercepts_xs_plus_xs[v13],
              LODWORD(v19) = v18 << 16,
              HIDWORD(v19) = v18 >> 16,
              word_720A70_intercepts_xs_plus_xs[v13]
            + ((signed int)(((unsigned __int64)(v19
                                              / (v14 - word_7209A0_intercepts_ys_plus_ys[v13])
                                              * ((v24 - (signed int)word_7209A0_intercepts_ys_plus_ys[v13]) << 16)) >> 16)
                          + 32768) >> 16) >= v23) )
          ++a4d;
      }
    }
    ++v21;
    v12 = v14 >= v24;
  }
  while ( v21 < v11 );
  result = 1;
  if ( a4d != 1 )
LABEL_29:
    result = 0;
  return result;
}

//----- (00475D85) --------------------------------------------------------
bool __fastcall sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, BLVFace *a4)
{
  BLVFace *v4; // ebx@1
  int v5; // ST24_4@2
  int v6; // ST28_4@2
  int v7; // edi@2
  int v8; // eax@5
  signed int v9; // esi@5
  signed __int64 v10; // qtt@10
  Vec3_int_ *v11; // esi@11
  int v12; // ST14_4@11
  Vec3_int_ *v14; // [sp+Ch] [bp-18h]@1
  Vec3_int_ *v15; // [sp+14h] [bp-10h]@1
  int v16; // [sp+18h] [bp-Ch]@2
  int v17; // [sp+20h] [bp-4h]@10
  int a4b; // [sp+30h] [bp+Ch]@2
  int a4c; // [sp+30h] [bp+Ch]@9
  signed int a4a; // [sp+30h] [bp+Ch]@10

  v4 = a4;
  v15 = a2;
  v14 = a1;
  if ( BYTE3(a4->uAttributes) & 0x20
    || (v5 = (unsigned __int64)(a2->x * (signed __int64)a4->pFacePlane_old.vNormal.x) >> 16,
        a4b = (unsigned __int64)(a2->y * (signed __int64)a4->pFacePlane_old.vNormal.y) >> 16,
        v6 = (unsigned __int64)(a2->z * (signed __int64)v4->pFacePlane_old.vNormal.z) >> 16,
        v7 = v5 + v6 + a4b,
        (v16 = v5 + v6 + a4b) == 0)
    || v7 > 0 && !(v4->uAttributes & 1) )
    return 0;
  v8 = v4->pFacePlane_old.vNormal.z * a1->z;
  v9 = -(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x);
  if ( v7 <= 0 )
  {
    if ( v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x < 0 )
      return 0;
  }
  else
  {
    if ( v9 < 0 )
      return 0;
  }
  a4c = abs(-(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x)) >> 14;
  if ( a4c > abs(v7)
    || (LODWORD(v10) = v9 << 16, HIDWORD(v10) = v9 >> 16, a4a = v10 / v16, v17 = v10 / v16, v17 > *a3 << 16)
    || (v11 = v14,
        LOWORD(v12) = LOWORD(v14->x)
                    + (((unsigned int)((unsigned __int64)(v17 * (signed __int64)v15->x) >> 16) + 32768) >> 16),
        HIWORD(v12) = LOWORD(v11->y)
                    + (((unsigned int)((unsigned __int64)(v17 * (signed __int64)v15->y) >> 16) + 32768) >> 16),
        !sub_475665(
           v4,
           v12,
           LOWORD(v11->z) + (((unsigned int)((unsigned __int64)(v17 * (signed __int64)v15->z) >> 16) + 32768) >> 16))) )
    return 0;
  *a3 = a4a >> 16;
  return 1;
}

//----- (00475F30) --------------------------------------------------------
bool __fastcall sub_475F30(int *a1, BLVFace *a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9)
{
  BLVFace *v9; // ebx@1
  int v10; // ST20_4@2
  int v11; // ST28_4@2
  int v12; // ST24_4@2
  char v13; // zf@2
  int v14; // edi@2
  int v15; // eax@5
  signed int v16; // esi@5
  int v17; // ST20_4@9
  signed __int64 v18; // qtt@10
  int v19; // ST14_4@11
  int *v21; // [sp+14h] [bp-10h]@1
  int v22; // [sp+1Ch] [bp-8h]@2
  int v23; // [sp+1Ch] [bp-8h]@10
  signed int v24; // [sp+20h] [bp-4h]@10

  v9 = a2;
  v21 = a1;
  if ( BYTE3(a2->uAttributes) & 0x20
    || (v10 = (unsigned __int64)(a6 * (signed __int64)a2->pFacePlane_old.vNormal.x) >> 16,
        v11 = (unsigned __int64)(a7 * (signed __int64)a2->pFacePlane_old.vNormal.y) >> 16,
        v12 = (unsigned __int64)(a8 * (signed __int64)a2->pFacePlane_old.vNormal.z) >> 16,
        v13 = v10 + v12 + v11 == 0,
        v14 = v10 + v12 + v11,
        v22 = v10 + v12 + v11,
        v13)
    || v14 > 0 && !(a2->uAttributes & 1) )
    return 0;
  v15 = a4 * a2->pFacePlane_old.vNormal.y;
  v16 = -(a2->pFacePlane_old.dist + v15 + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z);
  if ( v14 <= 0 )
  {
    if ( a2->pFacePlane_old.dist + v15 + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z < 0 )
      return 0;
  }
  else
  {
    if ( v16 < 0 )
      return 0;
  }
  v17 = abs(-(a2->pFacePlane_old.dist + v15 + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z)) >> 14;
  if ( v17 > abs(v14)
    || (LODWORD(v18) = v16 << 16, HIDWORD(v18) = v16 >> 16, v24 = v18 / v22, v23 = v18 / v22, v23 > *v21 << 16)
    || (LOWORD(v19) = a3 + (((unsigned int)((unsigned __int64)(v23 * (signed __int64)a6) >> 16) + 32768) >> 16),
        HIWORD(v19) = a4 + (((unsigned int)((unsigned __int64)(v23 * (signed __int64)a7) >> 16) + 32768) >> 16),
        !sub_4759C9(
           v9,
           a9,
           v19,
           a5 + (((unsigned int)((unsigned __int64)(v23 * (signed __int64)a8) >> 16) + 32768) >> 16))) )
    return 0;
  *v21 = v24 >> 16;
  return 1;
}





//----- (004760D5) --------------------------------------------------------
PartyAction ActionQueue::Next()
{
  if (!uNumActions)
    return PARTY_INVALID;

  auto result = pActions[0];
  for (unsigned int i = 0; i < uNumActions - 1; ++i)
    pActions[i] = pActions[i + 1];
  --uNumActions;

  return result;
}

//----- (00476387) --------------------------------------------------------
bool __cdecl sub_476387()
{
  return (pNPCStats->pNewNPCData[57].uFlags & 0x80) != 0;
}

//----- (00476395) --------------------------------------------------------
//0x26 Wizard eye at skill level 2
bool __thiscall CheckHiredNPCSpeciality(unsigned int uProfession)
{
  bool result; // eax@2
  signed int v2; // esi@3
  char *v3; // eax@4

  if ( bNoNPCHiring == 1 )
    return 0;
  v2 = 0;
  if ( (signed int)pNPCStats->uNumNewNPCs <= 0 )
  {
LABEL_8:
    result = 0;
    if ( pParty->pHirelings[0].uProfession != uProfession )
    {
      LOBYTE(result) = pParty->pHirelings[1].uProfession == uProfession;
      return result;
    }
  }
  else
  {
    v3 = (char *)&pNPCStats->pNewNPCData[0].uFlags;
    while ( *((int *)v3 + 4) != uProfession || !(*v3 & 0x80) )
    {
      ++v2;
      v3 += 76;
      if ( v2 >= (signed int)pNPCStats->uNumNewNPCs )
        goto LABEL_8;
    }
    result = 0;
  }
  ++result;
  return result;
}
// 6BE3C5: using guessed type char bNoNPCHiring;

//----- (004763E0) --------------------------------------------------------
void __cdecl InitializeAwards()
{
  char *v0; // ebx@1
  char *v1; // eax@4
  char v2; // dl@5
  char *v3; // ecx@5
  int v4; // esi@9
  signed int v5; // [sp+Ch] [bp-Ch]@4
  char *v6; // [sp+10h] [bp-8h]@4
  Award *v7; // [sp+14h] [bp-4h]@3

  v0 = 0;
  if ( pAwardsTXT_Raw )
    pAllocator->FreeChunk(pAwardsTXT_Raw);
  pAwardsTXT_Raw = 0;
  pAwardsTXT_Raw = (char *)pEvents_LOD->LoadRaw("awards.txt", 0);
  strtok(pAwardsTXT_Raw, "\r");
  v7 = pAwards;
  for (uint i = 0; i < 104; ++i)
  {
    v1 = strtok(v0, "\r") + 1;
    v6 = v0;
    v5 = (signed int)v0;
    do
    {
      v2 = *v1;
      v3 = 0;
      if ( *v1 != 9 )
      {
        v0 = 0;
        do
        {
          if ( !v2 )
            break;
          ++v3;
          v2 = v1[(int)v3];
        }
        while ( v2 != 9 );
      }
      v4 = (int)&v1[(int)v3];
      if ( v1[(int)v3] == (char)v0 )
        v5 = 1;
      *(char *)v4 = (char)v0;
      if ( v3 == v0 )
      {
        v5 = 1;
      }
      else
      {
        if ( v6 == (char *)1 )
        {
          v7->pText = RemoveQuotes(v1);
        }
        else
        {
          if ( v6 == (char *)2 )
            v7->uSort = atoi(v1);
        }
      }
      ++v6;
      v1 = (char *)(v4 + 1);
    }
    while ( (signed int)(v6 - 1) <= 2 && (char *)v5 == v0 );
    ++v7;
  }
  //while ( (signed int)v7 < (signed int)&dword_7241C8 );
}
// 7241C8: using guessed type int dword_7241C8;

//----- (004764C2) --------------------------------------------------------
void __cdecl InitializeScrolls()
{
  char *v0; // ebx@1
  char *v1; // eax@4
  int v2; // edi@4
  char v3; // dl@5
  char *v4; // ecx@5
  int v5; // esi@9
  const char **v6; // [sp+10h] [bp-8h]@3
  signed int v7; // [sp+14h] [bp-4h]@4

  v0 = 0;
  if ( pScrollsTXT_Raw )
    pAllocator->FreeChunk(pScrollsTXT_Raw);
  pScrollsTXT_Raw = 0;
  pScrollsTXT_Raw = (char *)pEvents_LOD->LoadRaw("scroll.txt", 0);
  strtok(pScrollsTXT_Raw, "\r");
  v6 = pScrolls;
  for (uint i = 0; i < 82; ++i)
  {
    v1 = strtok(v0, "\r") + 1;
    v2 = 0;
    v7 = (signed int)v0;
    do
    {
      v3 = *v1;
      v4 = 0;
      if ( *v1 != 9 )
      {
        v0 = 0;
        do
        {
          if ( !v3 )
            break;
          ++v4;
          v3 = v1[(int)v4];
        }
        while ( v3 != 9 );
      }
      v5 = (int)&v1[(int)v4];
      if ( v1[(int)v4] == (char)v0 )
        v7 = 1;
      *(char *)v5 = (char)v0;
      if ( v4 == v0 )
      {
        v7 = 1;
      }
      else
      {
        if ( v2 == 1 )
          *v6 = RemoveQuotes(v1);
      }
      ++v2;
      v1 = (char *)(v5 + 1);
    }
    while ( v2 - 1 <= 1 && (char *)v7 == v0 );
    ++v6;
  }
  //while ( (signed int)v6 < (signed int)dword_723E80_award_related );
}


//----- (00476590) --------------------------------------------------------
void __cdecl InitializeMerchants()
{
  char *v0; // ebx@1
  //char **v1; // edi@3
  char *v2; // ecx@4
  char v3; // dl@5
  char *v4; // eax@5
  int v5; // esi@9
  signed int v6; // [sp+Ch] [bp-8h]@4
  char *v7; // [sp+10h] [bp-4h]@4

  v0 = 0;
  if ( pMerchantsTXT_Raw )
    pAllocator->FreeChunk(pMerchantsTXT_Raw);
  pMerchantsTXT_Raw = 0;
  pMerchantsTXT_Raw = (char *)pEvents_LOD->LoadRaw("merchant.txt", 0);
  strtok(pMerchantsTXT_Raw, "\r");
  //v1 = (char **)pMerchantsRepairPhrases;
  for (uint i = 0; i < 7; ++i)
  {
    v7 = v0;
    v6 = (signed int)v0;
    v2 = strtok(v0, "\r") + 1;
    do
    {
      v3 = *v2;
      v4 = 0;
      if ( *v2 != 9 )
      {
        v0 = 0;
        do
        {
          if ( !v3 )
            break;
          ++v4;
          v3 = v2[(int)v4];
        }
        while ( v3 != 9 );
      }
      v5 = (int)&v2[(int)v4];
      if ( v2[(int)v4] == (char)v0 )
        v6 = 1;
      *(char *)v5 = (char)v0;
      if ( v4 == v0 )
      {
        v6 = 1;
      }
      else
      {
        if ( v7 == (char *)1 )
        {
          pMerchantsBuyPhrases[i] = RemoveQuotes(v2);
        }
        else
        {
          if ( v7 == (char *)2 )
          {
            pMerchantsSellPhrases[i] = RemoveQuotes(v2);
          }
          else
          {
            if ( v7 == (char *)3 )
            {
              pMerchantsRepairPhrases[i] = RemoveQuotes(v2);
            }
            else
            {
              if ( v7 - 3 == (char *)1 )
                pMerchantsIdentifyPhrases[i] = RemoveQuotes(v2);
            }
          }
        }
      }
      ++v7;
      v2 = (char *)(v5 + 1);
    }
    while ( (signed int)(v7 - 1) <= 4 && (char *)v6 == v0 );
    //++v1;
  }
  //while ( (signed int)v1 < (signed int)pMerchantsIdentifyPhrases );
}

//----- (00476682) --------------------------------------------------------
void __cdecl InitializeTransitions()
{
  char *v0; // ebx@1
  char *v1; // eax@4
  int v2; // edi@4
  char v3; // dl@5
  char *v4; // ecx@5
  int v5; // esi@9
  char **v6; // [sp+10h] [bp-8h]@3
  signed int v7; // [sp+14h] [bp-4h]@4

  v0 = 0;
  if ( pTransitionsTXT_Raw )
    pAllocator->FreeChunk(pTransitionsTXT_Raw);
  pTransitionsTXT_Raw = 0;
  pTransitionsTXT_Raw = (char *)pEvents_LOD->LoadRaw("trans.txt", 0);
  strtok(pTransitionsTXT_Raw, "\r");
  v6 = pTransitionStrings;
  for (uint i = 0; i < 464; ++i)
  {
    v1 = strtok(v0, "\r") + 1;
    v2 = 0;
    v7 = (signed int)v0;
    do
    {
      v3 = *v1;
      v4 = 0;
      if ( *v1 != 9 )
      {
        v0 = 0;
        do
        {
          if ( !v3 )
            break;
          ++v4;
          v3 = v1[(int)v4];
        }
        while ( v3 != 9 );
      }
      v5 = (int)&v1[(int)v4];
      if ( v1[(int)v4] == (char)v0 )
        v7 = 1;
      *(char *)v5 = (char)v0;
      if ( v4 == v0 )
      {
        v7 = 1;
      }
      else
      {
        if ( v2 == 1 )
          *v6 = (char *)RemoveQuotes(v1);
      }
      ++v2;
      v1 = (char *)(v5 + 1);
    }
    while ( v2 - 1 <= 1 && (char *)v7 == v0 );
    ++v6;
  }
  //while ( (signed int)v6 < (signed int)"awards.txt" );
}

//----- (00476750) --------------------------------------------------------
void __cdecl InitializeAutonotes()
{
  Autonote *v0; // ebp@3
  int v1; // ebx@4
  char *v2; // esi@4
  char v3; // cl@5
  int v4; // eax@5
  char *v5; // edi@9
  signed int v6; // [sp+0h] [bp-4h]@4

  if ( pAutonoteTXT_Raw )
    pAllocator->FreeChunk(pAutonoteTXT_Raw);
  pAutonoteTXT_Raw = 0;
  pAutonoteTXT_Raw = (char *)pEvents_LOD->LoadRaw("autonote.txt", 0);
  strtok(pAutonoteTXT_Raw, "\r");
  v0 = pAutonoteTxt;
  for (uint i = 0; i < 195; ++i)
  {
    v1 = 0;
    v2 = strtok(0, "\r") + 1;
    v6 = 0;
    do
    {
      v3 = *v2;
      v4 = 0;
      while ( v3 != 9 && v3 )
      {
        ++v4;
        v3 = v2[v4];
      }
      v5 = &v2[v4];
      if ( !v2[v4] )
        v6 = 1;
      *v5 = 0;
      if ( v4 )
      {
        if ( v1 == 1 )
        {
			v0->pText = RemoveQuotes(v2);
        }
        else
        {
          if ( v1 == 2 )
          {
            if ( _strcmpi(v2, "potion") )
            {
              if ( _strcmpi(v2, "stat") )
              {
                if ( _strcmpi(v2, "seer") )
                {
                  if ( _strcmpi(v2, "obelisk") )
					  v0->eType = (AUTONOTE_TYPE)(5 - (_strcmpi(v2, "teacher") != 0));
                  else
					  v0->eType = (AUTONOTE_TYPE)2;
                }
                else
                {
                  v0->eType = (AUTONOTE_TYPE)3;
                }
              }
              else
              {
                v0->eType = (AUTONOTE_TYPE)1;
              }
            }
            else
            {
              v0->eType = (AUTONOTE_TYPE)0;
            }
          }
        }
      }
      else
      {
        v6 = 1;
      }
      ++v1;
      v2 = v5 + 1;
    }
    while ( v1 - 1 <= 2 && !v6 );
    ++v0;
  }
  //while ( (signed int)v0 < (signed int)&pScrolls[1] );
}


//----- (004768A9) --------------------------------------------------------
void __cdecl InitializeQuests()
{
  char *v0; // ebx@1
  char *v1; // eax@4
  int v2; // edi@4
  char v3; // dl@5
  char *v4; // ecx@5
  int v5; // esi@9
  //const char **v6; // [sp+10h] [bp-8h]@3
  signed int v7; // [sp+14h] [bp-4h]@4

  v0 = 0;
  if ( pQuestsTXT_Raw )
    pAllocator->FreeChunk(pQuestsTXT_Raw);
  pQuestsTXT_Raw = 0;
  pQuestsTXT_Raw = (char *)pEvents_LOD->LoadRaw("quests.txt", 0);
  strtok(pQuestsTXT_Raw, "\r");

  //v6 = pQuestTable;
  for (uint i = 0; i < 512; ++i)
  //do
  {
    v1 = strtok(v0, "\r") + 1;
    v2 = 0;
    v7 = (signed int)v0;
    do
    {
      v3 = *v1;
      v4 = 0;
      if ( *v1 != '\t' )
      {
        v0 = 0;
        do
        {
          if ( !v3 )
            break;
          ++v4;
          v3 = v1[(int)v4];
        }
        while ( v3 != '\t' );
      }
      v5 = (int)&v1[(int)v4];
      if ( v1[(int)v4] == (char)v0 )
        v7 = 1;
      *(char *)v5 = (char)v0;
      if ( v4 == v0 )
      {
        v7 = 1;
      }
      else
      {
        if ( v2 == 1 )
          pQuestTable[i] = RemoveQuotes(v1);
      }
      ++v2;
      v1 = (char *)(v5 + 1);
    }
    while ( v2 - 1 <= 1 && (char *)v7 == v0 );
    //++v6;
  }
  //while ( (signed int)v6 < (signed int)&unk_723714 );
}



//----- (00476977) --------------------------------------------------------
void NPCStats::Initialize2()
{
  char *v4; // eax@4
  char v5; // dl@5
  char *v6; // ecx@5
  int v7; // edi@9
  char *v9; // eax@21
  char v10; // dl@22
  char *v11; // ecx@22
  int v12; // edi@26
  char *v14; // eax@39
  char v15; // dl@40
  int v16; // ecx@40
  int v17; // edi@44
  char v18; // zf@47
  NPCStats_stru0 *v19; // eax@57
  signed int v20; // edx@57
  signed int v21; // ecx@58
  char *v22; // [sp+10h] [bp-10h]@4
  char *v23; // [sp+10h] [bp-10h]@21
  char *v25; // [sp+14h] [bp-Ch]@4
  char *v26; // [sp+14h] [bp-Ch]@21
  signed int v27; // [sp+14h] [bp-Ch]@39
  //signed int v28; // [sp+18h] [bp-8h]@3
  //signed int v29; // [sp+18h] [bp-8h]@20
  signed int v30; // [sp+18h] [bp-8h]@37
  char *v31; // [sp+1Ch] [bp-4h]@37

  //v1 = this;
  //v2 = 0;
  if (pNPCTextTXT_Raw)
    pAllocator->FreeChunk(pNPCTextTXT_Raw);

  //v3 = (char *)pEvents_LOD->LoadRaw("npctext.txt", 0);
  pNPCTextTXT_Raw = (char *)pEvents_LOD->LoadRaw("npctext.txt", 0);
  strtok(pNPCTextTXT_Raw, "\r");

  for (uint i = 0; i < 789; ++i)
  {
    v4 = strtok(nullptr, "\r") + 1;
    v22 = nullptr;
    v25 = nullptr;
    do
    {
      v5 = *v4;
      v6 = 0;
      if ( *v4 != 9 )
      {
        do
        {
          if ( !v5 )
            break;
          ++v6;
          v5 = v4[(int)v6];
        }
        while ( v5 != 9 );
        //v2 = 0;
      }
      v7 = (int)&v4[(int)v6];
      if ( !v4[(int)v6] )
        v25 = (char *)1;
      *(char *)v7 = 0;
      if ( v6 == nullptr )
      {
        v25 = (char *)1;
      }
      else
      {
        if ( v22 == (char *)1 )
          pNPCTopics[i].pText = RemoveQuotes(v4);
      }
      ++v22;
      v4 = (char *)(v7 + 1);
    }
    while ( (signed int)(v22 - 1) <= 1 && v25 == nullptr );
  }

  if (pNPCTopicTXT_Raw)
    pAllocator->FreeChunk(pNPCTopicTXT_Raw);

  //v8 = (char *)pEvents_LOD->LoadRaw("npctopic.txt", (int)v2);
  pNPCTopicTXT_Raw = (char *)pEvents_LOD->LoadRaw("npctopic.txt", 0);
  strtok(pNPCTopicTXT_Raw, "\r");

  for (uint i = 0; i < 579; ++i)
  {
    v9 = strtok(nullptr, "\r") + 1;
    v23 = nullptr;
    v26 = nullptr;
    do
    {
      v10 = *v9;
      v11 = 0;
      if ( *v9 != 9 )
      {
        do
        {
          if ( !v10 )
            break;
          ++v11;
          v10 = v9[(int)v11];
        }
        while ( v10 != 9 );
        //v2 = 0;
      }
      v12 = (int)&v9[(int)v11];
      if ( !v9[(int)v11] )
        v26 = (char *)1;
      *(char *)v12 = 0;
      if ( v11 == nullptr )
      {
        v26 = (char *)1;
      }
      else
      {
        if ( v23 == (char *)1 )
          pNPCTopics[i].pTopic = RemoveQuotes(v9);
      }
      ++v23;
      v9 = (char *)(v12 + 1);
    }
    while ( (signed int)(v23 - 1) <= 1 && v26 == nullptr );
  }

  if (pNPCDistTXT_Raw)
    pAllocator->FreeChunk(pNPCDistTXT_Raw);

  //v13 = (char *)pEvents_LOD->LoadRaw("npcdist.txt", (int)v2);
  pNPCDistTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcdist.txt", 0);
  strtok(pNPCDistTXT_Raw, "\r");
  strtok(nullptr, "\r");
  v30 = 1;
  v31 = &array_16544[0].field_4[1];

  char *v2 = 0;
  while ( 2 )
  {
    v14 = strtok(nullptr, "\r") + 1;
    v27 = 0;
    char *v24 = nullptr;
    do
    {
      v15 = *v14;
      v16 = 0;
      if ( *v14 != 9 )
      {
        do
        {
          if ( !v15 )
            break;
          ++v16;
          v15 = v14[v16];
        }
        while ( v15 != 9 );
        v2 = v24;
      }
      v17 = (int)&v14[v16];
      if ( !v14[v16] )
        v27 = 1;
      *(char *)v17 = 0;
      if ( !v16 )
      {
        v27 = 1;
        goto LABEL_54;
      }
      v18 = v2 == 0;
      if ( (signed int)v2 > 0 )
      {
        if ( (signed int)v2 < 77 )
        {
          array_16544[(int)v2].field_4[v30] = atoi(v14);
          goto LABEL_54;
        }
        v18 = v2 == 0;
      }
      if ( v18 )
        *v31 = 10;
LABEL_54:
      ++v2;
      v14 = (char *)(v17 + 1);
      v24 = v2;
    }
    while ( (signed int)(v2 - 1) <= 77 && !v27 );
    ++v30;
    ++v31;
    if ( v30 < 59 )
    {
      v2 = 0;
      continue;
    }
    break;
  }
  v19 = array_16544;
  v20 = 77;
  do
  {
    v19->field_0 = 0;
    v21 = 1;
    do
      v19->field_0 += v19->field_4[v21++];
    while ( v21 < 59 );
    ++v19;
    --v20;
  }
  while ( v20 );

  if (pNPCDistTXT_Raw)
  {
    pAllocator->FreeChunk(pNPCDistTXT_Raw);
    pNPCDistTXT_Raw = nullptr;
  }
}

//----- (00476C60) --------------------------------------------------------
void NPCStats::_476C60()
{
  for (uint i = 1; i < uNumNewNPCs; ++i)
    pNewNPCData[i].pName = pNPCNames2[i - 1];

  if (pParty->pHirelings[0].pName)
    pParty->pHirelings[0].pName = pParty->pHireling1Name;
  if (pParty->pHirelings[1].pName)
    pParty->pHirelings[1].pName = pParty->pHireling2Name;
}

//----- (00476CB5) --------------------------------------------------------
void NPCStats::Initialize1()
{
  NPCStats *pNPCStats; // esi@1
  char *pRaw; // eax@1
  char *pHouse; // edi@1
  char *v4; // eax@2
  char v5; // dl@3
  int v6; // ecx@3
  char *v7; // eax@11
  char *v8; // eax@26
  char *v9; // ecx@27
  char v10; // dl@28
  int v11; // eax@28
  int v12; // edi@32
  char *v13; // eax@42
  char *v14; // eax@43
  char v15; // dl@44
  int v16; // ecx@44
  int v17; // edi@48
  char *v18; // eax@56
  char *v19; // eax@57
  char v20; // cl@58
  int v21; // edi@58
  int v22; // esi@62
  int v23; // [sp+Ch] [bp-14h]@7
  signed int v24; // [sp+10h] [bp-10h]@1
  signed int v25; // [sp+10h] [bp-10h]@26
  signed int v26; // [sp+10h] [bp-10h]@42
  signed int v27; // [sp+10h] [bp-10h]@56
  char *Str; // [sp+14h] [bp-Ch]@1
  NPCGreeting *pGreetings; // [sp+14h] [bp-Ch]@26
  unsigned __int16 *pGroups; // [sp+14h] [bp-Ch]@42
  char **pCatchPhrase; // [sp+14h] [bp-Ch]@56
  signed int v32; // [sp+18h] [bp-8h]@2
  signed int v33; // [sp+18h] [bp-8h]@27
  signed int v34; // [sp+18h] [bp-8h]@43
  signed int v35; // [sp+18h] [bp-8h]@57
  signed int v36; // [sp+1Ch] [bp-4h]@2
  signed int v37; // [sp+1Ch] [bp-4h]@27
  signed int v38; // [sp+1Ch] [bp-4h]@43
  signed int v39; // [sp+1Ch] [bp-4h]@57

  pNPCStats = this;
  pRaw = (char *)pEvents_LOD->LoadRaw("npcdata.txt", 0);
  pNPCStats->pNPCDataTXT_Raw = pRaw;
  strtok(pRaw, "\r");
  strtok(0, "\r");
  pHouse = (char *)&pNPCStats->pNPCData[1].house;
  Str = (char *)pNPCStats->pNPCNames2;
  v24 = 500;
  do
  {
    v32 = 0;
    v4 = strtok(0, "\r") + 1;
    v36 = -1;
    do
    {
      v5 = *v4;
      v6 = 0;
      while ( v5 != 9 && v5 )
      {
        ++v6;
        v5 = v4[v6];
      }
      v23 = (int)&v4[v6];
      if ( !v4[v6] )
        v32 = 1;
      v4[v6] = 0;
      if ( v6 )
      {
        switch ( v36 )
        {
          case 0:
            v7 = RemoveQuotes(v4);
            *((int *)pHouse - 5) = (int)v7;
            *(int *)Str = (int)v7;
            break;
          case 1:
            *((int *)pHouse - 4) = atoi(v4);
            break;
          case 5:
            *(int *)pHouse = atoi(v4);
            break;
          case 6:
            *((int *)pHouse + 1) = atoi(v4);
            break;
          case 7:
            *((int *)pHouse + 2) = atoi(v4);
            break;
          case 8:
            *((int *)pHouse + 3) = *v4 == 121;
            break;
          case 9:
            *((int *)pHouse + 5) = atoi(v4);
            break;
          case 10:
            *((int *)pHouse + 6) = atoi(v4);
            break;
          case 11:
            *((int *)pHouse + 7) = atoi(v4);
            break;
          case 12:
            *((int *)pHouse + 8) = atoi(v4);
            break;
          case 13:
            *((int *)pHouse + 9) = atoi(v4);
            break;
          case 14:
            *((int *)pHouse + 10) = atoi(v4);
            break;
          default:
            break;
        }
      }
      ++v36;
      v4 = (char *)(v23 + 1);
    }
    while ( v36 + 1 <= 15 && !v32 );
    Str += 4;
    pHouse += 76;
    --v24;
  }
  while ( v24 );
  pNPCStats->uNumNewNPCs = 501;
  v8 = (char *)pEvents_LOD->LoadRaw("npcgreet.txt", 0);
  pNPCStats->pNPCGreetTXT_Raw = v8;
  strtok(v8, "\r");
  pGreetings = pNPCStats->pNPCGreetings;
  v25 = 205;
  do
  {
    v37 = 0;
    v33 = 0;
    v9 = strtok(0, "\r") + 1;
    do
    {
      v10 = *v9;
      v11 = 0;
      while ( v10 != 9 && v10 )
      {
        ++v11;
        v10 = v9[v11];
      }
      v12 = (int)&v9[v11];
      if ( !v9[v11] )
        v33 = 1;
      *(char *)v12 = 0;
      if ( v11 )
      {
        if ( v37 == 1 )
        {
          pGreetings->pGreeting1 = (char *)RemoveQuotes(v9);
        }
        else
        {
          if ( v37 == 2 )
            pGreetings->pGreeting2 = (char *)RemoveQuotes(v9);
        }
      }
      ++v37;
      v9 = (char *)(v12 + 1);
    }
    while ( v37 <= 2 && !v33 );
    ++pGreetings;
    --v25;
  }
  while ( v25 );
  v13 = (char *)pEvents_LOD->LoadRaw("npcgroup.txt", 0);
  pNPCStats->pNCPGroupTXT_Raw = v13;
  strtok(v13, "\r");
  pGroups = pNPCStats->pGroups;
  v26 = 51;
  do
  {
    v14 = strtok(0, "\r") + 1;
    v38 = 0;
    v34 = 0;
    do
    {
      v15 = *v14;
      v16 = 0;
      while ( v15 != 9 && v15 )
      {
        ++v16;
        v15 = v14[v16];
      }
      v17 = (int)&v14[v16];
      if ( !v14[v16] )
        v34 = 1;
      *(char *)v17 = 0;
      if ( v16 && v38 == 1 )
        *pGroups = atoi(v14);
      ++v38;
      v14 = (char *)(v17 + 1);
    }
    while ( v38 <= 1 && !v34 );
    ++pGroups;
    --v26;
  }
  while ( v26 );
  v18 = (char *)pEvents_LOD->LoadRaw("npcnews.txt", 0);
  pNPCStats->pNPCNewsTXT_Raw = v18;
  strtok(v18, "\r");
  pCatchPhrase = pNPCStats->pCatchPhrases;
  v27 = 51;
  do
  {
    v19 = strtok(0, "\r") + 1;
    v39 = 0;
    v35 = 0;
    do
    {
      v20 = *v19;
      v21 = 0;
      while ( v20 != 9 && v20 )
      {
        ++v21;
        v20 = v19[v21];
      }
      v22 = (int)&v19[v21];
      if ( !v19[v21] )
        v35 = 1;
      *(char *)v22 = 0;
      if ( v21 && v39 == 1 )
        *pCatchPhrase = (char *)RemoveQuotes(v19);
      ++v39;
      v19 = (char *)(v22 + 1);
    }
    while ( v39 <= 1 && !v35 );
    ++pCatchPhrase;
    --v27;
  }
  while ( v27 );
}

//----- (0047702F) --------------------------------------------------------
void NPCStats::Initialize()
{
  //NPCStats *v1; // edi@1
  char *v2; // ebx@1
  //char *v3; // eax@1
  char *v4; // ebx@3
  char v5; // al@4
  int v6; // ecx@4
  //char *v7; // eax@18
  char *v8; // ebx@18
  char *v9; // ecx@19
  char v10; // dl@20
  int v11; // eax@20
  char v12; // zf@41
  signed int v13; // [sp+Ch] [bp-14h]@18
  int v14; // [sp+10h] [bp-10h]@4
  int v15; // [sp+10h] [bp-10h]@24
  char *v16; // [sp+14h] [bp-Ch]@1
  signed int v17; // [sp+14h] [bp-Ch]@19
  unsigned int v18; // [sp+18h] [bp-8h]@1
  char *v19; // [sp+18h] [bp-8h]@18
  signed int v20; // [sp+1Ch] [bp-4h]@3
  signed int v21; // [sp+1Ch] [bp-4h]@19
  //v1 = this;

  Initialize1();
  Initialize2();

  InitializeQuests();
  InitializeAutonotes();
  InitializeAwards();
  InitializeTransitions();
  InitializeMerchants();
  InitializeScrolls();
  v2 = 0;
  field_17FC0 = 0;
  pNPCNamesTXT_Raw = 0;
  //v3 = (char *)pEvents_LOD->LoadRaw("npcnames.txt", 0);
  pNPCNamesTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcnames.txt", 0);
  strtok(pNPCNamesTXT_Raw, "\r");
  v18 = 0;
  v16 = (char *)pNPCNames;
  while ( 1 )
  {
    v4 = strtok(v2, "\r") + 1;
    v20 = 0;
    do
    {
      v5 = *v4;
      v6 = 0;
      v14 = 0;
      if ( *v4 == 9 )
        goto LABEL_45;
      do
      {
        if ( !v5 )
          break;
        if ( v5 == 10 )
          break;
        ++v6;
        v14 = v6;
        v5 = v4[v6];
      }
      while ( v5 != 9 );
      if ( v6 )
      {
        v4[v6] = 0;
        if ( v20 )
        {
          if ( v20 == 1 )
            *((int *)v16 + 1) = (int)RemoveQuotes(v4);
        }
        else
        {
          *(int *)v16 = (int)RemoveQuotes(v4);
        }
      }
      else
      {
LABEL_45:
        if ( v20 == 1 && !uNumNPCNames[1] )
          uNumNPCNames[1] = v18;
      }
      ++v20;
      v4 += v14 + 1;
    }
    while ( v20 <= 1 );
    ++v18;
    v16 += 8;
    if ( (signed int)v18 >= 540 )
      break;
    v2 = 0;
  }
  pNPCProfTXT_Raw = 0;
  uNumNPCNames[0] = v18;
  //v7 = (char *)pEvents_LOD->LoadRaw("npcprof.txt", 0);
  pNPCProfTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcprof.txt", 0);
  strtok(pNPCProfTXT_Raw, "\r");
  strtok(0, "\r");
  strtok(0, "\r");
  strtok(0, "\r");
  v8 = (char *)&pProfessions[0].pJoinText;
  v19 = (char *)&pProfessions[0].pJoinText;
  v13 = 58;
  do
  {
    v21 = 0;
    v9 = strtok(0, "\r") + 1;
    v17 = 0;
    do
    {
      v10 = *v9;
      v11 = 0;
      if ( *v9 != 9 )
      {
        do
        {
          if ( !v10 )
            break;
          ++v11;
          v10 = v9[v11];
        }
        while ( v10 != 9 );
        v8 = v19;
      }
      v15 = (int)&v9[v11];
      if ( !v9[v11] )
        v17 = 1;
      *(char *)v15 = 0;
      if ( v11 )
      {
        switch ( v21 )
        {
          case 2:
            *((int *)v8 - 3) = atoi(v9);
            break;
          case 3:
            *((int *)v8 - 1) = (int)RemoveQuotes(v9);
            break;
          case 4:
            *((int *)v8 - 2) = (int)RemoveQuotes(v9);
            break;
          case 5:
            *(int *)v8 = (int)RemoveQuotes(v9);
            break;
          case 6:
            *((int *)v8 + 1) = (int)RemoveQuotes(v9);
            break;
        }
      }
      else
      {
        if ( !v21 )
          v17 = 1;
      }
      ++v21;
      v9 = (char *)(v15 + 1);
    }
    while ( v21 <= 6 && !v17 );
    v8 += 20;
    v12 = v13-- == 1;
    v19 = v8;
  }
  while ( !v12 );
  uNumNPCProfessions = 59;
}

//----- (00477266) --------------------------------------------------------
void NPCStats::Release()
{
  NPCStats *v1; // esi@1
  void *v2; // ST00_4@1
  int v3; // ebx@1

  v1 = this;
  pAllocator->FreeChunk(this->pNPCTopicTXT_Raw);
  v2 = v1->pNPCTextTXT_Raw;
  v1->pNPCNewsTXT_Raw = 0;
  pAllocator->FreeChunk(v2);
  v1->pNPCNewsTXT_Raw = 0;
  pAllocator->FreeChunk(0);
  v1->pNPCNewsTXT_Raw = 0;
  pAllocator->FreeChunk(v1->pNPCProfTXT_Raw);
  v1->pNPCProfTXT_Raw = 0;
  pAllocator->FreeChunk(v1->pNPCNamesTXT_Raw);
  v1->pNPCNamesTXT_Raw = 0;
  pAllocator->FreeChunk(v1->pNPCDataTXT_Raw);
  v1->pNPCDataTXT_Raw = 0;
  pAllocator->FreeChunk(v1->pNPCDistTXT_Raw);
  v1->pNPCDistTXT_Raw = 0;
  v3 = (int)&v1->pNPCGreetTXT_Raw;
  pAllocator->FreeChunk(v1->pNPCGreetTXT_Raw);
  v1 = (NPCStats *)((char *)v1 + 98296);
  *(int *)v3 = 0;
  pAllocator->FreeChunk(v1->pNPCData[0].pName);
  v1->pNPCData[0].pName = 0;
}

//----- (0047730C) --------------------------------------------------------
int __fastcall const_1(int a1, int)
{
  return 1;
}
// 47730C: using guessed type int __stdcall const_1(int);

//----- (0047732C) --------------------------------------------------------
bool NPCStats::InitializeAdditionalNPCs(NPCData *a2, int a3, int a4, int a5)
{
  //NPCStats *v5; // ebx@1
  signed __int64 v6; // qax@1
  int v7; // esi@1
  int v8; // edx@1
  NPCData *v9; // edi@1
  int v10; // eax@1
  //int v11; // eax@23
  int v12; // ecx@23
  int v13; // edx@28
  int v14; // esi@37
  int v15; // edx@37
  int v16; // ecx@37
  int v17; // eax@37
  int v18; // edx@37
  signed int result; // eax@39
  int v20; // [sp+Ch] [bp-Ch]@1
  signed int v21; // [sp+10h] [bp-8h]@1
  signed int v22; // [sp+14h] [bp-4h]@1
  int v23; // [sp+24h] [bp+Ch]@1


  v23 = a3 - 1;
  //v5 = this;
  v6 = (signed __int64)((double)v23 * -0.33333334);
  v7 = (unsigned __int8)byte_4E8394[-(_DWORD)v6 + 28];
  v20 = (unsigned __int8)byte_4E8394[-(_DWORD)v6 + 116];
  v8 = rand() % uNumNPCNames[v7];
  v9 = a2;
  a2->uSex = v7;
  a2->pName = pNPCNames[v8][v7];
  v10 = 0;
  v22 = 0;
  v21 = 0;

  while ( 1 )
  {
    if ( v20 == v10 )
    {
      if ( v7 == v10 )
      {
        v23 = 2;
        a2 = (NPCData *)100;
      }
      else
      {
        if ( v7 - v10 == 1 )
        {
          v23 = 201;
          a2 = (NPCData *)250;
        }
      }
    }
    else
    {
      switch ( v20 - v10 )
      {
        case 1:
          if ( v7 == v10 )
          {
            v23 = 400;
            a2 = (NPCData *)430;
          }
          else
          {
            if ( v7 - v10 == 1 )
            {
              v23 = 460;
              a2 = (NPCData *)490;
            }
          }
          break;
        case 2:
          if ( v7 == v10 )
          {
            v23 = 500;
            a2 = (NPCData *)520;
          }
          else
          {
            if ( v7 - v10 == 1 )
            {
              v23 = 530;
              a2 = (NPCData *)550;
            }
          }
          break;
        case 3:
          if ( v7 == v10 )
          {
            v23 = 300;
            a2 = (NPCData *)330;
          }
          else
          {
            if ( v7 - v10 == 1 )
            {
              v23 = 360;
              a2 = (NPCData *)387;
            }
          }
          break;
      }
    }
    v12 = v23 + rand() % ((int)a2 - v23 + 1);
    if ( const_1(v12, v7) == 1 )
      v21 = 1;
    ++v22;
    if ( v22 >= 4 )
    {
      v12 = v23;
      v21 = 1;
    }
    if ( v21 )
      break;
    v10 = 0;
  }

  v9->uPortraitID = v12;
  v9->uFlags = 0;
  v9->fame = 0;
  v13 = rand() % 100 + 1;

  if ( v13 >= 60 )
  {
    if ( v13 >= 90 )
    {
      if ( v13 >= 95 )
      {
        if ( v13 >= 98 )
          v9->rep = -600;
        else
          v9->rep = 400;
      }
      else
      {
        v9->rep = -300;
      }
    }
    else
    {
      v9->rep = 200;
    }
  }
  else
  {
    v9->rep = 0;
  }

  //v14 = (int)((char *)v5 + 64 * a5);
  //v15 = rand() % *(_DWORD *)(v14 + 91460);
  v15 = rand() % array_16544[a5].field_0;
  v16 = 0;
  v17 = 0;
  v18 = v15 + 1;
  
  if ( v18 > 0 )
  {
    do
      //v14 += *(char *)(v14 + v17++ + 0x16548);
      v16 += array_16544[a5].field_4[v17++];
    while ( v16 < v18 );
  }
  v9->uProfession = v17 - 1;
  v9->house = a4;
  v9->field_24 = 1;
  v9->joins = 1;
  return true;
}
// 47730C: using guessed type int __stdcall const_1(int);

//----- (0047752B) --------------------------------------------------------
int __cdecl GetPartyReputation()
{
  DDM_DLV_Header *v0; // ebx@1
  signed int v1; // esi@3

  v0 = &pOutdoor->ddm;
  if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
    v0 = &pIndoor->dlv;
  v1 = 0;
  if ( CheckHiredNPCSpeciality(0x2Du) )
    v1 = 5;
  if ( CheckHiredNPCSpeciality(0x33u) )
    v1 += 5;
  if ( CheckHiredNPCSpeciality(0x30u) )
    v1 += 5;
  if ( CheckHiredNPCSpeciality(0x32u) )
    v1 += 5;
  if ( CheckHiredNPCSpeciality(0x34u) )
    v1 += 5;
  return v1 + v0->uReputation;
}





//----- (004775ED) --------------------------------------------------------
int stru6_stru1_indoor_sw_billboard::_4775ED(float a2)
{
  char *v2; // edi@1
  int v3; // eax@1
  char *v4; // edx@2
  char *v5; // esi@3
  double v6; // st7@6
  signed __int64 v7; // ST84_8@6
  double v8; // ST0C_8@6
  int v9; // esi@6
  double v10; // ST44_8@6
  int v11; // ecx@6
  double v12; // ST34_8@6
  int v13; // ecx@6
  double v14; // ST14_8@6
  double v15; // st7@8
  unsigned int v16; // ecx@8
  signed __int64 v17; // ST64_8@8
  double v18; // ST24_8@8
  int v19; // edi@8
  double v20; // ST3C_8@8
  int v21; // ecx@8
  double v22; // ST2C_8@8
  int v23; // ST9C_4@8
  double v24; // ST1C_8@8
  int *v25; // edi@8
  int v26; // esi@8
  int *v27; // edi@10
  int v28; // esi@10
  int result; // eax@12
  __int64 v30; // [sp+A8h] [bp-30h]@8
  float v31; // [sp+B0h] [bp-28h]@6
  float v32; // [sp+B4h] [bp-24h]@6
  int v33; // [sp+B8h] [bp-20h]@6
  int v34; // [sp+BCh] [bp-1Ch]@2
  stru6_stru1_indoor_sw_billboard *v35; // [sp+C0h] [bp-18h]@1
  float v36; // [sp+C4h] [bp-14h]@6
  int v37; // [sp+C8h] [bp-10h]@6
  int v38; // [sp+CCh] [bp-Ch]@1
  float v39; // [sp+D0h] [bp-8h]@6
  int *v40; // [sp+D4h] [bp-4h]@2

  v2 = (char *)&this->field_14[4 * this->field_10 + 20];
  v38 = 0;
  *(int *)v2 = this->field_14[20];
  v2 += 4;
  *(int *)v2 = this->field_14[21];
  v2 += 4;
  *(int *)v2 = this->field_14[22];
  *((int *)v2 + 1) = this->field_14[23];
  v3 = this->field_10;
  v35 = this;
  if ( v3 > 0 )
  {
    v40 = &this->field_14[40];
    v4 = (char *)&this->field_14[23] + 3;
    v34 = v3;
    while ( 1 )
    {
      v5 = v4 - 15;
      if ( *(float *)(v4 - 15) <= (double)a2 && *(float *)(v4 + 1) <= (double)a2 )
        goto LABEL_11;
      if ( *(float *)v5 <= (double)a2 )
        break;
      if ( *(float *)(v4 + 1) <= (double)a2 )
      {
        v15 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5);
        v16 = (unsigned __int8)*v4;
        HIDWORD(v30) = LODWORD(a2);
        v17 = (unsigned __int8)v4[16] - v16;
        v36 = v15;
        v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v15 + *(float *)(v4 - 11);
        v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v15 + *(float *)(v4 - 7);
        v39 = (double)v17 * v15;
        v18 = v39 + 6.7553994e15;
        v19 = (unsigned __int8)*v4;
        v39 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36;
        v20 = v39 + 6.7553994e15;
        v21 = (unsigned __int8)*(v4 - 2);
        v37 = LODWORD(v20) + (unsigned __int8)*(v4 - 1);
        v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v21) * v36;
        v22 = v39 + 6.7553994e15;
        v23 = LODWORD(v22) + (unsigned __int8)*(v4 - 2);
        v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36;
        v24 = v39 + 6.7553994e15;
        v33 = (LODWORD(v24) + (*(int *)(v4 - 3) & 0xFF)) | ((v23 | ((v37 | ((LODWORD(v18) + v19) << 8)) << 8)) << 8);
        v25 = v40;
        *v40 = *(int *)v5;
        v26 = (int)(v5 + 4);
        ++v25;
        *v25 = *(int *)v26;
        v26 += 4;
        ++v25;
        ++v38;
        v40 += 4;
        *v25 = *(int *)v26;
        v25[1] = *(int *)(v26 + 4);
        goto LABEL_9;
      }
LABEL_10:
      v27 = v40;
      ++v38;
      *v40 = *(int *)v5;
      v28 = (int)(v5 + 4);
      ++v27;
      *v27 = *(int *)v28;
      v28 += 4;
      ++v27;
      v40 += 4;
      *v27 = *(int *)v28;
      v27[1] = *(int *)(v28 + 4);
LABEL_11:
      v4 += 16;
      --v34;
      if ( !v34 )
        goto LABEL_12;
    }
    v6 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5);
    v7 = (unsigned __int8)v4[16] - (unsigned int)(unsigned __int8)*v4;
    v36 = v6;
    v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v6 + *(float *)(v4 - 11);
    v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v6 + *(float *)(v4 - 7);
    *(float *)&v37 = (double)v7 * v6;
    v8 = *(float *)&v37 + 6.7553994e15;
    v9 = (unsigned __int8)*v4;
    *(float *)&v37 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36;
    v10 = *(float *)&v37 + 6.7553994e15;
    v11 = (unsigned __int8)*(v4 - 2);
    v37 = LODWORD(v10) + (unsigned __int8)*(v4 - 1);
    v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v11) * v36;
    v12 = v39 + 6.7553994e15;
    v13 = LODWORD(v12) + (unsigned __int8)*(v4 - 2);
    v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36;
    v14 = v39 + 6.7553994e15;
    v33 = (LODWORD(v14) + (*(int *)(v4 - 3) & 0xFF)) | ((v13 | ((v37 | ((LODWORD(v8) + v9) << 8)) << 8)) << 8);
LABEL_9:
    //this = v35;
    v5 = (char *)&v30 + 4;
    goto LABEL_10;
  }
LABEL_12:
  result = v38;
  this->field_10 = v38;
  return result;
}

//----- (00477927) --------------------------------------------------------
int stru6_stru1_indoor_sw_billboard::_477927(float a2)
{
  char *v2; // edi@1
  int v3; // eax@1
  char *v4; // edx@2
  char *v5; // esi@3
  double v6; // st7@6
  signed __int64 v7; // ST84_8@6
  double v8; // ST0C_8@6
  int v9; // esi@6
  double v10; // ST44_8@6
  int v11; // ecx@6
  double v12; // ST34_8@6
  int v13; // ecx@6
  double v14; // ST14_8@6
  double v15; // st7@8
  unsigned int v16; // ecx@8
  signed __int64 v17; // ST64_8@8
  double v18; // ST24_8@8
  int v19; // edi@8
  double v20; // ST3C_8@8
  int v21; // ecx@8
  double v22; // ST2C_8@8
  int v23; // ST9C_4@8
  double v24; // ST1C_8@8
  int *v25; // edi@8
  int v26; // esi@8
  int *v27; // edi@10
  int v28; // esi@10
  int result; // eax@12
  __int64 v30; // [sp+A8h] [bp-30h]@8
  float v31; // [sp+B0h] [bp-28h]@6
  float v32; // [sp+B4h] [bp-24h]@6
  int v33; // [sp+B8h] [bp-20h]@6
  int v34; // [sp+BCh] [bp-1Ch]@2
  stru6_stru1_indoor_sw_billboard *v35; // [sp+C0h] [bp-18h]@1
  float v36; // [sp+C4h] [bp-14h]@6
  int v37; // [sp+C8h] [bp-10h]@6
  int v38; // [sp+CCh] [bp-Ch]@1
  float v39; // [sp+D0h] [bp-8h]@6
  int *v40; // [sp+D4h] [bp-4h]@2

  v2 = (char *)&this->field_14[4 * this->field_10 + 20];
  v38 = 0;
  *(int *)v2 = this->field_14[20];
  v2 += 4;
  *(int *)v2 = this->field_14[21];
  v2 += 4;
  *(int *)v2 = this->field_14[22];
  *((int *)v2 + 1) = this->field_14[23];
  v3 = this->field_10;
  v35 = this;
  if ( v3 > 0 )
  {
    v40 = &this->field_14[40];
    v4 = (char *)&this->field_14[23] + 3;
    v34 = v3;
    while ( 1 )
    {
      v5 = v4 - 15;
      if ( *(float *)(v4 - 15) >= (double)a2 && *(float *)(v4 + 1) >= (double)a2 )
        goto LABEL_11;
      if ( *(float *)v5 >= (double)a2 )
        break;
      if ( *(float *)(v4 + 1) >= (double)a2 )
      {
        v15 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5);
        v16 = (unsigned __int8)*v4;
        HIDWORD(v30) = LODWORD(a2);
        v17 = (unsigned __int8)v4[16] - v16;
        v36 = v15;
        v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v15 + *(float *)(v4 - 11);
        v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v15 + *(float *)(v4 - 7);
        v39 = (double)v17 * v15;
        v18 = v39 + 6.7553994e15;
        v19 = (unsigned __int8)*v4;
        v39 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36;
        v20 = v39 + 6.7553994e15;
        v21 = (unsigned __int8)*(v4 - 2);
        v37 = LODWORD(v20) + (unsigned __int8)*(v4 - 1);
        v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v21) * v36;
        v22 = v39 + 6.7553994e15;
        v23 = LODWORD(v22) + (unsigned __int8)*(v4 - 2);
        v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36;
        v24 = v39 + 6.7553994e15;
        v33 = (LODWORD(v24) + (*(int *)(v4 - 3) & 0xFF)) | ((v23 | ((v37 | ((LODWORD(v18) + v19) << 8)) << 8)) << 8);
        v25 = v40;
        *v40 = *(int *)v5;
        v26 = (int)(v5 + 4);
        ++v25;
        *v25 = *(int *)v26;
        v26 += 4;
        ++v25;
        ++v38;
        v40 += 4;
        *v25 = *(int *)v26;
        v25[1] = *(int *)(v26 + 4);
        goto LABEL_9;
      }
LABEL_10:
      v27 = v40;
      ++v38;
      *v40 = *(int *)v5;
      v28 = (int)(v5 + 4);
      ++v27;
      *v27 = *(int *)v28;
      v28 += 4;
      ++v27;
      v40 += 4;
      *v27 = *(int *)v28;
      v27[1] = *(int *)(v28 + 4);
LABEL_11:
      v4 += 16;
      --v34;
      if ( !v34 )
        goto LABEL_12;
    }
    v6 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5);
    v7 = (unsigned __int8)v4[16] - (unsigned int)(unsigned __int8)*v4;
    v36 = v6;
    v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v6 + *(float *)(v4 - 11);
    v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v6 + *(float *)(v4 - 7);
    *(float *)&v37 = (double)v7 * v6;
    v8 = *(float *)&v37 + 6.7553994e15;
    v9 = (unsigned __int8)*v4;
    *(float *)&v37 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36;
    v10 = *(float *)&v37 + 6.7553994e15;
    v11 = (unsigned __int8)*(v4 - 2);
    v37 = LODWORD(v10) + (unsigned __int8)*(v4 - 1);
    v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v11) * v36;
    v12 = v39 + 6.7553994e15;
    v13 = LODWORD(v12) + (unsigned __int8)*(v4 - 2);
    v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36;
    v14 = v39 + 6.7553994e15;
    v33 = (LODWORD(v14) + (*(int *)(v4 - 3) & 0xFF)) | ((v13 | ((v37 | ((LODWORD(v8) + v9) << 8)) << 8)) << 8);
LABEL_9:
    //this = v35;
    v5 = (char *)&v30 + 4;
    goto LABEL_10;
  }
LABEL_12:
  result = v38;
  this->field_10 = v38;
  return result;
}

//----- (00477C61) --------------------------------------------------------
int stru6_stru1_indoor_sw_billboard::sub_477C61()
{
  stru6_stru1_indoor_sw_billboard *v1; // ebx@1
  int v2; // ecx@2
  int v3; // eax@3
  double v4; // st7@4
  double v5; // st7@5
  double v6; // st6@5
  double v7; // st5@6
  float v8; // ST30_4@8
  float v9; // ST24_4@8
  double v10; // st7@8
  double v11; // st6@8
  double v12; // st5@8
  float v13; // ST24_4@13
  int v14; // esi@13
  char *v15; // esi@15
  signed int v16; // eax@16
  __int16 v17; // fps@16
  unsigned __int8 v18; // c2@16
  unsigned __int8 v19; // c3@16
  double v20; // st6@16
  float v21; // ST18_4@17
  float v22; // ST2C_4@17
  float v23; // ST34_4@17
  float v24; // ST24_4@17
  double v25; // st7@17
  double v26; // st6@17
  float v27; // ST34_4@18
  float v28; // ST30_4@18
  int v29; // eax@19
  signed int v31; // [sp+8h] [bp-28h]@15
  float v32; // [sp+Ch] [bp-24h]@16
  float v33; // [sp+14h] [bp-1Ch]@16
  float v34; // [sp+18h] [bp-18h]@16
  float v35; // [sp+1Ch] [bp-14h]@17
  float v36; // [sp+20h] [bp-10h]@4
  float v37; // [sp+24h] [bp-Ch]@4
  float v38; // [sp+24h] [bp-Ch]@16
  float v39; // [sp+28h] [bp-8h]@9
  float v40; // [sp+28h] [bp-8h]@16
  float v41; // [sp+2Ch] [bp-4h]@6
  float v42; // [sp+2Ch] [bp-4h]@9

  v1 = this;
  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
  {
    v2 = 0;
    if ( v1->field_10 > 0 )
    {
      v3 = (int)&v1->field_14[1];
      do
      {
        v4 = *(float *)(v3 - 4);
        LODWORD(v37) = *(int *)v3;
        LODWORD(v36) = *(int *)(v3 + 4);
        if ( pBLVRenderParams->sPartyRotX )
        {
          v5 = v4 - (double)pBLVRenderParams->vPartyPos.x;
          v6 = v37 - (double)pBLVRenderParams->vPartyPos.y;
          if ( pRenderer->pRenderD3D )
          {
            v41 = pBLVRenderParams->fSineY * v6 + pBLVRenderParams->fCosineY * v5;
            v7 = pBLVRenderParams->fSineY * v5 - pBLVRenderParams->fCosineY * v6;
          }
          else
          {
            v41 = pBLVRenderParams->fCosineY * v5 - pBLVRenderParams->fSineY * v6;
            v7 = pBLVRenderParams->fSineY * v5 + pBLVRenderParams->fCosineY * v6;
          }
          v8 = v7;
          v9 = v36 - (double)pBLVRenderParams->vPartyPos.z;
          v10 = pBLVRenderParams->fCosineNegX * v41 - pBLVRenderParams->fSineNegX * v9;
          v11 = v8;
          v12 = pBLVRenderParams->fCosineNegX * v9 + pBLVRenderParams->fSineNegX * v41;
        }
        else
        {
          v42 = v4 - (double)pBLVRenderParams->vPartyPos.x;
          v39 = v37 - (double)pBLVRenderParams->vPartyPos.y;
          if ( pRenderer->pRenderD3D )
          {
            v10 = pBLVRenderParams->fSineY * v39 + pBLVRenderParams->fCosineY * v42;
            v11 = pBLVRenderParams->fSineY * v42 - pBLVRenderParams->fCosineY * v39;
          }
          else
          {
            v10 = pBLVRenderParams->fCosineY * v42 - pBLVRenderParams->fSineY * v39;
            v11 = pBLVRenderParams->fSineY * v42 + pBLVRenderParams->fCosineY * v39;
          }
          v12 = v36 - (double)pBLVRenderParams->vPartyPos.z;
        }
        v13 = v12;
        ++v2;
        *(int *)(v3 + 84) = LODWORD(v13);
        v14 = *(int *)(v3 + 8);
        *(float *)(v3 + 76) = v10;
        *(int *)(v3 + 88) = v14;
        *(float *)(v3 + 80) = v11;
        v3 += 16;
      }
      while ( v2 < v1->field_10 );
    }
  }
  else
  {
    v15 = (char *)&this->field_14[1];
    v31 = 3;
    do
    {
      v40 = (double)stru_5C6E00->SinCos(pIndoorCamera->sRotationX) * 0.0000152587890625;
      v32 = (double)stru_5C6E00->SinCos(pIndoorCamera->sRotationX - stru_5C6E00->uIntegerHalfPi)
          * 0.0000152587890625;
      v34 = (double)stru_5C6E00->SinCos(pIndoorCamera->sRotationY) * 0.0000152587890625;
      v16 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY - stru_5C6E00->uIntegerHalfPi);
      LODWORD(v38) = *(int *)v15;
      v33 = (double)v16 * 0.0000152587890625;
      //UNDEF(v17);
      v20 = *((float *)v15 - 1) - (double)pIndoorCamera->pos.x;
      if ( v19 | v18 )
      {
        v27 = v20;
        LODWORD(v35) = *((int *)v15 + 1);
        v28 = v38 - (double)pIndoorCamera->pos.y;
        v25 = v33 * v28 + v34 * v27;
        v26 = v34 * v28 - v33 * v27;
      }
      else
      {
        v21 = v20;
        v22 = v38 - (double)pIndoorCamera->pos.y;
        v23 = v33 * v22 + v34 * v21;
        v24 = *((float *)v15 + 1) - (double)pIndoorCamera->pos.z;
        v25 = v32 * v24 + v40 * v23;
        v26 = v34 * v22 - v33 * v21;
        v35 = v40 * v24 - v32 * v23;
      }
      *((int *)v15 + 21) = LODWORD(v35);
      v29 = *((int *)v15 + 2);
      *((float *)v15 + 19) = v25;
      *((int *)v15 + 22) = v29;
      *((float *)v15 + 20) = v26;
      v15 += 16;
      --v31;
    }
    while ( v31 );
  }
  v1->field_10 = 3;
  return 1;
}

//----- (00477F63) --------------------------------------------------------
bool stru6_stru1_indoor_sw_billboard::sub_477F63()
{
  signed int v1; // ebx@1
  stru6_stru1_indoor_sw_billboard *v2; // esi@1
  double v3; // st7@2
  int v4; // edx@4
  char *v5; // ecx@5
  int v6; // edi@5
  float v7; // ST08_4@13
  signed int v9; // [sp+Ch] [bp-8h]@1
  float v10; // [sp+10h] [bp-4h]@2

  auto a1 = this;

  v1 = 0;
  v2 = a1;
  v9 = 0;
  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
  {
    v10 = 16192.0;
    v3 = (double)pBLVRenderParams->field_40 * 0.000015258789;
  }
  else
  {
    v10 = (double)pOutdoorCamera->shading_dist_mist;
    v3 = 8.0;
  }
  v4 = a1->field_10;
  if ( v4 <= 0 )
    goto LABEL_16;
  v5 = (char *)&a1->field_14[20];
  v6 = v4;
  do
  {
    if ( v3 >= *(float *)v5 || *(float *)v5 >= (double)v10 )
    {
      if ( v3 < *(float *)v5 )
        v9 = 1;
      else
        v1 = 1;
    }
    v5 += 16;
    --v6;
  }
  while ( v6 );
  if ( !v1 )
  {
    if ( v9 )
    {
      v2->_477927(v10);
      return v2->field_10 != 0;
    }
LABEL_16:
    memcpy(&v2->field_14[40], &v2->field_14[20], 16 * v4);
    return v2->field_10 != 0;
  }
  v7 = v3;
  _4775ED(v7);
  return v2->field_10 != 0;
}

//----- (0047802A) --------------------------------------------------------
int stru6_stru1_indoor_sw_billboard::sub_47802A()
{
  int v1; // edx@1
  stru6_stru1_indoor_sw_billboard *v2; // edi@1
  int v3; // ebx@2
  char *v4; // esi@3
  float v5; // eax@4
  double v6; // st7@4
  double v7; // ST30_8@5
  double v8; // st6@6
  double v9; // st5@6
  char *v10; // ecx@15
  float v11; // eax@16
  double v12; // st7@16
  double v13; // st6@16
  double v14; // st5@16
  signed int v16; // [sp+38h] [bp-Ch]@1
  int a6; // [sp+3Ch] [bp-8h]@5
  int a5; // [sp+40h] [bp-4h]@5

  auto a1 = this;

  v1 = 0;
  v2 = a1;
  v16 = 0;
  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
  {
    v3 = 0;
    if ( a1->field_10 > 0 )
    {
      v4 = (char *)&a1->field_14[42];
      do
      {
        LODWORD(v5) = *((int *)v4 - 2);
        v6 = (double)pBLVRenderParams->field_40 * 0.000015258789 / *((float *)v4 - 2);
        if ( pRenderer->pRenderD3D )
        {
          v7 = v5 + 6.7553994e15;
          pGame->pIndoorCameraD3D->Project(
            COERCE_UNSIGNED_INT64(v5 + 6.7553994e15),
            COERCE_UNSIGNED_INT64(*((float *)v4 - 1) + 6.7553994e15),
            COERCE_UNSIGNED_INT64(*(float *)v4 + 6.7553994e15),
            &a5,
            &a6);
          *((float *)v4 + 18) = (double)a5;
          *((float *)v4 + 19) = (double)a6;
          *((float *)v4 + 20) = (double)SLODWORD(v7);
        }
        else
        {
          *((float *)v4 + 18) = (double)pBLVRenderParams->uViewportCenterX - v6 * *((float *)v4 - 1);
          v8 = (double)pBLVRenderParams->uViewportCenterY;
          v9 = v6 * *(float *)v4;
          *((int *)v4 + 20) = LODWORD(v5);
          *((float *)v4 + 19) = v8 - v9;
        }
        *((int *)v4 + 21) = *((int *)v4 + 1);
        if ( (double)(signed int)pViewport->uViewportX <= *((float *)v4 + 18)
          && (double)(signed int)pViewport->uViewportZ > *((float *)v4 + 18)
          && (double)(signed int)pViewport->uViewportY <= *((float *)v4 + 19)
          && (double)(signed int)pViewport->uViewportW > *((float *)v4 + 19) )
          v16 = 1;
        ++v3;
        v4 += 16;
      }
      while ( v3 < v2->field_10 );
    }
  }
  else
  {
    if ( a1->field_10 > 0 )
    {
      v10 = (char *)&a1->field_14[40];
      do
      {
        LODWORD(v11) = *(int *)v10;
        v12 = (double)pOutdoorCamera->int_fov_rad / *(float *)v10;
        *((float *)v10 + 20) = (double)pViewport->uScreenCenterX - v12 * *((float *)v10 + 1);
        v13 = (double)pViewport->uScreenCenterY;
        v14 = v12 * *((float *)v10 + 2);
        *((int *)v10 + 22) = LODWORD(v11);
        *((int *)v10 + 23) = *((int *)v10 + 3);
        *((float *)v10 + 21) = v13 - v14;
        if ( (double)(signed int)pViewport->uViewportX <= *((float *)v10 + 20)
          && (double)(signed int)pViewport->uViewportZ > *((float *)v10 + 20)
          && (double)(signed int)pViewport->uViewportY <= *((float *)v10 + 21)
          && (double)(signed int)pViewport->uViewportW > *((float *)v10 + 21) )
          v16 = 1;
        ++v1;
        v10 += 16;
      }
      while ( v1 < v2->field_10 );
    }
  }
  return v16;
}



//----- (004783FA) --------------------------------------------------------
void __cdecl sub_4783FA_construct_global_73D150()
{
  char *v0; // eax@1
  signed int v1; // ecx@1

  v0 = (char *)&array_73D150[0].flt_2C;
  v1 = 20;
  do
  {
    *(float *)v0 = 0.0;
    v0 += 48;
    --v1;
  }
  while ( v1 );
}



//----- (0047840D) --------------------------------------------------------
char Render::DrawBuildingsD3D()
{
  IndoorCameraD3D *v0; // eax@3
  char result; // al@3
  BSPModel *v2; // ebx@4
  int v3; // eax@6
  ODMFace *pFace; // esi@6
  Vec3_int_ *v5; // ecx@8
  int v6; // eax@8
  stru148 *v7; // ebx@8
  LightmapBuilder *v8; // eax@8
  int v9; // ecx@8
  char v10; // zf@8
  Texture *pFaceTexture; // eax@10
  signed int v12; // ecx@10
  unsigned int v13; // eax@14
  unsigned int v14; // eax@18
  unsigned int v15; // eax@22
  unsigned int v16; // edi@22
  int v17; // eax@24
  int v18; // edi@34
  RenderVertexSoft *v19; // eax@35
  unsigned short *v20; // ecx@35
  unsigned short *v20b; // ecx@35
  unsigned short *v20c; // ecx@35
  Vec3_int_ *v21; // edx@36
  int v22; // edx@36
  RenderVertexSoft *v23; // edi@37
  int v24; // eax@50
  int v25; // ecx@55
  int v26; // eax@57
  int v27; // eax@57
  int v28; // eax@58
  int v29; // edx@58
  double v30; // st7@59
  LightmapBuilder *v31; // edi@63
  signed int v32; // eax@73
  int v33; // eax@78
  unsigned int v34; // eax@80
  std::string v35; // [sp-18h] [bp-70h]@2
  int v36; // [sp-14h] [bp-6Ch]@69
  RenderVertexSoft *v37; // [sp-10h] [bp-68h]@69
  int v38; // [sp-Ch] [bp-64h]@69
  LightmapBuilder *v39; // [sp-8h] [bp-60h]@2
  int v40; // [sp-4h] [bp-5Ch]@2
  std::string *v41; // [sp+Ch] [bp-4Ch]@2
  int v41b;
  int v42; // [sp+10h] [bp-48h]@6
  LightmapBuilder *pLightmapBuilder; // [sp+14h] [bp-44h]@8
  float v44; // [sp+18h] [bp-40h]@10
  float v45; // [sp+1Ch] [bp-3Ch]@10
  ODMFace *v46; // [sp+20h] [bp-38h]@6
  IndoorCameraD3D *v47; // [sp+24h] [bp-34h]@3
  unsigned int v48; // [sp+28h] [bp-30h]@8
  int v49; // [sp+2Ch] [bp-2Ch]@10
  int v50; // [sp+30h] [bp-28h]@34
  int v51; // [sp+34h] [bp-24h]@35
  int v52; // [sp+38h] [bp-20h]@36
  int v53; // [sp+3Ch] [bp-1Ch]@8
  Vec3_int_ *v54; // [sp+40h] [bp-18h]@6
  int a1; // [sp+44h] [bp-14h]@3
  BSPModel *v56; // [sp+48h] [bp-10h]@4
  int uNumVertices; // [sp+4Ch] [bp-Ch]@34
  int unused; // [sp+50h] [bp-8h]@3
  int a3; // [sp+57h] [bp-1h]@2

  if ( !pRenderer->pRenderD3D )
  {
          MessageBoxW(nullptr, L"D3D version of RenderBuildings called in software!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odbuild.cpp:73", 0);
  }
  unused = 0;
  v0 = pGame->pIndoorCameraD3D;
  a1 = 0;
  v47 = v0;
  result = LOBYTE(pOutdoor->pBModels);
  v41b = pOutdoor->uNumBModels;
  if ( (signed int)pOutdoor->uNumBModels > 0 )
  {
    v2 = pOutdoor->pBModels;
    v56 = pOutdoor->pBModels;
    while ( 1 )
    {
      if ( IsBModelVisible(a1, &unused) )
      {
		v2->field_40 |= 1u;
        v3 = v2->uNumFaces;
        pFace = v2->pFaces;
        v54 = 0;
        v46 = pFace;
        v42 = v3;
        if ( v3 > 0 )
          break;
      }
LABEL_86:
      ++a1;
      ++v2;// += 47;
      result = a1;
      v56 = v2;
      if ( a1 >= v41b )
        return result;
    }
    while ( 1 )
    {
      if (pFace->Invisible())
        goto LABEL_85;
      //v5 = (int)*(v2 - 1);
	  v5 = v2->pVertices.pVertices;
      v6 = pFace->pVertexIDs[0];
      v53 = 0;
      v7 = &array_77EC08[pOutdoorCamera->numStru148s];
	  //v8 = *(LightmapBuilder **)(v5 + 12 * v6 + 8);
      v8 = (LightmapBuilder *)v5[v6].z;
      *(int *)&v7->flags = 0;
      pLightmapBuilder = v8;
      v9 = pFace->uTextureID;
      v10 = (BYTE1(pFace->uAttributes) & 0x40) == 0;
      v48 = pFace->uTextureID;
      if ( !v10 )
      {
        v48 = pTextureFrameTable->GetFrameTexture(v9, pEventTimer->uTotalGameTimeElapsed);
        v9 = v48;
      }
      pFaceTexture = (Texture *)(v9 != -1 ? (int)&pBitmaps_LOD->pTextures[v9] : 0);
      v7->pTexture = pFaceTexture;
      v12 = (v9 != -1 ? pBitmaps_LOD->pTextures[v9].uTextureWidth : 24);
      v49 = v12;
      v49 = pFaceTexture->uTextureHeight;
      v10 = (pFace->uAttributes & 0x10) == 0;
      v45 = 1.0 / (double)v12;
      v44 = 1.0 / (double)v49;
      if ( !v10 )
        *(int *)&v7->flags |= 2u;
      if ( BYTE2(pFace->uAttributes) & 0x40 )
        HIBYTE(v7->flags) |= 4u;
      v13 = pFace->uAttributes;
      if ( v13 & 4 )
      {
        HIBYTE(v7->flags) |= 4u;
      }
      else
      {
        if ( v13 & 0x20 )
          HIBYTE(v7->flags) |= 8u;
      }
      v14 = pFace->uAttributes;
      if ( BYTE1(v14) & 8 )
      {
        *(int *)&v7->flags |= 0x2000u;
      }
      else
      {
        if ( v14 & 0x40 )
          HIBYTE(v7->flags) |= 0x10u;
      }
      v15 = GetTickCount();
      v7->sTextureDeltaU = pFace->sTextureDeltaU;
      v7->sTextureDeltaV = pFace->sTextureDeltaV;
      v16 = v15 >> 4;
      if ( pFace->pFacePlane.vNormal.z && (v40 = pFace->pFacePlane.vNormal.z, abs(v40) >= 59082) )
      {
        v17 = *(int *)&v7->flags;
        if ( BYTE1(v17) & 4 )
          goto LABEL_29;
        if ( BYTE1(v17) & 8 )
        {
LABEL_26:
          v7->sTextureDeltaV -= v16 & v7->pTexture->uHeightMinus1;
          goto LABEL_30;
        }
      }
      else
      {
        v17 = *(int *)&v7->flags;
        if ( BYTE1(v17) & 4 )
          goto LABEL_26;
        if ( BYTE1(v17) & 8 )
        {
LABEL_29:
          v7->sTextureDeltaV += v16 & v7->pTexture->uHeightMinus1;
          goto LABEL_30;
        }
      }
LABEL_30:
      if ( BYTE1(v17) & 0x10 )
      {
        v7->sTextureDeltaU -= v16 & v7->pTexture->uWidthMinus1;
      }
      else
      {
        if ( BYTE1(v17) & 0x20 )
          v7->sTextureDeltaU += v16 & v7->pTexture->uWidthMinus1;
      }
      v18 = pFace->uNumVertices;
      v50 = 0;
      v49 = 0;
      uNumVertices = v18;
      if ( v18 > 0 )
      {
        //v19 = (char *)&array_73D150[0].vWorldPosition.z;
        //v20 = (char *)pFace->pTextureUIDs;
		v19 = array_73D150;
        v20 = pFace->pTextureUIDs;
		v20b = pFace->pVertexIDs;
		v20c = pFace->pTextureVIDs;
        v51 = v18;
        do
        {
/*          v21 = &(*(v56 - 1))[*((short *)v20 - 20)];
          *((float *)v19 - 2) = (double)v21->x;
          *((float *)v19 - 1) = (double)v21->y;
          *(float *)v19 = (double)v21->z;
          v19 += 48;
          v52 = v7->sTextureDeltaU + *(short *)v20;
          *((float *)v19 - 5) = (double)v52 * v45;
          v22 = v7->sTextureDeltaV + *((short *)v20 + 20);
          v20 += 2;
          v10 = v51-- == 1;
          v52 = v22;
          *((float *)v19 - 4) = (double)v22 * v44;*/
          
		  //v21 = (BSPVertexBuffer *)(*((_DWORD *)v56 - 1) + 12 * *(v20 - 20));
		  v21 = &v56->pVertices.pVertices[*v20b];
          //*((float *)v19 - 2) = (double)v21->x;
          //*((float *)v19 - 1) = (double)v21->y;
		  v19->vWorldPosition.x = (double)v21->x;
		  v19->vWorldPosition.y = (double)v21->y;
          v19->vWorldPosition.z = (double)v21->z;
          ++v19;
          v52 = v7->sTextureDeltaU + (signed __int16)*v20;
          //*((float *)v19 - 5) = (double)v52 * v45;
		  (v19-1)->u = (double)v52 * v45;
          v22 = v7->sTextureDeltaV + (signed __int16)*v20c;
          ++v20;
		  ++v20b;
		  ++v20c;
          v10 = v51-- == 1;
          v52 = v22;
          //*((float *)v19 - 4) = (double)v22 * v44;
		  (v19-1)->v = (double)v22 * v44;
        }
        while ( !v10 );
        //v23 = (char *)&array_73D150[0].vWorldViewPosition;
		v23 = array_73D150;
        v51 = uNumVertices;
        *(float *)&pLightmapBuilder = (double)(signed int)pLightmapBuilder;
        do
        {
          //if ( *(float *)&pLightmapBuilder == *((float *)v23 - 1) )
		  if ( *(float *)&pLightmapBuilder == v23->vWorldPosition.z )
            ++v53;
          //v47->ViewTransform((RenderVertexSoft *)(v23 - 12), 1u);
		  v47->ViewTransform(v23, 1u);
		  if ( v23->vWorldViewPosition.x < 8.0 || (double)pOutdoorCamera->shading_dist_mist < v23->vWorldViewPosition.x )
          {
            if ( v23->vWorldViewPosition.x >= 8.0 )
              v49 = 1;
            else
              v50 = 1;
          }
          else
          {
            v47->Project(v23, 1u, 0);
          }
          ++v23;// += 48;
          --v51;
        }
        while ( v51 );
        v18 = uNumVertices;
      }
      if ( v53 == v18 )
        LOBYTE(v7->field_32) |= 1u;
      v24 = pOutdoor->vSunlight.x;
      v7->pODMFace = pFace;
      v7->uNumVertices = v18;
      v7->field_59 = 5;
      pLightmapBuilder = (LightmapBuilder *)-v24;
      v51 = pFace->pFacePlane.vNormal.x;
      v51 = (unsigned __int64)(-v24 * (signed __int64)v51) >> 16;
      v53 = pFace->pFacePlane.vNormal.y;
      pLightmapBuilder = (LightmapBuilder *)-pOutdoor->vSunlight.y;
      v53 = (unsigned __int64)(-pOutdoor->vSunlight.y * (signed __int64)v53) >> 16;
      v52 = pFace->pFacePlane.vNormal.z;
      v52 = (unsigned __int64)(-pOutdoor->vSunlight.z * (signed __int64)v52) >> 16;
      pLightmapBuilder = (LightmapBuilder *)(v51 + v53 + v52);
      v51 = 20 * (int)pLightmapBuilder;
      result = 20 - (20 * (signed int)pLightmapBuilder >> 16);
      v7->field_58 = result;
      if ( result < 0 )
        v7->field_58 = 0;
      if ( v7->field_58 > 31 )
        v7->field_58 = 31;
      if ( pOutdoorCamera->numStru148s >= 1999 )
        return result;
      ++pOutdoorCamera->numStru148s;
      ++pOutdoorCamera->field_44;
      if ( ODMFace::IsBackfaceCulled(pFace, array_73D150, v7) )
      {
        LOBYTE(v25) = (char)v54;
        v26 = a1;
        pFace->bVisible = 1;
        v7->uBModelFaceID = v25;
        LOWORD(v25) = (unsigned __int8)v25;
        v7->uBModelID = v26;
        v27 = 8 * (v25 | (v26 << 6));
        LOBYTE(v27) = v27 | 6;
        v7->field_50 = v27;
        if ( v18 > 0 )
        {
          v28 = 0;
          v29 = v18;
          do
          {
            v30 = 1.0 / (array_73D150[v28].vWorldViewPosition.x + 0.0000001);
            memcpy(&array_50AC10[v28], &array_73D150[v28], sizeof(array_50AC10[v28]));
            ++v28;
            --v29;
            array_50A2B0[v28 + 49]._rhw = v30;
          }
          while ( v29 );
          pFace = v46;
        }

        static stru154 static_RenderBuildingsD3D_stru_73C834;
        /*static bool __init_flag = false;
        if (!__init_flag)
        {
          __init_flag = true;

          static_RenderBuildingsD3D_byte_73C84C_init_flag |= 1u;
          stru154::stru154(&static_RenderBuildingsD3D_stru_73C834);
          atexit(loc_4789D4);
        }*/

        v40 = (int)pFace;
        pLightmapBuilder = pGame->pLightmapBuilder;
        v31 = pLightmapBuilder;
        pLightmapBuilder->ApplyLights_OutdoorFace(pFace);
        pDecalBuilder->ApplyDecals_OutdoorFace(pFace);
        v31->std__vector_000004_size = 0;
        LOBYTE(v31) = 0;
        if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 )
        {
          v31 = (LightmapBuilder *)(v50 ? 3 : v49 != 0 ? 5 : 0);
          static_RenderBuildingsD3D_stru_73C834._49B04D(pFace, (BSPVertexBuffer *)v56 - 1);
          if ( pDecalBuilder->uNumDecals > 0 )
          {
            v40 = -1;
            v39 = v31;
            v38 = 0;
            v37 = array_50AC10;
            v36 = uNumVertices;
            pDecalBuilder->ApplyDecals(
              31 - v7->field_58,
              2,
              &static_RenderBuildingsD3D_stru_73C834,
              uNumVertices,
              array_50AC10,
              0,
              (char)v31,
              -1);
          }
        }
        if ( stru_F8AD28.uNumLightsApplied > 0 )
          pLightmapBuilder->ApplyLights(
            &stru_F8AD28,
            &static_RenderBuildingsD3D_stru_73C834,
            uNumVertices,
            array_50AC10,
            0,
            (char)v31);
        if ( v50 )
        {
          v32 = sr_424CD7(uNumVertices);
          goto LABEL_76;
        }
        if ( v49 )
        {
          v32 = sr_424EE0_MakeFanFromTriangle(uNumVertices);
LABEL_76:
          v7->uNumVertices = v32;
          uNumVertices = v32;
          OutdoorCamera::Project(v32);
        }
        if ( uNumVertices )
        {
          v33 = *(int *)&v7->flags;
          if ( v33 & 2 )
          {
            if ( BYTE1(v33) & 0x3C )
              v34 = pRenderer->pHDWaterBitmapIDs[0];
            else
              v34 = pRenderer->pHDWaterBitmapIDs[pRenderer->field_1036A8_bitmapid];
            v40 = (int)pBitmaps_LOD->pHardwareTextures[v34];
          }
          else
          {
            v40 = (int)pBitmaps_LOD->pHardwareTextures[v48];
          }
          pRenderer->DrawPolygon(uNumVertices, v7, pFace, (IDirect3DTexture2 *)v40);
        }
        goto LABEL_85;
      }
      --pOutdoorCamera->numStru148s;
      --pOutdoorCamera->field_44;
LABEL_85:
      v54 = (Vec3_int_ *)((char *)v54 + 1);
      v2 = v56;
      ++pFace;
      v46 = pFace;
      if ( (signed int)v54 >= (signed int)v42 )
        goto LABEL_86;
    }
  }
  return result;
}
// 73C84C: using guessed type char static_RenderBuildingsD3D_byte_73C84C_init_flag;

//----- (004789DE) --------------------------------------------------------
BSPModel *Render::DrawBuildingsSW()
{
  BSPModel *result; // eax@1
  BSPModel *v1; // ebx@2
  int v2; // eax@4
  ODMFace *v3; // edi@4
  int v4; // ecx@6
  int v5; // eax@6
  int v6; // ecx@6
  int v7; // ecx@6
  double v8; // st7@7
  char *v9; // ebx@7
  int v10; // eax@9
  double v11; // st7@9
  stru148 *v12; // ebx@19
  double v13; // st7@21
  double v14; // ST4C_8@23
  int v15; // eax@23
  int v16; // eax@27
  int v17; // ecx@29
  unsigned __int8 v18; // sf@29
  unsigned __int8 v19; // of@29
  int v20; // ecx@30
  int v21; // eax@31
  int v22; // eax@31
  int v23; // eax@35
  int v24; // eax@39
  Texture *v25; // eax@43
  int v26; // esi@43
  signed int v27; // ecx@43
  double v28; // st6@43
  double v29; // st5@43
  unsigned short *v30; // edx@44
  int v31; // eax@44
  double v32; // st4@45
  int v33; // ecx@45
  char v34; // zf@45
  BSPVertexBuffer *v35; // eax@50
  unsigned int v36; // eax@53
  signed int v37; // esi@53
  int v38; // eax@54
  signed int v39; // edx@55
  char *v40; // ecx@56
  double v41; // ST1C_8@57
  double v42; // ST24_8@57
  signed int v43; // eax@60
  signed int v44; // esi@60
  int v45; // eax@61
  signed int v46; // edx@62
  char *v47; // ecx@63
  double v48; // ST34_8@64
  double v49; // ST44_8@64
  int v50; // eax@66
  signed int v51; // ecx@67
  char *v52; // edx@68
  double v53; // ST3C_8@69
  double v54; // ST2C_8@69
  float v55; // [sp+44h] [bp-7Ch]@50
  float v56; // [sp+48h] [bp-78h]@50
  float v57; // [sp+4Ch] [bp-74h]@50
  float v58; // [sp+50h] [bp-70h]@64
  int v59; // [sp+54h] [bp-6Ch]@64
  int v60; // [sp+58h] [bp-68h]@69
  float v61; // [sp+5Ch] [bp-64h]@64
  float v62; // [sp+60h] [bp-60h]@69
  float v63; // [sp+64h] [bp-5Ch]@57
  float v64; // [sp+68h] [bp-58h]@57
  int v65; // [sp+6Ch] [bp-54h]@64
  int v66; // [sp+70h] [bp-50h]@1
  int v67; // [sp+74h] [bp-4Ch]@6
  int v68; // [sp+78h] [bp-48h]@4
  int v69; // [sp+7Ch] [bp-44h]@57
  int v70; // [sp+80h] [bp-40h]@69
  int v71; // [sp+84h] [bp-3Ch]@23
  float v72; // [sp+88h] [bp-38h]@69
  int v73; // [sp+8Ch] [bp-34h]@57
  int v74; // [sp+90h] [bp-30h]@6
  int v75; // [sp+94h] [bp-2Ch]@6
  ODMFace *v76; // [sp+98h] [bp-28h]@4
  int v77; // [sp+9Ch] [bp-24h]@6
  BSPModel *v78; // [sp+A0h] [bp-20h]@2
  int v79; // [sp+A4h] [bp-1Ch]@4
  int a1; // [sp+A8h] [bp-18h]@1
  unsigned short *v81; // [sp+ACh] [bp-14h]@7
  int v82; // [sp+B0h] [bp-10h]@6
  int v83; // [sp+B4h] [bp-Ch]@6
  signed int v84; // [sp+B8h] [bp-8h]@7
  int a2; // [sp+BCh] [bp-4h]@1

  a2 = 0;
  a1 = 0;
  result = (BSPModel *)pOutdoor->pBModels;
  v66 = pOutdoor->uNumBModels;
  if ( (signed int)pOutdoor->uNumBModels > 0 )
  {
    v1 = pOutdoor->pBModels;
    v78 = pOutdoor->pBModels;
    while ( 1 )
    {
      if ( IsBModelVisible(a1, &a2) )
      {
		v1->field_40 |= 1u;
        v2 = v1->uNumFaces;
        v3 = (ODMFace *)v1->pFaces;
        v74 = 0;
        v76 = v3;
        v68 = v2;
        if ( v2 > 0 )
          break;
      }
LABEL_73:
      ++a1;
      ++v1;
      result = (BSPModel *)a1;
      v78 = v1;
      if ( a1 >= v66 )
        return result;
    }
    while ( 1 )
    {
	  if ( !v3->Invisible() )
      {
        v4 = 3 * v3->pVertexIDs[0];
        v5 = (int)((char *)v1 - 8);
        v67 = (int)((char *)v1 - 8);
        v6 = *(_DWORD *)(*(&v1->uNumConvexFaces - 2) + 4 * v4 + 8) + 4;
        v82 = 0;
        v83 = v6;
        v74 = 0;
        v7 = v3->uNumVertices;
        v75 = 0;
        v77 = v7;
        if ( v7 > 0 )
        {
          v8 = (double)v83;
          v9 = (char *)&array_73D150[0].vWorldViewPosition;
		  v81 = v3->pVertexIDs;
          v83 = v7;
          *(float *)&v84 = v8;
          while ( 1 )
          {
            v10 = *(int *)(v5 + 4) + 12 * *(short *)v81;
            *((float *)v9 - 3) = (double)*(signed int *)v10 + 4.0;
            *((float *)v9 - 2) = (double)*(signed int *)(v10 + 4) + 4.0;
            v11 = (double)*(signed int *)(v10 + 8) + 4.0;
            *((float *)v9 - 1) = v11;
            if ( *(float *)&v84 == v11 )
              ++v82;
            pGame->pIndoorCameraD3D->ViewTransform((RenderVertexSoft *)(v9 - 12), 1u);
            if ( *(float *)v9 < 8.0 || (double)pOutdoorCamera->shading_dist_mist < *(float *)v9 )
            {
              if ( *(float *)v9 >= 8.0 )
                v75 = 1;
              else
                v74 = 1;
            }
            else
            {
              pGame->pIndoorCameraD3D->Project((RenderVertexSoft *)(v9 - 12), 1u, 0);
            }
            v81 += 2;
            v9 += 48;
            --v83;
            if ( !v83 )
              break;
            v5 = v67;
          }
          v7 = v77;
        }
        v12 = &array_77EC08[pOutdoorCamera->numStru148s];
        *(int *)&v12->flags = 0;
        if ( v82 == v7 )
          *(int *)&v12->flags = 65536;
        v12->pODMFace = (ODMFace *)v3;
        v12->uNumVertices = v7;
        v12->field_59 = 5;
        v84 = *(int *)v3;
        v83 = (unsigned __int64)(v84 * (signed __int64)-pOutdoor->vSunlight.x) >> 16;
        v82 = -pOutdoor->vSunlight.y;
        v84 = *(int *)(v3 + 4);
        v82 = (unsigned __int64)(v84 * (signed __int64)-pOutdoor->vSunlight.y) >> 16;
        v81 = (unsigned __int16 *)-pOutdoor->vSunlight.z;
        v84 = *(int *)(v3 + 8);
        v81 = (unsigned __int16 *)((unsigned __int64)(v84 * (signed __int64)-pOutdoor->vSunlight.z) >> 16);
        v84 = v83 + v82 + ((unsigned __int64)(v84 * (signed __int64)-pOutdoor->vSunlight.z) >> 16);
        v13 = (double)v84 * 0.000015258789;
        if ( v13 < 0.0 )
          v13 = 0.0;
        *(float *)&v84 = v13 * 31.0;
        v14 = *(float *)&v84 + 6.7553994e15;
        v71 = LODWORD(v14);
        v15 = (int)&v12->field_58;
        v12->field_58 = 31 - LOBYTE(v14);
        if ( (char)(31 - LOBYTE(v14)) < 0 )
          *(char *)v15 = 0;
        if ( *(char *)v15 > 31 )
          *(char *)v15 = 31;
        v16 = *(short *)(v3 + 272);
        if ( *(char *)(v3 + 29) & 0x40 )
          v16 = pTextureFrameTable->GetFrameTexture(v16, pEventTimer->uTotalGameTimeElapsed);
        v17 = v16;
        result = (BSPModel *)&pBitmaps_LOD->pTextures[v16];
        v19 = __OFSUB__(pOutdoorCamera->numStru148s, 1999);
        v18 = pOutdoorCamera->numStru148s - 1999 < 0;
        v12->pTexture = (Texture *)(v17 != -1 ? (int)result : 0);
        if ( !(v18 ^ v19) )
          return result;
        ++pOutdoorCamera->numStru148s;
        ++pOutdoorCamera->field_44;
        if ( !ODMFace::IsBackfaceCulled((ODMFace *)v3, array_73D150, v12) )
        {
LABEL_71:
          --pOutdoorCamera->numStru148s;
          --pOutdoorCamera->field_44;
          goto LABEL_72;
        }
        LOBYTE(v20) = v79;
        v21 = a1;
        *(char *)(v3 + 305) = 1;
        v12->uBModelFaceID = v20;
        LOWORD(v20) = (unsigned __int8)v20;
        v12->uBModelID = v21;
        v22 = 8 * (v20 | (v21 << 6));
        LOBYTE(v22) = v22 | 6;
        v12->field_50 = v22;
        if ( *(char *)(v3 + 28) & 0x10 )
          *(int *)&v12->flags |= 2u;
        if ( *(char *)(v3 + 30) & 0x40 )
          HIBYTE(v12->flags) |= 4u;
        v23 = *(int *)(v3 + 28);
        if ( v23 & 4 )
        {
          HIBYTE(v12->flags) |= 4u;
        }
        else
        {
          if ( v23 & 0x20 )
            HIBYTE(v12->flags) |= 8u;
        }
        v24 = *(int *)(v3 + 28);
        if ( BYTE1(v24) & 8 )
        {
          HIBYTE(v12->flags) |= 0x20u;
        }
        else
        {
          if ( v24 & 0x40 )
            HIBYTE(v12->flags) |= 0x10u;
        }
        v25 = v12->pTexture;
        v26 = v77;
        v27 = v25->uTextureWidth;
        v84 = v25->uTextureHeight;
        v28 = 1.0 / (double)v27;
        v29 = 1.0 / (double)v84;
        if ( v77 > 0 )
        {
		  v30 = v3->pTextureVIDs;
          v31 = 0;
          v83 = v77;
          do
          {
            v32 = 1.0 / (*(float *)(v31 * 48 + 7590236) + 0.0000001);
            memcpy(&array_50AC10[v31], &array_73D150[v31], sizeof(array_50AC10[v31]));
            ++v31;
            array_50A2B0[v31 + 49]._rhw = v32;
            v84 = v12->sTextureDeltaU + *(short *)(v30 - 40);
            array_50A2B0[v31 + 49].u = (double)v84 * v28;
            v33 = v12->sTextureDeltaV + *(short *)v30;
            v30 += 2;
            v34 = v83-- == 1;
            v84 = v33;
            array_50A2B0[v31 + 49].v = (double)v33 * v29;
          }
          while ( !v34 );
          v3 = v76;
          v26 = v77;
        }
        
        static stru154 static_sub_004789DE_stru_73C818; // idb
        /*static bool __init_flag = false;
        if (!__init_flag)
        {
          __init_flag = true;

          static_sub_004789DE_byte_73C830__init_flag |= 1u;
          stru154::stru154(&static_sub_004789DE_stru_73C818);
        }*/

        pGame->pLightmapBuilder->ApplyLights_OutdoorFace((ODMFace *)v3);
        if ( stru_F8AD28.uNumLightsApplied <= 0 )
        {
          v12->field_108 = 0;
        }
        else
        {
          v35 = (BSPVertexBuffer *)(v78 - 2);
          v12->field_108 = 1;

          static_sub_004789DE_stru_73C818._49B04D((ODMFace *)v3, v35);
          v55 = static_sub_004789DE_stru_73C818.face_plane.vNormal.x;
          v56 = static_sub_004789DE_stru_73C818.face_plane.vNormal.y;
          v57 = static_sub_004789DE_stru_73C818.face_plane.vNormal.z;
          pGame->pLightmapBuilder->_45CA88(&stru_F8AD28, array_50AC10, v26, (Vec3_float_ *)&v55);
        }
        if ( v74 )
        {
          v36 = sr_4250FE(v26);
          v37 = v36;
          if ( !v36 || (OutdoorCamera::Project(v36), v38 = sr_4254D2(v37), (v12->uNumVertices = v38) == 0) )
            goto LABEL_71;
          v12->_48276F_sr();
          v39 = 0;
          if ( (signed int)v12->uNumVertices > 0 )
          {
            v40 = (char *)&array_508690[0].vWorldViewProjY;
            do
            {
              LODWORD(v64) = *((int *)v40 - 1);
              v41 = v64 + 6.7553994e15;
              v69 = LODWORD(v41);
              dword_50B638[v39] = LODWORD(v41);
              LODWORD(v63) = *(int *)v40;
              v42 = v63 + 6.7553994e15;
              v73 = LODWORD(v42);
              v40 += 48;
              dword_50B570[v39++] = LODWORD(v42);
            }
            while ( v39 < (signed int)v12->uNumVertices );
          }
        }
        else
        {
          if ( v75 )
          {
            v43 = sr_4252E8(v26);
            v44 = v43;
            if ( !v43 || (OutdoorCamera::Project(v43), v45 = sr_4254D2(v44), (v12->uNumVertices = v45) == 0) )
              goto LABEL_71;
            v12->_48276F_sr();
            v46 = 0;
            if ( (signed int)v12->uNumVertices > 0 )
            {
              v47 = (char *)&array_508690[0].vWorldViewProjY;
              do
              {
                LODWORD(v61) = *((int *)v47 - 1);
                v48 = v61 + 6.7553994e15;
                v65 = LODWORD(v48);
                dword_50B638[v46] = LODWORD(v48);
                LODWORD(v58) = *(int *)v47;
                v49 = v58 + 6.7553994e15;
                v59 = LODWORD(v49);
                v47 += 48;
                dword_50B570[v46++] = LODWORD(v49);
              }
              while ( v46 < (signed int)v12->uNumVertices );
            }
          }
          else
          {
            v50 = sr_4254D2(v26);
            v12->uNumVertices = v50;
            if ( !v50 )
              goto LABEL_71;
            sr_sub_4829B9(
              &array_73D150[*(char *)(v3 + 298)],
              &array_73D150[*(char *)(v3 + 299)],
              &array_73D150[*(char *)(v3 + 300)],
              v12,
              0);
            v51 = 0;
            if ( (signed int)v12->uNumVertices > 0 )
            {
              v52 = (char *)&array_508690[0].vWorldViewProjY;
              do
              {
                LODWORD(v62) = *((int *)v52 - 1);
                v53 = v62 + 6.7553994e15;
                v60 = LODWORD(v53);
                dword_50B638[v51] = LODWORD(v53);
                LODWORD(v72) = *(int *)v52;
                v54 = v72 + 6.7553994e15;
                v70 = LODWORD(v54);
                v52 += 48;
                dword_50B570[v51++] = LODWORD(v54);
              }
              while ( v51 < (signed int)v12->uNumVertices );
            }
          }
        }
        sr_sub_486B4E_push_outdoor_edges(array_508690, dword_50B638, dword_50B570, v12);
      }
LABEL_72:
      ++v79;
      v1 = v78;
      v3 += 308;
      v76 = v3;
      if ( v79 >= v68 )
        goto LABEL_73;
    }
  }
  return result;
}
// 50B570: using guessed type int dword_50B570[];
// 50B638: using guessed type int dword_50B638[];
// 73C830: using guessed type char static_sub_004789DE_byte_73C830__init_flag;

//----- (00479089) --------------------------------------------------------
bool __fastcall IsBModelVisible(unsigned int uModelID, int *unused)
{
  BSPModel *v2; // eax@1
  int v3; // edi@1
  int v4; // ebx@1
  int v5; // ST28_4@1
  int v6; // ecx@1
  int v7; // ebx@3
  int v8; // eax@3
  int v9; // eax@3
  int v10; // ebx@3
  signed int v11; // esi@6
  int v12; // esi@8
  bool result; // eax@9
  unsigned int v14; // [sp+Ch] [bp-20h]@1
  int v15; // [sp+Ch] [bp-20h]@5
  int *v16; // [sp+10h] [bp-1Ch]@1
  int v17; // [sp+1Ch] [bp-10h]@1
  int v18; // [sp+20h] [bp-Ch]@1
  int v19; // [sp+20h] [bp-Ch]@3
  int angle; // [sp+24h] [bp-8h]@1
  int v21; // [sp+28h] [bp-4h]@1
  int v22; // [sp+28h] [bp-4h]@3

  v16 = unused;
  angle = (signed int)(pOutdoorCamera->uCameraFovInDegrees << 11) / 360 >> 1;
  v14 = uModelID;
  v2 = &pOutdoor->pBModels[uModelID];
  v3 = v2->vBoundingCenter.x - pIndoorCamera->pos.x;
  v4 = v2->vBoundingCenter.y - pIndoorCamera->pos.y;
  v5 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY);
  v21 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY - stru_5C6E00->uIntegerHalfPi);
  v18 = stru_5C6E00->SinCos(pIndoorCamera->sRotationX);
  stru_5C6E00->SinCos(pIndoorCamera->sRotationX - stru_5C6E00->uIntegerHalfPi);
  v6 = v5;
  v17 = v3 * v5 + v4 * v21;
  if ( pIndoorCamera->sRotationX )
    v17 = (unsigned __int64)(v17 * (signed __int64)v18) >> 16;
  v19 = v4 * v6 - v3 * v21;
  v7 = abs(v4);
  v8 = abs(v3);
  v9 = sub_4621DA(v8, v7, 0);
  v10 = v14 * 188;
  v22 = v9;
  *v16 = 0;
  if ( v9 < pOutdoor->pBModels[v14].sBoundingRadius + 256 )
    *v16 = 1;
  v15 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
  if ( v19 >= 0 )
    v11 = ((unsigned __int64)(v15 * (signed __int64)v17) >> 16)
        - ((unsigned __int64)(stru_5C6E00->SinCos(angle) * (signed __int64)v19) >> 16);
  else
    v11 = ((unsigned __int64)(stru_5C6E00->SinCos(angle) * (signed __int64)v19) >> 16)
        + ((unsigned __int64)(v15 * (signed __int64)v17) >> 16);
  v12 = v11 >> 16;
  if ( v22 <= pOutdoorCamera->shading_dist_mist + 2048 )
  {
    //if ( abs(v12) > *(int *)((char *)&pOutdoor->pBModels->sBoundingRadius + v10) + 512 )
	if ( abs(v12) > *(int *)((char *)&pOutdoor->pBModels[v14].sBoundingRadius) + 512 )
    {
      result = v12 < 0;
      LOBYTE(result) = v12 >= 0;
    }
    else
    {
      result = 1;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}




//----- (00479295) --------------------------------------------------------
int stru148::_479295()
{
  stru148 *v1; // edi@1
  ODMFace *v2; // esi@1
  int v3; // ecx@4
  int v4; // eax@4
  int v5; // edx@4
  int v6; // ST14_4@5
  int v7; // ST04_4@5
  stru149 *v8; // ecx@5
  Vec3_int_ thisa; // [sp+Ch] [bp-10h]@8
  int v11; // [sp+18h] [bp-4h]@4

  v1 = this;
  v2 = this->pODMFace;
  if ( !v2->pFacePlane.vNormal.z )
  {
    v3 = v2->pFacePlane.vNormal.x;
    v4 = -v2->pFacePlane.vNormal.y;
LABEL_9:
    v5 = 0;
    v11 = 65536;
    goto LABEL_5;
  }
  if ( (v2->pFacePlane.vNormal.x || v2->pFacePlane.vNormal.y) && abs(v2->pFacePlane.vNormal.z) < 59082 )
  {
    thisa.x = -v2->pFacePlane.vNormal.y;
    thisa.y = v2->pFacePlane.vNormal.x;
    thisa.z = 0;
    thisa.Normalize_float();
    v4 = thisa.x;
    v3 = thisa.y;
    goto LABEL_9;
  }
  v3 = 0;
  v4 = 65536;
  v11 = 0;
  v5 = -65536;
LABEL_5:
  v6 = v11;
  v1->sTextureDeltaU = v2->sTextureDeltaU;
  v7 = v3;
  v8 = v1->ptr_38;
  v1->sTextureDeltaV = v2->sTextureDeltaV;
  v8->_48616B(v4, v7, 0, 0, v5, v6);
  return 1;
}

//----- (00479332) --------------------------------------------------------
int Render::OnOutdoorRedrawSW()
{
  signed int result; // eax@1
  unsigned int v1; // edi@1
  char *v2; // esi@2
  char v3; // cl@3
  double v4; // st7@4
  float v5; // ST34_4@6
  double v6; // ST24_8@6
  int v7; // eax@6
  unsigned int v8; // eax@11
  signed int v9; // eax@13
  Vec3_float_ *v10; // eax@14
  double v11; // st7@17
  float v12; // ST34_4@19
  double v13; // ST1C_8@19
  float v14; // [sp+4h] [bp-34h]@1
  float v15; // [sp+8h] [bp-30h]@1
  float v16; // [sp+Ch] [bp-2Ch]@1

  v14 = (double)pOutdoor->vSunlight.x * 0.000015258789;
  result = 0;
  v1 = (unsigned int)&array_77EC08[pOutdoorCamera->numStru148s];
  v15 = (double)pOutdoor->vSunlight.y * 0.000015258789;
  v16 = (double)pOutdoor->vSunlight.z * 0.000015258789;
  if ( v1 > (unsigned int)array_77EC08 )
  {
    v2 = (char *)&array_77EC08[0].pODMFace;
    while ( 1 )
    {
      v3 = v2[5];
      if ( v3 == 5 )
        break;
      if ( v3 == 1 )
      {
        v9 = pTerrainNormalIndices[((*((int *)v2 - 9) >> 15) & 1)
                                 + 2 * ((unsigned __int8)v2[9] + ((unsigned __int8)v2[8] << 7))];
        if ( v9 > (signed int)(uNumTerrainNormals - 1) )
          v10 = 0;
        else
          v10 = &pTerrainNormals[v9];
        if ( v10 )
        {
          v11 = -(v16 * v10->z + v15 * v10->y + v14 * v10->x);
          if ( v11 < 0.0 )
            v11 = 0.0;
          v12 = v11 * 31.0;
          v13 = v12 + 6.7553994e15;
          v2[4] = 31 - LOBYTE(v13);
        }
        else
        {
          v2[4] = 0;
        }
        if ( v2[4] < 0 )
          v2[4] = 0;
        goto LABEL_23;
      }
LABEL_24:
      v2 += 268;
      if ( (unsigned int)(v2 - 84) >= v1 )
        return result;
    }
    v4 = (double)(signed int)(((unsigned __int64)(**(int **)v2 * (signed __int64)-pOutdoor->vSunlight.x) >> 16)
                            + ((unsigned __int64)(*(int *)(*(int *)v2 + 4) * (signed __int64)-pOutdoor->vSunlight.y) >> 16)
                            + ((unsigned __int64)(*(int *)(*(int *)v2 + 8) * (signed __int64)-pOutdoor->vSunlight.z) >> 16))
       * 0.000015258789;
    if ( v4 < 0.0 )
      v4 = 0.0;
    v5 = v4 * 31.0;
    v6 = v5 + 6.7553994e15;
    v7 = (int)(v2 + 4);
    v2[4] = 31 - LOBYTE(v6);
    if ( (char)(31 - LOBYTE(v6)) < 0 )
      *(char *)v7 = 0;
    if ( *(char *)v7 > 31 )
      *(char *)v7 = 31;
    if ( *(char *)(*(int *)v2 + 29) & 0x40 )
    {
      v8 = pTextureFrameTable->GetFrameTexture(
             *((short *)v2 - 4),
             pEventTimer->uTotalGameTimeElapsed);
      *((int *)v2 - 6) = v8 != -1 ? (int)&pBitmaps_LOD->pTextures[v8] : 0;
    }
LABEL_23:
    result = 1;
    goto LABEL_24;
  }
  return result;
}



unsigned short *LoadTgaTexture(const wchar_t *filename, int *out_width = nullptr, int *out_height = nullptr)
{
  #pragma pack(push, 1)
    struct TGAHeader
    {
      unsigned char  tgaSkip;
      unsigned char  colourmaptype;      // type of colour map 0=none, 1=has palette
      unsigned char  tgaType;            // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed

      short colourmapstart;     // first colour map entry in palette
      short colourmaplength;    // number of colours in palette
      char  colourmapbits;      // number of bits per palette entry 15,16,24,32

      //unsigned char  tgaDontCare2[9];
      short xstart;             // image x origin
      short ystart;             // image y origin

      unsigned short tgaWidth;
      unsigned short tgaHeight;
      unsigned char  tgaBPP;

      char  descriptor;         // image descriptor bits:   00vhaaaa
        //      h horizontal flip
        //      v vertical flip
        //      a alpha bits
    };
  #pragma pack(pop)

  if (out_width)
    *out_width = 0;
  if (out_height)
    *out_height = 0;

  DWORD w;
  auto  file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
  if (file == INVALID_HANDLE_VALUE)
    return nullptr;

  TGAHeader header;
  ReadFile(file, &header, sizeof(header), &w, nullptr);
  SetFilePointer(file, header.tgaSkip, nullptr, FILE_CURRENT);

  if (header.tgaBPP != 24 || header.tgaType != 2)
  {
    CloseHandle(file);
    return nullptr;
  }

  int imgSize = header.tgaWidth * header.tgaHeight * 3;
  auto pixels = new unsigned char[imgSize];
  ReadFile(file, pixels, imgSize, &w, nullptr);
  CloseHandle(file);

  if (w != imgSize)
  {
    delete [] pixels;
    return nullptr;
  }

  if (out_width)
    *out_width = header.tgaWidth;
  if (out_height)
    *out_height = header.tgaHeight;

  auto pixels_16bit = new unsigned short[imgSize / 3];
  for (int i = 0; i < imgSize / 3; ++i)
  {
    pixels_16bit[i] = (pixels[i * 3] / 8 & 0x1F) |
                      ((pixels[i * 3 + 1] / 4 & 0x3F) << 5) |
                      ((pixels[i * 3 + 2] / 8 & 0x1F) << 11);
  }
  delete [] pixels;
  return pixels_16bit;
}

unsigned short *skybox_xn, *skybox_xp,
              *skybox_yn, *skybox_yp,
              *skybox_zn, *skybox_zp;
int            skybox_width, skybox_height;
IDirect3DTexture2   *skybox_texture;
IDirectDrawSurface4 *skybox_surface;
bool Skybox_Initialize(const wchar_t *skybox_name)
{
  wchar_t xn_filename[1024], xp_filename[1024],
          yn_filename[1024], yp_filename[1024],
          zn_filename[1024], zp_filename[1024];
  swprintf(xn_filename, L"%s_xn.tga", skybox_name); swprintf(xp_filename, L"%s_xp.tga", skybox_name);
  swprintf(yn_filename, L"%s_yn.tga", skybox_name); swprintf(yp_filename, L"%s_yp.tga", skybox_name);
  swprintf(zn_filename, L"%s_zn.tga", skybox_name); swprintf(zp_filename, L"%s_zp.tga", skybox_name);

  int xn_width, xn_height;
  skybox_xn = LoadTgaTexture(xn_filename, &xn_width, &xn_height);
  if (!skybox_xn)
    return false;

  int xp_width, xp_height;
  skybox_xp = LoadTgaTexture(xp_filename, &xp_width, &xp_height);
  if (!skybox_xp || xp_width != xn_width || xp_height != xn_height)
  {
    delete [] skybox_xn;
    if (skybox_xp) delete [] skybox_xp;
    return false;
  }

  int yn_width, yn_height;
  skybox_yn = LoadTgaTexture(yn_filename, &yn_width, &yn_height);
  if (!skybox_yn || yn_width != xn_width || yn_height != xn_height)
  {
    delete [] skybox_xn;
    if (skybox_xp) delete [] skybox_xp;
    if (skybox_yn) delete [] skybox_yn;
    return false;
  }

  int yp_width, yp_height;
  skybox_yp = LoadTgaTexture(yp_filename, &yp_width, &yp_height);
  if (!skybox_yp || yp_width != xn_width || yp_height != xn_height)
  {
    delete [] skybox_xn;
    if (skybox_xp) delete [] skybox_xp;
    if (skybox_yn) delete [] skybox_yn;
    if (skybox_yp) delete [] skybox_yp;
    return false;
  }

  int zn_width, zn_height;
  skybox_zn = LoadTgaTexture(zn_filename, &zn_width, &zn_height);
  if (!skybox_zn || zn_width != xn_width || zn_height != xn_height)
  {
    delete [] skybox_xn;
    if (skybox_xp) delete [] skybox_xp;
    if (skybox_yn) delete [] skybox_yn;
    if (skybox_yp) delete [] skybox_yp;
    if (skybox_zn) delete [] skybox_zn;
    return false;
  }

  int zp_width, zp_height;
  skybox_zp = LoadTgaTexture(zp_filename, &zp_width, &zp_height);
  if (!skybox_zp || zp_width != xn_width || zp_height != xn_height)
  {
    delete [] skybox_xn;
    if (skybox_xp) delete [] skybox_xp;
    if (skybox_yn) delete [] skybox_yn;
    if (skybox_yp) delete [] skybox_yp;
    if (skybox_zn) delete [] skybox_zn;
    if (skybox_zp) delete [] skybox_zp;
    return false;
  }

  skybox_width = xn_width;
  skybox_height = xn_height;

  
  if (!pRenderer->pRenderD3D->CreateTexture(skybox_width, skybox_height, &skybox_surface, &skybox_texture,
                                            false, false, pRenderer->uMinDeviceTextureDim))
    return false;

  return true;
}


struct vector
{
  float x, y, z;
};
struct matrix
{
  float m[4][4];
};
void VectorNormalize(vector *v)
{
  float invmag = 1.0f / sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
  v->x *= invmag;
  v->y *= invmag;
  v->z *= invmag;
}
void MatrixRotationAxis(matrix *pout, CONST vector *pv, float angle)
{
  memset(pout, 0, sizeof(matrix));
  pout->m[3][0] = 0;
  pout->m[3][1] = 0;
  pout->m[3][2] = 0;
  pout->m[3][3] = 1;

  vector v;
  v.x = pv->x; v.y = pv->y; v.z = pv->z;
  VectorNormalize(&v);

    pout->m[0][0] = (1.0f - cos(angle)) * v.x * v.x + cos(angle);
    pout->m[1][0] = (1.0f - cos(angle)) * v.x * v.y - sin(angle) * v.z;
    pout->m[2][0] = (1.0f - cos(angle)) * v.x * v.z + sin(angle) * v.y;
    pout->m[0][1] = (1.0f - cos(angle)) * v.y * v.x + sin(angle) * v.z;
    pout->m[1][1] = (1.0f - cos(angle)) * v.y * v.y + cos(angle);
    pout->m[2][1] = (1.0f - cos(angle)) * v.y * v.z - sin(angle) * v.x;
    pout->m[0][2] = (1.0f - cos(angle)) * v.z * v.x - sin(angle) * v.y;
   pout->m[1][2] = (1.0f - cos(angle)) * v.z * v.y + sin(angle) * v.x;
    pout->m[2][2] = (1.0f - cos(angle)) * v.z * v.z + cos(angle);
}
void VectorTransform(const matrix *m, const vector *v, vector *out)
{
  out->x = m->m[0][0] * v->x + m->m[1][0] * v->y + m->m[2][0] * v->z + m->m[3][0];
  out->y = m->m[0][1] * v->x + m->m[1][1] * v->y + m->m[2][1] * v->z + m->m[3][1];
  out->z = m->m[0][2] * v->x + m->m[1][2] * v->y + m->m[2][2] * v->z + m->m[3][2];
}


bool DrawSkyD3D_Skybox()
{
  static bool initialized = false,
              initialization_failed = false;
  if (initialization_failed)
    return false;
  
  static int last_camera_rot_y,
             last_camera_rot_x;
  if (!initialized)
  {
    if (!Skybox_Initialize(L"data/skybox/stars"))
    {
      initialization_failed = true;
      return false;
    }
    initialized = true;

    last_camera_rot_y = pParty->sRotationY + 1; // force update for the first run 
    last_camera_rot_x = pParty->sRotationX + 1;
  }

  /*
  r(y) = 
cos y	0	sin y	0
0	1	0	0
-sin y	0	cos y	0
0	0	0	1

x cos y - z sin y
y
x sin y + z cos y
1



r(x) =     // should be r(right) actually
1	0      	0	0
0	cos x	-sin x	0
0	sin x	cos x	0
0	0	    0	1


x
y cos x + z sin x
-y sin x + z cos x
1

  */

  if (last_camera_rot_y == pParty->sRotationY &&
      last_camera_rot_x == pParty->sRotationX)
  {
draw:
    struct RenderVertexD3D3  v[6];

    v[0].pos.x = pViewport->uScreenX;
    v[0].pos.y = pViewport->uScreenY;
    v[0].pos.z = 0.99989998;
    v[0].rhw = 1;
    v[0].diffuse = 0xFFFFFFFF;
    v[0].specular = 0;
    v[0].texcoord.x = 0;
    v[0].texcoord.y = 0;
    
    v[1].pos.x = pViewport->uScreenX + pViewport->uScreenWidth;
    v[1].pos.y = pViewport->uScreenY + pViewport->uScreenHeight;
    v[1].pos.z = 0.99989998;
    v[1].rhw = 1;
    v[1].diffuse = 0xFFFFFFFF;
    v[1].specular = 0;
    v[1].texcoord.x = (float)pViewport->uScreenWidth / skybox_width;
    v[1].texcoord.y = (float)pViewport->uScreenHeight / skybox_height;

    v[2].pos.x = pViewport->uScreenX + pViewport->uScreenWidth;
    v[2].pos.y = pViewport->uScreenY;
    v[2].pos.z = 0.99989998;
    v[2].rhw = 1;
    v[2].diffuse = 0xFFFFFFFF;
    v[2].specular = 0;
    v[2].texcoord.x = (float)pViewport->uScreenWidth / skybox_width;
    v[2].texcoord.y = 0;

    memcpy(&v[3], &v[0], sizeof(*v));

    v[4].pos.x = pViewport->uScreenX;
    v[4].pos.y = pViewport->uScreenY + pViewport->uScreenHeight;
    v[4].pos.z = 0.99989998;
    v[4].rhw = 1;
    v[4].diffuse = 0xFFFFFFFF;
    v[4].specular = 0;
    v[4].texcoord.x = 0;
    v[4].texcoord.y = (float)pViewport->uScreenHeight / skybox_height;

    memcpy(&v[5], &v[1], sizeof(*v));

    pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
    pRenderer->pRenderD3D->pDevice->SetTexture(0, skybox_texture);
    pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v, 6, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTLIGHT);
    //pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v + 1, 3, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTLIGHT);

    return true;
  }


  DDSURFACEDESC2 desc;
  desc.dwSize = sizeof(desc);
  if (!pRenderer->LockSurface_DDraw4(skybox_surface, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY))
    return false;
  
  last_camera_rot_y = pParty->sRotationY;
  last_camera_rot_x = pParty->sRotationX;

  float aspect = (float)pViewport->uScreenWidth / (float)pViewport->uScreenHeight;
  float fov_x = 3.141592f * (pOutdoorCamera->uCameraFovInDegrees + 0) / 360.0f;
  float fov_y = fov_x / aspect;

  float ray_dx = fov_x / (float)pViewport->uScreenWidth,
        ray_dy = fov_y / (float)pViewport->uScreenHeight;
  float party_angle_x = 2 * 3.141592653589 * pParty->sRotationX / 2048.0,
        party_angle_y = 2 * 3.141592653589 * pParty->sRotationY / 2048.0;
  for (int y = 0; y < pViewport->uScreenHeight; ++y)
    for (int x = 0; x < pViewport->uScreenWidth; ++x)
    {
      float angle_x = party_angle_x - (y - pViewport->uScreenHeight / 2) * ray_dy;
      float angle_y = party_angle_y - (x - pViewport->uScreenWidth / 2) * ray_dx;

      float _dir_x_ = 1,
            _dir_y_ = 0,
            _dir_z_ = 0;

      float dir_x_ = _dir_x_ * cosf(angle_y);// - _dir_z_ * sinf(angle_y);  // rotation around y
      //float dir_y_ = _dir_y_;
      float dir_z_ = _dir_x_ * sinf(angle_y);// + _dir_z_ * cosf(angle_y);

      //float dir_x =  dir_x_;                                               // rotation around x
      //float dir_y =  /*dir_y_ * cosf(angle_x)*/ + dir_z_ * sinf(angle_x);
      //float dir_z = /*-dir_y_ * sinf(angle_x)*/ + dir_z_ * cosf(angle_x);

      vector right;                                            // rotate around right actually to avoid space distortion
      right.x = /*dir_y * 0*/ - dir_z_ * 1;
      right.y = /*dir_z_ * 0 - dir_x_ * */0;
      right.z = dir_x_ * 1/* - dir_y_ * 0*/;
      //VectorNormalize(&right);

      matrix rightMatrix;
      MatrixRotationAxis(&rightMatrix, &right, angle_x);

      vector v1, v2;
      v1.x = dir_x_; v1.y = 0; v1.z = dir_z_;
      VectorTransform(&rightMatrix, &v1, &v2);

      float dir_x = v2.x,
            dir_y = v2.y,
            dir_z = v2.z;

      float abs_dir_x = fabsf(dir_x),
            abs_dir_y = fabsf(dir_y),
            abs_dir_z = fabsf(dir_z);

      unsigned short color = (0x1F << 11) | (0x1F << 5) | (5);  //default to orange
      if (abs_dir_x >= abs_dir_y)
      {
        if (abs_dir_x >= abs_dir_z)
        {
          if (dir_x >= 0)
          {
            float instersect_y = dir_y / (2.0f * dir_x); // plane equation for this side is x + 0.5 = 0
            float instersect_z = dir_z / (2.0f * dir_x);

            float u = 1.0f - (instersect_z + 0.5f),
                  v = 1.0f - (instersect_y + 0.5f);
            
            int tx = u * (skybox_width - 1),
                ty = v * (skybox_height - 1);

            color = skybox_xp[ty * skybox_width + tx];
            //color = ty * 0x1F / skybox_height;
          }
          else
          {
            float instersect_y = dir_y / (2.0f * dir_x);
            float instersect_z = dir_z / (2.0f * dir_x);

            float u = 1.0f - (instersect_z + 0.5f),
                  v = instersect_y + 0.5f;
            
            int tx = u * (skybox_width - 1),
                ty = v * (skybox_height - 1);

            color = skybox_xn[ty * skybox_width + tx];
            //color = tx * 0x1F / skybox_height;
          }
        }
        else if (dir_z >= 0)
          goto DIR_ZP;
        else
          goto DIR_ZN;
      }
      else if (abs_dir_y >= abs_dir_z)
      {
        if (dir_y >= 0)
        {
            float instersect_x = dir_x / (2.0f * dir_y);
            float instersect_z = dir_z / (2.0f * dir_y);

            float u = instersect_x + 0.5f,
                  v = instersect_z + 0.5f;
            
            int tx = u * (skybox_width - 1),
                ty = v * (skybox_height - 1);

            color = skybox_yp[ty * skybox_width + tx];
            //color = tx * 0x1F / skybox_height;
        }
        /*else   should never be seen i guess
        {
            __debugbreak();
          // -y
            //Log::Warning(L"(%03u, %03u): -y", x, y);
        }*/
      }
      else if (dir_z >= 0)
      {
DIR_ZP:
        // +z
        float instersect_x = dir_x / (2.0f * dir_z);
        float instersect_y = dir_y / (2.0f * dir_z);
        //float intersect_z = 0.5f;

        float u = instersect_x + 0.5f,
              v = -instersect_y + 0.5f;

        int tx = u * (skybox_width - 1),
            ty = v * (skybox_height - 1);

        color = skybox_zp[ty * skybox_width + tx];
      }
      else
      {
DIR_ZN:
        // -z
        float instersect_x = -dir_x / (2.0f * dir_z);
        float instersect_y = -dir_y / (2.0f * dir_z);
        //float intersect_z = -0.5f;

        float u = 1.0f - instersect_x - 0.5f,
              v = -instersect_y + 0.5f;

        int tx = u * (skybox_width - 1),
            ty = v * (skybox_height - 1);

        color = skybox_zn[ty * skybox_width + tx];
      }

      //pRenderer->pTargetSurface[(pViewport->uScreenY + y) * pRenderer->uTargetSurfacePitch + pViewport->uScreenX + x] = color;
      ((unsigned __int16 *)((char *)desc.lpSurface + y * desc.lPitch))[x] = color;
    }
    
  ErrD3D((skybox_surface)->Unlock(0));
  goto draw;
}

//----- (00479543) --------------------------------------------------------
void Render::DrawSkyD3D()
{
  int v0; // esi@2
  int v1; // eax@2
  //double v2; // st7@2
  //double v3; // st6@2
  //double v4; // st5@2
  //double v5; // st4@2
  //double v6; // st7@2
  //char *v7; // esi@3
  int v8; // eax@4
  int v9; // eax@4
  int v10; // ebx@4
  signed __int64 v11; // qax@6
  double v12; // st7@6
  int v13; // edi@6
  int v14; // ecx@6
  int v15; // eax@8
  int v16; // eax@12
  signed __int64 v17; // qtt@13
  signed int v18; // ecx@13
  //Texture *v19; // eax@15
  //double v20; // st6@15
  //double v21; // st7@15
  //double v22; // st6@15
  //unsigned __int8 v23; // sf@15
  //unsigned __int8 v24; // of@15
  stru148 _this; // [sp+14h] [bp-150h]@1
  //double v26; // [sp+120h] [bp-44h]@4
  //float v27; // [sp+128h] [bp-3Ch]@4
  float v28; // [sp+12Ch] [bp-38h]@2
  int v29; // [sp+130h] [bp-34h]@4
  int v30; // [sp+134h] [bp-30h]@1
  //int v31; // [sp+138h] [bp-2Ch]@2
  int v32; // [sp+13Ch] [bp-28h]@6
  int v33; // [sp+140h] [bp-24h]@2
  int v34; // [sp+144h] [bp-20h]@1
  int v35; // [sp+148h] [bp-1Ch]@4
  int v36; // [sp+14Ch] [bp-18h]@2
  int v37; // [sp+154h] [bp-10h]@8
  int v38; // [sp+158h] [bp-Ch]@1
  int v39; // [sp+15Ch] [bp-8h]@4
  int v40; // [sp+160h] [bp-4h]@7
  
  extern bool new_sky;
  if (new_sky)
  {
    if (DrawSkyD3D_Skybox())
    return;
  }

  v30 = ((double)(pOutdoorCamera->int_fov_rad * pIndoorCamera->pos.z)
        / ((double)pOutdoorCamera->int_fov_rad + 8192.0) + pViewport->uScreenCenterY);
  v38 = pViewport->uScreenCenterY - 
        pOutdoorCamera->int_fov_rad / (pOutdoorCamera->shading_dist_mist * cos(pIndoorCamera->sRotationX * 0.003066406352445483) + 0.0000001000000011686097) *
        (pOutdoorCamera->shading_dist_mist * -sin(pIndoorCamera->sRotationX * 0.003066406352445483) - pIndoorCamera->pos.z);
  _this._48607B(&stru_8019C8);
  _this.ptr_38->_48694B();
  _this.uTileBitmapID = pOutdoor->uSky_TextureID;
  _this.pTexture = (Texture *)(SLOWORD(pOutdoor->uSky_TextureID) != -1 ? &pBitmaps_LOD->pTextures[SLOWORD(pOutdoor->uSky_TextureID)] : 0);
  if (pOutdoor->uSky_TextureID == -1)
    return;

  _this.field_58 = 0;
  _this.uNumVertices = 4;
  _this.v_18.x = -stru_5C6E00->SinCos(pIndoorCamera->sRotationX - stru_5C6E00->uIntegerHalfPi + 16);
  _this.v_18.y = 0;
  _this.v_18.z = -stru_5C6E00->SinCos(pIndoorCamera->sRotationX + 16);
  _this.field_24 = 0x2000000;

  _this.sTextureDeltaU = 224 * pMiscTimer->uTotalGameTimeElapsed;
  _this.sTextureDeltaV = 224 * pMiscTimer->uTotalGameTimeElapsed;

  array_50AC10[0].vWorldViewProjX = pViewport->uViewportX;
  array_50AC10[0].vWorldViewProjY = pViewport->uViewportY;

  array_50AC10[1].vWorldViewProjX = pViewport->uViewportX;
  array_50AC10[1].vWorldViewProjY = v38;

  array_50AC10[2].vWorldViewProjX = pViewport->uViewportZ;
  array_50AC10[2].vWorldViewProjY = pViewport->uViewportY;

  array_50AC10[3].vWorldViewProjX = pViewport->uViewportZ;
  array_50AC10[3].vWorldViewProjY = v38;

  v36 = (double)(pViewport->uViewportZ - pViewport->uViewportX) * 0.5;
  v33 = 65536 / (signed int)(v36 / tan(0.6457717418670654) + 0.5);

  for (int i = 0; i < _this.uNumVertices; ++i)
  {
     v29 = floorf(array_50AC10[i].vWorldViewProjY + 0.5f);
     v39 = (unsigned __int64)(_this.ptr_38->field_14 * v33 * (v30 - v29)) / 65536;
     v8 = v39 + _this.ptr_38->field_C;

     v39 = (unsigned __int64)(_this.ptr_38->field_20 * v33 * (v30 - v29)) / 65536;
     v36 = v39 + _this.ptr_38->field_18;

      v9 = (unsigned __int64)(_this.v_18.z * v33 * (v30 - v29)) / 65536;
      v10 = _this.v_18.x + v9;
      v39 = _this.v_18.x + v9;
      if ( _this.v_18.x + v9 > 0 )
      {
        v10 = 0;
        v39 = 0;
      }
      v11 = (signed __int64)array_50AC10[i].vWorldViewProjX;
      v38 = v10;
      v12 = array_50AC10[i].vWorldViewProjY - 1.0;
      v13 = v33 * (pViewport->uScreenCenterX - v11);
      v34 = -_this.field_24;
      v32 = (signed __int64)v12;
      v14 = v33 * (v30 - v32);
      while ( 1 )
      {
        v40 = v14;
        if ( !v10 )
          goto LABEL_12;
        v37 = abs(v34 >> 14);
        v15 = abs(v10);
        if ( v37 <= v15 || v32 <= pViewport->uViewportY )
        {
          if ( v39 <= 0 )
            break;
        }
        v14 = v40;
LABEL_12:
        v37 = _this.v_18.z;
        v16 = (unsigned __int64)(_this.v_18.z * (signed __int64)v14) >> 16;
        --v32;
        v14 += v33;
        v10 = _this.v_18.x + v16;
        v39 = _this.v_18.x + v16;
        v38 = _this.v_18.x + v16;
        break;
      }
      LODWORD(v17) = v34 << 16;
      HIDWORD(v17) = v34 >> 16;
      v18 = v17 / v38;
      if ( v18 < 0 )
        v18 = pOutdoorCamera->shading_dist_mist;

      v37 += ((unsigned __int64)(_this.ptr_38->field_10 * v13) >> 16);
      v36 += ((unsigned __int64)(_this.ptr_38->field_1C * v13) >> 16);
      v35 = 224 * pMiscTimer->uTotalGameTimeElapsed + (signed int)((unsigned __int64)(v37 * v18) >> 16) / 8;
      v36 = 224 * pMiscTimer->uTotalGameTimeElapsed + (signed int)((unsigned __int64)(v36 * v18) >> 16) / 8;

      array_50AC10[i].vWorldViewPosition.x = pOutdoorCamera->shading_dist_mist;
      array_50AC10[i]._rhw = 1.0 / (double)(v17 / 65536);
      array_50AC10[i].u = (double)v35 / (65536.0 * pBitmaps_LOD->pTextures[pOutdoor->uSky_TextureID].uTextureWidth);
      array_50AC10[i].v = (double)v36 / (65536.0 * pBitmaps_LOD->pTextures[pOutdoor->uSky_TextureID].uTextureWidth);
    }

     float t = (GetTickCount() % 96000) / 96000.0f;

 array_50AC10[0].vWorldViewPosition.x = pOutdoorCamera->shading_dist_mist;
 array_50AC10[0]._rhw = 1;
 array_50AC10[0].u = 0;
 array_50AC10[0].v = 0 + t;

 array_50AC10[1].vWorldViewPosition.x = pOutdoorCamera->shading_dist_mist;
 array_50AC10[1]._rhw = 1;
 array_50AC10[1].u = 0;
 array_50AC10[1].v = 1 + t;
 
 array_50AC10[2].vWorldViewPosition.x = pOutdoorCamera->shading_dist_mist;
 array_50AC10[2]._rhw = 1;
 array_50AC10[2].u = 1;
 array_50AC10[2].v = 0 + t;

 array_50AC10[3].vWorldViewPosition.x = pOutdoorCamera->shading_dist_mist;
 array_50AC10[3]._rhw = 1;
 array_50AC10[3].u = 1;
 array_50AC10[3].v = 1 + t;
 pRenderer->DrawStrip(_this.uNumVertices, &_this,
          pBitmaps_LOD->pHardwareTextures[_this.uTileBitmapID]);
        return;
}


//----- (00479A53) --------------------------------------------------------
void __fastcall _479A53_draw_some_blv_poly(unsigned int uNumVertices, unsigned int uFaceID)
{
  BLVFace *pFace; // esi@1
  unsigned int v3; // edi@1
  PolygonType v4; // al@1
  double v5; // st7@3
  signed __int64 v6; // qax@3
  PolygonType v7; // cl@3
  int v8; // esi@7
  int v9; // eax@7
  unsigned int v10; // eax@7
  double v11; // st6@7
  int v12; // edx@7
  int v13; // eax@7
  char *v14; // esi@8
  void *v15; // ecx@9
  int v16; // eax@9
  int v17; // edi@9
  double v18; // st7@9
  signed int v19; // ebx@9
  void *v20; // ecx@9
  int v21; // ebx@11
  int v22; // eax@14
  signed __int64 v23; // qtt@16
  double v24; // st7@16
  unsigned __int8 v25; // sf@16
  unsigned __int8 v26; // of@16
  Render *v27; // ecx@17
  double v28; // st7@20
  char *v29; // ebx@20
  char *v30; // edx@20
  unsigned __int8 v31; // c0@21
  unsigned __int8 v32; // c3@21
  double v33; // st6@23
  char *v34; // esi@30
  const void *v35; // ecx@31
  int v36; // eax@31
  const void *v37; // edi@31
  signed __int64 v38; // qax@31
  int v39; // ecx@31
  int v40; // ebx@33
  int v41; // eax@36
  signed __int64 v42; // qtt@39
  int v43; // eax@39
  char v44; // zf@39
  double v45; // st7@39
  double v46; // st7@39
  unsigned int v47; // edx@40
  double v48; // st7@41
  RenderVertexSoft *v49; // ebx@41
  void *v50; // edi@43
  double v51; // st7@46
  RenderVertexSoft *v52; // edx@46
  void *v53; // edi@48
  char *v54; // ebx@52
  unsigned int v55; // eax@53
  unsigned int v56; // eax@55
  int v57; // ST10_4@55
  Texture *v58; // eax@55
  signed int v59; // [sp-4h] [bp-178h]@17
  stru148 *v60; // [sp+0h] [bp-174h]@17
  IDirect3DTexture2 *v61; // [sp+4h] [bp-170h]@17
  stru148 v62; // [sp+14h] [bp-160h]@6
  unsigned int v63; // [sp+120h] [bp-54h]@7
  double v64; // [sp+124h] [bp-50h]@7
  unsigned int v65; // [sp+128h] [bp-4Ch]@1
  unsigned int v66; // [sp+12Ch] [bp-48h]@7
  float v67; // [sp+130h] [bp-44h]@7
  __int64 v68; // [sp+134h] [bp-40h]@3
  __int64 v69; // [sp+13Ch] [bp-38h]@3
  int v70; // [sp+144h] [bp-30h]@3
  int X; // [sp+148h] [bp-2Ch]@9
  int v72; // [sp+14Ch] [bp-28h]@7
  float v73; // [sp+150h] [bp-24h]@16
  unsigned int v74; // [sp+154h] [bp-20h]@3
  RenderVertexSoft *v75; // [sp+158h] [bp-1Ch]@3
  float v76; // [sp+15Ch] [bp-18h]@9
  int v77; // [sp+160h] [bp-14h]@9
  int v78; // [sp+164h] [bp-10h]@7
  void *v79; // [sp+168h] [bp-Ch]@9
  float v80; // [sp+16Ch] [bp-8h]@3
  const void *v81; // [sp+170h] [bp-4h]@7

  __debugbreak();

  pFace = &pIndoor->pFaces[uFaceID];
  v65 = uFaceID;
  v3 = uNumVertices;
  v4 = pFace->uPolygonType;
  if ( v4 == POLYGON_InBetweenFloorAndWall || v4 == POLYGON_Floor )
  {
    if ( (signed int)uNumVertices > 0 )
    {
      v54 = (char *)&array_507D30[0].u;
      LODWORD(v80) = uNumVertices;
      do
      {
        v69 = (GetTickCount() >> 5) - pBLVRenderParams->vPartyPos.x;
        *(float *)v54 = (double)v69 + *(float *)v54;
        *(float *)v54 = *(float *)v54 * 0.25;
        v55 = GetTickCount();
        v54 += 48;
        v44 = LODWORD(v80)-- == 1;
        v68 = pBLVRenderParams->vPartyPos.y + (v55 >> 5);
        *((float *)v54 - 11) = ((double)v68 + *((float *)v54 - 11)) * 0.25;
      }
      while ( !v44 );
      uFaceID = v65;
    }
    v56 = 8 * uFaceID;
    LOBYTE(v56) = 8 * uFaceID | 6;
    v57 = v56;
    v58 = pFace->GetTexture();
    pRenderer->DrawIndoorPolygon(v3, pFace, pBitmaps_LOD->pHardwareTextures[pFace->uBitmapID], v58, v57, -1, 0);
    return;
  }
  HIDWORD(v69) = pIndoorCamera->sRotationX;
  HIDWORD(v68) = pIndoorCamera->pos.z;
  *(float *)&v74 = (double)pBLVRenderParams->uViewportCenterY;
  v70 = (signed __int64)((double)(pBLVRenderParams->field_40 * pBLVRenderParams->vPartyPos.z)
                       / (((double)pBLVRenderParams->field_40 + 16192.0)
                        * 65536.0)
                       + *(float *)&v74);
  v5 = (double)pIndoorCamera->sRotationX * 0.0030664064;
  *(float *)&v75 = v5;
  v80 = cos(v5) * 16192.0;
  v6 = (signed __int64)(*(float *)&v74
                      - (double)pBLVRenderParams->field_40
                      / ((v80 + 0.0000001)
                       * 65535.0)
                      * (sin(*(float *)&v75) * -16192.0 - (double)SHIDWORD(v68)));
  v7 = pFace->uPolygonType;
  if ( v7 == 4 || v7 == 3 )
    v70 = v6;
  stru_8019C8._48653D(65536, 0, 0, 0, 65536, 0);
  v62._48607B(&stru_8019C8);
  v62.uTileBitmapID = pFace->uBitmapID;
  v62.pTexture = (Texture *)((signed __int16)v62.uTileBitmapID != -1 ? &pBitmaps_LOD->pTextures[(signed __int16)v62.uTileBitmapID] : 0);
  if ( !v62.pTexture )
    return;
  v8 = pBLVRenderParams->sPartyRotX;
  v62.field_58 = 0;
  v62.uNumVertices = v3;
  v9 = stru_5C6E00->SinCos(pBLVRenderParams->sPartyRotX - stru_5C6E00->uIntegerHalfPi + 16);
  v62.v_18.y = 0;
  v62.v_18.x = -v9;
  v62.v_18.z = -stru_5C6E00->SinCos(v8 + 16);
  v10 = pBLVRenderParams->uViewportZ - pBLVRenderParams->uViewportX;
  memcpy(&array_507D30[v3], array_507D30, sizeof(array_507D30[v3]));
  LODWORD(v80) = v10;
  v62.field_24 = 33554432;
  v64 = (double)(signed int)v10 * 0.5;
  v72 = 65536 / (signed int)(signed __int64)(v64 / tan(0.6457717418670654) + 0.5);
  LODWORD(v80) = v62.pTexture->uTextureWidth;
  v11 = 1.0 / (double)SLODWORD(v80);
  LODWORD(v80) = v62.pTexture->uTextureHeight;
  v12 = v62.pTexture->uWidthMinus1;
  v13 = v62.pTexture->uHeightMinus1;
  v67 = v11;
  v63 = 224 * pMiscTimer->uTotalGameTimeElapsed & v13;
  v66 = 224 * pMiscTimer->uTotalGameTimeElapsed & v12;
  v78 = 0;
  v81 = 0;
  *((float *)&v68 + 1) = 1.0 / (double)SLODWORD(v80);
  if ( (signed int)v62.uNumVertices <= 0 )
  {
LABEL_17:
    v61 = pBitmaps_LOD->pHardwareTextures[(signed __int16)v62.uTileBitmapID];
    v27 = pRenderer;
    v60 = &v62;
    v59 = v62.uNumVertices;
    goto LABEL_18;
  }
  v14 = (char *)&array_507D30[0].vWorldViewProjY;
  while ( 2 )
  {
    v15 = (void *)(v72 * (v70 - (unsigned __int64)(signed __int64)*(float *)v14));
    LODWORD(v80) = v62.ptr_38->field_14;
    v77 = (unsigned __int64)(SLODWORD(v80) * (signed __int64)(signed int)v15) >> 16;
    v16 = v77 + v62.ptr_38->field_C;
    v77 = (int)v15;
    v74 = v16;
    LODWORD(v80) = v62.ptr_38->field_20;
    v77 = (unsigned __int64)(SLODWORD(v80) * (signed __int64)(signed int)v15) >> 16;
    v79 = v15;
    v75 = (RenderVertexSoft *)(v77 + v62.ptr_38->field_18);
    LODWORD(v80) = v62.v_18.z;
    v79 = (void *)((unsigned __int64)(v62.v_18.z * (signed __int64)(signed int)v15) >> 16);
    v17 = v72 * (pBLVRenderParams->uViewportCenterX - (unsigned __int64)(signed __int64)*((float *)v14 - 1));
    v18 = *(float *)v14 - 1.0;
    v19 = -v62.field_24;
    v77 = -v62.field_24;
    X = (int)((char *)v79 + v62.v_18.x);
    LODWORD(v76) = (signed __int64)v18;
    v20 = (void *)(v72 * (v70 - LODWORD(v76)));
    while ( 1 )
    {
      v79 = v20;
      if ( !X )
        goto LABEL_14;
      v21 = abs(v19 >> 14);
      if ( v21 <= abs(X) )
        break;
      if ( SLODWORD(v76) <= (signed int)pViewport->uViewportY )
        break;
      v19 = v77;
      v20 = v79;
LABEL_14:
      LODWORD(v80) = v62.v_18.z;
      v79 = (void *)((unsigned __int64)(v62.v_18.z * (signed __int64)(signed int)v20) >> 16);
      v22 = (unsigned __int64)(v62.v_18.z * (signed __int64)(signed int)v20) >> 16;
      --LODWORD(v76);
      v20 = (char *)v20 + v72;
      X = v22 + v62.v_18.x;
      v78 = 1;
    }
    if ( !v78 )
    {
      LODWORD(v23) = v77 << 16;
      HIDWORD(v23) = v77 >> 16;
      v79 = (void *)(v23 / X);
      v77 = v17;
      LODWORD(v80) = v62.ptr_38->field_10;
      v77 = v17;
      LODWORD(v76) = v74 + ((unsigned __int64)(SLODWORD(v80) * (signed __int64)v17) >> 16);
      LODWORD(v80) = v62.ptr_38->field_1C;
      v75 = (RenderVertexSoft *)((char *)v75 + ((unsigned __int64)(SLODWORD(v80) * (signed __int64)v17) >> 16));
      v77 = (unsigned __int64)(SLODWORD(v76) * v23 / X) >> 16;
      LODWORD(v73) = (unsigned __int64)((signed int)v75 * v23 / X) >> 16;
      v14 += 48;
      LODWORD(v80) = v66 + ((signed int)((unsigned __int64)(SLODWORD(v76) * v23 / X) >> 16) >> 4);
      v81 = (char *)v81 + 1;
      v24 = (double)SLODWORD(v80) * 0.000015259022;
      LODWORD(v80) = v63 + ((signed int)((unsigned __int64)((signed int)v75 * v23 / X) >> 16) >> 4);
      v26 = __OFSUB__((int)v81, v62.uNumVertices);
      v25 = (signed int)((char *)v81 - v62.uNumVertices) < 0;
      *((float *)v14 - 10) = v24 * v67;
      *((float *)v14 - 9) = (double)SLODWORD(v80) * 0.000015259022 * *((float *)&v68 + 1);
      *((float *)v14 - 11) = 65536.0 / (double)(signed int)v79;
      if ( !(v25 ^ v26) )
        goto LABEL_17;
      continue;
    }
    break;
  }
  LODWORD(v73) = 0;
  v80 = v76;
  if ( (signed int)v62.uNumVertices > 0 )
  {
    v28 = (double)SLODWORD(v76);
    LODWORD(v76) = (int)(char *)array_50AC10 + 28;
    v29 = (char *)&array_50AC10[0].vWorldViewProjX;
    v30 = (char *)&array_507D30[1].vWorldViewProjY;
    v79 = array_50AC10;
    v81 = array_507D30;
    v78 = v62.uNumVertices;
    do
    {
      v31 = v28 < *((float *)v30 - 12);
      v32 = v28 == *((float *)v30 - 12);
      ++LODWORD(v73);
      memcpy(v79, v81, 0x30u);
      v79 = (char *)v79 + 48;
      LODWORD(v76) += 48;
      v29 += 48;
      if ( v31 | v32 || v28 >= *(float *)v30 )
      {
        if ( v28 >= *((float *)v30 - 12) || v28 <= *(float *)v30 )
          goto LABEL_28;
        v33 = (*((float *)v30 - 1) - *((float *)v30 - 13)) * v28 / (*(float *)v30 - *((float *)v30 - 12))
            + *((float *)v30 - 1);
      }
      else
      {
        v33 = (*((float *)v30 - 13) - *((float *)v30 - 1)) * v28 / (*((float *)v30 - 12) - *(float *)v30)
            + *((float *)v30 - 13);
      }
      *(float *)v29 = v33;
      v79 = (char *)v79 + 48;
      v29 += 48;
      ++LODWORD(v73);
      *(unsigned int *)LODWORD(v76) = v28;
      LODWORD(v76) += 48;
LABEL_28:
      v81 = (char *)v81 + 48;
      v30 += 48;
      --v78;
    }
    while ( v78 );
  }
  if ( SLODWORD(v73) <= 0 )
    goto LABEL_40;
  v34 = (char *)&array_50AC10[0].vWorldViewProjY;
  v65 = v77 >> 14;
  HIDWORD(v69) = LODWORD(v73);
  do
  {
    v35 = (const void *)(v72 * (v70 - (unsigned __int64)(signed __int64)*(float *)v34));
    v78 = v62.ptr_38->field_14;
    v81 = (const void *)((unsigned __int64)(v78 * (signed __int64)(signed int)v35) >> 16);
    v36 = (int)((char *)v81 + v62.ptr_38->field_C);
    v81 = v35;
    v74 = v36;
    v78 = v62.ptr_38->field_20;
    v81 = (const void *)((unsigned __int64)(v78 * (signed __int64)(signed int)v35) >> 16);
    v78 = (int)v35;
    v75 = (RenderVertexSoft *)((char *)v81 + v62.ptr_38->field_18);
    v81 = (const void *)v62.v_18.z;
    v78 = (unsigned __int64)(v62.v_18.z * (signed __int64)(signed int)v35) >> 16;
    v37 = (const void *)(v72
                       * (pBLVRenderParams->uViewportCenterX - (unsigned __int64)(signed __int64)*((float *)v34 - 1)));
    v38 = (signed __int64)(*(float *)v34 - 1.0);
    v81 = 0;
    LODWORD(v76) = v38;
    v39 = v72 * (v70 - v38);
    while ( 1 )
    {
      v78 = v39;
      if ( !X )
        goto LABEL_36;
      v40 = abs(X);
      if ( abs((signed __int64)v65) <= v40 )
        break;
      if ( SLODWORD(v76) <= (signed int)pViewport->uViewportY )
        break;
      v39 = v78;
LABEL_36:
      v78 = v62.v_18.z;
      v41 = (unsigned __int64)(v62.v_18.z * (signed __int64)v39) >> 16;
      --LODWORD(v76);
      v39 += v72;
      X = v41 + v62.v_18.x;
      v81 = (const void *)1;
    }
    if ( v81 )
    {
      v79 = (void *)v62.v_18.z;
      v78 = 2 * LODWORD(v76);
      v81 = (const void *)((unsigned __int64)(v62.v_18.z
                                            * (signed __int64)(signed int)(signed __int64)(((double)v70
                                                                                          - ((double)(2 * LODWORD(v76))
                                                                                           - *(float *)v34))
                                                                                         * (double)v72)) >> 16);
      X = (int)((char *)v81 + v62.v_18.x);
    }
    LODWORD(v42) = v77 << 16;
    HIDWORD(v42) = v77 >> 16;
    v79 = (void *)(v42 / X);
    v81 = v37;
    v78 = v62.ptr_38->field_10;
    v81 = (const void *)((unsigned __int64)(v78 * (signed __int64)(signed int)v37) >> 16);
    v43 = v74 + ((unsigned __int64)(v78 * (signed __int64)(signed int)v37) >> 16);
    v74 = (unsigned int)v37;
    LODWORD(v76) = v43;
    v78 = v62.ptr_38->field_1C;
    v75 = (RenderVertexSoft *)((char *)v75 + ((unsigned __int64)(v78 * (signed __int64)(signed int)v37) >> 16));
    v74 = (unsigned __int64)(v43 * v42 / X) >> 16;
    v81 = (const void *)((unsigned __int64)((signed int)v75 * v42 / X) >> 16);
    v34 += 48;
    v78 = v66 + ((signed int)v74 >> 4);
    v44 = HIDWORD(v69)-- == 1;
    v45 = (double)v78 * 0.000015259022;
    v78 = v63 + ((signed int)((unsigned __int64)((signed int)v75 * v42 / X) >> 16) >> 4);
    *((float *)v34 - 10) = v45 * v67;
    *((float *)v34 - 9) = (double)v78 * 0.000015259022 * *((float *)&v68 + 1);
    v46 = (double)(signed int)v79;
    *((float *)v34 - 16) = 0.000015258789 * v46;
    *((float *)v34 - 11) = 65536.0 / v46;
  }
  while ( !v44 );
LABEL_40:
  v47 = 0;
  if ( SLODWORD(v73) > 0 )
  {
    v48 = (double)SLODWORD(v80);
    v75 = array_507D30;
    v49 = array_50AC10;
    HIDWORD(v69) = LODWORD(v73);
    do
    {
      if ( v48 >= v49->vWorldViewProjY )
      {
        v50 = v75;
        ++v47;
        ++v75;
        memcpy(v50, v49, 0x30u);
      }
      ++v49;
      --HIDWORD(v69);
    }
    while ( HIDWORD(v69) );
  }
  v62.uNumVertices = v47;
  pRenderer->_4A2ED5(v47, &v62, pBitmaps_LOD->pHardwareTextures[(signed __int16)v62.uTileBitmapID]);
  *(float *)&v74 = 0.0;
  if ( SLODWORD(v73) > 0 )
  {
    v51 = (double)SLODWORD(v80);
    v75 = array_507D30;
    v52 = array_50AC10;
    v80 = v73;
    do
    {
      if ( v51 <= v52->vWorldViewProjY )
      {
        v53 = v75;
        ++v74;
        ++v75;
        memcpy(v53, v52, 0x30u);
      }
      ++v52;
      --LODWORD(v80);
    }
    while ( v80 != 0.0 );
  }
  v62.uNumVertices = v74;
  v61 = pBitmaps_LOD->pHardwareTextures[(signed __int16)v62.uTileBitmapID];
  v60 = &v62;
  v59 = v74;
  v27 = pRenderer;
LABEL_18:
  v27->_4A2ED5(v59, v60, v61);
}

//----- (0047A384) --------------------------------------------------------
void ODM_LoadAndInitialize(const char *pLevelFilename, OutdoorCamera *thisa)
{
  int v2; // ebx@3
  unsigned int v3; // eax@3
  MapInfo *v4; // edi@4
  //int v5; // eax@8
  //SpawnPointMM7 *v6; // edx@14
  size_t v7; // eax@19
  char *v8; // eax@19
  char *v9; // eax@21
  char Source[120]; // [sp+Ch] [bp-84h]@19
  const char *pFilename; // [sp+84h] [bp-Ch]@1
  //unsigned int v12; // [sp+88h] [bp-8h]@12
  //int v13; // [sp+8Ch] [bp-4h]@11

  pFilename = pLevelFilename;
  thisa->AllocSoftwareDrawBuffers();
  pOutdoorCamera->_485F64();
  pWeather->bRenderSnow = 0;
  pRenderer->ClearZBuffer(0, 479);
  thisa = (OutdoorCamera *)1;
  GetAlertStatus();
  if ( qword_A750D8 )
    qword_A750D8 = 0i64;
  v2 = pMapStats->GetMapInfo(pCurrentMapName);
  v3 = 0;
  if ( v2 )
  {
    v4 = &pMapStats->pInfos[v2];
    v3 = v4->uRespawnIntervalDays;
  }
  else
  {
    v4 = (MapInfo *)thisa;
  }
  day_attrib &= 0xFFFFFFFEu;
  dword_6BE13C_uCurrentlyLoadedLocationID = v2;
  pOutdoor->Initialize(
    pFilename,
    (unsigned int)(signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) / 0x3C / 0x3C / 0x18 + 1,
    v3,
    (int)&thisa);
  if ( !(BYTE1(dword_6BE364_game_settings_1) & 0x20) )
  {
    InitializeActors();
    InitializeLayingItems();
  }
  BYTE1(dword_6BE364_game_settings_1) &= 0xDFu;
  //v5 = 0;
  if ( !v2 )
    thisa = 0;
  if ( thisa == (OutdoorCamera *)1 )
  {
    //v13 = 0;
    for (uint i = 0; i < pOutdoor->uNumSpawnPoints; ++i)
    {
      //v12 = 0;
      //while ( 1 )
      //{
      auto spawn = pOutdoor->pSpawnPoints + i;
        //v6 = &pOutdoor->pSpawnPoints[v12 / 0x18];
      if (spawn->uKind == 3 )
        SpawnEncounter(v4, spawn, 0, 0, 0);
      else
        v4->SpawnRandomTreasure(spawn);
        //++v13;
        //v12 += 24;
        //if ( v13 >= (signed int)pOutdoor->uNumSpawnPoints )
        //  break;
        //v5 = 0;
      //}
    }
    RespawnGlobalDecorations();
  }
  pOutdoor->PrepareDecorations();
  pOutdoor->_47F223_LooksLikeGenerateMonsterLoot();
  pOutdoor->InitalizeActors(v2);
  pOutdoor->MessWithLUN();
  v7 = strlen("levels\\");
  strcpy(Source, &pFilename[v7]);
  strcpy(pOutdoor->pLevelFilename, Source);
  pWeather->Initialize();
  pIndoorCamera->sRotationY = pParty->sRotationY;
  pIndoorCamera->sRotationX = pParty->sRotationX;
  pOutdoorCamera->RotationToInts();
  pOutdoor->UpdateSunlightVectors();
  pOutdoorCamera->int_fov_rad = (signed __int64)pIndoorCamera->flt_1C_fov;
  pOutdoorCamera->int_fov_rad_inv = (signed __int64)pIndoorCamera->flt_20_inv_1C;
  v8 = (char *)&array_77EC08[0].ptr_38;
  do
  {
    *(int *)v8 = (int)&stru_8019C8;
    v8 += 268;
  }
  while ( (signed int)v8 < (signed int)&unk_801A00 );
  v9 = (char *)&array_77EC08[0].prolly_tail;
  do
  {
    *((int *)v9 - 1) = 0;
    *(int *)v9 = 0;
    *((int *)v9 - 5) = 0;
    v9 += 268;
  }
  while ( (signed int)v9 < (signed int)&unk_801A0C );
  MM7Initialization();
}



//----- (0047A825) --------------------------------------------------------
bool LevelDecoration::_47A825()
{
  bool v1; // ebx@1
  LevelDecoration *v2; // edi@1

  v1 = 0;
  v2 = this;
  if ( pParty->uCurrentHour >= 1 || (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 178) )
  {
    v1 = 0;
  }
  else
  {
    if ( (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 164)
      && (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 165)
      && (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 166)
      && (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 167)
      && (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 168)
      && (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 169)
      && (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 170)
      && (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 171)
      && (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 172)
      && (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 173)
      && (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 174)
      && (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 175)
      && (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 176)
      && (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 177) )
    {
      v1 = 1;
      LOBYTE(v2->field_2) &= 0xDFu;
      return v1;
    }
  }
  LOBYTE(v2->field_2) |= 0x20u;
  return v1;
}



//----- (0047BC6F) --------------------------------------------------------
unsigned __int16 *__fastcall GetBillboardPalette(RenderBillboard *a1, int a2, signed int a3, int a4)
{
  int v4; // ebx@1
  int v6; // edx@4
  int v7; // ecx@5
  signed int v8; // eax@6
  signed __int64 v9; // qtt@11
  signed int v10; // eax@12
  int v11; // esi@17
  signed __int64 v12; // qtt@19
  double v13; // ST10_8@19
  int v14; // edi@25
  signed int v15; // edx@26
  signed __int64 v16; // qtt@29
  signed int v17; // eax@30
  int v18; // [sp+10h] [bp-8h]@1
  float a3a; // [sp+20h] [bp+8h]@19

  v4 = a2;
  v18 = a2;
  if ( pParty->field_1613C )
    return PaletteManager::Get(a2);
  if ( !pWeather->field_FA0 )
  {
    if ( day_attrib & 1 )
    {
      v14 = day_fogrange_1 << 16;
      if ( a3 >= day_fogrange_1 << 16 )
      {
        if ( a3 <= day_fogrange_2 << 16 )
        {
          LODWORD(v16) = (a3 - v14) << 16;
          HIDWORD(v16) = (a3 - v14) >> 16;
          v15 = (unsigned __int64)(27 * v16 / ((day_fogrange_2 - day_fogrange_1) << 16)) >> 16;
        }
        else
        {
          v15 = 27;
        }
      }
      else
      {
        v15 = 0;
      }
      v17 = _43F55F_get_billboard_light_level(a1, v15);
      if ( v17 > 27 )
        v17 = 27;
      if ( !a3 )
        v17 = 27;
      v7 = v18;
      v6 = v17;
      return (unsigned __int16 *)PaletteManager::Get_Mist_or_Red_LUT(v7, v6, 1);
    }
    v11 = a4;
    if ( a4 < 0 )
      v11 = 0;
    LODWORD(v12) = a3 << 16;
    HIDWORD(v12) = a3 >> 16;
    a3a = (double)(signed int)(((unsigned __int64)(11 * v12 / (pOutdoorCamera->shading_dist_shade << 16)) >> 16) + 20)
        * pOutdoor->fFogDensity;
    v13 = a3a + 6.7553994e15;
    v10 = _43F55F_get_billboard_light_level(a1, LODWORD(v13) + v11);
    if ( v10 > 27 )
      v10 = 27;
    if ( v10 < a4 )
      v10 = a4;
    if ( v10 > pOutdoor->field_CBC_terrain_triangles_shade_type )
      v10 = pOutdoor->field_CBC_terrain_triangles_shade_type;
    return PaletteManager::Get_Dark_or_Red_LUT(v4, v10, 1);
  }
  v6 = 0;
  if ( pWeather->field_FA0 == 1 )
  {
    v8 = 67108864;
    if ( (signed __int64)pParty->pPartyBuffs[16].uExpireTime > 0 )
      v8 = pParty->pPartyBuffs[16].uPower << 26;
    if ( a3 <= v8 )
    {
      if ( a3 > 0 )
      {
        LODWORD(v9) = a3 << 16;
        HIDWORD(v9) = a3 >> 16;
        v6 = (unsigned __int64)(27 * v9 / v8) >> 16;
      }
    }
    else
    {
      v6 = 27;
    }
    v10 = _43F55F_get_billboard_light_level(a1, v6);
    if ( v10 > 27 || !a3 )
      v10 = 27;
    return PaletteManager::Get_Dark_or_Red_LUT(v4, v10, 1);
  }
  v7 = 0;
  return (unsigned __int16 *)PaletteManager::Get_Mist_or_Red_LUT(v7, v6, 1);
}
// 6BE030: using guessed type int day_attrib;
// 6BE040: using guessed type int day_fogrange_1;
// 6BE044: using guessed type int day_fogrange_2;








//----- (0047BEB1) --------------------------------------------------------
int __fastcall sr_sub_47BEB1(signed int a1, stru148 *a2, int terrain_gamma, int a4, int *a5, int *a6, int a7, int a8)
{
  stru148 *v8; // ebx@1
  signed int v9; // edx@1
  int v10; // eax@5
  signed int v11; // eax@9
  signed int v12; // eax@15
  signed __int64 v13; // qtt@21
  int *v14; // ecx@30
  int *v15; // edi@30
  int v16; // ebx@32
  signed __int64 v17; // qtt@37
  double v18; // ST10_8@37
  double v19; // ST10_8@38
  int v20; // edi@39
  int result; // eax@46
  int *v22; // eax@48
  signed int v23; // edx@51
  signed __int64 v24; // qtt@51
  int v25; // ecx@51
  signed int v26; // [sp+14h] [bp-4h]@1
  float v27; // [sp+28h] [bp+10h]@37
  float v28; // [sp+28h] [bp+10h]@38
  int v29; // [sp+2Ch] [bp+14h]@37

  v8 = a2;
  v9 = a1;
  v26 = a1;
  if ( pParty->field_1613C )
  {
    *a5 = -1;
    *a6 = -1;
    *(char *)a7 = 1;
LABEL_46:
    result = a8;
    *(char *)a8 = 0;
    return result;
  }
  if ( a1 < 0 )
  {
    v26 = v8->field_34 << 16;
    v9 = v8->field_34 << 16;
  }
  v10 = pWeather->field_FA0;
  if ( bUnderwater == 1 )
    v10 = 0;
  if ( !v10 )
  {
    if ( !(day_attrib & 1) && !bUnderwater )
    {
      v14 = a5;
      v15 = a6;
      if ( !v9 )
      {
        *a5 = 31;
        *a6 = -1;
      }
      v16 = v8->field_58 - terrain_gamma;
      if ( v16 >= 0 )
      {
        if ( v16 > 27 )
          v16 = 27;
      }
      else
      {
        v16 = 0;
      }
      *a6 = 27;
      if ( a4 )
      {
        v28 = pOutdoor->fFogDensity * 27.0;
        v19 = v28 + 6.7553994e15;
        v29 = LODWORD(v19);
      }
      else
      {
        LODWORD(v17) = v9 << 16;
        HIDWORD(v17) = v9 >> 16;
        v27 = (double)(signed int)(((unsigned __int64)(v17 / (pOutdoorCamera->shading_dist_shade << 16) * (31 - *a6)) >> 16)
                                 + *a6)
            * pOutdoor->fFogDensity;
        v18 = v27 + 6.7553994e15;
        v29 = LODWORD(v18);
      }
      *v14 = v16 + v29;
      v20 = *v15;
      if ( v16 + v29 > v20 )
        *v14 = v20;
      if ( *v14 < v16 )
        *v14 = v16;
      if ( *v14 > pOutdoor->field_CBC_terrain_triangles_shade_type )
        *v14 = pOutdoor->field_CBC_terrain_triangles_shade_type;
      goto LABEL_45;
    }
    if ( v9 >= day_fogrange_1 << 16 )
    {
      if ( v9 <= day_fogrange_2 << 16 )
      {
        v23 = v9 - (day_fogrange_1 << 16);
        LODWORD(v24) = v23 << 16;
        HIDWORD(v24) = v23 >> 16;
        v25 = (unsigned __int64)(27 * v24 / ((day_fogrange_2 - day_fogrange_1) << 16)) >> 16;
        v22 = a5;
        *a5 = v25;
        if ( v25 > 27 )
          goto LABEL_54;
        v9 = v26;
      }
      else
      {
        v22 = a5;
        *a5 = 27;
      }
    }
    else
    {
      v22 = a5;
      *a5 = 0;
    }
    if ( v9 )
    {
LABEL_55:
      if ( a4 )
        *v22 = 31;
      *a6 = 31;
      *(char *)a7 = 0;
      goto LABEL_59;
    }
LABEL_54:
    *v22 = 27;
    goto LABEL_55;
  }
  if ( v10 == 1 )
  {
    v11 = 1;
    if ( byte_4D864C && BYTE1(pGame->uFlags) & 0x10 )
    {
      v12 = 0;
    }
    else
    {
      if ( (signed __int64)pParty->pPartyBuffs[16].uExpireTime > 0 )
      {
        if ( (signed __int64)pParty->pPartyBuffs[16].uExpireTime <= 0 )
          v11 = 0;
        else
          v11 = pParty->pPartyBuffs[16].uPower;
      }
      v12 = v11 << 26;
    }
    if ( a4 )
      goto LABEL_24;
    if ( v9 <= v12 )
    {
      if ( v9 > 0 )
      {
        LODWORD(v13) = v9 << 16;
        HIDWORD(v13) = v9 >> 16;
        v9 = v26;
        *a5 = (unsigned __int64)(27 * v13 / v12) >> 16;
      }
      if ( *a5 > 27 )
        goto LABEL_24;
    }
    else
    {
      *a5 = 27;
    }
    if ( v9 )
    {
LABEL_25:
      if ( v8->field_32 & 4 )
        *a5 = 27;
      *a6 = 27;
LABEL_45:
      *(char *)a7 = 0;
      goto LABEL_46;
    }
LABEL_24:
    *a5 = 27;
    goto LABEL_25;
  }
  *a5 = -1;
  *a6 = -1;
  *(char *)a7 = 1;
LABEL_59:
  result = a8;
  *(char *)a8 = 1;
  return result;
}
// 4D864C: using guessed type char byte_4D864C;
// 6BE030: using guessed type int day_attrib;
// 6BE040: using guessed type int day_fogrange_1;
// 6BE044: using guessed type int day_fogrange_2;
// 6BE3C4: using guessed type char bUnderwater;

//----- (0047C178) --------------------------------------------------------
void *__fastcall sr_sub_47C178(signed int a1, stru148 *a2, int terrain_gamma, int a4)
{
  stru148 *v4; // esi@1
  void *result; // eax@2
  int v6; // [sp+4h] [bp-8h]@3
  int v7; // [sp+8h] [bp-4h]@3

  v4 = a2;
  if ( pParty->field_1613C )
  {
    result = PaletteManager::Get(a2->pTexture->palette_id2);
  }
  else
  {
    sr_sub_47BEB1(a1, a2, terrain_gamma, a4, &v6, &v7, (int)((char *)&terrain_gamma + 3), (int)((char *)&a4 + 3));
    result = sr_sub_47C1CA(v4, SBYTE3(a4), v6, v7);
  }
  return result;
}

//----- (0047C1CA) --------------------------------------------------------
void *__fastcall sr_sub_47C1CA(stru148 *a1, char a2, int a3, signed int a4)
{
  stru148 *v4; // esi@1
  void *result; // eax@2
  int v6; // edx@3
  int v7; // ecx@8
  int a3a; // [sp+4h] [bp-8h]@1
  char v9; // [sp+8h] [bp-4h]@1

  v9 = a2;
  v4 = a1;
  a3a = 1;
  if ( pParty->field_1613C )
  {
    result = PaletteManager::Get(a1->pTexture->palette_id2);
  }
  else
  {
    v6 = pGame->_44EC23(a1, &a3a, a4);
    if ( v6 == -1 )
      v6 = a3;
    if ( v9 == 1 )
    {
      if ( v6 != -1 || a4 != -1 )
      {
        v7 = v4->pTexture->palette_id2;
      }
      else
      {
        v6 = 0;
        v7 = 0;
      }
      result = PaletteManager::Get_Mist_or_Red_LUT(v7, v6, a3a);
    }
    else
    {
      result = PaletteManager::Get_Dark_or_Red_LUT(v4->pTexture->palette_id2, v6, a3a);
    }
  }
  return result;
}

//----- (0047C24C) --------------------------------------------------------
unsigned __int16 *__fastcall sr_sub_47C24C_get_palette(BLVFace *a1, int a2, int a3, char a4)
{
  int v4; // esi@1
  int v5; // eax@2
  int a3a; // [sp+4h] [bp-4h]@1

  v4 = a2;
  a3a = 1;
  if ( a4 )
  {
    v5 = pGame->_44ED0A(a1, &a3a, 31);
    if ( v5 != -1 )
      a3 = v5;
  }
  return PaletteManager::Get_Dark_or_Red_LUT(v4, a3, a3a);
}

//----- (0047C28C) --------------------------------------------------------
char *__fastcall sr_sub_47C28C_get_palette(stru148 *a1, char a2, signed int a3, signed int a4)
{
  stru148 *v4; // esi@1
  char *result; // eax@2
  signed int v6; // eax@3
  int v7; // ecx@8
  int a2a; // [sp+4h] [bp-8h]@1
  char v9; // [sp+8h] [bp-4h]@1

  v9 = a2;
  v4 = a1;
  a2a = 1;
  if ( pParty->field_1613C )
  {
    result = (char *)pPaletteManager->field_199600_palettes[a1->pTexture->palette_id2];
  }
  else
  {
    v6 = pGame->_44EC23(a1, &a2a, a4);
    if ( v6 != -1 )
      a3 = v6;
    if ( v9 == 1 )
    {
      if ( a3 != -1 || a4 != -1 )
        v7 = v4->pTexture->palette_id2;
      else
        v7 = 0;
      result = (char *)PaletteManager::_47C30E_get_palette(v7, a2a);
    }
    else
    {
      result = (char *)PaletteManager::_47C33F_get_palette(v4->pTexture->palette_id2, a2a);
    }
  }
  return result;
}

// 4D864C: using guessed type char byte_4D864C;


//----- (0047C370) --------------------------------------------------------
unsigned int __cdecl GetLevelFogColor()
{
  unsigned int result; // eax@2
  signed __int64 v1; // qax@5
  int v2; // eax@6

  if ( bUnderwater )
  {
    result = 0xFF258F5Cu;
  }
  else
  {
    if ( day_attrib & 1 )
    {
      if ( pWeather->field_FA0 )
      {
        v2 = -(pWeather->field_FA0 != 1);
        result = (v2 & 0xE0E0E1) - 0xE0E0E1;
      }
      else
      {
        v1 = (signed __int64)((1.0 - pOutdoor->fFogDensity) * 200.0 + pOutdoor->fFogDensity * 31.0);
        result = v1 | (((unsigned int)v1 | (((unsigned int)v1 | 0xFFFFFF00) << 8)) << 8);
      }
    }
    else
    {
      result = 0;
    }
  }
  return result;
}
// 6BE030: using guessed type int day_attrib;
// 6BE3C4: using guessed type char bUnderwater;

//----- (0047C3D7) --------------------------------------------------------
int __fastcall sub_47C3D7_get_fog_related_stuff(int a1, int a2, float a3)
{
  int v3; // ecx@1
  double v5; // st7@10
  signed int v6; // esi@10
  signed int v7; // ecx@11
  double v8; // st6@12
  double v9; // st7@15
  double v10; // st6@16
  float v11; // ST14_4@17
  double v12; // ST08_8@17

  v3 = pWeather->field_FA0;
  if ( bUnderwater == 1 )
    v3 = 0;
  if ( pParty->field_1613C || !(day_attrib & 1) && !bUnderwater )
    return 0xFF000000u;
  if ( v3 )
  {
    if ( v3 != 1 )
      return 0;
    v5 = (double)day_fogrange_1;
    v6 = 216;
    if ( a3 < v5 )
      goto LABEL_11;
    v8 = (double)day_fogrange_2;
    if ( a3 > v8 )
    {
LABEL_13:
      v7 = v6;
      goto LABEL_19;
    }
    v7 = (signed __int64)((a3 - v5) / (v8 - v5) * 216.0);
  }
  else
  {
    v9 = (double)day_fogrange_1;
    v6 = 216;
    if ( a3 < v9 )
    {
LABEL_11:
      v7 = 0;
      goto LABEL_19;
    }
    v10 = (double)day_fogrange_2;
    if ( a3 > v10 )
      goto LABEL_13;
    v11 = (a3 - v9) * 216.0 / (v10 - v9);
    v12 = v11 + 6.7553994e15;
    v7 = LODWORD(v12);
  }
  if ( v7 > v6 )
  {
LABEL_20:
    v7 = v6;
    goto LABEL_21;
  }
LABEL_19:
  if ( a3 == 0.0 )
    goto LABEL_20;
LABEL_21:
  if ( a2 )
    v7 = 248;
  return (-1 - v7) << 24;
}
// 6BE030: using guessed type int day_attrib;
// 6BE040: using guessed type int day_fogrange_1;
// 6BE044: using guessed type int day_fogrange_2;
// 6BE3C4: using guessed type char bUnderwater;

//----- (0047C4FC) --------------------------------------------------------
signed int __fastcall GetActorTintColor(int a1, int a2, float a3, int a4, RenderBillboard *a5)
{
  int v5; // esi@1
  signed int v6; // edx@1
  signed int result; // eax@2
  int v8; // eax@3
  double v9; // st7@12
  double v10; // ST0C_8@18
  int v11; // ecx@28
  signed int v12; // edi@28
  double v13; // ST0C_8@33
  double v14; // ST0C_8@34
  double v15; // st7@44
  double v16; // ST0C_8@44
  double v17; // ST0C_8@44
  int v18; // ST14_4@44
  double v19; // ST0C_8@44
  signed int v20; // [sp+10h] [bp-4h]@10
  float a3a; // [sp+1Ch] [bp+8h]@33
  float a3b; // [sp+1Ch] [bp+8h]@34
  float a3c; // [sp+1Ch] [bp+8h]@44
  float a3d; // [sp+1Ch] [bp+8h]@44
  float a4b; // [sp+20h] [bp+Ch]@18
  int a4a; // [sp+20h] [bp+Ch]@33
  float a4c; // [sp+20h] [bp+Ch]@44
  float a4d; // [sp+20h] [bp+Ch]@44
  int a5a; // [sp+24h] [bp+10h]@44

  v5 = a2;
  v6 = 0;
  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
    return 8 * (31 - a1) | ((8 * (31 - a1) | ((31 - a1) << 11)) << 8);
  v8 = pWeather->field_FA0;
  if ( bUnderwater == 1 )
    v8 = 0;
  if ( pParty->field_1613C )
    return 16711680;
  if ( v8 )
  {
    if ( v8 != 1 )
      return 0;
    v20 = 1;
    if ( (signed __int64)pParty->pPartyBuffs[16].uExpireTime > 0 )
      v20 = pParty->pPartyBuffs[16].uPower;
    v9 = (double)v20 * 1024.0;
    if ( a4 )
      goto LABEL_19;
    if ( a3 <= v9 )
    {
      if ( a3 > 0.0 )
      {
        a4b = a3 * 216.0 / v9;
        v10 = a4b + 6.7553994e15;
        v6 = LODWORD(v10);
        if ( SLODWORD(v10) > 216 )
          goto LABEL_19;
      }
    }
    else
    {
      v6 = 216;
    }
    if ( a3 != 0.0 )
    {
LABEL_20:
      if ( a5 )
        v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3);
      if ( v6 > 216 )
        v6 = 216;
      return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8);
    }
LABEL_19:
    v6 = 216;
    goto LABEL_20;
  }
  if ( a3 == 0.0 )
  {
    result = (signed int)0xF8F8F8;
  }
  else
  {
    v11 = 8 * (a1 - v5);
    v12 = v11;
    if ( v11 >= 0 )
    {
      if ( v11 > 216 )
        v12 = 216;
    }
    else
    {
      v12 = 0;
    }
    if ( a4 )
    {
      a3b = pOutdoor->fFogDensity * 216.0;
      v14 = a3b + 6.7553994e15;
      a4a = LODWORD(v14);
    }
    else
    {
      a3a = (a3 / (double)pOutdoorCamera->shading_dist_shade * 32.0 + 216.0) * pOutdoor->fFogDensity;
      v13 = a3a + 6.7553994e15;
      a4a = LODWORD(v13);
    }
    v6 = a4a + v12;
    if ( a5 )
      v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3);
    if ( v6 > 216 )
      v6 = 216;
    if ( v6 < v12 )
      v6 = v12;
    if ( v6 > 8 * pOutdoor->field_CBC_terrain_triangles_shade_type )
      v6 = 8 * pOutdoor->field_CBC_terrain_triangles_shade_type;
    if ( !bUnderwater )
      return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8);
    v15 = (double)(255 - v6) * 0.0039215689;
    a3c = v15;
    a4c = v15 * 16.0;
    v16 = a4c + 6.7553994e15;
    a5a = LODWORD(v16);
    a4d = a3c * 194.0;
    v17 = a4d + 6.7553994e15;
    v18 = LODWORD(v17);
    a3d = a3c * 153.0;
    v19 = a3d + 6.7553994e15;
    result = LODWORD(v19) | ((v18 | (a5a << 8)) << 8);
  }
  return result;
}
// 6BE3C4: using guessed type char bUnderwater;




//----- (0047F44B) --------------------------------------------------------
unsigned int __stdcall WorldPosToGridCellX(signed int sWorldPosX)
{
  return (sWorldPosX / 512) + 64;
}
// 47F44B: using guessed type int __stdcall WorldPosToGridCellX(int);

//----- (0047F458) --------------------------------------------------------
unsigned int __stdcall WorldPosToGridCellZ(signed int sWorldPosZ)
{
  return 64 - (sWorldPosZ / 512);
}

//----- (0047F469) --------------------------------------------------------
int __stdcall GridCellToWorldPosX(int a1)
{
  return (a1 - 64) << 9;
}

//----- (0047F476) --------------------------------------------------------
int __stdcall GridCellToWorldPosZ(int a1)
{
  return (64 - a1) << 9;
}

//----- (0047F4D3) --------------------------------------------------------
void __fastcall sub_47F4D3(int band1, int band2, int band3)
{
  int v3; // edi@1
  //stru220 *v4; // esi@1
  double v5; // ST2C_8@3
  double v6; // st7@3
  //double v7; // [sp+18h] [bp-28h]@3
  //double v8; // [sp+20h] [bp-20h]@2
  int v9; // [sp+34h] [bp-Ch]@1
  int v10; // [sp+38h] [bp-8h]@1
  //signed int band3a; // [sp+48h] [bp+8h]@2

  v9 = band2 * 512;
  pOutdoorCamera->outdoor_grid_band_3 = band3;
  v10 = band1 * 512;
  v3 = band3 * 512;
  pOutdoorCamera->uPickDepth = band3 * 512;
  //v4 = stru_76E5C8;                             // v4:  0 -> 65536
  for (uint i = 0; i < 16384; ++i)
  //do
  {
    auto v4 = stru_76E5C8 + i;
    //band3a = 256;
    //v8 = (double)(signed int)((char *)v4 + 256 - (int)stru_76E5C8);
    for (uint j = 0; j < 128; ++j)                  // band3a: 0 -> 128
    {
      v5 = pow(j * 512 + 256, 2.0);
      v6 = pow(i * 4 + 256, 2.0);
      //*((float *)&v5 + 1) = sqrt(v6 + v5);
      int v7 = floorf(sqrtf(v5 + v6) + 0.5f);//*((float *)&v5 + 1) + 6.7553994e15;
      if (v7 >= v10)
      {
        if (v7 >= v9)
          v4->field_0 = ((v7 >= v3) - 1) & 2;
        else
          v4->field_0 = 2;
      }
      else
      {
        v4->field_0 = 1;
      }
      //band3a += 512;
      v4->distance = v7;
      ++v4;
    }
    //while ( band3a < 65792 );
  }
  //while ( (signed int)v4 < (signed int)arary_77E5C8 );
}




//----- (004811A3) --------------------------------------------------------
void stru148::_4811A3()
{
  __debugbreak();

  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 0));
  pRenderer->DrawTerrainPolygon(uNumVertices, this,
    pBitmaps_LOD->pHardwareTextures[pRenderer->pHDWaterBitmapIDs[pRenderer->field_1036A8_bitmapid]],
    0, 0);

  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1));
  pRenderer->DrawTerrainPolygon(uNumVertices, this, pBitmaps_LOD->pHardwareTextures[uTileBitmapID], 1, 1);
}



//----- (00481DB2) --------------------------------------------------------
char __fastcall sr_sub_481DB2(RenderVertexSoft *a1, signed int a2, stru148 *a3)
{
  int v3; // eax@2
  int v4; // esi@2
  signed int v5; // esi@2
  char *v6; // edi@3
  double v7; // ST14_8@4
  double v8; // ST0C_8@4
  char result; // al@5

  if ( a2 >= 3 )
  {
    v3 = a3->uTileBitmapID;
    v4 = a3->uTileBitmapID;
    a3->ptr_38 = &stru_8019C8;
    a3->pTexture = (Texture *)(v4 != -1 ? (int)&pBitmaps_LOD->pTextures[v3] : 0);
    v5 = 0;
    if ( (signed int)a3->uNumVertices > 0 )
    {
      v6 = (char *)&array_508690[0].vWorldViewProjY;
      do
      {
        v7 = *((float *)v6 - 1) + 6.7553994e15;
        dword_50B638[v5] = LODWORD(v7);
        v8 = *(float *)v6 + 6.7553994e15;
        v6 += 48;
        dword_50B570[v5++] = LODWORD(v8);
      }
      while ( v5 < (signed int)a3->uNumVertices );
    }
    result = sr_sub_486B4E_push_outdoor_edges(a1, dword_50B638, dword_50B570, a3);
  }
  return result;
}
// 50B570: using guessed type int dword_50B570[];
// 50B638: using guessed type int dword_50B638[];



//----- (00481E55) --------------------------------------------------------
void OutdoorCamera::Project(unsigned int uNumVertices)
{
  double v1; // st7@2
  double v2; // st6@2
  double v3; // st5@2
  int v4; // eax@2
  unsigned int v5; // edx@2
  double v6; // st4@3
  double v7; // st3@3

  if ( (signed int)uNumVertices > 0 )
  {
    v1 = (double)pOutdoorCamera->int_fov_rad;
    v2 = (double)pViewport->uScreenCenterX;
    v3 = (double)pViewport->uScreenCenterY;
    v4 = 0;
    v5 = uNumVertices;
    do
    {
      v6 = v1 * array_507D30[v4]._rhw;
      v7 = v6 * array_507D30[v4].vWorldViewPosition.y;
      memcpy(&array_50AC10[v4], &array_507D30[v4], sizeof(array_50AC10[v4]));
      array_50AC10[v4].vWorldViewProjX = v2 - v7;
      array_50AC10[v4].vWorldViewProjY = v3 - v6 * array_507D30[v4].vWorldViewPosition.z;
      ++v4;
      --v5;
    }
    while ( v5 );
  }
}

//----- (00481EB7) --------------------------------------------------------
void __cdecl ResetStru148s()
{
  int v0; // ecx@1
  char *v1; // eax@2

  v0 = pOutdoorCamera->numStru148s;
  if ( pOutdoorCamera->numStru148s > 0 )
  {
    v1 = (char *)&array_77EC08[0].prolly_tail;
    do
    {
      *((int *)v1 - 1) = 0;
      *(int *)v1 = 0;
      *((int *)v1 - 5) = 0;
      v1 += 268;
      --v0;
    }
    while ( v0 );
  }
}

//----- (00481ED9) --------------------------------------------------------
void __cdecl sub_481ED9_MessWithOutdoorCamera()
{
  stru_8019C8._48616B(65536, 0, 0, 0, 65536, 0);
  pOutdoorCamera->numStru148s = 0;
  pOutdoorCamera->uNumEdges = 0;
  pOutdoorCamera->uNumSpans = 0;
  pOutdoorCamera->uNumSurfs = 0;
  pOutdoorCamera->uNumBillboards = 0;
  pOutdoorCamera->field_44 = 0;
}

//----- (00481EFA) --------------------------------------------------------
bool __fastcall sub_481EFA(RenderVertexSoft *a1, RenderVertexSoft *a2, RenderVertexSoft *a3, RenderVertexSoft *a4, int a5)
{
  RenderVertexSoft *v5; // esi@1
  RenderVertexSoft *v6; // edx@1
  bool v7; // edi@2
  bool v8; // ecx@5
  bool v9; // esi@8
  bool v10; // eax@11
  double v11; // st7@14
  signed int v12; // esi@15
  signed int v13; // edx@18
  signed int v14; // ecx@21
  signed int v15; // eax@24
  RenderVertexSoft *v17; // [sp+Ch] [bp-8h]@1

  v5 = a2;
  v6 = a1;
  v17 = v5;
  v7 = a1->vWorldViewPosition.x < 8.0;
  v8 = v5->vWorldViewPosition.x < 8.0;
  v9 = a3->vWorldViewPosition.x < 8.0;
  v10 = a4->vWorldViewPosition.x < 8.0;
  return !(v8 & v9 & v10 & v7)
      && ((v11 = (double)pOutdoorCamera->shading_dist_mist, v11 > v6->vWorldViewPosition.x) ? (v12 = 0) : (v12 = 1),
          v11 > v17->vWorldViewPosition.x ? (v13 = 0) : (v13 = 1),
          v11 > a3->vWorldViewPosition.x ? (v14 = 0) : (v14 = 1),
          v11 > a4->vWorldViewPosition.x ? (v15 = 0) : (v15 = 1),
          !(v13 & v14 & v15 & v12));
}

//----- (00481FC9) --------------------------------------------------------
int __fastcall sub_481FC9(RenderVertexSoft *a1, RenderVertexSoft *a2, RenderVertexSoft *a3, stru148 *a4)//Rotate camera
{
  float arg_0, arg_4, var_4, var_8, var_c, var_10, var_14;

  if (a1->vWorldPosition.y == a2->vWorldPosition.y && a2->vWorldPosition.y == a3->vWorldPosition.y)
    a4->flags |= 0x10;
  var_c = a1->vWorldViewPosition.x - a2->vWorldViewPosition.x;
  var_14 = a1->vWorldViewPosition.y - a2->vWorldViewPosition.y;
  arg_0 = a1->vWorldViewPosition.z - a2->vWorldViewPosition.z;
  var_10 = a3->vWorldViewPosition.x - a2->vWorldViewPosition.x;
  var_8 = a3->vWorldViewPosition.y - a2->vWorldViewPosition.y;
  var_4 = a3->vWorldViewPosition.z - a2->vWorldViewPosition.z;
  arg_4 = a3->vWorldPosition.y - a2->vWorldPosition.y;
  if (((a3->vWorldPosition.y - a2->vWorldPosition.y) * (a1->vWorldPosition.x - a2->vWorldPosition.x) - (a3->vWorldPosition.x - a2->vWorldPosition.x) * (a1->vWorldPosition.y - a2->vWorldPosition.y)) * (pIndoorCamera->pos.y - a2->vWorldPosition.z) +
      ((a3->vWorldPosition.z - a2->vWorldPosition.z) * (a1->vWorldPosition.y - a2->vWorldPosition.y) - (a3->vWorldPosition.y - a2->vWorldPosition.y) * (a1->vWorldPosition.z - a2->vWorldPosition.z)) * (pIndoorCamera->pos.x - a2->vWorldPosition.x) +
      ((a3->vWorldPosition.x - a2->vWorldPosition.x) * (a1->vWorldPosition.z - a2->vWorldPosition.z) - (a3->vWorldPosition.z - a2->vWorldPosition.z) * (a1->vWorldPosition.x - a2->vWorldPosition.x)) * (pIndoorCamera->pos.z - a2->vWorldPosition.y) < 0)
  {
   arg_4 = var_4 * var_14 - var_8 * arg_0;
   a4->v_18.x = floorf(arg_4 + 0.5f);
   arg_4 = var_10 * arg_0 - var_4 * var_c;
   a4->v_18.y = floorf(arg_4 + 0.5f);
   arg_4 = var_8 * var_c - var_10 * var_14;
   a4->v_18.z = floorf(arg_4 + 0.5f);
   a4->_486089_normalize_v_18();
   arg_4 = -(a4->v_18.x * a2->vWorldViewPosition.x) - a4->v_18.y * a2->vWorldViewPosition.y - a4->v_18.z * a2->vWorldViewPosition.z;
   a4->field_24 = floorf(arg_4 + 0.5f);
   return true;
  }
  else
    return false;
}



//----- (004823F4) --------------------------------------------------------
bool IsTerrainSlopeTooHigh(int pos_x, int pos_z)
{
  //unsigned int v2; // ebx@1
  //unsigned int v3; // edi@1
  //int v4; // eax@1
  //int v6; // esi@5
  //int v7; // ecx@6
  //int v8; // edx@6
  //int v9; // eax@6
  //int v10; // esi@10
  //int v11; // [sp+14h] [bp-8h]@1
  //int v12; // [sp+18h] [bp-4h]@1

  //v12 = a1;
  //v11 = a2;
  auto grid_x = WorldPosToGridCellX(pos_x);
  auto grid_z = WorldPosToGridCellZ(pos_z) - 1;

  auto party_grid_x1 = GridCellToWorldPosX(grid_x);
  //dword_76D56C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1);
  //dword_76D570_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1);
  //dword_76D574_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x);
  auto party_grid_z1 = GridCellToWorldPosZ(grid_z);
  //dword_76D55C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z);
  //dword_76D560_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1);
  //dword_76D564_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1);
  auto party_x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z);
  auto party_x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z);
  auto party_x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1);
  auto party_x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1);
  //dword_76D554_terrain_cell_world_pos_around_party_y = v4;
  if (party_x1z1_y == party_x2z1_y &&
      party_x2z1_y == party_x2z2_y &&
      party_x2z2_y == party_x1z2_y )
    return false;

  auto dx = abs(pos_x - party_grid_x1),
       dz = abs(party_grid_z1 - pos_z);

  int y1, y2, y3;
  if (dz >= dx)
  {
    y1 = party_x1z2_y;  //  lower-left triangle
    y2 = party_x2z2_y;  //  y3 | \ 
    y3 = party_x1z1_y;  //     |   \ 
                        /*     |     \ 
                               |______ \
                            y1           y2   */
  }
  else
  {
    y1 = party_x2z1_y;  // upper-right
    y2 = party_x1z1_y;  //  y2_______ y1
    y3 = party_x2z2_y;  //    \     |
                        /*      \   |
                                  \ |
                                    y3     */
  }

  int y_min = min(y1, min(y2, y3)),
      y_max = max(y1, max(y2, y3));
  return y_max - y_min > 512;

  /*if ( y1 >= y2 )
  {
    y_min = y2;
    if ( y2 < y3 )
      goto LABEL_13;
LABEL_12:
    y_min = y3;
    goto LABEL_13;
  }
  else if ( y1 >= y3 )
    goto LABEL_12;
  else
  y_min = y1;

LABEL_13:
  if ( y1 <= y2 )
  {
    if ( y2 > y3 )
      y3 = y2;
  }
  else
  {
    if ( y1 > y3 )
      y3 = y1;
  }
  return y3 - v10 > 512;*/
}


//----- (0048257A) --------------------------------------------------------
int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *a3, int a4)
{
  unsigned int v4; // ebx@1
  unsigned int v5; // edi@1
  int result; // eax@9
  int v7; // ebx@10
  int v8; // ebx@11
  int v9; // eax@11
  int v10; // ecx@11
  int v11; // [sp+Ch] [bp-Ch]@1
  int v12; // [sp+10h] [bp-8h]@1
  int v13; // [sp+10h] [bp-8h]@11
  signed int v14; // [sp+14h] [bp-4h]@3
  int v15; // [sp+24h] [bp+Ch]@11

  v11 = a1;
  v12 = a2;
  v4 = WorldPosToGridCellX(a1);
  v5 = WorldPosToGridCellZ(v12) - 1;
  dword_76D538_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4);
  dword_76D53C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1);
  dword_76D540_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1);
  dword_76D544_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4);
  dword_76D528_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5);
  dword_76D52C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5);
  dword_76D530_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1);
  dword_76D534_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1);
  dword_76D518_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5);
  dword_76D51C_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5);
  dword_76D520_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5 + 1);
  dword_76D524_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5 + 1);
  *a3 = 0;
  if ( pOutdoor->ActuallyGetSomeOtherTileInfo(v4, v5) & 2 )
    *a3 = 1;
  v14 = 0;
  if ( !a4 && *a3 )
    v14 = -60;
  if ( dword_76D518_terrain_cell_world_pos_around_party_y != dword_76D51C_terrain_cell_world_pos_around_party_y
    || dword_76D51C_terrain_cell_world_pos_around_party_y != dword_76D520_terrain_cell_world_pos_around_party_y
    || dword_76D520_terrain_cell_world_pos_around_party_y != dword_76D524_terrain_cell_world_pos_around_party_y )
  {
    v7 = abs(v11 - dword_76D538_terrain_cell_world_pos_around_party_x);
    if ( abs(dword_76D528_terrain_cell_world_pos_around_party_z - v12) >= v7 )
    {
      v8 = dword_76D524_terrain_cell_world_pos_around_party_y;
      v9 = dword_76D520_terrain_cell_world_pos_around_party_y;
      v10 = dword_76D518_terrain_cell_world_pos_around_party_y;
      v15 = v11 - dword_76D544_terrain_cell_world_pos_around_party_x;
      v13 = v12 - dword_76D534_terrain_cell_world_pos_around_party_z;
    }
    else
    {
      v8 = dword_76D51C_terrain_cell_world_pos_around_party_y;
      v9 = dword_76D518_terrain_cell_world_pos_around_party_y;
      v10 = dword_76D520_terrain_cell_world_pos_around_party_y;
      v15 = dword_76D53C_terrain_cell_world_pos_around_party_x - v11;
      v13 = dword_76D52C_terrain_cell_world_pos_around_party_z - v12;
    }
    result = v14
           + v8
           + ((unsigned __int64)(v13 * (signed __int64)((v10 - v8) << 7)) >> 16)
           + ((unsigned __int64)(v15 * (signed __int64)((v9 - v8) << 7)) >> 16);
  }
  else
  {
    result = v14 + dword_76D518_terrain_cell_world_pos_around_party_y;
  }
  return result;
}


//----- (0048276F) --------------------------------------------------------
void stru148::_48276F_sr()
{
  unsigned int v1; // ebx@1
  float v2; // edx@2
  double v3; // st7@2
  char *v4; // ecx@3
  float v5; // eax@5
  float v6; // eax@7
  float v7; // eax@9
  float v8; // ecx@13
  int i; // eax@16
  int v10; // edx@20
  RenderVertexSoft *v11; // ecx@22
  RenderVertexSoft *v12; // edx@22
  RenderVertexSoft *v13; // esi@22
  int v14; // ebx@26
  RenderVertexSoft *v15; // ebx@27
  double v16; // st6@28
  double v17; // st5@28
  double v18; // st4@28
  int v19; // [sp+4h] [bp-2Ch]@20
  int v20; // [sp+8h] [bp-28h]@22
  int v21; // [sp+Ch] [bp-24h]@22
  stru148 *v22; // [sp+10h] [bp-20h]@1
  float v23; // [sp+14h] [bp-1Ch]@11
  float v24; // [sp+18h] [bp-18h]@7
  float v25; // [sp+1Ch] [bp-14h]@5
  float v26; // [sp+20h] [bp-10h]@2
  float v27; // [sp+24h] [bp-Ch]@2
  float v28; // [sp+28h] [bp-8h]@2
  float v29; // [sp+2Ch] [bp-4h]@9

  v1 = this->uNumVertices;
  v22 = this;
  if ( (signed int)v1 >= 3 )
  {
    LODWORD(v2) = 0;
    v26 = 10000.0;
    v28 = 10000.0;
    v3 = -10000.0;
    v27 = -10000.0;
    if ( (signed int)v1 > 0 )
    {
      v4 = (char *)&array_508690[0].vWorldViewProjY;
      do
      {
        if ( *((float *)v4 - 1) < (double)v26 )
        {
          LODWORD(v5) = *((int *)v4 - 1);
          v25 = v2;
          v26 = v5;
        }
        if ( *((float *)v4 - 1) > (double)v27 )
        {
          LODWORD(v6) = *((int *)v4 - 1);
          v24 = v2;
          v27 = v6;
        }
        if ( *(float *)v4 < (double)v28 )
        {
          LODWORD(v7) = *(int *)v4;
          v29 = v2;
          v28 = v7;
        }
        if ( v3 < *(float *)v4 )
        {
          v3 = *(float *)v4;
          v23 = v2;
        }
        ++LODWORD(v2);
        v4 += 48;
      }
      while ( SLODWORD(v2) < (signed int)v1 );
    }
    v8 = v29;
    if ( LODWORD(v29) == LODWORD(v25) || LODWORD(v29) == LODWORD(v24) )
      v8 = v23;
    v29 = 0.0;
    for ( i = 0; i < (signed int)v1; ++i )
    {
      if ( i == LODWORD(v25) || i == LODWORD(v24) || i == LODWORD(v8) )
      {
        v10 = LODWORD(v29)++;
        *(&v19 + v10) = i;
      }
    }
    v11 = &array_508690[v19];
    v12 = &array_508690[v20];
    v13 = &array_508690[v21];
    if ( LODWORD(v29) != 3 )
    {
      v11 = array_508690;
      v13 = (RenderVertexSoft *)((char *)array_508690 + 16 * (3 * v1 - 3));
      v12 = &array_508690[1];
      v28 = array_508690[1].vWorldPosition.x - array_508690[0].vWorldPosition.x;
      v27 = array_508690[1].vWorldPosition.y - array_508690[0].vWorldPosition.y;
      v29 = array_508690[1].vWorldPosition.z - array_508690[0].vWorldPosition.z;
      v26 = v13->vWorldPosition.x - array_508690[0].vWorldPosition.x;
      v25 = v13->vWorldPosition.y - array_508690[0].vWorldPosition.y;
      v24 = v13->vWorldPosition.z - array_508690[0].vWorldPosition.z;
      if ( v24 * v27 - v25 * v29 == 0.0 )
      {
        if ( v26 * v29 - v24 * v28 == 0.0 )
        {
          if ( v25 * v28 - v26 * v27 == 0.0 )
          {
            v14 = v1 - 2;
            LODWORD(v26) = v14;
            if ( v14 >= 2 )
            {
              v15 = &array_508690[v14];
              do
              {
                v16 = v15->vWorldPosition.x - array_508690[0].vWorldPosition.x;
                v17 = v15->vWorldPosition.y - array_508690[0].vWorldPosition.y;
                v18 = v15->vWorldPosition.z - array_508690[0].vWorldPosition.z;
                v13 = v15;
                if ( v27 * v18 - v17 * v29 != 0.0 )
                  break;
                if ( v16 * v29 - v18 * v28 != 0.0 )
                  break;
                if ( v28 * v17 - v16 * v27 != 0.0 )
                  break;
                --LODWORD(v26);
                --v15;
              }
              while ( SLODWORD(v26) >= 2 );
            }
          }
        }
      }
    }
    sr_sub_4829B9(v11, v12, v13, v22, 1);
  }
}

//----- (004829B9) --------------------------------------------------------
stru148 *__fastcall sr_sub_4829B9(RenderVertexSoft *a1, RenderVertexSoft *a2, RenderVertexSoft *a3, stru148 *a4, int a5)
{
  double v5; // st7@1
  RenderVertexSoft *v6; // esi@1
  double v7; // st6@1
  stru148 *result; // eax@3
  double v9; // st6@3
  double v10; // st5@3
  float v11; // ST0C_4@3
  float v12; // ST04_4@3
  double v13; // st4@3
  float v14; // [sp+8h] [bp-Ch]@1
  float v15; // [sp+10h] [bp-4h]@1
  float v16; // [sp+1Ch] [bp+8h]@1
  float v17; // [sp+1Ch] [bp+8h]@3

  v5 = a2->vWorldViewProjX - a1->vWorldViewProjX;
  v6 = a3;
  v16 = a3->vWorldViewProjY - a1->vWorldViewProjY;
  v15 = a2->vWorldViewProjY - a1->vWorldViewProjY;
  v14 = v6->vWorldViewProjX - a1->vWorldViewProjX;
  v7 = v16 * v5 - v14 * v15;
  if ( v7 == 0.0 )
    v7 = 0.0000001;
  result = a4;
  v9 = 1.0 / v7;
  v10 = 1.0 / a1->vWorldViewPosition.x;
  v11 = 1.0 / a2->vWorldViewPosition.x - v10;
  v12 = 1.0 / v6->vWorldViewPosition.x - v10;
  v13 = (v11 * v16 - v12 * v15) * v9;
  v17 = (v11 * v14 - v12 * v5) * -v9;
  a4->field_C = a1->vWorldViewProjX;
  a4->field_10 = a1->vWorldViewProjY;
  a4->field_0 = v10;
  a4->field_8 = v17;
  a4->field_4 = v13;
  return result;
}

//----- (00482A90) --------------------------------------------------------
signed int __cdecl const_1_0()
{
  return 1;
}


//----- (00482A94) --------------------------------------------------------
int sr_sub_482A94(Span *_this)
{
  stru315 *v1; // ebp@0
  Span *v2; // edi@1
  stru148 *v3; // esi@1
  int v4; // ecx@1
  stru149 *v5; // eax@1
  stru149 *v6; // eax@1
  int v7; // edx@1
  int v8; // eax@1
  int v9; // ecx@1
  int v10; // edx@1
  int v11; // ebx@1
  int v12; // eax@1
  signed int v13; // ebx@1
  int v14; // ebx@2
  signed __int64 v15; // qtt@3
  stru149 *v16; // eax@3
  signed int v17; // ebx@3
  Texture *v18; // eax@14
  unsigned __int16 *v19; // eax@15
  stru149 *v20; // eax@21
  signed int v21; // eax@21
  int v22; // eax@21
  int v23; // ecx@21
  Texture *v24; // edx@21
  signed int v25; // eax@21
  signed int v27; // [sp-4h] [bp-A4h]@8
  int v28; // [sp+Ch] [bp-94h]@1
  int v29; // [sp+10h] [bp-90h]@1
  stru316 a2; // [sp+14h] [bp-8Ch]@21
  stru315 a1; // [sp+3Ch] [bp-64h]@1
  int v32; // [sp+80h] [bp-20h]@1
  int v33; // [sp+84h] [bp-1Ch]@1
  int v34; // [sp+88h] [bp-18h]@1
  int v35; // [sp+8Ch] [bp-14h]@1
  int v36; // [sp+90h] [bp-10h]@1
  int v37; // [sp+94h] [bp-Ch]@1
  int v38; // [sp+98h] [bp-8h]@1
  int X; // [sp+9Ch] [bp-4h]@1

  v2 = _this;
  v3 = _this->pParent;
  v4 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterY - _this->field_A);
  v5 = v3->ptr_38;
  v38 = v4;
  v37 = v5->field_14;
  v38 = (unsigned __int64)(v37 * (signed __int64)v4) >> 16;
  v6 = v3->ptr_38;
  v7 = v38 + v6->field_C;
  v37 = v6->field_20;
  v33 = v7;
  v8 = ((unsigned __int64)(v37 * (signed __int64)v4) >> 16) + v3->ptr_38->field_18;
  v38 = v4;
  v34 = v8;
  v37 = v3->v_18.z;
  v38 = (unsigned __int64)(v37 * (signed __int64)v4) >> 16;
  v9 = v3->v_18.x;
  v28 = v3->sTextureDeltaU << 16;
  v35 = v3->sTextureDeltaV << 16;
  v10 = v2->field_8;
  v29 = pOutdoorCamera->camera_rotation_y_int_sine;
  v32 = pOutdoorCamera->camera_rotation_y_int_cosine;
  a1.field_28 = v2->field_C;
  v11 = v3->field_24;
  v37 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterX - v10);
  v12 = v3->v_18.y;
  v13 = -v11;
  v36 = v13;
  X = ((unsigned __int64)(v37 * (signed __int64)v12) >> 16) + v38 + v9;
  if ( !X || (v14 = abs(v13 >> 14), v14 > abs(X)) )
    return 0;
  LODWORD(v15) = v36 << 16;
  HIDWORD(v15) = v36 >> 16;
  v38 = v15 / X;
  v16 = v3->ptr_38;
  X = v37;
  v36 = v16->field_10;
  X = v37;
  v36 = v33 + ((unsigned __int64)(v36 * (signed __int64)v37) >> 16);
  v33 = v3->ptr_38->field_1C;
  X = (unsigned __int64)(v33 * (signed __int64)v37) >> 16;
  v34 += (unsigned __int64)(v33 * (signed __int64)v37) >> 16;
  v17 = 2;
  a1.pTextureLOD = (unsigned __int16 *)v3->pTexture->pLevelOfDetail2;
  if ( v38 >= mipmapping_building_mm1 << 16 )
  {
    if ( v38 >= mipmapping_building_mm2 << 16 )
    {
      if ( v38 >= mipmapping_building_mm3 << 16 )
      {
        if ( bUseLoResSprites )
          goto LABEL_12;
        v27 = 3;
      }
      else
      {
        v27 = 2;
      }
      v17 = v27;
      goto LABEL_12;
    }
    v17 = 1;
  }
  else
  {
    v17 = 0;
  }
LABEL_12:
  if ( v17 < (signed int)v3->ptr_48 )
    v17 = (signed int)v3->ptr_48;
  v18 = v3->pTexture;
  if ( v17 )
  {
    if ( v17 == 1 )
    {
      v19 = (unsigned __int16 *)v18->pLevelOfDetail1;
    }
    else
    {
      if ( v17 == 2 )
        v19 = (unsigned __int16 *)v18->pLevelOfDetail2;
      else
        v19 = (unsigned __int16 *)v18->pLevelOfDetail3;
    }
  }
  else
  {
    v19 = (unsigned __int16 *)v18->pLevelOfDetail0;
  }
  a1.pTextureLOD = v19;
  X = (unsigned __int64)(v36 * (signed __int64)v38) >> 16;
  v20 = v3->ptr_38;
  X = v38;
  a1.field_30 = v28 + ((unsigned __int64)(v36 * (signed __int64)v38) >> 16) - v20->field_24;
  X = (unsigned __int64)(v34 * (signed __int64)v38) >> 16;
  v21 = X - v3->ptr_38->field_28 - v35;
  a1.field_30 >>= v17 + bUseLoResSprites;
  a1.field_2C = v21 >> (v17 + bUseLoResSprites);
  v35 = pOutdoorCamera->int_fov_rad_inv;
  v37 = (signed int)((unsigned __int64)(pOutdoorCamera->int_fov_rad_inv * (signed __int64)v38) >> 16) >> (v17 + bUseLoResSprites);
  a1.field_4 = (unsigned __int64)(v37 * (signed __int64)v29) >> 16;
  X = (unsigned __int64)(v37 * (signed __int64)v32) >> 16;
  a1.field_0 = -(signed int)((unsigned __int64)(v37 * (signed __int64)v32) >> 16);
  v22 = v2->field_A;
  a1.pColorBuffer = &pRenderer->pTargetSurface[v2->field_8 + pRenderer->uTargetSurfacePitch * v2->field_A];
  HIWORD(v23) = HIWORD(v38);
  a1.pDepthBuffer = (unsigned int *)&pRenderer->pActiveZBuffer[v2->field_8 + 640 * v22];
  LOWORD(v23) = 0;
  a1.field_24 = v23 | v3->field_50;
  v24 = v3->pTexture;
  v32 = (signed int)v24->uTextureWidth >> v17;
  v25 = (signed int)v24->uTextureHeight >> v17;
  a1.field_10 = v17 - v24->uWidthLn2 + 16;
  a1.field_C = v32 - 1;
  a1.field_8 = (v25 << 16) - 65536;
  a1.field_34_palette = (unsigned __int16 *)sr_sub_485E1F(&a2, v2, v38, v3, pOutdoorCamera->building_gamme, 1u, 1);
  if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
    sr_sub_485975(&a1, (stru315 *)&a2);
  else
    sr_sub_4D6FB0(v1);
  return 1;
}

//----- (00482E07) --------------------------------------------------------
signed int __fastcall sr_sub_482E07(Span *ecx0, unsigned __int16 *pRenderTarget)
{
  stru315 *v2; // ebp@0
  stru148 *v3; // esi@1
  int v4; // edi@1
  int v5; // edi@1
  stru149 *v6; // eax@1
  stru149 *v7; // eax@1
  int v8; // edx@1
  int v9; // eax@1
  int v10; // edi@1
  int v11; // eax@1
  unsigned __int64 v12; // qax@1
  int v13; // eax@1
  signed __int64 v14; // qtt@3
  int v15; // ebx@4
  signed __int64 v16; // qtt@5
  int v17; // eax@5
  unsigned __int16 *v18; // eax@7
  Texture *v19; // eax@8
  Texture *v20; // eax@10
  Texture *v21; // eax@12
  Texture *v22; // eax@14
  int v23; // ecx@17
  Texture *v24; // ebx@17
  signed int v25; // edx@17
  signed int v26; // eax@17
  char v27; // bl@17
  stru149 *v28; // eax@18
  stru149 *v29; // eax@18
  int v30; // eax@18
  int v31; // eax@18
  unsigned int v32; // edx@18
  int v33; // edi@21
  signed __int64 v34; // qtt@22
  signed int v35; // ecx@22
  int v36; // eax@24
  stru149 *v37; // eax@24
  int v38; // edi@24
  int v39; // eax@24
  int v40; // edi@35
  signed __int64 v41; // qtt@36
  int v42; // edx@36
  stru149 *v43; // eax@36
  int v44; // edi@36
  int v45; // eax@36
  Span *v46; // edi@44
  stru149 *v47; // eax@44
  stru149 *v48; // eax@44
  int v49; // eax@44
  int v50; // ecx@44
  unsigned int v51; // edx@44
  int v52; // edi@46
  signed __int64 v53; // qtt@47
  unsigned int v54; // ecx@47
  int v55; // eax@49
  stru149 *v56; // eax@49
  int v57; // edi@49
  int v58; // eax@49
  int v59; // edi@60
  signed __int64 v60; // qtt@61
  int v61; // edx@61
  stru149 *v62; // eax@61
  int v63; // edi@61
  int v64; // eax@61
  int v66; // [sp+Ch] [bp-B8h]@1
  int v67; // [sp+10h] [bp-B4h]@1
  int v68; // [sp+14h] [bp-B0h]@1
  int v69; // [sp+18h] [bp-ACh]@1
  int v70; // [sp+1Ch] [bp-A8h]@5
  int v71; // [sp+20h] [bp-A4h]@1
  signed int v72; // [sp+24h] [bp-A0h]@1
  stru316 a2; // [sp+28h] [bp-9Ch]@18
  int v74; // [sp+50h] [bp-74h]@17
  stru315 a1; // [sp+54h] [bp-70h]@5
  Span *v76; // [sp+98h] [bp-2Ch]@1
  unsigned __int16 *v77; // [sp+9Ch] [bp-28h]@1
  int v78; // [sp+A0h] [bp-24h]@17
  int v79; // [sp+A4h] [bp-20h]@3
  int v80; // [sp+A8h] [bp-1Ch]@3
  int v81; // [sp+ACh] [bp-18h]@1
  int X; // [sp+B0h] [bp-14h]@2
  int v83; // [sp+B4h] [bp-10h]@1
  int v84; // [sp+B8h] [bp-Ch]@1
  int v85; // [sp+BCh] [bp-8h]@1
  int v86; // [sp+C0h] [bp-4h]@18

  v85 = ecx0->field_C;
  v3 = ecx0->pParent;
  v4 = pViewport->uScreenCenterY - ecx0->field_A;
  v77 = pRenderTarget;
  v5 = pOutdoorCamera->int_fov_rad_inv * v4;
  v6 = v3->ptr_38;
  v76 = ecx0;
  v81 = v5;
  v83 = v6->field_14;
  v81 = (unsigned __int64)(v83 * (signed __int64)v5) >> 16;
  v7 = v3->ptr_38;
  v8 = v81 + v7->field_C;
  v83 = v7->field_20;
  v67 = v8;
  v9 = ((unsigned __int64)(v83 * (signed __int64)v5) >> 16) + v3->ptr_38->field_18;
  v81 = v5;
  v71 = v9;
  v83 = v3->v_18.z;
  v81 = (unsigned __int64)(v83 * (signed __int64)v5) >> 16;
  v68 = v3->sTextureDeltaU << 16;
  v69 = v3->sTextureDeltaV << 16;
  v72 = -v3->field_24;
  v10 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterX - ecx0->field_8);
  v11 = v3->v_18.y;
  v66 = v81 + v3->v_18.x;
  v83 = v10;
  v12 = v10 * (signed __int64)v11;
  v81 = v12 >> 16;
  v13 = v66 + (v12 >> 16);
  v84 = v13;
  if ( !v13
    || (X = v72 >> 15, v83 = abs(v13), abs(v72 >> 15) >= v83)
    || (LODWORD(v14) = v72 << 16,
        HIDWORD(v14) = v72 >> 16,
        v79 = v14 / v84,
        v80 = v10 - v85 * pOutdoorCamera->int_fov_rad_inv,
        v81 = (unsigned __int64)(v80 * (signed __int64)v3->v_18.y) >> 16,
        (v84 = v66 + v81) == 0)
    || (v15 = abs(v66 + v81), abs(X) >= v15) )
    return 0;
  LODWORD(v16) = v72 << 16;
  HIDWORD(v16) = v72 >> 16;
  v70 = v16 / v84;
  v17 = v16 / v84;
  a1.field_24 = v79;
  if ( v79 >= v17 )
    a1.field_24 = v17;
  v18 = (unsigned __int16 *)v3->pTexture->pLevelOfDetail2;
  a1.pTextureLOD = (unsigned __int16 *)v3->pTexture->pLevelOfDetail2;
  v84 = 2;
  if ( a1.field_24 >= mipmapping_building_mm1 << 16 )
  {
    if ( a1.field_24 >= mipmapping_building_mm2 << 16 )
    {
      if ( a1.field_24 >= mipmapping_building_mm3 << 16 )
      {
        if ( bUseLoResSprites )
          goto LABEL_16;
        v22 = v3->pTexture;
        v84 = 3;
        v18 = (unsigned __int16 *)v22->pLevelOfDetail3;
      }
      else
      {
        v21 = v3->pTexture;
        v84 = 2;
        v18 = (unsigned __int16 *)v21->pLevelOfDetail2;
      }
    }
    else
    {
      v20 = v3->pTexture;
      v84 = 1;
      v18 = (unsigned __int16 *)v20->pLevelOfDetail1;
    }
  }
  else
  {
    v19 = v3->pTexture;
    v84 = 0;
    v18 = (unsigned __int16 *)v19->pLevelOfDetail0;
  }
  a1.pTextureLOD = v18;
LABEL_16:
  if ( v18 )
  {
    v23 = v3->field_5A;
    v83 = v3->field_52;
    v24 = v3->pTexture;
    v74 = v23;
    v78 = v85 >> v23;
    v25 = v24->uTextureWidth;
    v81 = v85 - (v85 >> v23 << v23);
    v26 = (signed int)v24->uTextureHeight >> v84;
    a1.field_10 = v84 - v24->uWidthLn2 + 16;
    v27 = v84 + bUseLoResSprites;
    a1.field_8 = (v26 << 16) - 65536;
    a1.field_C = (v25 >> v84) - 1;
    if ( v79 >= v70 )
    {
      v46 = v76;
      a1.field_34_palette = (unsigned __int16 *)sr_sub_485E1F(&a2, v76, v70, v3, pOutdoorCamera->building_gamme, 0, 1);
      v47 = v3->ptr_38;
      v79 = v80;
      v86 = v47->field_10;
      v79 = v80;
      v84 = v67 + ((unsigned __int64)(v86 * (signed __int64)v80) >> 16);
      v86 = v3->ptr_38->field_1C;
      v86 = v71 + ((unsigned __int64)(v86 * (signed __int64)v80) >> 16);
      v79 = (unsigned __int64)(v84 * (signed __int64)v70) >> 16;
      v48 = v3->ptr_38;
      v79 = v70;
      a1.field_30 = v68 + ((unsigned __int64)(v84 * (signed __int64)v70) >> 16) - v48->field_24;
      v79 = (unsigned __int64)(v86 * (signed __int64)v70) >> 16;
      v49 = ((unsigned __int64)(v86 * (signed __int64)v70) >> 16) - v3->ptr_38->field_28;
      a1.field_30 >>= v27;
      a1.field_2C = (v69 + v49) >> v27;
      a1.field_14 = dword_80AA20 >> v27;
      a1.field_18 = dword_80AA1C >> v27;
      a1.field_1C = dword_80AA18 >> v27;
      v50 = v46->field_8;
      a1.field_20 = dword_80AA14 >> v27;
      v51 = v50 + pRenderer->uTargetSurfacePitch * v46->field_A;
      a1.pDepthBuffer = (unsigned int *)(&pRenderer->pActiveZBuffer[640 * v46->field_A - 1] + v85 + v50);
      a1.pColorBuffer = &v77[v85 - 1] + v51;
      v80 += pOutdoorCamera->int_fov_rad_inv << v74;
      if ( v78 > 0 )
      {
        do
        {
          v77 = (unsigned __int16 *)v3->v_18.y;
          v86 = (unsigned __int64)((signed int)v77 * (signed __int64)v80) >> 16;
          v84 = v66 + ((unsigned __int64)((signed int)v77 * (signed __int64)v80) >> 16);
          if ( v66 + (unsigned int)((unsigned __int64)((signed int)v77 * (signed __int64)v80) >> 16)
            && (v52 = abs((signed __int64)v66 + ((__int64)((signed int)v77 * (signed __int64)v80) >> 16)), abs((signed __int64)X) < v52) )
          {
            LODWORD(v53) = v72 << 16;
            HIDWORD(v53) = v72 >> 16;
            v86 = v53 / v84;
            v54 = v53 / v84;
            v84 = v53 / v84;
          }
          else
          {
            v84 = 0x40000000u;
            v54 = 0x40000000u;
          }
          HIWORD(v55) = HIWORD(v54);
          LOWORD(v55) = 0;
          a1.field_24 = v3->field_50 | v55;
          v77 = (unsigned __int16 *)v3->ptr_38->field_10;
          v77 = (unsigned __int16 *)(v67 + ((unsigned __int64)((signed int)v77 * (signed __int64)v80) >> 16));
          v86 = (unsigned __int64)((signed int)v77 * (signed __int64)(signed int)v54) >> 16;
          v56 = v3->ptr_38;
          v57 = ((unsigned __int64)((signed int)v77 * (signed __int64)(signed int)v54) >> 16) - v56->field_24;
          v77 = (unsigned __int16 *)v56->field_1C;
          v77 = (unsigned __int16 *)(v71 + ((unsigned __int64)((signed int)v77 * (signed __int64)v80) >> 16));
          v86 = (unsigned __int64)((signed int)v77 * (signed __int64)(signed int)v54) >> 16;
          v58 = (((v69 + v86 - v3->ptr_38->field_28) >> v27) - a1.field_2C) >> v74;
          a1.field_4 = (((v68 + v57) >> v27) - a1.field_30) >> v74;
          a1.field_0 = v58;
          a1.field_28 = v83;
          if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
          {
            if ( v3->pODMFace->uPolygonType == 1 )
              sr_sub_485BAE(&a1, &a2);
            else
              sr_sub_485AFF(&a1, &a2);
          }
          else
          {
            if ( v3->pODMFace->uPolygonType == 1 )
              sr_sub_4D71F8(&a1);
            else
              sr_sub_4D714C(&a1);
          }
          a1.field_34_palette = (unsigned __int16 *)sr_sub_485E1F(
                                                      &a2,
                                                      v76,
                                                      v84,
                                                      v3,
                                                      pOutdoorCamera->building_gamme,
                                                      0,
                                                      0);
          v80 += pOutdoorCamera->int_fov_rad_inv << v74;
          --v78;
        }
        while ( v78 );
      }
      if ( !v81 )
        return 1;
      v83 = v3->v_18.y;
      v86 = (unsigned __int64)(v83 * (signed __int64)v80) >> 16;
      v84 = v66 + ((unsigned __int64)(v83 * (signed __int64)v80) >> 16);
      if ( v66 + (unsigned int)((unsigned __int64)(v83 * (signed __int64)v80) >> 16) )
      {
        v59 = abs((signed __int64)v66 + ((__int64)(v83 * (signed __int64)v80) >> 16));
        if ( abs(X) < v59 )
        {
          LODWORD(v60) = v72 << 16;
          HIDWORD(v60) = v72 >> 16;
          v86 = v60 / v84;
          HIWORD(v61) = (unsigned int)(v60 / v84) >> 16;
          LOWORD(v61) = 0;
          a1.field_24 = v61 | v3->field_50;
          v83 = v3->ptr_38->field_10;
          v83 = v67 + ((unsigned __int64)(v83 * (signed __int64)v80) >> 16);
          v86 = (unsigned __int64)(v83 * v60 / v84) >> 16;
          v62 = v3->ptr_38;
          v63 = ((unsigned __int64)(v83 * v60 / v84) >> 16) - v62->field_24;
          v83 = v62->field_1C;
          v83 = v71 + ((unsigned __int64)(v83 * (signed __int64)v80) >> 16);
          v86 = (unsigned __int64)(v83 * v60 / v84) >> 16;
          v64 = (((signed int)(v69 + ((unsigned __int64)(v83 * v60 / v84) >> 16) - v3->ptr_38->field_28) >> v27)
               - a1.field_2C) >> v74;
          a1.field_4 = (((v68 + v63) >> v27) - a1.field_30) >> v74;
          a1.field_0 = v64;
          a1.field_28 = v81;
          if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
          {
            if ( v3->pODMFace->uPolygonType == 1 )
              sr_sub_485BAE(&a1, &a2);
            else
              sr_sub_485AFF(&a1, &a2);
          }
          else
          {
            if ( v3->pODMFace->uPolygonType == 1 )
              sr_sub_4D71F8(&a1);
            else
              sr_sub_4D714C(&a1);
          }
          return 1;
        }
      }
    }
    else
    {
      a1.field_34_palette = (unsigned __int16 *)sr_sub_485E1F(&a2, v76, v79, v3, pOutdoorCamera->building_gamme, 1u, 1);
      v28 = v3->ptr_38;
      v85 = v10;
      v86 = v28->field_10;
      v85 = v10;
      v84 = v67 + ((unsigned __int64)(v86 * (signed __int64)v10) >> 16);
      v86 = v3->ptr_38->field_1C;
      v86 = v71 + ((unsigned __int64)(v86 * (signed __int64)v10) >> 16);
      v85 = (unsigned __int64)(v84 * (signed __int64)v79) >> 16;
      v29 = v3->ptr_38;
      v85 = v79;
      a1.field_30 = v68 + ((unsigned __int64)(v84 * (signed __int64)v79) >> 16) - v29->field_24;
      v85 = (unsigned __int64)(v86 * (signed __int64)v79) >> 16;
      v30 = ((unsigned __int64)(v86 * (signed __int64)v79) >> 16) - v3->ptr_38->field_28;
      a1.field_30 >>= v27;
      a1.field_2C = (v69 + v30) >> v27;
      a1.field_14 = dword_80AA20 >> v27;
      a1.field_18 = dword_80AA1C >> v27;
      a1.field_1C = dword_80AA18 >> v27;
      a1.field_20 = dword_80AA14 >> v27;
      v31 = v76->field_A;
      v32 = pRenderer->uTargetSurfacePitch * v76->field_A;
      v86 = v76->field_8;
      a1.pColorBuffer = &v77[v86 + v32];
      a1.pDepthBuffer = (unsigned int *)&pRenderer->pActiveZBuffer[v86 + 640 * v31];
      v80 = v10 - (pOutdoorCamera->int_fov_rad_inv << v74);
      if ( v78 > 0 )
      {
        v86 = v78;
        do
        {
          v78 = v3->v_18.y;
          v85 = (unsigned __int64)(v78 * (signed __int64)v80) >> 16;
          v84 = v66 + ((unsigned __int64)(v78 * (signed __int64)v80) >> 16);
          if ( v66 + (unsigned int)((unsigned __int64)(v78 * (signed __int64)v80) >> 16)
            && (v33 = abs((signed __int64)v66 + ((__int64)(v78 * (signed __int64)v80) >> 16)), abs((signed __int64)X) < v33) )
          {
            LODWORD(v34) = v72 << 16;
            HIDWORD(v34) = v72 >> 16;
            v85 = v34 / v84;
            v35 = v34 / v84;
            v84 = v34 / v84;
          }
          else
          {
            v84 = 1073741824;
            v35 = 1073741824;
          }
          HIWORD(v36) = HIWORD(v35);
          LOWORD(v36) = 0;
          a1.field_24 = v3->field_50 | v36;
          v78 = v3->ptr_38->field_10;
          v78 = v67 + ((unsigned __int64)(v78 * (signed __int64)v80) >> 16);
          v85 = (unsigned __int64)(v78 * (signed __int64)v35) >> 16;
          v37 = v3->ptr_38;
          v38 = ((unsigned __int64)(v78 * (signed __int64)v35) >> 16) - v37->field_24;
          v78 = v37->field_1C;
          v78 = v71 + ((unsigned __int64)(v78 * (signed __int64)v80) >> 16);
          v85 = (unsigned __int64)(v78 * (signed __int64)v35) >> 16;
          v39 = (((v69 + v85 - v3->ptr_38->field_28) >> v27) - a1.field_2C) >> v74;
          a1.field_4 = (((v68 + v38) >> v27) - a1.field_30) >> v74;
          a1.field_0 = v39;
          a1.field_28 = v83;
          if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
          {
            if ( v3->pODMFace->uPolygonType == 1 )
              sr_sub_485A24(&a1, (stru315 *)&a2);
            else
              sr_sub_485975(&a1, (stru315 *)&a2);
          }
          else
          {
            if ( v3->pODMFace->uPolygonType == 1 )
              sr_sub_4D705A(v2);
            else
              sr_sub_4D6FB0(v2);
          }
          a1.field_34_palette = (unsigned __int16 *)sr_sub_485E1F(
                                                      &a2,
                                                      v76,
                                                      v84,
                                                      v3,
                                                      pOutdoorCamera->building_gamme,
                                                      1u,
                                                      0);
          v80 -= pOutdoorCamera->int_fov_rad_inv << v74;
          --v86;
        }
        while ( v86 );
      }
      if ( !v81 )
        return 1;
      v83 = v3->v_18.y;
      v76 = (Span *)((unsigned __int64)(v83 * (signed __int64)v80) >> 16);
      v84 = v66 + ((unsigned __int64)(v83 * (signed __int64)v80) >> 16);
      if ( v66 + (unsigned int)((unsigned __int64)(v83 * (signed __int64)v80) >> 16) )
      {
        v40 = abs((signed __int64)v66 + ((__int64)(v83 * (signed __int64)v80) >> 16));
        if ( abs(X) < v40 )
        {
          LODWORD(v41) = v72 << 16;
          HIDWORD(v41) = v72 >> 16;
          X = v41 / v84;
          HIWORD(v42) = (unsigned int)(v41 / v84) >> 16;
          LOWORD(v42) = 0;
          a1.field_24 = v42 | v3->field_50;
          v83 = v3->ptr_38->field_10;
          v83 = v67 + ((unsigned __int64)(v83 * (signed __int64)v80) >> 16);
          X = (unsigned __int64)(v83 * v41 / v84) >> 16;
          v43 = v3->ptr_38;
          v44 = ((unsigned __int64)(v83 * v41 / v84) >> 16) - v43->field_24;
          v83 = v43->field_1C;
          v83 = v71 + ((unsigned __int64)(v83 * (signed __int64)v80) >> 16);
          X = (unsigned __int64)(v83 * v41 / v84) >> 16;
          v45 = (((signed int)(v69 + ((unsigned __int64)(v83 * v41 / v84) >> 16) - v3->ptr_38->field_28) >> v27)
               - a1.field_2C) >> v74;
          a1.field_4 = (((v68 + v44) >> v27) - a1.field_30) >> v74;
          a1.field_0 = v45;
          a1.field_28 = v81;
          if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
          {
            if ( v3->pODMFace->uPolygonType == 1 )
              sr_sub_485A24(&a1, (stru315 *)&a2);
            else
              sr_sub_485975(&a1, (stru315 *)&a2);
          }
          else
          {
            if ( v3->pODMFace->uPolygonType == 1 )
              sr_sub_4D705A(v2);
            else
              sr_sub_4D6FB0(v2);
          }
          return 1;
        }
      }
    }
  }
  return 0;
}
// 4D864C: using guessed type char byte_4D864C;
// 6BE0E4: using guessed type int mipmapping_building_mm1;
// 6BE0E8: using guessed type int mipmapping_building_mm2;
// 6BE0EC: using guessed type int mipmapping_building_mm3;
// 80AA14: using guessed type int dword_80AA14;
// 80AA18: using guessed type int dword_80AA18;
// 80AA1C: using guessed type int dword_80AA1C;
// 80AA20: using guessed type int dword_80AA20;

//----- (004839BD) --------------------------------------------------------
signed int __fastcall sr_sub_4839BD(Span *ecx0, unsigned __int16 *pTargetSurface)
{
  stru315 *v2; // ebp@0
  int v3; // eax@1
  int v4; // edi@1
  stru148 *v5; // esi@1
  unsigned int v6; // ebx@1
  int v7; // ecx@1
  int v8; // ebx@1
  int v9; // ecx@1
  int v10; // eax@1
  stru149 *v11; // eax@1
  int v12; // edx@1
  int v13; // eax@1
  int v14; // edi@1
  int v15; // ecx@1
  int v16; // eax@1
  signed int v17; // edi@1
  int v18; // edi@2
  signed __int64 v19; // qtt@3
  int v20; // edi@3
  unsigned __int16 *v21; // eax@3
  Texture *v22; // eax@4
  Texture *v23; // eax@6
  Texture *v24; // eax@8
  Texture *v25; // eax@10
  stru149 *v26; // eax@13
  int v27; // edi@13
  signed int v28; // edx@13
  Texture *v29; // ebx@13
  int v30; // edi@13
  signed int v31; // edx@13
  signed int v32; // eax@13
  signed int v33; // eax@13
  int v34; // ebx@13
  int v35; // eax@15
  int v36; // ebx@15
  int v37; // eax@16
  signed __int64 v38; // qtt@17
  int v39; // ecx@17
  int v40; // eax@19
  stru149 *v41; // eax@21
  int v42; // ebx@21
  int v43; // ebx@21
  int v44; // eax@21
  char v45; // zf@25
  int v46; // eax@28
  int v47; // eax@28
  int v48; // ebx@28
  int v49; // eax@29
  signed __int64 v50; // qtt@30
  int v51; // ecx@30
  int v52; // eax@30
  int v53; // edx@31
  stru149 *v54; // eax@33
  int v55; // ebx@33
  signed int v56; // ebx@33
  int v57; // eax@33
  unsigned __int64 v58; // qax@33
  int v60; // [sp+Ch] [bp-BCh]@1
  Span *v61; // [sp+10h] [bp-B8h]@1
  int v62; // [sp+14h] [bp-B4h]@2
  int v63; // [sp+18h] [bp-B0h]@1
  stru315 a1; // [sp+1Ch] [bp-ACh]@1
  stru316 a2; // [sp+60h] [bp-68h]@13
  int v66; // [sp+88h] [bp-40h]@13
  int v67; // [sp+8Ch] [bp-3Ch]@1
  int v68; // [sp+90h] [bp-38h]@13
  int v69; // [sp+94h] [bp-34h]@3
  int v70; // [sp+98h] [bp-30h]@1
  int v71; // [sp+9Ch] [bp-2Ch]@1
  int v72; // [sp+A0h] [bp-28h]@1
  int v73; // [sp+A4h] [bp-24h]@13
  int v74; // [sp+A8h] [bp-20h]@1
  int v75; // [sp+ACh] [bp-1Ch]@3
  int v76; // [sp+B0h] [bp-18h]@1
  int v77; // [sp+B4h] [bp-14h]@1
  int X; // [sp+B8h] [bp-10h]@1
  int v79; // [sp+BCh] [bp-Ch]@21
  int v80; // [sp+C0h] [bp-8h]@13
  unsigned int v81; // [sp+C4h] [bp-4h]@1

  v3 = ecx0->field_A;
  v4 = ecx0->field_8;
  v5 = ecx0->pParent;
  v6 = v4 + pRenderer->uTargetSurfacePitch * ecx0->field_A;
  v61 = ecx0;
  v7 = ecx0->field_C;
  a1.pColorBuffer = &pTargetSurface[v6];
  v74 = v7;
  a1.pDepthBuffer = (unsigned int *)&pRenderer->pActiveZBuffer[v4 + 640 * v3];
  v8 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterX - v4);
  v9 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterY - v3);
  v10 = v5->ptr_38->field_14;
  v76 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterX - v4);
  v72 = v10;
  v81 = (unsigned __int64)(v10 * (signed __int64)v9) >> 16;
  v11 = v5->ptr_38;
  v12 = v81 + v11->field_C;
  v72 = v11->field_20;
  v67 = v12;
  v13 = ((unsigned __int64)(v72 * (signed __int64)v9) >> 16) + v5->ptr_38->field_18;
  v81 = v9;
  v70 = v13;
  v72 = v5->v_18.z;
  v81 = (unsigned __int64)(v72 * (signed __int64)v9) >> 16;
  v14 = v5->field_24;
  v15 = v81 + v5->v_18.x;
  v71 = v5->sTextureDeltaU << 16;
  v63 = v5->sTextureDeltaV << 16;
  v16 = v5->v_18.y;
  v17 = -v14;
  v60 = v15;
  v77 = v17;
  v81 = (unsigned __int64)(v76 * (signed __int64)v16) >> 16;
  X = v81 + v15;
  if ( !(v81 + v15) || (v62 = v17 >> 14, v18 = abs(v17 >> 14), v18 > abs(X)) )
    return 0;
  LODWORD(v19) = v77 << 16;
  HIDWORD(v19) = v77 >> 16;
  v69 = v19 / X;
  v20 = v19 / X;
  v21 = (unsigned __int16 *)v5->pTexture->pLevelOfDetail2;
  a1.pTextureLOD = (unsigned __int16 *)v5->pTexture->pLevelOfDetail2;
  v75 = 2;
  if ( v20 >= mipmapping_building_mm1 << 16 )
  {
    if ( v20 >= mipmapping_building_mm2 << 16 )
    {
      if ( v20 >= mipmapping_building_mm3 << 16 )
      {
        if ( bUseLoResSprites )
          goto LABEL_12;
        v25 = v5->pTexture;
        v75 = 3;
        v21 = (unsigned __int16 *)v25->pLevelOfDetail3;
      }
      else
      {
        v24 = v5->pTexture;
        v75 = 2;
        v21 = (unsigned __int16 *)v24->pLevelOfDetail2;
      }
    }
    else
    {
      v23 = v5->pTexture;
      v75 = 1;
      v21 = (unsigned __int16 *)v23->pLevelOfDetail1;
    }
  }
  else
  {
    v22 = v5->pTexture;
    v75 = 0;
    v21 = (unsigned __int16 *)v22->pLevelOfDetail0;
  }
  a1.pTextureLOD = v21;
LABEL_12:
  if ( v21 )
  {
    a1.field_34_palette = (unsigned __int16 *)sr_sub_485E1F(&a2, v61, v20, v5, pOutdoorCamera->building_gamme, 1u, 1);
    a1.field_28 = 16;
    v66 = v74 >> 4;
    v81 = v8;
    v26 = v5->ptr_38;
    v72 = v74 - 16 * (v74 >> 4);
    v76 = v26->field_10;
    v81 = v8;
    v74 = v67 + ((unsigned __int64)(v76 * (signed __int64)v8) >> 16);
    v76 = v5->ptr_38->field_1C;
    v76 = v70 + ((unsigned __int64)(v76 * (signed __int64)v8) >> 16);
    v81 = (unsigned __int64)(v74 * (signed __int64)v20) >> 16;
    v27 = ((unsigned __int64)(v74 * (signed __int64)v20) >> 16) - v5->ptr_38->field_24;
    v81 = (unsigned __int64)(v76 * (signed __int64)v69) >> 16;
    v28 = v63 + ((unsigned __int64)(v76 * (signed __int64)v69) >> 16) - v5->ptr_38->field_28;
    v76 = v75 + bUseLoResSprites;
    v73 = v8 - 16 * pOutdoorCamera->int_fov_rad_inv;
    v29 = v5->pTexture;
    v30 = (v71 + v27) >> v76;
    v31 = v28 >> v76;
    v32 = (signed int)v29->uTextureWidth >> v75;
    v74 = (signed __int16)v75;
    v68 = v31;
    v80 = v32;
    v33 = (signed int)v29->uTextureHeight >> v75;
    v34 = v75 - v29->uWidthLn2;
    a1.field_8 = (v33 << 16) - 65536;
    v81 = 2 * pMiscTimer->uTotalGameTimeElapsed;
    a1.field_10 = v34 + 16;
    a1.field_C = v80 - 1;
    if ( v66 > 0 )
    {
      v74 = v66;
      v66 = 12 - v75;
      do
      {
        v80 = v5->v_18.y;
        v35 = (unsigned __int64)(v80 * (signed __int64)v73) >> 16;
        v36 = v35 + v60;
        X = v35 + v60;
        if ( v35 + v60 && (v80 = abs(v62), v37 = abs(v36), v80 <= v37) )
        {
          LODWORD(v38) = v77 << 16;
          HIDWORD(v38) = v77 >> 16;
          v80 = v38 / X;
          v39 = v38 / X;
          X = v38 / X;
        }
        else
        {
          X = 0x40000000u;
          v39 = 0x40000000u;
        }
        HIWORD(v40) = HIWORD(v39);
        if ( v39 <= v69 )
          HIWORD(v40) = HIWORD(v69);
        LOWORD(v40) = 0;
        a1.field_24 = v5->field_50 | v40;
        v79 = v5->ptr_38->field_10;
        v79 = v67 + ((unsigned __int64)(v79 * (signed __int64)v73) >> 16);
        v80 = (unsigned __int64)(v79 * (signed __int64)v39) >> 16;
        v41 = v5->ptr_38;
        v42 = ((unsigned __int64)(v79 * (signed __int64)v39) >> 16) - v41->field_24;
        v79 = v41->field_1C;
        v79 = v70 + ((unsigned __int64)(v79 * (signed __int64)v73) >> 16);
        v80 = (unsigned __int64)(v79 * (signed __int64)v39) >> 16;
        v43 = (v71 + v42) >> v76;
        v79 = (signed int)(v63 + ((unsigned __int64)(v79 * (signed __int64)v39) >> 16) - v5->ptr_38->field_28) >> v76;
        a1.field_4 = (v43 - v30) >> 4;
        a1.field_0 = (v79 - v68) >> 4;
        a1.field_30 = v30 + 4 * stru_5C6E00->SinCos(v81 + (v68 >> v66));
        v44 = stru_5C6E00->SinCos(v81 + (v30 >> v66) - stru_5C6E00->uIntegerHalfPi);
        a1.field_2C = v68 + 4 * v44;
        if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
          sr_sub_485975(&a1, (stru315 *)&a2);
        else
          sr_sub_4D6FB0(v2);
        a1.field_34_palette = (unsigned __int16 *)sr_sub_485E1F(&a2, v61, X, v5, pOutdoorCamera->building_gamme, 1u, 0);
        v73 -= 16 * pOutdoorCamera->int_fov_rad_inv;
        v45 = v74-- == 1;
        a1.field_28 = 16;
        v30 = v43;
        v68 = v79;
      }
      while ( !v45 );
      v31 = v79;
    }
    if ( !v72 )
      return 1;
    v66 = 12 - v75;
    a1.field_30 = v30 + 4 * stru_5C6E00->SinCos(v81 + (v31 >> (12 - v75)));
    v46 = stru_5C6E00->SinCos(v81 + (v30 >> v66) - stru_5C6E00->uIntegerHalfPi);
    a1.field_2C = v68 + 4 * v46;
    v79 = v5->v_18.y;
    v80 = (unsigned __int64)(v79 * (signed __int64)v73) >> 16;
    v47 = (unsigned __int64)(v79 * (signed __int64)v73) >> 16;
    v48 = v47 + v60;
    X = v47 + v60;
    if ( v47 + v60 )
    {
      v79 = abs(v62);
      v49 = abs(v48);
      if ( v79 <= v49 )
      {
        LODWORD(v50) = v77 << 16;
        HIDWORD(v50) = v77 >> 16;
        v77 = v50 / X;
        v51 = v50 / X;
        HIWORD(v52) = HIWORD(v69);
        if ( v51 <= v69 )
        {
          LOWORD(v52) = 0;
          a1.field_24 = v52 | v5->field_50;
        }
        else
        {
          HIWORD(v53) = HIWORD(v51);
          LOWORD(v53) = 0;
          a1.field_24 = v53 | v5->field_50;
        }
        v79 = v5->ptr_38->field_10;
        v77 = (unsigned __int64)(v79 * (signed __int64)v73) >> 16;
        v79 = v67 + ((unsigned __int64)(v79 * (signed __int64)v73) >> 16);
        v67 = (unsigned __int64)(v79 * (signed __int64)v51) >> 16;
        v54 = v5->ptr_38;
        v55 = v67 - v54->field_24;
        v79 = v54->field_1C;
        v56 = v71 + v55;
        v71 = (unsigned __int64)(v79 * (signed __int64)v73) >> 16;
        v57 = v70 + ((unsigned __int64)(v79 * (signed __int64)v73) >> 16);
        v79 = v57;
        v58 = v57 * (signed __int64)v51;
        v70 = v58 >> 16;
        LODWORD(v58) = (signed int)(v63 + (v58 >> 16) - v5->ptr_38->field_28) >> v76;
        a1.field_4 = ((v56 >> v76) - v30) >> 4;
        a1.field_0 = ((signed int)v58 - v68) >> 4;
        a1.field_28 = v72;
        if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
          sr_sub_485975(&a1, (stru315 *)&a2);
        else
          sr_sub_4D6FB0(v2);
        return 1;
      }
    }
  }
  return 0;
}
// 4D864C: using guessed type char byte_4D864C;
// 6BE0E4: using guessed type int mipmapping_building_mm1;
// 6BE0E8: using guessed type int mipmapping_building_mm2;
// 6BE0EC: using guessed type int mipmapping_building_mm3;



//----- (0048408A) --------------------------------------------------------
signed int sr_sub_48408A_prolly_odm_water_no_waves(Span *_this)
{
  stru315 *v1; // ebp@0
  Span *v2; // edi@1
  stru148 *v3; // esi@1
  int v4; // ecx@1
  stru149 *v5; // eax@1
  stru149 *v6; // eax@1
  int v7; // edx@1
  int v8; // eax@1
  int v9; // ebx@1
  int v10; // eax@1
  int v11; // ecx@1
  int v12; // eax@1
  int v13; // ecx@1
  int v14; // eax@1
  signed int v15; // ecx@1
  int v16; // ebx@1
  signed __int64 v17; // qtt@3
  stru149 *v18; // eax@3
  int v19; // ebx@3
  Texture *v20; // eax@4
  unsigned __int16 *v21; // eax@4
  Texture *v22; // eax@6
  Texture *v23; // ecx@8
  Texture *v24; // eax@10
  stru149 *v25; // eax@12
  signed int v26; // eax@12
  int v27; // ecx@12
  int v28; // eax@14
  int v29; // edx@14
  int v30; // ecx@14
  Texture *v31; // esi@14
  int v32; // edx@14
  int v33; // eax@14
  int v35; // [sp+Ch] [bp-8Ch]@1
  int v36; // [sp+10h] [bp-88h]@1
  stru316 a2; // [sp+14h] [bp-84h]@14
  stru315 a1; // [sp+3Ch] [bp-5Ch]@1
  int v39; // [sp+80h] [bp-18h]@1
  int v40; // [sp+84h] [bp-14h]@1
  int v41; // [sp+88h] [bp-10h]@1
  int v42; // [sp+8Ch] [bp-Ch]@1
  int v43; // [sp+90h] [bp-8h]@2
  int v44; // [sp+94h] [bp-4h]@1

  v2 = _this;
  v3 = _this->pParent;
  v4 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterY - _this->field_A);
  v5 = v3->ptr_38;
  v44 = v4;
  v42 = v5->field_14;
  v44 = (unsigned __int64)(v42 * (signed __int64)v4) >> 16;
  v6 = v3->ptr_38;
  v7 = v44 + v6->field_C;
  v42 = v6->field_20;
  v39 = v7;
  v8 = ((unsigned __int64)(v42 * (signed __int64)v4) >> 16) + v3->ptr_38->field_18;
  v44 = v4;
  v41 = v8;
  v42 = v3->v_18.z;
  v44 = (unsigned __int64)(v42 * (signed __int64)v4) >> 16;
  v9 = v44 + v3->v_18.x;
  v35 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY - stru_5C6E00->uIntegerHalfPi);
  v10 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY);
  v11 = v2->field_8;
  v36 = v10;
  a1.field_28 = v2->field_C;
  v12 = pViewport->uScreenCenterX - v11;
  v13 = v3->field_24;
  v42 = pOutdoorCamera->int_fov_rad_inv * v12;
  v14 = v3->v_18.y;
  v15 = -v13;
  v40 = v15;
  v16 = ((unsigned __int64)(v42 * (signed __int64)v14) >> 16) + v9;
  v44 = v16;
  if ( !v16 || (v43 = abs(v15 >> 14), v43 > abs(v16)) )
    return 0;
  LODWORD(v17) = v40 << 16;
  HIDWORD(v17) = v40 >> 16;
  v43 = v17 / v44;
  v18 = v3->ptr_38;
  v44 = v42;
  v40 = v18->field_10;
  v44 = v42;
  v40 = v39 + ((unsigned __int64)(v40 * (signed __int64)v42) >> 16);
  v39 = v3->ptr_38->field_1C;
  v44 = (unsigned __int64)(v39 * (signed __int64)v42) >> 16;
  v19 = v43;
  v41 += (unsigned __int64)(v39 * (signed __int64)v42) >> 16;
  a1.pTextureLOD = (unsigned __int16 *)v3->pTexture->pLevelOfDetail2;
  v44 = 2;
  if ( v43 < mipmapping_terrain_mm1 << 16 )
  {
    v20 = v3->pTexture;
    v44 = 0;
    v21 = (unsigned __int16 *)v20->pLevelOfDetail0;
LABEL_11:
    a1.pTextureLOD = v21;
    goto LABEL_12;
  }
  if ( v43 < mipmapping_terrain_mm2 << 16 )
  {
    v22 = v3->pTexture;
    v44 = 1;
    v21 = (unsigned __int16 *)v22->pLevelOfDetail1;
    goto LABEL_11;
  }
  if ( v43 >= mipmapping_terrain_mm3 << 16 )
  {
    if ( !bUseLoResSprites )
    {
      v24 = v3->pTexture;
      v44 = 3;
      v21 = (unsigned __int16 *)v24->pLevelOfDetail3;
      goto LABEL_11;
    }
  }
  else
  {
    v23 = v3->pTexture;
    v44 = 2;
    a1.pTextureLOD = (unsigned __int16 *)v23->pLevelOfDetail2;
  }
LABEL_12:
  v43 = (unsigned __int64)(v40 * (signed __int64)v43) >> 16;
  v25 = v3->ptr_38;
  v43 = v19;
  a1.field_30 = ((unsigned __int64)(v40 * (signed __int64)v19) >> 16) - v25->field_24;
  v43 = (unsigned __int64)(v41 * (signed __int64)v19) >> 16;
  v26 = ((unsigned __int64)(v41 * (signed __int64)v19) >> 16) - v3->ptr_38->field_28;
  v27 = bUseLoResSprites + v44 + 2;
  a1.field_30 >>= v27;
  v41 = bUseLoResSprites + v44 + 2;
  a1.field_2C = v26 >> v27;
  if ( byte_80AA10 )
  {
    a1.field_14 = dword_80AA20 >> v27;
    a1.field_18 = dword_80AA1C >> v27;
    a1.field_1C = dword_80AA18 >> v27;
    a1.field_20 = dword_80AA14 >> v27;
  }
  v41 = pOutdoorCamera->int_fov_rad_inv;
  v42 = (signed int)((unsigned __int64)(pOutdoorCamera->int_fov_rad_inv * (signed __int64)v19) >> 16) >> v27;
  a1.field_4 = (unsigned __int64)(v42 * (signed __int64)v35) >> 16;
  v43 = (unsigned __int64)(v42 * (signed __int64)v36) >> 16;
  a1.field_0 = (unsigned __int64)(v42 * (signed __int64)v36) >> 16;
  a1.field_34_palette = (unsigned __int16 *)sr_sub_485E1F(&a2, v2, v19, v3, pOutdoorCamera->terrain_gamma, 1u, 1);
  LOWORD(v19) = 0;
  v28 = v2->field_A;
  v29 = v2->field_A;
  a1.field_24 = v19;
  v30 = v2->field_8;
  a1.pColorBuffer = &pRenderer->pTargetSurface[v30 + pRenderer->uTargetSurfacePitch * v29];
  a1.pDepthBuffer = (unsigned int *)&pRenderer->pActiveZBuffer[v30 + 640 * v28];
  v31 = v3->pTexture;
  v32 = ((signed int)v31->uTextureWidth >> v44) - 1;
  v33 = ((signed int)v31->uTextureHeight >> v44 << 16) - 65536;
  a1.field_10 = v44 - v31->uWidthLn2 + 16;
  a1.field_C = v32;
  a1.field_8 = v33;
  if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
  {
    if ( byte_80AA10 )
      sr_sub_485A24(&a1, (stru315 *)&a2);
    else
      sr_sub_485975(&a1, (stru315 *)&a2);
  }
  else
  {
    if ( byte_80AA10 )
      sr_sub_4D705A(v1);
    else
      sr_sub_4D6FB0(v1);
  }
  return 1;
}



//----- (00484442) --------------------------------------------------------
signed int sr_sub_484442(Span *_this)
{
  int v1; // ebp@0
  Span *v2; // edi@1
  stru148 *v3; // esi@1
  int v4; // ecx@1
  stru149 *v5; // eax@1
  stru149 *v6; // eax@1
  int v7; // edx@1
  int v8; // eax@1
  int v9; // ebx@1
  int v10; // eax@1
  int v11; // ecx@1
  int v12; // eax@1
  int v13; // ecx@1
  signed int v14; // ecx@1
  int v15; // ebx@1
  signed __int64 v16; // qtt@3
  int v17; // ecx@3
  int v18; // ebx@3
  int v19; // eax@3
  signed int v20; // ebx@3
  unsigned __int16 *v21; // eax@4
  stru149 *v22; // eax@12
  signed int v23; // eax@12
  int v24; // ecx@12
  int v25; // ecx@14
  unsigned int *v26; // eax@14
  Texture *v27; // esi@14
  signed int v28; // edi@14
  signed int v29; // eax@14
  signed int v31; // [sp+Ch] [bp-90h]@1
  int v32; // [sp+10h] [bp-8Ch]@1
  int v33; // [sp+14h] [bp-88h]@1
  stru316 v34; // [sp+18h] [bp-84h]@14
  stru315 v35; // [sp+40h] [bp-5Ch]@1
  int v36; // [sp+84h] [bp-18h]@1
  int v37; // [sp+88h] [bp-14h]@1
  int v38; // [sp+8Ch] [bp-10h]@1
  int v39; // [sp+90h] [bp-Ch]@1
  int v40; // [sp+94h] [bp-8h]@1
  int v41; // [sp+98h] [bp-4h]@1

  v2 = _this;
  v3 = _this->pParent;
  v4 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterY - _this->field_A);
  v5 = v3->ptr_38;
  v40 = v4;
  v39 = v5->field_14;
  v40 = (unsigned __int64)(v39 * (signed __int64)v4) >> 16;
  v6 = v3->ptr_38;
  v7 = v40 + v6->field_C;
  v39 = v6->field_20;
  v36 = v7;
  v8 = ((unsigned __int64)(v39 * (signed __int64)v4) >> 16) + v3->ptr_38->field_18;
  v40 = v4;
  v38 = v8;
  v39 = v3->v_18.z;
  v40 = (unsigned __int64)(v39 * (signed __int64)v4) >> 16;
  v9 = v40 + v3->v_18.x;
  v32 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY - stru_5C6E00->uIntegerHalfPi);
  v10 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY);
  v11 = v2->field_8;
  v33 = v10;
  v35.field_28 = v2->field_C;
  v12 = pViewport->uScreenCenterX - v11;
  v13 = v3->field_24;
  v41 = pOutdoorCamera->int_fov_rad_inv * v12;
  v14 = -v13;
  v31 = v14;
  v15 = ((unsigned __int64)(pOutdoorCamera->int_fov_rad_inv * v12 * (signed __int64)v3->v_18.y) >> 16) + v9;
  v37 = v15;
  if ( !v15 || (v39 = abs(v14 >> 14), v39 > abs(v15)) )
    return 0;
  LODWORD(v16) = v31 << 16;
  HIDWORD(v16) = v31 >> 16;
  v40 = v16 / v37;
  v17 = v16 / v37;
  v18 = v41;
  HIWORD(v19) = (unsigned int)(v16 / v37) >> 16;
  LOWORD(v19) = 0;
  v35.field_24 = v19;
  v37 = v36 + ((unsigned __int64)(v3->ptr_38->field_10 * (signed __int64)v41) >> 16);
  v36 = v3->ptr_38->field_1C;
  v41 = (unsigned __int64)(v36 * (signed __int64)v41) >> 16;
  v38 += (unsigned __int64)(v36 * (signed __int64)v18) >> 16;
  v20 = 2;
  v35.pTextureLOD = (unsigned __int16 *)v3->pTexture->pLevelOfDetail2;
  if ( v17 < mipmapping_terrain_mm1 << 16 )
  {
    v20 = 0;
    v21 = (unsigned __int16 *)v3->pTexture->pLevelOfDetail0;
LABEL_11:
    v35.pTextureLOD = v21;
    goto LABEL_12;
  }
  if ( v17 < mipmapping_terrain_mm2 << 16 )
  {
    v20 = 1;
    v21 = (unsigned __int16 *)v3->pTexture->pLevelOfDetail1;
    goto LABEL_11;
  }
  if ( v17 < mipmapping_terrain_mm3 << 16 )
  {
    v21 = (unsigned __int16 *)v3->pTexture->pLevelOfDetail2;
    goto LABEL_11;
  }
  if ( !bUseLoResSprites )
  {
    v20 = 3;
    v21 = (unsigned __int16 *)v3->pTexture->pLevelOfDetail3;
    goto LABEL_11;
  }
LABEL_12:
  v41 = (unsigned __int64)(v37 * (signed __int64)v17) >> 16;
  v22 = v3->ptr_38;
  v41 = v17;
  v35.field_30 = ((unsigned __int64)(v37 * (signed __int64)v17) >> 16) - v22->field_24;
  v23 = ((unsigned __int64)(v38 * (signed __int64)v17) >> 16) - v3->ptr_38->field_28;
  v24 = bUseLoResSprites + v20 + 2;
  v35.field_30 >>= v24;
  v38 = bUseLoResSprites + v20 + 2;
  v35.field_2C = v23 >> v24;
  if ( byte_80AA10 )
  {
    v35.field_14 = dword_80AA20 >> v24;
    v35.field_18 = dword_80AA1C >> v24;
    v35.field_1C = dword_80AA18 >> v24;
    v35.field_20 = dword_80AA14 >> v24;
  }
  v38 = pOutdoorCamera->int_fov_rad_inv;
  v39 = (signed int)((unsigned __int64)(pOutdoorCamera->int_fov_rad_inv * (signed __int64)v40) >> 16) >> v24;
  v35.field_4 = (unsigned __int64)(v39 * (signed __int64)v32) >> 16;
  v41 = (unsigned __int64)(v39 * (signed __int64)v33) >> 16;
  v35.field_0 = (unsigned __int64)(v39 * (signed __int64)v33) >> 16;
  v35.field_34_palette = (unsigned __int16 *)sr_sub_485E1F(&v34, v2, v40, v3, pOutdoorCamera->terrain_gamma, 1u, 1);
  v25 = v2->field_8;
  v26 = (unsigned int *)&pRenderer->pActiveZBuffer[v25 + 640 * v2->field_A];
  v35.pColorBuffer = &pRenderer->pTargetSurface[v25 + pRenderer->uTargetSurfacePitch * v2->field_A];
  v35.pDepthBuffer = v26;
  v27 = v3->pTexture;
  v28 = (signed int)v27->uTextureWidth >> v20;
  v29 = (signed int)v27->uTextureHeight >> v20;
  v35.field_10 = v20 - v27->uWidthLn2 + 16;
  v35.field_C = v28 - 1;
  v35.field_8 = (v29 << 16) - 65536;
  if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
  {
    if ( byte_80AA10 )
      sr_sub_485D3E(&v35, &v34);
    else
      sr_sub_485C89(&v35, &v34);
  }
  else
  {
    if ( byte_80AA10 )
      sr_sub_4D72EC(v1);
    else
      sr_sub_4D73DF(v1);
  }
  return 1;
}


//----- (004847EB) --------------------------------------------------------
int sr_sub_4847EB(Span *_this)
{
  stru315 *v1; // ebp@0
  int v2; // ebx@1
  int v3; // edx@1
  stru148 *v4; // esi@1
  int v5; // eax@1
  signed int v6; // eax@3
  int v7; // edi@3
  stru149 *v8; // eax@3
  stru149 *v9; // eax@3
  int v10; // edx@3
  int v11; // eax@3
  signed int v12; // ebx@3
  int v13; // ebx@4
  signed __int64 v14; // qtt@5
  int v15; // eax@5
  signed int v16; // ebx@5
  unsigned __int16 *v17; // ecx@6
  stru149 *v18; // eax@14
  stru149 *v19; // eax@14
  signed int v20; // eax@14
  int v21; // ecx@14
  Texture *v22; // edx@16
  signed int v23; // eax@16
  int v24; // ebx@16
  int v25; // edi@17
  int v26; // ebx@17
  int v27; // eax@17
  int v28; // edi@17
  int v29; // eax@18
  signed __int64 v30; // qtt@19
  int v31; // ecx@19
  int v32; // eax@19
  stru149 *v33; // eax@21
  signed int v34; // edi@21
  int v35; // ebx@21
  signed int v36; // edi@21
  signed __int64 v37; // qtt@21
  signed int v38; // ebx@21
  int v39; // ebx@29
  int v40; // eax@32
  unsigned __int64 v41; // qax@32
  int v42; // edi@32
  int v43; // eax@33
  signed __int64 v44; // qtt@34
  int v45; // ecx@34
  int v46; // eax@34
  stru149 *v47; // eax@36
  signed int v48; // edi@36
  int v49; // eax@36
  int v50; // eax@47
  unsigned __int64 v51; // qax@47
  int v52; // edi@47
  int v53; // eax@48
  signed __int64 v54; // qtt@49
  int v55; // ecx@49
  int v56; // eax@49
  stru149 *v57; // eax@51
  signed int v58; // edi@51
  int v59; // eax@51
  Span *v61; // [sp+Ch] [bp-B0h]@1
  int v62; // [sp+10h] [bp-ACh]@3
  int v63; // [sp+14h] [bp-A8h]@3
  int v64; // [sp+18h] [bp-A4h]@3
  int v65; // [sp+1Ch] [bp-A0h]@3
  signed int v66; // [sp+20h] [bp-9Ch]@3
  signed int v67; // [sp+24h] [bp-98h]@3
  int v68; // [sp+28h] [bp-94h]@1
  char v69; // [sp+2Ch] [bp-90h]@1
  stru315 sr; // [sp+30h] [bp-8Ch]@1
  stru316 sr2; // [sp+74h] [bp-48h]@14
  int v72; // [sp+9Ch] [bp-20h]@5
  int v73; // [sp+A0h] [bp-1Ch]@1
  int v74; // [sp+A4h] [bp-18h]@3
  int v75; // [sp+A8h] [bp-14h]@21
  int v76; // [sp+ACh] [bp-10h]@1
  int v77; // [sp+B0h] [bp-Ch]@14
  int v78; // [sp+B4h] [bp-8h]@3
  int v79; // [sp+B8h] [bp-4h]@3

  v2 = _this->field_A;
  v3 = _this->field_8;
  v4 = _this->pParent;
  v73 = 0;
  v61 = _this;
  sr.pDepthBuffer = (unsigned int *)&pRenderer->pActiveZBuffer[v3 + 640 * v2];
  v76 = v3;
  v5 = _this->field_C;
  sr.pColorBuffer = &pRenderer->pTargetSurface[v3 + pRenderer->uTargetSurfacePitch * v2];
  v68 = texmapping_terrain_subdivsize;
  v69 = texmapping_terrain_subdivpow2;
  if ( v5 >= texmapping_terrain_subdivsize )
    v73 = texmapping_terrain_subdivsize - (v3 & (texmapping_terrain_subdivsize - 1));
  v6 = v5 - v73;
  v67 = v6 >> texmapping_terrain_subdivpow2;
  v62 = v6 - (v6 >> texmapping_terrain_subdivpow2 << texmapping_terrain_subdivpow2);
  v7 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterX - v76);
  v8 = v4->ptr_38;
  v79 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterX - v76);
  v78 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterY - v2);
  v76 = v8->field_14;
  v78 = (unsigned __int64)(v76 * (signed __int64)(pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterY - v2))) >> 16;
  v9 = v4->ptr_38;
  v10 = v78 + v9->field_C;
  v76 = v9->field_20;
  v65 = v10;
  v11 = ((unsigned __int64)(v76 * (signed __int64)(pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterY - v2))) >> 16)
      + v4->ptr_38->field_18;
  v78 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterY - v2);
  v64 = v11;
  v76 = v4->v_18.z;
  v78 = (unsigned __int64)(v76 * (signed __int64)(pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterY - v2))) >> 16;
  v12 = -v4->field_24;
  v63 = v78 + v4->v_18.x;
  v66 = -v4->field_24;
  v78 = (unsigned __int64)(v79 * (signed __int64)v4->v_18.y) >> 16;
  v74 = v78 + v63;
  if ( !(v78 + v63) || (v76 = v12 >> 14, v13 = abs(v12 >> 14), v13 > abs(v74)) )
    return 0;
  LODWORD(v14) = v66 << 16;
  HIDWORD(v14) = v66 >> 16;
  v72 = v14 / v74;
  sr.pTextureLOD = (unsigned __int16 *)v4->pTexture->pLevelOfDetail2;
  v15 = v14 / v74;
  v16 = 2;
  if ( v15 >= mipmapping_terrain_mm1 << 16 )
  {
    if ( v15 >= mipmapping_terrain_mm2 << 16 )
    {
      if ( v15 >= mipmapping_terrain_mm3 << 16 )
      {
        if ( bUseLoResSprites )
          goto LABEL_14;
        v16 = 3;
        v17 = (unsigned __int16 *)v4->pTexture->pLevelOfDetail3;
      }
      else
      {
        v17 = (unsigned __int16 *)v4->pTexture->pLevelOfDetail2;
      }
    }
    else
    {
      v16 = 1;
      v17 = (unsigned __int16 *)v4->pTexture->pLevelOfDetail1;
    }
  }
  else
  {
    v16 = 0;
    v17 = (unsigned __int16 *)v4->pTexture->pLevelOfDetail0;
  }
  sr.pTextureLOD = v17;
LABEL_14:
  sr.field_34_palette = (unsigned __int16 *)sr_sub_485E1F(&sr2, v61, v15, v4, pOutdoorCamera->terrain_gamma, 1u, 1);
  v18 = v4->ptr_38;
  v78 = v7;
  v79 = v18->field_10;
  v78 = v7;
  v77 = v65 + ((unsigned __int64)(v79 * (signed __int64)v7) >> 16);
  v79 = v4->ptr_38->field_1C;
  v79 = v64 + ((unsigned __int64)(v79 * (signed __int64)v7) >> 16);
  v78 = (unsigned __int64)(v77 * (signed __int64)v72) >> 16;
  v19 = v4->ptr_38;
  v78 = v72;
  sr.field_30 = ((unsigned __int64)(v77 * (signed __int64)v72) >> 16) - v19->field_24;
  v78 = (unsigned __int64)(v79 * (signed __int64)v72) >> 16;
  v20 = ((unsigned __int64)(v79 * (signed __int64)v72) >> 16) - v4->ptr_38->field_28;
  v21 = bUseLoResSprites + v16 + 2;
  sr.field_30 >>= v21;
  v78 = bUseLoResSprites + v16 + 2;
  sr.field_2C = v20 >> v21;
  if ( byte_80AA10 )
  {
    sr.field_14 = dword_80AA20 >> v21;
    sr.field_18 = dword_80AA1C >> v21;
    sr.field_1C = dword_80AA18 >> v21;
    sr.field_20 = dword_80AA14 >> v21;
  }
  v22 = v4->pTexture;
  v79 = (signed int)v22->uTextureWidth >> v16;
  v23 = (signed int)v22->uTextureHeight >> v16;
  v24 = v16 - v22->uWidthLn2 + 16;
  sr.field_8 = (v23 << 16) - 65536;
  sr.field_10 = v24;
  sr.field_C = v79 - 1;
  if ( v73 )
  {
    v25 = v7 - v73 * pOutdoorCamera->int_fov_rad_inv;
    v26 = v25;
    v77 = v4->v_18.y;
    v79 = v25;
    v27 = (unsigned __int64)(v77 * (signed __int64)v25) >> 16;
    v28 = v27 + v63;
    v74 = v27 + v63;
    if ( !(v27 + v63) || (v77 = abs(v76), v29 = abs(v28), v77 > v29) )
      return 0;
    LODWORD(v30) = v66 << 16;
    HIDWORD(v30) = v66 >> 16;
    v77 = v30 / v74;
    v31 = v30 / v74;
    HIWORD(v32) = HIWORD(v72);
    if ( v72 <= v31 )
      HIWORD(v32) = HIWORD(v31);
    LOWORD(v32) = 0;
    v77 = v26;
    sr.field_24 = v32;
    v74 = v4->ptr_38->field_10;
    v74 = v65 + ((unsigned __int64)(v74 * (signed __int64)v26) >> 16);
    v77 = (unsigned __int64)(v74 * (signed __int64)v31) >> 16;
    v33 = v4->ptr_38;
    v77 = v26;
    v34 = ((unsigned __int64)(v74 * (signed __int64)v31) >> 16) - v33->field_24;
    v74 = v33->field_1C;
    v74 = v64 + ((unsigned __int64)(v74 * (signed __int64)v26) >> 16);
    v77 = (unsigned __int64)(v74 * (signed __int64)v31) >> 16;
    v35 = (v77 - v4->ptr_38->field_28) >> v78;
    v74 = v73 << 16;
    v36 = (v34 >> v78) - sr.field_30;
    LODWORD(v37) = v36 << 16;
    HIDWORD(v37) = v36 >> 16;
    v38 = v35 - sr.field_2C;
    sr.field_4 = v37 / (v73 << 16);
    v75 = v73 << 16;
    LODWORD(v37) = v38 << 16;
    HIDWORD(v37) = v38 >> 16;
    v77 = v37 / (v73 << 16);
    sr.field_0 = v37 / (v73 << 16);
    sr.field_28 = v73;
    if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
    {
      if ( byte_80AA10 )
        sr_sub_485A24(&sr, (stru315 *)&sr2);
      else
        sr_sub_485975(&sr, (stru315 *)&sr2);
    }
    else
    {
      if ( byte_80AA10 )
        sr_sub_4D705A(v1);
      else
        sr_sub_4D6FB0(v1);
    }
    v39 = v79 - (pOutdoorCamera->int_fov_rad_inv << v69);
  }
  else
  {
    v79 = v7 - (pOutdoorCamera->int_fov_rad_inv << v69);
    v39 = v7 - (pOutdoorCamera->int_fov_rad_inv << v69);
  }
  sr.field_28 = v68;
  while ( v67 > 0 )
  {
    v40 = v4->v_18.y;
    --v67;
    v75 = v40;
    v41 = v40 * (signed __int64)v39;
    v79 = v41 >> 16;
    LODWORD(v41) = v41 >> 16;
    v42 = v41 + v63;
    v74 = v41 + v63;
    if ( !((int)v41 + v63) || (v75 = abs(v76), v43 = abs(v42), v75 > v43) )
      return 0;
    LODWORD(v44) = v66 << 16;
    HIDWORD(v44) = v66 >> 16;
    v73 = v44 / v74;
    v45 = v44 / v74;
    HIWORD(v46) = HIWORD(v72);
    if ( v72 <= v45 )
      HIWORD(v46) = HIWORD(v45);
    LOWORD(v46) = 0;
    v79 = v39;
    sr.field_24 = v46;
    v75 = v4->ptr_38->field_10;
    v75 = v65 + ((unsigned __int64)(v75 * (signed __int64)v39) >> 16);
    v79 = (unsigned __int64)(v75 * (signed __int64)v45) >> 16;
    v47 = v4->ptr_38;
    v79 = v39;
    v48 = ((unsigned __int64)(v75 * (signed __int64)v45) >> 16) - v47->field_24;
    v75 = v47->field_1C;
    v75 = v64 + ((unsigned __int64)(v75 * (signed __int64)v39) >> 16);
    v79 = (unsigned __int64)(v75 * (signed __int64)v45) >> 16;
    v49 = (((v79 - v4->ptr_38->field_28) >> v78) - sr.field_2C) >> v69;
    sr.field_4 = ((v48 >> v78) - sr.field_30) >> v69;
    sr.field_0 = v49;
    if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
    {
      if ( byte_80AA10 )
        sr_sub_485A24(&sr, (stru315 *)&sr2);
      else
        sr_sub_485975(&sr, (stru315 *)&sr2);
    }
    else
    {
      if ( byte_80AA10 )
        sr_sub_4D705A(v1);
      else
        sr_sub_4D6FB0(v1);
    }
    sr.field_34_palette = (unsigned __int16 *)sr_sub_485E1F(&sr2, v61, v73, v4, pOutdoorCamera->terrain_gamma, 1u, 0);
    sr.field_28 = v68;
    v39 -= pOutdoorCamera->int_fov_rad_inv << v69;
  }
  if ( !v62 )
    return 1;
  v50 = v4->v_18.y;
  v75 = v50;
  v51 = v50 * (signed __int64)v39;
  v79 = v51 >> 16;
  LODWORD(v51) = v51 >> 16;
  v52 = v51 + v63;
  v74 = v51 + v63;
  if ( (int)v51 + v63 )
  {
    v75 = abs(v76);
    v53 = abs(v52);
    if ( v75 <= v53 )
    {
      LODWORD(v54) = v66 << 16;
      HIDWORD(v54) = v66 >> 16;
      v76 = v54 / v74;
      v55 = v54 / v74;
      HIWORD(v56) = HIWORD(v72);
      if ( v72 <= v55 )
        HIWORD(v56) = HIWORD(v55);
      LOWORD(v56) = 0;
      v76 = v39;
      sr.field_24 = v56;
      v75 = v4->ptr_38->field_10;
      v75 = v65 + ((unsigned __int64)(v75 * (signed __int64)v39) >> 16);
      v76 = (unsigned __int64)(v75 * (signed __int64)v55) >> 16;
      v57 = v4->ptr_38;
      v76 = v39;
      v58 = ((unsigned __int64)(v75 * (signed __int64)v55) >> 16) - v57->field_24;
      v75 = v57->field_1C;
      v75 = v64 + ((unsigned __int64)(v75 * (signed __int64)v39) >> 16);
      v76 = (unsigned __int64)(v75 * (signed __int64)v55) >> 16;
      v59 = (((v76 - v4->ptr_38->field_28) >> v78) - sr.field_2C) >> v69;
      sr.field_4 = ((v58 >> v78) - sr.field_30) >> v69;
      sr.field_0 = v59;
      sr.field_28 = v62;
      if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
      {
        if ( byte_80AA10 )
          sr_sub_485A24(&sr, (stru315 *)&sr2);
        else
          sr_sub_485975(&sr, (stru315 *)&sr2);
      }
      else
      {
        if ( byte_80AA10 )
          sr_sub_4D705A(v1);
        else
          sr_sub_4D6FB0(v1);
      }
      return 1;
    }
  }
  return 0;
}
// 4D864C: using guessed type char byte_4D864C;
// 6BE050: using guessed type int texmapping_terrain_subdivsize;
// 6BE054: using guessed type int texmapping_terrain_subdivpow2;
// 6BE0F0: using guessed type int mipmapping_terrain_mm1;
// 6BE0F4: using guessed type int mipmapping_terrain_mm2;
// 6BE0F8: using guessed type int mipmapping_terrain_mm3;
// 80AA10: using guessed type char byte_80AA10;
// 80AA14: using guessed type int dword_80AA14;
// 80AA18: using guessed type int dword_80AA18;
// 80AA1C: using guessed type int dword_80AA1C;
// 80AA20: using guessed type int dword_80AA20;



//----- (00485407) --------------------------------------------------------
signed int __fastcall sr_sub_485407_prolly_odm_water_wavy(Span *a1)
{
  stru315 *v1; // ebp@0
  int v2; // eax@1
  int v3; // edx@1
  unsigned int v4; // edi@1
  stru148 *v5; // esi@1
  int v6; // ecx@1
  int v7; // ebx@1
  int v8; // ecx@1
  stru149 *v9; // eax@1
  stru149 *v10; // eax@1
  int v11; // edx@1
  int v12; // eax@1
  int v13; // eax@1
  int v14; // ecx@1
  signed int v15; // edi@1
  int v16; // edi@2
  signed __int64 v17; // qtt@3
  int v18; // edi@3
  int v19; // eax@3
  unsigned __int8 *pLOD; // eax@3
  Texture *v21; // eax@4
  Texture *v22; // eax@6
  Texture *v23; // eax@8
  Texture *v24; // eax@10
  stru149 *v25; // eax@13
  stru149 *v26; // eax@13
  signed int v27; // ebx@13
  stru149 *v28; // eax@13
  Texture *v29; // esi@13
  signed int v30; // ebx@13
  signed int v31; // edi@13
  signed int v32; // edx@13
  signed int v33; // eax@13
  int v34; // esi@13
  int v35; // eax@13
  unsigned __int64 v36; // qax@13
  int v37; // eax@13
  unsigned __int64 v38; // qax@13
  char v39; // cl@14
  stru316 a2; // [sp+Ch] [bp-90h]@13
  stru315 a1a; // [sp+34h] [bp-68h]@1
  Span *v43; // [sp+78h] [bp-24h]@1
  int v44; // [sp+7Ch] [bp-20h]@1
  int v45; // [sp+80h] [bp-1Ch]@1
  int v46; // [sp+84h] [bp-18h]@1
  Span *v47; // [sp+88h] [bp-14h]@1
  int v48; // [sp+8Ch] [bp-10h]@1
  int v49; // [sp+90h] [bp-Ch]@3
  int i; // [sp+94h] [bp-8h]@3
  int X; // [sp+98h] [bp-4h]@1

  v2 = a1->field_A;
  v3 = a1->field_8;
  v4 = v3 + pRenderer->uTargetSurfacePitch * a1->field_A;
  v5 = a1->pParent;
  v43 = a1;
  v6 = a1->field_C;
  a1a.pColorBuffer = &pRenderer->pTargetSurface[v4];
  v46 = v6;
  v7 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterX - v3);
  v8 = pOutdoorCamera->int_fov_rad_inv * (pViewport->uScreenCenterY - v2);
  a1a.pDepthBuffer = (unsigned int *)&pRenderer->pActiveZBuffer[v3 + 640 * v2];
  v9 = v5->ptr_38;
  v47 = (Span *)v7;
  X = v8;
  v48 = v9->field_14;
  X = (unsigned __int64)(v48 * (signed __int64)v8) >> 16;
  v10 = v5->ptr_38;
  v11 = X + v10->field_C;
  v48 = v10->field_20;
  v44 = v11;
  v12 = ((unsigned __int64)(v48 * (signed __int64)v8) >> 16) + v5->ptr_38->field_18;
  X = v8;
  v45 = v12;
  v48 = v5->v_18.z;
  X = (unsigned __int64)(v48 * (signed __int64)v8) >> 16;
  v13 = v5->v_18.y;
  v14 = X + v5->v_18.x;
  v15 = -v5->field_24;
  v48 = -v5->field_24;
  X = ((unsigned __int64)(v7 * (signed __int64)v13) >> 16) + v14;
  if ( !X || (v16 = abs(v15 >> 14), v16 > abs(X)) )
    return 0;
  LODWORD(v17) = v48 << 16;
  HIDWORD(v17) = v48 >> 16;
  i = v17 / X;
  v18 = v17 / X;
  HIWORD(v19) = (unsigned int)(v17 / X) >> 16;
  LOWORD(v19) = 0;
  a1a.field_24 = v19;
  pLOD = v5->pTexture->pLevelOfDetail2;
  a1a.pTextureLOD = (unsigned __int16 *)v5->pTexture->pLevelOfDetail2;
  v49 = 2;
  if ( v18 >= mipmapping_terrain_mm1 << 16 )
  {
    if ( v18 >= mipmapping_terrain_mm2 << 16 )
    {
      if ( v18 >= mipmapping_terrain_mm3 << 16 )
      {
        if ( bUseLoResSprites )
          goto LABEL_12;
        v24 = v5->pTexture;
        v49 = 3;
        pLOD = v24->pLevelOfDetail3;
      }
      else
      {
        v23 = v5->pTexture;
        v49 = 2;
        pLOD = v23->pLevelOfDetail2;
      }
    }
    else
    {
      v22 = v5->pTexture;
      v49 = 1;
      pLOD = v22->pLevelOfDetail1;
    }
  }
  else
  {
    v21 = v5->pTexture;
    v49 = 0;
    pLOD = v21->pLevelOfDetail0;
  }
  a1a.pTextureLOD = (unsigned __int16 *)pLOD;
LABEL_12:
  if ( !pLOD )
    return 0;
  a1a.field_34_palette = (unsigned __int16 *)sr_sub_485E1F(&a2, v43, v18, v5, pOutdoorCamera->terrain_gamma, 1u, 1);
  a1a.field_28 = 16;
  v43 = (Span *)(v46 >> 4);
  X = v7;
  v25 = v5->ptr_38;
  v48 = v46 - 16 * (v46 >> 4);
  v46 = v25->field_10;
  X = v7;
  v46 = v44 + ((unsigned __int64)(v46 * (signed __int64)v7) >> 16);
  v44 = v5->ptr_38->field_1C;
  v45 += (unsigned __int64)(v44 * (signed __int64)v7) >> 16;
  X = (unsigned __int64)(v46 * (signed __int64)v18) >> 16;
  v26 = v5->ptr_38;
  X = v18;
  v27 = ((unsigned __int64)(v46 * (signed __int64)v18) >> 16) - v26->field_24;
  X = (unsigned __int64)(v45 * (signed __int64)v18) >> 16;
  v28 = v5->ptr_38;
  v29 = v5->pTexture;
  v44 = bUseLoResSprites + v49 + 2;
  v30 = v27 >> v44;
  v31 = (signed int)(((unsigned __int64)(v45 * (signed __int64)v18) >> 16) - v28->field_28) >> v44;
  v32 = (signed int)v29->uTextureWidth >> v49;
  v33 = (signed int)v29->uTextureHeight >> v49;
  v34 = v49 - v29->uWidthLn2;
  a1a.field_8 = (v33 << 16) - 65536;
  X = 2 * pMiscTimer->uTotalGameTimeElapsed;
  v45 = pOutdoorCamera->int_fov_rad_inv;
  a1a.field_10 = v34 + 16;
  a1a.field_C = v32 - 1;
  i = (unsigned __int64)(pOutdoorCamera->int_fov_rad_inv * (signed __int64)i) >> 16;
  v47 = (Span *)(i >> v44);
  v35 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY - stru_5C6E00->uIntegerHalfPi);
  v36 = (signed int)v47 * (signed __int64)v35;
  i = v36 >> 16;
  a1a.field_4 = v36 >> 16;
  v37 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY);
  v38 = (signed int)v47 * (signed __int64)v37;
  i = v38 >> 16;
  a1a.field_0 = v38 >> 16;
  if ( (signed int)v43 > 0 )
  {
    v47 = v43;
    v39 = 12 - v49;
    for ( i = 12 - v49; ; v39 = i )
    {
      a1a.field_30 = v30 + 4 * stru_5C6E00->SinCos(X + (v31 >> v39));
      a1a.field_2C = v31 + 4 * stru_5C6E00->SinCos(X + (v30 >> i) - stru_5C6E00->uIntegerHalfPi);
      if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
        sr_sub_485975(&a1a, (stru315 *)&a2);
      else
        sr_sub_4D6FB0(v1);
      a1a.field_28 = 16;
      v30 += 16 * a1a.field_4;
      v31 += 16 * a1a.field_0;
      v47 = (Span *)((char *)v47 - 1);
      if ( !v47 )
        break;
    }
  }
  if ( v48 )
  {
    i = 12 - v49;
    a1a.field_30 = v30 + 4 * stru_5C6E00->SinCos(X + (v31 >> (12 - v49)));
    a1a.field_2C = v31 + 4 * stru_5C6E00->SinCos(X + (v30 >> i) - stru_5C6E00->uIntegerHalfPi);
    a1a.field_28 = v48;
    if ( byte_4D864C && BYTE1(pGame->uFlags) & 8 )
      sr_sub_485975(&a1a, (stru315 *)&a2);
    else
      sr_sub_4D6FB0(v1);
  }
  return 1;
}


//----- (0048585C) --------------------------------------------------------
signed int __fastcall sr_sub_48585C_mb_DrawSpan(Span *a1, unsigned __int16 *pRenderTarget, int a4)
{
  Span *v3; // esi@1
  stru148 *v4; // edi@1
  int v5; // ebx@2
  signed __int64 v6; // qtt@3
  int v7; // ebx@3
  signed int v8; // ecx@3
  void *v9; // eax@5
  int v10; // ecx@5
  unsigned __int16 *pPixels; // [sp+Ch] [bp-14h]@1
  signed int v13; // [sp+10h] [bp-10h]@1
  int X; // [sp+18h] [bp-8h]@1

  v3 = a1;
  pPixels = pRenderTarget;
  v4 = a1->pParent;
  v13 = -v4->field_24;
  X = ((unsigned __int64)(pOutdoorCamera->int_fov_rad_inv
                        * (pViewport->uScreenCenterX - (signed int)a1->field_8)
                        * (signed __int64)v4->v_18.y) >> 16)
    + ((unsigned __int64)(v4->v_18.z
                        * (signed __int64)(pOutdoorCamera->int_fov_rad_inv
                                         * (pViewport->uScreenCenterY - (signed int)a1->field_A))) >> 16)
    + v4->v_18.x;
  if ( X && (v5 = abs(-v4->field_24 >> 14), v5 <= abs(X)) )
  {
    LODWORD(v6) = v13 << 16;
    HIDWORD(v6) = v13 >> 16;
    v7 = v6 / X;
    v8 = v6 / X;
  }
  else
  {
    v7 = pOutdoorCamera->shading_dist_mist << 16;
    v8 = pOutdoorCamera->shading_dist_mist << 16;
  }
  v9 = sr_sub_47C178(v8, v4, pOutdoorCamera->terrain_gamma, a4);
  fill_pixels_fast(*((short *)v9 + v4->pTexture->uDecompressedSize), pPixels, v3->field_C);
  HIWORD(v10) = HIWORD(v7);
  LOWORD(v10) = 0;
  j_memset32(v10, &pRenderer->pActiveZBuffer[v3->field_8 + 640 * v3->field_A], v3->field_C);
  return 1;
}

//----- (00485975) --------------------------------------------------------
stru315 *__fastcall sr_sub_485975(stru315 *a1, stru315 *a2)
{
  stru315 *result; // eax@1
  int i; // ecx@1
  int v4; // esi@2
  int v5; // esi@2
  int v6; // ecx@2
  int v7; // esi@3
  int v8; // edi@3
  int v9; // ebx@3
  int v10; // ecx@8
  unsigned __int16 *v11; // esi@10
  unsigned int *v12; // ecx@12
  int v13; // esi@12
  int v14; // [sp+0h] [bp-4h]@2

  result = a1;
  for ( i = a1->field_28; i; i = result->field_28 )
  {
    v4 = result->field_8 & result->field_2C;
    result->field_28 = i - 1;
    v5 = (result->field_C & HIWORD(result->field_30)) + (v4 >> result->field_10);
    v6 = *((char *)result->pTextureLOD + v5);
    v14 = *((char *)result->pTextureLOD + v5);
    if ( a2->field_20 )
    {
      v7 = HIWORD(a2->field_10);
      v8 = a2->field_C;
      v9 = v7;
      if ( v7 >= v8 )
        v9 = a2->field_C;
      if ( a2->field_8 - v9 <= 0 )
      {
        v10 = 0;
      }
      else
      {
        if ( v7 >= v8 )
          v7 = a2->field_C;
        v10 = a2->field_8 - v7;
      }
      v11 = (unsigned __int16 *)a2->field_24;
      v6 = v14 + (v10 << 8);
    }
    else
    {
      v11 = result->field_34_palette;
    }
    *result->pColorBuffer = v11[v6];
    v12 = result->pDepthBuffer;
    v13 = result->field_24;
    ++result->pColorBuffer;
    *v12 = v13;
    ++result->pDepthBuffer;
    a2->field_10 += a2->field_18;
    result->field_30 += result->field_4;
    result->field_2C += result->field_0;
  }
  --result->field_28;
  return result;
}

//----- (00485A24) --------------------------------------------------------
stru315 *__fastcall sr_sub_485A24(stru315 *a1, stru315 *a2)
{
  stru315 *result; // eax@1
  int i; // ecx@1
  int v4; // ecx@2
  int v5; // ecx@4
  int v6; // ecx@6
  int v7; // ecx@8
  int v8; // esi@10
  int v9; // ecx@10
  int v10; // esi@11
  int v11; // edi@11
  int v12; // ebx@11
  int v13; // ecx@16
  unsigned __int16 *v14; // esi@18
  unsigned int *v15; // ecx@20
  int v16; // esi@20
  int v17; // [sp+0h] [bp-4h]@10

  result = a1;
  for ( i = a1->field_28; i; i = result->field_28 )
  {
    result->field_28 = i - 1;
    v4 = result->field_18;
    if ( result->field_30 > v4 )
      result->field_30 = v4;
    v5 = result->field_20;
    if ( result->field_2C > v5 )
      result->field_2C = v5;
    v6 = result->field_14;
    if ( result->field_30 < v6 )
      result->field_30 = v6;
    v7 = result->field_1C;
    if ( result->field_2C < v7 )
      result->field_2C = v7;
    v8 = (result->field_C & HIWORD(result->field_30)) + ((result->field_2C & result->field_8) >> result->field_10);
    v9 = *((char *)result->pTextureLOD + v8);
    v17 = *((char *)result->pTextureLOD + v8);
    if ( a2->field_20 )
    {
      v10 = HIWORD(a2->field_10);
      v11 = a2->field_C;
      v12 = v10;
      if ( v10 >= v11 )
        v12 = a2->field_C;
      if ( a2->field_8 - v12 <= 0 )
      {
        v13 = 0;
      }
      else
      {
        if ( v10 >= v11 )
          v10 = a2->field_C;
        v13 = a2->field_8 - v10;
      }
      v14 = (unsigned __int16 *)a2->field_24;
      v9 = v17 + (v13 << 8);
    }
    else
    {
      v14 = result->field_34_palette;
    }
    *result->pColorBuffer = v14[v9];
    v15 = result->pDepthBuffer;
    v16 = result->field_24;
    ++result->pColorBuffer;
    *v15 = v16;
    ++result->pDepthBuffer;
    a2->field_10 += a2->field_18;
    result->field_30 += result->field_4;
    result->field_2C += result->field_0;
  }
  --result->field_28;
  return result;
}

//----- (00485AFF) --------------------------------------------------------
stru315 *__fastcall sr_sub_485AFF(stru315 *a1, stru316 *a2)
{
  stru315 *result; // eax@1
  int i; // ecx@1
  int v4; // esi@2
  int v5; // esi@2
  int v6; // ecx@2
  int v7; // esi@3
  int v8; // edi@3
  int v9; // ebx@3
  int v10; // ecx@8
  unsigned __int16 *v11; // esi@10
  unsigned int *v12; // ecx@12
  int v13; // esi@12
  int v14; // [sp+0h] [bp-4h]@2

  result = a1;
  for ( i = a1->field_28; i; i = result->field_28 )
  {
    v4 = result->field_8 & result->field_2C;
    result->field_28 = i - 1;
    v5 = (result->field_C & HIWORD(result->field_30)) + (v4 >> result->field_10);
    v6 = *((char *)result->pTextureLOD + v5);
    v14 = *((char *)result->pTextureLOD + v5);
    if ( a2->field_20 )
    {
      v7 = HIWORD(a2->field_14);
      v8 = a2->field_C;
      v9 = v7;
      if ( v7 >= v8 )
        v9 = a2->field_C;
      if ( a2->field_8 - v9 <= 0 )
      {
        v10 = 0;
      }
      else
      {
        if ( v7 >= v8 )
          v7 = a2->field_C;
        v10 = a2->field_8 - v7;
      }
      v11 = a2->field_24_palette;
      v6 = v14 + (v10 << 8);
    }
    else
    {
      v11 = result->field_34_palette;
    }
    *result->pColorBuffer = v11[v6];
    v12 = result->pDepthBuffer;
    v13 = result->field_24;
    --result->pColorBuffer;
    *v12 = v13;
    --result->pDepthBuffer;
    a2->field_14 -= a2->field_18;
    result->field_30 += result->field_4;
    result->field_2C += result->field_0;
  }
  --result->field_28;
  return result;
}

//----- (00485BAE) --------------------------------------------------------
stru315 *__fastcall sr_sub_485BAE(stru315 *a1, stru316 *a2)
{
  stru315 *result; // eax@1
  int i; // ecx@1
  int v4; // ecx@2
  int v5; // ecx@4
  int v6; // ecx@6
  int v7; // ecx@8
  int v8; // esi@10
  int v9; // ecx@10
  int v10; // esi@11
  int v11; // edi@11
  int v12; // ebx@11
  int v13; // ecx@16
  unsigned __int16 *v14; // esi@18
  unsigned int *v15; // ecx@20
  int v16; // esi@20
  int v17; // [sp+0h] [bp-4h]@10

  result = a1;
  for ( i = a1->field_28; i; i = result->field_28 )
  {
    result->field_28 = i - 1;
    v4 = result->field_18;
    if ( result->field_30 > v4 )
      result->field_30 = v4;
    v5 = result->field_20;
    if ( result->field_2C > v5 )
      result->field_2C = v5;
    v6 = result->field_14;
    if ( result->field_30 < v6 )
      result->field_30 = v6;
    v7 = result->field_1C;
    if ( result->field_2C < v7 )
      result->field_2C = v7;
    v8 = (result->field_C & HIWORD(result->field_30)) + ((result->field_2C & result->field_8) >> result->field_10);
    v9 = *((char *)result->pTextureLOD + v8);
    v17 = *((char *)result->pTextureLOD + v8);
    if ( a2->field_20 )
    {
      v10 = HIWORD(a2->field_14);
      v11 = a2->field_C;
      v12 = v10;
      if ( v10 >= v11 )
        v12 = a2->field_C;
      if ( a2->field_8 - v12 <= 0 )
      {
        v13 = 0;
      }
      else
      {
        if ( v10 >= v11 )
          v10 = a2->field_C;
        v13 = a2->field_8 - v10;
      }
      v14 = a2->field_24_palette;
      v9 = v17 + (v13 << 8);
    }
    else
    {
      v14 = result->field_34_palette;
    }
    *result->pColorBuffer = v14[v9];
    v15 = result->pDepthBuffer;
    v16 = result->field_24;
    --result->pColorBuffer;
    *v15 = v16;
    --result->pDepthBuffer;
    a2->field_14 -= a2->field_18;
    result->field_30 += result->field_4;
    result->field_2C += result->field_0;
  }
  --result->field_28;
  return result;
}

//----- (00485C89) --------------------------------------------------------
stru315 *__fastcall sr_sub_485C89(stru315 *a1, stru316 *a2)
{
  stru315 *result; // eax@1
  int i; // ecx@1
  int v4; // esi@2
  int v5; // esi@2
  int v6; // ecx@2
  int v7; // esi@4
  int v8; // edi@4
  int v9; // ecx@9
  unsigned __int16 *v10; // esi@11
  unsigned int *v11; // ecx@14
  int v12; // esi@14
  int v13; // [sp+0h] [bp-4h]@2

  result = a1;
  for ( i = a1->field_28; i; i = result->field_28 )
  {
    v4 = result->field_8 & result->field_2C;
    result->field_28 = i - 1;
    v5 = (result->field_C & HIWORD(result->field_30)) + (v4 >> result->field_10);
    v6 = *((char *)result->pTextureLOD + v5);
    v13 = *((char *)result->pTextureLOD + v5);
    if ( *((char *)result->pTextureLOD + v5) )
    {
      if ( a2->field_20 )
      {
        v7 = HIWORD(a2->field_10);
        v8 = v7;
        if ( v7 >= a2->field_C )
          v8 = a2->field_C;
        if ( a2->field_8 - v8 <= 0 )
        {
          v9 = 0;
        }
        else
        {
          if ( v7 >= a2->field_C )
            v7 = a2->field_C;
          v9 = a2->field_8 - v7;
        }
        v10 = a2->field_24_palette;
        v6 = v13 + (v9 << 8);
      }
      else
      {
        v10 = result->field_34_palette;
      }
      *result->pColorBuffer = v10[v6];
    }
    v11 = result->pDepthBuffer;
    v12 = result->field_24;
    ++result->pColorBuffer;
    *v11 = v12;
    ++result->pDepthBuffer;
    a2->field_10 += a2->field_18;
    result->field_30 += result->field_4;
    result->field_2C += result->field_0;
  }
  --result->field_28;
  return result;
}

//----- (00485D3E) --------------------------------------------------------
stru315 *__fastcall sr_sub_485D3E(stru315 *a1, stru316 *a2)
{
  stru315 *result; // eax@1
  int i; // ecx@1
  int v4; // ecx@2
  int v5; // ecx@4
  int v6; // ecx@6
  int v7; // ecx@8
  int v8; // esi@10
  int v9; // ecx@10
  int v10; // esi@12
  int v11; // edi@12
  int v12; // ecx@17
  unsigned __int16 *v13; // esi@19
  unsigned int *v14; // ecx@22
  int v15; // esi@22
  int v16; // [sp+0h] [bp-4h]@10

  result = a1;
  for ( i = a1->field_28; i; i = result->field_28 )
  {
    result->field_28 = i - 1;
    v4 = result->field_18;
    if ( result->field_30 > v4 )
      result->field_30 = v4;
    v5 = result->field_20;
    if ( result->field_2C > v5 )
      result->field_2C = v5;
    v6 = result->field_14;
    if ( result->field_30 < v6 )
      result->field_30 = v6;
    v7 = result->field_1C;
    if ( result->field_2C < v7 )
      result->field_2C = v7;
    v8 = (result->field_C & HIWORD(result->field_30)) + ((result->field_2C & result->field_8) >> result->field_10);
    v9 = *((char *)result->pTextureLOD + v8);
    v16 = *((char *)result->pTextureLOD + v8);
    if ( *((char *)result->pTextureLOD + v8) )
    {
      if ( a2->field_20 )
      {
        v10 = HIWORD(a2->field_10);
        v11 = v10;
        if ( v10 >= a2->field_C )
          v11 = a2->field_C;
        if ( a2->field_8 - v11 <= 0 )
        {
          v12 = 0;
        }
        else
        {
          if ( v10 >= a2->field_C )
            v10 = a2->field_C;
          v12 = a2->field_8 - v10;
        }
        v13 = a2->field_24_palette;
        v9 = v16 + (v12 << 8);
      }
      else
      {
        v13 = result->field_34_palette;
      }
      *result->pColorBuffer = v13[v9];
    }
    v14 = result->pDepthBuffer;
    v15 = result->field_24;
    ++result->pColorBuffer;
    *v14 = v15;
    ++result->pDepthBuffer;
    a2->field_10 += a2->field_18;
    result->field_30 += result->field_4;
    result->field_2C += result->field_0;
  }
  --result->field_28;
  return result;
}

//----- (00485E1F) --------------------------------------------------------
void *__fastcall sr_sub_485E1F(stru316 *a1, Span *a2, int a3, stru148 *a4, int a5, unsigned __int8 a6, char a7)
{
  stru316 *v7; // esi@1
  signed int *v8; // edi@1
  signed int *v9; // ebx@1
  char v10; // zf@1
  int v11; // eax@1
  Span *v12; // ecx@3
  double v13; // ST24_8@3
  double v14; // ST24_8@3
  int v15; // eax@3
  signed int v16; // ST14_4@4
  char v17; // dl@4
  signed int v18; // ST10_4@4
  void *v19; // eax@4
  signed int v20; // ST14_4@5
  char v21; // dl@5
  int v22; // ST10_4@5
  signed int v23; // ST14_4@6
  char v24; // dl@6
  Span *v26; // [sp+10h] [bp-8h]@1
  char v27; // [sp+16h] [bp-2h]@1
  char v28; // [sp+17h] [bp-1h]@1
  float v29; // [sp+30h] [bp+18h]@3
  float v30; // [sp+30h] [bp+18h]@3

  v7 = a1;
  v26 = a2;
  v8 = &a1->field_C;
  v9 = &a1->field_8;
  v10 = a1->field_0 == 0;
  v27 = a1->field_4 != 0;
  v28 = !v10;
  sr_sub_47BEB1(a3, a4, a5, 0, &a1->field_8, &a1->field_C, (int)&v27, (int)&v28);
  v7->field_24_palette = (unsigned __int16 *)sr_sub_47C28C_get_palette(a4, v28, *v9, *v8);
  v11 = a4->field_108;
  v7->field_20 = v11;
  if ( v11 )
  {
    if ( a7 )
    {
      v12 = v26;
      v29 = v26->field_10 * 31.0;
      v13 = v29 + 6.7553994e15;
      v7->field_10 = LODWORD(v13) << 16;
      v30 = v12->field_14 * 31.0;
      v14 = v30 + 6.7553994e15;
      v15 = v7->field_10;
      v7->field_14 = LODWORD(v14) << 16;
      v7->field_18 = -((v15 - (LODWORD(v14) << 16)) / v12->field_C);
    }
    v16 = *v8;
    v17 = v28;
    v18 = *v9;
    v7->field_1C = a6;
    v19 = sr_sub_47C28C_get_palette(a4, v17, v18, v16);
  }
  else
  {
    v20 = *v8;
    v21 = v28;
    v7->field_10 = 0;
    v7->field_14 = 0;
    v22 = *v9;
    v7->field_18 = 0;
    v7->field_1C = 0;
    v19 = sr_sub_47C1CA(a4, v21, v22, v20);
  }
  v23 = *v8;
  v24 = v28;
  v7->field_24_palette = (unsigned __int16 *)v19;
  return sr_sub_47C1CA(a4, v24, *v9, v23);
}

//----- (00485F53) --------------------------------------------------------
void __thiscall sub_485F53(Vec2_int_ *v)
{
  ++v->y;
  if ( v->y > 1000 )
    v->y = 0;
}



//----- (00485F64) --------------------------------------------------------
void OutdoorCamera::_485F64()
{
  int v1; // eax@1
  int v2; // eax@2
  signed __int64 v3; // qtt@4
  int v4; // eax@4

  this->uCameraFovInDegrees = 75;
  v1 = stru_5C6E00->uPiMask & 0xD5;
  if ( v1 >= (signed int)stru_5C6E00->uIntegerHalfPi )
    v2 = -stru_5C6E00->pTanTable[stru_5C6E00->uIntegerPi - v1];
  else
    v2 = stru_5C6E00->pTanTable[v1];
  LODWORD(v3) = (viewparams->uSomeZ - viewparams->uSomeX) << 31;
  HIDWORD(v3) = (viewparams->uSomeZ - viewparams->uSomeX) << 15 >> 16;
  v4 = (signed int)(v3 / v2) >> 16;
  this->int_fov_rad = v4;
  this->field_4C = 360000;
  this->int_fov_rad_inv = 65536 / v4;
  this->field_50 = 115;
  unnamed_6BE060[1] = 1;
  RotationToInts();
}

//----- (0048600E) --------------------------------------------------------
void OutdoorCamera::RotationToInts()
{
  camera_rotation_y_int_sine   = stru_5C6E00->SinCos(pIndoorCamera->sRotationY - stru_5C6E00->uIntegerHalfPi);
  camera_rotation_y_int_cosine = stru_5C6E00->SinCos(pIndoorCamera->sRotationY);
  camera_rotation_x_int_sine   = stru_5C6E00->SinCos(pIndoorCamera->sRotationX - stru_5C6E00->uIntegerHalfPi);
  camera_rotation_x_int_cosine = stru_5C6E00->SinCos(pIndoorCamera->sRotationX);
}


//----- (0048607B) --------------------------------------------------------
void stru148::_48607B(stru149 *a2)
{
  this->pTexture = 0;
  this->ptr_38 = a2;
}

//----- (00486089) --------------------------------------------------------
void stru148::_486089_normalize_v_18()
{
  stru148 *v1; // esi@1
  double v2; // st7@1
  double v3; // st6@1
  float v4; // ST18_4@2
  double v5; // st5@1
  float v6; // ST14_4@2
  double v7; // st7@1
  float v8; // ST24_4@2
  float v9; // ST20_4@2
  double v10; // ST0C_8@2
  float v11; // ST18_4@2
  double v12; // ST0C_8@2
  float v13; // ST14_4@2
  double v14; // ST0C_8@2
  float v15; // [sp+20h] [bp-8h]@1

  v1 = this;
  v2 = (double)this->v_18.x;
  v15 = v2;
  v3 = (double)this->v_18.y;
  v5 = (double)this->v_18.z;
  v7 = sqrt(v5 * v5 + v3 * v3 + v2 * v2);
  if ( v7 == 0.0 )
  {
    v1->v_18.x = 0;
    v1->v_18.y = 0;
    v1->v_18.z = 65536;
  }
  else
  {
    v8 = 1.0 / v7;
    v9 = v8 * v15 * 65536.0;
    v10 = v9 + 6.7553994e15;
    v1->v_18.x = LODWORD(v10);
    v4 = v3;
    v11 = v8 * v4 * 65536.0;
    v12 = v11 + 6.7553994e15;
    v1->v_18.y = LODWORD(v12);
    v6 = v5;
    v13 = v8 * v6 * 65536.0;
    v14 = v13 + 6.7553994e15;
    v1->v_18.z = LODWORD(v14);
  }
}

//----- (0048616B) --------------------------------------------------------
int stru149::_48616B(int a2, int a3, int a4, int a5, int a6, int a7)
{
  int v7; // ebx@1
  int v8; // esi@1
  int v9; // edi@1
  int v10; // eax@1
  int v11; // edx@1
  int v12; // esi@2
  int v13; // eax@2
  int v14; // ST10_4@3
  int v15; // esi@3
  int v16; // eax@5
  int v17; // ST0C_4@6
  int v18; // eax@8
  int v19; // ST0C_4@9
  int v20; // eax@10
  int v21; // edx@10
  int v22; // eax@10
  int result; // eax@10
  int v24; // [sp+14h] [bp-14h]@1
  int v25; // [sp+18h] [bp-10h]@1
  int v26; // [sp+1Ch] [bp-Ch]@1
  int v27; // [sp+24h] [bp-4h]@1
  int v28; // [sp+30h] [bp+8h]@10
  int v29; // [sp+3Ch] [bp+14h]@10

  v25 = pOutdoorCamera->camera_rotation_x_int_cosine;
  v7 = pOutdoorCamera->camera_rotation_y_int_sine;
  v27 = pOutdoorCamera->camera_rotation_x_int_sine;
  v8 = -pIndoorCamera->pos.y;
  v9 = pOutdoorCamera->camera_rotation_y_int_cosine;
  v26 = -pIndoorCamera->pos.z;
  v24 = -pIndoorCamera->pos.x;
  v10 = pOutdoorCamera->camera_rotation_y_int_cosine * -pIndoorCamera->pos.x;
  v11 = v10 + pOutdoorCamera->camera_rotation_y_int_sine * -pIndoorCamera->pos.y;
  if ( pIndoorCamera->sRotationX )
  {
    v14 = v10 + pOutdoorCamera->camera_rotation_y_int_sine * -pIndoorCamera->pos.y;
    v15 = pOutdoorCamera->camera_rotation_y_int_cosine * v8 - pOutdoorCamera->camera_rotation_y_int_sine * v24;
    this->field_0 = ((unsigned __int64)(v11 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_cosine) >> 16)
                  + ((unsigned __int64)(-65536
                                      * pIndoorCamera->pos.z
                                      * (signed __int64)pOutdoorCamera->camera_rotation_x_int_sine) >> 16);
    this->field_4 = v15;
    v12 = v25;
    v13 = ((unsigned __int64)((v26 << 16) * (signed __int64)v25) >> 16)
        - ((unsigned __int64)(v14 * (signed __int64)v27) >> 16);
  }
  else
  {
    this->field_4 = pOutdoorCamera->camera_rotation_y_int_cosine * v8 - pOutdoorCamera->camera_rotation_y_int_sine * v24;
    v12 = v25;
    this->field_0 = v11;
    v13 = v26 << 16;
  }
  this->field_8 = v13;
  if ( pIndoorCamera->sRotationX )
  {
    v17 = ((unsigned __int64)(a2 * (signed __int64)v9) >> 16) + ((unsigned __int64)(a3 * (signed __int64)v7) >> 16);
    this->field_C = ((unsigned __int64)(v17 * (signed __int64)v12) >> 16)
                  + ((unsigned __int64)(a4 * (signed __int64)v27) >> 16);
    this->field_10 = ((unsigned __int64)(a3 * (signed __int64)v9) >> 16)
                   - ((unsigned __int64)(a2 * (signed __int64)v7) >> 16);
    v16 = ((unsigned __int64)(a4 * (signed __int64)v12) >> 16) - ((unsigned __int64)(v17 * (signed __int64)v27) >> 16);
  }
  else
  {
    this->field_C = ((unsigned __int64)(a2 * (signed __int64)v9) >> 16)
                  + ((unsigned __int64)(a3 * (signed __int64)v7) >> 16);
    this->field_10 = ((unsigned __int64)(a3 * (signed __int64)v9) >> 16)
                   - ((unsigned __int64)(a2 * (signed __int64)v7) >> 16);
    v16 = a4;
  }
  this->field_14 = v16;
  if ( pIndoorCamera->sRotationX )
  {
    v19 = ((unsigned __int64)(a5 * (signed __int64)v9) >> 16) + ((unsigned __int64)(a6 * (signed __int64)v7) >> 16);
    this->field_18 = ((unsigned __int64)(v19 * (signed __int64)v12) >> 16)
                   + ((unsigned __int64)(a7 * (signed __int64)v27) >> 16);
    this->field_1C = ((unsigned __int64)(a6 * (signed __int64)v9) >> 16)
                   - ((unsigned __int64)(a5 * (signed __int64)v7) >> 16);
    v18 = ((unsigned __int64)(a7 * (signed __int64)v12) >> 16) - ((unsigned __int64)(v19 * (signed __int64)v27) >> 16);
  }
  else
  {
    this->field_18 = ((unsigned __int64)(a5 * (signed __int64)v9) >> 16)
                   + ((unsigned __int64)(a6 * (signed __int64)v7) >> 16);
    this->field_1C = ((unsigned __int64)(a6 * (signed __int64)v9) >> 16)
                   - ((unsigned __int64)(a5 * (signed __int64)v7) >> 16);
    v18 = a7;
  }
  this->field_18 = -this->field_18;
  this->field_1C = -this->field_1C;
  this->field_20 = v18;
  v20 = this->field_C;
  this->field_20 = -this->field_20;
  v21 = ((unsigned __int64)(v20 * (signed __int64)this->field_0) >> 16)
      + ((unsigned __int64)(this->field_10 * (signed __int64)this->field_4) >> 16)
      + ((unsigned __int64)(this->field_14 * (signed __int64)this->field_8) >> 16);
  v28 = this->field_18;
  v22 = this->field_0;
  this->field_24 = v21;
  v29 = (unsigned __int64)(v28 * (signed __int64)v22) >> 16;
  result = (unsigned __int64)(this->field_1C * (signed __int64)this->field_4) >> 16;
  this->field_28 = v29 + result + ((unsigned __int64)(this->field_20 * (signed __int64)this->field_8) >> 16);
  return result;
}

//----- (0048653D) --------------------------------------------------------
int stru149::_48653D(int a2, int a3, int a4, int a5, int a6, int a7)
{
  stru149 *v7; // esi@1
  int v8; // edi@1
  int v9; // eax@1
  int v10; // edx@1
  int v11; // ecx@1
  int v12; // eax@1
  int v13; // ebx@2
  int v14; // ecx@2
  int v15; // eax@2
  int v16; // ST14_4@3
  int v17; // ST10_4@3
  int v18; // eax@5
  int v19; // ST10_4@6
  int v20; // eax@8
  int v21; // ST10_4@9
  int v22; // eax@10
  int v23; // ecx@10
  int v24; // eax@10
  int result; // eax@10
  int v26; // [sp+14h] [bp-14h]@1
  int v27; // [sp+18h] [bp-10h]@1
  int v28; // [sp+1Ch] [bp-Ch]@1
  int v29; // [sp+24h] [bp-4h]@1
  int v30; // [sp+30h] [bp+8h]@10
  int v31; // [sp+3Ch] [bp+14h]@10

  v7 = this;
  v8 = stru_5C6E00->SinCos(pBLVRenderParams->sPartyRotY);
  v29 = stru_5C6E00->SinCos(pBLVRenderParams->sPartyRotY - stru_5C6E00->uIntegerHalfPi);
  v28 = stru_5C6E00->SinCos(pBLVRenderParams->sPartyRotX);
  v9 = stru_5C6E00->SinCos(pBLVRenderParams->sPartyRotX - stru_5C6E00->uIntegerHalfPi);
  v11 = -pBLVRenderParams->vPartyPos.y;
  v26 = -pBLVRenderParams->vPartyPos.x;
  v27 = v9;
  v12 = -pBLVRenderParams->vPartyPos.z;
  if ( pBLVRenderParams->sPartyRotX )
  {
    v16 = v8 * -pBLVRenderParams->vPartyPos.x + v29 * -pBLVRenderParams->vPartyPos.y;
    v13 = v28;
    v17 = -65536 * pBLVRenderParams->vPartyPos.z;
    v7->field_0 = ((unsigned __int64)(v16 * (signed __int64)v28) >> 16)
                + ((unsigned __int64)(-65536 * pBLVRenderParams->vPartyPos.z * (signed __int64)v27) >> 16);
    v7->field_4 = v8 * v11 - v29 * v26;
    v14 = v27;
    v15 = ((unsigned __int64)(v17 * (signed __int64)v28) >> 16) - ((unsigned __int64)(v16 * (signed __int64)v27) >> 16);
  }
  else
  {
    v7->field_0 = v10 + v29 * -pBLVRenderParams->vPartyPos.y;
    v13 = v28;
    v7->field_4 = v8 * v11 - v29 * v26;
    v14 = v27;
    v15 = v12 << 16;
  }
  v7->field_8 = v15;
  if ( pBLVRenderParams->sPartyRotX )
  {
    v19 = ((unsigned __int64)(a2 * (signed __int64)v8) >> 16) + ((unsigned __int64)(a3 * (signed __int64)v29) >> 16);
    v7->field_C = ((unsigned __int64)(v19 * (signed __int64)v13) >> 16)
                + ((unsigned __int64)(a4 * (signed __int64)v14) >> 16);
    v7->field_10 = ((unsigned __int64)(a3 * (signed __int64)v8) >> 16)
                 - ((unsigned __int64)(a2 * (signed __int64)v29) >> 16);
    v18 = ((unsigned __int64)(a4 * (signed __int64)v13) >> 16) - ((unsigned __int64)(v19 * (signed __int64)v14) >> 16);
  }
  else
  {
    v7->field_C = ((unsigned __int64)(a2 * (signed __int64)v8) >> 16)
                + ((unsigned __int64)(a3 * (signed __int64)v29) >> 16);
    v7->field_10 = ((unsigned __int64)(a3 * (signed __int64)v8) >> 16)
                 - ((unsigned __int64)(a2 * (signed __int64)v29) >> 16);
    v18 = a4;
  }
  v7->field_14 = v18;
  if ( pBLVRenderParams->sPartyRotX )
  {
    v21 = ((unsigned __int64)(a5 * (signed __int64)v8) >> 16) + ((unsigned __int64)(a6 * (signed __int64)v29) >> 16);
    v7->field_18 = ((unsigned __int64)(v21 * (signed __int64)v13) >> 16)
                 + ((unsigned __int64)(a7 * (signed __int64)v14) >> 16);
    v7->field_1C = ((unsigned __int64)(a6 * (signed __int64)v8) >> 16)
                 - ((unsigned __int64)(a5 * (signed __int64)v29) >> 16);
    v20 = ((unsigned __int64)(a7 * (signed __int64)v13) >> 16) - ((unsigned __int64)(v21 * (signed __int64)v14) >> 16);
  }
  else
  {
    v7->field_18 = ((unsigned __int64)(a5 * (signed __int64)v8) >> 16)
                 + ((unsigned __int64)(a6 * (signed __int64)v29) >> 16);
    v7->field_1C = ((unsigned __int64)(a6 * (signed __int64)v8) >> 16)
                 - ((unsigned __int64)(a5 * (signed __int64)v29) >> 16);
    v20 = a7;
  }
  v7->field_18 = -v7->field_18;
  v7->field_1C = -v7->field_1C;
  v7->field_20 = v20;
  v22 = v7->field_C;
  v7->field_20 = -v7->field_20;
  v23 = ((unsigned __int64)(v22 * (signed __int64)v7->field_0) >> 16)
      + ((unsigned __int64)(v7->field_10 * (signed __int64)v7->field_4) >> 16)
      + ((unsigned __int64)(v7->field_14 * (signed __int64)v7->field_8) >> 16);
  v30 = v7->field_18;
  v24 = v7->field_0;
  v7->field_24 = v23;
  v31 = (unsigned __int64)(v30 * (signed __int64)v24) >> 16;
  result = (unsigned __int64)(v7->field_1C * (signed __int64)v7->field_4) >> 16;
  v7->field_28 = v31 + result + ((unsigned __int64)(v7->field_20 * (signed __int64)v7->field_8) >> 16);
  return result;
}

//----- (0048694B) --------------------------------------------------------
int stru149::_48694B()
{
  int v1; // eax@1
  int v2; // ST04_4@1
  int v3; // ST00_4@1
  int v4; // eax@1
  int v5; // ST0C_4@1
  int result; // eax@1

  v1 = this->field_C;
  this->field_18 = -this->field_18;
  this->field_1C = -this->field_1C;
  this->field_20 = -this->field_20;
  v2 = (unsigned __int64)(v1 * (signed __int64)this->field_0) >> 16;
  v3 = this->field_18;
  v4 = this->field_0;
  this->field_24 = v2
                 + ((unsigned __int64)(this->field_10 * (signed __int64)this->field_4) >> 16)
                 + ((unsigned __int64)(this->field_14 * (signed __int64)this->field_8) >> 16);
  v5 = (unsigned __int64)(v3 * (signed __int64)v4) >> 16;
  result = (unsigned __int64)(this->field_1C * (signed __int64)this->field_4) >> 16;
  this->field_28 = v5 + result + ((unsigned __int64)(this->field_20 * (signed __int64)this->field_8) >> 16);
  return result;
}


//----- (00486A28) --------------------------------------------------------
void OutdoorCamera::AllocSoftwareDrawBuffers()
{
  if ( !this || !pSpans )
  {
    ReleaseSoftwareDrawBuffers();
    pSpans = (Span *)pAllocator->AllocNamedChunk(pSpans, 0x493E0u, "SPANS");
    pEdges = (Edge *)pAllocator->AllocNamedChunk(pEdges, 0x4C2C0u, "EDGES");
    pSurfs = (Surf *)pAllocator->AllocNamedChunk(pSurfs, 0x11940u, "SURFS");
    pNewEdges = (Edge *)pAllocator->AllocNamedChunk(pNewEdges, 0x6180u, "NEWEDGES");
    memset(pSpans, 0, 0x493E0u);
    memset(pEdges, 0, 0x4C2C0u);
    memset(pSurfs, 0, 0x11940u);
    memset(pNewEdges, 0, 0x6180u);
  }
}

//----- (00486AFC) --------------------------------------------------------
void OutdoorCamera::ReleaseSoftwareDrawBuffers()
{
  pAllocator->FreeChunk(pSpans);
  pAllocator->FreeChunk(pEdges);
  pAllocator->FreeChunk(pSurfs);
  pAllocator->FreeChunk(pNewEdges);
  pSpans = 0;
  pEdges = 0;
  pSurfs = 0;
  pNewEdges = 0;
}

//----- (00486B4E) --------------------------------------------------------
char __fastcall sr_sub_486B4E_push_outdoor_edges(RenderVertexSoft *a1, int *a2, int *a3, stru148 *a4)
{
  stru148 *v4; // esi@1
  RenderVertexSoft *v5; // edi@1
  char v6; // zf@1
  unsigned int v7; // eax@3
  int v8; // ebx@3
  int *v9; // ecx@7
  int v10; // ebx@8
  int v11; // eax@10
  double v12; // st7@14
  int *v13; // edx@14
  double v14; // st6@14
  double v15; // st7@16
  int v16; // edi@16
  double v17; // st7@16
  double v18; // st7@16
  int v19; // edi@18
  double v20; // st7@18
  double v21; // st7@18
  Edge *i; // edx@20
  double v23; // st7@28
  Edge *v24; // eax@28
  std::string v26; // [sp-18h] [bp-98h]@2
  const char *v27; // [sp-8h] [bp-88h]@2
  int v28; // [sp-4h] [bp-84h]@2
  double v29; // [sp+Ch] [bp-74h]@28
  double v30; // [sp+14h] [bp-6Ch]@28
  double v31; // [sp+1Ch] [bp-64h]@20
  double v32; // [sp+24h] [bp-5Ch]@16
  double v33; // [sp+2Ch] [bp-54h]@14
  unsigned int v34; // [sp+34h] [bp-4Ch]@2
  unsigned __int64 v35; // [sp+38h] [bp-48h]@28
  int v36; // [sp+40h] [bp-40h]@28
  int v37; // [sp+44h] [bp-3Ch]@20
  float v38; // [sp+48h] [bp-38h]@18
  int v39; // [sp+4Ch] [bp-34h]@16
  int v40; // [sp+50h] [bp-30h]@14
  int v41; // [sp+54h] [bp-2Ch]@3
  RenderVertexSoft *v42; // [sp+58h] [bp-28h]@1
  int v43; // [sp+5Ch] [bp-24h]@14
  int v44; // [sp+60h] [bp-20h]@6
  int v45; // [sp+64h] [bp-1Ch]@6
  unsigned int v46; // [sp+68h] [bp-18h]@7
  int *v47; // [sp+6Ch] [bp-14h]@1
  int v48; // [sp+70h] [bp-10h]@7
  float *v49; // [sp+74h] [bp-Ch]@7
  float v50; // [sp+78h] [bp-8h]@10
  float v51; // [sp+7Ch] [bp-4h]@14

  v4 = a4;
  v5 = a1;
  v47 = a2;
  v6 = (HIBYTE(a4->flags) & 0x40) == 0;
  v42 = a1;
  if ( !v6 )
  {
          MessageBoxW(nullptr, L"The Texture Frame Table is not a supported feature.", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odspan.cpp:162", 0);
  }
  LOBYTE(v7) = v4->field_108;
  v8 = v4->uNumVertices;
  v4->field_108 = 0;
  BYTE3(a4) = v7;
  v41 = v8;
  if ( v8 > 0 )
  {
    if ( (signed int)pOutdoorCamera->uNumSurfs < 1999 )
    {
      v7 = pOutdoorCamera->uNumEdges;
      if ( (signed int)pOutdoorCamera->uNumEdges < 5979 )
      {
        v4->uEdgeList1Size = 0;
        v4->uEdgeList2Size = 0;
        v45 = -1;
        v34 = v7;
        v28 = v8;
        v27 = (const char *)v5;
        v44 = 10000;
        pGame->pLightmapBuilder->_45CB89(v5, v8);
        if ( v8 > 0 )
        {
          v9 = a3;
          v48 = 1;
          v49 = &v5->flt_2C;
          v46 = (char *)v47 - (char *)a3;
          do
          {
            v10 = v48;
            ++pOutdoorCamera->uNumEdges;
            if ( v48 >= v41 )
              v10 = 0;
            v11 = *v9;
            LODWORD(v50) = *v9;
            if ( SLODWORD(v50) > v45 )
              v45 = v11;
            if ( v11 < v44 )
              v44 = v11;
            v12 = (double)SLODWORD(v50);
            v13 = &a3[v10];
            v51 = v12;
            v14 = (double)*v13;
            v50 = v14;
            *(float *)&v40 = v14 - v12;
            v33 = *(float *)&v40 + 6.7553994e15;
            v43 = LODWORD(v33);
            if ( LODWORD(v33) )
            {
              if ( SLODWORD(v33) >= 0 )
              {
                v19 = (int)((char *)v9 + v46);
                ptr_80C978_Edges->field_8 = 1;
                LODWORD(v38) = (int)&v47[v10];
                v40 = *(unsigned int *)LODWORD(v38) - *(int *)v19;
                v6 = BYTE3(a4) == 0;
                v20 = (double)v40;
                v40 = *v13 - *v9;
                v21 = v20 / (double)v40;
                ptr_80C978_Edges->field_4 = v21;
                ptr_80C978_Edges->field_0 = (v51 - (double)*v9) * v21 + (double)*(signed int *)v19;
                if ( !v6 )
                {
                  ptr_80C978_Edges->field_1C = *v49;
                  ptr_80C978_Edges->field_20 = v42[v10].flt_2C;
                  ptr_80C978_Edges->field_24 = (double)*(signed int *)v19;
                  ptr_80C978_Edges->field_28 = (double)(signed int)*(unsigned int *)LODWORD(v38);
                  ptr_80C978_Edges->field_2C = (double)*v9;
                  ptr_80C978_Edges->field_30 = (double)*v13;
                  v4->pEdgeList1[v4->uEdgeList1Size++] = ptr_80C978_Edges;
                }
              }
              else
              {
                v32 = v51 + 6.7553994e15;
                v39 = LODWORD(v32);
                v51 = v50;
                v15 = (double)SLODWORD(v32);
                ptr_80C978_Edges->field_8 = 0;
                v16 = (int)&v47[v10];
                v50 = v15;
                v40 = *(int *)((char *)v9 + v46) - *(int *)v16;
                v6 = BYTE3(a4) == 0;
                v17 = (double)v40;
                v40 = *v9 - *v13;
                v18 = v17 / (double)v40;
                ptr_80C978_Edges->field_4 = v18;
                ptr_80C978_Edges->field_0 = (v51 - (double)*v13) * v18 + (double)*(signed int *)v16;
                if ( !v6 )
                {
                  ptr_80C978_Edges->field_1C = v42[v10].flt_2C;
                  ptr_80C978_Edges->field_20 = *v49;
                  ptr_80C978_Edges->field_24 = (double)*(signed int *)v16;
                  ptr_80C978_Edges->field_28 = (double)*(int *)((char *)v9 + v46);
                  ptr_80C978_Edges->field_2C = (double)*v13;
                  ptr_80C978_Edges->field_30 = (double)*v9;
                  v4->pEdgeList2[v4->uEdgeList2Size++] = ptr_80C978_Edges;
                }
              }
              v31 = v51 + 6.7553994e15;
              v37 = LODWORD(v31);
              for ( i = &pNewEdges[LODWORD(v31)]; i->pNext->field_0 < (double)ptr_80C978_Edges->field_0; i = i->pNext )
                ;
              if ( i->field_0 != ptr_80C978_Edges->field_0 || i->field_8 || ptr_80C978_Edges->field_8 != 1 )
              {
                ptr_80C978_Edges->pNext = i->pNext;
                i->pNext = ptr_80C978_Edges;
              }
              else
              {
                ptr_80C978_Edges->pNext = i;
                i->pPrev->pNext = ptr_80C978_Edges;
              }
              v23 = v50 - 1.0;
              *(float *)&v40 = v23;
              v38 = v23;
              v30 = v38 + 6.7553994e15;
              v36 = LODWORD(v30);
              ptr_80C978_Edges->ptr_18 = ptr_80CA10[LODWORD(v30)];
              v29 = *(float *)&v40 + 6.7553994e15;
              v35 = __PAIR__(v40, LODWORD(v29));
              v24 = ptr_80C978_Edges;
              ptr_80CA10[LODWORD(v29)] = ptr_80C978_Edges;
              v24->pSurf = ptr_80C97C_Surfs;
              if ( ptr_80C978_Edges < &pEdges[5999] )
                ++ptr_80C978_Edges;
            }
            ++v48;
            v49 += 12;
            ++v9;
          }
          while ( v48 - 1 < v41 );
        }
        LOBYTE(v7) = v34;
        if ( pOutdoorCamera->uNumEdges != v34 )
        {
          v4->ptr_48 = 0;
          ptr_80C97C_Surfs->field_22 = 0;
          ptr_80C97C_Surfs->pParent = v4;
          ptr_80C97C_Surfs->field_4 = v4->field_4;
          ptr_80C97C_Surfs->field_8 = v4->field_8;
          ptr_80C97C_Surfs->field_0 = v4->field_0;
          ptr_80C97C_Surfs->field_C = v4->field_C;
          ptr_80C97C_Surfs->field_10 = v4->field_10;
          LOBYTE(v7) = (char)pSurfs + 28;
          if ( ptr_80C97C_Surfs < &pSurfs[1999] )
          {
            ++ptr_80C97C_Surfs;
            ++pOutdoorCamera->uNumSurfs;
          }
          if ( BYTE3(a4) )
            v4->field_108 = 1;
        }
      }
    }
  }
  return v7;
}



//----- (0043F953) --------------------------------------------------------
void PrepareBspRenderList_BLV()
{
  pBspRenderer->uNumFaceIDs = 0;

  if (pBLVRenderParams->uPartySectorID)
  {
    pBspRenderer->field_FA8[0].uSectorID = pBLVRenderParams->uPartySectorID;
    pBspRenderer->field_FA8[0].uViewportW = pBLVRenderParams->uViewportW;
    pBspRenderer->field_FA8[0].uViewportZ = pBLVRenderParams->uViewportZ;
    pBspRenderer->field_FA8[0].uViewportY = pBLVRenderParams->uViewportY;
    pBspRenderer->field_FA8[0].uViewportX = pBLVRenderParams->uViewportX;
    pBspRenderer->field_FA8[0].field_C._43F9E1(
      pBLVRenderParams->uViewportX,
      pBLVRenderParams->uViewportY,
      pBLVRenderParams->uViewportZ,
      pBLVRenderParams->uViewportW);
    pBspRenderer->field_FA8[0].uFaceID = -1;
    pBspRenderer->field_FA8[0].std__vector_0007A8 = -1;
    pBspRenderer->std__vector_000FA8 = 1;
    sub_440639(0);
  }

  pBspRenderer->MakeVisibleSectorList();
}

//----- (0043F9E1) --------------------------------------------------------
void BspRenderer_stru2::_43F9E1(__int16 x, int y, __int16 z, int w)
{
  _viewport_space_y = y;
  _viewport_space_w = w;

  for (uint i = 0; i < 480; ++i)
  {
    if ( i < y || i > w )
    {
      array_3D8[i] = -1;
      array_18[i] = 640;
    }
    else
    {
      array_18[i] = x;
      array_3D8[i] = z;
    } 
  }
}

//----- (0043FA33) --------------------------------------------------------
void __fastcall PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID)
{
  LevelDecoration *v2; // esi@1
  DecorationDesc *v3; // ebx@2
  __int16 v4; // ax@2
  double v5; // st7@3
  int v6; // eax@5
  int v7; // edx@5
  unsigned int v8; // edi@5
  int v9; // edi@5
  int v10; // eax@7
  SpriteFrame *v11; // eax@7
  SpriteFrame *v12; // esi@7
  int v13; // eax@7
  int v14; // ebx@16
  RenderBillboard *v15; // ecx@17
  char v16; // zf@18
  IndoorCameraD3D **v17; // eax@19
  double v18; // st7@19
  float v19; // eax@19
  signed __int64 v20; // qtt@19
  signed __int64 v21; // qtt@20
  int v22; // edx@21
  int v23; // eax@21
  Particle_ local_0; // [sp+Ch] [bp-A0h]@3
  double v25; // [sp+74h] [bp-38h]@19
  unsigned int v26; // [sp+7Ch] [bp-30h]@1
  int a2; // [sp+80h] [bp-2Ch]@5
  int a3; // [sp+84h] [bp-28h]@5
  int a1; // [sp+88h] [bp-24h]@5
  int v30; // [sp+8Ch] [bp-20h]@7
  float v31; // [sp+90h] [bp-1Ch]@1
  int a5; // [sp+94h] [bp-18h]@17
  int z; // [sp+98h] [bp-14h]@15
  int a6; // [sp+9Ch] [bp-10h]@17
  int y; // [sp+A0h] [bp-Ch]@15
  int x; // [sp+A4h] [bp-8h]@15
  int v37; // [sp+A8h] [bp-4h]@5

  v26 = uDecorationID;
  LODWORD(v31) = uSectorID;
  v2 = &pLevelDecorations[uDecorationID];
  if ( !(v2->field_2 & 0x20) )
  {
    v3 = &pDecorationList->pDecorations[v2->uDecorationDescID];
    v4 = v3->uFlags;
    if ( (char)v4 >= 0 )
    {
      if ( !(v4 & DECORATION_DONT_DRAW) )
      {
        v6 = v2->vPosition.x;
        v7 = v2->vPosition.z;
        a2 = v2->vPosition.y;
        a1 = v6;
        a3 = v7;
        v8 = v2->field_10_y_rot
           + ((signed int)stru_5C6E00->uIntegerPi >> 3)
           - stru_5C6E00->Atan2(v6 - pBLVRenderParams->vPartyPos.x, a2 - pBLVRenderParams->vPartyPos.y);
        v37 = pBLVRenderParams->field_0_timer_;
        v9 = ((signed int)(stru_5C6E00->uIntegerPi + v8) >> 8) & 7;
        if ( pParty->bTurnBasedModeOn == 1 )
          v37 = pMiscTimer->uTotalGameTimeElapsed;
        v10 = abs(v2->vPosition.x + v2->vPosition.y);
        v11 = pSpriteFrameTable->GetFrame(v3->uSpriteID, v37 + v10);
        v30 = 0;
        v12 = v11;
        v13 = v11->uFlags;
        if ( v13 & 2 )
          v30 = 2;
        if ( v13 & 0x40000 )
          v30 |= 0x40u;
        if ( v13 & 0x20000 )
          LOBYTE(v30) = v30 | 0x80;
        if ( (256 << v9) & v13 )
          v30 |= 4u;
        if ( pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(a1, a2, a3, &x, &y, &z, 1) )
        {
          v14 = abs(x);
          if ( v14 >= abs(y) )
          {
            pGame->pIndoorCameraD3D->Project(x, y, z, &a5, &a6);
            v15 = &pBillboardRenderList[uNumBillboardsToDraw];
            if ( (signed int)uNumBillboardsToDraw < 500 )
            {
              ++uNumBillboardsToDraw;
              ++uNumDecorationsDrawnThisFrame;
              v16 = pRenderer->pRenderD3D == 0;
              v15->uHwSpriteID = v12->pHwSpriteIDs[v9];
              v15->uPalette = v12->uPaletteIndex;
              v15->uIndoorSectorID = LOWORD(v31);
              if ( v16 )
              {
                LODWORD(v21) = pBLVRenderParams->field_40 << 16;
                HIDWORD(v21) = pBLVRenderParams->field_40 >> 16;
                v37 = v21 / x;
                LODWORD(v31) = v12->scale;
                v37 = v21 / x;
                v15->_screenspace_x_scaler_packedfloat = (unsigned __int64)(SLODWORD(v31) * v21 / x) >> 16;
                v37 = (unsigned __int64)(v12->scale * (signed __int64)v37) >> 16;
              }
              else
              {
                v17 = &pGame->pIndoorCameraD3D;
                v15->fov_x = pGame->pIndoorCameraD3D->fov_x;
                v18 = (*v17)->fov_y;
                v19 = v15->fov_x;
                v15->fov_y = v18;
                v31 = v19;
                v25 = v19 + 6.7553994e15;
                LODWORD(v20) = 0;
                HIDWORD(v20) = SLOWORD(v25);
                v37 = v20 / x;
                LODWORD(v31) = v12->scale;
                v37 = (unsigned __int64)(SLODWORD(v31) * v20 / x) >> 16;
                v15->_screenspace_x_scaler_packedfloat = (unsigned __int64)(SLODWORD(v31) * v20 / x) >> 16;
                v31 = v15->fov_y;
                v25 = v31 + 6.7553994e15;
                LODWORD(v20) = 0;
                HIDWORD(v20) = SLOWORD(v25);
                v37 = v20 / x;
                v37 = (unsigned __int64)(v12->scale * v20 / x) >> 16;
              }
              HIWORD(v22) = HIWORD(x);
              v15->_screenspace_y_scaler_packedfloat = v37;
              v15->field_1E = v30;
              v15->some_x = a1;
              v15->some_y = a2;
              v15->some_z = a3;
              v15->uScreenSpaceX = a5;
              v15->uScreenSpaceY = a6;
              v23 = 8 * v26;
              LOBYTE(v23) = 8 * v26 | 5;
              LOWORD(v22) = 0;
              v15->uTintColor = 0;
              v15->sZValue = v22 + v23;
              v15->pSpriteFrame = v12;
            }
          }
        }
      }
    }
    else
    {
      memset(&local_0, 0, 0x68u);               // fire,  like at the Pit's tavern
      v5 = (double)v2->vPosition.x;
      local_0.bFree = 1036;
      local_0.uDiffuse = 0xFF3C1Eu;
      local_0.x = v5;
      local_0.y = (double)v2->vPosition.y;
      local_0.z = (double)v2->vPosition.z;
      local_0.flt_10 = 0.0;
      local_0.flt_14 = 0.0;
      local_0.flt_18 = 0.0;
      local_0.flt_28 = 1.0;
      local_0.timeToLive = (rand() & 0x80) + 128;
      local_0.uTextureID = pBitmaps_LOD->LoadTexture("effpar01");
      pGame->pParticleEngine->AddParticle(&local_0);
    }
  }
}


//----- (0044028F) --------------------------------------------------------
void PrepareItemsRenderList_BLV()
{
  ObjectDesc *v1; // ebx@4
  __int16 v2; // ax@5
  RenderBillboard *v3; // esi@12
  SpriteFrame *v4; // eax@12
  SpriteFrame *v5; // ebx@12
  unsigned int v6; // eax@12
  int v7; // ecx@12
  int v8; // edx@12
  int v9; // ecx@12
  unsigned __int16 v10; // ax@12
  int *v11; // eax@20
  char v12; // zf@26
  int v18; // ST5C_4@27
  signed __int64 v19; // qtt@28
  int v20; // ST5C_4@28
  int v21; // edx@29
  __int16 v22; // ax@29
  int v23; // eax@29
  SpriteFrame *v24; // [sp+1Ch] [bp-40h]@12
  __int16 a5; // [sp+28h] [bp-34h]@12
  int a6; // [sp+2Ch] [bp-30h]@12
  int a2; // [sp+30h] [bp-2Ch]@12
  int a1; // [sp+34h] [bp-28h]@12
  int v30; // [sp+38h] [bp-24h]@12
  int v31; // [sp+38h] [bp-24h]@27
  int a3; // [sp+40h] [bp-1Ch]@12
  signed __int16 v34; // [sp+44h] [bp-18h]@14
  int v35; // [sp+48h] [bp-14h]@25
  int v36; // [sp+4Ch] [bp-10h]@25
  signed int z; // [sp+50h] [bp-Ch]@24
  signed int y; // [sp+54h] [bp-8h]@24
  signed int x; // [sp+58h] [bp-4h]@24

  for (uint i = 0; i < uNumLayingItems; ++i)
  {
    auto p = pLayingItems + i;
    if (p->uObjectDescID)
    {
      v1 = &pObjectList->pObjects[p->uObjectDescID];
        if ( !(v1->uFlags & 1) )
         {
          if ( ((v2 = p->uItemType, v2 < 1000) || v2 >= 10000)
            && (v2 < 500 || v2 >= 600)
            && (v2 < 811 || v2 >= 815)
            || pGame->pStru6Instance->_4A81CA(p))
          {
            a5 = p->uSectorID;
            a1 = p->vPosition.x;
            a2 = p->vPosition.y;
            a3 = p->vPosition.z;
            v3 = &pBillboardRenderList[uNumBillboardsToDraw];
            v4 = pSpriteFrameTable->GetFrame(v1->uSpriteID, p->uSpriteFrameID);
            v5 = v4;
            v24 = v4;
            v30 = v4->uFlags;
            a6 = v4->uGlowRadius * p->field_22;
            v6 = stru_5C6E00->Atan2(
                   p->vPosition.x - pBLVRenderParams->vPartyPos.x,
                   p->vPosition.y - pBLVRenderParams->vPartyPos.y);
            LOWORD(v7) = p->uFacing;
            v8 = v30;
            v9 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + v7 - v6) >> 8) & 7;
            v10 = v5->pHwSpriteIDs[v9];
            v3->uHwSpriteID = v10;
            if ( v30 & 0x20 )
            {
              v8 = v30;
              a3 -= (signed int)((unsigned __int64)(v5->scale
                                                  * (signed __int64)pSprites_LOD->pSpriteHeaders[(signed __int16)v10].uHeight) >> 16) >> 1;
            }
            v34 = 0;
            if ( v8 & 2 )
              v34 = 2;
            if ( v8 & 0x40000 )
              v34 |= 0x40u;
            if ( v8 & 0x20000 )
              LOBYTE(v34) = v34 | 0x80;
            v11 = (int *)(256 << v9);
            if ( (256 << v9) & v8 )
              v34 |= 4u;
            if ( a6 )
            {
              LOBYTE(v11) = byte_4E94D3;
              pMobileLightsStack->AddLight(
                a1,
                a2,
                a3,
                a5,
                a6,
                v1->uParticleTrailColorR,
                v1->uParticleTrailColorG,
                v1->uParticleTrailColorB,
                byte_4E94D3);
            }
            if ( pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(
                   a1,
                   a2,
                   a3,
                   &x,
                   &y,
                   &z,
                   1) )
            {
              pGame->pIndoorCameraD3D->Project(x, y, z, &v36, &v35);
              if ( (signed int)uNumBillboardsToDraw >= 500 )
                return;
              ++uNumBillboardsToDraw;
              ++uNumSpritesDrawnThisFrame;
              p->uAttributes |= 1u;
              v12 = pRenderer->pRenderD3D == 0;
              v3->uPalette = v24->uPaletteIndex;
              v3->uIndoorSectorID = a5;
              if ( v12 )
              {
                LODWORD(v19) = pBLVRenderParams->field_40 << 16;
                HIDWORD(v19) = pBLVRenderParams->field_40 >> 16;
                v20 = v19 / x;
                v3->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v24->scale * v19 / x) >> 16;
                v31 = (unsigned __int64)(v24->scale * (signed __int64)v20) >> 16;
              }
              else
              {
                v3->fov_x = pGame->pIndoorCameraD3D->fov_x;
                v3->fov_y = pGame->pIndoorCameraD3D->fov_y;
                v18 = (int)floorf(v3->fov_x + 0.5f) / x;
                v3->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v24->scale * (__int64)v18) >> 16;
                v31 = (unsigned __int64)(v24->scale * (__int64)v18) >> 16;
              }
              HIWORD(v21) = HIWORD(x);
              v3->_screenspace_y_scaler_packedfloat = v31;
              v3->field_1E = v34;
              v3->some_x = a1;
              v3->some_y = a2;
              v3->some_z = a3;
              v3->uScreenSpaceX = v36;
              v22 = v35;
              v3->uTintColor = 0;
              v3->uScreenSpaceY = v22;
              LOWORD(v21) = 0;
              v23 = 8 * i;
              LOBYTE(v23) = 8 * i | 2;
              v3->pSpriteFrame = v24;
              v12 = (p->uAttributes & 0x20) == 0;
              v3->sZValue = v21 + v23;
              if ( !v12 )
              {
                if ( !pRenderer->pRenderD3D )
                  v3->sZValue = 0;
              }
            }
          }
        }
      }
  }
}



//----- (00440639) --------------------------------------------------------
void __fastcall sub_440639(int a1)
{
  int v1; // ebx@1
  signed int v2; // edi@1
  BLVSector *v3; // esi@1

  v1 = a1;
  v2 = 0;
  v3 = &pIndoor->pSectors[pBspRenderer->field_FA8[a1].uSectorID];
  if ( pRenderer->pRenderD3D )
  {
    if ( v3->uNumNonBSPFaces > 0 )
    {
      do
      {
        Log::Warning(L"Non-BSP face: %X", v3->pFaceIDs[v2]);
        pBspRenderer->PrepareFaceRenderList_d3d(v1, v3->pFaceIDs[v2++]);
      }
      while ( v2 < v3->uNumNonBSPFaces );
    }
  }
  else
  {
    if ( v3->uNumNonBSPFaces > 0 )
    {
      do
        pBspRenderer->PrepareFaceRenderList_sw(v1, v3->pFaceIDs[v2++]);
      while ( v2 < v3->uNumNonBSPFaces );
    }
  }
  if ( v3->field_0 & 0x10 )
    sub_4406BC(v1, v3->uFirstBSPNode);
}

//----- (004406BC) --------------------------------------------------------
void __fastcall sub_4406BC(int a1, unsigned int uFirstNode)
{
  BLVSector *v2; // esi@2
  BSPNode *v3; // edi@2
  BLVFace *v4; // eax@2
  int v5; // ecx@2
  __int16 v6; // ax@6
  int v7; // ebp@10
  int v8; // ebx@10
  __int16 v9; // di@18
  int v10; // [sp+10h] [bp-Ch]@1
  bool v11; // [sp+14h] [bp-8h]@5
  BspRenderer_stru0 *v12; // [sp+18h] [bp-4h]@1

  Log::Warning(L"sub_4406BC(%u, %u)", a1, uFirstNode);

  v10 = a1;
  v12 = &pBspRenderer->field_FA8[a1];
  while ( 1 )
  {
    v2 = &pIndoor->pSectors[v12->uSectorID];
    v3 = &pIndoor->pNodes[uFirstNode];
    v4 = &pIndoor->pFaces[v2->pFaceIDs[v3->uCoplanarOffset]];
    v5 = v4->pFacePlane_old.dist
       + pBLVRenderParams->vPartyPos.x * v4->pFacePlane_old.vNormal.x
       + pBLVRenderParams->vPartyPos.y * v4->pFacePlane_old.vNormal.y
       + pBLVRenderParams->vPartyPos.z * v4->pFacePlane_old.vNormal.z;
    if ( v4->uAttributes & 1 && v4->uSectorID != v12->uSectorID )
      v5 = -v5;
    v11 = v5 > 0;
    if ( v5 <= 0 )
      v6 = v3->uFront;
    else
      v6 = v3->uBack;
    if ( v6 != -1 )
      sub_4406BC(v10, v6);
    v7 = v3->uCoplanarOffset;
    v8 = v7 + v3->uCoplanarSize;

    Log::Warning(L"Node %u: %X to %X (%hX)", uFirstNode, v7, v8, v2->pFaceIDs[v7]);
    
    if ( pRenderer->pRenderD3D )
    {
      while ( v7 < v8 )
        pBspRenderer->PrepareFaceRenderList_d3d(v10, v2->pFaceIDs[v7++]);
    }
    else
    {
      while ( v7 < v8 )
        pBspRenderer->PrepareFaceRenderList_sw(v10, v2->pFaceIDs[v7++]);
    }
    v9 = v11 ? v3->uFront : v3->uBack;
    if ( v9 == -1 )
      break;
    uFirstNode = v9;
  }
}

//----- (00440DF5) --------------------------------------------------------
int stru167_wrap::Push(__int16 a2, __int16 a3, __int16 a4, int a5, __int16 bgr)
{
  int result; // eax@1

  pElements[uNumElements].field_6_rnd_value = a2;
  pElements[uNumElements].field_8_rnd_value = a3;
  pElements[uNumElements].field_A_rnd_value = a4;
  pElements[uNumElements].field_C_time_left = rand() % 64 + 256;
  pElements[uNumElements].field_E_time_to_live = pElements[uNumElements].field_C_time_left;
  result = 3 * uNumElements;
  pElements[uNumElements++].bgr16 = bgr;
  if (uNumElements >= 100 )
    uNumElements = 0;
   return result;
}

//----- (00440E91) --------------------------------------------------------
void stru167_wrap::_440E91(__int16 x, int y, int z, int a5, __int16 bgr)
{
  stru167_wrap *v6; // edi@1
  int i; // esi@1
  int v8; // ST08_4@2
  int v9; // ST04_4@2
  int v10; // eax@2

  v6 = this;
  for ( i = 0; i < rand() % 6 + 5; ++i )
  {
    v8 = z + rand() % 33;
    v9 = rand() % 33 + y - 16;
    v10 = rand();
    Push(v10 % 33 + x - 16, v9, v8, a5, bgr);
  }
}

//----- (00440F07) --------------------------------------------------------
void stru167_wrap::_440F07()
{
  for (uint i = 0; i < 100; ++i)
  {
    if (pElements[i].field_C_time_left > 0)
    {
      pElements[i].field_A_rnd_value += rand() % 5 + 4;
      pElements[i].field_6_rnd_value += rand() % 5 - 2;
      pElements[i].field_8_rnd_value += rand() % 5 - 2;
      pElements[i].field_C_time_left -= (short)pEventTimer->uTimeElapsed;
    }
  }
}

//----- (0044100D) --------------------------------------------------------
bool __cdecl sub_44100D()
{
  return pCurrentScreen == SCREEN_NPC_DIALOGUE
      || pCurrentScreen == SCREEN_CHARACTERS
      || pCurrentScreen > SCREEN_LOADGAME
      && (pCurrentScreen <= SCREEN_E
       || pCurrentScreen > SCREEN_VIDEO
       && (pCurrentScreen <= SCREEN_INPUT_BLV
        || pCurrentScreen == SCREEN_CASTING));
}
// 4E28F8: using guessed type int pCurrentScreen;

//----- (00441498) --------------------------------------------------------
void __cdecl GameUI_DrawTorchlightAndWizardEye()
{
  unsigned int v0; // eax@15
  IconFrame *v1; // eax@15
  unsigned int v2; // eax@19
  IconFrame *v3; // eax@19

  if ( !pCurrentScreen
    || pCurrentScreen == SCREEN_MENU
    || pCurrentScreen == SCREEN_OPTIONS
    || pCurrentScreen == SCREEN_REST
    || pCurrentScreen == SCREEN_SPELL_BOOK
    || pCurrentScreen == SCREEN_CHEST
    || pCurrentScreen == SCREEN_SAVEGAME
    || pCurrentScreen == SCREEN_LOADGAME
    || pCurrentScreen == SCREEN_F
    || pCurrentScreen == SCREEN_BOOKS
    || pCurrentScreen == SCREEN_BRANCHLESS_NPC_DIALOG )
  {
    if ( SHIDWORD(pParty->pPartyBuffs[16].uExpireTime) >= 0
      && (SHIDWORD(pParty->pPartyBuffs[16].uExpireTime) > 0 || LODWORD(pParty->pPartyBuffs[16].uExpireTime)) )
    {
      v0 = pEventTimer->Time();
      v1 = pIconsFrameTable->GetFrame((signed __int16)pUIAnum_Torchlight->uIconID, v0);
      pRenderer->DrawTextureTransparent(
        pUIAnum_Torchlight->x,
        pUIAnum_Torchlight->y,
        &pIcons_LOD->pTextures[v1->uTextureID]);
    }
    if ( SHIDWORD(pParty->pPartyBuffs[19].uExpireTime) >= 0
      && (SHIDWORD(pParty->pPartyBuffs[19].uExpireTime) > 0 || LODWORD(pParty->pPartyBuffs[19].uExpireTime)) )
    {
      v2 = pEventTimer->Time();
      v3 = pIconsFrameTable->GetFrame((signed __int16)pUIAnim_WizardEye->uIconID, v2);
      pRenderer->DrawTextureTransparent(
        pUIAnim_WizardEye->x,
        pUIAnim_WizardEye->y,
        &pIcons_LOD->pTextures[v3->uTextureID]);
    }
  }
}
// 4E28F8: using guessed type int pCurrentScreen;

//----- (0044158F) --------------------------------------------------------
void __cdecl GameUI_DrawCharacterSelectionFrame()
{
  if ( uActiveCharacter )
    pRenderer->DrawTextureTransparent(
      pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[uActiveCharacter - 1] - 9,
      0x17Cu,
      &pIcons_LOD->pTextures[dword_50C98C]);
}


//----- (004415C5) --------------------------------------------------------
void __cdecl Load_isn_spells_21_27()
{
  signed int v0; // esi@1
  char pContainer[120]; // [sp+8h] [bp-20h]@2

  v0 = 0;
  do
  {
    sprintf(pContainer, "isn-%02d", v0 + 1);
    pTextureIDs_isns[v0++] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
  }
  while ( v0 < 14 );
  uIconIdx_Spell21 = pIconsFrameTable->FindIcon("spell21");
  uIconIdx_Spell27 = pIconsFrameTable->FindIcon("spell27");
}

//----- (0044162D) --------------------------------------------------------
void __cdecl GameUI_DrawPartySpells()
{
  unsigned int v0; // ebp@1
  signed int v1; // edi@1
  int v2; // eax@2
  int v3; // ecx@5
  __int16 *v4; // ebx@25
  Player *v5; // edi@26
  unsigned int v6; // [sp-4h] [bp-1Ch]@11
  Texture *v7; // [sp-4h] [bp-1Ch]@12
  unsigned int v8; // [sp-4h] [bp-1Ch]@20
  Texture *v9; // [sp-4h] [bp-1Ch]@21
  Player **v10; // [sp+10h] [bp-8h]@25

  v0 = (signed __int64)((double)GetTickCount() * 0.050000001);
  v1 = 0;
  do
  {
    v2 = (unsigned __int8)byte_4E5DD8[v1];
    if ( SHIDWORD(pParty->pPartyBuffs[v2].uExpireTime) >= 0
      && (SHIDWORD(pParty->pPartyBuffs[v2].uExpireTime) > 0 || LODWORD(pParty->pPartyBuffs[v2].uExpireTime) > 0) )
    {
      v3 = pTextureIDs_isns[v1];
      pRenderer->_4A65CC(
        pPartySpellbuffsUI_XYs[v1][0],
        pPartySpellbuffsUI_XYs[v1][1],
        (Texture *)(v3 != -1 ? &pIcons_LOD->pTextures[v3] : 0),
        (Texture *)(v3 != -1 ? &pIcons_LOD->pTextures[v3] : 0),
        v0 + 20 * pPartySpellbuffsUI_smthns[v1],
        0,
        63);
    }
    ++v1;
  }
  while ( v1 < 14 );
  if ( !pCurrentScreen
    || pCurrentScreen == SCREEN_NPC_DIALOGUE )
  {
    if ( (signed __int64)pParty->pPartyBuffs[7].uExpireTime > 0 )
    {
      if ( pParty->bFlying )
        v6 = v0;
      else
        v6 = 0;
      v7 = &pIcons_LOD->pTextures[pIconsFrameTable->GetFrame(uIconIdx_Spell21, v6)->uTextureID];
      if ( pRenderer->pRenderD3D )
        pRenderer->DrawTextureIndexed(8u, 8u, v7);
      else
        pRenderer->DrawTextureTransparent(8u, 8u, v7);
    }
    if ( SHIDWORD(pParty->pPartyBuffs[18].uExpireTime) >= 0
      && (SHIDWORD(pParty->pPartyBuffs[18].uExpireTime) > 0 || LODWORD(pParty->pPartyBuffs[18].uExpireTime)) )
    {
      if ( pParty->uFlags & 0x80 )
        v8 = v0;
      else
        v8 = 0;
      v9 = &pIcons_LOD->pTextures[pIconsFrameTable->GetFrame(uIconIdx_Spell27, v8)->uTextureID];
      if ( pRenderer->pRenderD3D )
        pRenderer->DrawTextureIndexed(396u, 8u, v9);
      else
        pRenderer->DrawTextureTransparent(396u, 8u, v9);
    }
  }

  uint _it = 0;
  v10 = &pPlayers[1];
  v4 = pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing;
  do
  {
    v5 = *v10;
    if ( (signed __int64)(*v10)->pPlayerBuffs[6].uExpireTime > 0 )
      pRenderer->DrawTextureIndexed(
        *v4 + 72,
        0x1ABu,
        (Texture *)(dword_507964 != -1 ? &pIcons_LOD->pTextures[dword_507964] : 0));
    if ( (signed __int64)v5->pPlayerBuffs[1].uExpireTime > 0 )
      pRenderer->DrawTextureIndexed(
        *v4 + 72,
        0x189u,
        (Texture *)(dword_50796C != -1 ? &pIcons_LOD->pTextures[dword_50796C] : 0));
    if ( (signed __int64)v5->pPlayerBuffs[11].uExpireTime > 0 )
      pRenderer->DrawTextureIndexed(
        *v4 + 72,
        0x19Au,
        (Texture *)(dword_507968 != -1 ? &pIcons_LOD->pTextures[dword_507968] : 0));
    if ( (signed __int64)v5->pPlayerBuffs[10].uExpireTime > 0 )
      pRenderer->DrawTextureIndexed(
        *v4 + 72,
        0x1BCu,
        (Texture *)(dword_507960 != -1 ? &pIcons_LOD->pTextures[dword_507960] : 0));
    ++v10;
    ++v4;
  }
  //while ( (signed int)v4 < (signed int)pBaseHealthByClass );
  while (++_it != 4);
}


//----- (00441A4E) --------------------------------------------------------
__int16 __fastcall sub_441A4E(int a1)
{
  __int16 result; // ax@1
  int v2; // ebx@1
  char *v3; // esi@1
  int v4; // edi@4
  int v5; // ecx@4
  SpriteFrame *v6; // eax@6
  SpriteFrame *v7; // edi@6
  int v8; // eax@6
  unsigned __int16 v9; // ax@6
  RenderBillboardTransform_local0 v10; // [sp+Ch] [bp-5Ch]@1
  int v11; // [sp+5Ch] [bp-Ch]@6
  int v12; // [sp+60h] [bp-8h]@1
  int v13; // [sp+64h] [bp-4h]@6

  v10.uParentBillboardID = -1;
  v10.pTarget = pRenderer->pTargetSurface;
  v10.pTargetZ = pRenderer->pActiveZBuffer;
  v10.uTargetPitch = pRenderer->field_10;
  result = 0;
  v2 = a1;
  v10.uViewportX = 0;
  v10.uViewportY = 0;
  v10.uViewportZ = 639;
  v10.uViewportW = 479;
  v12 = 0;
  v3 = (char *)&pOtherOverlayList->pOverlays[0].field_C;
  do
  {
    if ( *((short *)v3 - 3) > 0 )
    {
      result = *((short *)v3 - 6);
      if ( result >= 300 )
      {
        v4 = result;
        v5 = result == v2 + 320 | result == v2 + 330 | result == v2 + 340 | result == v2 + 350;
        result = v2 + 310;
        if ( v4 == v2 + 310 | v5 )
        {
          if ( !*(short *)v3 )
          {
            v6 = pSpriteFrameTable->GetFrame(
                   pOverlayList->pOverlays[*((short *)v3 - 5)].uSpriteFramesetID,
                   *((short *)v3 - 4));
            v7 = v6;
            v11 = *((int *)v3 + 1);
            v13 = v6->scale;
            v13 = (unsigned __int64)(v11 * (signed __int64)v13) >> 16;
            v10.uScreenSpaceX = *((short *)v3 - 2);
            v10.uScreenSpaceY = *((short *)v3 - 1);
            v10._screenspace_x_scaler_packedfloat = v13;
            v10._screenspace_y_scaler_packedfloat = v13;
            v10.pPalette = PaletteManager::Get_Dark_or_Red_LUT(v6->uPaletteIndex, 0, 1);
            v8 = *((short *)v3 - 5);
            v10.sZValue = 0;
            v10.uFlags = 0;
            v9 = pOverlayList->pOverlays[v8].uOverlayType;
            if ( !v9 || v9 == 2 )
              v10.uScreenSpaceY += pSprites_LOD->pSpriteHeaders[v7->pHwSpriteIDs[0]].uHeight >> 1;
            result = pSprites_LOD->pSpriteHeaders[v7->pHwSpriteIDs[0]]._4AD2D1(&v10, 0);
            ++v12;
            if ( v12 == 5 )
              break;
          }
        }
      }
    }
    v3 += 20;
  }
  while ( (signed int)v3 < (signed int)&pOverlayList->pOverlays );
  return result;
}



//----- (00441D38) --------------------------------------------------------
void GameUI_DrawMinimap(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW, unsigned int uZoom, unsigned int bRedrawOdmMinimap)
{
  int uHeight; // ebx@6
  __int16 v11; // cx@11
  unsigned int v14; // ebx@23
  int v15; // eax@23
  __int16 v17; // di@30
  double v18; // st7@30
  float v19; // ST38_4@30
  double v20; // st7@30
  double v21; // st6@30
  double v22; // st5@33
  signed int v27; // eax@37
  unsigned __int16 *v28; // ecx@37
  signed int v29; // edi@40
  signed int v33; // ebx@50
  unsigned int v34; // eax@50
  signed int v35; // ecx@50
  unsigned __int16 v36; // di@66
  int v37; // edi@72
  int v38; // ebx@72
  __int16 v39; // ax@87
  int v40; // edi@91
  int v41; // ebx@91
  unsigned int v42; // eax@101
  unsigned int v43; // ebx@101
  unsigned int v44; // ST30_4@101
  char *v45; // ebx@106
  int v46; // edi@108
  int v47; // eax@108
  unsigned int v48; // ebx@114
  unsigned int v49; // ST64_4@114
  unsigned int v51; // [sp-10h] [bp-64h]@79
  unsigned int v52; // [sp-10h] [bp-64h]@100
  unsigned int v53; // [sp-Ch] [bp-60h]@79
  unsigned int v54; // [sp-Ch] [bp-60h]@100
  unsigned int v55; // [sp-8h] [bp-5Ch]@77
  unsigned int v56; // [sp-8h] [bp-5Ch]@100
  signed int v57; // [sp-4h] [bp-58h]@54
  unsigned __int16 v58; // [sp-4h] [bp-58h]@77
  unsigned __int16 v59; // [sp-4h] [bp-58h]@100
  unsigned __int16 v60; // [sp+10h] [bp-44h]@66
  unsigned int v61; // [sp+10h] [bp-44h]@85
  unsigned int v63; // [sp+14h] [bp-40h]@85
  unsigned int v65; // [sp+18h] [bp-3Ch]@85
  unsigned int lPitch; // [sp+20h] [bp-34h]@1
  unsigned int lPitcha; // [sp+20h] [bp-34h]@23
  char *lPitchb; // [sp+20h] [bp-34h]@106
  unsigned int v69; // [sp+24h] [bp-30h]@23
  signed int v70; // [sp+24h] [bp-30h]@37
  unsigned __int16 uBlue; // [sp+28h] [bp-2Ch]@1
  signed int uBluea; // [sp+28h] [bp-2Ch]@37
  int v73; // [sp+2Ch] [bp-28h]@30
  int v76; // [sp+34h] [bp-20h]@91
  int v77; // [sp+34h] [bp-20h]@108
  int v79; // [sp+38h] [bp-1Ch]@72
  char *a2c; // [sp+40h] [bp-14h]@68
  signed int uCenterY; // [sp+48h] [bp-Ch]@1
  signed int uCenterX; // [sp+4Ch] [bp-8h]@1
  signed int uWidth; // [sp+5Ch] [bp+8h]@30
  signed int uZe; // [sp+5Ch] [bp+8h]@67
  signed int uZf; // [sp+5Ch] [bp+8h]@85
  signed int uZg; // [sp+5Ch] [bp+8h]@105
  unsigned int uWa; // [sp+60h] [bp+Ch]@23
  float uWb; // [sp+60h] [bp+Ch]@30
  unsigned int uWd; // [sp+60h] [bp+Ch]@95
  float uZooma; // [sp+64h] [bp+10h]@117
  unsigned int flagsb; // [sp+68h] [bp+14h]@66
  Actor *flagsc; // [sp+68h] [bp+14h]@86
  unsigned int flagsd; // [sp+68h] [bp+14h]@105

  uCenterX = (uX + uZ) / 2;
  uCenterY = (uY + uW) / 2;
  lPitch = pRenderer->uTargetSurfacePitch;
  GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 0, 0);
  uBlue = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 0, 0xFFu);
  auto bWizardEyeActive = pParty->WizardEyeActive();
  auto uWizardEyeSkillLevel = pParty->WizardEyeSkillLevel();
  if (CheckHiredNPCSpeciality(0x26u))
  {
    bWizardEyeActive = true;
    uWizardEyeSkillLevel = 2;
  }
  pRenderer->Clip_v2(uX, uY, uZ - 1, uW - 1);
  uHeight = uW - uY;
  uWidth = uZ - uX;

  if ( uCurrentlyLoadedLevelType != LEVEL_Indoor)
  {
    v17 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2;
    auto pMapLod0 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pLevelOfDetail0;
    auto pPal = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pPalette16;
    v73 = (1 << (v17 + 16)) / (signed int)uZoom;
    v18 = (double)(1 << (16 - v17));
    v19 = v18;
    v20 = (double)(pParty->vPosition.x + 32768) / v18;
    v21 = (double)(32768 - pParty->vPosition.y) / v19;
    uWb = v21;
    switch (uZoom)
    {
      case 512:
      {
        v20 = v20 - (double)(uWidth / 2);
        v22 = (double)(uHeight / 2);
        uWb = v21 - v22;
      }
      break;

      case 1024:
      {
        v20 = v20 - (double)(uWidth / 4);
        v22 = (double)(uHeight / 4);
        uWb = v21 - v22;
      }
      break;

      case 2048:
      {
        v20 = v20 - (double)(uWidth / 8);
        v22 = (double)(uHeight / 8);
        uWb = v21 - v22;
      }
      break;

      default: assert(false);
    }
    assert(sizeof(pOdmMinimap) == 137 * 117 * sizeof(short));

    v70 = floorf(v20 * 65536.0 + 0.5f);//LODWORD(v24);
    uBluea = floorf(uWb * 65536.0 + 0.5f);//LODWORD(v25);
    v27 = uBluea >> 16;
    v28 = &pRenderer->pTargetSurface[uX + uY * lPitch];
    if (pMapLod0 && bRedrawOdmMinimap)
    {
      assert(uWidth == 137 && uHeight == 117);
      //auto pMinimap = (unsigned __int16 *)pOdmMinimap;

        auto mapWidth = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uTextureWidth;

          v29 = v70 >> 16;

          for (int y = 0; y < uHeight; ++y)
          {
              auto pMapLod0Line = &pMapLod0[v27 * mapWidth];
              for (int x = 0; x < uWidth; ++x)
              {
                //*pMinimap++ = pPal[pMapLod0Line[v29]];
                pOdmMinimap[y][x] = pPal[pMapLod0Line[v29]];
                v29 = (v70 + x * v73) >> 16;
              }

            v29 = v70 >> 16;
            v28 += 137 - uWidth;
            uBluea += v73;
            v27 = uBluea >> 16;
          }
    }

    for (int y = 0; y < 117; ++y)
    {
      for (int x = 0; x < 137; ++x)
      {
        *v28++ = pOdmMinimap[y][x];
      }
      v28 += lPitch - 137;
    }
    uNumBlueFacesInBLVMinimap = 0;
  }
  else
  {
    pRenderer->FillRectFast(uX, uY, uZ - uX, uHeight, 0xF);
    uNumBlueFacesInBLVMinimap = 0;

    for (uint i = 0; i < pIndoor->pMapOutlines->uNumOutlines; ++i)
    {
      auto pOutline = &pIndoor->pMapOutlines->pOutlines[i];

      auto pFace1 = pIndoor->pFaces + pOutline->uFace1ID;
      auto pFace2 = pIndoor->pFaces + pOutline->uFace2ID;
      //v9 = pIndoor->pFaces[pMapVertex->uFace1ID].uAttributes;
        //v10 = pIndoor->pFaces[pMapVertex->uFace2ID].uAttributes;
      if (pFace1->Visible() && pFace2->Visible())
      {
        v11 = pOutline->uFlags;
        if ( v11 & 1 )
          goto LABEL_15;
        if (pFace1->uAttributes & 0x80 || pFace2->uAttributes & 0x80u != 0 )
          goto LABEL_ABC;

      }
      continue;

LABEL_ABC:
    pOutline->uFlags = v11 | 1;
    pIndoor->_visible_outlines[i >> 3] |= 1 << (7 - i % 8);

LABEL_15:
    //v12 = &pIndoor->pFaces[pOutline->uFace1ID];
    if (bWizardEyeActive && uWizardEyeSkillLevel >= 3 &&
        (pFace1->uAttributes & 0x2000000 || pFace2->uAttributes & 0x2000000) &&
        (pIndoor->pFaceExtras[pFace1->uFaceExtraID].uEventID || pIndoor->pFaceExtras[pFace2->uFaceExtraID].uEventID))
    {
      if (uNumBlueFacesInBLVMinimap < 49)
        pBlueFacesInBLVMinimapIDs[uNumBlueFacesInBLVMinimap++] = i;
    }
    else
    {
      auto _a = (uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x);
      auto _b = ((unsigned int)((unsigned __int64)_a >> 16) << 16);
      auto _c = ((signed int)(_b - uZoom * pParty->vPosition.x) >> 16);
      v69 =     uCenterX + _c;
      v69 =     uCenterX + ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16);
      lPitcha = uCenterY - ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16);
      uWa =     uCenterX + ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16);
      v14 =     uCenterY - ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16);
      v15 = abs(pOutline->sZ - pParty->vPosition.z) / 8;
      if ( v15 > 100 )
        v15 = 100;
      pRenderer->Line2D(v69, lPitcha, uWa, v14, viewparams->pPalette[-v15 + 200]);
    }
  }


  for (uint i = 0; i < uNumBlueFacesInBLVMinimap; ++i)
  {
    //v16 = (uint *)&pIndoor->pMapOutlines->pOutlines[pBlueFacesInBLVMinimapIDs[uZb]];
    auto pOutline = &pIndoor->pMapOutlines->pOutlines[pBlueFacesInBLVMinimapIDs[i]];
    pRenderer->Line2D(uCenterX + ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom
                                                     * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x) >> 16) << 16)
                  - uZoom * pParty->vPosition.x) >> 16),
      uCenterY
    - ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom
                                                     * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].y) >> 16) << 16)
                  - uZoom * pParty->vPosition.y) >> 16),
      uCenterX
    + ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom
                                                     * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].x) >> 16) << 16)
                  - uZoom * pParty->vPosition.x) >> 16),
      uCenterY
    - ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom
                                                     * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].y) >> 16) << 16)
                  - uZoom * pParty->vPosition.y) >> 16),
      uBlue);
  }
  }


//_draw_party_arrow:
  v33 = 0;
  v34 = pParty->sRotationY & stru_5C6E00->uDoublePiMask;
  v35 = 0;
  if ( (signed int)(pParty->sRotationY & stru_5C6E00->uDoublePiMask) < 128 )
    goto LABEL_66;
  if ( (signed int)v34 <= 384 )
  {
    v35 = 1;
    goto LABEL_66;
  }
  if ( (signed int)v34 >= 640 )
  {
    if ( (signed int)v34 > 896 )
    {
      if ( (signed int)v34 >= 1152 )
      {
        if ( (signed int)v34 > 1408 )
        {
          if ( (signed int)v34 >= 1664 )
          {
            if ( (signed int)v34 > 1920 )
              goto LABEL_66;
            v57 = 7;
          }
          else
          {
            v57 = 6;
          }
        }
        else
        {
          v57 = 5;
        }
      }
      else
      {
        v57 = 4;
      }
    }
    else
    {
      v57 = 3;
    }
  }
  else
  {
    v57 = 2;
  }
  v35 = v57;
LABEL_66:
  pRenderer->DrawTextureTransparent(uCenterX - 3, uCenterY - 3,
    (Texture *)(pTextureIDs_pMapDirs[v35] != -1 ? &pIcons_LOD->pTextures[pTextureIDs_pMapDirs[v35]] : 0));
  v36 = 255;
  flagsb = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 0, 0xFFu);
  v60 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0, 0);
  if ( bWizardEyeActive = true)
  {
    uZe = 0;
    //for (uint i = 0; i < uNumLayingItems; ++i)
    if (uNumLayingItems > 0)
    {
      a2c = (char *)&pLayingItems[0].uObjectDescID;
      while ( 1 )
      {
        if ( !*((short *)a2c - 1)
          || !*(short *)a2c
          || uWizardEyeSkillLevel == 1
          || (v37 = ((unsigned __int64)((*(int *)(a2c + 2) - pParty->vPosition.x) * (signed __int64)(signed int)uZoom) >> 16)
                  + uCenterX,
              v79 = (unsigned __int64)((*(int *)(a2c + 6) - pParty->vPosition.y) * (signed __int64)(signed int)uZoom) >> 16,
              v38 = uCenterY - v79,
              v37 < pRenderer->field_1C_clipx)
          || v37 > pRenderer->field_24_clipz
          || v38 < pRenderer->field_20_clipy
          || v38 > pRenderer->field_28_clipw )
          goto LABEL_83;
        if ( pObjectList->pObjects[*(short *)a2c].uFlags & 0x10 )
          break;
        if ( (signed int)uZoom > 512 )
        {
          pRenderer->Line2D(v37 - 1, v38 - 1, v37 - 1, v38 + 1, flagsb);
          pRenderer->Line2D(v37, v38 - 2, v37, v38 + 1, flagsb);
          pRenderer->Line2D(v37 + 1, v38 - 1, v37 + 1, v38 + 1, flagsb);
          pRenderer->Line2D(v37 - 2, v38, v37 - 2, v38 + 1, flagsb);
          v37 += 2;
          v58 = flagsb;
          v55 = v38 + 1;
          goto LABEL_81;
        }
        pRenderer->Line2D(v37 - 1, v38 - 1, v37 - 1, uCenterY - v79, flagsb);
        v58 = flagsb;
        v55 = uCenterY - v79;
        v53 = v37;
        v51 = v38 - 1;
LABEL_82:
        pRenderer->Line2D(v37, v51, v53, v55, v58);
LABEL_83:
        ++uZe;
        a2c += 112;
        if ( uZe >= (signed int)uNumLayingItems )
        {
          v36 = 255;
          v33 = 0;
          goto LABEL_85;
        }
      }
      v58 = v60;
      v55 = uCenterY - v79;
LABEL_81:
      v53 = v37;
      v51 = uCenterY - v79;
      goto LABEL_82;
    }
LABEL_85:
    v63 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(v36, 0, v33);
    v61 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, v36, v33);
    v65 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(v36, v36, v33);
    uZf = v33;
    if ( (signed int)uNumActors > v33 )
    {
      flagsc = pActors;//[0].uAIState;
      do
      {
		v39 = flagsc->uAIState;
		if ( flagsc->uAIState != 11 && v39 != 19 && (v39 == 5 || BYTE1(flagsc->uAttributes) & 0x80) )
        {
		  v40 = ((unsigned __int64)(( flagsc->vPosition.x - pParty->vPosition.x)
                                  * (signed __int64)(signed int)uZoom) >> 16)
              + uCenterX;
          v76 = (unsigned __int64)(( flagsc->vPosition.y - pParty->vPosition.y)
                                 * (signed __int64)(signed int)uZoom) >> 16;
          v41 = uCenterY - v76;
          if ( v40 >= pRenderer->field_1C_clipx )
          {
            if ( v40 <= pRenderer->field_24_clipz && v41 >= pRenderer->field_20_clipy && v41 <= pRenderer->field_28_clipw )
            {
              uWd = v61;
			  if ( BYTE3(flagsc->uAttributes) & 1 )
                uWd = v63;
              if ( flagsc->uAIState == 5 )
                uWd = v65;
              if ( (signed int)uZoom > 1024 )
              {
                pRenderer->Line2D(v40 - 1, v41 - 2, v40 - 1, v41 + 2, uWd);
                pRenderer->Line2D(v40, v41 - 2, v40, v41 + 2, uWd);
                pRenderer->Line2D(v40 + 1, v41 - 2, v40 + 1, v41 + 2, uWd);
                v42 = v41 + 1;
                v43 = v41 - 1;
                v44 = v42;
                pRenderer->Line2D(v40 - 2, v43, v40 - 2, v42, uWd);
                v40 += 2;
                v59 = uWd;
                v56 = v44;
                v54 = v40;
                v52 = v43;
              }
              else
              {
                pRenderer->Line2D(v40 - 1, v41 - 1, v40 - 1, uCenterY - v76, uWd);
                v59 = uWd;
                v56 = uCenterY - v76;
                v54 = v40;
                v52 = v41 - 1;
              }
              pRenderer->Line2D(v40, v52, v54, v56, v59);
            }
          }
        }
        ++uZf;
        ++flagsc;
      }
      while ( uZf < (signed int)uNumActors );
      v36 = 255;
      v33 = 0;
    }
  }
  flagsd = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(v36, v36, v36);
  uZg = v33;
  if ( (signed int)uNumLevelDecorations > v33 )
  {
    v45 = (char *)&pLevelDecorations[0].vPosition;
    lPitchb = (char *)&pLevelDecorations[0].vPosition;
    do
    {
      if ( *(v45 - 2) & 8 )
      {
        v46 = ((unsigned __int64)((*(int *)v45 - pParty->vPosition.x) * (signed __int64)(signed int)uZoom) >> 16)
            + uCenterX;
        v77 = (unsigned __int64)((*((int *)v45 + 1) - pParty->vPosition.y) * (signed __int64)(signed int)uZoom) >> 16;
        v47 = uCenterY - v77;
        if ( v46 >= pRenderer->field_1C_clipx )
        {
          if ( v46 <= pRenderer->field_24_clipz && v47 >= pRenderer->field_20_clipy && v47 <= pRenderer->field_28_clipw )
          {
            if ( (signed int)uZoom > 512 )
            {
              v48 = v47 + 1;
              v49 = v47 - 1;
              pRenderer->Line2D(v46 - 1, v47 - 1, v46 - 1, v47 + 1, flagsd);
              pRenderer->Line2D(v46, v49, v46, v48, flagsd);
              pRenderer->Line2D(v46 + 1, v49, v46 + 1, v48, flagsd);
              v45 = lPitchb;
            }
            else
            {
              pRenderer->Line2D(v46, uCenterY - v77, v46, uCenterY - v77, flagsd);
            }
          }
        }
      }
      ++uZg;
      v45 += 32;
      lPitchb = v45;
    }
    while ( uZg < (signed int)uNumLevelDecorations );
    v33 = 0;
  }
  pRenderer->DrawTextureTransparent(0x1D4u, v33, (Texture *)(dword_5079D8 != -1 ? &pIcons_LOD->pTextures[dword_5079D8] : 0));
  uZooma = (double)pParty->sRotationY * 0.1171875;
  //v50 = uZooma + 6.7553994e15;
  pRenderer->Clip(0x21Du, v33, 0x237u, 0x1E0u);
  pRenderer->DrawTextureIndexed(floorf(uZooma + 0.5f) + 285, 0x88u, (Texture *)(dword_5079B4 != -1 ? &pIcons_LOD->pTextures[dword_5079B4] : 0));
  pRenderer->ResetClip();
}


//----- (00442955) --------------------------------------------------------
int __fastcall DrawBook_Map_sub(unsigned int x, unsigned int y, unsigned int a4, int a5, int _48074)
{
  int v5; // ebx@1
  int v6; // edi@1
  unsigned int *v7; // eax@8
  unsigned __int8 v8; // zf@8
  unsigned __int8 v9; // sf@8
  int v10; // esi@10
  unsigned int v11; // edx@11
  __int16 v12; // cx@12
  signed int v13; // eax@15
  int v14; // eax@16
  Vec3_short_ *v15; // ecx@16
  int v16; // edx@16
  int v17; // ecx@16
  Vec3_short_ *v18; // eax@16
  int v19; // ecx@16
  int v20; // eax@16
  signed int v21; // esi@18
  int v22; // ecx@21
  int v23; // ecx@21
  Vec3_short_ *v24; // edx@21
  Vec3_short_ *v25; // eax@21
  int v26; // ecx@21
  unsigned __int16 *v27; // edi@21
  int v28; // edx@21
  int v29; // eax@21
  double v30; // st7@23
  signed __int64 v31; // qax@23
  char *v32; // edx@23
  int v33; // esi@23
  signed int v34; // eax@23
  signed int v35; // ecx@23
  int v36; // esi@27
  int v37; // ecx@27
  int v38; // edx@31
  unsigned int v39; // eax@33
  const void *v40; // esi@33
  unsigned __int16 *v41; // edi@33
  unsigned __int8 v42; // cf@33
  unsigned int v43; // ecx@33
  int v44; // edi@33
  int v45; // esi@33
  int v46; // ecx@33
  signed int v47; // esi@38
  signed int v48; // ecx@38
  int v49; // eax@38
  signed int v50; // edx@55
  unsigned int v51; // ecx@55
  int result; // eax@72
  int v53; // eax@75
  int v54; // esi@75
  int v55; // eax@75
  __int16 v56; // si@85
  double v57; // st7@85
  int v58; // ebx@85
  signed __int64 v59; // qax@85
  signed int v60; // edi@85
  signed __int64 v61; // qax@85
  signed int v62; // ebx@85
  signed int v63; // esi@85
  int v64; // eax@87
  unsigned int v65; // ebx@95
  char *v66; // edx@95
  unsigned __int16 *v67; // esi@96
  int v68; // edi@98
  unsigned __int16 v69; // cx@99
  unsigned int v70; // [sp-10h] [bp-48074h]@80
  unsigned int v71; // [sp-Ch] [bp-48070h]@80
  unsigned int v72; // [sp-8h] [bp-4806Ch]@80
  signed int v73; // [sp-4h] [bp-48068h]@59
  unsigned __int16 v74; // [sp-4h] [bp-48068h]@79
  char v75; // [sp+Ch] [bp-48058h]@23
  int v76; // [sp+4800Ch] [bp-58h]@23
  unsigned __int16 *v77; // [sp+48010h] [bp-54h]@27
  unsigned __int16 *v78; // [sp+48014h] [bp-50h]@23
  unsigned int v79; // [sp+48018h] [bp-4Ch]@1
  unsigned int y_; // [sp+4801Ch] [bp-48h]@1
  int v81; // [sp+48020h] [bp-44h]@23
  unsigned int x_; // [sp+48024h] [bp-40h]@1
  unsigned int teal; // [sp+48028h] [bp-3Ch]@8
  int v84; // [sp+4802Ch] [bp-38h]@1
  int v85; // [sp+48030h] [bp-34h]@1
  int v86; // [sp+48034h] [bp-30h]@1
  int v87; // [sp+48038h] [bp-2Ch]@16
  unsigned int v88; // [sp+4803Ch] [bp-28h]@16
  int black; // [sp+48040h] [bp-24h]@8
  int v90; // [sp+48044h] [bp-20h]@1
  unsigned int i; // [sp+48048h] [bp-1Ch]@9
  unsigned int v92; // [sp+4804Ch] [bp-18h]@16
  unsigned __int16 *v93; // [sp+48050h] [bp-14h]@16
  unsigned int v94; // [sp+48054h] [bp-10h]@8
  unsigned int v95; // [sp+48058h] [bp-Ch]@16
  int v96; // [sp+4805Ch] [bp-8h]@10
  const void *v97; // [sp+48060h] [bp-4h]@16
  char *a4a; // [sp+4806Ch] [bp+8h]@85
  int a5a; // [sp+48070h] [bp+Ch]@86

  x_ = x;
  y_ = y;
  v85 = (signed int)(x + a4) >> 1;
  v90 = (signed int)(y + a5) >> 1;
  v79 = pRenderer->uTargetSurfacePitch;
  pRenderer->Clip_v2(x, y, a4, a5);
  v5 = viewparams->field_2C;
  v6 = viewparams->sPartyPosX;
  v86 = viewparams->sPartyPosX;
  v84 = viewparams->sPartyPosZ;
  if ( viewparams->field_2C != 384 )
  {
    if ( viewparams->field_2C == 768 )
    {
      if ( uCurrentlyLoadedLevelType != LEVEL_Indoor)
        goto LABEL_23;
      v5 = 680;
    }
    if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
      goto LABEL_8;
LABEL_23:
    v94 = a4 - x_ + 1;
    v92 = a5 - y_ + 1;
    v93 = &pRenderer->pTargetSurface[x_ + y_ * v79];
    v95 = (unsigned int)pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pLevelOfDetail0;
    v78 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pPalette16;
    v87 = (1 << (pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2 + 16)) / v5;
    v30 = (double)(1 << (16 - pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2));
    black = 22528 / (v5 / 384);
    teal = (unsigned int)(signed __int64)((double)(v6 - 22528 / (v5 / 384) + 32768) / v30) << 16;
    v97 = (const void *)((unsigned int)(signed __int64)((double)(v6 - 22528 / (v5 / 384) + 32768) / v30) << 16);
    v96 = 32768 - black - v84;
    v31 = (signed __int64)((double)v96 / v30);
    v32 = &v75;
    v33 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uTextureWidth;
    v34 = (int)v31 << 16;
    v81 = (signed __int16)(signed __int64)((double)(v6 - 22528 / (v5 / 384) + 32768) / v30);
    black = (signed __int16)(signed __int64)((double)(v6 - 22528 / (v5 / 384) + 32768) / v30);
    v76 = v33;
    v35 = v34 >> 16;
    if ( v95 && (signed int)v92 > 0 )
    {
      v96 = v92;
      do
      {
        v88 = 0;
        if ( (signed int)v94 > 0 )
        {
          v36 = v95 + v35 * v76;
          i = v94;
          v88 = v94;
          v37 = black;
          v77 = (unsigned __int16 *)v36;
          do
          {
            *(short *)v32 = v78[*((char *)v77 + v37)];//crash
            v32 += 2;
            v97 = (char *)v97 + v87;
            v37 = (signed int)v97 >> 16;
            --i;
          }
          while ( i );
        }
        v34 += v87;
        v97 = (const void *)teal;
        black = v81;
        v32 += 2 * (v94 - v88);
        v35 = v34 >> 16;
        --v96;
      }
      while ( v96 );
    }
    v97 = &v75;
    if ( (signed int)v92 > 0 )
    {
      v96 = v92;
      v38 = 2 * (v79 - v94);
      do
      {
        if ( (signed int)v94 > 0 )
        {
          v39 = v94;
          v40 = v97;
          v41 = v93;
          v42 = v94 & 1;
          v43 = v94 >> 1;
          memcpy(v93, v97, 4 * (v94 >> 1));
          v45 = (int)((char *)v40 + 4 * v43);
          v44 = (int)&v41[2 * v43];
          v46 = v42;
          v39 *= 2;
          v93 = (unsigned __int16 *)((char *)v93 + v39);
          v97 = (char *)v97 + v39;
          while ( v46 )
          {
            *(short *)v44 = *(short *)v45;
            v45 += 2;
            v44 += 2;
            --v46;
          }
          v6 = v86;
        }
        v93 = (unsigned __int16 *)((char *)v93 + v38);
        --v96;
      }
      while ( v96 );
    }
    goto LABEL_38;
  }
  v6 = viewparams->field_38;
  v86 = viewparams->field_38;
  v84 = viewparams->field_3A;
  if ( uCurrentlyLoadedLevelType != LEVEL_Indoor)
    goto LABEL_23;
  v5 = viewparams->field_2C - 34;
LABEL_8:
  black = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 0, 0);
  teal = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 0xFFu, 0xFFu);
  v7 = (uint *)pIndoor->pMapOutlines;
  uNumBlueFacesInBLVMinimap = 0;
  v8 = pIndoor->pMapOutlines->uNumOutlines == 0;
  v9 = (pIndoor->pMapOutlines->uNumOutlines & 0x80000000u) != 0;
  v94 = 0;
  if ( !(v9 | v8) )
  {
    i = 0;
    do
    {
      v10 = (int)((char *)v7 + i + 4);
      v96 = pIndoor->pFaces[*(short *)((char *)v7 + i + 8)].uAttributes;
      if ( BYTE1(v96) & 0x20 || (v11 = pIndoor->pFaces[*(short *)((char *)v7 + i + 10)].uAttributes, BYTE1(v11) & 0x20) )
        goto LABEL_17;
      v12 = *(short *)((char *)v7 + i + 14);
      if ( !(v12 & 1) )
      {
        if ( !(v96 & 0x80) && (v11 & 0x80u) == 0 )
          goto LABEL_17;
        v96 = (signed int)v94 >> 3;
        v13 = v94;
        *(short *)(v10 + 10) = v12 | 1;
        pIndoor->_visible_outlines[v96] |= 1 << (7 - v13 % 8);
      }
      v14 = *(short *)v10;
      v88 = v5;
      v15 = &pIndoor->pVertices[v14];
      v16 = v15->x;
      v17 = v15->y - v84;
      v93 = (unsigned __int16 *)(v16 - v6);
      v92 = v17;
      v18 = &pIndoor->pVertices[*(short *)(v10 + 2)];
      v19 = v18->x;
      v20 = v18->y - v84;
      v95 = v19 - v6;
      v97 = (const void *)v20;
      v88 = (unsigned __int64)((v16 - v6) * (signed __int64)v5) >> 16;
      v87 = (unsigned __int64)((signed int)v92 * (signed __int64)v5) >> 16;
      v93 = (unsigned __int16 *)((unsigned __int64)((v19 - v6) * (signed __int64)v5) >> 16);
      v92 = (unsigned __int64)(v20 * (signed __int64)v5) >> 16;
      pRenderer->Line2D(
        v85 + v88,
        v90 - v87,
        v85 + ((unsigned __int64)((v19 - v6) * (signed __int64)v5) >> 16),
        v90 - v92,
        black);
      v7 = (uint *)pIndoor->pMapOutlines;
LABEL_17:
      ++v94;
      i += 12;
    }
    while ( (signed int)v94 < (signed int)*v7 );
  }
  v21 = 0;
  if ( (signed int)uNumBlueFacesInBLVMinimap > 0 )
  {
    while ( 1 )
    {
      v22 = pBlueFacesInBLVMinimapIDs[v21];
      v87 = v5;
      v23 = (int)&v7[3 * v22 + 1];
      v24 = &pIndoor->pVertices[*(short *)v23];
      v25 = &pIndoor->pVertices[*(short *)(v23 + 2)];
      v26 = v25->x;
      v27 = (unsigned __int16 *)(v24->x - v86);
      v28 = v24->y - v84;
      v29 = v25->y - v84;
      v93 = v27;
      v92 = v28;
      v97 = (const void *)v29;
      v87 = (unsigned __int64)((signed int)v27 * (signed __int64)v5) >> 16;
      v88 = (unsigned __int64)(v28 * (signed __int64)v5) >> 16;
      i = (unsigned __int64)((v26 - v86) * (signed __int64)v5) >> 16;
      v95 = (unsigned __int64)(v29 * (signed __int64)v5) >> 16;
      pRenderer->Line2D(
        v85 + ((unsigned __int64)((signed int)v27 * (signed __int64)v5) >> 16),
        v90 - v88,
        v85 + ((unsigned __int64)((v26 - v86) * (signed __int64)v5) >> 16),
        v90 - v95,
        teal);
      ++v21;
      if ( v21 >= (signed int)uNumBlueFacesInBLVMinimap )
        break;
      v7 = (uint *)pIndoor->pMapOutlines;
    }
    v6 = v86;
  }
LABEL_38:
  v47 = ((unsigned __int64)((pParty->vPosition.x - v6) * (signed __int64)v5) >> 16) + v85 - 3;
  v81 = pParty->vPosition.y - v84;
  v97 = (const void *)((unsigned __int64)((pParty->vPosition.y - v84) * (signed __int64)v5) >> 16);
  v48 = 1;
  v49 = v90 - (int)v97 - 3;
  if ( v47 >= (signed int)x_ )
  {
    if ( v47 > (signed int)a4 )
    {
      if ( (signed int)(((unsigned __int64)((pParty->vPosition.x - v6) * (signed __int64)v5) >> 16) + v85 - 6) > (signed int)a4 )
        v48 = 0;
      v47 = a4;
    }
  }
  else
  {
    if ( (signed int)(((unsigned __int64)((pParty->vPosition.x - v6) * (signed __int64)v5) >> 16) + v85) < (signed int)x_ )
      v48 = 0;
    v47 = x_;
  }
  if ( v49 >= (signed int)y_ )
  {
    if ( v49 > a5 )
    {
      if ( v90 - (signed int)v97 - 6 > a5 )
        v48 = 0;
      v49 = a5;
    }
  }
  else
  {
    if ( v90 - (signed int)v97 < (signed int)y_ )
      v48 = 0;
    v49 = y_;
  }
  if ( v48 == 1 )
  {
    v50 = 0;
    v51 = pParty->sRotationY & stru_5C6E00->uDoublePiMask;
    if ( (signed int)(pParty->sRotationY & stru_5C6E00->uDoublePiMask) >= 128 )
    {
      if ( (signed int)v51 > 384 )
      {
        if ( (signed int)v51 >= 640 )
        {
          if ( (signed int)v51 > 896 )
          {
            if ( (signed int)v51 >= 1152 )
            {
              if ( (signed int)v51 > 1408 )
              {
                if ( (signed int)v51 >= 1664 )
                {
                  if ( (signed int)v51 > 1920 )
                    goto LABEL_71;
                  v73 = 7;
                }
                else
                {
                  v73 = 6;
                }
              }
              else
              {
                v73 = 5;
              }
            }
            else
            {
              v73 = 4;
            }
          }
          else
          {
            v73 = 3;
          }
        }
        else
        {
          v73 = 2;
        }
        v50 = v73;
        goto LABEL_71;
      }
      v50 = 1;
    }
LABEL_71:
    pRenderer->_4A6776(
      v47,
      v49,
      (Texture *)(pTextureIDs_pMapDirs[v50] != -1 ? (int)&pIcons_LOD->pTextures[pTextureIDs_pMapDirs[v50]] : 0));
  }
  result = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0xFFu);
  v95 = 0;
  v86 = result;
  if ( (signed int)uNumLevelDecorations > 0 )
  {
    v94 = (unsigned int)&pLevelDecorations[0].vPosition;
    do
    {
      if ( *(char *)(v94 - 2) & 8 )
      {
        v53 = *(int *)(v94 + 4) - v84;
        v93 = (unsigned __int16 *)(*(int *)v94 - v6);
        v92 = v53;
        v54 = ((unsigned __int64)((signed int)v93 * (signed __int64)v5) >> 16) + v85;
        v97 = (const void *)((unsigned __int64)(v53 * (signed __int64)v5) >> 16);
        v55 = v90 - (int)v97;
        if ( v54 >= pRenderer->field_1C_clipx )
        {
          if ( v54 <= pRenderer->field_24_clipz && v55 >= pRenderer->field_20_clipy && v55 <= pRenderer->field_28_clipw )
          {
            v74 = v86;
            if ( v5 > 512 )
            {
              v96 = v55 + 1;
              black = v55 - 1;
              pRenderer->Line2D(v54 - 1, v55 - 1, v54 - 1, v55 + 1, v86);
              pRenderer->Line2D(v54, black, v54, v96, v86);
              ++v54;
              v74 = v86;
              v72 = v96;
              v71 = v54;
              v70 = black;
            }
            else
            {
              v72 = v90 - (int)v97;
              v71 = ((unsigned __int64)((signed int)v93 * (signed __int64)v5) >> 16) + v85;
              v70 = v90 - (int)v97;
            }
            pRenderer->Line2D(v54, v70, v71, v72, v74);
          }
        }
      }
      ++v95;
      result = v95;
      v94 += 32;
    }
    while ( (signed int)v95 < (signed int)uNumLevelDecorations );
  }
  if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
  {
    v90 = a4 - x_ + 1;
    v95 = a5 - y_ + 1;
    v77 = &pRenderer->pTargetSurface[x_ + y_ * v79];
    v56 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2;
    black = (1 << (v56 + 16)) / v5;
    v57 = (double)(1 << (16 - v56));
    v58 = 22528 / (v5 / 384);
    v59 = (signed __int64)((double)(v6 - v58 + 32768) / v57);
    v60 = (int)v59 << 16;
    v97 = (const void *)((int)v59 << 16);
    v61 = (signed __int64)((double)(32768 - v58 - v84) / v57);
    v78 = (unsigned __int16 *)(v60 >> 16);
    v62 = (int)v61 << 16;
    teal = v60 >> 16;
    v63 = (signed __int16)v61;
    a4a = &v75;
    result = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xCu, 0xCu, 0xCu);
    v85 = 0;
    for ( i = result; v85 < (signed int)v95; result = v85 )
    {
      a5a = 0;
      if ( v90 > 0 )
      {
        v96 = (v63 - 80) / 4;
        v64 = teal;
        do
        {
          v81 = (v64 - 80) / 4;
          if ( !pOutdoor->_47F04C(v81, v96) )
          {
            if ( pOutdoor->_47F097(v81, v96) )
            {
              if ( !((a5a + v85) % 2) )
                *(short *)a4a = i;
            }
            else
            {
              *(short *)a4a = 0;
            }
          }
          a4a += 2;
          v97 = (char *)v97 + black;
          v64 = (signed int)v97 >> 16;
          ++a5a;
        }
        while ( a5a < v90 );
      }
      v62 += black;
      v97 = (const void *)v60;
      a4a += 2 * (v90 - a5a);
      v63 = v62 >> 16;
      ++v85;
      teal = (unsigned int)v78;
    }
    v65 = v95;
    v66 = &v75;
    if ( (signed int)v95 > 0 )
    {
      v67 = v77;
      result = 2 * (v79 - v90);
      do
      {
        if ( v90 > 0 )
        {
          v68 = v90;
          do
          {
            v69 = *(short *)v66;
            if ( !*(short *)v66 || v69 == (short)i )
              *v67 = v69;
            v66 += 2;
            ++v67;
            --v68;
          }
          while ( v68 );
        }
        v67 = (unsigned __int16 *)((char *)v67 + result);
        --v65;
      }
      while ( v65 );
    }
  }
  return result;
}

//----- (00443219) --------------------------------------------------------
int ViewingParams::_443219()
{
  this->sPartyPosZ += 512;
  return _4432E7();
}

//----- (00443225) --------------------------------------------------------
int ViewingParams::_443225()
{
  this->sPartyPosX -= 512;
  return _4432E7();
}

//----- (00443231) --------------------------------------------------------
int ViewingParams::_443231()
{
  this->sPartyPosZ -= 512;
  return _4432E7();
}

//----- (0044323D) --------------------------------------------------------
int ViewingParams::_44323D()
{
  this->sPartyPosX += 512;
  return _4432E7();
}

//----- (00443249) --------------------------------------------------------
int ViewingParams::_443249()
{
  int v1; // edx@1

  v1 = (unsigned __int64)((signed __int64)this->field_2C << 15) >> 16;
  this->field_2C = v1;
  if ( v1 < 384 )
    this->field_2C = 384;
  this->sPartyPosX = pParty->vPosition.x;
  this->sPartyPosZ = pParty->vPosition.y;
  return _4432E7();
}

//----- (00443291) --------------------------------------------------------
int ViewingParams::_443291()
{
  int v1; // edx@1
  int v2; // eax@1

  v1 = 2 * this->field_2C;
  v2 = 1536;
  this->field_2C = v1;
  if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
    v2 = 3072;
  if ( v1 > v2 )
    this->field_2C = v2;
  this->sPartyPosX = pParty->vPosition.x;
  this->sPartyPosZ = pParty->vPosition.y;
  return _4432E7();
}

//----- (004432E7) --------------------------------------------------------
int ViewingParams::_4432E7()
{
  ViewingParams *v1; // esi@1
  int v2; // ebx@1
  signed int v3; // edx@1
  int v4; // ecx@1
  int v5; // edi@3
  int v6; // eax@3
  int v7; // eax@5
  int result; // eax@7

  v1 = this;
  v2 = this->field_3A;
  v3 = 88 >> this->field_2C / 384;
  v4 = (44 - v3) << 9;
  if ( v1->sPartyPosZ > v2 + v4 )
    v1->sPartyPosZ = v2 + v4;
  v5 = v1->field_38;
  v6 = (v3 - 44) << 9;
  if ( v1->sPartyPosX < v5 + v6 )
    v1->sPartyPosX = v5 + v6;
  v7 = v2 + v6;
  if ( v1->sPartyPosZ < v7 )
    v1->sPartyPosZ = v7;
  result = v5 + v4;
  if ( v1->sPartyPosX > v5 + v4 )
    v1->sPartyPosX = result;
  return result;
}

//----- (00443343) --------------------------------------------------------
unsigned int ViewingParams::_443343()
{
  signed int v1; // esi@1
  unsigned __int16 *v2; // edi@1
  unsigned int result; // eax@2

  v1 = 0;
  v2 = this->pPalette;
  do
  {
    result = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(v1, v1, v1);
    *v2 = result;
    ++v1;
    ++v2;
  }
  while ( v1 < 256 );
  return result;
}

//----- (00443365) --------------------------------------------------------
int ViewingParams::_443365()
{
  ViewingParams *v1; // esi@1
  __int16 *v2; // edi@3
  Vec3_short_ *v3; // eax@4
  unsigned int v4; // edx@4
  signed int v5; // eax@8
  Vec3_short_ *v6; // eax@12
  signed int v7; // edi@12
  signed int v8; // eax@16
  char v9; // zf@20
  int result; // eax@21
  unsigned int v11; // [sp+4h] [bp-1Ch]@3
  unsigned int *v12; // [sp+8h] [bp-18h]@3
  unsigned int v13; // [sp+Ch] [bp-14h]@8
  unsigned int v14; // [sp+10h] [bp-10h]@2
  unsigned int v15; // [sp+14h] [bp-Ch]@2
  unsigned int v16; // [sp+18h] [bp-8h]@2
  unsigned int v17; // [sp+1Ch] [bp-4h]@2

  v1 = this;
  _443343();
  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
  {
    v16 = 0x40000000u;
    v14 = 0x40000000u;
    v17 = 0xC0000000u;
    v15 = 0xC0000000u;
    if ( (signed int)pIndoor->pMapOutlines->uNumOutlines > 0 )
    {
      v2 = (__int16 *)(pIndoor->pMapOutlines->pOutlines);
      v11 = pIndoor->pMapOutlines->uNumOutlines;
      v12 = (uint *)pIndoor->pMapOutlines->pOutlines;
      do
      {
        v3 = &pIndoor->pVertices[*v2];
        v4 = v3->x;
        if ( (signed int)v4 < (signed int)v16 )
          v16 = v3->x;
        if ( (signed int)v4 > (signed int)v17 )
          v17 = v3->x;
        v5 = v3->y;
        v13 = v5;
        if ( v5 < (signed int)v14 )
          v14 = v4;
        if ( v5 > (signed int)v15 )
          v15 = v4;
        v6 = &pIndoor->pVertices[v2[1]];
        v7 = v6->x;
        if ( v7 < (signed int)v16 )
          v16 = v4;
        if ( v7 > (signed int)v17 )
          v17 = v4;
        v8 = v6->y;
        if ( v8 < (signed int)v14 )
          v14 = v13;
        if ( v8 > (signed int)v15 )
          v15 = v13;
        v2 = (__int16 *)(v12 + 3);
        v9 = v11-- == 1;
        v12 += 3;
      }
      while ( !v9 );
    }
    v1->uMinimapZoom = 1024;
    v1->field_38 = (signed int)(v16 + v17) / 2;
    v1->field_28 = 10;
    result = (signed int)(v14 + v15) / 2;
    v1->field_3A = result;
  }
  else
  {
    v1->field_38 = 0;
    v1->field_3A = 0;
    v1->uMinimapZoom = dword_576E2C;
    result = dword_576E28;
    v1->field_28 = dword_576E28;
  }
  v1->field_2C = 384;
  return result;
}


//----- (00443801) --------------------------------------------------------
int __cdecl Initialize2DA()
{
  const char *v0; // esi@3
  _2devent *v1; // edi@3
  char *v2; // esi@5
  int v3; // edx@5
  char v4; // cl@6
  int v5; // eax@6
  int v6; // ebx@10
  int v7; // eax@60
  int result; // eax@78
  signed int v9; // [sp+10h] [bp-8h]@5
  signed int v10; // [sp+14h] [bp-4h]@5

  int it = 0;

  if ( p2DEventsTXT_Raw )
    pAllocator->FreeChunk(p2DEventsTXT_Raw);
  p2DEventsTXT_Raw = 0;
  v0 = "\r";
  p2DEventsTXT_Raw = (char *)pEvents_LOD->LoadRaw("2dEvents.txt", 0);
  strtok(p2DEventsTXT_Raw, "\r");
  strtok(0, "\r");
  v1 = p2DEvents;
  while ( 1 )
  {
    v2 = strtok(0, v0) + 1;
    v10 = 0;
    v3 = -2;
    v9 = -2;
    do
    {
      v4 = *v2;
      v5 = 0;
      while ( v4 != 9 && v4 )
      {
        ++v5;
        v4 = v2[v5];
      }
      v6 = (int)&v2[v5];
      if ( !v2[v5] )
        v10 = 1;
      *(char *)v6 = 0;
      if ( v5 )
      {
        switch ( v3 )
        {
          case 0:
            if ( _strnicmp(v2, "wea", 3u) )
            {
              if ( _strnicmp(v2, "arm", 3u) )
              {
                if ( _strnicmp(v2, "mag", 3u) )
                {
                  if ( _strnicmp(v2, "alc", 3u) )
                  {
                    if ( _strnicmp(v2, "sta", 3u) )
                    {
                      if ( _strnicmp(v2, "boa", 3u) )
                      {
                        if ( _strnicmp(v2, "tem", 3u) )
                        {
                          if ( _strnicmp(v2, "tra", 3u) )
                          {
                            if ( _strnicmp(v2, "tow", 3u) )
                            {
                              if ( _strnicmp(v2, "tav", 3u) )
                              {
                                if ( _strnicmp(v2, "ban", 3u) )
                                {
                                  if ( _strnicmp(v2, "fir", 3u) )
                                  {
                                    if ( _strnicmp(v2, "air", 3u) )
                                    {
                                      if ( _strnicmp(v2, "wat", 3u) )
                                      {
                                        if ( _strnicmp(v2, "ear", 3u) )
                                        {
                                          if ( _strnicmp(v2, "spi", 3u) )
                                          {
                                            if ( _strnicmp(v2, "min", 3u) )
                                            {
                                              if ( _strnicmp(v2, "bod", 3u) )
                                              {
                                                if ( _strnicmp(v2, "lig", 3u) )
                                                {
                                                  if ( _strnicmp(v2, "dar", 3u) )
                                                  {
                                                    if ( _strnicmp(v2, "ele", 3u) )
                                                    {
                                                      if ( _strnicmp(v2, "sel", 3u) )
                                                      {
                                                        if ( _strnicmp(v2, "mir", 3u) )
                                                        {
                                                          v7 = -(_strnicmp(v2, "mer", 3u) != 0);
                                                          LOBYTE(v7) = v7 & 0xEE;
                                                          v1->uType = v7 + 18;
                                                        }
                                                        else
                                                        {
                                                          v1->uType = 16;
                                                        }
                                                      }
                                                      else
                                                      {
                                                        v1->uType = 15;
                                                      }
                                                    }
                                                    else
                                                    {
                                                      v1->uType = 14;
                                                    }
                                                  }
                                                  else
                                                  {
                                                    v1->uType = 13;
                                                  }
                                                }
                                                else
                                                {
                                                  v1->uType = 12;
                                                }
                                              }
                                              else
                                              {
                                                v1->uType = 11;
                                              }
                                            }
                                            else
                                            {
                                              v1->uType = 10;
                                            }
                                          }
                                          else
                                          {
                                            v1->uType = 9;
                                          }
                                        }
                                        else
                                        {
                                          v1->uType = 8;
                                        }
                                      }
                                      else
                                      {
                                        v1->uType = 7;
                                      }
                                    }
                                    else
                                    {
                                      v1->uType = 6;
                                    }
                                  }
                                  else
                                  {
                                    v1->uType = 5;
                                  }
                                }
                                else
                                {
                                  v1->uType = 22;
                                }
                              }
                              else
                              {
                                v1->uType = 21;
                              }
                            }
                            else
                            {
                              v1->uType = 17;
                            }
                          }
                          else
                          {
                            v1->uType = 30;
                          }
                        }
                        else
                        {
                          v1->uType = 23;
                        }
                      }
                      else
                      {
                        v1->uType = 28;
                      }
                    }
                    else
                    {
                      v1->uType = 27;
                    }
                  }
                  else
                  {
                    v1->uType = 4;
                  }
                }
                else
                {
                  v1->uType = 3;
                }
              }
              else
              {
                v1->uType = 2;
              }
            }
            else
            {
              v1->uType = 1;
            }
            break;
          case 2:
            v1->uAnimationID = atoi(v2);
            break;
          case 3:
            v1->pName = (char *)RemoveQuotes(v2);
            break;
          case 4:
            v1->pProprieterName = RemoveQuotes(v2);
            break;
          case 5:
            v1->pProprieterTitle = RemoveQuotes(v2);
            break;
          case 6:
            v1->field_14 = atoi(v2);
            break;
          case 7:
            v1->_state = atoi(v2);
            break;
          case 8:
            v1->_rep = atoi(v2);
            break;
          case 9:
            v1->_per = atoi(v2);
            break;
          case 10:
            v1->fPriceMultiplier = atof(v2);
            break;
          case 11:
            v1->flt_24 = atof(v2);
            break;
          case 13:
            v1->field_1C = atoi(v2);
            break;
          case 16:
            v1->uOpenTime = atoi(v2);
            break;
          case 17:
            v1->uCloseTime = atoi(v2);
            break;
          case 18:
            v1->uExitPicID = atoi(v2);
            break;
          case 19:
            v1->uExitMapID = atoi(v2);
            break;
          case 20:
            v1->_quest_related = atoi(v2);
            break;
          case 21:
            v1->pEnterText = RemoveQuotes(v2);
            break;
          default:
            break;
        }
      }
      v2 = (char *)(v6 + 1);
      v3 = v9 + 1;
      v9 = v3;
      result = v3 + 1;
    }
    while ( v3 + 1 <= 23 && !v10 );
    ++v1;
    //if ( (signed int)v1 >= (signed int)&unk_597F10 )
    if (++it >= 525)
      return result;
    v0 = "\r";
  }
}

//----- (00443CE1) --------------------------------------------------------
unsigned int __fastcall LoadEventsToBuffer(const char *pContainerName, char *a2, unsigned int uBufferSize)
{
  const char *v3; // edi@1
  FILE *v4; // eax@1
  unsigned int v5; // esi@3
  char Args; // [sp+8h] [bp-B4h]@6
  //Texture DstBuf; // [sp+6Ch] [bp-50h]@1
  void *Dst; // [sp+B4h] [bp-8h]@1
  void *ptr; // [sp+B8h] [bp-4h]@1

  v3 = pContainerName;
  Dst = a2;
  ptr = pEvents_LOD->LoadRaw(pContainerName, 0);
  
  Texture DstBuf; // [sp+6Ch] [bp-50h]@1
  //Texture::Texture(&DstBuf);

  v4 = pEvents_LOD->FindContainer(v3, 0);
  if ( !v4 )
    Abortf("Unable to load %s", v3);
  fread(&DstBuf, 1u, 0x30u, v4);
  v5 = DstBuf.uDecompressedSize;
  if ( !DstBuf.uDecompressedSize )
    v5 = DstBuf.uTextureSize;
  memset(&DstBuf, 0, 0x48u);
  if ( (signed int)v5 >= (signed int)uBufferSize )
  {
    sprintf(&Args, "File %s Size %lu - Buffer size %lu", v3, v5, uBufferSize);
    Abortf(&Args);
  }
  memcpy(Dst, ptr, v5);
  pAllocator->FreeChunk(ptr);
  return v5;
}

//----- (00443DA1) --------------------------------------------------------
void __cdecl Initialize_GlobalEVT()
{
  signed int v0; // esi@1
  unsigned int v1; // ecx@2
  char *v2; // eax@2

  v0 = 0;
  uGlobalEVT_Size = LoadEventsToBuffer("global.evt", pGlobalEVT, 0xB400u);
  if ( uGlobalEVT_Size )
  {
    uGlobalEVT_NumEvents = 0;
    memset(pGlobalEVT_Events, 128, 0xCE40u);
    v1 = uGlobalEVT_NumEvents;
    v2 = (char *)&pGlobalEVT_Events[uGlobalEVT_NumEvents].field_4;
    do
    {
      ++v1;
      *((int *)v2 - 1) = (unsigned __int8)pGlobalEVT[v0 + 1] + ((unsigned __int8)pGlobalEVT[v0 + 2] << 8);
      *(int *)v2 = (unsigned __int8)pGlobalEVT[v0 + 3];
      *((int *)v2 + 1) = v0;
      v2 += 12;
      v0 += (unsigned __int8)pGlobalEVT[v0] + 1;
    }
    while ( v0 < (signed int)uGlobalEVT_Size );
    uGlobalEVT_NumEvents = v1;
  }
}

//----- (00443E31) --------------------------------------------------------
void __cdecl LoadLevel_InitializeLevelStr()
{
  signed __int16 v0; // si@1
  //unsigned int v1; // ecx@1
  signed int v2; // edi@1
  int v3; // edx@1
  //int v4; // eax@2
  int v5; // ebx@4
  int v6; // ebx@11
  int v7; // eax@12
  unsigned int *v8; // edi@13
  char Args[100]; // [sp+Ch] [bp-68h]@9
  int v10; // [sp+70h] [bp-4h]@1

  if (sizeof(pLevelStrOffsets) != 0x7D0)
    Log::Warning(L"pLevelStrOffsets: deserialization warning");
  memset(pLevelStrOffsets, 0, 0x7D0u);
  
  v0 = 0;
  //v1 = uLevelStrFileSize;
  v2 = 1;
  v3 = 0;
  v10 = 0;
    //v4 = 0;
  for (uint i = 0; i < uLevelStrFileSize; ++i)
  {
      if ( !pLevelStr[i] )
      {
        v5 = (signed __int16)v2++;
        pLevelStrOffsets[v5] = i + 1;
        if ( (signed __int16)(i - (short)v10) > v0 )
          v0 = i - v10;
        v10 = i;
      }
  }

  uLevelStrNumStrings = (signed __int16)v2 - 1;
  if ( v0 > 800 )
  {
    sprintf(Args, "MAX_EVENT_TEXT_LENGTH needs to be increased to %lu", v0 + 1);
    Abortf(Args);
  }
  v6 = 0;
  if ( (signed __int16)v2 - 1 > 0 )
  {
    v7 = 0;
    do
    {
      v8 = &pLevelStrOffsets[v7];
      if ( RemoveQuotes(&pLevelStr[*v8]) != &pLevelStr[*v8] )
        ++*v8;
      ++v6;
      v7 = (signed __int16)v6;
    }
    while ( (signed __int16)v6 < (signed int)uLevelStrNumStrings );
  }
}

//----- (00443EF8) --------------------------------------------------------
void __cdecl LoadLevel_InitializeLevelEvt()
{
  if (!uLevelEVT_Size)
    return;

  memset(array_5B5928, 0, 0xC80u);
  memset(pLevelEVT_Events, 128, 0xCE40u);

  uLevelEVT_NumEvents = 0;
  dword_5B65C8 = 0;

  for (uint i = 0, j = 0; j < uLevelEVT_Size; ++i)
  {
    pLevelEVT_Events[i].uEventID = pLevelEVT[j + 1] + ((unsigned short)pLevelEVT[j + 2] << 8);
    pLevelEVT_Events[i].field_4 = pLevelEVT[j + 3];
    pLevelEVT_Events[i].uEventOffsetInEVT = j;
    j += pLevelEVT[j] + 1;

    uLevelEVT_NumEvents++;
  }
}

//----- (00443F95) --------------------------------------------------------
void __cdecl OnMapLeave()
{
  signed int v0; // edi@1
  char *v1; // esi@2
  int v2; // ecx@4

  v0 = 0;
  if ( (signed int)uLevelEVT_NumEvents > 0 )
  {
    v1 = (char *)&pLevelEVT_Events[0].field_4;
    do
    {
      if ( pLevelEVT[*((short *)v1 + 2) + 4] == 53 )
      {
        v2 = *((int *)v1 - 1);
        dword_597F18 = *(int *)v1;
        EventProcessor(v2, 0, 1);
        dword_597F18 = 0;
      }
      ++v0;
      v1 += 12;
    }
    while ( v0 < (signed int)uLevelEVT_NumEvents );
  }
}


//----- (00443FDC) --------------------------------------------------------
void OnMapLoad()
{
  stru176 *v3; // esi@7
  __int16 v4; // cx@9
  __int16 v5; // di@9
  int v6; // eax@9
  signed __int64 v8; // qax@26
  unsigned int v9; // ecx@26
  signed __int64 v10; // qax@26
  signed __int64 v11; // qax@26
  int v12; // ST50_4@26
  signed __int64 v13; // qax@26
  signed __int64 v14; // qax@26
  int v15; // ST58_4@26
  signed __int64 v16; // qax@26
  int v17; // ebx@26
  unsigned __int64 v18; // [sp+Ch] [bp-44h]@12
  signed __int64 v19; // [sp+14h] [bp-3Ch]@26
  unsigned __int64 v20; // [sp+1Ch] [bp-34h]@7
  int v22; // [sp+2Ch] [bp-24h]@26
  int v24; // [sp+34h] [bp-1Ch]@26
  int v25; // [sp+38h] [bp-18h]@26
  int v26; // [sp+3Ch] [bp-14h]@15
  int v27; // [sp+3Ch] [bp-14h]@26
  int v28; // [sp+40h] [bp-10h]@26
  __int16 v29; // [sp+46h] [bp-Ah]@9
  __int16 v30; // [sp+48h] [bp-8h]@9
  __int16 v31; // [sp+4Ah] [bp-6h]@9
  __int16 v32; // [sp+4Ch] [bp-4h]@9
  __int16 v33; // [sp+4Eh] [bp-2h]@9

  for (uint i = 0; i < uLevelEVT_NumEvents; ++i)
  {
    auto pEvent = pLevelEVT_Events + i;

    auto _evt = (_evt_raw *)(pLevelEVT + pEvent->uEventOffsetInEVT);

    if (_evt->v4 == 3)
    {
      pSoundList->LoadSound(
          _evt->v5 +
          ((_evt->v6 + ((_evt->v7 + ((unsigned int)_evt->v8 << 8)) << 8)) << 8),
          0);
    }
    else if (_evt->v4 == 37)
    {
      dword_597F18 = pEvent->field_4;
      EventProcessor(pEvent->uEventID, 0, 0);
      dword_597F18 = 0;
    }
    else if (_evt->v4 == 31 || _evt->v4 == 38)
    {
      v3 = &array_5B5928[dword_5B65C8];
      v20 = pOutdoor->uLastVisitDay;
      if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
        v20 = pIndoor->stru1.uLastVisitDay;

      v4 = _evt->v4;
      v3->field_1C = v4;
      v3->field_8 = pEvent->uEventID;
      v3->field_A = pEvent->field_4;
      v33 = _evt->v6;
      v3->field_12 = v33;
      v32 = _evt->v7;
      v3->field_14 = v32;
      v31 = _evt->v8;
      v3->field_16 = v31;
      v5 = _evt->v5;
      v30 = _evt->v9;
      v3->field_18 = v30;
      v29 = _evt->v10;
      v3->field_1A = v29;

      v6 = ((unsigned short)_evt->v12 << 8) + _evt->v11;
      v3->field_10 = v5;
      v3->field_C = v6;
      v3->field_E = v6;
      if ( v4 == 38 && !(short)v6 )
      {
        if ( v20 )
          v18 = pParty->uTimePlayed - v20;
        else
          v18 = 0i64;
        v26 = (signed int)(signed __int64)((double)(signed __int64)v18 * 0.234375) / 60 / 60 / 24;

        if ( v26 / 7 / 4 / 12 )
        {
          if ( v5 )
          {
            v3->field_4 = 0;
            ++dword_5B65C8;
            v3->field_0 = 0;
            continue;
          }
        }
        if (v26 / 7 / 4 != 0 && v33 != 0 ||
            v26 / 7 != 0 && v32 != 0 ||
            v26 != 0 || !v20)
        {
          v3->field_4 = 0;
          ++dword_5B65C8;
          v3->field_0 = 0;
          continue;
        }
      }

      v8 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375);
      v9 = v8;
      v10 = (signed int)v8 / 60;
      v22 = v10 % 60;
      v11 = (signed int)(v10 / 60);
      v12 = v11 % 24;
      v13 = (signed int)(v11 / 24);
      v27 = v13 % 7;
      v14 = (signed int)(v13 / 7);
      v15 = v14 % 4;
      v16 = (signed int)(v14 / 4);
      v24 = v16 / 12;

      auto _1 = (unsigned __int64)((double)pParty->uTimePlayed * 0.234375) >> 32;
      auto _2 = ((__int64)v9 << 32) | _1;

      v19 = _2 % 60;
      //v19 = (signed __int64)__PAIR__((unsigned __int64)(signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) >> 32,
      //                        v9)
      //    % 60;

      v17 = v12;
      v25 = v15;
      v28 = v16 % 12;
      if ( v5 )
      {
        ++v24;
      }
      else
      {
        if ( v33 )
        {
          ++v28;
        }
        else
        {
          if ( v32 )
          {
            ++v25;
          }
          else
          {
            ++v27;
            v22 = v30;
            v17 = v31;
            v19 = v29;
          }
        }
      }
      auto v0 = (signed __int64)((double)((v19
                                + 0x3C * v22
                                + 0xE10 * v17
                                + 0x93A80 * v25
                                + 0x15180 * v27
                                + 0x24EA00 * (v28 + 12i64 * v24)) << 7)
                      * 0.033333335);
      v3->field_4 = HIDWORD(v0);

      ++dword_5B65C8;
      v3->field_0 = v0;
    }
  }
}

//----- (00444360) --------------------------------------------------------
void __thiscall Level_LoadEvtAndStr(const char *pLevelName)
{
  char pContainerName[120]; // [sp+8h] [bp-98h]@1

  sprintf(pContainerName, "%s.evt", pLevelName);
  uLevelEVT_Size = LoadEventsToBuffer(pContainerName, pLevelEVT, 0x2400u);

  sprintf(pContainerName, "%s.str", pLevelName);
  uLevelStrFileSize = LoadEventsToBuffer(pContainerName, pLevelStr, 0x2400u);
  if (uLevelStrFileSize)
    LoadLevel_InitializeLevelStr();
}

//----- (004443D5) --------------------------------------------------------
char *__cdecl _4443D5_GetMinimapRightClickText()
{
  int v0; // ST20_4@1
  unsigned int v1; // esi@1
  signed int v2; // ebx@1
  double v3; // st7@1
  int v4; // esi@3
  int v5; // edi@4
  int v6; // eax@4
  int v7; // eax@4
  BSPModel *v8; // ecx@4
  unsigned __int8 v9; // zf@5
  char v10; // sf@5
  unsigned __int8 v11; // of@5
  ODMFace *v12; // eax@6
  __int16 v13; // cx@6
  const char *v14; // eax@8
  const char *v15; // edi@8
  char *result; // eax@12
  unsigned int v17; // eax@14
  unsigned int v18; // [sp+Ch] [bp-20h]@1
  int v19; // [sp+10h] [bp-1Ch]@1
  int v20; // [sp+14h] [bp-18h]@1
  char *v21; // [sp+18h] [bp-14h]@1
  unsigned int pY; // [sp+1Ch] [bp-10h]@1
  int v23; // [sp+20h] [bp-Ch]@1
  int v24; // [sp+24h] [bp-8h]@1
  int pX; // [sp+28h] [bp-4h]@1

  v24 = pParty->vPosition.x;
  v0 = pParty->vPosition.y;
  v1 = pOutdoor->uNumBModels;
  *(float *)&v23 = (double)(signed int)viewparams->uMinimapZoom * 0.000015258789;
  v2 = 0;
  v18 = pOutdoor->uNumBModels;
  v21 = 0;
  pMouse->GetClickPos((unsigned int *)&pX, &pY);
  v3 = 1.0 / *(float *)&v23;
  v23 = pX - 557;
  v19 = (signed __int64)((double)(pX - 557) * v3 + (double)v24);
  v20 = (signed __int64)((double)v0 - (double)(signed int)(pY - 74) * v3);
  if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor || (*(float *)&v23 = 0.0, (signed int)v1 <= 0) )
  {
LABEL_14:
    v17 = pMapStats->GetMapInfo(pCurrentMapName);
    if ( v17 == v2 )
      result = "No Maze Info for this maze on file!";
    else
      result = pMapStats->pInfos[v17].pName;
  }
  else
  {
    v4 = 0;
    while ( 1 )
    {
      pX = pOutdoor->pBModels[v4].vBoundingCenter.x - v19;
      pY = pOutdoor->pBModels[v4].vBoundingCenter.y - v20;
      v5 = abs((signed)pY);
      v6 = abs((signed)pX);
      v7 = sub_4621DA(v6, v5, v2);
      v8 = &pOutdoor->pBModels[0];
      if ( v7 < 2 * pOutdoor->pBModels[v4].sBoundingRadius )
      {
        v11 = __OFSUB__(pOutdoor->pBModels[v4].uNumFaces, v2);
        v9 = pOutdoor->pBModels[v4].uNumFaces == v2;
        v10 = ((pOutdoor->pBModels[v4].uNumFaces - v2) & 0x80000000u) != 0;
        v24 = v2;
        if ( !((unsigned __int8)(v10 ^ v11) | v9) )
        {
          do
          {
            v12 = &v8[v4].pFaces[v2 / 0x134u];
            v13 = v12->sCogTriggeredID;
            if ( v13 )
            {
              if ( !(BYTE2(v12->uAttributes) & 0x10) )
              {
                v14 = _444732_GetEventHintString(v13);
                v15 = v14;
                if ( v14 )
                {
                  if ( _strcmpi(v14, "") )
                    v21 = (char *)v15;
                }
              }
            }
            ++v24;
            v8 = pOutdoor->pBModels;
            v2 += 308;
          }
          while ( v24 < (signed int)pOutdoor->pBModels[v4].uNumFaces );
        }
        result = v21;
        v2 = 0;
        if ( v21 )
          break;
      }
      ++v23;
      ++v4;
      if ( v23 >= (signed int)v18 )
        goto LABEL_14;
    }
  }
  return result;
}

//----- (00444564) --------------------------------------------------------
const char *__cdecl sub_444564()
{
  double v0; // st7@3
  int v1; // ebx@3
  int v2; // edi@3
  int v3; // eax@3
  int v4; // esi@5
  int v5; // edi@6
  int v6; // eax@6
  int v7; // eax@6
  BSPModel **v8; // ecx@6
  unsigned __int8 v9; // zf@7
  unsigned __int8 v10; // sf@7
  ODMFace *v11; // eax@9
  __int16 v12; // cx@9
  const char *v13; // eax@11
  const char *v14; // edi@11
  const char *result; // eax@15
  unsigned int v16; // [sp+0h] [bp-20h]@3
  const char *v17; // [sp+4h] [bp-1Ch]@3
  unsigned int pY; // [sp+8h] [bp-18h]@3
  float v19; // [sp+Ch] [bp-14h]@1
  int v20; // [sp+10h] [bp-10h]@1
  int v21; // [sp+14h] [bp-Ch]@1
  unsigned int v22; // [sp+18h] [bp-8h]@8
  int pX; // [sp+1Ch] [bp-4h]@3

  v20 = viewparams->sPartyPosX;
  v21 = viewparams->sPartyPosZ;
  v19 = (double)viewparams->field_2C * 0.000015258789;
  if ( viewparams->field_2C == 384 )
  {
    v20 = viewparams->field_38;
    v21 = viewparams->field_3A;
  }
  v17 = 0;
  v16 = pOutdoor->uNumBModels;
  pMouse->GetClickPos((unsigned int *)&pX, &pY);
  v0 = 1.0 / v19;
  v1 = (signed __int64)((double)(pX - 229) * v0 + (double)v20);
  LODWORD(v19) = (signed __int64)((double)v21 - (double)(signed int)(pY - 181) * v0);
  v2 = abs(v1 + 22528) / 512;
  v3 = abs((signed)LODWORD(v19) - 22528);
  if ( pOutdoor->_47F04C(v2, v3 / 512)
    && uCurrentlyLoadedLevelType == LEVEL_Outdoor
    && (v4 = 0, v20 = 0, (signed int)v16 > 0) )
  {
    while ( 1 )
    {
      pX = *(int *)((char *)&pOutdoor->pBModels[v4].vBoundingCenter.x) - v1;
      pY = *(int *)((char *)&pOutdoor->pBModels[v4].vBoundingCenter.y) - LODWORD(v19);
      v5 = abs((signed)pY);
      v6 = abs((signed)pX);
      v7 = sub_4621DA(v6, v5, 0);
      v8 = &pOutdoor->pBModels;
      if ( v7 < *(int *)((char *)&pOutdoor->pBModels[v4].sBoundingRadius) )
      {
        v9 = pOutdoor->pBModels[v4].uNumFaces == 0;
        v10 = pOutdoor->pBModels[v4].uNumFaces < 0;
        v21 = 0;
        if ( !(v10 | v9) )
        {
          v22 = 0;
          do
          {
            v11 = &v8[v4]->pFaces[v22 / 0x134];
            v12 = v11->sCogTriggeredID;
            if ( v12 )
            {
              if ( !(BYTE2(v11->uAttributes) & 0x10) )
              {
                v13 = _444732_GetEventHintString(v12);
                v14 = v13;
                if ( v13 )
                {
                  if ( _strcmpi(v13, "") )
                    v17 = v14;
                }
              }
            }
            ++v21;
            v8 = &pOutdoor->pBModels;
            v22 += 308;
          }
          while ( v21 < pOutdoor->pBModels[v4].uNumFaces );
        }
        result = v17;
        if ( v17 )
          break;
      }
      ++v20;
      v4 += 188;
      if ( v20 >= (signed int)v16 )
        goto LABEL_17;
    }
  }
  else
  {
LABEL_17:
    result = 0;
  }
  return result;
}




//----- (00444A51) --------------------------------------------------------
char *__cdecl TransitionUI_Draw()
{
  MapInfo *pMapInfo; // esi@5
  char *v1; // eax@6
  char *result; // eax@12
  std::string v3; // [sp-18h] [bp-84h]@11
  unsigned int v4; // [sp-10h] [bp-7Ch]@12
  int v5; // [sp-Ch] [bp-78h]@12
  const char *v6; // [sp-8h] [bp-74h]@11
  signed int v7; // [sp-4h] [bp-70h]@11
  GUIWindow v8; // [sp+Ch] [bp-60h]@1
  unsigned int v9; // [sp+60h] [bp-Ch]@1
  unsigned int v10; // [sp+64h] [bp-8h]@1
  int a3; // [sp+6Bh] [bp-1h]@11

  memcpy(&v8, pPrimaryWindow, sizeof(v8));
  v10 = pMapStats->GetMapInfo(pCurrentMapName);
  v9 = IndoorLocation::GetLocationIndex(dword_591164_teleport_map_name);
  pRenderer->DrawTextureIndexed(0x1DDu, 0, pTexture_Dialogue_Background);
  pRenderer->DrawTextureIndexed(pNPCPortraits_x - 4, pNPCPortraits_y - 4, (Texture *)(uTextureID_50795C != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_50795C] : 0));
  pRenderer->DrawTextureIndexed(pNPCPortraits_x, pNPCPortraits_y, pTexture_outside);
  uTextureID_507B04 = uTextureID_right_panel;
  pRenderer->DrawTextureTransparent(468, 0, (Texture *)(uTextureID_right_panel != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_right_panel] : 0));
  pRenderer->DrawTextureIndexed(556, 451, (Texture *)(uTextureID_x_x_u != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_x_x_u] : 0));
  pRenderer->DrawTextureIndexed(476, 451, (Texture *)(uTextureID_x_ok_u != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_x_ok_u] : 0));
  if ( (pVideoPlayer->AnyMovieLoaded() || v9) && *dword_591164_teleport_map_name != 48 )
    v10 = pMapStats->GetMapInfo(dword_591164_teleport_map_name);
  pMapInfo = &pMapStats->pInfos[v10];
  v8.uFrameX = 493;
  v8.uFrameWidth = 126;
  v8.uFrameZ = 366;
  v8.DrawTitleText(pFontCreate, 0, 5u, 0, pMapInfo->pName, 3);
  v8.uFrameX = 483;
  v8.uFrameWidth = 148;
  v8.uFrameZ = 334;
  if ( uCurrentHouse_Animation )
  {
    v1 = (&off_4EB080)[4 * uCurrentHouse_Animation];
  }
  else
  {
    if ( v10 )
    {
      sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[409], pMapInfo->pName);// "Do you wish to leave %s?"
      v4 = (212 - pFontCreate->CalcTextHeight(pTmpBuf, &v8, 0, 0)) / 2 + 101;
      result = v8.DrawTitleText(pFontCreate, 0, v4, 0, pTmpBuf, 3);
      dword_5B5924 = 1;
      return result;
    }
    v1 = "";
  }
  if ( !v1 )
  {
    MessageBoxW(nullptr, L"No transition text found!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Events.cpp:1410", 0);
    v1 = "";
  }
  v4 = (212 - pFontCreate->CalcTextHeight(v1, &v8, 0, 0)) / 2 + 101;
  result = v8.DrawTitleText(pFontCreate, 0, v4, 0, v1, 3);
  dword_5B5924 = 1;
  return result;
}


//----- (00444C8F) --------------------------------------------------------
GUIWindow *__cdecl UI_CreateTravelDialogue()
{
  signed int v0; // eax@1
  unsigned int v1; // eax@6
  GUIWindow *result; // eax@9
  const char *v3; // [sp-4h] [bp-2Ch]@2
  char pContainer[32]; // [sp+0h] [bp-28h]@1

  pEventTimer->Pause();
  v0 = const_2();
  sprintf(pContainer, "evt%02d", v0);
  if ( pParty->uAlignment )
  {
    if ( pParty->uAlignment != 2 )
      goto LABEL_6;
    v3 = "-c";
  }
  else
  {
    v3 = "-b";
  }
  strcat(pContainer, v3);
LABEL_6:
  pTexture_Dialogue_Background = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE)];
  pTexture_outside = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("outside", TEXTURE_16BIT_PALETTE)];
  v1 = pMapStats->GetMapInfo(pCurrentMapName);
  if ( v1 )
    sprintf(byte_591098, pGlobalTXT_LocalizationStrings[410], pMapStats->pInfos[v1].pName);// "Leave %s"
  else
    strcpy(byte_591098, pGlobalTXT_LocalizationStrings[79]);// "Exit"
  result = GUIWindow::Create(0, 0, 640, 480, (enum WindowType)17, 0, (int)byte_591098);
  pDialogueWindow = result;
  return result;
}

//----- (00444D80) --------------------------------------------------------
signed int __cdecl GetTravelTime()
{
  signed int v0; // esi@1

  v0 = uDefaultTravelTime_ByFoot;
  if ( CheckHiredNPCSpeciality(5u) )
    --v0;
  if ( CheckHiredNPCSpeciality(6u) )
    v0 -= 2;
  if ( CheckHiredNPCSpeciality(7u) )
    v0 -= 3;
  if ( CheckHiredNPCSpeciality(0x2Cu) )
    --v0;
  if ( v0 < 1 )
    v0 = 1;
  return v0;
}
// 6BD07C: using guessed type int uDefaultTravelTime_ByFoot;

//----- (00444DCA) --------------------------------------------------------
void __cdecl TravelUI_Draw()
{
  unsigned int v0; // edi@1
  MapInfo *v1; // edi@2
  char *v2; // ST14_4@2
  signed int v3; // eax@2
  int v4; // eax@5
  const char *v5; // [sp-Ch] [bp-90h]@3
  signed int v6; // [sp-8h] [bp-8Ch]@3
  GUIWindow v7; // [sp+Ch] [bp-78h]@1
  char pDestinationMapName[32]; // [sp+60h] [bp-24h]@1
  unsigned int v9; // [sp+80h] [bp-4h]@1

  memcpy(&v7, pPrimaryWindow, sizeof(v7));
  v9 = pMapStats->GetMapInfo(pCurrentMapName);
  pOutdoor->GetTravelDestination(pParty->vPosition.x, pParty->vPosition.y, pDestinationMapName, 20);
  v0 = pMapStats->GetMapInfo(pDestinationMapName);
  pRenderer->DrawTextureIndexed(0x1DDu, 0, pTexture_Dialogue_Background);
  pRenderer->DrawTextureTransparent(0x1D4u, 0,
    (Texture *)(uTextureID_507B04 != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_507B04] : 0));
  pRenderer->DrawTextureIndexed(pNPCPortraits_x, pNPCPortraits_y, pTexture_outside);
  pRenderer->DrawTextureIndexed(0x22Cu, 0x1C3u,
    (Texture *)(uTextureID_x_x_u != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_x_x_u] : 0));
  pRenderer->DrawTextureIndexed(0x1DCu, 0x1C3u,
    (Texture *)(uTextureID_x_ok_u != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_x_ok_u] : 0));
  if ( v0 )
  {
    v1 = &pMapStats->pInfos[v0];
    v7.uFrameX = 493;
    v7.uFrameWidth = 126;
    v2 = v1->pName;
    v7.uFrameZ = 366;
    v7.DrawTitleText(pFontCreate, 0, 4u, 0, v2, 3u);
    v7.uFrameX = 483;
    v7.uFrameWidth = 148;
    v7.uFrameZ = 334;
    v3 = GetTravelTime();
    if ( v3 == 1 )
    {
      v6 = 1;
      v5 = pGlobalTXT_LocalizationStrings[663]; // "It will take %d day to cross to %s."
    }
    else
    {
      v6 = v3;
      v5 = pGlobalTXT_LocalizationStrings[128]; // "It will take %d days to travel to %s."
    }
    sprintf(pTmpBuf, v5, v6, v1->pName);
    strcat(pTmpBuf, "\n \n");
    sprintf(pTmpBuf2, pGlobalTXT_LocalizationStrings[126], pMapStats->pInfos[v9].pName);
    strcat(pTmpBuf, pTmpBuf2);
    v4 = pFontCreate->CalcTextHeight(pTmpBuf, &v7, 0, 0);
    v7.DrawTitleText(pFontCreate, 0, (212 - v4) / 2 + 101, 0, pTmpBuf, 3u);
    dword_5B5924 = 1;
  }
}


//----- (00444FBE) --------------------------------------------------------
void __cdecl DrawBranchlessDialogueUI()
{
  GUIFont *v0; // esi@1
  int v1; // esi@4
  char *v2; // eax@6
  int v3; // edi@12
  char Str[200]; // [sp+Ch] [bp-120h]@12
  GUIWindow v5; // [sp+D4h] [bp-58h]@4
  GUIFont *pFont; // [sp+128h] [bp-4h]@1

  v0 = pFontArrus;
  pFont = pFontArrus;
  if ( ptr_F8B1E8 && !byte_5B0938[0] )
    strcpy(byte_5B0938, ptr_F8B1E8);
  v5.uFrameWidth = 460;
  v5.uFrameZ = 452;
  v1 = pFontArrus->CalcTextHeight(byte_5B0938, &v5, 12, 0) + 7;
  if ( 352 - v1 < 8 )
  {
    pFont = pFontCreate;
    v1 = pFontCreate->CalcTextHeight(byte_5B0938, &v5, 12, 0) + 7;
  }
  pRenderer->_4A6A68(
    8u,
    352 - v1,
    (Texture *)(uTextureID_Leather != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_Leather] : 0),
    (uTextureID_Leather != -1 ? pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight : 26) - v1);
  pRenderer->DrawTextureIndexed(8u, 347 - v1, pTexture_591428);
  v2 = FitTextInAWindow(byte_5B0938, pFont, &v5, 0xCu, 0);
  pGUIWindow2->DrawText(pFont, 12, 354 - v1, 0, v2, 0, 0, 0);
  pRenderer->DrawTextureRGB(0, 0x160u, pTexture_StatusBar);
  if ( pGUIWindow2->field_40 != 1 )
  {
    if ( pGUIWindow2->field_40 == 2 )
    {
      pGUIWindow2->field_40 = 0;
      strcpy(GameUI_StatusBar_TimedString, (const char *)pKeyActionMap->pPressedKeysBuffer);
LABEL_16:
      sub_4452BB();
      return;
    }
    if ( pGUIWindow2->field_40 != 3 )
      return;
    pGUIWindow2->field_40 = 0;
LABEL_15:
    memset(GameUI_StatusBar_TimedString, 0, 0xC8u);
    goto LABEL_16;
  }
  if ( pGUIWindow2->ptr_1C == (void *)26 )
  {
    sprintf(Str, "%s %s", GameUI_StatusBar_TimedString, pKeyActionMap->pPressedKeysBuffer);
    v3 = pFontLucida->GetLineWidth(Str);
    pGUIWindow2->DrawText(pFontLucida, 13, 357, 0, Str, 0, 0, 0);
    pGUIWindow2->DrawFlashingInputCursor(v3 + 13, 357, pFontLucida);
    return;
  }
  if ( pKeyActionMap->pPressedKeysBuffer[0] )
  {
    pKeyActionMap->_459ED1(0);
    goto LABEL_15;
  }
}

//----- (004451A8) --------------------------------------------------------
void __fastcall sub_4451A8_press_any_key(int a1, int a2, int a4)
{
  int v3; // esi@1
  int v4; // edi@1

  v3 = a2;
  v4 = a1;
  if ( !pGUIWindow2 )
  {
    if ( pParty->uFlags & 2 )
      pGame->Draw();
    if ( !dword_597F18 )
      pAudioPlayer->StopChannels(-1, -1);
    pMiscTimer->Pause();
    pEventTimer->Pause();
    dword_5C3418 = v4;
    dword_5C341C = v3;
    _591094_decoration = _5C3420_pDecoration;
    pGUIWindow2 = GUIWindow::Create(0, 0, 640u, 480u, (enum WindowType)19, a4, 0);
    pGUIWindow2->CreateButton(61u, 424u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 1u, 0x31u, "", 0);
    pGUIWindow2->CreateButton(177u, 424u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 2u, 0x32u, "", 0);
    pGUIWindow2->CreateButton(292u, 424u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 3u, 0x33u, "", 0);
    pGUIWindow2->CreateButton(407u, 424u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 4u, 0x34u, "", 0);
  }
}

//----- (004452BB) --------------------------------------------------------
void __cdecl sub_4452BB()
{
  pGUIWindow2->Release();
  pGUIWindow2 = 0;
  _5C3420_pDecoration = _591094_decoration;
  dword_597F18 = dword_5C341C;
  EventProcessor(dword_5C3418, 0, 1);
  dword_597F18 = 0;
  _5C3420_pDecoration = 0;
  pEventTimer->Resume();
}


//----- (00445308) --------------------------------------------------------
const char *__fastcall sub_445308(int a1)
{
  if ( a1 == 10
    || a1 == 11
    || a1 == 12
    || a1 == 33
    || a1 == 34
    || a1 == 39
    || a1 == 40
    || a1 == 41
    || a1 == 42
    || a1 == 43
    || a1 == 52 )
    return (const char *)*(&pNPCStats->field_13A60 + 5 * a1);
  else
    return pNPCTopics[407].pTopic;
}


//----- (00445350) --------------------------------------------------------
void __cdecl DrawDialogueUI()
{
  NPCData *pNPC; // ebx@2
  int v1; // eax@2
  unsigned __int16 v2; // di@2
  //unsigned int v3; // eax@2
  char *v4; // esi@3
  int v5; // eax@11
  char *v6; // ecx@13
  char *v7; // eax@16
  unsigned int v8; // edi@19
  char *v9; // ecx@27
  char *v10; // eax@29
  int v11; // eax@30
  int v12; // esi@39
  char *v13; // eax@41
  GUIButton *v14; // eax@43
  GUIButton *v15; // edi@43
  signed int v16; // eax@44
  int v17; // eax@46
  int v18; // eax@47
  int v19; // eax@48
  int v20; // eax@49
  int v21; // eax@50
  int v22; // eax@51
  unsigned int v23; // eax@53
  const char *v24; // eax@59
  int v25; // eax@65
  int v26; // eax@66
  int v27; // eax@67
  int v28; // eax@68
  int v29; // eax@69
  unsigned __int16 v30; // cx@83
  int v31; // ecx@86
  int v32; // ebx@93
  unsigned int v33; // eax@93
  GUIWindow *v34; // ecx@93
  int v35; // esi@93
  int i; // eax@93
  GUIButton *v37; // eax@94
  int v38; // eax@95
  signed int v39; // esi@99
  signed int v40; // eax@102
  unsigned int v41; // ebx@102
  int v42; // edi@102
  GUIButton *v43; // esi@103
  int v44; // eax@104
  unsigned int v45; // ecx@104
  unsigned __int16 *v46; // edx@104
  unsigned __int16 v47; // ax@104
  GUIWindow pWindow; // [sp+4h] [bp-110h]@39
  int v49; // [sp+Ch] [bp-108h]@39
  int v50; // [sp+14h] [bp-100h]@39
  GUIWindow v51; // [sp+58h] [bp-BCh]@2
  GUIWindow v52; // [sp+ACh] [bp-68h]@42
  char *Str; // [sp+100h] [bp-14h]@104
  __int16 v54[2]; // [sp+104h] [bp-10h]@2
  unsigned __int16 *v55; // [sp+108h] [bp-Ch]@82
  GUIFont *pOutString; // [sp+10Ch] [bp-8h]@39
  char *pInString; // [sp+110h] [bp-4h]@32

  if ( !pDialogueWindow )
    return;
  memcpy(&v51, pDialogueWindow, sizeof(v51));
  pNPC = GetNPCData(uDialogue_SpeakingActorNPC_ID);
  v1 = sub_445C8B(uDialogue_SpeakingActorNPC_ID);
  v51.uFrameWidth -= 10;
  v51.uFrameZ -= 10;
  *(int *)v54 = v1;
  GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0xFFu);
  GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xE1u, 0xCDu, 0x23u);
  v2 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0x15u, 0x99u, 0xE9u);
  pRenderer->DrawTextureIndexed(477, 0, pTexture_Dialogue_Background);
  pRenderer->DrawTextureTransparent(468, 0, (Texture *)(uTextureID_507B04 != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_507B04] : 0));
  pRenderer->DrawTextureIndexed(pNPCPortraits_x - 4, pNPCPortraits_y - 4, (Texture *)(uTextureID_50795C != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_50795C] : 0));
  pRenderer->DrawTextureIndexed(pNPCPortraits_x, pNPCPortraits_y, pDialogueNPCPortraits[0]);
  if ( pNPC->uProfession )
  {
    sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[429], pNPC->pName, aNPCProfessionNames[pNPC->uProfession]);//^Pi[%s] %s
  }
  else
  {
    strcpy(pTmpBuf, pNPC->pName);
  }
  v51.DrawTitleText(pFontArrus, 483, 112, v2, pTmpBuf, 3);
  pParty->GetPartyFame();
  if ( (signed int)uDialogueType > DIALOGUE_ARENA_WELCOME )
  {
    if ( uDialogueType == DIALOGUE_ARENA_FIGHT_NOT_OVER_YET )
    {
      pWindow.uFrameWidth = 460;
      pWindow.uFrameZ = 452;
      pOutString = pFontArrus;
      v12 = pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[577], &pWindow, 13, 0) + 7;//"Get back in there you wimps:"
      if ( 352 - v12 < 8 )
      {
        pOutString = pFontCreate;
        v12 = pFontCreate->CalcTextHeight(pGlobalTXT_LocalizationStrings[577], &pWindow, 13, 0) + 7;
      }
      pRenderer->_4A6A68(8, 352 - v12, (Texture *)(uTextureID_Leather != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_Leather] : 0),
        (uTextureID_Leather != -1 ? pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight : 26) - v12);
      pRenderer->DrawTextureIndexed(8, 347 - v12, pTexture_591428);
      v13 = FitTextInAWindow(pGlobalTXT_LocalizationStrings[577], pFontArrus, &pWindow, 0xDu, 0);
      pDialogueWindow->DrawText(pFontArrus, 13, 354 - v12, 0, v13, 0, 0, 0);
      goto LABEL_42;
    }
    if ( uDialogueType == DIALOGUE_ARENA_REWARD )
    {
      sprintf(v4, pGlobalTXT_LocalizationStrings[576], dword_F8B1B4);// "Congratulations on your win: here's your stuff: %u gold."
      pInString = v4;
      pWindow.uFrameWidth = 460;
      pWindow.uFrameZ = 452;
      pOutString = pFontArrus;
      v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
      if ( 352 - v12 < 8 )
      {
        pOutString = pFontCreate;
        v12 = pFontCreate->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
      }
      pRenderer->_4A6A68(8, 352 - v12, (Texture *)(uTextureID_Leather != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_Leather] : 0),
        (uTextureID_Leather != -1 ? pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight : 26) - v12);
      pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
      v13 = FitTextInAWindow(pInString, pOutString, &pWindow, 0xDu, 0);
      pDialogueWindow->DrawText(pOutString, 13, 354 - v12, 0, v13, 0, 0, 0);
      goto LABEL_42;
    }
    if ( uDialogueType == DIALOGUE_ARENA_ALREADY_WON )
    {
      pInString = pGlobalTXT_LocalizationStrings[582]; // "You already won this trip to the Arena:"
      pWindow.uFrameWidth = 460;
      pWindow.uFrameZ = 452;
      pOutString = pFontArrus;
      v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
      if ( 352 - v12 < 8 )
      {
        pOutString = pFontCreate;
        v12 = pFontCreate->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
      }
      pRenderer->_4A6A68(8, 352 - v12, (Texture *)(uTextureID_Leather != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_Leather] : 0),
        (uTextureID_Leather != -1 ? pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight : 26) - v12);
      pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
      v13 = FitTextInAWindow(pInString, pOutString, &pWindow, 0xDu, 0);
      pDialogueWindow->DrawText(pOutString, 13, 354 - v12, 0, v13, 0, 0, 0);
      goto LABEL_42;
    }
  }
  else
  {
    if ( uDialogueType == DIALOGUE_ARENA_WELCOME )
    {
      v7 = pGlobalTXT_LocalizationStrings[574]; // "Welcome to the Arena of Life and Death.  Remember, you are only allowed one arena combat per visit.  To fight an arena battle, select the option that best describes your abilities and return to me- if you survive:"
      pInString = v7;
      pWindow.uFrameWidth = 460;
      pWindow.uFrameZ = 452;
      pOutString = pFontArrus;
      v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
      if ( 352 - v12 < 8 )
      {
        pOutString = pFontCreate;
        v12 = pFontCreate->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
      }
      pRenderer->_4A6A68(8, 352 - v12, (Texture *)(uTextureID_Leather != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_Leather] : 0),
        (uTextureID_Leather != -1 ? pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight : 26) - v12);
      pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
      v13 = FitTextInAWindow(pInString, pOutString, &pWindow, 0xDu, 0);
      pDialogueWindow->DrawText(pOutString, 13, 354 - v12, 0, v13, 0, 0, 0);
      goto LABEL_42;
    }
    if ( uDialogueType == DIALOGUE_13 )
    {
      v5 = 5 * pNPC->uProfession;
      v6 = (char *)*(&pNPCStats->field_13A64 + v5);
      v7 = sub_495461(v6, uActiveCharacter - 1, 0, 0, 0, 0);
      pInString = v7;
      pWindow.uFrameWidth = 460;
      pWindow.uFrameZ = 452;
      pOutString = pFontArrus;
      v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
      if ( 352 - v12 < 8 )
      {
        pOutString = pFontCreate;
        v12 = pFontCreate->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
      }
      pRenderer->_4A6A68(8, 352 - v12, (Texture *)(uTextureID_Leather != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_Leather] : 0),
        (uTextureID_Leather != -1 ? pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight : 26) - v12);
      pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
      v13 = FitTextInAWindow(pInString, pOutString, &pWindow, 0xDu, 0);
      pDialogueWindow->DrawText(pOutString, 13, 354 - v12, 0, v13, 0, 0, 0);
      goto LABEL_42;
    }
    if ( (signed int)uDialogueType > DIALOGUE_18 )
    {
      if ( (signed int)uDialogueType > DIALOGUE_24 )
      {
        if ( uDialogueType == DIALOGUE_77 )
        {
          v5 = 5 * pNPC->uProfession;
          if ( byte_F8B1EC )
          {
            v6 = (char *)*(&pNPCStats->field_13A5C + 5 * pNPC->uProfession);
            v7 = sub_495461(v6, uActiveCharacter - 1, 0, 0, 0, 0);
            pInString = v7;
            pWindow.uFrameWidth = 460;
            pWindow.uFrameZ = 452;
            pOutString = pFontArrus;
            v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
            if ( 352 - v12 < 8 )
            {
              pOutString = pFontCreate;
              v12 = pFontCreate->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
            }
            pRenderer->_4A6A68(8, 352 - v12, (Texture *)(uTextureID_Leather != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_Leather] : 0),
                              (uTextureID_Leather != -1 ? pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight : 26) - v12);
            pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
            v13 = FitTextInAWindow(pInString, pOutString, &pWindow, 0xDu, 0);
            pDialogueWindow->DrawText(pOutString, 13, 354 - v12, 0, v13, 0, 0, 0);
            goto LABEL_42;
          }
          if ( pNPC->uFlags & 0x80 )
          {
            v6 = (char *)*(&pNPCStats->field_13A68 + 5 * pNPC->uProfession);
            v7 = sub_495461(v6, uActiveCharacter - 1, 0, 0, 0, 0);
            pInString = v7;
            pWindow.uFrameWidth = 460;
            pWindow.uFrameZ = 452;
            pOutString = pFontArrus;
            v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
            if ( 352 - v12 < 8 )
            {
              pOutString = pFontCreate;
              v12 = pFontCreate->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
            }
            pRenderer->_4A6A68(8, 352 - v12, (Texture *)(uTextureID_Leather != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_Leather] : 0),
                               (uTextureID_Leather != -1 ? pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight : 26) - v12);
            pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
            v13 = FitTextInAWindow(pInString, pOutString, &pWindow, 0xDu, 0);
            pDialogueWindow->DrawText(pOutString, 13, 354 - v12, 0, v13, 0, 0, 0);
            goto LABEL_42;
          }
          v6 = (char *)*(&pNPCStats->field_13A64 + v5);
          v7 = sub_495461(v6, uActiveCharacter - 1, 0, 0, 0, 0);
          pInString = v7;
          pWindow.uFrameWidth = 460;
          pWindow.uFrameZ = 452;
          pOutString = pFontArrus;
          v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
          if ( 352 - v12 < 8 )
          {
            pOutString = pFontCreate;
            v12 = pFontCreate->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
          }
          pRenderer->_4A6A68(8, 352 - v12, (Texture *)(uTextureID_Leather != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_Leather] : 0),
                                     (uTextureID_Leather != -1 ? pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight : 26) - v12);
          pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
          v13 = FitTextInAWindow(pInString, pOutString,  &pWindow, 0xDu, 0);
          pDialogueWindow->DrawText(pOutString, 13, 354 - v12, 0, v13, 0, 0, 0);
          goto LABEL_42;
        }
        goto LABEL_24;
      }
      if ( byte_5B0938[0] )
        goto LABEL_24;
      v7 = (char *)ptr_F8B1E8;
      pInString = v7;
      pWindow.uFrameWidth = 460;
      pWindow.uFrameZ = 452;
      pOutString = pFontArrus;
      v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
      if ( 352 - v12 < 8 )
      {
        pOutString = pFontCreate;
        v12 = pFontCreate->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
      }
      pRenderer->_4A6A68(8, 352 - v12, (Texture *)(uTextureID_Leather != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_Leather] : 0),
        (uTextureID_Leather != -1 ? pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight : 26) - v12);
      pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
      v13 = FitTextInAWindow(pInString, pOutString, &pWindow, 0xDu, 0);
      pDialogueWindow->DrawText(pOutString, 13, 354 - v12, 0, v13, 0, 0, 0);
      goto LABEL_42;
    }
  }
LABEL_24:
  if ( *(int *)v54 == 1 )
  {
    v11 = pNPC->greet;
    v8 = 0;
    if ( v11 )
    {
      v10 = (char *)*(&pNPCStats->field_17884 + ((pNPC->uFlags & 3) == 2) + 2 * v11);
      goto LABEL_32;
    }
  }
  else
  {
    if ( *(int *)v54 == 2 )
    {
      if ( pNPC->uFlags & 0x80 )
        v9 = (char *)pNPCStats->pProfessions[pNPC->uProfession].pDismissText;
      else
        v9 = (char *)pNPCStats->pProfessions[pNPC->uProfession].pJoinText; //"Invalid String Passed"
       pInString = sub_495461(v9, uActiveCharacter - 1, 0, 0, 0, 0);
LABEL_32:

      if (  pInString == NULL )
        goto LABEL_42;
      pWindow.uFrameWidth = 460;
      pWindow.uFrameZ = 452;
      pOutString = pFontArrus;
      v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
      if ( 352 - v12 < 8 )
      {
        pOutString = pFontCreate;
        v12 = pFontCreate->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
      }
      pRenderer->_4A6A68(8, 352 - v12, (Texture *)(uTextureID_Leather != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_Leather] : 0),
        (uTextureID_Leather != -1 ? pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight : 26) - v12);
      pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
      v13 = FitTextInAWindow(pInString, pOutString, &pWindow, 0xDu, 0);
      pDialogueWindow->DrawText(pOutString, 13, 354 - v12, 0, v13, 0, 0, 0);
      goto LABEL_42;
    }
  }
LABEL_42:
  memcpy(&v52, pDialogueWindow, sizeof(v52));
  v52.uFrameX = 483;
  v52.uFrameWidth = 148;
  v52.uFrameZ = 334;
  for ( pOutString = (GUIFont *)v52.pStartingPosActiveItem;
        (signed int)pOutString < v52.pStartingPosActiveItem + v52.pNumPresenceButton;
        pOutString = (GUIFont *)((char *)pOutString + 1) )
  {
    v14 = v52.GetControl((unsigned int)pOutString);
    v15 = v14;
    if ( !v14 )
      break;
    v16 = v14->uControlParam;
    if ( v16 > 24 )
    {
      v25 = v16 - 76;
      if ( v25 )
      {
        v26 = v25 - 1;
        if ( v26 )
        {
          v27 = v26 - 8;
          if ( v27 )
          {
            v28 = v27 - 1;
            if ( v28 )
            {
              v29 = v28 - 1;
              if ( v29 )
              {
                if ( v29 != 1 )
                {
                  v24 = "";
                  goto LABEL_79;
                }
                v24 = pGlobalTXT_LocalizationStrings[581];
              }
              else
              {
                v24 = pGlobalTXT_LocalizationStrings[580];
              }
            }
            else
            {
              v24 = pGlobalTXT_LocalizationStrings[579];
            }
          }
          else
          {
            v24 = pGlobalTXT_LocalizationStrings[578];
          }
        }
        else
        {
          v24 = pGlobalTXT_LocalizationStrings[407];
        }
      }
      else
      {
        if ( pNPC->uFlags & 0x80 )
        {
          sprintf(pTmpBuf, (const char*)pGlobalTXT_LocalizationStrings[408], pNPC->pName);
          v24 = pTmpBuf;
          goto LABEL_79;
        }
        v24 = pGlobalTXT_LocalizationStrings[406];
      }
    }
    else
    {
      if ( v16 == 24 )
      {
        v23 = pNPC->evtf;
LABEL_63:
        v24 = pNPCTopics[v23-1].pTopic;//(&dword_721660)[8 * v23];
        if ( !v24 )
        {
          v24 = "";
          v15->uControlParam = 0;
        }
        goto LABEL_79;
      }
      v17 = v16 - 9;
      if ( !v17 )
      {
        v24 = (const char *)sub_445308(pNPC->uProfession);
        goto LABEL_79;
      }
      v18 = v17 - 4;
      if ( v18 )
      {
        v19 = v18 - 6;
        if ( !v19 )
        {
          v23 = pNPC->bDrawSomeAnim;
          goto LABEL_63;
        }
        v20 = v19 - 1;
        if ( !v20 )
        {
          v23 = pNPC->_anim_current_time;
          goto LABEL_63;
        }
        v21 = v20 - 1;
        if ( !v21 )
        {
          v23 = pNPC->_anim_end_time;
          goto LABEL_63;
        }
        v22 = v21 - 1;
        if ( !v22 )
        {
          v23 = pNPC->evtd;
          goto LABEL_63;
        }
        if ( v22 == 1 )
        {
          v23 = pNPC->evte;
          goto LABEL_63;
        }
        v24 = "";
        goto LABEL_79;
      }
      if ( pNPC->uFlags & 0x80 )
      {
        sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[408], pNPC->pName);
        v24 = pTmpBuf;
        goto LABEL_79;
      }
      v24 = pGlobalTXT_LocalizationStrings[122];
    }
LABEL_79:
    if ( pParty->field_7B5_in_arena_quest && pParty->field_7B5_in_arena_quest != -1 )
    {
      pInString = 0;
      if ( (signed int)uNumActors > 0 )
      {
        v55 = (unsigned short *)&pActors[0].uAIState;
        *(int *)v54 = uNumActors;
        do
        {
          v30 = *v55;
          if ( *v55 == Dead || v30 == Removed || v30 == Disabled || (v31 = *((int *)v55 + 159)) != 0 && (v31 & 7) == OBJECT_Player)
            ++pInString;
          v55 += 418;
          --*(int *)v54;
        }
        while ( *(int *)v54 );
      }
      if ( pInString == (char *)uNumActors )
        v24 = pGlobalTXT_LocalizationStrings[658];
    }
    strcpy(v15->pButtonName, v24);
  }
  v32 = 0;
  pInString = (char *)GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0xFFu);
  v33 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xE1u, 0xCDu, 0x23u);
  v34 = pDialogueWindow;
  *(int *)v54 = v33;
  v35 = pDialogueWindow->pStartingPosActiveItem;
  for ( i = v35 + pDialogueWindow->pNumPresenceButton; v35 < i; i = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem )
  {
    v37 = v34->GetControl(v35);
    if ( !v37 )
    {
      v34 = pDialogueWindow;
      break;
    }
    v38 = pFontArrus->CalcTextHeight(v37->pButtonName, &v52, 0, 0);
    v34 = pDialogueWindow;
    v32 += v38;
    ++v35;
  }
  v39 = v34->pNumPresenceButton;
  if ( v39 )
  {
    pOutString = (GUIFont *)((174 - v32) / v39);
    if ( (174 - v32) / v39 > 32 )
      pOutString = (GUIFont *)32;
    v55 = (unsigned __int16 *)1;
    v40 = 174 - (int)pOutString * v39 - v32;
    v41 = v34->pStartingPosActiveItem;
    v42 = v40 / 2 - (signed int)pOutString / 2 + 138;
    if ( (signed int)v41 < (signed int)(v41 + v39) )
    {
      do
      {
        v43 = v34->GetControl(v41);
        if ( !v43 )
          break;
        v43->uY = (unsigned int)((char *)pOutString + v42);
        Str = v43->pButtonName;
        v44 = pFontArrus->CalcTextHeight(v43->pButtonName, &v52, 0, 0);
        v45 = v43->uY;
        v46 = v55;
        v43->uHeight = v44;
        v42 = v45 + v44 - 1;
        v43->uW = v42;
        v47 = v54[0];
        if ( (unsigned __int16 *)pDialogueWindow->pCurrentPosActiveItem != v46 )
          v47 = (unsigned __int16)pInString;
        v52.DrawTitleText(pFontArrus, 0, v45, v47, Str, 3u);
        v34 = pDialogueWindow;
        v55 = (unsigned __int16 *)((char *)v55 + 1);
        ++v41;
      }
      while ( (signed int)v41 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
    }
  }
  pRenderer->DrawTextureIndexed(471, 445, (Texture *)(uTextureID_506438 != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_506438] : 0));
}

//----- (004459F9) --------------------------------------------------------
NPCData *__fastcall GetNPCData(unsigned int npcid)
{
  unsigned int v1; // esi@1
  NPCData *result; // eax@5
  int v3; // esi@9
  int v4; // ecx@9
  //int v5; // edx@9
  //NPCData *v6; // eax@9
  char *v7; // ebx@14
  NPCData *v8; // edi@14
  char v9; // al@22
  char v10;
  //std::string v10; // [sp-18h] [bp-2Ch]@4
  int v11;
  //const char *v11; // [sp-8h] [bp-1Ch]@4
  int v12; // [sp-4h] [bp-18h]@4
  int v13; 
  char *v14;
  //std::string *v13; // [sp+Ch] [bp-8h]@4
  int a3; // [sp+13h] [bp-1h]@4
  int i;

  /*v1 = npcid;
  if ( (npcid & 0x80000000u) == 0 )
  {
    if ( (signed int)npcid < 5000 )
    {
      if ( (signed int)npcid >= 501 )
      {
    MessageBoxW(nullptr, L"NPC id exceeds MAX_DATA!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Events.cpp:1984", 0);
      }
      return &pNPCStats->pNewNPCData[v1];
    }
    return &pNPCStats->array_13EF4[npcid - 5000];
  }
  if ( (signed int)npcid >= 5000 )
    return &pNPCStats->array_13EF4[npcid - 5000];
  if ( (uDialogue_SpeakingActorNPC_ID & 0x80000000u) == 0 )
  {
    result = 0;
  }
  else
  {
    v3 = abs((int)uDialogue_SpeakingActorNPC_ID) - 1;
    v4 = 0;
    v5 = 0;
    v6 = pParty->pHirelings;
    do
    {
      if ( v6->pName )
        pTmpBuf[v4++] = v5;
      ++v6;
      ++v5;
    }
    while ( (signed int)v6 < (signed int)&pParty->pPickedItem );
    v13 = 0;
    if ( (signed int)pNPCStats->uNumNewNPCs > 0 )
    {
      v7 = &pTmpBuf[v4];
      v8 = pNPCStats->pNewNPCData;
      do
      {
        if ( v8->uFlags & 0x80
          && (!pParty->pHirelings[0].pName || strcmp(v8->pName, pParty->pHirelings[0].pName))
          && (!pParty->pHirelings[1].pName || strcmp(v8->pName, pParty->pHirelings[1].pName)) )
          *v7++ = (char)v13 + 2;
        v13 = (std::string *)((char *)v13 + 1);
        ++v8;
      }
      while ( (signed int)v13 < (signed int)pNPCStats->uNumNewNPCs );
    }
    v9 = pTmpBuf[v3];
    if ( (unsigned __int8)v9 >= 2u )
      result = &pNPCStats->pNPCData[(unsigned __int8)v9 + 499];
    else
      result = &pParty->pHirelings[(unsigned __int8)v9];
  }
  return result;*/
  v1 = npcid;
  if ( npcid >= 0 )
  {
    if ( npcid < 5000 )
    {
      if ( npcid >= 501 )
      {
        MessageBoxW(nullptr, L"NPC id exceeds MAX_DATA!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Events.cpp:1984", 0);
      }
      return &pNPCStats->pNewNPCData[v1 - 1];
    }
    return &pNPCStats->array_13EF4[npcid - 5000];
  }


  if ( npcid >= 5000 )
    return &pNPCStats->array_13EF4[npcid - 5000];
  if (uDialogue_SpeakingActorNPC_ID >= 0)
  {
    result = 0;
  }
  else
  {
    v3 = uDialogue_SpeakingActorNPC_ID - 1;
    v4 = 0;

    for (i = 0; i < 4; ++i)
    {
      if (pParty->pHirelings[i].pName)
        pTmpBuf[v4++] = i;
    }

    if (pNPCStats->uNumNewNPCs > 0)
    {
      for (i = 0; i < pNPCStats->uNumNewNPCs; ++i)
      {
        if (pNPCStats->pNewNPCData[i].uFlags & 0x80)
        {
          if (!pParty->pHirelings[0].pName || strcmp((char *)pNPCStats->pNewNPCData[i].pName, (char *)pParty->pHirelings[0].pName))
          {
            if (!pParty->pHirelings[1].pName || strcmp((char *)pNPCStats->pNewNPCData[i].pName, (char *)pParty->pHirelings[1].pName))
              pTmpBuf[v4++] = i + 2;
          }
        }
      }
    }

    v9 = pTmpBuf[v3];
    if ( v9 >= 2 )
     result = &pNPCStats->pNPCData[499 + v9];
    else
      result = &pParty->pHirelings[v9];
  }
}

//----- (00445B2C) --------------------------------------------------------
NPCData *__fastcall GetNewNPCData(signed int npcid, int a2)
{
  signed int v2; // esi@1
  int v3; // edi@1
  NPCData *result; // eax@5
  int v5; // esi@9
  int v6; // ecx@9
  int v7; // edx@9
  NPCData *v8; // eax@9
  NPCData *v9; // edi@14
  int v10; // ecx@20
  char v11; // al@23
  std::string v12; // [sp-18h] [bp-34h]@4
  const char *v13; // [sp-8h] [bp-24h]@4
  int v14; // [sp-4h] [bp-20h]@4
  std::string *v15; // [sp+Ch] [bp-10h]@1
  char *v16; // [sp+10h] [bp-Ch]@14
  int v17; // [sp+14h] [bp-8h]@13
  int a3; // [sp+1Bh] [bp-1h]@4

  v2 = npcid;
  v3 = a2;
  v15 = (std::string *)a2;
  if ( npcid >= 0 )
  {
    if ( npcid < 5000 )
    {
      if ( npcid >= 501 )
      {
    MessageBoxW(nullptr, L"NPC id exceeds MAX_DATA!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Events.cpp:2040", 0);
      }
      *(int *)v3 = v2;
      return &pNPCStats->pNewNPCData[v2];
    }
LABEL_7:
    *(int *)a2 = npcid - 5000;
    return &pNPCStats->array_13EF4[npcid - 5000];
  }
  if ( npcid >= 5000 )
    goto LABEL_7;
  if ( (uDialogue_SpeakingActorNPC_ID & 0x80000000u) == 0 )
  {
    *(int *)a2 = 0;
    result = 0;
  }
  else
  {
    v5 = abs((int)uDialogue_SpeakingActorNPC_ID) - 1;
    v6 = 0;
    v7 = 0;
    v8 = pParty->pHirelings;
    do
    {
      if ( v8->pName )
        pTmpBuf[v6++] = v7;
      ++v8;
      ++v7;
    }
    while ( (signed int)v8 < (signed int)&pParty->pPickedItem );
    v17 = 0;
    if ( (signed int)pNPCStats->uNumNewNPCs > 0 )
    {
      v9 = pNPCStats->pNewNPCData;
      v16 = &pTmpBuf[v6];
      do
      {
        if ( v9->uFlags & 0x80
          && (!pParty->pHirelings[0].pName || strcmp(v9->pName, pParty->pHirelings[0].pName))
          && (!pParty->pHirelings[1].pName || strcmp(v9->pName, pParty->pHirelings[1].pName)) )
        {
          v10 = (int)v16++;
          *(char *)v10 = v17 + 2;
        }
        ++v17;
        ++v9;
      }
      while ( v17 < (signed int)pNPCStats->uNumNewNPCs );
      v3 = (int)v15;
    }
    v11 = pTmpBuf[v5];
    if ( (unsigned __int8)v11 >= 2u )
    {
      *(int *)v3 = (unsigned __int8)v11 - 2;
      result = &pNPCStats->pNPCData[(unsigned __int8)pTmpBuf[v5] + 499];
    }
    else
    {
      *(int *)v3 = (unsigned __int8)v11;
      result = &pParty->pHirelings[(unsigned __int8)pTmpBuf[v5]];
    }
  }
  return result;
}

//----- (00445C8B) --------------------------------------------------------
int __fastcall sub_445C8B(signed int a1)
{
  signed int v1; // ebx@1
  int v3; // edi@6
  int v4; // ecx@6
  int v5; // edx@6
  NPCData *v6; // eax@6
  char *v7; // ebp@11
  NPCData *v8; // esi@11

  v1 = 0;
  if ( a1 >= 0 )
  {
    if ( a1 < 5000 )
      return 1;
    return 2;
  }
  if ( a1 >= 5000 )
    return 2;
  v3 = abs((int)uDialogue_SpeakingActorNPC_ID) - 1;
  v4 = 0;
  v5 = 0;
  v6 = pParty->pHirelings;
  do
  {
    if ( v6->pName )
      pTmpBuf[v4++] = v5;
    ++v6;
    ++v5;
  }
  while ( (signed int)v6 < (signed int)&pParty->pPickedItem );
  if ( (signed int)pNPCStats->uNumNewNPCs > 0 )
  {
    v7 = &pTmpBuf[v4];
    v8 = pNPCStats->pNewNPCData;
    do
    {
      if ( v8->uFlags & 0x80 && (!pParty->pHirelings[0].pName || strcmp(v8->pName, pParty->pHirelings[0].pName)) )
      {
        if ( !pParty->pHirelings[1].pName || strcmp(v8->pName, pParty->pHirelings[1].pName) )
          *v7++ = v1 + 2;
      }
      ++v1;
      ++v8;
    }
    while ( v1 < (signed int)pNPCStats->uNumNewNPCs );
  }
  return ((unsigned __int8)pTmpBuf[v3] < 2u) + 1;
}


//----- (0044603D) --------------------------------------------------------
void __cdecl sub_44603D()
{
  uDialogue_SpeakingActorNPC_ID = 0;
  pDialogueWindow->Release();
  pDialogueWindow = 0;
  pMiscTimer->Resume();
  pEventTimer->Resume();
}


//----- (004465DF) --------------------------------------------------------
int sub_4465DF_check_season(int a1)
{
  unsigned int v1; // eax@1
  unsigned int v2; // edx@1
  int v3; // ecx@2
  int v4; // ecx@3
  char v6; // zf@9

  v1 = pParty->uCurrentMonth + 1;
  v2 = pParty->uDaysPlayed + 1;
  if ( a1 )
  {
    v3 = a1 - 1;
    if ( v3 )
    {
      v4 = v3 - 1;
      if ( v4 )
      {
        if ( v4 != 1 )
          return 0;
        if ( v1 != 12 )
        {
          if ( (signed int)v1 >= 1 && (signed int)v1 <= 2 )
            return 1;
          v6 = v1 == 3;
LABEL_24:
          if ( !v6 || (signed int)v2 >= 21 )
            return 0;
          return 1;
        }
      }
      else
      {
        if ( v1 != 9 )
        {
          if ( (signed int)v1 >= 10 && (signed int)v1 <= 11 )
            return 1;
          v6 = v1 == 12;
          goto LABEL_24;
        }
      }
    }
    else
    {
      if ( v1 != 6 )
      {
        if ( (signed int)v1 >= 7 && (signed int)v1 <= 8 )
          return 1;
        v6 = v1 == 9;
        goto LABEL_24;
      }
    }
  }
  else
  {
    if ( v1 != 3 )
    {
      if ( (signed int)v1 >= 4 && (signed int)v1 <= 5 )
        return 1;
      v6 = v1 == 6;
      goto LABEL_24;
    }
  }
  if ( (signed int)v2 >= 21 )
    return 1;
  return 0;
}

//----- (0044665D) --------------------------------------------------------
// uType:     0 -> any monster
//            1 -> uParam is GroupID
//            2 -> uParam is MonsterID
//            3 -> uParam is ActorID
// uNumAlive: 0 -> all must be alive
int __fastcall IsActorAlive(unsigned int uType, unsigned int uParam, unsigned int uNumAlive)
{
  unsigned int uAliveActors; // eax@6
  int v5; // ecx@10
  unsigned int uTotalActors; // [sp+0h] [bp-4h]@1

  uTotalActors = 0;
  if ( uType )
  {
    if ( uType == 1 )
    {
      uAliveActors = SearchActorByGroup(&uTotalActors, uParam);
    }
    else
    {
      if ( uType == 2 )
      {
        uAliveActors = SearchActorByMonsterID(&uTotalActors, uParam);
      }
      else
      {
        if ( uType != 3 )
          return 0;
        uAliveActors = SearchActorByID(&uTotalActors, uParam);
      }
    }
  }
  else
  {
    uAliveActors = SearchAliveActors(&uTotalActors);
  }
  v5 = 0;
  if ( uNumAlive )
    LOBYTE(v5) = (signed int)uAliveActors >= (signed int)uNumAlive;
  else
    LOBYTE(v5) = uTotalActors == uAliveActors;
  return v5;
}

//----- (004466C4) --------------------------------------------------------
bool __thiscall sub_4466C4(void *_this)
{
  signed int v1; // ebp@1
  bool result; // eax@2
  int v3; // esi@3
  signed int v4; // edx@3
  signed int v5; // eax@4
  unsigned int v6; // ebx@6
  char *v7; // eax@6
  signed int v8; // edi@18
  int v9; // eax@19
  Player *v10; // [sp+8h] [bp-10h]@18
  signed int v11; // [sp+Ch] [bp-Ch]@3
  signed int v12; // [sp+10h] [bp-8h]@3
  void *v13; // [sp+14h] [bp-4h]@1

  v1 = 0;
  v13 = _this;
  if ( !_this )
    return 0;
  v3 = dword_597F18;
  pSomeOtherEVT = pGlobalEVT;
  uSomeOtherEVT_NumEvents = uGlobalEVT_NumEvents;
  memcpy(pSomeOtherEVT_Events, pGlobalEVT_Events, 0xCE40u);
  v4 = 1;
  v12 = 1;
  v11 = 0;
  if ( (signed int)uSomeOtherEVT_NumEvents <= 0 )
    goto LABEL_16;
  do
  {
    v5 = v1;
    if ( (void *)pSomeOtherEVT_Events[v1].uEventID == v13 && pSomeOtherEVT_Events[v5].field_4 == v3 )
    {
      v6 = pSomeOtherEVT_Events[v5].uEventOffsetInEVT;
      v7 = &pSomeOtherEVT[v6];
      if ( (unsigned __int8)pSomeOtherEVT[v6 + 4] == 1 )
        break;
      if ( (unsigned __int8)pSomeOtherEVT[v6 + 4] == 44 )
      {
        v11 = v4;
        v10 = pParty->pPlayers;
        v8 = (unsigned __int8)v7[7]
           + (((unsigned __int8)v7[8] + (((unsigned __int8)v7[9] + ((unsigned __int8)v7[10] << 8)) << 8)) << 8);
        while ( 1 )
        {
          LOBYTE(v9) = v10->CompareVariable(
                         (enum VariableType)((unsigned __int8)pSomeOtherEVT[v6 + 5]
                                           + ((unsigned __int8)pSomeOtherEVT[v6 + 6] << 8)),
                         v8);
          if ( v9 )
            break;
          ++v10;
          if ( (signed int)v10 >= (signed int)pParty->pHirelings )
            goto LABEL_13;
        }
      }
      else
      {
        if ( (unsigned __int8)pSomeOtherEVT[v6 + 4] == 45 )
          break;
        if ( (unsigned __int8)pSomeOtherEVT[v6 + 4] == 46 )
        {
          v11 = v4;
          v12 = (unsigned __int8)v7[5];
          goto LABEL_13;
        }
        if ( (unsigned __int8)pSomeOtherEVT[v6 + 4] != 52
          || !IsActorAlive(
                (unsigned __int8)v7[5],
                (unsigned __int8)v7[6]
              + (((unsigned __int8)v7[7] + (((unsigned __int8)v7[8] + ((unsigned __int8)v7[9] << 8)) << 8)) << 8),
                (unsigned __int8)v7[10]) )
          goto LABEL_13;
      }
      v1 = -1;
      v3 = (unsigned __int8)pSomeOtherEVT[v6 + 11] - 1;
LABEL_13:
      ++v3;
      v4 = 1;
    }
    ++v1;
  }
  while ( v1 < (signed int)uSomeOtherEVT_NumEvents );
  if ( v11 )
    result = v12 != 0;
  else
LABEL_16:
    result = 2;
  return result;
}


//----- (0044684A) --------------------------------------------------------
void __fastcall EventProcessor(int uEventID, int a2, int a3)
{
  unsigned int v3; // eax@5
  //signed int v4; // esi@7
  //char *v5; // eax@8
  Player *v6; // ecx@8
  //char *v7; // ebp@8
  //signed int v8; // edx@10
  //int v9; // edi@12
  //ByteArray *v10; // esi@12
  int v11; // eax@14
  char *v12; // eax@15
  //char *v13; // edi@21
  int v14; // ebp@21
  int v15; // edi@21
  const char *v16; // esi@21
  bool v17; // edx@21
  int v18; // ecx@22
  int v19; // ebp@36
  signed int v20; // ecx@40
  int v21; // eax@40
  int v22; // edx@40
  int v23; // eax@40
  unsigned __int16 v24; // ax@45
  int v25; // eax@54
  LevelDecoration *v26; // eax@55
  int v27; // eax@57
  int v28; // ecx@57
  int v29; // edx@58
  int v30; // eax@58
  int v31; // ecx@58
  int v32; // esi@58
  NPCData *v33; // ecx@58
  int v34; // esi@59
  int v35; // esi@60
  int v36; // esi@61
  int v37; // esi@62
  int v38; // eax@78
  int v39; // ecx@78
  size_t v40; // edx@78
  Actor *v41; // esi@79
  int v42; // eax@84
  int v43; // ecx@84
  size_t v44; // edx@84
  Actor *v45; // esi@85
  void *v46; // eax@91
  GUIWindow *v47; // eax@93
  GUIButton *v48; // ecx@93
  GUIButton *v49; // esi@94
  char v50; // al@100
  Player *v51; // esi@103
  Player *v52; // ecx@106
  int v53; // ecx@107
  char v54; // al@111
  Player *v55; // esi@114
  Player *v56; // ecx@117
  int v57; // ecx@118
  signed int v58; // ebp@124
  Player *v59; // esi@125
  int v60; // eax@126
  int v61; // edx@133
  int v62; // eax@139
  void *v63; // ebp@145
  signed int v64; // edi@146
  unsigned int v65; // edx@148
  Player *v66; // ecx@148
  int v67; // esi@148
  signed int v68; // eax@151
  int v69; // esi@151
  Player *v70; // ecx@158
  unsigned int v71; // eax@159
  int v72; // esi@159
  signed int v73; // eax@162
  int v74; // esi@162
  int v75; // edx@172
  Player *v76; // esi@173
  signed int v77; // ebp@186
  int v78; // edx@186
  Player *v79; // esi@187
  signed int v80; // ebp@200
  int v81; // edx@200
  Player *v82; // esi@201
  int v83; // eax@212
  int v84; // ebp@220
  signed int v85; // ebp@224
  char v86; // al@224
  Player *v87; // esi@227
  Player *v88; // ecx@231
  int v89; // ecx@232
  int v90; // eax@243
  const char *v91; // ecx@247
  int v92; // eax@251
  char *v93; // eax@252
  int v94; // ecx@262
  int v95; // ebp@262
  int v96; // edx@262
  int v97; // eax@262
  unsigned int v98; // edx@265
  const char *v99; // esi@267
  int v100; // edx@267
  //char *v101; // edi@281
  unsigned int v102; // esi@281
  int v103; // edi@284
  int v104; // eax@288
  int v105; // edx@294
  int v106; // [sp-20h] [bp-4C8h]@278
  signed int v107; // [sp-1Ch] [bp-4C4h]@278
  unsigned int v108; // [sp-18h] [bp-4C0h]@278
  signed int v109; // [sp-14h] [bp-4BCh]@278
  signed int v110; // [sp-10h] [bp-4B8h]@278
  int v111; // [sp-Ch] [bp-4B4h]@278
  Event *v112; // [sp-8h] [bp-4B0h]@5
  int v113; // [sp-8h] [bp-4B0h]@106
  int v114; // [sp-8h] [bp-4B0h]@117
  signed int v115; // [sp-8h] [bp-4B0h]@231
  unsigned int v116; // [sp-8h] [bp-4B0h]@278
  int v117; // [sp-4h] [bp-4ACh]@106
  int v118; // [sp-4h] [bp-4ACh]@117
  int v119; // [sp-4h] [bp-4ACh]@231
  int v120; // [sp-4h] [bp-4ACh]@278
  int v121; // [sp-4h] [bp-4ACh]@294
  int v122; // [sp+10h] [bp-498h]@4
  //char *v123; // [sp+14h] [bp-494h]@0
  //signed int v124; // [sp+18h] [bp-490h]@7
  signed int v125; // [sp+1Ch] [bp-48Ch]@155
  int v126; // [sp+1Ch] [bp-48Ch]@262
  int v127; // [sp+20h] [bp-488h]@4
  int v128; // [sp+24h] [bp-484h]@21
  int v129; // [sp+24h] [bp-484h]@262
  signed int v130; // [sp+28h] [bp-480h]@0
  //int v131; // [sp+2Ch] [bp-47Ch]@1
  int v132; // [sp+30h] [bp-478h]@262
  signed int v133; // [sp+34h] [bp-474h]@1
  int v134; // [sp+38h] [bp-470h]@262
  int v135; // [sp+3Ch] [bp-46Ch]@262
  int v136; // [sp+40h] [bp-468h]@40
  int v137; // [sp+44h] [bp-464h]@40
  int v138; // [sp+48h] [bp-460h]@40
  int v139; // [sp+4Ch] [bp-45Ch]@40
  ItemGen item; // [sp+50h] [bp-458h]@15
  char Source[120]; // [sp+74h] [bp-434h]@15
  char Str[120]; // [sp+ECh] [bp-3BCh]@21
  Actor Dst; // [sp+164h] [bp-344h]@53

  //v131 = uEventID;
  v133 = 0;
  dword_5B5920 = a2;
  dword_5B65C4 = 0;
  if ( !a1 )
  {
    if ( !GameUI_StatusBar_TimedStringTimeLeft )
      ShowStatusBarString(pGlobalTXT_LocalizationStrings[521], 2u);// Nothing here
    return;
  }
  v127 = 2 * (uActiveCharacter == 0) + 4;
  v122 = dword_597F18;
  if ( _5C3420_pDecoration )
  {
    v3 = uGlobalEVT_NumEvents;
    pSomeEVT = pGlobalEVT;
    v112 = pGlobalEVT_Events;
  }
  else
  {
    v3 = uLevelEVT_NumEvents;
    pSomeEVT = pLevelEVT;
    v112 = pLevelEVT_Events;
  }
  uSomeEVT_NumEvents = v3;
  memcpy(pSomeEVT_Events, v112, 0xCE40u);
  //v4 = 0;
  //v124 = 0;
  for (uint i = 0; i < uSomeEVT_NumEvents; ++i)
  {
    //v5 = pSomeEVT;
    //v6 = v123;
    //v7 = "";
    //while ( 1 )
    //{
      if ( dword_5B65C4 )
        goto LABEL_301;
      //v8 = v4;
      if ( pSomeEVT_Events[i/*v4*/].uEventID == uEventID && pSomeEVT_Events[i/*v4*/].field_4 == v122 )
      {
        //v9 = pSomeEVT_Events[v8].uEventOffsetInEVT;
        //v10 = (ByteArray *)&v5[v9];
        auto _evt = (_evt_raw *)(pSomeEVT + pSomeEVT_Events[i/*v4*/].uEventOffsetInEVT);

        switch (_evt->v4)
        {
          case EVENT_CheckSeason:
            if ( !sub_4465DF_check_season(_evt->v5) )
            {
              ++v122;
              //v4 = v124;
              //v5 = pSomeEVT;
              //v6 = v123;
              //v7 = "";
              break;
            }
            v11 = _evt->v6;
            goto LABEL_130;
          case EVENT_ShowMovie:
            strcpy(Source, (char *)&_evt->v7);
            v12 = (char *)&item.uExpireTime + strlen(Source) + 7;
            if ( *v12 == 32 )
              *v12 = 0;
            if ( pVideoPlayer->field_54 )
              pVideoPlayer->Unload();
            pVideoPlayer->bStopBeforeSchedule = 0;
            pVideoPlayer->pResetflag = 0;
            if (pAsyncMouse)
              pAsyncMouse->Suspend();
            v128 = pCurrentScreen;
            //v13 = &pSomeEVT[v9];
            //v14 = (unsigned __int8)v13[5];
            //v15 = (unsigned __int8)v13[6];
            v14 = _evt->v5;
            v15 = _evt->v6;
            strcpy(Str, Source);
            v16 = RemoveQuotes(Str);
            VideoPlayer::MovieLoop(v16, 0, v14, 1);
            if ( !_strcmpi(v16, "arbiter good") )
            {
              pParty->uAlignment = 0;
              v18 = 0;
              LOBYTE(v17) = 1;
              SetUserInterface(v18, v17);
              if ( !v15 || v128 == 3 )
              {
                pCurrentScreen = v128;
                if ( v128 == 3 )
                  pGameLoadingUI_ProgressBar->uType = GUIProgressBar::TYPE_Fullscreen;
                if ( v128 == 13 )
                  pVideoPlayer->_4BF28F(pAnimatedRooms[uCurrentHouse_Animation].field_0, 1u);
              }
              if (pAsyncMouse)
                pAsyncMouse->Resume();
              ++v122;
              //v4 = v124;
              //v5 = pSomeEVT;
              //v6 = v123;
              //v7 = "";
              break;
            }
            if ( !_strcmpi(v16, "arbiter evil") )
            {
              v18 = 2;
              pParty->uAlignment = 2;
              LOBYTE(v17) = 1;
              SetUserInterface(v18, v17);
              if ( !v15 || v128 == 3 )
              {
                pCurrentScreen = v128;
                if ( v128 == 3 )
                  pGameLoadingUI_ProgressBar->uType = GUIProgressBar::TYPE_Fullscreen;
                if ( v128 == 13 )
                  pVideoPlayer->_4BF28F(pAnimatedRooms[uCurrentHouse_Animation].field_0, 1u);
              }
              if (pAsyncMouse)
                pAsyncMouse->Resume();
              ++v122;
              //v4 = v124;
              //v5 = pSomeEVT;
              //v6 = v123;
              //v7 = "";
              break;
            }
            if ( !_strcmpi(v16, "pcout01") )    // moving to harmondale from emerald isle
            {
              Rest(0x2760u);
              pParty->RestAndHeal();
              pParty->field_764 = 0;
            }
            if ( !v15 || v128 == 3 )
            {
              pCurrentScreen = v128;
              if ( v128 == 3 )
                pGameLoadingUI_ProgressBar->uType = GUIProgressBar::TYPE_Fullscreen;
              if ( v128 == 13 )
                pVideoPlayer->_4BF28F(pAnimatedRooms[uCurrentHouse_Animation].field_0, 1u);
            }
            if (pAsyncMouse)
              pAsyncMouse->Resume();
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_CheckSkill:
            v19 = _evt->v7 + ((_evt->v8 + ((_evt->v9 + ((unsigned int)_evt->v10 << 8)) << 8)) << 8);
            if ( v127 < 0 )
              goto LABEL_47;
            if ( v127 <= 3 )
            {
              v24 = pParty->pPlayers[0].pActiveSkills[3486 * v127 + _evt->v5];
            }
            else
            {
              if ( v127 == 4 )
              {
                v24 = pPlayers[uActiveCharacter]->pActiveSkills[_evt->v5];
              }
              else
              {
                if ( v127 == 5 )
                {
                  v20 = 0;
                  v21 = 3486 * v130 + _evt->v5;
                  v136 = 1;
                  LOWORD(v21) = pParty->pPlayers[0].pActiveSkills[v21];
                  v137 = v21 & 0x40;
                  v138 = v21 & 0x80;
                  v22 = v21 & 0x100;
                  v23 = v21 & 0x3F;
                  v139 = v22;
                  while ( v23 < v19 || !*(&v136 + _evt->v6) )
                  {
                    ++v20;
                    if ( v20 >= 4 )
                    {
                      ++v122;
                      //v4 = v124;
                      //v5 = pSomeEVT;
                      //v6 = v123;
                      //v7 = "";
                      break;
                    }
                  }
                  v11 = _evt->v11;
                  goto LABEL_130;
                }
LABEL_47:
                //v10 = (ByteArray *)&v5[v9];
                v24 = pParty->pPlayers[0].pActiveSkills[_evt->v5 + 3486 * rand() % 4];
              }
            }
            v136 = 1;
            v137 = v24 & 0x40;
            v138 = v24 & 0x80;
            v139 = v24 & 0x100;
            if ( (v24 & 0x3F) >= v19 && *(&v136 + _evt->v6) )
            {
              v11 = _evt->v11;
              goto LABEL_130;
            }
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_SpeakNPC:
            if ( a3 )
            {
              //Actor::Actor(&Dst);
              memset(&Dst, 0, 0x344u);
              dword_5B65D0_dialogue_actor_npc_id = _evt->v5
                                                 + ((_evt->v6
                                                   + ((_evt->v7
                                                     + ((unsigned int)_evt->v8 << 8)) << 8)) << 8);
              Dst.uNPC_ID = dword_5B65D0_dialogue_actor_npc_id;
              Dst.InitializeDialogue(0);
            }
            else
            {
              bDialogueUI_InitializeActor_NPC_ID = _evt->v5
                                                 + ((_evt->v6 + ((_evt->v7 + ((unsigned int)_evt->v8 << 8)) << 8)) << 8);
            }
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_ChangeEvent:
            v25 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((unsigned int)_evt->v8 << 8)) << 8)) << 8);
            if ( v25 )
            {
              stru_5E4C90._decor_events[_5C3420_pDecoration->_idx_in_stru123 - 75] = _evt->v5 - 124;
            }
            else
            {
              v26 = _5C3420_pDecoration;
              stru_5E4C90._decor_events[_5C3420_pDecoration->_idx_in_stru123 - 75] = 0;
              LOBYTE(v26->field_2) |= 0x20u;
            }
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_SetNPCGreeting:
            v27 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
            v28 = _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8);
            pNPCStats->pNewNPCData[v27].uFlags &= 0xFFFFFFFCu;
            pNPCStats->pNewNPCData[v27].greet = v28;
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_SetNPCTopic:
            v29 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
            v30 = _evt->v10 + ((_evt->v11 + ((_evt->v12 + ((uint)_evt->v13 << 8)) << 8)) << 8);
            v31 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
            v32 = _evt->v9;
            v33 = &pNPCStats->pNewNPCData[v31];
            if ( v32 )
            {
              v34 = v32 - 1;
              if ( v34 )
              {
                v35 = v34 - 1;
                if ( v35 )
                {
                  v36 = v35 - 1;
                  if ( v36 )
                  {
                    v37 = v36 - 1;
                    if ( v37 )
                    {
                      if ( v37 == 1 )
                        v33->evtf = v30;
                    }
                    else
                    {
                      v33->evte = v30;
                    }
                  }
                  else
                  {
                    v33->evtd = v30;
                  }
                }
                else
                {
                  v33->_anim_end_time = v30;
                }
              }
              else
              {
                v33->_anim_current_time = v30;
              }
            }
            else
            {
              v33->bDrawSomeAnim = v30;
            }
            if ( v29 == 8 )
            {
              if ( v30 == 78 )
              {
                sub_4BD8B5();
                ptr_507BC0->Release();
                pParty->uFlags &= 0xFFFFFFFDu;
                if ( EnterHouse((enum HOUSE_TYPE)170) )
                {
                  pAudioPlayer->StopChannels(-1, -1);
                  ptr_507BC0 = GUIWindow::Create(0, 0, 640, 480, WINDOW_HouseInterior, 170, 0);
                  ptr_507BC0->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 1u, 0x31u, "", 0);
                  ptr_507BC0->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 2u, 0x32u, "", 0);
                  ptr_507BC0->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 3u, 0x33u, "", 0);
                  ptr_507BC0->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 4u, 0x34u, "", 0);
                  ptr_507BC0->CreateButton(0, 0, 0, 0, 1, 0, 0xB0u, 0, 9u, "", 0);
                  ptr_F8B1E8 = pNPCTopics[90].pText;
                }
              }
            }
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_NPCSetItem:
            sub_448518_npc_set_item(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8),
              _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8), _evt->v13);
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_SetActorItem:
            Actor::GiveItem(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8),
              _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8), _evt->v13);
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_SetNPCGroupNews:
            pNPCStats->pGroups_copy[_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8)] = _evt->v9 + ((uint)_evt->v10 << 8);
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_SetActorGroup:
            __debugbreak();
            *(&pActors[0].uGroup + 0x11000000 * _evt->v8 + 209 * (_evt->v5 + ((_evt->v6 + ((uint)_evt->v7 << 8)) << 8))) = _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8);
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_ChangeGroup:
            v38 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
            v39 = _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8);
            v40 = uNumActors;
            __debugbreak();
            if ( (signed int)uNumActors > 0 )
            {
              v41 = pActors;//[0].uGroup;
              do
              {
                if ( v41->uGroup == v38 )
                v41->uGroup = v39;
                ++v41;
                --v40;
              }
              while ( v40 );
            }
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_ChangeGroupAlly:
            v42 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
            v43 = _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8);
            v44 = uNumActors;
            __debugbreak();
            if ( (signed int)uNumActors > 0 )
            {
              v45 = pActors;//[0].uAlly;
              do
              {
                if ( v45->uGroup == v42 )
                v45->uAlly = v43;
                ++v45;
                --v44;
              }
              while ( v44 );
            }
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_MoveNPC:
            pNPCStats->pNewNPCData[_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8)].house = _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8);
            if ( ptr_507BC0 )
            {
              v46 = ptr_507BC0->ptr_1C;
              if ( v46 == (void *)165 )
              {
                sub_4BD8B5();
                pVideoPlayer->Unload();
                ptr_507BC0->Release();
                pParty->uFlags &= 0xFFFFFFFDu;
                _5C3420_pDecoration = (LevelDecoration *)1;
                if ( EnterHouse((enum HOUSE_TYPE)165) )
                {
                  pAudioPlayer->PlaySound((SoundID)0, 0, 0, -1, 0, 0, 0, 0);
                  v47 = GUIWindow::Create(0, 0, 640, 480, WINDOW_HouseInterior, 165, 0);
                  ptr_507BC0 = v47;
                  v48 = v47->pControlsHead;
                  if ( v48 )
                  {
                    do
                    {
                      v49 = v48->pNext;
                      pAllocator->FreeChunk(v48);
                      v48 = v49;
                    }
                    while ( v49 );
                    v47 = ptr_507BC0;
                  }
                  v47->pControlsHead = 0;
                  ptr_507BC0->pControlsTail = 0;
                  ptr_507BC0->uNumControls = 0;
                }
              }
              else
              {
                if ( v46 == (void *)553 )
                  pVideoPlayer->bLoopPlaying = 0;
              }
            }
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_Jmp:
            //v124 = -1;
            v122 = _evt->v5 - 1;
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_ShowFace:
            v50 = _evt->v5;
            if ( (unsigned __int8)v50 <= 3u )
            {
              v117 = 0;
              v113 = _evt->v6;
              v53 = (unsigned __int8)v50;
              v52 = &pParty->pPlayers[v53];
              v52->PlayEmotion((CHARACTER_EXPRESSION_ID)v113, v117);
              ++v122;
              //v4 = v124;
              //v5 = pSomeEVT;
              //v6 = v123;
              //v7 = "";
              break;
            }
            if ( v50 == 4 )
            {
              v117 = 0;
              v113 = _evt->v6;
              v52 = pPlayers[uActiveCharacter];
              v52->PlayEmotion((CHARACTER_EXPRESSION_ID)v113, v117);
              ++v122;
              //v4 = v124;
              //v5 = pSomeEVT;
              //v6 = v123;
              //v7 = "";
              break;
            }
            if ( v50 != 5 )
            {
              v117 = 0;
              v113 = _evt->v6;
              v53 = rand() % 4;
              v52 = &pParty->pPlayers[v53];
              v52->PlayEmotion((CHARACTER_EXPRESSION_ID)v113, v117);
              ++v122;
              //v4 = v124;
              //v5 = pSomeEVT;
              //v6 = v123;
              //v7 = "";
              break;
            }
            v51 = pParty->pPlayers;
            do
            {
              v51->PlayEmotion((CHARACTER_EXPRESSION_ID)_evt->v6, 0);
              ++v51;
            }
            while ( (signed int)v51 < (signed int)pParty->pHirelings );
//LABEL_291:
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_CharacterAnimation:
            v54 = _evt->v5;
            if ( (unsigned __int8)v54 <= 3u )
            {
              v118 = 0;
              v114 = _evt->v6;
              v57 = (unsigned __int8)v54;
              goto LABEL_119;
            }
            if ( v54 == 4 )
            {
              v118 = 0;
              v114 = _evt->v6;
              v56 = pPlayers[uActiveCharacter];
              goto LABEL_120;
            }
            if ( v54 != 5 )
            {
              v118 = 0;
              v114 = _evt->v6;
              v57 = rand() % 4;
LABEL_119:
              v56 = &pParty->pPlayers[v57];
LABEL_120:
              v56->PlaySound((PlayerSpeech)v114, v118);
              ++v122;
              //v4 = v124;
              //v5 = pSomeEVT;
              //v6 = v123;
              //v7 = "";
              break;
            }
            v55 = pParty->pPlayers;
            for (int iii = 0; iii < 4; ++iii)
            {
              v55->PlaySound((PlayerSpeech)_evt->v6, 0);
              ++v55;
            }
            //while ( (signed int)v55 < (signed int)pParty->pHirelings );
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_ForPartyMember:
            v127 = _evt->v5;
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_SummonItem:
            sub_42F7EB_DropItemAt(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8),
              _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8),
              _evt->v13 + ((_evt->v14 + ((_evt->v15 + ((uint)_evt->v16 << 8)) << 8)) << 8),
              _evt->v17 + ((_evt->v18 + ((_evt->v19 + ((uint)_evt->v20 << 8)) << 8)) << 8),
              _evt->v21 + ((_evt->v22 + ((_evt->v23 + ((uint)_evt->v24 << 8)) << 8)) << 8),
              _evt->v25, _evt->v26, 0, 0);
              ++v122;
              //v4 = v124;
              //v5 = pSomeEVT;
              //v6 = v123;
              //v7 = "";
              break;
          case EVENT_Compare:
            v58 = _evt->v7 + ((_evt->v8 + ((_evt->v9 + ((uint)_evt->v10 << 8)) << 8)) << 8);
            if ( v127 == 5 )
            {
              v130 = 0;
              v59 = pParty->pPlayers;
              while ( 1 )
              {
                LOBYTE(v60) = v59->CompareVariable((enum VariableType)(_evt->v5 + ((uint)_evt->v6 << 8)), v58);
                if ( v60 )
                  break;
                ++v130;
                ++v59;
                if ( (signed int)v59 >= (signed int)pParty->pHirelings )
                {
                  ++v122;
                  //v4 = v124;
                  //v5 = pSomeEVT;
                  //v6 = v123;
                  //v7 = "";
                  break;
                }
              }
LABEL_129:
              v11 = _evt->v11;
              goto LABEL_130;
            }
            if ( v127 < 0 )
              goto LABEL_139;
            v61 = v127;
            if ( v127 <= 3 )
              goto LABEL_137;
            if ( v127 == 4 )
            {
              if ( uActiveCharacter )
              {
                v6 = pPlayers[uActiveCharacter];
                goto LABEL_138;
              }
            }
            else
            {
              if ( v127 != 6 )
                goto LABEL_139;
            }
            v61 = rand() % 4;
            //v5 = pSomeEVT;
LABEL_137:
            v6 = &pParty->pPlayers[v61];
LABEL_138:
            //v123 = v6;
LABEL_139:
            LOBYTE(v62) = ((Player *)v6)->CompareVariable(
                            (enum VariableType)(_evt->v5 + ((uint)_evt->v6 << 8)),
                            v58);
LABEL_140:
            if ( v62 )
              goto LABEL_129;
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_IsActorAlive:
            v62 = IsActorAlive(
                    _evt->v5,
                    _evt->v6 + ((_evt->v7 + ((_evt->v8 + ((uint)_evt->v9 << 8)) << 8)) << 8),
                    _evt->v10);
            goto LABEL_140;
          case EVENT_Substract:
            v63 = (void *)(_evt->v7 + ((_evt->v8 + ((_evt->v9 + ((uint)_evt->v10 << 8)) << 8)) << 8));
            if ( _evt->v5 + ((uint)_evt->v6 << 8) == VAR_PlayerItemInHands )
            {
              v64 = 0;
              if ( (void *)pParty->pPickedItem.uItemID == v63 )
              {
                pMouse->RemoveHoldingItem();
                ++v122;
                //v4 = v124;
                //v5 = pSomeEVT;
                //v6 = v123;
                //v7 = "";
                break;
              }
              v65 = 0;
              v66 = pPlayers[uActiveCharacter];
              v67 = (int)v66->pInventoryIndices;
              do
              {
                if ( *(void **)&v66->spellbook.pDarkSpellbook.bIsSpellAvailable[36 * *(int *)v67 + 5] == v63 )
                {
                  v66->RemoveItemAtInventoryIndex(v65);
                  ++v122;
                  //v4 = v124;
                  //v5 = pSomeEVT;
                  //v6 = v123;
                  //v7 = "";
                  break;
                }
                ++v65;
                v67 += 4;
              }
              while ( (signed int)v65 < 126 );
              v68 = 0;
              v69 = (int)&v66->pEquipment;
              do
              {
                if ( *(int *)v69 && *(void **)&v66->spellbook.pDarkSpellbook.bIsSpellAvailable[36 * *(int *)v69 + 5] == v63 )
                {
                  *(&v66->pEquipment.uOffHand + v68) = 0;
                  ++v122;
                  //v4 = v124;
                  //v5 = pSomeEVT;
                  //v6 = v123;
                  //v7 = "";
                  break;
                }
                ++v68;
                v69 += 4;
              }
              while ( v68 < 16 );
              v125 = (signed int)&pPlayers[1];
              while ( 1 )
              {
                v70 = *(Player **)v125;
                if ( !v64 )
                {
                  v71 = 0;
                  v72 = (int)v70->pInventoryIndices;
                  do
                  {
                    if ( *(void **)&v70->spellbook.pDarkSpellbook.bIsSpellAvailable[36 * *(int *)v72 + 5] == v63 )
                    {
                      v70->RemoveItemAtInventoryIndex(v71);
                      goto LABEL_169;
                    }
                    ++v71;
                    v72 += 4;
                  }
                  while ( (signed int)v71 < 126 );
                  v73 = 0;
                  v74 = (int)&v70->pEquipment;
                  while ( !*(int *)v74
                       || *(void **)&v70->spellbook.pDarkSpellbook.bIsSpellAvailable[36 * *(int *)v74 + 5] != v63 )
                  {
                    ++v73;
                    v74 += 4;
                    if ( v73 >= 16 )
                      goto LABEL_170;
                  }
                  *(&v70->pEquipment.uOffHand + v73) = 0;
LABEL_169:
                  v64 = 1;
                }
LABEL_170:
                v125 += 4;
                if ( v125 > (signed int)&pPlayers[4] )
                {
                  ++v122;
                  //v4 = v124;
                  //v5 = pSomeEVT;
                  //v6 = v123;
                  //v7 = "";
                  break;
                }
              }
            }
            v75 = v127;
            if ( v127 != 5 )
            {
              if ( v127 < 0 )
                goto LABEL_183;
              if ( v127 > 3 )
              {
                if ( v127 != 4 )
                {
                  if ( v127 == 6 )
                    goto LABEL_180;
LABEL_183:
                  ((Player *)v6)->SubtractVariable((enum VariableType)(_evt->v5 + ((uint)_evt->v6 << 8)), v63);
                  ++v122;
                  //v4 = v124;
                  //v5 = pSomeEVT;
                  //v6 = v123;
                  //v7 = "";
                  break;
                }
                if ( uActiveCharacter )
                {
                  v6 = pPlayers[uActiveCharacter];
                  goto LABEL_182;
                }
LABEL_180:
                v75 = rand() % 4;
                //v5 = pSomeEVT;
              }
              v6 = &pParty->pPlayers[v75];
LABEL_182:
              //v123 = v6;
              goto LABEL_183;
            }
            v76 = pParty->pPlayers;
            v130 = 4;
            do
            {
              v76->SubtractVariable(
                (enum VariableType)(_evt->v5 + ((uint)_evt->v6 << 8)),
                v63);
              ++v76;
            }
            while ( (signed int)v76 < (signed int)pParty->pHirelings );
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_Set:
            v77 = _evt->v7 + ((_evt->v8 + ((_evt->v9 + ((uint)_evt->v10 << 8)) << 8)) << 8);
            v78 = v127;
            if ( v127 != 5 )
            {
              if ( v127 < 0 )
                goto LABEL_197;
              if ( v127 > 3 )
              {
                if ( v127 != 4 )
                {
                  if ( v127 == 6 )
                    goto LABEL_194;
LABEL_197:
                  ((Player *)v6)->SetVariable((enum VariableType)(_evt->v5 + ((uint)_evt->v6 << 8)), v77);
                  ++v122;
                  //v4 = v124;
                  //v5 = pSomeEVT;
                  //v6 = v123;
                  //v7 = "";
                  break;
                }
                if ( uActiveCharacter )
                {
                  v6 = pPlayers[uActiveCharacter];
                  goto LABEL_196;
                }
LABEL_194:
                v78 = rand() % 4;
                //v5 = pSomeEVT;
              }
              v6 = &pParty->pPlayers[v78];
LABEL_196:
              //v123 = v6;
              goto LABEL_197;
            }
            v79 = pParty->pPlayers;
            v130 = 4;
            do
            {
              v79->SetVariable(
                (enum VariableType)(_evt->v5 + ((uint)_evt->v6 << 8)),
                v77);
              ++v79;
            }
            while ( (signed int)v79 < (signed int)pParty->pHirelings );
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_Add:
            v80 = _evt->v7 + ((_evt->v8 + ((_evt->v9 + ((uint)_evt->v10 << 8)) << 8)) << 8);
            v81 = v127;
            if ( v127 != 5 )
            {
              if ( v127 < 0 )
                goto LABEL_211;
              if ( v127 > 3 )
              {
                if ( v127 != 4 )
                {
                  if ( v127 == 6 )
                    goto LABEL_208;
LABEL_211:
                  ((Player *)v6)->AddVariable(
                    (enum VariableType)(_evt->v5 + ((uint)_evt->v6 << 8)),
                    v80);
                  goto LABEL_212;
                }
                if ( uActiveCharacter )
                {
                  v6 = pPlayers[uActiveCharacter];
                  goto LABEL_210;
                }
LABEL_208:
                v81 = rand() % 4;
                //v5 = pSomeEVT;
              }
              v6 = &pParty->pPlayers[v81];
LABEL_210:
              //v123 = v6;
              goto LABEL_211;
            }
            v82 = pParty->pPlayers;
            v130 = 4;
            do
            {
              v82->AddVariable(
                (enum VariableType)(_evt->v5 + ((uint)_evt->v6 << 8)),
                v80);
              ++v82;
            }
            while ( (signed int)v82 < (signed int)pParty->pHirelings );
LABEL_212:
            v83 = _evt->v5 + ((uint)_evt->v6 << 8);
            if ( v83 == 21 || v83 == 22 || v83 == 23 || v83 == 24 )
              viewparams->bRedrawGameUI = 1;
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_InputString:
            if ( !dword_597F18 )
            {
              strcpy(
                GameUI_StatusBar_TimedString,
                &pLevelStr[pLevelStrOffsets[_evt->v5
                                          + ((_evt->v6
                                            + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8)]]);
              v105 = v122;
              v121 = 26;
LABEL_295:
              sub_4451A8_press_any_key(uEventID, v105, v121);
LABEL_301:
              if ( v133 == 1 )
LABEL_302:
                OnMapLeave();
              return;
            }
            v84 = _evt->v13 + ((_evt->v14 + ((_evt->v15 + ((uint)_evt->v16 << 8)) << 8)) << 8);
            if ( !_strcmpi(
                    GameUI_StatusBar_TimedString,
                    &pLevelStr[pLevelStrOffsets[_evt->v9
                                              + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8)]])
              || !_strcmpi(GameUI_StatusBar_TimedString, &pLevelStr[pLevelStrOffsets[v84]]) )
            {
              v11 = _evt->v17;
LABEL_130:
              //v124 = -1;
LABEL_131:
              v122 = v11 - 1;
            }
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_RandomGoTo:
            //v124 = -1;
            v11 = (unsigned __int8)*(&_evt->v5 + rand() % ((_evt->v5 != 0) + (_evt->v6 != 0) + (_evt->v7 != 0) + (_evt->v8 != 0) + (_evt->v9 != 0)
                                    + (_evt->v10 != 0)));
            goto LABEL_131;
          case EVENT_ReceiveDamage:
            v85 = _evt->v7 + ((_evt->v8 + ((_evt->v9 + ((uint)_evt->v10 << 8)) << 8)) << 8);
            v86 = _evt->v5;
            if ( (unsigned __int8)v86 <= 3u )
            {
              v119 = _evt->v6;
              v115 = _evt->v7 + ((_evt->v8 + ((_evt->v9 + ((uint)_evt->v10 << 8)) << 8)) << 8);
              v89 = (unsigned __int8)v86;
              goto LABEL_233;
            }
            if ( v86 == 4 )
            {
              if ( !uActiveCharacter )
              {
                ++v122;
                //v4 = v124;
                //v5 = pSomeEVT;
                //v6 = v123;
                //v7 = "";
                break;
              }
              v119 = _evt->v6;
              v88 = pPlayers[uActiveCharacter];
              v115 = _evt->v7 + ((_evt->v8 + ((_evt->v9 + ((uint)_evt->v10 << 8)) << 8)) << 8);
              goto LABEL_234;
            }
            if ( v86 != 5 )
            {
              v119 = _evt->v6;
              v115 = _evt->v7 + ((_evt->v8 + ((_evt->v9 + ((uint)_evt->v1 << 8)) << 8)) << 8);
              v89 = rand() % 4;
LABEL_233:
              v88 = &pParty->pPlayers[v89];
LABEL_234:
              v88->ReceiveDamage(v115, v119);
              ++v122;
              //v4 = v124;
              //v5 = pSomeEVT;
              //v6 = v123;
              //v7 = "";
              break;
            }
            v87 = pParty->pPlayers;
            do
            {
              v87->ReceiveDamage(v85, _evt->v6);
              ++v87;
            }
            while ( (signed int)v87 < (signed int)pParty->pHirelings );
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_ToggleIndoorLight:
            pIndoor->ToggleLight(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8), _evt->v9);
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_SetFacesBit:
            sub_44892E_set_faces_bit(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8),
              _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8), _evt->v13);
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_ToggleChestFlag:
            Chest::ToggleFlag(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8),
              _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8), _evt->v13);
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_ToggleActorFlag:
            Actor::ToggleFlag(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8),
              _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8), _evt->v13);
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_ToggleActorGroupFlag:
            ToggleActorGroupFlag(
              _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8),
              _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8),
              _evt->v13);
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_SetSnow:
            if ( !_evt->v5 )
              pWeather->bRenderSnow = _evt->v6 != 0;
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_StatusText:
            v90 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
            if ( _5C3420_pDecoration )
            {
              if ( _5C3420_pDecoration == (LevelDecoration *)1 )
              {
                ptr_F8B1E8 = pNPCTopics[v90-1].pText;//(&dword_721664)[8 * v90];
                ++v122;
                //v4 = v124;
                //v5 = pSomeEVT;
                //v6 = v123;
                //v7 = "";
                break;
              }
              if ( a3 == 1 )
              {
                v91 = pNPCTopics[v90-1].pText;//(&dword_721664)[8 * v90];
//LABEL_248:
                ShowStatusBarString(v91, 2u);
                ++v122;
                //v4 = v124;
                //v5 = pSomeEVT;
                //v6 = v123;
                //v7 = "";
                break;
              }
            }
            else
            {
              if ( a3 == 1 )
              {
                v91 = &pLevelStr[pLevelStrOffsets[v90]];
                ShowStatusBarString(v91, 2u);
                ++v122;
                //v4 = v124;
                //v5 = pSomeEVT;
                //v6 = v123;
                //v7 = "";
                break;
              }
            }
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_ShowMessage:
            v92 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
            if ( _5C3420_pDecoration )
            {
              v93 = (char *)pNPCTopics[v92-1].pText;//(&dword_721664)[8 * v92];
              byte_5B0938[0] = 0;
              ptr_F8B1E8 = v93;
            }
            else
            {
              strcpy(byte_5B0938, &pLevelStr[pLevelStrOffsets[v92]]);
            }
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_CastSpell:
            sub_448DF8_cast_spell(_evt->v5, _evt->v6, _evt->v7, _evt->v8 + ((_evt->v9 + ((_evt->v10 + ((uint)_evt->v11 << 8)) << 8)) << 8),
              _evt->v12 + ((_evt->v13 + ((_evt->v14 + ((uint)_evt->v15 << 8)) << 8)) << 8),
              _evt->v16 + ((_evt->v17 + ((_evt->v18 + ((uint)_evt->v19 << 8)) << 8)) << 8),
              _evt->v20 + ((_evt->v21 + ((_evt->v22 + ((uint)_evt->v23 << 8)) << 8)) << 8),
              _evt->v24 + ((_evt->v25 + ((_evt->v26 + ((uint)_evt->v27 << 8)) << 8)) << 8),
              _evt->v28 + ((_evt->v29 + ((_evt->v30 + ((uint)_evt->v31 << 8)) << 8)) << 8));
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_SetTexture:
            sub_44861E_set_texture(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8), (char *)&_evt->v9);
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_SetSprite:
            SetDecorationSprite(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8), _evt->v9, (char *)&_evt->v10);
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_SummonMonsters:
            sub_448CF4_spawn_monsters(_evt->v5, _evt->v6, _evt->v7,
              _evt->v8 + ((_evt->v9 + ((_evt->v10 + ((uint)_evt->v11 << 8)) << 8)) << 8),
              _evt->v12 + ((_evt->v13 + ((_evt->v14 + ((uint)_evt->v15 << 8)) << 8)) << 8),
              _evt->v16 + ((_evt->v17 + ((_evt->v18 + ((uint)_evt->v19 << 8)) << 8)) << 8),
              _evt->v20 + ((_evt->v21 + ((_evt->v22 + ((uint)_evt->v23 << 8)) << 8)) << 8),
              _evt->v24 + ((_evt->v25 + ((_evt->v26 + ((uint)_evt->v27 << 8)) << 8)) << 8));
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_MouseOver:
          case EVENT_LocationName:
            --v122;
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_ChangeDoorState:
            sub_449A49_door_switch_animation(_evt->v5, _evt->v6);
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_OpenChest:
            if ( !Chest::Open(_evt->v5) )
              goto LABEL_301;
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_MoveToMap:
            v94 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
            v135 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
            v132 = _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8);
            v126 = _evt->v13 + ((_evt->v14 + ((_evt->v15 + ((uint)_evt->v16 << 8)) << 8)) << 8);
            v129 = _evt->v17 + ((_evt->v18 + ((_evt->v19 + ((uint)_evt->v20 << 8)) << 8)) << 8);
            v95 = _evt->v21 + ((_evt->v22 + ((_evt->v23 + ((uint)_evt->v24 << 8)) << 8)) << 8);
            v96 = _evt->v25;
            v97 = v96 + ((_evt->v26 + ((_evt->v27 + ((uint)_evt->v28 << 8)) << 8)) << 8);
            v134 = v96 + ((_evt->v26 + ((_evt->v27 + ((uint)_evt->v28 << 8)) << 8)) << 8);
            if ( _evt->v29 || _evt->v30 )
            {
              if ( pRenderer->pRenderD3D && !pRenderer->bWindowMode )
                pRenderer->_49FD3A();
              sub_444839_move_map(_evt->v29, _evt->v30, v135, v132, v126, v129, v95, v134, (char *)&_evt->v31);
              dword_5C3418 = uEventID;
              dword_5C341C = v122 + 1;
              goto LABEL_301;
            }
            _5B65AC_npcdata_fame_or_other = _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8);
            _5B65A8_npcdata_uflags_or_other = v94;
            _5B65B0_npcdata_rep_or_other = v126;
            if ( v129 == -1 )
            {
              v98 = _5B65B4_npcdata_loword_house_or_other;
            }
            else
            {
              v98 = v129 & stru_5C6E00->uDoublePiMask;
              _5B65B4_npcdata_loword_house_or_other = v129 & stru_5C6E00->uDoublePiMask;
            }
            v99 = (char *)&_evt->v31;
            _5B65B8_npcdata_hiword_house_or_other = v95;
            dword_5B65BC = v97;
            v100 = v94 | v132 | v126 | v95 | v97 | v98;
            dword_5B65C0 = v100;
            if ( *v99 == 48 )
            {
              if ( v100 )
              {
                pParty->vPosition.x = v135;
                pParty->vPosition.y = v132;
                pParty->vPosition.z = v126;
                pParty->uFallStartY = v126;
                if ( _5B65B4_npcdata_loword_house_or_other != -1 )
                  pParty->sRotationY = _5B65B4_npcdata_loword_house_or_other;
                _5B65B4_npcdata_loword_house_or_other = -1;
                v120 = 0;
                v116 = 0;
                v111 = 0;
                v110 = 0;
                v109 = -1;
                v108 = 0;
                v107 = 0;
                pParty->sRotationX = v95;
                pParty->uFallSpeed = v134;
                dword_5B65C0 = 0;
                dword_5B65BC = 0;
                _5B65B8_npcdata_hiword_house_or_other = 0;
                _5B65B0_npcdata_rep_or_other = 0;
                _5B65AC_npcdata_fame_or_other = 0;
                _5B65A8_npcdata_uflags_or_other = 0;
                v106 = 232;
LABEL_280:
                pAudioPlayer->PlaySound((SoundID)v106, v107, v108, v109, v110, v111, v116, v120);
              }
            }
            else
            {
              pGameLoadingUI_ProgressBar->uType = (GUIProgressBar::Type)((_5C3420_pDecoration == 0) + 1);
              sub_44987B(v99, 0);
              v133 = 1;
              if ( pCurrentScreen == SCREEN_HOUSE )
              {
                if ( uGameState == 2 )
                {
                  pAudioPlayer->StopChannels(-1, -1);
                  dword_F8B19C = 0;
                  while ( sub_4BD8B5() )
                    ;
                  pVideoPlayer->Unload();
                  ptr_507BC0->Release();
                  ptr_507BC0 = 0;
                  if ( pMessageQueue_50CBD0->uNumMessages )
                    pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
                  pCurrentScreen = SCREEN_GAME;
                  viewparams->bRedrawGameUI = 1;
                  array_5913D8[6] = 0;
                  pDialogueWindow->Release();
                  dword_F8B19C = 0;
                  pDialogueWindow = 0;
                  pIcons_LOD->_40F9C5();
                }
                goto LABEL_302;
              }
            }
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_PlaySound:
            v120 = 0;
            v116 = 0;
            v111 = 0;
            v110 = _evt->v13 + ((_evt->v14 + ((_evt->v15 + ((uint)_evt->v16 << 8)) << 8)) << 8);
            v109 = _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8);
            v108 = 0;
            v107 = 0;
            v106 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
            goto LABEL_280;
          case EVENT_GiveItem:
            item.Reset();
            //v101 = &pSomeEVT[v9];
            v102 = _evt->v7
                 + ((_evt->v8 + ((_evt->v9 + ((uint)_evt->v10 << 8)) << 8)) << 8);
            pItemsTable->GenerateItem(_evt->v5, _evt->v6, &item);
            if ( v102 )
              item.uItemID = v102;
            pParty->SetHoldingItem(&item);
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_SpeakInHouse:
            v103 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
            if ( EnterHouse((enum HOUSE_TYPE)(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8))) )
            {
              if ( pRenderer->pRenderD3D && !pRenderer->bWindowMode )
                pRenderer->_49FD3A();
              pAudioPlayer->PlaySound((SoundID)0, 0, 0, -1, 0, 0, 0, 0);
              pAudioPlayer->PlaySound(SOUND_EnteringAHouse, 814, 0, -1, 0, 0, 0, 0);
              v104 = 187;
              if ( uCurrentHouse_Animation != 167 )
                v104 = v103;
              ptr_507BC0 = GUIWindow::Create(0, 0, 640, 480, WINDOW_HouseInterior, v104, 0);
              ptr_507BC0->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 1u, 0x31u, "", 0);
              ptr_507BC0->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 2u, 0x32u, "", 0);
              ptr_507BC0->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 3u, 0x33u, "", 0);
              ptr_507BC0->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 4u, 0x34u, "", 0);
              ptr_507BC0->CreateButton(0, 0, 0, 0, 1, 0, 0xB0u, 0, 9u, "", 0);
            }
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
          case EVENT_PressAnyKey:
            v121 = 33;
            v105 = v122 + 1;
            goto LABEL_295;
          case EVENT_Exit:
            goto LABEL_301;
          default:
            ++v122;
            //v4 = v124;
            //v5 = pSomeEVT;
            //v6 = v123;
            //v7 = "";
            break;
        }
      }
      //++v4;
      //v124 = v4;
      //if ( v4 >= (signed int)uSomeEVT_NumEvents )
        //goto LABEL_301;
    //}
  }
}



//----- (0044861E) --------------------------------------------------------
void __fastcall sub_44861E_set_texture(unsigned int uFaceCog, const char *pFilename)
{
  unsigned int v2; // eax@2
  unsigned __int16 v3; // di@2
  signed int v4; // esi@5
  BLVFace *v5; // eax@7
  unsigned int *v6; // eax@8
  char *v7; // eax@9
  int v8; // edi@16
  char *v9; // esi@16
  ODMFace *v10; // eax@17
  unsigned int *v11; // eax@19
  unsigned __int16 v12; // [sp+Ch] [bp-18h]@2
  const char *Str2; // [sp+10h] [bp-14h]@1
  unsigned int v14; // [sp+14h] [bp-10h]@1
  signed int v15; // [sp+18h] [bp-Ch]@14
  int v16; // [sp+1Ch] [bp-8h]@15
  signed int v17; // [sp+20h] [bp-4h]@4
  signed int v18; // [sp+20h] [bp-4h]@16

  Str2 = pFilename;
  v14 = uFaceCog;
  if ( uFaceCog )
  {
    v2 = pBitmaps_LOD->LoadTexture(pFilename);
    v3 = v2;
    v12 = v2;
    if ( v2 != -1 ? (int)&pBitmaps_LOD->pTextures[v2] : 0 )
    {
      pBitmaps_LOD->pTextures[v2].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[v2].palette_id1);

      if ( uCurrentlyLoadedLevelType == 1 )
      {
        v17 = 1;
        if ( (signed int)pIndoor->uNumFaceExtras > 1 )
        {
          v4 = 1;
          do
          {
            if ( pIndoor->pFaceExtras[v4].sCogNumber == v14 )
            {
              v5 = &pIndoor->pFaces[pIndoor->pFaceExtras[v4].field_C];
              if ( BYTE1(v5->uAttributes) & 0x40 )
              {
                pIndoor->pFaces[pIndoor->pFaceExtras[v4].field_C].uBitmapID = pTextureFrameTable->FindTextureByName(
                                                                              Str2);
                v6 = (unsigned int *)&pIndoor->pFaces[pIndoor->pFaceExtras[v4].field_C].uBitmapID;
                if ( *(_WORD *)v6 )
                {
                  pTextureFrameTable->LoadAnimationSequenceAndPalettes(*(_WORD *)v6);
                }
                else
                {
                  *(_WORD *)v6 = v3;
                  v7 = (char *)&pIndoor->pFaces[pIndoor->pFaceExtras[v4].field_C].uAttributes;
                  v7[1] &= 0xBFu;
                }
              }
              else
              {
                v5->uBitmapID = v3;
              }
            }
            ++v17;
            ++v4;
          }
          while ( v17 < (signed int)pIndoor->uNumFaceExtras );
        }
        pParty->uFlags |= 2u;
      }
      else
      {
        v15 = 0;
        if ( (signed int)pOutdoor->uNumBModels > 0 )
        {
          v16 = 0;
          do
          {
            v8 = 0;
            v9 = (char *)&pOutdoor->pBModels[v16].pVertices;
            v18 = 0;
            if ( (signed int)pOutdoor->pBModels[v16].uNumFaces > 0 )
            {
              do
              {
                v10 = (ODMFace *)(v8 + *((_DWORD *)v9 + 4));
                if ( v10->sCogNumber == v14 )
                {
                  if ( BYTE1(v10->uAttributes) & 0x40 )
                  {
                    *(_WORD *)(*((_DWORD *)v9 + 4) + v8 + 272) = pTextureFrameTable->FindTextureByName(
                                                                   Str2);
                    v11 = (unsigned int *)(*((_DWORD *)v9 + 4) + v8 + 272);
                    if ( *(_WORD *)v11 )
                    {
                      pTextureFrameTable->LoadAnimationSequenceAndPalettes(*(_WORD *)v11);
                    }
                    else
                    {
                      *(_WORD *)v11 = v12;
                      *(_BYTE *)(*((_DWORD *)v9 + 4) + v8 + 29) &= 0xBFu;
                    }
                  }
                  else
                  {
                    v10->uTextureID = v12;
                  }
                }
                ++v18;
                v8 += 308;
              }
              while ( v18 < *((_DWORD *)v9 + 2) );
            }
            ++v15;
            ++v16;
          }
          while ( v15 < (signed int)pOutdoor->uNumBModels );
        }
      }
      pParty->uFlags |= 2u;
    }
  }
}




//----- (0044882F) --------------------------------------------------------
void __fastcall SetDecorationSprite(unsigned int uCog, int a2, const char *pFileName)
{
  signed int v3; // ebp@1
  char *v4; // esi@2
  unsigned __int16 v5; // ax@6
  unsigned int v6; // [sp+4h] [bp-8h]@1
  int v7; // [sp+8h] [bp-4h]@1

  v3 = 0;
  v7 = a2;
  v6 = uCog;
  if ( (signed int)uNumLevelDecorations > 0 )
  {
    v4 = (char *)&pLevelDecorations[0].field_2;
    do
    {
      if ( *((_WORD *)v4 + 9) == v6 )
      {
        if ( pFileName && _strcmpi(pFileName, "0") )
        {
          v5 = pDecorationList->GetDecorIdByName(pFileName);
          *((_WORD *)v4 - 1) = v5;
          pDecorationList->InitializeDecorationSprite((signed __int16)v5);
        }
        if ( v7 )
          *v4 &= 0xDFu;
        else
          *v4 |= 0x20u;
        pParty->uFlags |= 2u;
      }
      ++v3;
      v4 += 32;
    }
    while ( v3 < (signed int)uNumLevelDecorations );
  }
}


//----- (004488B6) --------------------------------------------------------
unsigned __int16 DecorationList::GetDecorIdByName(const char *pName)
{
  DecorationList *v2; // esi@1
  signed int uID; // edi@2
  signed int v4; // ebx@3
  unsigned __int16 result; // ax@6

  v2 = this;
  if ( pName && (uID = 1, (signed int)this->uNumDecorations > 1) )
  {
    v4 = 1;
    while ( _strcmpi(pName, v2->pDecorations[v4].pName) )
    {
      ++uID;
      ++v4;
      if ( uID >= (signed int)v2->uNumDecorations )
        goto LABEL_6;
    }
    result = uID;
  }
  else
  {
LABEL_6:
    result = 0;
  }
  return result;
}


//----- (0044892E) --------------------------------------------------------
void __fastcall sub_44892E_set_faces_bit(int sCogNumber, int bit, int on)
{
  signed int v3; // esi@2
  signed int v4; // ecx@4
  char *v5; // eax@6
  int v6; // edi@13
  char *v7; // esi@13
  signed int v8; // ecx@13
  ODMFace *v9; // eax@14
  int v10; // [sp+0h] [bp-Ch]@1
  signed int v11; // [sp+4h] [bp-8h]@11
  int v12; // [sp+8h] [bp-4h]@12

  v10 = sCogNumber;
  if ( sCogNumber )
  {
    v3 = 1;
    if ( uCurrentlyLoadedLevelType == 1 )
    {
      if ( (signed int)pIndoor->uNumFaceExtras > 1 )
      {
        v4 = 1;
        do
        {
          if ( pIndoor->pFaceExtras[v4].sCogNumber == v10 )
          {
            v5 = (char *)&pIndoor->pFaces[pIndoor->pFaceExtras[v4].field_C].uAttributes;
            if ( on )
              *(_DWORD *)v5 |= bit;
            else
              *(_DWORD *)v5 &= ~bit;
          }
          ++v3;
          ++v4;
        }
        while ( v3 < (signed int)pIndoor->uNumFaceExtras );
      }
      pParty->uFlags |= 2u;
    }
    else
    {
      v11 = 0;
      if ( (signed int)pOutdoor->uNumBModels > 0 )
      {
        v12 = 0;
        do
        {
          v6 = 0;
          v7 = (char *)&pOutdoor->pBModels[v12].pVertices;
          v8 = 0;
          if ( (signed int)pOutdoor->pBModels[v12].uNumFaces > 0 )
          {
            do
            {
              v9 = (ODMFace *)(v6 + *((_DWORD *)v7 + 4));
              if ( v9->sCogNumber == v10 )
              {
                if ( on )
                  v9->uAttributes |= bit;
                else
                  v9->uAttributes &= ~bit;
              }
              ++v8;
              v6 += 308;
            }
            while ( v8 < *((_DWORD *)v7 + 2) );
          }
          ++v11;
          ++v12;
        }
        while ( v11 < (signed int)pOutdoor->uNumBModels );
      }
    }
    pParty->uFlags |= 2u;
  }
}


//----- (00448A17) --------------------------------------------------------
void Chest::ToggleFlag(unsigned int uChestID, unsigned __int16 uFlag, unsigned int bToggle)
{
  unsigned __int16 *pFlags; // eax@3

  if ( (uChestID & 0x80000000u) == 0 && (signed int)uChestID <= 19 )
  {
    pFlags = &pChests[uChestID].uFlags;
    if ( bToggle )
      *pFlags |= uFlag;
    else
      *pFlags &= ~uFlag;
  }
}

//----- (00448A40) --------------------------------------------------------
void Actor::ToggleFlag(signed int uActorID, unsigned int uFlag, int bToggle)
{
  if ( uActorID >= 0 && uActorID <= (signed int)(uNumActors - 1) )
  {
    if ( bToggle )
    {
      pActors[uActorID].uAttributes |= uFlag;
    }
    else
    {
      if ( uFlag == 0x10000 )
      {
        if (pActors[uActorID].uAIState == Disabled )
          pActors[uActorID].uAIState = Standing;
      }
      pActors[uActorID].uAttributes &= ~uFlag;
    }
  }
}

//----- (00448A98) --------------------------------------------------------
void __fastcall ToggleActorGroupFlag(unsigned int uGroupID, unsigned int uFlag, unsigned int bToggle)
{
  unsigned int v3; // ebx@1
  unsigned int v4; // ebp@1
  signed int v5; // edi@1
  Actor *v6; // esi@4
  size_t v7; // ecx@10
  Actor *v8; // eax@11
  unsigned __int16 v9; // dx@14

  v4 = uGroupID;
  v5 = Standing;
  v3 = uFlag;
  if ( uGroupID )
  {
    if ( bToggle )
    {
      if ( (signed int)uNumActors > Standing )
      {
        v6 = pActors;//[0].uAttributes;
        do
        {
          if ( v6->uGroup == v4 )
          {
            v6->uAttributes |= v3;
            if ( v3 == 0x10000 )
            {
              v6->uAIState = Disabled;
              v6->UpdateAnimation();
            }
          }
          ++v5;
          ++v6;
        }
        while ( v5 < (signed int)uNumActors );
      }
    }
    else
    {
      v7 = uNumActors;
      if ( (signed int)uNumActors > Standing )
      {
        v8 = pActors;//[0].uAIState;
        do
        {
          if ( v8->uGroup == v4 )
          {
            if ( v3 == 0x10000 )
            {
              v9 = v8->uAIState;
              if ( v8->uAIState != Dead )
              {
                if ( v9 != 4 && v9 != 11 )
                  v8->uAIState = Standing;
              }
            }
			LODWORD(v8->uAttributes) &= ~v3;
          }
          ++v8;
          --v7;
        }
        while ( v7 );
      }
    }
  }
}


//----- (00448B45) --------------------------------------------------------
void __thiscall GameUI_StatusBar_UpdateTimedString(unsigned int bForceHide)
{
  if ( bForceHide || GameUI_StatusBar_TimedStringTimeLeft && GetTickCount() >= GameUI_StatusBar_TimedStringTimeLeft )
    GameUI_StatusBar_TimedStringTimeLeft = 0;
}

//----- (00448B67) --------------------------------------------------------
void __thiscall OnTimer(int a1)
{
  int v1; // ebp@1
  unsigned int v2; // ebx@4
  unsigned int v3; // edi@4
  char *v4; // esi@6
  __int16 v5; // ax@8
  int v6; // ecx@10
  unsigned int v7; // ebp@12
  int v8; // eax@16
  int v9; // eax@19
  unsigned __int64 v10; // qax@20
  int v11; // ecx@24
  int v12; // [sp+Ch] [bp-10h]@5
  unsigned int v13; // [sp+10h] [bp-Ch]@4

  v1 = 0;
  if ( !pEventTimer->bPaused )
  {
    if ( a1 )
      dword_5773C0 = 0;
    v3 = HIDWORD(pParty->uTimePlayed);
    v2 = LODWORD(pParty->uTimePlayed);
    v13 = (signed __int64)(pParty->uTimePlayed - _5773B8_event_timer) / 128;
    if ( v13 )
    {
      _5773B8_event_timer = pParty->uTimePlayed;
      v12 = 0;
      if ( dword_5B65C8 > 0 )
      {
        v4 = (char *)&array_5B5928[0].field_C;
        while ( 1 )
        {
          v5 = *(short *)v4;
          if ( *(short *)v4 != (short)v1 )
            break;
          v7 = *((int *)v4 - 2);
          if ( v7 <= v3 && (v7 < v3 || *((int *)v4 - 3) <= v2) )
          {
            if ( *((short *)v4 + 2) )
            {
              v8 = 29030400;
            }
            else
            {
              if ( *((short *)v4 + 3) )
              {
                v8 = 2419200;
              }
              else
              {
                v9 = -(*((short *)v4 + 4) != 0);
                v8 = (v9 & 0x7E900) + 86400;
              }
            }
            v10 = v7 + *((int *)v4 - 3) + (signed __int64)((double)((signed __int64)v8 << 7) * 0.033333335);//v10 = __PAIR__(v7, *((int *)v4 - 3)) + (signed __int64)((double)((signed __int64)v8 << 7) * 0.033333335);
            *((int *)v4 - 3) = v10;
            *((int *)v4 - 2) = HIDWORD(v10);
            if ( HIDWORD(v10) <= v3 && (HIDWORD(v10) < v3 || *((int *)v4 - 3) < v2) )
            {
              *((int *)v4 - 3) = v2;
              *((int *)v4 - 2) = v3;
            }
            v11 = *((short *)v4 - 2);
            dword_597F18 = *((short *)v4 - 1);
            EventProcessor(v11, 0, 1);
            dword_597F18 = 0;
LABEL_25:
            v3 = HIDWORD(pParty->uTimePlayed);
            v2 = LODWORD(pParty->uTimePlayed);
          }
LABEL_26:
          ++v12;
          v4 += 32;
          if ( v12 >= dword_5B65C8 )
            return;
          v1 = 0;
        }
        if ( v13 < v5 )
        {
          *(short *)v4 = v5 - v13;
          goto LABEL_26;
        }
        v6 = *((short *)v4 - 2);
        *(short *)v4 = *((short *)v4 + 1);
        dword_597F18 = *((short *)v4 - 1);
        EventProcessor(v6, 0, 1);
        dword_597F18 = v1;
        goto LABEL_25;
      }
    }
  }
}

//----- (00481D77) --------------------------------------------------------
void _outdoor_project(RenderVertexSoft *v)
{
  double v1; // st7@1
  double v2; // st7@1

  v1 = 1.0 / (v->vWorldViewPosition.x + 0.0000001);
  v->_rhw = v1;
  v2 = v1 * (double)pOutdoorCamera->int_fov_rad;
  v->vWorldViewProjX = (double)pViewport->uScreenCenterX - v2 * v->vWorldViewPosition.y;
  v->vWorldViewProjY = (double)pViewport->uScreenCenterY - v2 * v->vWorldViewPosition.z;
}


//----- (00448CF4) --------------------------------------------------------
void __fastcall sub_448CF4_spawn_monsters(__int16 typeindex, __int16 level, int count, int x, int y, int z, int group, unsigned int uUniqueName)
{
  __int16 v8; // di@1
  __int16 v9; // si@1
  unsigned int v10; // eax@1
  size_t v11; // ebx@2
  signed int v12; // esi@2
  Actor *pActor;//Actor_uYawAngle_cr *v13; // ebx@3
  AIDirection a3; // [sp+Ch] [bp-50h]@2
  AIDirection v15; // [sp+28h] [bp-34h]@2
  //SpawnPointMM7 v16; // [sp+44h] [bp-18h]@1

  v8 = typeindex;
  v9 = level;

  SpawnPointMM7 v16; // [sp+44h] [bp-18h]@1
  //SpawnPointMM7::SpawnPointMM7(&v16);

  v16.vPosition.x = x;
  v16.vPosition.y = y;
  v16.vPosition.z = z;
  v16.uGroup = group;
  v16.uRadius = 32;
  v16.uKind = 3;
  v16.uIndex = v8 + 2 * v9 + v9;
  v10 = pMapStats->GetMapInfo(pCurrentMapName);
  if ( v10 )
  {
    v11 = uNumActors;
    SpawnEncounter((MapInfo *)&pMapStats->pInfos[v10], &v16, 0, count, 0);
    memcpy(&v15, Actor::GetDirectionInfo(8 * v11 | AI_OBJECT_ACTOR, 4u, &a3, 1), sizeof(v15));
    v12 = v11;
    if ( (signed int)v11 < (signed int)uNumActors )
    {
      for ( pActor = &pActors[v11]; v12 < (signed int)uNumActors; ++pActor )
      {
        pActor->PrepareSprites(0);
        ++v12;
        pActor->uYawAngle = v15.uYawAngle;
        pActor->dword_000334_unique_name = uUniqueName;
      }
    }
  }
}


//----- (00448DF8) --------------------------------------------------------
void __fastcall sub_448DF8_cast_spell(int spellnum, int rank, int level, int fromx, int fromy, int fromz, int tox, int toy, int toz)
{
  int v9; // esi@1
  double v10; // st7@4
  double v11; // st6@4
  double v12; // st5@4
  double v13; // st7@6
  int v14; // ST44_4@7
  signed int v15; // ebx@9
  signed int v16; // edx@15
  char *v17; // ecx@16
  unsigned __int16 v18; // ax@20
  char *v19; // ecx@31
  int v20; // edx@35
  signed int v21; // edx@37
  char *v22; // ecx@38
  unsigned __int16 v23; // ax@41
  int i; // esi@42
  signed int v25; // edx@55
  char *v26; // ecx@56
  unsigned __int16 v27; // ax@59
  int j; // esi@60
  signed int v29; // edx@66
  char *v30; // ecx@67
  unsigned __int16 v31; // ax@70
  Player *v32; // eax@80
  unsigned __int16 v33; // si@85
  int v34; // eax@96
  int v35; // eax@97
  unsigned __int64 v36; // qax@99
  SpellBuff *v37; // ecx@99
  int v38; // esi@103
  signed __int64 v39; // qax@105
  int v40; // ebx@108
  int v41; // ebx@109
  int v42; // esi@111
  int v43; // ebx@111
  int v44; // eax@117
  unsigned __int16 v45; // si@137
  unsigned __int16 v46; // [sp-8h] [bp-BCh]@99
  int v47; // [sp-4h] [bp-B8h]@35
  unsigned __int16 v48; // [sp-4h] [bp-B8h]@99
  int v49; // [sp+0h] [bp-B4h]@35
  int v50; // [sp+0h] [bp-B4h]@99
  int v51; // [sp+4h] [bp-B0h]@35
  unsigned __int8 v52; // [sp+4h] [bp-B0h]@99
  float v53; // [sp+14h] [bp-A0h]@4
  float v54; // [sp+18h] [bp-9Ch]@4
  int v55; // [sp+28h] [bp-8Ch]@7
  unsigned int yaw; // [sp+30h] [bp-84h]@7
  int pitch; // [sp+34h] [bp-80h]@7
  //LayingItem a1; // [sp+38h] [bp-7Ch]@12
  int v59; // [sp+A8h] [bp-Ch]@1
  int v60; // [sp+ACh] [bp-8h]@1
  int spellnum_; // [sp+B0h] [bp-4h]@1
  signed int levela; // [sp+BCh] [bp+8h]@80
  int a6_4; // [sp+C8h] [bp+14h]@117
  float a7a; // [sp+CCh] [bp+18h]@6
  signed int a7b; // [sp+CCh] [bp+18h]@12
  int a7c; // [sp+CCh] [bp+18h]@29
  int a7d; // [sp+CCh] [bp+18h]@55
  float a8a; // [sp+D0h] [bp+1Ch]@6
  int a8b; // [sp+D0h] [bp+1Ch]@37
  int a8c; // [sp+D0h] [bp+1Ch]@55
  float toza; // [sp+D4h] [bp+20h]@6

  v9 = 0;
  v59 = rank + 1;
  spellnum_ = spellnum;
  v60 = 0;
  if ( tox || toy || toz )
  {
    v10 = (double)tox - (double)fromx;
    v53 = v10;
    v11 = (double)toy - (double)fromy;
    v54 = v11;
    v12 = (double)toz;
  }
  else
  {
    v10 = (double)pParty->vPosition.x - (double)fromx;
    v53 = v10;
    v11 = (double)pParty->vPosition.y - (double)fromy;
    v54 = v11;
    v12 = (double)(pParty->vPosition.z + pParty->sEyelevel);
  }
  a7a = v12 - (double)fromz;
  toza = v11 * v11;
  a8a = v10 * v10;
  v13 = sqrt(a7a * a7a + a8a + toza);
  if ( v13 <= 1.0 )
  {
    LOBYTE(v55) = 1;
    yaw = 0;
    pitch = 0;
  }
  else
  {
    v55 = (signed __int64)v13;
    v14 = (signed __int64)sqrt(a8a + toza);
    yaw = stru_5C6E00->Atan2((signed __int64)v53, (signed __int64)v54);
    pitch = stru_5C6E00->Atan2(v14, (signed __int64)a7a);
  }
  v15 = v59;
  if ( v59 <= 0 || v59 > 4 )
    v15 = 1;
  a7b = v15;

  LayingItem a1; // [sp+38h] [bp-7Ch]@12
  //LayingItem::LayingItem(&a1);

  a1.uItemType = stru_4E3ACC[spellnum_].uItemType;
  if ( spellnum_ > 58 )
  {
    if ( spellnum_ == 69 )
      goto LABEL_117;
    if ( spellnum_ != 83 )
      return;
    v40 = v15 - 2;
    if ( v40 )
    {
      v41 = v40 - 1;
      if ( !v41 )
      {
        v42 = 14400 * level;
        v43 = 4 * level + 10;
        goto LABEL_114;
      }
      if ( v41 == 1 )
      {
        v42 = 18000 * level;
        v43 = 5 * level + 10;
        goto LABEL_114;
      }
    }
    v42 = 10800 * level;
    v43 = 3 * level + 10;
LABEL_114:
    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 0);
    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 1u);
    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 2u);
    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 3u);
    v52 = 0;
    v50 = 0;
    v48 = v43;
    v46 = a7b;
    v39 = (signed __int64)((double)(v42 << 7) * 0.033333335);
    v37 = &pParty->pPartyBuffs[2];
LABEL_115:
    v36 = pParty->uTimePlayed + v39;
LABEL_116:
    v37->Apply(v36, v46, v48, v50, v52);
    goto LABEL_139;
  }
  if ( spellnum_ != 58 )
  {
    switch ( spellnum_ )
    {
      case 2:
      case 6:
      case 18:
      case 26:
      case 29:
      case 32:
      case 39:
      case 41:
        a1.stru_24.Reset();
        v16 = 0;
        a1.field_48 = spellnum_;
        a1.field_4C = level;
        a1.field_50 = v15;
        if ( (signed int)pObjectList->uNumObjects <= 0 )
          goto LABEL_34;
        v17 = (char *)&pObjectList->pObjects->uObjectID;
        while ( (short)a1.uItemType != *(short *)v17 )
        {
          ++v16;
          v17 += 56;
          if ( v16 >= (signed int)pObjectList->uNumObjects )
            goto LABEL_34;
        }
LABEL_20:
        v18 = v16;
        goto LABEL_35;
      case 24:
        switch ( v15 )
        {
          case 1:
            v60 = 1;
            break;
          case 2:
            v60 = 3;
            break;
          case 3:
            v60 = 5;
            break;
          case 4:
            v60 = 7;
            break;
        }
        a7c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
        if ( v60 != 1 )
        {
          a8b = a7c / (v60 - 1);
          a1.stru_24.Reset();
          v21 = 0;
          a1.field_48 = spellnum_;
          a1.field_4C = level;
          a1.field_50 = v15;
          if ( (signed int)pObjectList->uNumObjects <= 0 )
          {
LABEL_41:
            v23 = 0;
          }
          else
          {
            v22 = (char *)&pObjectList->pObjects->uObjectID;
            while ( (short)a1.uItemType != *(short *)v22 )
            {
              ++v21;
              v22 += 56;
              if ( v21 >= (signed int)pObjectList->uNumObjects )
                goto LABEL_41;
            }
            v23 = v21;
          }
          a1.uObjectDescID = v23;
          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
          a1.vPosition.x = fromx;
          a1.uAttributes = 16;
          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
          a1.field_60_distance_related_prolly_lod = v55;
          a1.uSpriteFrameID = 0;
          a1.field_58 = 8002;
          a1.field_5C = 4;
          a1.uSoundID = 0;
          for ( i = a7c / -2; i <= a7c / 2; i += a8b )
          {
            a1.uFacing = i + yaw;
            a1.Create(
              (signed __int16)(i + (short)yaw),
              pitch,
              pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
              0);
          }
          goto LABEL_139;
        }
        a1.stru_24.Reset();
        v16 = 0;
        a1.field_48 = spellnum_;
        a1.field_4C = level;
        a1.field_50 = v15;
        if ( (signed int)pObjectList->uNumObjects <= 0 )
          goto LABEL_34;
        v19 = (char *)&pObjectList->pObjects->uObjectID;
        do
        {
          if ( (short)a1.uItemType == *(short *)v19 )
            goto LABEL_20;
          ++v16;
          v19 += 56;
        }
        while ( v16 < (signed int)pObjectList->uNumObjects );
LABEL_34:
        v18 = 0;
LABEL_35:
        a1.uObjectDescID = v18;
        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
        a1.vPosition.x = fromx;
        a1.uAttributes = 16;
        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
        a1.field_60_distance_related_prolly_lod = v55;
        v20 = yaw;
        a1.uSpriteFrameID = 0;
        a1.field_58 = 8002;
        a1.field_5C = 0;
        a1.uFacing = yaw;
        a1.uSoundID = 0;
        v51 = 0;
        v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
        v47 = pitch;
        goto LABEL_36;
      case 15:
        switch ( v15 )
        {
          case 1:
            v60 = 3;
            break;
          case 2:
            v60 = 5;
            break;
          case 3:
            v60 = 7;
            break;
          case 4:
            v60 = 9;
            break;
        }
        a7d = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
        a8c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v60 - 1);
        a1.stru_24.Reset();
        v25 = 0;
        a1.field_48 = spellnum_;
        a1.field_4C = level;
        a1.field_50 = v15;
        if ( (signed int)pObjectList->uNumObjects <= 0 )
          goto LABEL_59;
        v26 = (char *)&pObjectList->pObjects->uObjectID;
        while ( (short)a1.uItemType != *(short *)v26 )
        {
          ++v25;
          v26 += 56;
          if ( v25 >= (signed int)pObjectList->uNumObjects )
          {
LABEL_59:
            v27 = 0;
            goto LABEL_60;
          }
        }
        v27 = v25;
LABEL_60:
        a1.uObjectDescID = v27;
        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
        a1.vPosition.x = fromx;
        a1.uAttributes = 16;
        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
        a1.field_60_distance_related_prolly_lod = v55;
        a1.uSpriteFrameID = 0;
        a1.field_58 = 8002;
        a1.field_5C = 4;
        a1.uSoundID = 0;
        for ( j = a7d / -2; j <= a7d / 2; j += a8c )
        {
          a1.uFacing = j + yaw;
          a1.Create(
            (signed __int16)(j + (short)yaw),
            pitch,
            pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
            0);
        }
        goto LABEL_139;
      case 43:
        if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
          return;
        a1.stru_24.Reset();
        v29 = 0;
        a1.field_48 = spellnum_;
        a1.field_4C = level;
        a1.field_50 = v15;
        if ( (signed int)pObjectList->uNumObjects <= 0 )
          goto LABEL_70;
        v30 = (char *)&pObjectList->pObjects->uObjectID;
        break;
      case 5:
        if ( v15 > 0 )
        {
          if ( v15 <= 2 )
          {
            v9 = 60 * (level + 60);
          }
          else
          {
            if ( v15 == 3 )
            {
              v9 = 180 * (level + 20);
            }
            else
            {
              if ( v15 == 4 )
                v9 = 240 * (level + 15);
            }
          }
        }
        levela = 1;
        v32 = pParty->pPlayers;//[0].pConditions[1];
        do
        {
		  if ( v32->pConditions[1] )
            levela = 0;
          ++v32;
        }
		while ( v32 <= &pParty->pPlayers[3] );
        if ( !levela )
          return;
        pParty->pPartyBuffs[8].Apply(
          pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 << 7) * 0.033333335),
          v15,
          0,
          0,
          0);
        v33 = spellnum_;
        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum_, 0);
        pGame->pStru6Instance->SetPlayerBuffAnim(v33, 1u);
        pGame->pStru6Instance->SetPlayerBuffAnim(v33, 2u);
        pGame->pStru6Instance->SetPlayerBuffAnim(v33, 3u);
        goto LABEL_138;
      case 17:
      case 38:
      case 51:
        switch ( v15 )
        {
          case 1:
          case 2:
            v9 = 300 * (level + 12);
            break;
          case 3:
            v9 = 900 * (level + 4);
            break;
          case 4:
            v9 = 3600 * (level + 1);
            break;
        }
        switch ( spellnum_ )
        {
          case 17:
            v60 = 0;
            level = 14;
            break;
          case 38:
            v35 = level + 5;
            level = 15;
            v60 = v35;
            break;
          case 51:
            v34 = level + 5;
            level = 9;
            v60 = v34;
            break;
        }
        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum_, 0);
        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum_, 1u);
        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum_, 2u);
        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum_, 3u);
        v52 = 0;
        v50 = 0;
        v48 = v60;
        v46 = v15;
        v36 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 << 7) * 0.033333335);
        v37 = &pParty->pPartyBuffs[level];
        goto LABEL_116;
      case 8:
        if ( v15 == 2 || v15 == 3 || v15 != 4 )
          v38 = 60 * level;
        else
          v38 = 600 * level;
        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum_, 0);
        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum_, 1u);
        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum_, 2u);
        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum_, 3u);
        v52 = 0;
        v50 = 0;
        v48 = level;
        v46 = v15;
        v39 = (signed __int64)((double)(v38 << 7) * 0.033333335);
        v37 = &pParty->pPartyBuffs[10];
        goto LABEL_115;
      case 3:
      case 14:
      case 25:
      case 36:
        goto LABEL_117;
      default:
        return;
    }
    while ( (short)a1.uItemType != *(short *)v30 )
    {
      ++v29;
      v30 += 56;
      if ( v29 >= (signed int)pObjectList->uNumObjects )
      {
LABEL_70:
        v31 = 0;
        goto LABEL_71;
      }
    }
    v31 = v29;
LABEL_71:
    a1.uObjectDescID = v31;
    *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
    a1.vPosition.x = fromx;
    a1.uAttributes = 16;
    a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
    a1.field_60_distance_related_prolly_lod = v55;
    a1.uSpriteFrameID = 0;
    a1.field_58 = 8002;
    a1.field_5C = 4;
    a1.uSoundID = 0;
    v51 = 0;
    v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
    v20 = yaw;
    v47 = (signed int)stru_5C6E00->uIntegerHalfPi / 2;
LABEL_36:
    a1.Create(v20, v47, v49, v51);
    goto LABEL_139;
  }
LABEL_117:
  v44 = level;
  a6_4 = 3600 * level;
  if ( v15 == 1 )
  {
LABEL_124:
    v60 = v44;
    goto LABEL_125;
  }
  if ( v15 == 2 )
  {
    v44 = 2 * level;
    goto LABEL_124;
  }
  if ( v15 == 3 )
  {
    v44 = 3 * level;
    goto LABEL_124;
  }
  if ( v15 == 4 )
  {
    v44 = 4 * level;
    goto LABEL_124;
  }
LABEL_125:
  switch ( spellnum_ )
  {
    case 3:
      level = 6;
      break;
    case 14:
      level = 0;
      break;
    case 25:
      level = 17;
      break;
    case 36:
      level = 4;
      break;
    case 58:
      level = 12;
      break;
    case 69:
      level = 1;
      break;
  }
  v45 = spellnum_;
  pGame->pStru6Instance->SetPlayerBuffAnim(spellnum_, 0);
  pGame->pStru6Instance->SetPlayerBuffAnim(v45, 1u);
  pGame->pStru6Instance->SetPlayerBuffAnim(v45, 2u);
  pGame->pStru6Instance->SetPlayerBuffAnim(v45, 3u);
  pParty->pPartyBuffs[level].Apply(
    pParty->uTimePlayed + (signed int)(signed __int64)((double)a6_4 * 4.2666669),
    v15,
    v60,
    0,
    0);
  levela = 1;
LABEL_138:
  if ( levela )
LABEL_139:
    pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[spellnum_], 0, 0, fromx, fromy, 0, 0, 0);
}
// 4EE088: using guessed type __int16 word_4EE088_sound_ids[];

//----- (0044987B) --------------------------------------------------------
char *__fastcall sub_44987B(const char *pMapName, unsigned int uStartingPointType)
{
  const char *v2; // edi@1
  unsigned int v3; // ebx@1
  char *result; // eax@3

  v2 = pMapName;
  v3 = uStartingPointType;
  pAudioPlayer->StopChannels(-1, -1);
  pGameLoadingUI_ProgressBar->_443484((GUIProgressBar::Type)0);
  if ( _strcmpi(pCurrentMapName, v2) )
    SaveGame(1, 0);
  uGameState = 2;
  result = strcpy(pCurrentMapName, v2);
  uLevel_StartingPointType = v3;
  return result;
}
// 6BE35C: using guessed type int uLevel_StartingPointType;

//----- (004498D5) --------------------------------------------------------
void __thiscall TeleportToStartingPoint(unsigned int uPointType)
{
  unsigned int v1; // ecx@2
  int v2; // ecx@3
  int v3; // ecx@4
  unsigned __int16 v4; // ax@11
  signed int v5; // ecx@12
  LevelDecoration *v6; // edx@13
  signed int v7; // ecx@17
  int v8; // eax@17
  int v9; // ecx@17
  const char *v10; // [sp-4h] [bp-84h]@6
  char pName[128]; // [sp+8h] [bp-78h]@11

  if ( uPointType )
  {
    v1 = uPointType - 1;
    if ( v1 )
    {
      v2 = v1 - 1;
      if ( v2 )
      {
        v3 = v2 - 1;
        if ( v3 )
        {
          if ( v3 != 1 )
            return;
          v10 = "West Start";
        }
        else
        {
          v10 = "East Start";
        }
      }
      else
      {
        v10 = "South Start";
      }
    }
    else
    {
      v10 = "North Start";
    }
  }
  else
  {
    v10 = "Party Start";
  }
  strcpy(pName, v10);
  v4 = pDecorationList->GetDecorIdByName(pName);
  if ( v4 )
  {
    v5 = 0;
    if ( (signed int)uNumLevelDecorations > 0 )
    {
      v6 = pLevelDecorations;
      while ( v6->uDecorationDescID != (signed __int16)v4 )
      {
        ++v5;
        ++v6;
        if ( v5 >= (signed int)uNumLevelDecorations )
          goto LABEL_20;
      }
      v7 = v5;
      pParty->vPosition.x = pLevelDecorations[v7].vPosition.x;
      pParty->vPosition.y = pLevelDecorations[v7].vPosition.y;
      pParty->vPosition.z = pLevelDecorations[v7].vPosition.z;
      pParty->uFallStartY = pParty->vPosition.z;
      v8 = (signed int)(stru_5C6E00->uIntegerHalfPi * pLevelDecorations[v7].field_1A) / 90;
      v9 = pLevelDecorations[v7].field_10_y_rot;
      pParty->sRotationY = v8;
      if ( v9 )
        pParty->sRotationY = v9;
      pParty->sRotationX = 0;
      pParty->uFallSpeed = 0;
    }
LABEL_20:
    if ( dword_5B65C0 )
    {
      if ( _5B65A8_npcdata_uflags_or_other )
        pParty->vPosition.x = _5B65A8_npcdata_uflags_or_other;
      if ( _5B65AC_npcdata_fame_or_other )
        pParty->vPosition.y = _5B65AC_npcdata_fame_or_other;
      if ( _5B65B0_npcdata_rep_or_other )
      {
        pParty->vPosition.z = _5B65B0_npcdata_rep_or_other;
        pParty->uFallStartY = _5B65B0_npcdata_rep_or_other;
      }
      if ( _5B65B4_npcdata_loword_house_or_other )
        pParty->sRotationY = _5B65B4_npcdata_loword_house_or_other;
      if ( _5B65B8_npcdata_hiword_house_or_other )
        pParty->sRotationX = _5B65B8_npcdata_hiword_house_or_other;
      if ( dword_5B65BC )
        pParty->uFallSpeed = dword_5B65BC;
    }
    _5B65B4_npcdata_loword_house_or_other = -1;
    dword_5B65C0 = 0;
    dword_5B65BC = 0;
    _5B65B8_npcdata_hiword_house_or_other = 0;
    _5B65B0_npcdata_rep_or_other = 0;
    _5B65AC_npcdata_fame_or_other = 0;
    _5B65A8_npcdata_uflags_or_other = 0;
  }
}
// 5B65A8: using guessed type int _5B65A8_npcdata_uflags_or_other;
// 5B65AC: using guessed type int _5B65AC_npcdata_fame_or_other;
// 5B65B0: using guessed type int _5B65B0_npcdata_rep_or_other;
// 5B65B4: using guessed type int _5B65B4_npcdata_loword_house_or_other;
// 5B65B8: using guessed type int _5B65B8_npcdata_hiword_house_or_other;
// 5B65BC: using guessed type int dword_5B65BC;
// 5B65C0: using guessed type int dword_5B65C0;

//----- (00449A49) --------------------------------------------------------
__int16 __fastcall sub_449A49_door_switch_animation(unsigned int uDoorID, int a2)
{
  int v2; // eax@1
  int v3; // ebx@1
  signed int v4; // esi@2
  int v5; // edx@2
  BLVDoor *v6; // ecx@8
  unsigned int v7; // edx@18
  signed int v8; // esi@19
  int v9; // eax@19
  char Args; // [sp+Ch] [bp-78h]@6

  LOWORD(v2) = LOWORD(pIndoor->pDoors);
  v3 = a2;
  if ( !pIndoor->pDoors )
    return v2;
  v4 = 0;
  v5 = (int)&pIndoor->pDoors->uDoorID;
  do
  {
    if ( *(int *)v5 == uDoorID )
      break;
    ++v4;
    v5 += 80;
  }
  while ( v4 < 200 );
  if ( v4 >= 200 )
  {
    sprintf(&Args, "Unable to find Door ID: %i!", uDoorID);
    Abortf(&Args);
  }
  v6 = &pIndoor->pDoors[v4];
  if ( v3 == 2 )
  {
    LOWORD(v2) = v6->uState;
    if ( (short)v2 == 3 || (short)v2 == 1 )
      return v2;
    if ( (short)v2 )
      goto LABEL_14;
  }
  else
  {
    if ( !v3 )
    {
LABEL_14:
      LOWORD(v2) = v6->uState;
      if ( (short)v2 && (short)v2 != 3 )
      {
        v6->uState = BLVDoor::Closing;
        if ( (short)v2 == 2 )
        {
LABEL_17:
          v6->uTimeSinceTriggered = 0;
          return v2;
        }
        v7 = v6->uTimeSinceTriggered;
        v2 = 15360;
        if ( v7 != 15360 )
        {
          v8 = v6->uOpenSpeed;
          v9 = v6->uCloseSpeed;
LABEL_26:
          v2 = (v6->uMoveLength << 7) / v8 - ((signed int)(v7 * v9) / 128 << 7) / v8;
          goto LABEL_27;
        }
        goto LABEL_27;
      }
      return v2;
    }
    if ( v3 != 1 )
      return v2;
  }
  LOWORD(v2) = v6->uState;
  if ( (short)v2 != 2 && (short)v2 != 1 )
  {
    v6->uState = BLVDoor::Opening;
    if ( !(short)v2 )
      goto LABEL_17;
    v7 = v6->uTimeSinceTriggered;
    v2 = 15360;
    if ( v7 != 15360 )
    {
      v8 = v6->uCloseSpeed;
      v9 = v6->uOpenSpeed;
      goto LABEL_26;
    }
LABEL_27:
    v6->uTimeSinceTriggered = v2;
  }
  return v2;
}

//----- (00449B57) --------------------------------------------------------
unsigned int __fastcall _449B57_test_bit(unsigned __int8 *a1, __int16 a2)
{
  return a1[(a2 - 1) >> 3] & (0x80u >> (a2 - 1) % 8);
}

//----- (00449B7E) --------------------------------------------------------
unsigned char *_449B7E_toggle_bit(unsigned char *pArray, __int16 a2, unsigned __int16 bToggle)
{
  signed int v3; // esi@1
  unsigned char *result; // eax@1
  unsigned int v5; // edx@1

  v3 = a2 - 1;
  result = &pArray[v3 / 8];
  v5 = 0x80 >> v3 % 8;
  if ( bToggle )
    *result |= v5;
  else
    *result &= ~(unsigned char)v5;
  return result;
}


//----- (0044A56A) --------------------------------------------------------
void __cdecl sub_44A56A()
{
  pParty->field_70A = 0;

  for (int i = 0; i < pNPCStats->uNumNewNPCs; ++i)
  {
    auto npc = pNPCStats->pNewNPCData + i;
    if (npc->uFlags & 0x80 &&
        (!pParty->pHirelings[0].pName || strcmp(npc->pName, pParty->pHirelings[0].pName)))
    {
      if (!pParty->pHirelings[1].pName || strcmp(npc->pName, pParty->pHirelings[1].pName))
        ++pParty->field_70A;
    }
  }
}


//----- (0044C175) --------------------------------------------------------
void __fastcall ShowStatusBarString(const char *pString, unsigned int uNumSeconds)
{
  unsigned int v2; // esi@1
  int i; // eax@1

  v2 = uNumSeconds;
  strcpy(GameUI_StatusBar_TimedString, pString);
  GameUI_StatusBar_TimedStringTimeLeft = 1000 * v2 + GetTickCount();
  for ( i = pFontLucida->GetLineWidth(GameUI_StatusBar_TimedString);
        i > 450;
        i = pFontLucida->GetLineWidth(GameUI_StatusBar_TimedString) )
    byte_5C3427[strlen(GameUI_StatusBar_TimedString)] = 0;
}

//----- (0044C1D0) --------------------------------------------------------
void __cdecl ShowNothingHereStatus()
{
  if ( !GameUI_StatusBar_TimedStringTimeLeft )
    ShowStatusBarString(pGlobalTXT_LocalizationStrings[521], 2u);// Nothing here
}


//----- (0044C28B) --------------------------------------------------------
signed int __cdecl const_2()
{
  return 2;
}

//----- (0044C28F) --------------------------------------------------------
bool __cdecl sub_44C28F_open_nwc_dungeon()
{
  bool result; // eax@1

  result = _strcmpi("nwc.blv", pCurrentMapName);
  if ( result )
  {
    _5B65A8_npcdata_uflags_or_other = 0;
    _5B65AC_npcdata_fame_or_other = 0;
    _5B65B0_npcdata_rep_or_other = 0;
    _5B65B4_npcdata_loword_house_or_other = 0;
    _5B65B8_npcdata_hiword_house_or_other = 0;
    dword_5B65BC = 0;
    dword_5B65C0 = 0;
    pGameLoadingUI_ProgressBar->uType = GUIProgressBar::TYPE_Fullscreen;
    sub_44987B("nwc.blv", 0);
    pCurrentScreen = SCREEN_GAME;
    result = 1;
  }
  return result;
}


//----- (0044C2F4) --------------------------------------------------------
int LevelDecoration::IsInteractive()
{
  signed int v1; // eax@1

  v1 = this->uDecorationDescID;
  if ( v1 > 34 )
  {
    if ( v1 == 184 || v1 == 187 || v1 == 190 || v1 > 205 && v1 <= 221 )
      return 1;
  }
  else
  {
    if ( v1 == 34 || v1 >= 4 && (v1 <= 6 || v1 == 11 || v1 > 12 && (v1 <= 14 || v1 == 24)) )
      return 1;
  }
  return 0;
}

//----- (0044C362) --------------------------------------------------------
void Vec3_int_::Normalize_float()
{
  Vec3_int_ *v1; // esi@1
  double v2; // st6@1
  float v3; // ST20_4@1
  double v4; // st5@1
  float v5; // ST18_4@1
  double v6; // st4@1
  float v7; // ST14_4@1
  float v8; // ST24_4@1
  float v9; // ST20_4@1
  double v10; // ST0C_8@1
  float v11; // ST18_4@1
  double v12; // ST0C_8@1
  float v13; // ST14_4@1
  double v14; // ST0C_8@1

  v1 = this;
  v2 = (double)this->x * 0.000015258789;
  v3 = v2;
  v4 = (double)this->y * 0.000015258789;
  v5 = v4;
  v6 = (double)this->z * 0.000015258789;
  v7 = v6;
  v8 = 1.0 / sqrt(v6 * v6 + v4 * v4 + v2 * v2);
  v9 = v8 * v3 * 65536.0;
  v10 = v9 + 6.7553994e15;
  v1->x = LODWORD(v10);
  v11 = v8 * v5 * 65536.0;
  v12 = v11 + 6.7553994e15;
  v1->y = LODWORD(v12);
  v13 = v8 * v7 * 65536.0;
  v14 = v13 + 6.7553994e15;
  v1->z = LODWORD(v14);
}






//----- (00401000) --------------------------------------------------------
void __stdcall mm7__vector_constructor(void *a1, int objSize, int numObjs, int (__thiscall *constructor)(int))
{
  void *v4; // esi@2
  int v5; // edi@2

  if ( numObjs - 1 >= 0 )
  {
    v4 = a1;
    v5 = numObjs;
    do
    {
      constructor((int)v4);
      v4 = (char *)v4 + objSize;
      --v5;
    }
    while ( v5 );
  }
}


//----- (004014E6) --------------------------------------------------------
int __cdecl ODM_4014E6_AI()
{
  Actor *v0; // esi@2
  int v1; // eax@4
  int v2; // ebx@4
  unsigned int v3; // ecx@4
  int v4; // edx@5
  int v5; // edx@7
  unsigned int v6; // edx@9
  unsigned int v7; // ST20_4@10
  int v8; // eax@10
  int v9; // edi@10
  int v10; // ebx@14
  char v11; // zf@16
  int v12; // eax@22
  int result; // eax@24
  int v14; // edx@25
  int v15; // ecx@25
  int v16; // ebx@26
  unsigned int *v17; // ecx@27
  unsigned int v18; // esi@27
  int i; // edx@33
  char *v20; // ecx@34
  int v21; // [sp+Ch] [bp-14h]@4
  int v22; // [sp+10h] [bp-10h]@4
  int v23; // [sp+14h] [bp-Ch]@10
  int v24; // [sp+14h] [bp-Ch]@29
  signed int v25; // [sp+18h] [bp-8h]@1
  signed int v26; // [sp+18h] [bp-8h]@25
  int v27; // [sp+1Ch] [bp-4h]@1

  pParty->uFlags &= 0xFFFFFFCFu;
  v27 = 0;
  v25 = 0;
  if ( (signed int)uNumActors > 0 )
  {
    v0 = pActors;//[0].uAttributes;
    do
    {
	  //*(char *)(v0 + 1) &= 0xFBu;
	  BYTE1(v0->uAttributes) &= 0xFBu;
      if ( ! v0->CanAct() )
        goto LABEL_37;
	  v22 = abs(pParty->vPosition.z - v0->vPosition.z);
      v21 = abs(pParty->vPosition.y - v0->vPosition.y);
      v1 = abs(pParty->vPosition.x - v0->vPosition.x);
      v2 = v21;
      v3 = v22;
      if ( v1 < v21 )
      {
        v4 = v1;
        v1 = v21;
        v2 = v4;
      }
      if ( v1 < v22 )
      {
        v5 = v1;
        v1 = v22;
        v3 = v5;
      }
      if ( v2 < (signed int)v3 )
      {
        v6 = v3;
        v3 = v2;
        v2 = v6;
      }
      v7 = ((unsigned int)(11 * v2) >> 5) + (v3 >> 2) + v1;
	  v8 = v0->uActorRadius;
      v9 = v7 - v8;
      v23 = v7 - v8;
      if ( v23 < 0 )
      {
        v9 = 0;
        v23 = 0;
      }
      if ( v9 < 5632 )
      {
        v10 = v0->uAttributes & 0xFEFFFFFF;
        v0->uAttributes = v10;
        if ( v10 & 0x80000 || v0->GetActorsRelation(0) )
        {
          v11 = (pParty->uFlags & 0x10) == 0;
          v0->uAttributes = v10 | 0x1000000;
          if ( v11 && (double)v23 < 307.2 )
            pParty->uFlags |= 0x10u;
          if ( !(pParty->uFlags & 0x20) && v9 < 5120 )
            pParty->uFlags |= 0x20u;
        }
		BYTE1(v0->uAttributes) |= 0x40u;
        v12 = v27++;
        ai_array_4F75E0[v12] = v9;
        ai_array_4F7DB0_actor_ids[v12] = v25;
      }
      else
      {
LABEL_37:
		  BYTE1(v0->uAttributes) &= 0xBFu;
      }
      ++v25;
      ++v0;
    }
    while ( v25 < (signed int)uNumActors );
  }
  result = v27;
  if ( v27 > 0 )
  {
    v14 = 0;
    v15 = 1;
    v26 = 1;
    do
    {
      while ( 1 )
      {
        v24 = v15;
        if ( v15 >= result )
          break;
        v16 = ai_array_4F75E0[v14];
        if ( v16 > ai_array_4F75E0[v15] )
        {
          v17 = &ai_array_4F7DB0_actor_ids[v15];
          v18 = ai_array_4F7DB0_actor_ids[v14];
          ai_array_4F7DB0_actor_ids[v14] = *v17;
          *v17 = v18;
          v15 = v24;
          ai_array_4F75E0[v14] = ai_array_4F75E0[v24];
          ai_array_4F75E0[v24] = v16;
        }
        result = v27;
        ++v15;
      }
      ++v14;
      v15 = v26 + 1;
      v26 = v15;
    }
    while ( v15 - 1 < result );
  }
  ai_arrays_size = result;
  if ( result > 30 )
  {
    result = 30;
    ai_arrays_size = 30;
  }
  for ( i = 0; i < result; ++i )
  {
    v20 = (char *)&pActors[ai_array_4F7DB0_actor_ids[i]].uAttributes;
    v20[1] |= 4u;
  }
  return result;
}
// 4F75D8: using guessed type int ai_arrays_size;

//----- (004016FA) --------------------------------------------------------
int __cdecl BLV_4016FA_AI()
{
  Actor *v0; // esi@2
  int v1; // eax@4
  int v2; // ebx@4
  unsigned int v3; // ecx@4
  int v4; // edx@5
  int v5; // edx@7
  unsigned int v6; // edx@9
  unsigned int v7; // ST24_4@10
  int v8; // eax@10
  int v9; // edi@10
  int v10; // ebx@14
  char v11; // zf@16
  int v12; // eax@22
  int v13; // edx@24
  int v14; // ecx@25
  int v15; // ebx@26
  unsigned int *v16; // ecx@27
  unsigned int v17; // esi@27
  int v18; // ecx@31
  signed int v19; // edi@31
  Actor *v20; // esi@32
  bool v21; // eax@33
  int v22; // eax@34
  signed int v23; // ebx@36
  Actor *v24; // esi@37
  signed int v25; // eax@40
  int v26; // eax@43
  int v27; // ebx@45
  int j; // edi@45
  unsigned int v29; // eax@46
  int v30; // eax@48
  int v31; // ecx@51
  int v32; // eax@51
  signed int v33; // eax@53
  __int64 v34; // qax@55
  char *v35; // ecx@56
  int v37; // [sp+Ch] [bp-18h]@1
  int v38; // [sp+10h] [bp-14h]@4
  int v39; // [sp+14h] [bp-10h]@4
  int v40; // [sp+18h] [bp-Ch]@10
  int v41; // [sp+18h] [bp-Ch]@29
  int i; // [sp+18h] [bp-Ch]@31
  signed int v43; // [sp+1Ch] [bp-8h]@1
  signed int v44; // [sp+1Ch] [bp-8h]@25
  int v45; // [sp+20h] [bp-4h]@1

  pParty->uFlags &= 0xFFFFFFCFu;
  v37 = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
  v45 = 0;
  v43 = 0;
  if ( (signed int)uNumActors > 0 )
  {
    v0 = pActors;//[0].uAttributes;
    do
    {
      BYTE1(v0->uAttributes) &= 0xFBu;
      if ( ! v0->CanAct() )
        goto LABEL_60;
	  v39 = abs(pParty->vPosition.z - v0->vPosition.z);
	  v38 = abs(pParty->vPosition.y - v0->vPosition.y);
	  v1 = abs(pParty->vPosition.x - v0->vPosition.x);
      v2 = v38;
      v3 = v39;
      if ( v1 < v38 )
      {
        v4 = v1;
        v1 = v38;
        v2 = v4;
      }
      if ( v1 < v39 )
      {
        v5 = v1;
        v1 = v39;
        v3 = v5;
      }
      if ( v2 < (signed int)v3 )
      {
        v6 = v3;
        v3 = v2;
        v2 = v6;
      }
      v7 = ((unsigned int)(11 * v2) >> 5) + (v3 >> 2) + v1;
      v8 = v0->uActorRadius;
      v9 = v7 - v8;
      v40 = v7 - v8;
      if ( v40 < 0 )
      {
        v9 = 0;
        v40 = 0;
      }
      if ( v9 < 10240 )
      {
        v10 = v0->uAttributes & 0xFEFFFFFF;
        v0->uAttributes = v10;
        if ( v10 & 0x80000 || v0->GetActorsRelation(0) )
        {
          v11 = (pParty->uFlags & 0x10) == 0;
          v0->uAttributes = v10 | 0x1000000;
          if ( v11 && (double)v40 < 307.2 )
            pParty->uFlags |= 0x10u;
          if ( !(pParty->uFlags & 0x20) && v9 < 5120 )
            pParty->uFlags |= 0x20u;
        }
        v12 = v45++;
        ai_array_4F75E0[v12] = v9;
        ai_array_4F7DB0_actor_ids[v12] = v43;
      }
      else
      {
LABEL_60:
        BYTE1(v0->uAttributes) &= 0xBFu;
      }
      ++v43;
      ++v0;
    }
    while ( v43 < (signed int)uNumActors );
  }
  v13 = 0;
  if ( v45 > 0 )
  {
    v14 = 1;
    v44 = 1;
    do
    {
      while ( 1 )
      {
        v41 = v14;
        if ( v14 >= v45 )
          break;
        v15 = ai_array_4F75E0[v13];
        if ( v15 > ai_array_4F75E0[v14] )
        {
          v16 = &ai_array_4F7DB0_actor_ids[v14];
          v17 = ai_array_4F7DB0_actor_ids[v13];
          ai_array_4F7DB0_actor_ids[v13] = *v16;
          *v16 = v17;
          v14 = v41;
          ai_array_4F75E0[v13] = ai_array_4F75E0[v41];
          ai_array_4F75E0[v41] = v15;
        }
        ++v14;
      }
      ++v13;
      v14 = v44 + 1;
      v44 = v14;
    }
    while ( v14 - 1 < v45 );
  }
  v18 = 0;
  v19 = 0;
  for ( i = 0; v18 < v45; i = v18 )
  {
    v20 = &pActors[ai_array_4F7DB0_actor_ids[v18]];
    if ( v20->uAttributes & 0x8000
      || (v21 = sub_4070EF_prolly_collide_objects(8 * ai_array_4F7DB0_actor_ids[v18] | 3, 4u), v18 = i, v21) )
    {
      v22 = ai_array_4F7DB0_actor_ids[v18];
      v20->uAttributes |= 0x8000u;
      ai_array_4F6638_actor_ids[v19] = v22;
      ai_array_4F5E68[v19++] = ai_array_4F75E0[v18];
      if ( v19 >= 30 )
        break;
    }
    ++v18;
  }
  v23 = 0;
  ai_arrays_size = v19;
  if ( (signed int)uNumActors > 0 )
  {
    v24 = pActors;//[0].uAttributes;
    do
    {
      if ( v24->CanAct() && v24->uSectorID == v37 )
      {
        v25 = 0;
        if ( v19 <= 0 )
        {
LABEL_43:
          v26 = ai_arrays_size;
          BYTE1(v24->uAttributes) |= 0x40u;
          ++ai_arrays_size;
          ai_array_4F6638_actor_ids[v26] = v23;
        }
        else
        {
          while ( ai_array_4F6638_actor_ids[v25] != v23 )
          {
            ++v25;
            if ( v25 >= v19 )
              goto LABEL_43;
          }
        }
      }
      ++v23;
      ++v24;
    }
    while ( v23 < (signed int)uNumActors );
  }
  v27 = ai_arrays_size;
  for ( j = 0; j < v45; ++j )
  {
    v29 = ai_array_4F7DB0_actor_ids[j];
    if ( pActors[v29].uAttributes & 0xC000 && pActors[v29].CanAct() )
    {
      v30 = 0;
      if ( v27 <= 0 )
      {
LABEL_51:
        v31 = ai_arrays_size;
        v32 = ai_array_4F7DB0_actor_ids[j];
        ++ai_arrays_size;
        ai_array_4F6638_actor_ids[v31] = v32;
      }
      else
      {
        while ( ai_array_4F6638_actor_ids[v30] != ai_array_4F7DB0_actor_ids[j] )
        {
          ++v30;
          if ( v30 >= v27 )
            goto LABEL_51;
        }
      }
    }
  }
  v33 = ai_arrays_size;
  if ( ai_arrays_size > 30 )
  {
    v33 = 30;
    ai_arrays_size = 30;
  }
  memcpy(ai_array_4F7DB0_actor_ids, ai_array_4F6638_actor_ids, 4 * v33);
  memcpy(ai_array_4F75E0, ai_array_4F5E68, 4 * ai_arrays_size);
  v34 = (unsigned int)ai_arrays_size;
  if ( ai_arrays_size > 0 )
  {
    do
    {
      v35 = (char *)&pActors[ai_array_4F7DB0_actor_ids[HIDWORD(v34)]].uAttributes;
      v35[1] |= 4u;
      ++HIDWORD(v34);
    }
    while ( SHIDWORD(v34) < (signed int)v34 );
  }
  return v34;
}
// 4F75D8: using guessed type int ai_arrays_size;

//----- (00401A91) --------------------------------------------------------
void __cdecl sub_401A91_AI()
{
  unsigned int v0; // esi@4
  int v1; // eax@7
  int v2; // ecx@7
  int v3; // eax@7
  signed int v4; // edi@10
  Actor *v5; // esi@12
  signed int v6; // eax@14
  __int16 v7; // cx@14
  Player **v8; // esi@20
  Player *pPlayer; // ecx@21
  Actor *pActor; // esi@34
  __int16 v11; // ax@34
  unsigned int v12; // eax@47
  signed int v13; // edi@47
  SpellBuff *v14; // ebx@47
  unsigned int v15; // edi@67
  char *v16; // eax@67
  unsigned int v17; // edx@67
  unsigned int v18; // ecx@67
  unsigned __int16 v19; // ax@72
  int *v20; // esi@80
  Actor *v21; // ebx@80
  unsigned __int16 v22; // ax@86
  signed int v23; // eax@94
  unsigned int v24; // eax@102
  signed int v25; // edi@102
  SpellBuff *v26; // esi@102
  unsigned int v27; // ecx@123
  unsigned int v28; // eax@123
  unsigned int v29; // eax@127
  AIDirection *v30; // eax@129
  unsigned __int16 v31; // ax@132
  unsigned int v32; // esi@142
  int v33; // eax@144
  int v34; // eax@147
  char v35; // al@150
  unsigned int v36; // edi@152
  signed int v37; // eax@154
  unsigned __int8 v38; // sf@158
  unsigned __int8 v39; // of@158
  signed int v40; // edx@166
  unsigned int v41; // ecx@166
  double v42; // st7@176
  double v43; // st6@176
  bool v44; // eax@189
  bool v45; // eax@192
  unsigned __int8 v46; // cl@197
  double v47; // st7@206
  double v48; // st7@207
  char v49; // zf@208
  char v50; // zf@214
  signed int v51; // edx@219
  unsigned int v52; // ecx@219
  __int16 v53; // fps@224
  unsigned __int8 v54; // c0@224
  unsigned __int8 v55; // c3@224
  double v56; // st7@226
  AIDirection *v57; // eax@246
  double v58; // st7@246
  signed int v59; // [sp-18h] [bp-C8h]@213
  int v60; // [sp-14h] [bp-C4h]@144
  int v61; // [sp-14h] [bp-C4h]@168
  AIDirection *v62; // [sp-14h] [bp-C4h]@213
  signed int v63; // [sp-14h] [bp-C4h]@216
  unsigned int v64; // [sp-14h] [bp-C4h]@219
  unsigned int v65; // [sp-10h] [bp-C0h]@144
  char v66; // [sp-10h] [bp-C0h]@147
  AIDirection *v67; // [sp-10h] [bp-C0h]@167
  int v68; // [sp-10h] [bp-C0h]@168
  AIDirection *v69; // [sp-10h] [bp-C0h]@206
  int v70; // [sp-10h] [bp-C0h]@213
  AIDirection *v71; // [sp-10h] [bp-C0h]@216
  AIDirection v72; // [sp+0h] [bp-B0h]@246
  AIDirection a3; // [sp+1Ch] [bp-94h]@129
  AIDirection v74; // [sp+38h] [bp-78h]@246
  AIDirection v75; // [sp+54h] [bp-5Ch]@129
  int v76; // [sp+70h] [bp-40h]@83
  signed int a1; // [sp+74h] [bp-3Ch]@129
  int v78; // [sp+78h] [bp-38h]@79
  AIDirection pDir; // [sp+7Ch] [bp-34h]@129
  float v80; // [sp+98h] [bp-18h]@33
  int v81; // [sp+9Ch] [bp-14h]@100
  int v82; // [sp+A0h] [bp-10h]@45
  unsigned int uActorID; // [sp+A4h] [bp-Ch]@32
  unsigned int v84; // [sp+A8h] [bp-8h]@11
  signed int a2; // [sp+ACh] [bp-4h]@83

  if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
    ODM_4014E6_AI();
  else
    BLV_4016FA_AI();
  v0 = 0;
  if ( uCurrentlyLoadedLevelType != LEVEL_Indoor && pParty->field_1613C > 0 )
  {
    if ( pParty->field_1613C > 417 )
    {
      pParty->field_1613C = 0;
    }
    else
    {
      pParty->sRotationY = (stru_5C6E00->uIntegerDoublePi - 1) & (pParty->sRotationY + rand() % 16 - 8);
      v1 = rand();
      v2 = 128;
      v3 = pParty->sRotationX + v1 % 16 - 8;
      pParty->sRotationX = v3;
      if ( v3 > 128 || (v2 = -128, v3 < -128) )
        pParty->sRotationX = v2;
      pParty->uFlags |= 2u;
      pParty->field_1613C -= pMiscTimer->uTimeElapsed;
      v4 = pParty->field_16140 + 50;
      if ( pParty->field_1613C <= 0 )
      {
        pParty->field_1613C = 0;
        v84 = 0;
        if ( (signed int)uNumActors > 0 )
        {
          v5 = pActors;//[0].sCurrentHP;
          do
          {
            if ( v5->CanAct() )
            {
              v6 = stru_50C198.CalcMagicalDamageToActor(v5, 5, v4);
              v7 = v5->sCurrentHP - v6;
              v5->sCurrentHP = v7;
              if ( v6 )
              {
                if ( v7 >= 0 )
                {
                  Actor::_4030AD(v84, 4, 0);
                }
                else
                {
                  Actor::Die(v84);
                  if ( v5->pMonsterInfo.uExp )
                    sub_4269A2_GivePartyExp(pMonsterStats->pInfos[v5->pMonsterInfo.uID].uExp);
                }
              }
            }
            ++v84;
            ++v5;
          }
          while ( (signed int)v84 < (signed int)uNumActors );
        }
        v8 = &pPlayers[1];
        do
        {
          pPlayer = *v8;
          if ( !(*v8)->pConditions[14] && !pPlayer->pConditions[15] && !pPlayer->pConditions[16] )
            pPlayer->ReceiveDamage(v4, 5);
          ++v8;
        }
        while ( (signed int)v8 <= (signed int)&pPlayers[4] );
        v0 = 0;
      }
      if ( pTurnEngine->field_1C != v0 )
        --pTurnEngine->field_1C;
    }
  }
  if ( pParty->bTurnBasedModeOn == 1 )
  {
    pTurnEngine->_405E14();
    return;
  }
  uActorID = v0;
  if ( (signed int)uNumActors > (signed int)v0 )
  {
    LODWORD(v80) = (int)(char *)pActors + 176;
    do
    {
      pActor = (Actor *)(LODWORD(v80) - 176);
      v11 = *(unsigned int *)LODWORD(v80);
      v49 = *(unsigned int *)LODWORD(v80) == 5;
      dword_4F6E08[uActorID] = 4;
      if ( v49 || v11 == 11 || v11 == 19 || *(char *)(LODWORD(v80) - 139) & 4 )
        goto LABEL_78;
      if ( !*(short *)(LODWORD(v80) - 136) && v11 != 4 )
        Actor::Die(uActorID);
      v84 = *(_QWORD *)(LODWORD(v80) + 84) <= 0i64 ? 0 : 1;
      v82 = *(_QWORD *)(LODWORD(v80) + 52) <= 0i64 ? 0 : 1;
      v12 = 0;
      v13 = 0;
      v14 = (SpellBuff *)(LODWORD(v80) + 36);
      do
      {
        if ( v13 != 10 )
        {
          v14->_4585CA(pParty->uTimePlayed);
          v12 = 0;
        }
        ++v13;
        ++v14;
      }
      while ( v13 < 22 );
      if ( v84 != v12
        && SHIDWORD(pActor->pActorBuffs[3].uExpireTime) <= (signed int)v12
        && (SHIDWORD(pActor->pActorBuffs[3].uExpireTime) < (signed int)v12
         || LODWORD(pActor->pActorBuffs[3].uExpireTime) <= v12) )
        pActor->uActorHeight = pMonsterList->pMonsters[pActor->pMonsterInfo.uID - 1].uMonsterHeight;
      if ( v82 != v12 )
      {
        pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
        if ( SHIDWORD(pActor->pActorBuffs[1].uExpireTime) <= (signed int)v12 )
        {
          if ( SHIDWORD(pActor->pActorBuffs[1].uExpireTime) < (signed int)v12
            || LODWORD(pActor->pActorBuffs[1].uExpireTime) <= v12 )
            pActor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[pActor->pMonsterInfo.uID].uHostilityType;
        }
      }
      if ( SHIDWORD(pActor->pActorBuffs[5].uExpireTime) > (signed int)v12
        || SHIDWORD(pActor->pActorBuffs[5].uExpireTime) >= (signed int)v12
        && LODWORD(pActor->pActorBuffs[5].uExpireTime)
        || SHIDWORD(pActor->pActorBuffs[6].uExpireTime) > 0
        || SHIDWORD(pActor->pActorBuffs[6].uExpireTime) >= 0 && LODWORD(pActor->pActorBuffs[6].uExpireTime) )
        goto LABEL_78;
      v15 = pMiscTimer->uTimeElapsed;
      v16 = (char *)&pActor->pMonsterInfo.uRecoveryTime;
      pActor->uCurrentActionTime += pMiscTimer->uTimeElapsed;
      v17 = pActor->uCurrentActionTime;
      v18 = pActor->pMonsterInfo.uRecoveryTime;
      if ( (signed int)v18 > 0 )
        *(int *)v16 = v18 - v15;
      if ( *(int *)v16 < 0 )
        *(int *)v16 = 0;
      if ( (signed int)v17 < pActor->uCurrentActionLength )
        goto LABEL_78;
      v19 = pActor->uAIState;
      if ( v19 == Dying )
      {
        pActor->uAIState = Dead;
      }
      else
      {
        if ( v19 != 17 )
        {
          Actor::_403F58(uActorID, Dying, 256, 0);
          goto LABEL_78;
        }
        pActor->uAIState = Standing;
      }
      pActor->uCurrentActionTime = 0;
      pActor->uCurrentActionLength = 0;
      pActor->UpdateAnimation();
LABEL_78:
      ++uActorID;
      LODWORD(v80) += 836;
    }
    while ( (signed int)uActorID < (signed int)uNumActors );
  }
  v78 = 0;
  if ( ai_arrays_size > 0 )
  {
    while ( 1 )
    {
      uActorID = ai_array_4F7DB0_actor_ids[v78];
      v20 = &dword_4F6E08[uActorID];
      v21 = &pActors[uActorID];
      Actor::_401221(uActorID, &dword_4F6E08[uActorID], 1u);
      if ( v21->pMonsterInfo.uHostilityType && !*v20 )
        v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
      a2 = *v20;
      v76 = a2 & 7;
      if ( (a2 & 7) == OBJECT_Actor)
        v80 = 0.5;
      else
        v80 = 1.0;
      v22 = v21->uAIState;
      if ( v22 == Dying || v22 == Dead || v22 == Removed || v22 == Disabled || v22 == Summoned)
        goto LABEL_254;
      if ( !v21->sCurrentHP )
        Actor::Die(uActorID);
      if ( (signed __int64)v21->pActorBuffs[3].uExpireTime <= 0 )
      {
        v84 = 0;
        v23 = 1;
      }
      else
      {
        v23 = 1;
        v84 = 1;
      }
      if ( (signed __int64)v21->pActorBuffs[1].uExpireTime <= 0 )
        v82 = 0;
      else
        v82 = v23;
      if ( (signed __int64)v21->pActorBuffs[2].uExpireTime <= 0 )
        v81 = 0;
      else
        v81 = v23;
      v24 = 0;
      v25 = 0;
      v26 = v21->pActorBuffs;
      do
      {
        if ( v25 != 10 )
        {
          v26->_4585CA(pParty->uTimePlayed);
          v24 = 0;
        }
        ++v25;
        ++v26;
      }
      while ( v25 < 22 );
      if ( v84 != v24
        && SHIDWORD(v21->pActorBuffs[3].uExpireTime) <= (signed int)v24
        && (SHIDWORD(v21->pActorBuffs[3].uExpireTime) < (signed int)v24
         || LODWORD(v21->pActorBuffs[3].uExpireTime) <= v24) )
        v21->uActorHeight = pMonsterList->pMonsters[v21->pMonsterInfo.uID - 1].uMonsterHeight;
      if ( v82 != v24 )
      {
        v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
        if ( SHIDWORD(v21->pActorBuffs[1].uExpireTime) <= (signed int)v24 )
        {
          if ( SHIDWORD(v21->pActorBuffs[1].uExpireTime) < (signed int)v24
            || LODWORD(v21->pActorBuffs[1].uExpireTime) <= v24 )
            v21->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[v21->pMonsterInfo.uID].uHostilityType;
        }
      }
      if ( v81 != v24
        && SHIDWORD(v21->pActorBuffs[2].uExpireTime) <= (signed int)v24
        && (SHIDWORD(v21->pActorBuffs[2].uExpireTime) < (signed int)v24
         || LODWORD(v21->pActorBuffs[2].uExpireTime) <= v24) )
      {
        v21->uAIState = Removed;
        goto LABEL_254;
      }
      if ( v21->pActorBuffs[5].uExpireTime || v21->pActorBuffs[6].uExpireTime )
        goto LABEL_254;
      v27 = pMiscTimer->uTimeElapsed;
      v28 = v21->pMonsterInfo.uRecoveryTime;
      v21->uCurrentActionTime += pMiscTimer->uTimeElapsed;
      if ( (signed int)v28 > 0 )
        v21->pMonsterInfo.uRecoveryTime = v28 - v27;
      if ( (v21->pMonsterInfo.uRecoveryTime & 0x80000000u) != 0 )
        v21->pMonsterInfo.uRecoveryTime = 0;
      v29 = v21->uAttributes;
      if ( !(v29 & 0x8000) )
        v21->uAttributes = v29 | 0x8000;
      a1 = 8 * uActorID | 3;
      v30 = Actor::GetDirectionInfo(8 * uActorID | 3, a2, &a3, 0);
      v49 = v21->pMonsterInfo.uHostilityType == 0;
      memcpy(&v75, v30, sizeof(v75));
      memcpy(&pDir, &v75, sizeof(pDir));
      if ( !v49 && (signed int)v21->pMonsterInfo.uRecoveryTime <= 0 )
      {
        if ( v80 * 307.2 >= (double)(signed int)v75.uDistance
          && ((v31 = v21->uAIState, v31 == 6) || !v31 || v31 == 1 || v31 == 9)
          || v21->pMonsterInfo.uMissleAttack1Type && v21->uAIState == 8 )
        {
          v32 = uActorID;
          goto LABEL_152;
        }
      }
      if ( (signed int)v21->uCurrentActionTime < v21->uCurrentActionLength )
        goto LABEL_254;
      if ( v21->uAIState == 2 )
      {
        v32 = uActorID;
        v35 = stru_50C198.special_ability_use_check(v21, uActorID);
        stru_50FE08.Add(
          a1,
          5120,
          v21->vPosition.x,
          v21->vPosition.y,
          v21->vPosition.z + ((signed int)v21->uActorHeight >> 1),
          v35,
          1);
        goto LABEL_152;
      }
      if ( v21->uAIState == 3 )
      {
        v34 = v21->pMonsterInfo.uMissleAttack1Type;
        v66 = 0;
        goto LABEL_149;
      }
      if ( v21->uAIState == 12 )
      {
        v34 = v21->pMonsterInfo.uMissleAttack2Type;
        v66 = 1;
LABEL_149:
        v32 = uActorID;
        Actor::_404874(uActorID, &pDir, v34, v66);
        goto LABEL_152;
      }
      v32 = uActorID;
      if ( v21->uAIState == 13 )
        break;
      if ( v21->uAIState == 18 )
      {
        v65 = v21->pMonsterInfo.uSpellSkillAndMastery2;
        v60 = 3;
        v33 = v21->pMonsterInfo.uSpell2ID;
LABEL_146:
        Actor::_404AC7(uActorID, &pDir, v33, v60, v65);
      }
LABEL_152:
      v36 = v75.uDistance;
      if ( v21->pMonsterInfo.uHostilityType )
        goto LABEL_165;
      if ( v76 == 3 )
      {
        v36 = v75.uDistance;
        v37 = (unsigned __int8)*(&byte_5C8D1A[89 * (v21->pMonsterInfo.uID - 1) / 3]
                               + (pActors[a2 >> 3].pMonsterInfo.uID - 1) / 3);
      }
      else
      {
        v37 = 4;
      }
      if ( v37 == 1 )
        goto LABEL_257;
      if ( v37 == 2 )
      {
        v39 = __OFSUB__(v36, 1024);
        v38 = ((v36 - 1024) & 0x80000000u) != 0;
      }
      else
      {
        if ( v37 == 3 )
        {
          v39 = __OFSUB__(v36, 2560);
          v38 = ((v36 - 2560) & 0x80000000u) != 0;
        }
        else
        {
          if ( v37 != 4 )
            goto LABEL_165;
          v39 = __OFSUB__(v36, 5120);
          v38 = ((v36 - 5120) & 0x80000000u) != 0;
        }
      }
      if ( v38 ^ v39 )
LABEL_257:
      v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
LABEL_165:
      if ( (signed __int64)v21->pActorBuffs[4].uExpireTime > 0 )
      {
        v40 = a2;
        v41 = v32;
        if ( (signed int)v36 >= 10240 )
        {
          v68 = 0;
          v61 = 1024;
          goto LABEL_253;
        }
        v67 = &pDir;
        goto LABEL_182;
      }
      if ( v21->pMonsterInfo.uHostilityType != 4 || !a2 )
        goto LABEL_241;
      if ( !(v21->uAttributes & 0x020000) || v21->pMonsterInfo.uAIType == 1 )
      {
        if ( v21->pMonsterInfo.uAIType == 1 )
        {
          v67 = &pDir;
          if ( v21->pMonsterInfo.uMovementType != 5 )
            goto LABEL_181;
          Actor::_403EB6(
            v32,
            a2,
            (signed __int64)((double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333),
            &pDir);
        }
        else
        {
          if ( v21->pMonsterInfo.uAIType == 2 )
          {
            v84 = v21->sCurrentHP;
            v42 = (double)(signed int)v84;
            v43 = (double)(signed int)v21->pMonsterInfo.uHP * 0.2;
          }
          else
          {
            if ( v21->pMonsterInfo.uAIType != 3 )
              goto LABEL_185;
            v84 = v21->sCurrentHP;
            v42 = (double)(signed int)v84;
            v43 = (double)(signed int)v21->pMonsterInfo.uHP * 0.1;
          }
          if ( v43 > v42 && (signed int)v36 < 10240 )
          {
            v67 = &pDir;
LABEL_181:
            v40 = a2;
            v41 = v32;
LABEL_182:
            Actor::_402968(v41, v40, 0, v67);
            goto LABEL_254;
          }
        }
      }
LABEL_185:
      v81 = v36 - v21->uActorRadius;
      if ( v76 == 3 )
        v81 -= pActors[a2 >> 3].uActorRadius;
      if ( v81 < 0 )
        v81 = 0;
      rand();
      v44 = (signed int)v21->pMonsterInfo.uRecoveryTime <= 0;
      v21->uAttributes &= 0xFBFFFF;
      v82 = 0;
      v49 = v21->pMonsterInfo.uMovementType == 5;
      v84 = v44;
      if ( v49 )
        v82 = 1;
      if ( v81 >= 5120 )
        goto LABEL_241;
      v45 = stru_50C198.special_ability_use_check(v21, v32);
      if ( !v45 )
      {
        if ( v21->pMonsterInfo.uMissleAttack1Type )
        {
          if ( v84 )
          {
            Actor::_403476(v32, a2, &pDir);
            goto LABEL_254;
          }
LABEL_223:
          if ( v82 )
            goto LABEL_217;
          v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
          //UNDEF(v53);
          v69 = &pDir;
          if ( !(v54 | v55) )
            goto LABEL_219;
LABEL_225:
          Actor::_402AD7(v32, a2, v32, (signed __int64)v47, v69);
          goto LABEL_254;
        }
        v56 = v80 * 307.2;
        if ( (double)v81 >= v56 )
        {
          if ( v81 >= 1024 )
          {
            if ( v82 )
              goto LABEL_217;
            v71 = &pDir;
            v63 = 0;
            goto LABEL_240;
          }
          goto LABEL_235;
        }
        goto LABEL_227;
      }
      if ( v45 != 1 )
      {
        if ( v45 > 1 && v45 <= 3 )
        {
          if ( v45 == 2 )
            v46 = v21->pMonsterInfo.uSpell1ID;
          else
            v46 = v21->pMonsterInfo.uSpell2ID;
          if ( v46 )
          {
            if ( v84 )
            {
              if ( v45 == 2 )
                Actor::_403854(v32, a2, &pDir);
              else
                Actor::_403A60(v32, a2, &pDir);
              goto LABEL_254;
            }
            if ( v80 * 307.2 > (double)v81 || v82 )
            {
LABEL_217:
              v69 = &pDir;
LABEL_218:
              v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
LABEL_219:
              v51 = a2;
              v64 = (signed __int64)v47;
              v52 = v32;
LABEL_247:
              Actor::_403EB6(v52, v51, v64, v69);
              goto LABEL_254;
            }
            v69 = &pDir;
            v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
            goto LABEL_225;
          }
          v48 = v80 * 307.2;
          if ( (double)v81 >= v48 )
          {
            if ( v81 >= 1024 )
            {
              v50 = v82 == 0;
LABEL_215:
              if ( !v50 )
                goto LABEL_217;
              v71 = &pDir;
              v63 = 256;
LABEL_240:
              Actor::_402686(v32, a2, v63, v71);
              goto LABEL_254;
            }
            if ( v82 )
              goto LABEL_217;
            v70 = (signed __int64)v48;
            v62 = &pDir;
            v59 = 0;
            goto LABEL_237;
          }
          v49 = v84 == 0;
          goto LABEL_209;
        }
LABEL_241:
        if ( !v21->pMonsterInfo.uMovementType )
        {
          v68 = 0;
          v61 = 1024;
LABEL_252:
          v41 = v32;
          v40 = 4;
LABEL_253:
          Actor::_4032B2(v41, v40, v61, v68);
          goto LABEL_254;
        }
        if ( v21->pMonsterInfo.uMovementType == 1 )
        {
          v68 = 0;
          v61 = 2560;
          goto LABEL_252;
        }
        if ( v21->pMonsterInfo.uMovementType == 2 )
        {
          v68 = 0;
          v61 = 5120;
          goto LABEL_252;
        }
        if ( v21->pMonsterInfo.uMovementType == 4 )
        {
          v68 = 0;
          v61 = 10240;
          goto LABEL_252;
        }
        if ( v21->pMonsterInfo.uMovementType == 5 )
        {
          v57 = Actor::GetDirectionInfo(a1, 4u, &v72, 0);
          v58 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
          memcpy(&v74, v57, sizeof(v74));
          memcpy(&pDir, &v74, sizeof(pDir));
          v69 = &pDir;
          v52 = uActorID;
          v64 = (signed __int64)v58;
          v51 = 4;
          goto LABEL_247;
        }
        goto LABEL_254;
      }
      if ( !v21->pMonsterInfo.uMissleAttack2Type )
      {
        v56 = v80 * 307.2;
        if ( (double)v81 >= v56 )
        {
          if ( v81 >= 1024 )
          {
            v50 = v82 == 0;
            goto LABEL_215;
          }
LABEL_235:
          if ( v82 )
            goto LABEL_217;
          v70 = (signed __int64)v56;
          v62 = &pDir;
          v59 = 0;
LABEL_237:
          Actor::_40281C(v32, a2, v59, v62, v70);
          goto LABEL_254;
        }
LABEL_227:
        v49 = v84 == 0;
LABEL_209:
        v69 = &pDir;
        if ( v49 )
          goto LABEL_218;
        Actor::_403C6C(v32, a2, &pDir);
        goto LABEL_254;
      }
      if ( !v84 )
        goto LABEL_223;
      Actor::_40368B(v32, a2, &pDir);
LABEL_254:
      ++v78;
      if ( v78 >= ai_arrays_size )
        return;
    }
    v65 = v21->pMonsterInfo.uSpellSkillAndMastery1;
    v60 = 2;
    v33 = v21->pMonsterInfo.uSpell1ID;
    goto LABEL_146;
  }
}




//----- (0040261D) --------------------------------------------------------
int stru298::Add(__int16 uID, __int16 a3, __int16 x, __int16 y, __int16 z, char a7, char a8)
{
  int result; // eax@1

  result = this->count;
  if ( this->count < 100 )
  {
    this->pIDs[result] = uID;
    this->pXs[this->count] = x;
    this->pYs[this->count] = y;
    this->pZs[this->count] = z;
    this->field_324[this->count] = a3;
    this->field_3EC[this->count] = a8;
    result = this->count;
    this->field_450[this->count++] = a7;
  }
  return result;
}





//----- (00402CAE) --------------------------------------------------------
int stru193_math::SinCos(int angle)
{
  int v2; // eax@1

  //a2: (angle - uIntegerHalfPi)    for  sin(angle)
  //    (angle)                     for  cos(angle)

  v2 = uDoublePiMask & angle;
  
  if ( v2 > uIntegerPi )
    v2 = uIntegerDoublePi - v2;
  if ( v2 >= uIntegerHalfPi )
    return -pCosTable[uIntegerPi - v2];
  else
    return pCosTable[v2];
}














//----- (00404544) --------------------------------------------------------
signed int stru262_TurnBased::_404544()
{
  stru262_TurnBased *v1; // ebx@1
  TurnBased_QueueElem *v2; // esi@2
  Actor *v3; // edi@4
  Actor *v4; // ecx@4
  Player *v5; // eax@7
  int v6; // ecx@15
  TurnBased_QueueElem *v7; // eax@16
  TurnBased_QueueElem *v8; // ecx@18
  int v9; // edx@19
  int v10; // esi@19
  int v11; // esi@21
  int v12; // ST0C_4@25
  int v13; // ST10_4@25
  int v14; // ST14_4@25
  int v15; // ST18_4@25
  signed int result; // eax@28
  TurnBased_QueueElem *v17; // edi@32
  int v18; // [sp+20h] [bp-Ch]@17
  int v19; // [sp+24h] [bp-8h]@1
  int v20; // [sp+28h] [bp-4h]@1
  signed int v21; // [sp+28h] [bp-4h]@16
  int v22; // [sp+28h] [bp-4h]@31

  v20 = 0;
  v1 = this;
  v19 = this->uActorQueueSize;
  if ( this->uActorQueueSize > 0 )
  {
    v2 = this->pQueue;
    do
    {
      if ( (v2->uPackedID & 7) == OBJECT_Actor )
      {
        v3 = &pActors[v2->uPackedID >> 3];
        v4 = &pActors[v2->uPackedID >> 3];
        LOBYTE(v4->uAttributes) |= 0x80u;
        if ( !v4->CanAct() )
        {
          --v19;
          v2->field_4 = 1001;
          LOBYTE(v3->uAttributes) &= 0x7Fu;
        }
      }
      if ( (v2->uPackedID & 7) == OBJECT_Player)
      {
        v5 = &pParty->pPlayers[v2->uPackedID >> 3];
        if ( v5->pConditions[14]
          || v5->pConditions[16]
          || v5->pConditions[15]
          || v5->pConditions[13]
          || v5->pConditions[12]
          || v5->pConditions[2] )
        {
          --v19;
          v2->field_4 = 1001;
        }
      }
      ++v20;
      ++v2;
    }
    while ( v20 < v1->uActorQueueSize );
  }
  v6 = v1->uActorQueueSize;
  if ( v6 > 0 )
  {
    v21 = 1;
    v7 = v1->pQueue;
    do
    {
      v18 = v21;
      if ( v21 < v6 )
      {
        v8 = v7 + 1;
        do
        {
          v9 = v8->field_4;
          v10 = v7->field_4;
          if ( v9 < v10
            || v9 == v10
            && ((v11 = v8->uPackedID & 7, v11 == OBJECT_Player) && (v7->uPackedID & 7) == OBJECT_Actor
             || v11 == (v7->uPackedID & 7) && (v8->uPackedID & 0xFFFFFFF8) < (v7->uPackedID & 0xFFFFFFF8)) )
          {
            v12 = v7->uPackedID;
            v13 = v7->field_4;
            v14 = v7->uActionLength;
            v15 = v7->field_C;
            v7->uPackedID = v8->uPackedID;
            v7->field_4 = v8->field_4;
            v7->uActionLength = v8->uActionLength;
            v7->field_C = v8->field_C;
            v8->uPackedID = v12;
            v8->field_4 = v13;
            v8->uActionLength = v14;
            v8->field_C = v15;
          }
          ++v18;
          ++v8;
        }
        while ( v18 < v1->uActorQueueSize );
      }
      ++v21;
      v6 = v1->uActorQueueSize;
      ++v7;
    }
    while ( v21 - 1 < v6 );
  }
  v1->uActorQueueSize = v19;
  result = v1->pQueue[0].uPackedID;
  if ( (v1->pQueue[0].uPackedID & 7) == OBJECT_Player)
  {
    result = (result >> 3) + 1;
    uActiveCharacter = result;
    v1->field_18 |= 4u;
  }
  else
  {
    uActiveCharacter = 0;
    v1->field_18 &= 0xFFFFFFFBu;
  }
  v22 = 0;
  if ( v1->uActorQueueSize > 0 )
  {
    v17 = v1->pQueue;
    do
    {
      if ( (v17->uPackedID & 7) == OBJECT_Player)
        pParty->pPlayers[v17->uPackedID >> 3].uTimeToRecovery = (signed __int64)((double)v17->field_4 * 0.46875);
      ++v22;
      ++v17;
      result = v22;
    }
    while ( v22 < v1->uActorQueueSize );
  }
  return result;
}

//----- (0040471C) --------------------------------------------------------
void stru262_TurnBased::_40471C()
{
  if ( pParty->bTurnBasedModeOn == 1 )
  {
    if ( pTurnEngine->field_4 == 2 )
      _406457(0);
  }
}


//----- (00404828) --------------------------------------------------------
LayingItem::LayingItem()
{
  LayingItem *v1; // esi@1

  v1 = this;
  v1->field_22 = 1;
  v1->uSoundID = 0;
  v1->uFacing = 0;
  v1->vVelocity.z = 0;
  v1->vVelocity.y = 0;
  v1->vVelocity.x = 0;
  v1->uItemType = 0;
  v1->uObjectDescID = 0;
  v1->field_61 = 0;
  v1->field_60_distance_related_prolly_lod = 0;
  v1->field_20 = 0;
  v1->uSpriteFrameID = 0;
  v1->field_50 = 0;
  v1->field_4C = 0;
  v1->field_48 = 0;
  v1->field_54 = 0;
}



//----- (004059DB) --------------------------------------------------------
signed int stru262_TurnBased::Start()
{
  stru262_TurnBased *v1; // ebx@1
  unsigned int v2; // edi@1
  int v3; // esi@1
  int v4; // eax@5
  unsigned int v5; // esi@7
  Actor *v6; // edi@7
  unsigned int v7; // eax@9
  unsigned int v8; // edx@10
  unsigned __int8 v9; // zf@14
  unsigned __int8 v10; // sf@14
  unsigned __int8 v11; // of@14
  char *v12; // esi@15
  int v13; // ecx@16
  unsigned __int16 v14; // ax@17
  int v15; // ecx@18
  signed __int64 v16; // qax@19
  int v17; // edx@22
  unsigned int v18; // esi@27
  char *v19; // esi@32
  int v20; // edx@33
  char *v21; // eax@33
  int v22; // ecx@33
  int v23; // eax@34
  char *v24; // eax@34
  char *v25; // ecx@34
  int v26; // edx@34
  int v27; // eax@38
  int v28; // ecx@38
  AIDirection v30; // [sp+Ch] [bp-68h]@10
  AIDirection v31; // [sp+28h] [bp-4Ch]@10
  AIDirection a3; // [sp+44h] [bp-30h]@10
  int v33; // [sp+60h] [bp-14h]@10
  int *v34; // [sp+64h] [bp-10h]@6
  int v35; // [sp+68h] [bp-Ch]@5
  Player *v40; // [sp+6Ch] [bp-8h]@1
  int v40b;
  unsigned int v37; // [sp+70h] [bp-4h]@7

  pTurnEngine->field_18 &= 0xFFFFFFFDu;
  v1 = this;
  pEventTimer->TrackGameTime();
  pAudioPlayer->StopChannels(-1, -1);
  v2 = 0;
  pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|SOUND_EnteringAHouse|0x1), 0, 0, -1, 0, 0, 0, 0);
  v40 = pParty->pPlayers;
  dword_50C998_turnbased_icon_1A = 8 * pIconsFrameTable->pIcons[uIconID_TurnStart].uAnimLength;
  dword_50C994 = 0;
  v1->field_10 = 100;
  v1->field_0 = 0;
  v1->field_8 = 64;
  v1->field_4 = 1;
  v1->uActorQueueSize = 0;
  v3 = 0;
  do
  {
    if ( v40->CanAct() )
    {
      *(&v1->field_0 + 4 * (v1->uActorQueueSize + 2)) = 8 * v3 | OBJECT_Player;
      v1->pQueue[v1->uActorQueueSize].field_C = 2;
      v1->pQueue[v1->uActorQueueSize].uActionLength = 0;
      pParty->pTurnBasedPlayerRecoveryTimes[v1->uActorQueueSize++] = 0;
    }
    ++v40;
    ++v3;
  }
  while ( v40 <=&pParty->pPlayers[3] );
  v35 = v1->uActorQueueSize;
  v4 = v35;
  v40b = v35;
  if ( v40b < v40b + ai_arrays_size )
  {
    v34 = (int *)ai_array_4F7DB0_actor_ids;
    do
    {
      v37 = *v34;
      v5 = v37;
      v6 = &pActors[v37];
      if ( v37 != 10 )
      {
        if ( pActors[v37].CanAct() )
        {
          v7 = v6->uAttributes;
          if ( v7 & 0x8000 < 0 )
          {
            v8 = dword_4F6E08[v5];
            LOBYTE(v7) = v7 | 0x80;
            v6->uAttributes = v7;
            v33 = 8 * v5 | OBJECT_Actor;
            memcpy(&v31, Actor::GetDirectionInfo(8 * v5 | OBJECT_Actor, v8, &a3, 0), sizeof(v31));
            memcpy(&v30, &v31, sizeof(v30));
            Actor::_403F58(v37, 4, 32, &v30);
            *(&v1->field_0 + 4 * (v1->uActorQueueSize + 2)) = v33;
            v1->pQueue[v1->uActorQueueSize].field_C = 2;
            v1->pQueue[v1->uActorQueueSize++].uActionLength = 0;
          }
        }
        v4 = v35;
      }
      ++v40b;
      ++v34;
    }
    while ( v40b < v4 + ai_arrays_size );
    v2 = 0;
  }
  v11 = __OFSUB__(v1->uActorQueueSize, v2);
  v9 = v1->uActorQueueSize == v2;
  v10 = ((v1->uActorQueueSize - v2) & 0x80000000u) != 0;
  v37 = v2;
  v40b = v2;
  if ( !((unsigned __int8)(v10 ^ v11) | v9) )
  {
    v12 = (char *)&v1->pQueue[0].field_4;
    while ( 1 )
    {
      v13 = *((int *)v12 - 1) & 7;
      if ( v13 != OBJECT_Player )
        break;
      v14 = pPlayers[(*((int *)v12 - 1) >> 3) + 1]->uTimeToRecovery;
      if ( v14 != (short)v2 )
      {
        v33 = v14;
        v16 = (signed __int64)((double)v14 * 0.46875);
LABEL_20:
        *(int *)v12 = v16;
        goto LABEL_26;
      }
      v15 = v37++;
      *(&a3.uDistance + v15) = v40b;
LABEL_26:
      ++v40b;
      v12 += 16;
      if ( v40b >= v1->uActorQueueSize )
        goto LABEL_27;
    }
    if ( v13 != 3 )
    {
      *(int *)v12 = 666;
      goto LABEL_26;
    }
    v17 = rand() % 99;
    if ( v17 < 33 )
    {
      *(int *)v12 = 1;
      goto LABEL_26;
    }
    LODWORD(v16) = SHIDWORD(v16) < 66;
    LOBYTE(v16) = SHIDWORD(v16) >= 66;
    LODWORD(v16) = 2 * v16 + 3;
    goto LABEL_20;
  }
LABEL_27:
  v18 = 0;
  if ( (signed int)v37 > (signed int)v2 )
  {
    do
    {
      *(&v31.uDistance + v18) = pParty->pPlayers[*(&v1->field_0 + 4 * (*(&a3.uDistance + v18) + 2)) >> 3].GetAttackRecoveryTime(
                                  v2);
      ++v18;
    }
    while ( (signed int)v18 < (signed int)v37 );
    if ( (signed int)v37 > (signed int)v2 )
    {
      v35 = v2;
      v34 = (int *)1;
      do
      {
        v40b = (int)v34;
        if ( (signed int)v34 < (signed int)v37 )
        {
          v19 = (char *)&v31.uDistance + v35;
          do
          {
            v20 = *(int *)v19;
            v33 = 4 * v40b;
            v21 = (char *)(&v31.uDistance + v40b);
            v22 = *(int *)v21;
            if ( *(int *)v21 < v20 )
            {
              *(int *)v21 = v20;
              v23 = v33;
              *(int *)v19 = v22;
              v24 = (char *)&a3.uDistance + v23;
              v25 = (char *)&a3.uDistance + v35;
              v26 = *(int *)v24;
              *(int *)v24 = *(unsigned int *)((char *)&a3.uDistance + v35);
              *(int *)v25 = v26;
              v2 = 0;
            }
            ++v40b;
          }
          while ( v40b < (signed int)v37 );
        }
        v34 = (int *)((char *)v34 + 1);
        v35 += 4;
      }
      while ( (signed int)((char *)v34 - 1) < (signed int)v37 );
      if ( (signed int)v37 > (signed int)v2 )
      {
        do
        {
          v27 = v2 + 2;
          v28 = *(&a3.uDistance + v2++);
          v11 = __OFSUB__(v2, v37);
          v10 = ((v2 - v37) & 0x80000000u) != 0;
          v1->pQueue[v28].field_4 = v27;
        }
        while ( v10 ^ v11 );
      }
    }
  }
  return v1->_404544();
}