changeset 2183:172cfb4ee150

CastSpell
author Ritor1
date Thu, 23 Jan 2014 23:35:10 +0600
parents e1e4a8a20b5f
children e0863f5beee0
files CastSpellInfo.cpp
diffstat 1 files changed, 343 insertions(+), 382 deletions(-) [+]
line wrap: on
line diff
--- a/CastSpellInfo.cpp	Thu Jan 23 17:31:12 2014 +0600
+++ b/CastSpellInfo.cpp	Thu Jan 23 23:35:10 2014 +0600
@@ -284,6 +284,7 @@
   int duration;
   signed int a2; // [sp+E7Ch] [bp-8h]@14
   int amount; // [sp+E80h] [bp-4h]@1
+  int obj_type;
 
   SpriteObject pSpellSprite; // [sp+DDCh] [bp-A8h]@1
 
@@ -1200,7 +1201,7 @@
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           break;
-        int obj_type = PID_TYPE(a2);
+        obj_type = PID_TYPE(a2);
         mon_id = PID_ID(a2);
         if (obj_type == OBJECT_Actor)//если закл поставить на быстрое закл., то можно указывать куда кидать метеоры
         {
@@ -1222,14 +1223,14 @@
           for ( meteor_num; meteor_num; meteor_num-- )
           {
             a2 = rand() % 1000;
-            if ( sqrt((double)(rand() % 1000) - 2500 * (double)(rand() % 1000) - 2500 + j * j + k * k) <= 1.0 )
+            if ( sqrt(((double)a2 - 2500) * ((double)a2 - 2500) + j * j + k * k) <= 1.0 )
             {
               LODWORD(v687) = 0;
               HIDWORD(v687) = 0;
             }
             else
             {
-              HIDWORD(v687) = stru_5C6E00->Atan2((signed __int64)sqrt((float)(j * j + k * k)), (double)(rand() % 1000) - 2500);
+              HIDWORD(v687) = stru_5C6E00->Atan2((signed __int64)sqrt((float)(j * j + k * k)), (double)a2 - 2500);
               LODWORD(v687) = stru_5C6E00->Atan2(j, k);
             }
             pSpellSprite.stru_24.Reset();
@@ -1240,8 +1241,8 @@
             pSpellSprite.uAttributes = 0;
             pSpellSprite.vPosition.x = dist_X;
             pSpellSprite.vPosition.y = dist_Y;
+            pSpellSprite.vPosition.z = a2 + dist_Z;
             pSpellSprite.uSectorID = 0;
-            pSpellSprite.vPosition.z = a2 + dist_Z;
             pSpellSprite.uSpriteFrameID = 0;
             pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
             pSpellSprite.spell_target_pid = v730;
@@ -1299,385 +1300,345 @@
         LODWORD(v727) = 1;
         break;
       }
-      case SPELL_AIR_WIZARD_EYE:
-		{
-			duration = 3600 * spell_level;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			for ( uint pl_id = 0; pl_id < 4; pl_id++ )
-				v169 = pOtherOverlayList->_4418B1(2000, pl_id + 100, 0, 65536);
-
-			pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)duration << 7) * 0.033333335), skill_level, 0, v169, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_AIR_FEATHER_FALL:
-		{
-			switch (skill_level)
-			{
-				case 1: LODWORD(v733) = 300 * spell_level; break;
-				case 2: LODWORD(v733) = 600 * spell_level; break;
-				case 3: LODWORD(v733) = 3600 * spell_level; break;
-				case 4: LODWORD(v733) = 3600 * spell_level; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v174 = 0;
-			do
-				pOtherOverlayList->_4418B1(2010, v174++ + 100, 0, 65536);
-			while ( v174 < 4 );
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
-
-			pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), skill_level, 0, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_AIR_SPARKS:
-		{
-			switch (skill_level)
-			{
-				case 1: amount = 3; break;
-				case 2: amount = 5; break;
-				case 3: amount = 7; break;
-				case 4: amount = 9; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			int _v726 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = spell_level;
-			pSpellSprite.spell_skill = skill_level;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-			pSpellSprite.uSectorID = pIndoor->GetSector(
-								pParty->vPosition.x,
-								pParty->vPosition.y,
-								pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			if ( pParty->bTurnBasedModeOn == 1 )
-				LOBYTE(pSpellSprite.uAttributes) |= 4u;
-			v188 = (signed int)_v726 / -2;
-			v189 = (signed int)_v726 / 2;
-			while ( v188 <= v189 )
-			{
-				pSpellSprite.uFacing = v188 + LOWORD(v715.uYawAngle);
-				if ( pSpellSprite.Create(
-						(signed __int16)(v188 + LOWORD(v715.uYawAngle)),
-						v715.uPitchAngle,
-						pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
-						pCastSpell->uPlayerID + 1) != -1
-						&& pParty->bTurnBasedModeOn == 1 )
-				    ++pTurnEngine->pending_actions;
-				v188 += _v726 / (amount - 1);
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_AIR_JUMP:
-		{
-			if ( pParty->uFlags & PARTY_FLAGS_1_FALLING)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[493], 2);  // Can't cast Jump while airborne!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				break;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v191 = 0;
-			do
-				pOtherOverlayList->_4418B1(2040, v191++ + 100, 0, 65536);
-			while ( v191 < 4 );
-			BYTE1(pParty->uFlags) |= 1u;
-			pParty->uFallSpeed = 1000;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_AIR_INVISIBILITY:
-		{
-			switch (skill_level)
-			{
-				case 1: LODWORD(v733) = 600 * spell_level; amount = spell_level; break;
-				case 2: LODWORD(v733) = 600 * spell_level; amount = 2 * spell_level; break;
-				case 3: LODWORD(v733) = 600 * spell_level; amount = 3 * spell_level; break;
-				case 4: LODWORD(v733) = 3600 * spell_level; amount = 4 * spell_level; break;
-				default:
-				assert(false);
-			}
-			if (pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW))
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[638], 2);  // There are hostile creatures nearby!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->uSpellID = 0;
-				continue;
-			}
-			if ( pPlayer->CanCastSpell(uRequiredMana) )
-			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
-
-				pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), skill_level, amount, 0, 0);
-				LODWORD(v727) = 1;
-			}
-			break;
-		}
-		case SPELL_AIR_FLY:
-		{
-			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[494], 2);  // Can not cast Fly indoors!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				break;
-			}
-			if ( !pPlayers[pCastSpell->uPlayerID + 1]->GetMaxMana() )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				break;
-			}
-			LODWORD(v733) = 3600 * spell_level;
-			if ( skill_level == 1 || skill_level == 2 || skill_level == 3 )
-				amount = 1;
-			else
-				amount = 0;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			for ( uint pl_id = 0; pl_id < 4; pl_id++)
-				pOtherOverlayList->_4418B1(2090, pl_id + 100, 0, 65536);
-			v206 = pOtherOverlayList->_4418B1(10008, 203, 0, 65536);
-			v207 = pCastSpell->uPlayerID + 1;
+      case SPELL_AIR_WIZARD_EYE://Глаз колдуна
+      {
+        duration = 3600 * spell_level;
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        for ( uint pl_id = 0; pl_id < 4; pl_id++ )
+          v169 = pOtherOverlayList->_4418B1(2000, pl_id + 100, 0, 65536);
+        pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)duration << 7) * 0.033333335), skill_level, 0, v169, 0);
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_AIR_FEATHER_FALL://Падение пёрышком
+      {
+        switch (skill_level)
+        {
+          case 1: duration = 300 * spell_level; break;
+          case 2: duration = 600 * spell_level; break;
+          case 3: duration = 3600 * spell_level; break;
+          case 4: duration = 3600 * spell_level; break;
+          default:
+            assert(false);
+        }
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        for ( uint pl_id = 0; pl_id < 4; pl_id++ )
+          pOtherOverlayList->_4418B1(2010, pl_id + 100, 0, 65536);
+        pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+        pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+        pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+        pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
-			pParty->pPartyBuffs[PARTY_BUFF_FLY].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), skill_level, amount, v206, v207);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_AIR_STARBURST:
-		{
-			//v67 = 2;
-			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[495], 2);  // Can't cast Starburst indoors!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->uSpellID = 0;
-				continue;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v208 = PID_TYPE(a2);
-			LODWORD(v725) = PID_TYPE(a2);
-			if ( v208 == 3 )
-			{
-				v209 = PID_ID(a2);
-				LODWORD(v718) = pActors[v209].vPosition.x;
-				v210 = pActors[v209].vPosition.y;
-				v211 = pActors[v209].vPosition.z;
-				v713 = v210;
-			}
-			else
-			{
-				v212 = stru_5C6E00->Cos(pParty->sRotationY);
-				LODWORD(v718) = pParty->vPosition.x + fixpoint_mul(2048, v212);
-				v213 = stru_5C6E00->Sin(pParty->sRotationY);
-				v214 = fixpoint_mul(2048, v213);
-				v211 = pParty->vPosition.z;
-				v713 = pParty->vPosition.y + v214;
-				v208 = LODWORD(v725);
-			}
-			signed int _v733 = 0;
-			*(float *)&v732 = (double)v211;
-			LODWORD(v725) = v211 + 2500;
-			v721 = 0;
-			*(float *)&y = (double)(v211 + 2500);
-			v730 = v208 == 3 ? a2 : 0;
-			for ( a2 = 20; a2; a2--)
-			{
-				v215 = rand();
-				v216 = (double)v721;
-				v217 = (double)_v733;
-				*(float *)&uRequiredMana = v217;
-				_this = (ItemGen *)(v215 % 1000);
-				*((float *)&v733 + 1) = (double)(v215 % 1000) + *(float *)&v732 - *(float *)&y;
-				*(float *)&v721 = v217 * v217;
-				//*(float *)&v726 = v216 * v216;
-				if ( sqrt(*((float *)&v733 + 1) * *((float *)&v733 + 1) + v216 * v216 + *(float *)&v721) <= 1.0 )
-				{
-					LODWORD(v685) = 0;
-					HIDWORD(v685) = 0;
-				}
-				else
-				{
-					v684 = (signed __int64)sqrt(v216 * v216 + *(float *)&v721);
-					v685 = __PAIR__(
-								stru_5C6E00->Atan2(v684, (signed __int64)*((float *)&v733 + 1)),
-								stru_5C6E00->Atan2((signed __int64)v216, (signed __int64)*(float *)&uRequiredMana));
-				}
-				pSpellSprite.stru_24.Reset();
-				pSpellSprite.spell_id = pCastSpell->uSpellID;
-				pSpellSprite.spell_level = spell_level;
-				pSpellSprite.spell_skill = skill_level;
-				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-				pSpellSprite.uAttributes = 0;
-				pSpellSprite.vPosition.x = LODWORD(v718);
-				pSpellSprite.vPosition.y = v713;
-				pSpellSprite.uSectorID = 0;
-				pSpellSprite.vPosition.z = (int)((char *)_this + LODWORD(v725));
-				pSpellSprite.uSpriteFrameID = 0;
-				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-				pSpellSprite.spell_target_pid = v730;
-				//__debugbreak();//звездопад
-				pSpellSprite.field_60_distance_related_prolly_lod = stru_50C198._427546(((int)_this) + 2500);
-				pSpellSprite.uFacing = v685;
-				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-				if ( pParty->bTurnBasedModeOn == 1 )
-				pSpellSprite.uAttributes = 4;
-				if ( pSpellSprite.Create(v685, SHIDWORD(v685), pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed, 0) != -1
-					   && pParty->bTurnBasedModeOn == 1 )
-				  ++pTurnEngine->pending_actions;
-				v721 = rand() % 1024 - 512;
-				v218 = rand();
-				//v14 = a2-- == 1;
-				_v733 = (unsigned __int64)(v218 % 1024) - 512;
-			}
-			//while ( !v14 );
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_WATER_AWAKEN:
-		{
-			switch (skill_level)
-			{
-				case 1: amount = 180 * spell_level; break;
-				case 2: amount = 3600 * spell_level; break;
-				case 3: amount = 86400 * spell_level; break;
-				case 4: amount = 0; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			for( int i=0; i < 4; i++ )
-			{
-				pPlayer = &pParty->pPlayers[i];
-				if ( skill_level == 4 )
-				{
-					if ( pPlayer->pConditions[Condition_Sleep] )
-					{
-						//*((int *)v222 + 4) = 0;
-						//*((int *)v222 + 5) = 0;
-						pPlayer->pConditions[Condition_Sleep] = 0;
-						pPlayer->PlaySound(SPEECH_103, 0);
-					}
-				}
-				else
-				{
-					v223 = pPlayer->DiscardConditionIfLastsLongerThan(
-								2u,
-								pParty->uTimePlayed - (signed int)(signed __int64)((double)(amount << 7) * 0.033333335));
-					if ( v223 )
-						pPlayer->PlaySound(SPEECH_103, 0);
-				}
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_WATER_POISON_SPRAY:
-		{
-			switch (skill_level)
-			{
-				case 1: amount = 1; break;
-				case 2: amount = 3; break;
-				case 3: amount = 5; break;
-				case 4: amount = 7; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			signed int _v733 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-			if ( amount == 1 )
-			{
-				pSpellSprite.stru_24.Reset();
-				pSpellSprite.spell_id = pCastSpell->uSpellID;
-				pSpellSprite.spell_skill = skill_level;
-				pSpellSprite.spell_level = spell_level;
-				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-				pSpellSprite.uAttributes = 0;
-				pSpellSprite.vPosition.x = pParty->vPosition.x;
-				pSpellSprite.vPosition.y = pParty->vPosition.y;
-				pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-				pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pSpellSprite.vPosition.z);
-				pSpellSprite.uSpriteFrameID = 0;
-				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-				pSpellSprite.spell_target_pid = a2;
-				pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-				pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-				if ( pParty->bTurnBasedModeOn == 1 )
-					LOBYTE(pSpellSprite.uAttributes) |= 4;
-				v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
-				if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-					++pTurnEngine->pending_actions;
-			}
-			else
-			{
-				pSpellSprite.stru_24.Reset();
-				pSpellSprite.spell_id = pCastSpell->uSpellID;
-				pSpellSprite.spell_level = spell_level;
-				pSpellSprite.spell_skill = skill_level;
-				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-				pSpellSprite.vPosition.y = pParty->vPosition.y;
-				pSpellSprite.vPosition.x = pParty->vPosition.x;
-				pSpellSprite.uAttributes = 0;
-				pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-				pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
-				pSpellSprite.uSpriteFrameID = 0;
-				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-				pSpellSprite.spell_target_pid = a2;
-				pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-				if ( pParty->bTurnBasedModeOn == 1 )
-					LOBYTE(pSpellSprite.uAttributes) |= 4u;
-				v227 = _v733 / -2;
-				signed int _y = _v733 / 2;
-				if ( _v733 / -2 <= _v733 / 2 )
-				{
-					v228 = v715.uYawAngle;
-					do
-					{
-						pSpellSprite.uFacing = v227 + v228;
-						if ( pSpellSprite.Create(
-								v227 + v228,
-								v715.uPitchAngle,
-								pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
-								pCastSpell->uPlayerID + 1) != -1
-								&& pParty->bTurnBasedModeOn == 1 )
-							++pTurnEngine->pending_actions;
-						v227 += _v733 / (amount - 1);
-					}
-					while ( v227 <= _y );
-				}
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_WATER_WATER_WALK:
-		{
+        pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(pParty->uTimePlayed + 
+          (signed int)(signed __int64)((double)(signed int)((int)duration << 7) * 0.033333335), skill_level, 0, 0, 0);
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_AIR_SPARKS://Искры
+      {
+        switch (skill_level)
+        {
+          case 1: amount = 3; break;
+          case 2: amount = 5; break;
+          case 3: amount = 7; break;
+          case 4: amount = 9; break;
+          default:
+            assert(false);
+        }
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        int _v726 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
+        pSpellSprite.stru_24.Reset();
+        pSpellSprite.spell_id = pCastSpell->uSpellID;
+        pSpellSprite.spell_level = spell_level;
+        pSpellSprite.spell_skill = skill_level;
+        pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+        pSpellSprite.vPosition.y = pParty->vPosition.y;
+        pSpellSprite.vPosition.x = pParty->vPosition.x;
+        pSpellSprite.uAttributes = 0;
+        pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+        pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y,
+                                                     pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+        pSpellSprite.uSpriteFrameID = 0;
+        pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+        pSpellSprite.spell_target_pid = a2;
+        pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+        pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+        if ( pParty->bTurnBasedModeOn == 1 )
+          LOBYTE(pSpellSprite.uAttributes) |= 4;
+        v188 = (signed int)_v726 / -2;
+        v189 = (signed int)_v726 / 2;
+        while ( v188 <= v189 )
+        {
+          pSpellSprite.uFacing = v188 + LOWORD(v715.uYawAngle);
+          if ( pSpellSprite.Create((signed __int16)(v188 + LOWORD(v715.uYawAngle)), v715.uPitchAngle,
+               pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed, pCastSpell->uPlayerID + 1) != -1
+             && pParty->bTurnBasedModeOn == 1 )
+            ++pTurnEngine->pending_actions;
+          v188 += _v726 / (amount - 1);
+        }
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_AIR_JUMP://Прыжок
+      {
+        if ( pParty->uFlags & PARTY_FLAGS_1_FALLING)
+        {
+          ShowStatusBarString(pGlobalTXT_LocalizationStrings[493], 2);  // Can't cast Jump while airborne!
+          pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+          break;
+        }
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        for ( uint pl_id = 0; pl_id < 4; pl_id++ )
+          pOtherOverlayList->_4418B1(2040, pl_id + 100, 0, 65536);
+        pParty->uFlags |= 0x100;
+        pParty->uFallSpeed = 1000;
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_AIR_INVISIBILITY://Невидимость
+      {
+        switch (skill_level)
+        {
+          case 1: duration = 600 * spell_level; amount = spell_level; break;
+          case 2: duration = 600 * spell_level; amount = 2 * spell_level; break;
+          case 3: duration = 600 * spell_level; amount = 3 * spell_level; break;
+          case 4: duration = 3600 * spell_level; amount = 4 * spell_level; break;
+          default:
+            assert(false);
+        }
+        if (pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW))
+        {
+          ShowStatusBarString(pGlobalTXT_LocalizationStrings[638], 2);  // There are hostile creatures nearby!
+          pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+          pCastSpell->uSpellID = 0;
+          continue;
+        }
+        if ( pPlayer->CanCastSpell(uRequiredMana) )
+        {
+          pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+          pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+          pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+          pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
+          pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Apply(pParty->uTimePlayed +
+                 (signed int)(signed __int64)((double)(signed int)((int)duration << 7) * 0.033333335), skill_level, amount, 0, 0);
+          LODWORD(v727) = 1;
+        }
+        break;
+      }
+      case SPELL_AIR_FLY://Полёт
+      {
+        if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+        {
+          ShowStatusBarString(pGlobalTXT_LocalizationStrings[494], 2);  // Can not cast Fly indoors!
+          pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+          break;
+        }
+        if ( !pPlayers[pCastSpell->uPlayerID + 1]->GetMaxMana() )
+        {
+          ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
+          pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+          break;
+        }
+        if ( skill_level == 1 || skill_level == 2 || skill_level == 3 )
+          amount = 1;
+        else
+          amount = 0;
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        for ( uint pl_id = 0; pl_id < 4; pl_id++)
+          pOtherOverlayList->_4418B1(2090, pl_id + 100, 0, 65536);
+        v206 = pOtherOverlayList->_4418B1(10008, 203, 0, 65536);
+        pParty->pPartyBuffs[PARTY_BUFF_FLY].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)(3600 * spell_level) << 7)
+                   * 0.033333335), skill_level, amount, v206, pCastSpell->uPlayerID + 1);
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_AIR_STARBURST://Звездопад
+      {
+        if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+        {
+          ShowStatusBarString(pGlobalTXT_LocalizationStrings[495], 2);  // Can't cast Starburst indoors!
+          pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+          pCastSpell->uSpellID = 0;
+          continue;
+        }
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        obj_type = PID_TYPE(a2);
+        mon_id = PID_ID(a2);
+        if ( obj_type == OBJECT_Actor )
+        {
+          dist_X = pActors[mon_id].vPosition.x;
+          dist_Y = pActors[mon_id].vPosition.y;
+          dist_Z = pActors[mon_id].vPosition.z;
+        }
+        else
+        {
+          dist_X = pParty->vPosition.x + fixpoint_mul(2048, stru_5C6E00->Cos(pParty->sRotationY));
+          dist_Y = pParty->vPosition.y + fixpoint_mul(2048, stru_5C6E00->Sin(pParty->sRotationY));
+          dist_Z = pParty->vPosition.z;
+        }
+        unsigned __int64 k = 0;
+        int j = 0;
+        v730 = obj_type == OBJECT_Actor ? a2 : 0;
+        for ( uint star_num = 20; star_num; star_num-- )
+        {
+          a2 = rand() % 1000;
+          if ( sqrt(((double)a2 + (double)dist_Z - (double)(dist_Z + 2500)) * ((double)a2 + (double)dist_Z - (double)(dist_Z + 2500))
+                     + j * j + k * k) <= 1.0 )
+          {
+            LODWORD(v685) = 0;
+            HIDWORD(v685) = 0;
+          }
+          else
+          {
+            HIDWORD(v685) = stru_5C6E00->Atan2((signed __int64)sqrt(j * j + k * k), ((double)a2 + (double)dist_Z - (double)(dist_Z + 2500)));
+            LODWORD(v685) = stru_5C6E00->Atan2(j, k);
+          }
+          pSpellSprite.stru_24.Reset();
+          pSpellSprite.spell_id = pCastSpell->uSpellID;
+          pSpellSprite.spell_level = spell_level;
+          pSpellSprite.spell_skill = skill_level;
+          pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+          pSpellSprite.uAttributes = 0;
+          pSpellSprite.vPosition.x = dist_X;
+          pSpellSprite.vPosition.y = dist_Y;
+          pSpellSprite.vPosition.z = (int)(a2 + (dist_Z + 2500));
+          pSpellSprite.uSectorID = 0;
+          pSpellSprite.uSpriteFrameID = 0;
+          pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+          pSpellSprite.spell_target_pid = v730;
+          pSpellSprite.field_60_distance_related_prolly_lod = stru_50C198._427546(a2 + 2500);
+          pSpellSprite.uFacing = v685;
+          pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+          if ( pParty->bTurnBasedModeOn == 1 )
+            pSpellSprite.uAttributes = 4;
+          if ( pSpellSprite.Create(v685, SHIDWORD(v685), pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed, 0) != -1
+               && pParty->bTurnBasedModeOn == 1 )
+            ++pTurnEngine->pending_actions;
+          j = rand() % 1024 - 512;
+          k = rand() % 1024 - 512;
+        }
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_WATER_AWAKEN://Пробуждение
+      {
+        switch (skill_level)
+        {
+          case 1: amount = 180 * spell_level; break;
+          case 2: amount = 3600 * spell_level; break;
+          case 3: amount = 86400 * spell_level; break;
+          case 4: amount = 0; break;
+          default:
+            assert(false);
+        }
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        for( int i=0; i < 4; i++ )
+        {
+          if ( skill_level == 4 )
+          {
+            if ( pParty->pPlayers[i].pConditions[Condition_Sleep] )
+            {
+              //*((int *)v222 + 4) = 0;
+              //*((int *)v222 + 5) = 0;
+              pParty->pPlayers[i].pConditions[Condition_Sleep] = 0;
+              pParty->pPlayers[i].PlaySound(SPEECH_103, 0);
+            }
+          }
+          else
+          {
+            if ( pParty->pPlayers[i].DiscardConditionIfLastsLongerThan(2, pParty->uTimePlayed -
+                             (signed int)(signed __int64)((double)(amount << 7) * 0.033333335)) )
+              pParty->pPlayers[i].PlaySound(SPEECH_103, 0);
+          }
+        }
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_WATER_POISON_SPRAY://Распыление яда
+      {
+        switch (skill_level)
+        {
+          case 1: amount = 1; break;
+          case 2: amount = 3; break;
+          case 3: amount = 5; break;
+          case 4: amount = 7; break;
+          default:
+            assert(false);
+        }
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        signed int _v733 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
+        if ( amount == 1 )
+        {
+          pSpellSprite.stru_24.Reset();
+          pSpellSprite.spell_id = pCastSpell->uSpellID;
+          pSpellSprite.spell_skill = skill_level;
+          pSpellSprite.spell_level = spell_level;
+          pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+          pSpellSprite.uAttributes = 0;
+          pSpellSprite.vPosition.x = pParty->vPosition.x;
+          pSpellSprite.vPosition.y = pParty->vPosition.y;
+          pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+          pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pSpellSprite.vPosition.z);
+          pSpellSprite.uSpriteFrameID = 0;
+          pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+          pSpellSprite.spell_target_pid = a2;
+          pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+          pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+          pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+          if ( pParty->bTurnBasedModeOn == 1 )
+            LOBYTE(pSpellSprite.uAttributes) |= 4;
+          v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
+          if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+            ++pTurnEngine->pending_actions;
+        }
+        else
+        {
+          pSpellSprite.stru_24.Reset();
+          pSpellSprite.spell_id = pCastSpell->uSpellID;
+          pSpellSprite.spell_level = spell_level;
+          pSpellSprite.spell_skill = skill_level;
+          pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+          pSpellSprite.vPosition.y = pParty->vPosition.y;
+          pSpellSprite.vPosition.x = pParty->vPosition.x;
+          pSpellSprite.uAttributes = 0;
+          pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+          pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+          pSpellSprite.uSpriteFrameID = 0;
+          pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+          pSpellSprite.spell_target_pid = a2;
+          pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+          pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+          if ( pParty->bTurnBasedModeOn == 1 )
+            LOBYTE(pSpellSprite.uAttributes) |= 4;
+          v227 = _v733 / -2;
+          signed int _y = _v733 / 2;
+          if ( v227 <= _y )
+          {
+            v228 = v715.uYawAngle;
+            do
+            {
+              pSpellSprite.uFacing = v227 + v228;
+              if ( pSpellSprite.Create(pSpellSprite.uFacing, v715.uPitchAngle, pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
+                         pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+                ++pTurnEngine->pending_actions;
+              v227 += _v733 / (amount - 1);
+            }
+            while ( v227 <= _y );
+          }
+        }
+        LODWORD(v727) = 1;
+       break;
+      }
+      case SPELL_WATER_WATER_WALK:
+      {
 			if ( !pPlayers[pCastSpell->uPlayerID + 1]->GetMaxMana() )
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed