view SpriteObject.cpp @ 2036:a453996ed5ac

Post-build Event to copy scripts from project dir to game dir.
author Nomad
date Thu, 21 Nov 2013 14:08:35 +0200
parents c1c74df0a33e
children 7a9477135943
line wrap: on
line source

#include "BSPModel.h"
#include "SpriteObject.h"
#include "Party.h"
#include "TurnEngine.h"
#include "MapInfo.h"
#include "Math.h"
#include "ObjectList.h"
#include "Indoor.h"
#include "Outdoor.h"
#include "ParticleEngine.h"
#include "Time.h"
#include "Game.h"
#include "LOD.h"
#include "Actor.h"
#include "Events.h"
#include "Level/Decoration.h"

#include "mm7_data.h"
#include "MM7.h"








size_t uNumSpriteObjects;
std::array<SpriteObject, MAX_SPRITE_OBJECTS> pSpriteObjects;

//----- (00404828) --------------------------------------------------------
SpriteObject::SpriteObject()
{
  field_22_glow_radius_multiplier = 1;
  uSoundID = 0;
  uFacing = 0;
  vVelocity.z = 0;
  vVelocity.y = 0;
  vVelocity.x = 0;
  uType = 0;
  uObjectDescID = 0;
  field_61 = 0;
  field_60_distance_related_prolly_lod = 0;
  field_20 = 0;
  uSpriteFrameID = 0;
  spell_skill = 0;
  spell_level = 0;
  spell_id = 0;
  field_54 = 0;
}

//----- (0042F5ED) --------------------------------------------------------
int SpriteObject::Create(int yaw, int pitch, int a4, int a5)
{
  signed int v6; // ebx@2
  int v13; // ST2C_4@20
  Vec3_int_ v17; // [sp-20h] [bp-30h]@11
  int angle; // [sp+Ch] [bp-4h]@1
  int a5a; // [sp+20h] [bp+10h]@20

  angle = yaw;
  if (!uObjectDescID)
    return -1;

  v6 = 1000;
  for (uint i = 0; i < MAX_SPRITE_OBJECTS; ++i)
    if (!pSpriteObjects[i].uObjectDescID)
    {
      v6 = i;
      break;
    }

  if ( v6 >= 1000 )
    return -1;
  field_64.x = vPosition.x;
  field_64.y = vPosition.y;
  field_64.z = vPosition.z;

  assert(sizeof(SpriteObject) == 0x70);
  memcpy(&pSpriteObjects[v6], this, sizeof(*this));
  if ( a5 == 0 )
  {
    pSpriteObjects[v6].vVelocity.z = 0;
    if ( a4 )
    {
      v13 = fixpoint_mul(stru_5C6E00->Cos(angle), stru_5C6E00->Cos(pitch));
      a5a = fixpoint_mul(stru_5C6E00->Sin(angle), stru_5C6E00->Cos(pitch));
      pSpriteObjects[v6].vVelocity.x = fixpoint_mul(v13, a4);
      pSpriteObjects[v6].vVelocity.y = fixpoint_mul(a5a, a4);
      pSpriteObjects[v6].vVelocity.z = fixpoint_mul(stru_5C6E00->Sin(pitch), a4);
    }
    else
    {
      pSpriteObjects[v6].vVelocity.y = 0;
      pSpriteObjects[v6].vVelocity.x = 0;
    }
    if ( v6 >= (signed int)uNumSpriteObjects )
      uNumSpriteObjects = v6 + 1;
    return v6;
  }
  if ( a5 == 1 )
  {
    v17.x = vPosition.x;
    v17.y = vPosition.y;
    v17.z = vPosition.z;
    Vec3_int_::Rotate(24, stru_5C6E00->uIntegerHalfPi + pSpriteObjects[v6].uFacing, 0, v17, &pSpriteObjects[v6].vPosition.x,
                      &pSpriteObjects[v6].vPosition.y, &pSpriteObjects[v6].vPosition.z);
    pSpriteObjects[v6].vVelocity.z = 0;
    if ( a4 )
    {
      v13 = fixpoint_mul(stru_5C6E00->Cos(angle), stru_5C6E00->Cos(pitch));
      a5a = fixpoint_mul(stru_5C6E00->Sin(angle), stru_5C6E00->Cos(pitch));
      pSpriteObjects[v6].vVelocity.x = fixpoint_mul(v13, a4);
      pSpriteObjects[v6].vVelocity.y = fixpoint_mul(a5a, a4);
      pSpriteObjects[v6].vVelocity.z = fixpoint_mul(stru_5C6E00->Sin(pitch), a4);
    }
    else
    {
      pSpriteObjects[v6].vVelocity.y = 0;
      pSpriteObjects[v6].vVelocity.x = 0;
    }
    if ( v6 >= (signed int)uNumSpriteObjects )
      uNumSpriteObjects = v6 + 1;
    return v6;
  }
  if ( a5 == 2 )
  {
    v17.x = vPosition.x;
    v17.y = vPosition.y;
    v17.z = vPosition.z;
    Vec3_int_::Rotate(8, stru_5C6E00->uIntegerHalfPi + pSpriteObjects[v6].uFacing, 0, v17, &pSpriteObjects[v6].vPosition.x,
                      &pSpriteObjects[v6].vPosition.y, &pSpriteObjects[v6].vPosition.z);
    pSpriteObjects[v6].vVelocity.z = 0;
    if ( a4 )
    {
      v13 = fixpoint_mul(stru_5C6E00->Cos(angle), stru_5C6E00->Cos(pitch)) >> 16;
      a5a = fixpoint_mul(stru_5C6E00->Sin(angle), stru_5C6E00->Cos(pitch)) >> 16;
      pSpriteObjects[v6].vVelocity.x = fixpoint_mul(v13, a4);
      pSpriteObjects[v6].vVelocity.y = fixpoint_mul(a5a, a4);
      pSpriteObjects[v6].vVelocity.z = fixpoint_mul(stru_5C6E00->Sin(pitch), a4);
    }
    else
    {
      pSpriteObjects[v6].vVelocity.y = 0;
      pSpriteObjects[v6].vVelocity.x = 0;
    }
    if ( v6 >= (signed int)uNumSpriteObjects )
      uNumSpriteObjects = v6 + 1;
    return v6;
  }
  if ( a5 == 3 )
  {
    v17.x = vPosition.x;
    v17.y = vPosition.y;
    v17.z = vPosition.z;
    Vec3_int_::Rotate(8, pSpriteObjects[v6].uFacing - stru_5C6E00->uIntegerHalfPi, 0, v17, &pSpriteObjects[v6].vPosition.x,
                      &pSpriteObjects[v6].vPosition.y, &pSpriteObjects[v6].vPosition.z);
    pSpriteObjects[v6].vVelocity.z = 0;
    if ( a4 )
    {
      v13 = fixpoint_mul(stru_5C6E00->Cos(angle), stru_5C6E00->Cos(pitch));
      a5a = fixpoint_mul(stru_5C6E00->Sin(angle), stru_5C6E00->Cos(pitch));
      pSpriteObjects[v6].vVelocity.x = fixpoint_mul(v13, a4);
      pSpriteObjects[v6].vVelocity.y = fixpoint_mul(a5a, a4);
      pSpriteObjects[v6].vVelocity.z = fixpoint_mul(stru_5C6E00->Sin(pitch), a4);
    }
    else
    {
      pSpriteObjects[v6].vVelocity.y = 0;
      pSpriteObjects[v6].vVelocity.x = 0;
    }
    if ( v6 >= (signed int)uNumSpriteObjects )
      uNumSpriteObjects = v6 + 1;
    return v6;
  }
  if ( a5 == 4 )
  {
    v17.x = vPosition.x;
    v17.y = vPosition.y;
    v17.z = vPosition.z;
    Vec3_int_::Rotate(24, pSpriteObjects[v6].uFacing - stru_5C6E00->uIntegerHalfPi, 0, v17, &pSpriteObjects[v6].vPosition.x,
                      &pSpriteObjects[v6].vPosition.y, &pSpriteObjects[v6].vPosition.z);
    pSpriteObjects[v6].vVelocity.z = 0;
    if ( a4 )
    {
      v13 = fixpoint_mul(stru_5C6E00->Cos(angle), stru_5C6E00->Cos(pitch));
      a5a = fixpoint_mul(stru_5C6E00->Sin(angle), stru_5C6E00->Cos(pitch));
      pSpriteObjects[v6].vVelocity.x = fixpoint_mul(v13, a4);
      pSpriteObjects[v6].vVelocity.y = fixpoint_mul(a5a, a4);
      pSpriteObjects[v6].vVelocity.z = fixpoint_mul(stru_5C6E00->Sin(pitch), a4);
    }
    else
    {
      pSpriteObjects[v6].vVelocity.y = 0;
      pSpriteObjects[v6].vVelocity.x = 0;
    }
    if ( v6 >= (signed int)uNumSpriteObjects )
      uNumSpriteObjects = v6 + 1;
    return v6;
  }

  assert(false);
  return 0;
}

//----- (00471C03) --------------------------------------------------------
void SpriteObject::UpdateObject_fn0_ODM(unsigned int uLayingItemID)
{
  SpriteObject *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
  int 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_sw 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 on_water; // [sp+A0h] [bp-8h]@1
  int v60; // [sp+A4h] [bp-4h]@11

  uLayingItemID_ = uLayingItemID;
  v1 = &pSpriteObjects[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 = ODM_GetFloorLevel(v4, v3, v1->vPosition.z, v5, &on_water, &v55, 0);
  v7 = v6;
  v54 = v6;
  v8 = v6 + 1;
  if ( v1->vPosition.z <= v6 + 1 )
  {
    if ( on_water )
    {
      v9 = v6 + 60;
      if ( v55 )
        v9 = v7 + 30;
      sub_42F960_create_object(v1->vPosition.x, v1->vPosition.y, v9);
      SpriteObject::OnInteraction(uLayingItemID_);
    }
  }
  else
  {
    v58 = 1;
  }
  v10 = v2->uFlags;
  if ( !(v2->uFlags & OBJECT_DESC_NO_GRAVITY) )
  {
    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 = ((unsigned __int64)(v56 * (signed __int64)v51.x) >> 16);
      v1->vVelocity.x += fixpoint_mul(v56, v51.x);
      //v60 = ((unsigned __int64)(v56 * (signed __int64)v51.y) >> 16);
      v1->vVelocity.y += fixpoint_mul(v56, v51.y);
      //v60 = ((unsigned __int64)(v56 * (signed __int64)v51.z) >> 16);
      v1->vVelocity.z += fixpoint_mul(v56, v51.z);
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 & OBJECT_DESC_BOUNCE) || (v21 = -v1->vVelocity.z >> 1, v1->vVelocity.z = v21, (signed __int16)v21 < 10) )
      v1->vVelocity.z = 0;

    v1->vVelocity.x = fixpoint_mul(58500, v1->vVelocity.x);
    v1->vVelocity.y = fixpoint_mul(58500, v1->vVelocity.y);
    v1->vVelocity.z = fixpoint_mul(58500, v1->vVelocity.z);

    if ( (v1->vVelocity.y * v1->vVelocity.y + v1->vVelocity.x * v1->vVelocity.x) < 400 )
        {

    v1->vVelocity.y = 0;
    v1->vVelocity.x = 0;
    memset(&Dst, 0, 0x68u);
    Dst.x = (double)v1->vPosition.x;
    Dst.y = (double)v1->vPosition.y;
    Dst.z = (double)v1->vPosition.z;
    Dst.r = 0.0;
    Dst.g = 0.0;
    Dst.b = 0.0;
    if (v2->uFlags & OBJECT_DESC_TRIAL_FIRE )
    {
      Dst.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8;
      Dst.uDiffuse = 0xFF3C1E;
      Dst.timeToLive = (unsigned __int8)(rand() & 0x80) + 128;
      Dst.uTextureID = pBitmaps_LOD->LoadTexture("effpar01", TEXTURE_DEFAULT);
      Dst.flt_28 = 1.0;
      pGame->pParticleEngine->AddParticle(&Dst);
    }
    else if ( v2->uFlags & OBJECT_DESC_TRIAL_LINE)
    {

        Dst.type = ParticleType_Line;
        Dst.uDiffuse = rand();
        Dst.timeToLive = 64;
        Dst.uTextureID = 0;
        Dst.flt_28 = 1.0;
        pGame->pParticleEngine->AddParticle(&Dst);
      }
    else if ( v2->uFlags & OBJECT_DESC_TRIAL_PARTICLE )
        {
      Dst.type = ParticleType_Bitmap | ParticleType_8;
      Dst.uDiffuse = rand();
      Dst.timeToLive = (unsigned __int8)(rand() & 0x80) + 128;
      Dst.uTextureID = pBitmaps_LOD->LoadTexture("effpar03", TEXTURE_DEFAULT);
      Dst.flt_28 = 1.0;
      pGame->pParticleEngine->AddParticle(&Dst);
    }
    return;
        }
  }
LABEL_13:
  if ( v1->vPosition.z > v7
    && (v13 = v1->vPosition.x, v13 >= -0x8000)
    && v13 <= 0x8000
    && (v14 = v1->vPosition.y, v14 >= -0x8000)
    && v14 <= 0x8000
    && v1->vPosition.z <= 13000
    || !(v2->uFlags & OBJECT_DESC_INTERACTABLE) )
    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.height = v2->uHeight;
    stru_721530.field_8_radius = 0;
    stru_721530.field_70 = 0;
    while ( 1 )
    {
      stru_721530.position.x = v1->vPosition.x;
      stru_721530.normal.x = stru_721530.position.x;
      v15 = v1->vPosition.y;
      stru_721530.uSectorID = 0;
      stru_721530.position.y = v15;
      stru_721530.normal.y = v15;
      stru_721530.position.z = v1->vPosition.z + stru_721530.prolly_normal_d + 1;
      stru_721530.normal.z = stru_721530.position.z;
      stru_721530.velocity.x = v1->vVelocity.x;
      stru_721530.velocity.y = v1->vVelocity.y;
      stru_721530.velocity.z = v1->vVelocity.z;
      if ( stru_721530._47050A(0) )
        return;
      _46E889_collide_against_bmodels(0);
      v16 = WorldPosToGridCellZ(v1->vPosition.y);
      v18 = WorldPosToGridCellX(v1->vPosition.x);
      _46E26D_collide_against_sprites(v18, v16);
      if (PID_TYPE(v1->spell_caster_pid) != OBJECT_Player)
        _46EF01_collision_chech_player(0);
      if (PID_TYPE(v1->spell_caster_pid) == OBJECT_Actor)
      {
        v19 = PID_ID(v1->spell_caster_pid);
        if (( v19 >= 0 )&&( v19 < (signed int)(uNumActors - 1) ))
        {
         
            v20 = &pActors[v19];
           for (v56 =0; v56 < uNumActors; ++v56)            
              {
                if ( v20->GetActorsRelation(&pActors[v56]) )
                  Actor::_46DF1A_collide_against_actor(v56, 0);

              }
        }
      }
      else
      {
        for ( i = 0; i < (signed int)uNumActors; ++i )
          Actor::_46DF1A_collide_against_actor(i, 0);
      }
      v26 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
      v27 = ODM_GetFloorLevel(
              stru_721530.normal2.x,
              stru_721530.normal2.y,
              stru_721530.normal2.z - stru_721530.prolly_normal_d - 1,
              v2->uHeight,
              &v49,
              &v50,
              0);
      if ( on_water && v26 < v27 + 60 )
      {
        if ( v50 )
          v44 = v27 + 30;
        else
          v44 = v54 + 60;
        sub_42F960_create_object(v1->vPosition.x, v1->vPosition.y, v44);
        SpriteObject::OnInteraction(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);
        memset(&Dst, 0, 0x68u);
        Dst.x = (double)v1->vPosition.x;
        Dst.y = (double)v1->vPosition.y;
        Dst.z = (double)v1->vPosition.z;
        Dst.r = 0.0;
        Dst.g = 0.0;
        Dst.b = 0.0;
        if ( v2->uFlags & OBJECT_DESC_TRIAL_FIRE )
        {
          Dst.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8;
          Dst.uDiffuse = 0xFF3C1E;
          Dst.timeToLive = (unsigned __int8)( rand() & 0x80) + 128;
          Dst.uTextureID = pBitmaps_LOD->LoadTexture("effpar01", TEXTURE_DEFAULT);
          Dst.flt_28 = 1.0;
          pGame->pParticleEngine->AddParticle(&Dst);
          return;
        }
        else if ( v2->uFlags & OBJECT_DESC_TRIAL_LINE )
        {
          Dst.type = ParticleType_Line;
          Dst.uTextureID = 0;
          Dst.uDiffuse = rand();
          Dst.timeToLive = 64;
          Dst.flt_28 = 1.0;
          pGame->pParticleEngine->AddParticle(&Dst);
          return;
        }
        else if ( v2->uFlags & OBJECT_DESC_TRIAL_PARTICLE)
            { 
            Dst.type = ParticleType_Bitmap | ParticleType_8;
            Dst.uDiffuse = rand();         
            Dst.timeToLive = (unsigned __int8)(rand() & 0x80) + 128;
            Dst.uTextureID = pBitmaps_LOD->LoadTexture("effpar03", TEXTURE_DEFAULT);
            Dst.flt_28 = 1.0;
            pGame->pParticleEngine->AddParticle(&Dst);
            }
        return;
      }
      //v60 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.x) >> 16);
      v1->vPosition.x += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x);
      //v60 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.y) >> 16);
      v1->vPosition.y += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y);
      //v60 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.z) >> 16);
      v28 = LOWORD(stru_721530.uSectorID);
      v1->vPosition.z += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z);
      v29 = v1->vPosition.z;
      v1->uSectorID = v28;
      stru_721530.field_70 += stru_721530.field_7C;
      if ( v2->uFlags & OBJECT_DESC_INTERACTABLE )
      {
        if ( v29 < v54 )
          v1->vPosition.z = v54 + 1;
        if ( !_46BFFA_check_object_intercept(uLayingItemID_, stru_721530.uFaceID) )
          return;
      }
      v30 = (signed int)PID_ID(stru_721530.uFaceID);
      if (PID_TYPE(stru_721530.uFaceID) == OBJECT_Decoration)
        break;
      if (PID_TYPE(stru_721530.uFaceID) == 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.speed >> 3) > v56 )
            v56 = stru_721530.speed >> 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 = ((unsigned __int64)(v56 * (signed __int64)v32->pFacePlane.vNormal.z) >> 16);
          v1->vVelocity.x += 2 * v57;
          v1->vVelocity.y += 2 * v58;
          if ( v32->pFacePlane.vNormal.z <= 32000 )
          {
            v37 = 2 * (short)v60;
          }
          else
          {
            v36 = v60;
            v1->vVelocity.z += (signed __int16)v60;
            v58 = (unsigned __int64)(32000 * (signed __int64)(signed int)v36) >> 16;
            v37 = (unsigned int)(32000 * 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:
      v1->vVelocity.x = (signed __int16)((unsigned __int64)(58500i64 * (signed __int64)(signed int)v1->vVelocity.x) >> 16);
      v1->vVelocity.y = (signed __int16)((unsigned __int64)(58500i64 * (signed __int64)(signed int)v1->vVelocity.y) >> 16);
      v1->vVelocity.z = (signed __int16)((unsigned __int64)(58500i64 * (signed __int64)(signed int)v1->vVelocity.z) >> 16);

      ++v55;
      //v43 = __OFSUB__(v55, 100);
   //   v42 = v55 - 100 < 0;
      if (v55>=100 )//!(v42 ^ v43) 
        return;
    }
    v57 = integer_sqrt(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->Cos(v38);
   // v60 = v39;
    v40 = v39 * (signed __int64)v57;
    v58 = v40 >> 16;
    v1->vVelocity.x = WORD1(v40);
    v41 = stru_5C6E00->Sin(v56 - stru_5C6E00->uIntegerHalfPi);
   // v60 = v41;
    v35 = (unsigned __int64)(v41 * (signed __int64)v57) >> 16;
    v58 = v35;
LABEL_73:
    v1->vVelocity.y = v35;
    goto LABEL_74;
  }
}

//----- (0047136C) --------------------------------------------------------
void SpriteObject::UpdateObject_fn0_BLV(unsigned int uLayingItemID)
{
  SpriteObject *pSpriteObject; // esi@1
  ObjectDesc *pObject; // 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_sw 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;
  pSpriteObject = &pSpriteObjects[uLayingItemID];
  pObject = &pObjectList->pObjects[pSpriteObject->uObjectDescID];
  //v3 = pSpriteObject->vPosition.x;
  //v37 = &pObjectList->pObjects[pSpriteObject->uObjectDescID];
  pSpriteObject->uSectorID = pIndoor->GetSector(pSpriteObject->vPosition.x, pSpriteObject->vPosition.y, pSpriteObject->vPosition.z);
  v42 = BLV_GetFloorLevel(pSpriteObject->vPosition.x, pSpriteObject->vPosition.y, pSpriteObject->vPosition.z, pSpriteObject->uSectorID, &uFaceID);
  if ( abs(pSpriteObject->vPosition.x) > 32767
    || abs(pSpriteObject->vPosition.y) > 32767
    || abs(pSpriteObject->vPosition.z) > 20000
    || v42 <= -30000
    && (pSpriteObject->uSectorID == 0))
//     || (v42 = _46CEC3_get_floor_level(pSpriteObject->vPosition.x, pSpriteObject->vPosition.y, pSpriteObject->vPosition.z, v4, &uFaceID), v42 == -30000)) )
  {
    SpriteObject::OnInteraction(uLayingItemID);
    return;
  }
  v5 = pObject->uFlags;
  if ( v5 & 0x20 )
  {
LABEL_24:
    v8 = 0;
LABEL_25:
    stru_721530.field_0 = v8;
    uFaceID = v8;
    stru_721530.prolly_normal_d = pObject->uRadius;

    stru_721530.field_84 = -1;
    stru_721530.height = pObject->uHeight;
    stru_721530.field_8_radius = v8;
    stru_721530.field_70 = v8;
    while ( 1 )
    {
      stru_721530.position.x = pSpriteObject->vPosition.x;
      stru_721530.normal.x = stru_721530.position.x;
      stru_721530.position.y = pSpriteObject->vPosition.y;
      stru_721530.normal.y = stru_721530.position.y;
      stru_721530.position.z = stru_721530.prolly_normal_d + pSpriteObject->vPosition.z + 1;
      stru_721530.normal.z = stru_721530.position.z;
      stru_721530.velocity.x = pSpriteObject->vVelocity.x;
      stru_721530.velocity.y = pSpriteObject->vVelocity.y;
      stru_721530.velocity.z = pSpriteObject->vVelocity.z;
      stru_721530.uSectorID = pSpriteObject->uSectorID;
      if ( stru_721530._47050A(v8) )
        return;
      v40 = v8;
      do
      {
        _46E44E_collide_against_faces_and_portals(0);
        _46E0B2_collide_against_decorations();
        if (PID_TYPE(pSpriteObject->spell_caster_pid) != OBJECT_Player)
          _46EF01_collision_chech_player(1);
        v13 = pSpriteObject->spell_caster_pid;
        v42 = v8;
        if (PID_TYPE(v13) == OBJECT_Actor)
        {
          if ( (signed int)uNumActors > v8 )
          {
            v39b = pActors.data();//[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[pSpriteObject->spell_caster_pid >> 3].pMonsterInfo.uID != v39b->pMonsterInfo.uID )
					//not sure: pMonsterList->pMonsters[v39b->word_000086_some_monster_id-1].uToHitRadius
					Actor::_46DF1A_collide_against_actor(v42, pMonsterList->pMonsters[v39b->word_000086_some_monster_id-1].uToHitRadius);
              ++v42;
              ++v39b;// += 836;
            }
            while ( v42 < (signed int)uNumActors );
            v8 = 0;
          }
        }
        else
        {
          if ( (signed int)uNumActors > v8 )
          {
            v39b = pActors.data();//[0].word_000086_some_monster_id;
            do
            {
				Actor::_46DF1A_collide_against_actor(v42++, pMonsterList->pMonsters[v39b->word_000086_some_monster_id-1].uToHitRadius);
              ++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 )
      {
        pSpriteObject->vPosition.x = stru_721530.normal2.x;
        pSpriteObject->vPosition.y = stru_721530.normal2.y;
        pSpriteObject->vPosition.z = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
        pSpriteObject->uSectorID = LOWORD(stru_721530.uSectorID);
        if ( !(HIBYTE(pObject->uFlags) & 1) )
          return;
        memset(&Dst, v8, 0x68u);
        v29 = pObject->uFlags;
        Dst.x = (double)pSpriteObject->vPosition.x;
        Dst.y = (double)pSpriteObject->vPosition.y;
        Dst.z = (double)pSpriteObject->vPosition.z;
        Dst.r = 0.0;
        Dst.g = 0.0;
        Dst.b = 0.0;
        if ( v29 & 0x200 )
        {
          Dst.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8;
          Dst.uDiffuse = 0xFF3C1E;
          v30 = rand();
          v34 = (TEXTURE_TYPE)v8;
          v32 = "effpar01";
        }
        else
        {
          if ( v29 & 0x400 )
          {
            Dst.type = ParticleType_Line;
            Dst.uDiffuse = rand();
            Dst.timeToLive = 64;
            Dst.uTextureID = v8;
            Dst.flt_28 = 1.0;
            pGame->pParticleEngine->AddParticle(&Dst);
            return;
          }
          Dst.type = ParticleType_Bitmap | ParticleType_8;
          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);
        Dst.flt_28 = 1.0;
        pGame->pParticleEngine->AddParticle(&Dst);
        return;
      }
      //v40 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.x) >> 16;
      pSpriteObject->vPosition.x += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x);
      //v40 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.y) >> 16;
      pSpriteObject->vPosition.y += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y);
      //v40 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.z) >> 16;
      pSpriteObject->vPosition.z += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z);
      pSpriteObject->uSectorID = stru_721530.uSectorID;
      stru_721530.field_70 += stru_721530.field_7C;
      if ( pObject->uFlags & 0x40 && !_46BFFA_check_object_intercept(uLayingItemID, stru_721530.uFaceID) )
        return;
      v15 = (signed int)stru_721530.uFaceID >> 3;
      if (PID_TYPE(stru_721530.uFaceID) == OBJECT_Decoration)
      {
        v40 = integer_sqrt(pSpriteObject->vVelocity.x * pSpriteObject->vVelocity.x + pSpriteObject->vVelocity.y * pSpriteObject->vVelocity.y);
        v23 = stru_5C6E00->Atan2(pSpriteObject->vPosition.x - pLevelDecorations[v15].vPosition.x,
                pSpriteObject->vPosition.y - pLevelDecorations[v15].vPosition.y);
        pSpriteObject->vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(v23), v40);
        pSpriteObject->vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(v23), v40);
      }
      else
      {
        if (PID_TYPE(stru_721530.uFaceID) != OBJECT_BModel)
          goto LABEL_64;
        stru_721530.field_84 = (signed int)PID_ID(stru_721530.uFaceID);
        v16 = &pIndoor->pFaces[v15];
        if ( v16->uPolygonType != 3 )
        {
          v42 = abs(v16->pFacePlane_old.vNormal.x * pSpriteObject->vVelocity.x + v16->pFacePlane_old.vNormal.z * pSpriteObject->vVelocity.z
                                                                    + v16->pFacePlane_old.vNormal.y * pSpriteObject->vVelocity.y) >> 16;
          if ( (stru_721530.speed >> 3) > v42 )
            v42 = stru_721530.speed >> 3;
          pSpriteObject->vVelocity.x += 2 * fixpoint_mul(v42, v16->pFacePlane_old.vNormal.x);
          pSpriteObject->vVelocity.y += 2 * fixpoint_mul(v42, v16->pFacePlane_old.vNormal.y);
          v39 = fixpoint_mul(v42, v16->pFacePlane_old.vNormal.z);
          if ( v16->pFacePlane_old.vNormal.z <= 32000 )
          {
            v22 = 2 * v39;
          }
          else
          {
            pSpriteObject->vVelocity.z += v39;
            v22 = fixpoint_mul(32000, v39);
          }
          pSpriteObject->vVelocity.z += v22;
          if ( BYTE3(v16->uAttributes) & 0x10 )
            EventProcessor(pIndoor->pFaceExtras[v16->uFaceExtraID].uEventID, 0, 1);
          goto LABEL_63;
        }
        if ( pObject->uFlags & 0x80 )
        {
          v17 = -pSpriteObject->vVelocity.z >> 1;
          pSpriteObject->vVelocity.z = v17;
          if ( (signed __int16)v17 < 10 )
            pSpriteObject->vVelocity.z = 0;
          if ( BYTE3(v16->uAttributes) & 0x10 )
            EventProcessor(pIndoor->pFaceExtras[v16->uFaceExtraID].uEventID, 0, 1);
          goto LABEL_63;
        }
        v18 = pSpriteObject->vVelocity.y;
        v19 = pSpriteObject->vVelocity.x;
        pSpriteObject->vVelocity.z = 0;
        if ( v19 * v19 + v18 * v18 >= 400 )
        {
          if ( BYTE3(v16->uAttributes) & 0x10 )
            EventProcessor(pIndoor->pFaceExtras[v16->uFaceExtraID].uEventID, 0, 1);
          goto LABEL_63;
        }
        v20 = pIndoor->pVertices;
        pSpriteObject->vVelocity.z = 0;
        pSpriteObject->vVelocity.y = 0;
        pSpriteObject->vVelocity.x = 0;
        pSpriteObject->vPosition.z = v20[*v16->pVertexIDs].z + 1;
      }
LABEL_63:
      //v2 = v37;
LABEL_64:
      pSpriteObject->vVelocity.x = fixpoint_mul(58500, pSpriteObject->vVelocity.x);
      pSpriteObject->vVelocity.y = fixpoint_mul(58500, pSpriteObject->vVelocity.y);
      pSpriteObject->vVelocity.z = fixpoint_mul(58500, pSpriteObject->vVelocity.z);
      ++uFaceID;
      v28 = __OFSUB__(uFaceID, 100);
      v27 = uFaceID - 100 < 0;
      if ( !(v27 ^ v28) )
        return;
      v8 = 0;
    }
  }
  if ( v42 <= pSpriteObject->vPosition.z - 3 )
  {
    pSpriteObject->vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength();
    goto LABEL_24;
  }
  if ( !(v5 & 0x40) || _46BFFA_check_object_intercept(uLayingItemID, 0) )
  {
    v6 = pIndoor->pFaces;
    pSpriteObject->vPosition.z = v42 + 1;
    v7 = &v6[uFaceID];
    if ( v7->uPolygonType == 3 )
    {
      v8 = 0;
      pSpriteObject->vVelocity.z = 0;
    }
    else
    {
      if ( v7->pFacePlane_old.vNormal.z < 45000 )
        pSpriteObject->vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength();
      v8 = 0;
    }
    pSpriteObject->vVelocity.x = fixpoint_mul(58500, pSpriteObject->vVelocity.x);
    pSpriteObject->vVelocity.y = fixpoint_mul(58500, pSpriteObject->vVelocity.y);
    pSpriteObject->vVelocity.z = fixpoint_mul(58500, pSpriteObject->vVelocity.z);
    v9 = pSpriteObject->vVelocity.x;
    if ( v9 * v9 + pSpriteObject->vVelocity.y * pSpriteObject->vVelocity.y < 400 )
    {
      pSpriteObject->vVelocity.z = v8;
      pSpriteObject->vVelocity.y = v8;
      pSpriteObject->vVelocity.x = v8;
      if ( !(pObject->uFlags & 1) )
        return;
      memset(&Dst, v8, 0x68u);
      v10 = pObject->uFlags;
      Dst.x = (double)pSpriteObject->vPosition.x;
      Dst.y = (double)pSpriteObject->vPosition.y;
      Dst.z = (double)pSpriteObject->vPosition.z;
      Dst.r = 0.0;
      Dst.g = 0.0;
      Dst.b = 0.0;
      if ( v10 & 0x200 )
      {
        Dst.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8;
        Dst.uDiffuse = 0xFF3C1E;
        Dst.flt_28 = 1.0;
        v11 = rand();
        v33 = (TEXTURE_TYPE)v8;
        v31 = "effpar01";
      }
      else
      {
        if ( v10 & 0x400 )
        {
          Dst.type = ParticleType_Line;
          Dst.uDiffuse = rand();
          Dst.timeToLive = 64;
          Dst.uTextureID = v8;
          Dst.flt_28 = 1.0;
          pGame->pParticleEngine->AddParticle(&Dst);
          return;
        }
        Dst.type = ParticleType_Bitmap | ParticleType_8;
        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);
      pGame->pParticleEngine->AddParticle(&Dst);
      return;
    }
    goto LABEL_25;
  }
}
// 46DF1A: using guessed type int __fastcall 46DF1A_collide_against_actor(int, int);

//----- (00438E35) --------------------------------------------------------
void SpriteObject::ExplosionTraps()
{
  MapInfo *pMapInfo; // esi@1
  int dir_x; // ebx@1
  int v7; // edx@2
  unsigned int v10; // eax@7
  signed int v11; // ebx@8
  signed int v13; // edi@20
  int dir_y; // [sp+Ch] [bp-Ch]@1
  int dir_z; // [sp+10h] [bp-8h]@1
  DAMAGE_TYPE pDamageType; // [sp+14h] [bp-4h]@14

  pMapInfo = &pMapStats->pInfos[pMapStats->GetMapInfo(pCurrentMapName)];
  dir_x = abs(pParty->vPosition.x - this->vPosition.x);
  dir_y = abs(pParty->vPosition.y - this->vPosition.y);
  dir_z = abs(pParty->vPosition.z + pParty->sEyelevel - this->vPosition.z);
  if ( dir_x < dir_y )
  {
    v7 = dir_x;
    dir_x = dir_y;
    dir_y = v7;
  }
  if ( dir_x < dir_z )
  {
    v7 = dir_x;
    dir_x = dir_z;
    dir_z = v7;
  }
  if ( dir_y < dir_z )
  {
    v7 = dir_z;
    dir_z = dir_y;
    dir_y = v7;
  }
  v10 = ((unsigned int)(11 * dir_y) >> 5) + (dir_z / 4) + dir_x;
  if ( (signed int)v10 <= 768 )
  {
    v11 = 5;
    if ( pMapInfo->Trap_D20 )
    {
      for ( uint i = 0; i < pMapInfo->Trap_D20; ++i )
        v11 += rand() % 20 + 1;
    }
    switch ( this->uType )
    {
      case 811:
        pDamageType = DMGT_FIRE;
        break;
      case 812:
        pDamageType = DMGT_ELECTR;
        break;
      case 813:
        pDamageType = DMGT_COLD;
        break;
      case 814:
        pDamageType = DMGT_BODY;
        break;
      default:
        return;
    }
    for ( uint i = 1; i <= 4; ++i )
    {
      if ( pPlayers[i]->CanAct() && (v13 = pPlayers[i]->GetPerception() + 20, rand() % v13 > 20) )
        pPlayers[i]->PlaySound(SPEECH_6, 0);
      else
        pPlayers[i]->ReceiveDamage(v11, pDamageType);
    }
  }
}

//----- (0042F933) --------------------------------------------------------
void SpriteObject::OnInteraction(unsigned int uLayingItemID)
{
  pSpriteObjects[uLayingItemID].uObjectDescID = 0;
  if ( pParty->bTurnBasedModeOn == 1 )
  {
    if (pSpriteObjects[uLayingItemID].uAttributes & 4 )
    {
      pSpriteObjects[uLayingItemID].uAttributes &= 0xFFFB;
      --pTurnEngine->pending_actions;
    }
  }
}


//----- (0042FA22) --------------------------------------------------------
void CompactLayingItemsList()
    {
    int new_obj_pos=0;

    for (int i=0; i<MAX_SPRITE_OBJECTS; ++i)
        {
        if (pSpriteObjects[i].uObjectDescID)
            memcpy(&pSpriteObjects[new_obj_pos++], &pSpriteObjects[i],sizeof(SpriteObject));
        }
    uNumSpriteObjects = new_obj_pos;
    }
//----- (00408896) --------------------------------------------------------
void InitializeSpriteObjects()
{
  for (uint i = 0; i < uNumSpriteObjects; ++i)
  {
    SpriteObject* item = &pSpriteObjects[i];

    if (item->uType &&
        (item->uSoundID & 8 || pObjectList->pObjects[item->uType].uFlags & 0x10))
      SpriteObject::OnInteraction(i);
  }
}
//----- (0046BEF1) --------------------------------------------------------
void SpriteObject::_46BEF1_apply_spells_aoe()
{
  SpriteObject *v1; // edi@1
  Actor *v2; // esi@2
  __int16 v3; // fps@4
  unsigned __int8 v4; // c0@4
  unsigned __int8 v5; // c3@4
  signed int v6; // [sp+8h] [bp-4h]@1

  int v7,v8,v9,v10,v11;

  v6 = 0;
  v1 = this;
  if ( (signed int)uNumActors > 0 )
  {
    v2 = pActors.data();//[0].vPosition.y;
    do
    {
      if ( v2->CanAct() )
      {
        //UNDEF(v3);
		//.text:0046BF26                 movsx   eax, word ptr [esi-2]
		//.text:0046BF2A                 sub     eax, [edi+4]
		//.text:0046BF31                 mov     [ebp+var_8], eax
		//.text:0046BF37                 fild    [ebp+var_8]
		// v7 pushed to stack
		v7 = v2->vPosition.x - this->vPosition.x;

		//.text:0046BF2D                 movsx   ecx, word ptr [esi+2]
		v8 = v2->vPosition.z;

		//.text:0046BF34                 movsx   eax, word ptr [esi]
		//.text:0046BF3A                 sub     eax, [edi+8]
		//.text:0046BF3D                 mov     [ebp+var_8], eax
		//.text:0046BF44                 fild    [ebp+var_8]
		// v9 pushed to stack
		v9 = v2->vPosition.y - this->vPosition.y;

		//.text:0046BF40                 movsx   eax, word ptr [esi-6]
		//.text:0046BF47                 sar     eax, 1
		//.text:0046BF49                 add     eax, ecx
		//.text:0046BF4B                 sub     eax, [edi+0Ch]
		//.text:0046BF4E                 mov     [ebp+var_8], eax
		//.text:0046BF51                 fild    [ebp+var_8]
		//.text:0046BF58                 fld     st
		// v10 pushed to stack, two times
		v10 = v2->uActorHeight / 2 + v8 - this->vVelocity.y;

		//.text:0046BF54                 movsx   eax, word ptr [esi-8]
		//.text:0046BF5A                 add     eax, 100h
		//.text:0046BF63                 mov     ecx, eax
		v11 = this->vVelocity.x;

		//.text:0046BF5F                 fmul    st, st(1)
		// stack: v10*v10, v10, v9, v7
		//.text:0046BF61                 fld     st(2)
		// stack: v7, v10*v10, v10, v9, v7
		

		//.text:0046BF65                 fmul    st, st(3)
		// stack: v7*v9, v10*v10, v10, v9, v7
		
		//.text:0046BF67                 imul    ecx, eax
		v11 = v11 * v11;

		//.text:0046BF6A                 faddp   st(1), st
		// stack: v10*v10+v7*v9, v10, v9, v7
		//.text:0046BF6C                 fld     st(3)
		// stack: v7, v10*v10+v7*v9, v10, v9, v7
		//.text:0046BF6E                 fmul    st, st(4)
		// stack: v7*v7, v10*v10+v7*v9, v10, v9, v7
		//.text:0046BF70                 faddp   st(1), st
		// stack: v10*v10+v7*v9+v7*v7, v10, v9, v7
		
		//.text:0046BF72                 mov     [ebp+var_8], ecx
		//.text:0046BF75                 fild    [ebp+var_8]
		// v11 pushed to stack

		//.text:0046BF78                 fcompp
		// if ( v11 > v10*v10+v7*v9+v7*v7 )
		// stack: v10, v9, v7

		//.text:0046BF7A                 fstp    st
		// stack: v9, v7

		//.text:0046BF7C                 fnstsw  ax
		//.text:0046BF7E                 fstp    st
		// stack: v7

		//.text:0046BF80                 test    ah, 41h
		//.text:0046BF83                 fstp    st
		//.text:0046BF85                 jnz     short loc_46BFDD

		if ( v11 >= v10*v10+v7*v9+v7*v7 )
        {
          if ( stru_50C198.GetMagicalResistance(v2, 0xAu) )
          {
			  v2->pActorBuffs[v1->spell_id].Apply(
              pParty->uTimePlayed + (signed int)(signed __int64)((double)(v1->spell_level << 7) * 0.033333335),
              v1->spell_skill,
              4u,
              0,
              0);
            HIWORD(v2->uAttributes) |= 8u;
          }
        }
      }
      ++v6;
      ++v2;
    }
    while ( v6 < (signed int)uNumActors );
  }
}