diff CastSpellInfo.cpp @ 2179:f0b5ca2dfb73

_427E01_cast_spell continue
author Ritor1
date Wed, 22 Jan 2014 17:34:05 +0600
parents 0a1438c16c2b
children 17b3e40daedc
line wrap: on
line diff
--- a/CastSpellInfo.cpp	Wed Jan 22 00:05:10 2014 +0600
+++ b/CastSpellInfo.cpp	Wed Jan 22 17:34:05 2014 +0600
@@ -32,17 +32,15 @@
 //----- (00427E01) --------------------------------------------------------
 void CastSpellInfoHelpers::_427E01_cast_spell()
 {
-  int v2; // edi@1
+  int spell_level; // edi@1
   CastSpellInfo *pCastSpell; // ebx@2
   signed int v6; // eax@14
   unsigned __int16 v11; // cx@45
   unsigned __int8 v14; // zf@53
   signed int i; // esi@76
   __int16 v23; // ax@88
-  int v51; // eax@146
-  __int16 v52; // ax@153
   signed __int64 v54; // qax@164
-  Actor *v55; // edi@164
+  //Actor *v55; // edi@164
   signed __int64 v58; // qax@177
   Actor *pActor; // edi@177
   unsigned __int16 v60; // ax@184
@@ -249,17 +247,14 @@
   unsigned int v656; // [sp-4h] [bp-E88h]@639
   int v657; // [sp-4h] [bp-E88h]@807
   int v659; // [sp+0h] [bp-E84h]@123
-  int v660; // [sp+0h] [bp-E84h]@146
   Actor *v661; // [sp+0h] [bp-E84h]@164
   unsigned __int64 v663; // [sp+0h] [bp-E84h]@639
   const char *v664; // [sp+0h] [bp-E84h]@802
   int v665; // [sp+0h] [bp-E84h]@807
   int v666; // [sp+4h] [bp-E80h]@12
   PLAYER_SKILL_TYPE v667; // [sp+4h] [bp-E80h]@25
-  int v671; // [sp+4h] [bp-E80h]@146
   int v675; // [sp+4h] [bp-E80h]@800
   int v676; // [sp+4h] [bp-E80h]@807
-  //int v677; // [sp+4h] [bp-E80h]@861
   int v679[800]; // [sp+14h] [bp-E70h]@515
   AIDirection a3; // [sp+C94h] [bp-1F0h]@21
   int v681[4]; // [sp+CB0h] [bp-1D4h]@1137
@@ -297,7 +292,7 @@
   int v730; // [sp+E68h] [bp-1Ch]@53
   Player *v730b;
   ItemGen *v730c;
-  int v731; // [sp+E6Ch] [bp-18h]@48
+  int skill_level; // [sp+E6Ch] [bp-18h]@48
   signed int v732; // [sp+E70h] [bp-14h]@325
   unsigned __int64 v733; // [sp+E74h] [bp-10h]@1
   signed int a2; // [sp+E7Ch] [bp-8h]@14
@@ -305,7 +300,7 @@
 
   SpriteObject pSpellSprite; // [sp+DDCh] [bp-A8h]@1
 
-  v2 = 0;
+  spell_level = 0;
   amount = 0;
   LODWORD(v733) = 0;
   v723 = 0;
@@ -351,7 +346,7 @@
       if (PID_TYPE(a2) == OBJECT_Actor)
       {
         Actor::GetDirectionInfo(PID(OBJECT_Player, pCastSpell->uPlayerID + 1), a2, &v715, 0);
-        v2 = v723;
+        spell_level = v723;
       }
       else
       {
@@ -366,7 +361,7 @@
     {
       v11 = pCastSpell->forced_spell_skill_level;
       v723 = v11 & 0x3F; // 6 bytes
-      v2 = v723;
+      spell_level = v723;
     }
     else
     {
@@ -395,17 +390,17 @@
 
       LODWORD(v725) = v667;
       v723 = pPlayer->GetActualSkillLevel(v667) & 0x3F;
-      v2 = v723;
+      spell_level = v723;
       v11 = pPlayer->pActiveSkills[LODWORD(v725)];
     }
 
-	v731 = SkillToMastery(v11);
+    skill_level = SkillToMastery(v11);
 
     if (pCastSpell->forced_spell_skill_level)
       uRequiredMana = 0;
     else 
-      uRequiredMana = pSpellDatas[pCastSpell->uSpellID - 1].mana_per_skill[v731 - 1];
-    sRecoveryTime = pSpellDatas[pCastSpell->uSpellID - 1].recovery_per_skill[v731 - 1];
+      uRequiredMana = pSpellDatas[pCastSpell->uSpellID].mana_per_skill[skill_level - 1];
+    sRecoveryTime = pSpellDatas[pCastSpell->uSpellID].recovery_per_skill[skill_level - 1];
 
     if (LODWORD(v725) == PLAYER_SKILL_DARK && pParty->uCurrentHour == 0 && pParty->uCurrentMinute == 0 ||
         LODWORD(v725) == PLAYER_SKILL_LIGHT && pParty->uCurrentHour == 12 && pParty->uCurrentMinute == 0)
@@ -413,30 +408,22 @@
 
     if (pCastSpell->uSpellID < SPELL_BOW_ARROW && pPlayer->sMana < uRequiredMana)
     {
-      ShowStatusBarString(pGlobalTXT_LocalizationStrings[586], 2u); // "Not enough spell points"
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[586], 2); // "Not enough spell points"
       pCastSpell->uSpellID = 0;
       continue;
     }
     v730 = pCastSpell->uSpellID;
-    if (pPlayer->IsCursed() && pCastSpell->uSpellID < SPELL_BOW_ARROW && rand() % 100 < 50)
+    if (pPlayer->IsCursed() && pCastSpell->uSpellID < SPELL_BOW_ARROW && rand() % 100 < 50)//неудачное кастование
     {
       if (!pParty->bTurnBasedModeOn)
-      {
-        //v646 = pPlayer;
         pPlayer->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
-        //v647 = n;
-      }
       else
       {
-        //v647 = n;
-        //v646 = pPlayer;
-        //v648 = sRecoveryTime;
-        //v649 = pPlayer;
         pParty->pTurnBasedPlayerRecoveryTimes[pCastSpellInfo[n].uPlayerID] = 100;
         pPlayer->SetRecoveryTime(sRecoveryTime);
         pTurnEngine->ApplyPlayerAction();
       }
-      ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u); // "Spell failed"
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // "Spell failed"
       pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
       pCastSpellInfo[n].uSpellID = 0;
       pPlayer->sMana -= uRequiredMana;
@@ -445,454 +432,411 @@
 
     switch ( pCastSpell->uSpellID )
     {
-		case SPELL_101:
-			assert(false && "Unknown spell effect #101 (prolly flaming bow arrow");
-		case SPELL_BOW_ARROW:
-		{
-			amount = 1;
-			if ( SkillToMastery(pPlayer->pActiveSkills[PLAYER_SKILL_BOW]) >= 3 )
-				amount = 2;
-			sRecoveryTime = pPlayer->GetAttackRecoveryTime(true);
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			if ( pPlayer->WearsItem(ITEM_ARTEFACT_ULLYSES, EQUIP_BOW) )
-				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(0xBD6u);
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-			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);
-			pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
-			memcpy(&pSpellSprite.stru_24, &pPlayer->pInventoryItemList[pPlayer->pEquipment.uBow-1], sizeof(pSpellSprite.stru_24));
-			pSpellSprite.uAttributes = 256;
-			if ( pParty->bTurnBasedModeOn == 1 )
-				pSpellSprite.uAttributes = 260;
-			for ( i = 0; i < amount; ++i )
-			{
-				if ( i )
-					pSpellSprite.vPosition.z += 32;
-				pSpellSprite.uSectorID = pIndoor->GetSector(pSpellSprite.vPosition.x, pSpellSprite.vPosition.y, pSpellSprite.vPosition.z);
-				if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
-					pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-				++pTurnEngine->pending_actions;
-			}
-			break;
-		}
-		case SPELL_LASER_PROJECTILE:
-		{
-			sRecoveryTime = pPlayer->GetAttackRecoveryTime(0);
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v723;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
-			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);
-			pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
-			memcpy(&pSpellSprite.stru_24, &pPlayer->pInventoryItemList[pPlayer->pEquipment.uMainHand-1],sizeof(pSpellSprite.stru_24));
-			//	&pParty->pPlayers[pCastSpell->uPlayerID].spellbook.pDarkSpellbook.bIsSpellAvailable[36
-			//		* pParty->pPlayers[pCastSpell->uPlayerID].pEquipment.uMainHand + 5], );
-			v23 = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pSpellSprite.vPosition.z);
-			HIBYTE(pSpellSprite.uAttributes) |= 1u;
-			pSpellSprite.uSectorID = v23;
-			if ( pParty->bTurnBasedModeOn == 1 )
-				LOBYTE(pSpellSprite.uAttributes) |= 4u;
-			if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
-					pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-				++pTurnEngine->pending_actions;
-			break;
-		}
-		case SPELL_FIRE_TORCH_LIGHT:
-		{
-			switch (v731)
-			{
-				case 1: amount = 2; break;
-				case 2: amount = 3; break;
-				case 3:
-				case 4: amount = 4; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)3600 * v2 * 4.2666669), v731, amount, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_FIRE_FIRE_SPIKE:
-		{
-			switch (v731)
-			{
-				case 1: amount = 3; break;
-				case 2: amount = 5; break;
-				case 3: amount = 7; break;
-				case 4: amount = 9; break;
-				default:
-				assert(false);
-			}
-
-			//v31 = v3->uPlayerID;
-			//v32 = 8 * v31;
-			//LOBYTE(v32) = v32 | OBJECT_Player;
-
-			//if ( (signed int)uNumSpriteObjects > 0 )
-			int _v733 = 0;
-			for (uint i = 0; i < uNumSpriteObjects; ++i)
-			{
-				SpriteObject* object = &pSpriteObjects[i];
-				if (object->uType && object->spell_id == SPELL_FIRE_FIRE_SPIKE && object->spell_caster_pid == PID(OBJECT_Player, pCastSpell->uPlayerID))
-				++_v733;
-				/*v33 = (char *)&pSpriteObjects[0].field_48;
-				v730 = uNumSpriteObjects;
-				do
-				{
-				if ( *((short *)v33 - 36) && *(int *)v33 == 7 && *((int *)v33 + 4) == v32 )
-					++HIDWORD(v733);
-				v33 += 112;
-				--v730;
-				}
-				while ( v730 );*/
-			}
-			if (_v733 > amount)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->uSpellID = 0;
-				continue;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			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.uFacing = LOWORD(v715.uYawAngle);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			if ( pParty->bTurnBasedModeOn == 1 )
-				LOBYTE(pSpellSprite.uAttributes) |= 4u;
-			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
-			if ( pSpellSprite.Create(pParty->sRotationY, pParty->sRotationX + 10, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-				++pTurnEngine->pending_actions;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_AIR_IMPLOSION:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			if (!a2)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->uSpellID = 0;
-				continue;
-			}
-			if (PID_TYPE(a2) != OBJECT_Actor)
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			v697.x = 0;
-			v697.y = 0;
-			v697.z = 0;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.field_60_distance_related_prolly_lod = 0;
-			pSpellSprite.uFacing = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
-			pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
-			pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
-			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, PID_ID(a2));
-			int obj_id = pSpellSprite.Create(0, 0, 0, 0);
-			DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v697);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_EARTH_MASS_DISTORTION:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			if ( !stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 3u) )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			pActors[PID_ID(a2)].pActorBuffs[ACTOR_BUFF_MASS_DISTORTION].Apply(pMiscTimer->uTotalGameTimeElapsed + 128, 0, 0, 0, 0);
-			v704.x = 0;
-			v704.y = 0;
-			v704.z = 0;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.field_60_distance_related_prolly_lod = 0;
-			pSpellSprite.uFacing = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
-			pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
-			pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
-			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, PID_ID(a2));
-			int obj_id = pSpellSprite.Create(0, 0, 0, 0);
-			DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v704);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_LIGHT_DESTROY_UNDEAD:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) || !a2 || PID_TYPE(a2) != OBJECT_Actor)
-				break;
-			//v730 = a2 >> 3;
-			//HIDWORD(v733) = (int)&pActors[PID_ID(a2)];
-			v691.x = 0;
-			v691.y = 0;
-			v691.z = 0;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
-			pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
-			pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = pIndoor->GetSector(pSpellSprite.vPosition.x, pSpellSprite.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.uAttributes |= 0x80u;
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			int obj_id = pSpellSprite.Create(0, 0, 0, 0);
-			if ( !MonsterStats::BelongsToSupertype(pActor->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->uSpellID = 0;
-				continue;
-			}
-			DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v691);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_FIRE_FIRE_BOLT:
-		case SPELL_FIRE_FIREBALL:
-		case SPELL_FIRE_INCINERATE:
-		case SPELL_AIR_LIGHNING_BOLT:
-		case SPELL_WATER_ICE_BOLT:
-		case SPELL_WATER_ICE_BLAST:
-		case SPELL_EARTH_STUN:
-		case SPELL_EARTH_DEADLY_SWARM:
-		case SPELL_MIND_MIND_BLAST:
-		case SPELL_MIND_PSYCHIC_SHOCK:
-		case SPELL_BODY_HARM:
-		case SPELL_LIGHT_LIGHT_BOLT:
-		case SPELL_DARK_DRAGON_BREATH:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			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;
-			if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
-				pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
-			else
-				pSpellSprite.uSectorID = 0;
-			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) |= 4u;
-			if ( pCastSpell->uSpellID == SPELL_AIR_LIGHNING_BOLT )
-				LOBYTE(pSpellSprite.uAttributes) |= 0x40u;
-			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;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_WATER_ACID_BURST:
-		case SPELL_EARTH_BLADES:
-		case SPELL_BODY_FLYING_FIST:
-		case SPELL_DARK_TOXIC_CLOUD:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			v51 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			v671 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
-			v660 = pParty->vPosition.y;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.vPosition.z = v51;
-			v52 = pIndoor->GetSector(pParty->vPosition.x, v660, v671);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.uSectorID = v52;
-			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) |= 4u;
-			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;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_LIGHT_SUNRAY:
-		{
-			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor
-				|| uCurrentlyLoadedLevelType == LEVEL_Outdoor && (pParty->uCurrentHour < 5 || pParty->uCurrentHour >= 21) )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->uSpellID = 0;
-				continue;
-			}
-			if ( pPlayer->CanCastSpell(uRequiredMana) )
-			{
-				pSpellSprite.stru_24.Reset();
-				pSpellSprite.spell_id = pCastSpell->uSpellID;
-				pSpellSprite.spell_skill = v731;
-				pSpellSprite.spell_level = v2;
-				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-				pSpellSprite.vPosition.y = pParty->vPosition.y;
-				v51 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-				v671 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-				v660 = pParty->vPosition.y;
-				pSpellSprite.uAttributes = 0;
-				pSpellSprite.vPosition.x = pParty->vPosition.x;
-				pSpellSprite.vPosition.z = v51;
-				v52 = pIndoor->GetSector(pParty->vPosition.x, v660, v671);
-				pSpellSprite.uSpriteFrameID = 0;
-				pSpellSprite.uSectorID = v52;
-				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) |= 4u;
-				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;
-				LODWORD(v727) = 1;
-			}
-			break;
-		}
-		case SPELL_LIGHT_PARALYZE:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			if (PID_TYPE(a2) != OBJECT_Actor || (v730 = PID_ID(a2), v721 = (int)&pActors[PID_ID(a2)],
-					!stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 9)) )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			Actor::AI_Stand(PID_ID(a2), 4u, 0x80u, 0);
-			v54 = (signed __int64)((double)(23040 * v2) * 0.033333335);
-			v55 = &pActors[PID_ID(a2)];
-			v55->pActorBuffs[ACTOR_BUFF_PARALYZED].Apply(pParty->uTimePlayed + (signed int)v54, v731, 0, 0, 0);
-			BYTE2(v55->uAttributes) |= 8u;
-			v55->vVelocity.x = 0;
-			//v672 = 0;
-			v55->vVelocity.y = 0;
-			v661 = v55;
-			pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_EARTH_SLOW:
-		{
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 180 * v2; amount = 2; break;
-				case 2: LODWORD(v733) = 300 * v2; amount = 2; break;
-				case 3: LODWORD(v733) = 300 * v2; amount = 4; break;
-				case 4: LODWORD(v733) = 300 * v2; amount = 8; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			if (PID_TYPE(a2) != OBJECT_Actor
-				|| (v721 = 836 * PID_ID(a2),
-					LODWORD(v718) = (int)&pActors[PID_ID(a2)],
-					!stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 3u)) )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			v58 = (signed __int64)((double)(23040 * v2) * 0.033333335);
-			//v59 = v721;
-			pActor = &pActors[PID_ID(a2)];
-			//((SpellBuff *)((char *)&pActors[0].pActorBuffs[ACTOR_BUFF_SLOWED] + v721))->Apply(
-			pActor->pActorBuffs[ACTOR_BUFF_SLOWED].Apply(pParty->uTimePlayed + (signed int)v58,	v731, amount, 0, 0);
-			//*((char *)&pActors[0].uAttributes + v59 + 2) |= 8u;
-			BYTE2(pActor->uAttributes) |= 8u;
-			//v672 = 0;
-			v661 = (Actor *)LODWORD(v718);
-			pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, 0);
-			LODWORD(v727) = 1;
-			break;
+      case SPELL_101:
+        assert(false && "Unknown spell effect #101 (prolly flaming bow arrow");
+      case SPELL_BOW_ARROW://стрельба из лука
+      {
+        amount = 1;
+        if ( SkillToMastery(pPlayer->pActiveSkills[PLAYER_SKILL_BOW]) >= 3 )
+          amount = 2;
+        sRecoveryTime = pPlayer->GetAttackRecoveryTime(true);
+        pSpellSprite.stru_24.Reset();
+        pSpellSprite.spell_level = spell_level;
+        pSpellSprite.spell_id = pCastSpell->uSpellID;
+        pSpellSprite.spell_skill = skill_level;
+        pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+        if ( pPlayer->WearsItem(ITEM_ARTEFACT_ULLYSES, EQUIP_BOW) )
+          pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(0xBD6u);
+        pSpellSprite.vPosition.x = pParty->vPosition.x;
+        pSpellSprite.vPosition.y = pParty->vPosition.y;
+        pSpellSprite.uAttributes = 0;
+        pSpellSprite.uSpriteFrameID = 0;
+        pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+        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);
+        pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
+        memcpy(&pSpellSprite.stru_24, &pPlayer->pInventoryItemList[pPlayer->pEquipment.uBow-1], sizeof(pSpellSprite.stru_24));
+        pSpellSprite.uAttributes = 256;
+        if ( pParty->bTurnBasedModeOn == 1 )
+          pSpellSprite.uAttributes = 260;
+        for ( i = 0; i < amount; ++i )
+        {
+          if ( i )
+            pSpellSprite.vPosition.z += 32;
+          pSpellSprite.uSectorID = pIndoor->GetSector(pSpellSprite.vPosition.x, pSpellSprite.vPosition.y, pSpellSprite.vPosition.z);
+          if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
+            pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+          ++pTurnEngine->pending_actions;
+        }
+        break;
+      }
+      case SPELL_LASER_PROJECTILE://стрельба из бластера
+      {
+        sRecoveryTime = pPlayer->GetAttackRecoveryTime(0);
+        pSpellSprite.stru_24.Reset();
+        pSpellSprite.spell_id = pCastSpell->uSpellID;
+        pSpellSprite.spell_level = v723;
+        pSpellSprite.spell_skill = skill_level;
+        pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+        pSpellSprite.vPosition.x = pParty->vPosition.x;
+        pSpellSprite.vPosition.y = pParty->vPosition.y;
+        pSpellSprite.uAttributes = 0;
+        pSpellSprite.uSpriteFrameID = 0;
+        pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
+        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);
+        pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
+        memcpy(&pSpellSprite.stru_24, &pPlayer->pInventoryItemList[pPlayer->pEquipment.uMainHand - 1],sizeof(pSpellSprite.stru_24));
+        //	&pParty->pPlayers[pCastSpell->uPlayerID].spellbook.pDarkSpellbook.bIsSpellAvailable[36
+        //		* pParty->pPlayers[pCastSpell->uPlayerID].pEquipment.uMainHand + 5], );
+        pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pSpellSprite.vPosition.z);
+        HIBYTE(pSpellSprite.uAttributes) |= 1;
+        if ( pParty->bTurnBasedModeOn == 1 )
+          LOBYTE(pSpellSprite.uAttributes) |= 4;
+        if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
+                                 pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+          ++pTurnEngine->pending_actions;
+        break;
+      }
+      case SPELL_FIRE_TORCH_LIGHT://свет факела
+      {
+        switch (skill_level)
+        {
+          case 1: amount = 2; break;
+          case 2: amount = 3; break;
+          case 3:
+          case 4: amount = 4; break;
+          default:
+            assert(false);
+        }
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)3600 * spell_level * 4.2666669), skill_level, amount, 0, 0);
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_FIRE_FIRE_SPIKE://огненный шип
+      {
+        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);
+        }
+        int _v733 = 0;
+        for (uint i = 0; i < uNumSpriteObjects; ++i)
+        {
+          SpriteObject* object = &pSpriteObjects[i];
+          if (object->uType && object->spell_id == SPELL_FIRE_FIRE_SPIKE && object->spell_caster_pid == PID(OBJECT_Player, pCastSpell->uPlayerID))
+            ++_v733;
+        }
+        if ( _v733 > amount )
+        {
+          ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+          pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+          pCastSpell->uSpellID = 0;
+          continue;
+        }
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        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.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(pParty->sRotationY, pParty->sRotationX + 10, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+          ++pTurnEngine->pending_actions;
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_AIR_IMPLOSION://Точечный взрыв
+      {
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        if (!a2)
+        {
+          ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+          pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+          pCastSpell->uSpellID = 0;
+          continue;
+        }
+        if (PID_TYPE(a2) == OBJECT_Actor)
+        {
+          v697.x = 0;
+          v697.y = 0;
+          v697.z = 0;
+          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.uSectorID = 0;
+          pSpellSprite.uSpriteFrameID = 0;
+          pSpellSprite.field_60_distance_related_prolly_lod = 0;
+          pSpellSprite.uFacing = 0;
+          pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+          pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+          pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
+          pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
+          pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
+          pSpellSprite.spell_target_pid = PID(OBJECT_Actor, PID_ID(a2));
+          int obj_id = pSpellSprite.Create(0, 0, 0, 0);
+          DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v697);
+        }
+        LODWORD(v727) = 1;
+        break;
       }
-		case SPELL_MIND_CHARM:
+      case SPELL_EARTH_MASS_DISTORTION://Изменение веса
+      {
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        if ( stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 3) )
+        {
+          pActors[PID_ID(a2)].pActorBuffs[ACTOR_BUFF_MASS_DISTORTION].Apply(pMiscTimer->uTotalGameTimeElapsed + 128, 0, 0, 0, 0);
+          v704.x = 0;
+          v704.y = 0;
+          v704.z = 0;
+          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.uSectorID = 0;
+          pSpellSprite.uSpriteFrameID = 0;
+          pSpellSprite.field_60_distance_related_prolly_lod = 0;
+          pSpellSprite.uFacing = 0;
+          pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+          pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+          pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
+          pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
+          pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
+          pSpellSprite.spell_target_pid = PID(OBJECT_Actor, PID_ID(a2));
+          int obj_id = pSpellSprite.Create(0, 0, 0, 0);
+          DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v704);
+        }
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_LIGHT_DESTROY_UNDEAD://Уничтожение нежити
+      {
+        if ( !pPlayer->CanCastSpell(uRequiredMana) || !a2 || PID_TYPE(a2) != OBJECT_Actor)
+          break;
+        //v730 = a2 >> 3;
+        //HIDWORD(v733) = (int)&pActors[PID_ID(a2)];
+        v691.x = 0;
+        v691.y = 0;
+        v691.z = 0;
+        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.x = pActors[PID_ID(a2)].vPosition.x;
+        pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
+        pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
+        pSpellSprite.uAttributes = 0;
+        pSpellSprite.uSectorID = pIndoor->GetSector(pSpellSprite.vPosition.x, pSpellSprite.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.uAttributes |= 0x80u;
+        pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+        int obj_id = pSpellSprite.Create(0, 0, 0, 0);
+        if ( !MonsterStats::BelongsToSupertype(pActor->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
+        {
+          ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+          pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+          pCastSpell->uSpellID = 0;
+          continue;
+        }
+        DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v691);
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_FIRE_FIRE_BOLT://Удар огня
+      case SPELL_FIRE_FIREBALL://Огненный шар
+      case SPELL_FIRE_INCINERATE://Испепеление
+      case SPELL_AIR_LIGHNING_BOLT://Удар молнии
+      case SPELL_WATER_ICE_BOLT://Льдяная молния
+      case SPELL_WATER_ICE_BLAST://Льдяной взрыв
+      case SPELL_EARTH_STUN://Оглушить
+      case SPELL_EARTH_DEADLY_SWARM://Рой смерти
+      case SPELL_MIND_MIND_BLAST://Удар мысли
+      case SPELL_MIND_PSYCHIC_SHOCK://Психический шок
+      case SPELL_BODY_HARM://Вред
+      case SPELL_LIGHT_LIGHT_BOLT://Луч света
+      case SPELL_DARK_DRAGON_BREATH://Дыхание дракона
+      {
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        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;
+        if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+          pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+        else
+          pSpellSprite.uSectorID = 0;
+        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;
+        if ( pCastSpell->uSpellID == SPELL_AIR_LIGHNING_BOLT )
+          LOBYTE(pSpellSprite.uAttributes) |= 0x40;
+        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;
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_WATER_ACID_BURST://Всплеск кислоты
+      case SPELL_EARTH_BLADES://Лезвия
+      case SPELL_BODY_FLYING_FIST://Летающий кулак
+      case SPELL_DARK_TOXIC_CLOUD://Токсичное облако
+      {
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        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 = pParty->vPosition.x;
+        pSpellSprite.vPosition.y = pParty->vPosition.y;
+        pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
+        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;
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_LIGHT_SUNRAY://Луч Солнца
+      {
+        if ( uCurrentlyLoadedLevelType == LEVEL_Indoor
+          || uCurrentlyLoadedLevelType == LEVEL_Outdoor && (pParty->uCurrentHour < 5 || pParty->uCurrentHour >= 21) )//только в дневное время
+        {
+          ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+          pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+          pCastSpell->uSpellID = 0;
+          continue;
+        }
+        if ( pPlayer->CanCastSpell(uRequiredMana) )
+        {
+          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;
+          LODWORD(v727) = 1;
+        }
+        break;
+      }
+      case SPELL_LIGHT_PARALYZE://Паралич
+      {
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        v721 = PID_ID(a2);
+        if (PID_TYPE(a2) == OBJECT_Actor && stru_50C198.GetMagicalResistance(&pActors[v721], 9) )
+        {
+          Actor::AI_Stand(PID_ID(a2), 4, 0x80, 0);
+          pActors[v721].pActorBuffs[ACTOR_BUFF_PARALYZED].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)23040 * spell_level * 0.033333335), skill_level, 0, 0, 0);
+          BYTE2(pActors[v721].uAttributes) |= 8;
+          pActors[v721].vVelocity.x = 0;
+          pActors[v721].vVelocity.y = 0;
+          pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(&pActors[v721], 0);
+        }
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_EARTH_SLOW://Замедление
+      {
+        switch (skill_level)
+        {
+          case 1: LODWORD(v733) = 180 * spell_level; amount = 2; break;
+          case 2: LODWORD(v733) = 300 * spell_level; amount = 2; break;
+          case 3: LODWORD(v733) = 300 * spell_level; amount = 4; break;
+          case 4: LODWORD(v733) = 300 * spell_level; amount = 8; break;
+          default:
+            assert(false);
+        }
+        if ( !pPlayer->CanCastSpell(uRequiredMana) )
+          break;
+        v721 = 836 * PID_ID(a2);
+        LODWORD(v718) = (int)&pActors[PID_ID(a2)];
+        if (PID_TYPE(a2) == OBJECT_Actor && stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 3) )
+        {
+          pActor = &pActors[PID_ID(a2)];
+          pActor->pActorBuffs[ACTOR_BUFF_SLOWED].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)23040 * spell_level * 0.033333335), skill_level, amount, 0, 0);
+          BYTE2(pActor->uAttributes) |= 8;
+          v661 = (Actor *)LODWORD(v718);
+          pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, 0);
+        }
+        LODWORD(v727) = 1;
+        break;
+      }
+      case SPELL_MIND_CHARM:
 		{
 		if ( !pPlayer->CanCastSpell(uRequiredMana) )
 			break;
@@ -903,12 +847,12 @@
 			break;
 		}
 
-		uint power = 300 * v2;
-		if ( v731 == 2 )
+		uint power = 300 * spell_level;
+		if ( skill_level == 2 )
 		{
-			power = 600 * v2;
+			power = 600 * spell_level;
 		}
-		else if ( v731 == 3 )
+		else if ( skill_level == 3 )
 			power  = 29030400;
 
 		//((SpellBuff *)((char *)&pActors[0].pActorBuffs[ACTOR_BUFF_BERSERK] + v730))->Reset();
@@ -917,11 +861,11 @@
 		pActors[PID_ID(a2)].pActorBuffs[ACTOR_BUFF_ENSLAVED].Reset();
 		//((SpellBuff *)((char *)&pActors[0].pActorBuffs[ACTOR_BUFF_CHARM] + v730))->Apply(
 		pActors[PID_ID(a2)].pActorBuffs[ACTOR_BUFF_CHARM].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)(power << 7) * 0.033333335),
-			v731, 0, 0, 0);
+			skill_level, 0, 0, 0);
 		pSpellSprite.stru_24.Reset();
 		pSpellSprite.spell_id = pCastSpell->uSpellID;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
+		pSpellSprite.spell_level = spell_level;
+		pSpellSprite.spell_skill = skill_level;
 		v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 		v61 = PID_ID(a2);
 			v600 = pActors[v61].vPosition.y;
@@ -968,11 +912,11 @@
 			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
 			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
 			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_skill = skill_level;
 			pSpellSprite.spell_id = SPELL_FIRE_PROTECTION_FROM_FIRE;
-			pSpellSprite.spell_level = 300 * v2;
+			pSpellSprite.spell_level = 300 * spell_level;
 				if ( pParty->bTurnBasedModeOn == 1 )
-				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+				LOBYTE(pSpellSprite.uAttributes) |= 4;
 
 				v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
 
@@ -983,11 +927,11 @@
 		}
 		case SPELL_FIRE_FIRE_AURA:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: LODWORD(v733) = 3600 * v2; amount = 10; break;
-				case 2: LODWORD(v733) = 3600 * v2; amount = 11; break;
-				case 3: LODWORD(v733) = 3600 * v2; amount = 12; break;
+				case 1: LODWORD(v733) = 3600 * spell_level; amount = 10; break;
+				case 2: LODWORD(v733) = 3600 * spell_level; amount = 11; break;
+				case 3: LODWORD(v733) = 3600 * spell_level; amount = 12; break;
 				case 4: LODWORD(v733) = 0; amount = 12; break;
 				default:
 				assert(false);
@@ -1006,7 +950,7 @@
 				&& !pItemsTable->IsMaterialNonCommon(v730c) )
 			{
 				v69 = v730c;
-				v14 = v731 == 4;
+				v14 = skill_level == 4;
 				v730c->uSpecEnchantmentType = amount;
 				if ( !v14 )
 				{
@@ -1032,12 +976,12 @@
 		}
 		case SPELL_BODY_REGENERATION:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: LODWORD(v733) = 3600 * v2; amount = 1; break;
-				case 2: LODWORD(v733) = 3600 * v2; amount = 1; break;
-				case 3: LODWORD(v733) = 3600 * v2; amount = 3; break;
-				case 4: LODWORD(v733) = 3600 * v2; amount = 10; break;
+				case 1: LODWORD(v733) = 3600 * spell_level; amount = 1; break;
+				case 2: LODWORD(v733) = 3600 * spell_level; amount = 1; break;
+				case 3: LODWORD(v733) = 3600 * spell_level; amount = 3; break;
+				case 4: LODWORD(v733) = 3600 * spell_level; amount = 10; break;
 				default:
 				assert(false);
 			}
@@ -1046,7 +990,7 @@
 
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 
-			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_REGENERATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)v733 * 4.2666669), v731, amount, 0, 0);
+			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_REGENERATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)v733 * 4.2666669), skill_level, amount, 0, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
@@ -1057,12 +1001,12 @@
 		case SPELL_MIND_PROTECTION_FROM_MIND:
 		case SPELL_BODY_PROTECTION_FROM_BODY:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
 				case 1: 
 				case 2: 
 				case 3: 
-				case 4: LODWORD(v733) = 3600 * v2; amount = v731 * v2; break;
+				case 4: LODWORD(v733) = 3600 * spell_level; amount = skill_level * spell_level; break;
 				default:
 				assert(false);
 			}
@@ -1098,18 +1042,18 @@
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 			v90 = (double)(signed int)v733 * 4.2666669;
-			pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
+			pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, skill_level, amount, 0, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
 		case SPELL_FIRE_HASTE:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: LODWORD(v733) = 60 * (v2 + 60); break;
-				case 2: LODWORD(v733) = 60 * (v2 + 60); break;
-				case 3: LODWORD(v733) = 180 * (v2 + 20); break;
-				case 4: LODWORD(v733) = 240 * (v2 + 15); break;
+				case 1: LODWORD(v733) = 60 * (spell_level + 60); break;
+				case 2: LODWORD(v733) = 60 * (spell_level + 60); break;
+				case 3: LODWORD(v733) = 180 * (spell_level + 20); break;
+				case 4: LODWORD(v733) = 240 * (spell_level + 15); break;
 				default:
 				assert(false);
 			}
@@ -1126,7 +1070,7 @@
 				while ( v92 <= &pParty->pPlayers[3] );
 				if (LODWORD(v727))
 				{
-					pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+					pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), skill_level, 0, 0, 0);
 
 					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
 					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
@@ -1138,19 +1082,19 @@
 		}
 		case SPELL_SPIRIT_BLESS:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 2: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 3: LODWORD(v733) = 900 * (v2 + 4); break;
-				case 4: LODWORD(v733) = 3600 * (v2 + 1); break;
+				case 1: LODWORD(v733) = 300 * (spell_level + 12); break;
+				case 2: LODWORD(v733) = 300 * (spell_level + 12); break;
+				case 3: LODWORD(v733) = 900 * (spell_level + 4); break;
+				case 4: LODWORD(v733) = 3600 * (spell_level + 1); break;
 				default:
 				assert(false);
 			}
-			amount = v2 + 5;
+			amount = spell_level + 5;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			if ( v731 == 1 )
+			if ( skill_level == 1 )
 			{
 				v108 = pCastSpell->uPlayerID_2;
 				v109 = pCastSpell->uSpellID;
@@ -1179,7 +1123,7 @@
 			{
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, v105);
 				v716 = pOtherOverlayList->_4418B1(10000, v105 + 310, 0, 65536);
-				v730b->pPlayerBuffs[1].Apply(pParty->uTimePlayed + v717, v731, amount, v716, 0);
+				v730b->pPlayerBuffs[1].Apply(pParty->uTimePlayed + v717, skill_level, amount, v716, 0);
 				++v730b;
 				++v105;
 			}
@@ -1226,7 +1170,7 @@
 					pSpellSprite.stru_24.Reset();
 					pSpellSprite.spell_id = pCastSpell->uSpellID;
 					pSpellSprite.spell_level = v723;
-					pSpellSprite.spell_skill = v731;
+					pSpellSprite.spell_skill = skill_level;
 					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 					pSpellSprite.uAttributes = 0;
 					pSpellSprite.uSectorID = 0;
@@ -1257,12 +1201,12 @@
 		case SPELL_EARTH_STONESKIN:
 		case SPELL_SPIRIT_HEROISM:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 2: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 3: LODWORD(v733) = 900 * (v2 + 4); break;
-				case 4: LODWORD(v733) = 3600 * (v2 + 1); break;
+				case 1: LODWORD(v733) = 300 * (spell_level + 12); break;
+				case 2: LODWORD(v733) = 300 * (spell_level + 12); break;
+				case 3: LODWORD(v733) = 900 * (spell_level + 4); break;
+				case 4: LODWORD(v733) = 3600 * (spell_level + 1); break;
 				default:
 				assert(false);
 			}
@@ -1277,14 +1221,14 @@
 				if ( v127 == 38 )
 				{
 					LODWORD(v725) = 15;
-					amount = v2 + 5;
+					amount = spell_level + 5;
 				}
 				else
 				{
 					if ( v127 != 51 )
 						continue;
 					LODWORD(v725) = 9;
-					amount = v2 + 5;
+					amount = spell_level + 5;
 				}
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
@@ -1295,16 +1239,16 @@
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 			v90 = (double)(signed int)((int)v733 << 7) * 0.033333335;
 	//LABEL_304:
-			pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
+			pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, skill_level, amount, 0, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
 		case SPELL_FIRE_IMMOLATION:
 		{
-			if ( v731 == 4 )
-				LODWORD(v733) = 600 * v2;
+			if ( skill_level == 4 )
+				LODWORD(v733) = 600 * spell_level;
 			else
-				LODWORD(v733) = 60 * v2;
+				LODWORD(v733) = 60 * spell_level;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
@@ -1313,23 +1257,19 @@
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
-			pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), skill_level, spell_level, 0, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
 		case SPELL_FIRE_METEOR_SHOWER:
 		{
-			//v149 = v731 - 1;
+			//v149 = skill_level - 1;
 			//if ( v149 && (v150 = v149 - 1) != 0 && (v151 = v150 - 1) != 0 )
 			int i;
-			if ( v731 == 4 )
-			{
+			if ( skill_level == 4 )
 				i = 20;
-			}
 			else
-			{
 				i = 16;
-			}
 			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[491], 2);  // Can't cast Meteor Shower indoors!
@@ -1379,8 +1319,8 @@
 					}
 					pSpellSprite.stru_24.Reset();
 					pSpellSprite.spell_id = pCastSpell->uSpellID;
-					pSpellSprite.spell_level = v2;
-					pSpellSprite.spell_skill = v731;
+					pSpellSprite.spell_level = spell_level;
+					pSpellSprite.spell_skill = skill_level;
 					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 					pSpellSprite.uAttributes = 0;
 					pSpellSprite.vPosition.x = uRequiredMana;
@@ -1424,8 +1364,8 @@
 			v700.x = 0;
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_level = spell_level;
+			pSpellSprite.spell_skill = skill_level;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			pSpellSprite.uAttributes = 0;
 			pSpellSprite.uSectorID = 0;
@@ -1458,7 +1398,7 @@
 		}
 		case SPELL_AIR_WIZARD_EYE:
 		{
-			LODWORD(v733) = 3600 * v2;
+			LODWORD(v733) = 3600 * spell_level;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			v168 = 0;
@@ -1469,18 +1409,18 @@
 			}
 			while ( v168 < 4 );
 
-			pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), skill_level, 0, 0, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
 		case SPELL_AIR_FEATHER_FALL:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: LODWORD(v733) = 300 * v2; break;
-				case 2: LODWORD(v733) = 600 * v2; break;
-				case 3: LODWORD(v733) = 3600 * v2; break;
-				case 4: LODWORD(v733) = 3600 * v2; break;
+				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);
 			}
@@ -1495,13 +1435,13 @@
 			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), v731, 0, 0, 0);
+			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 (v731)
+			switch (skill_level)
 			{
 				case 1: amount = 3; break;
 				case 2: amount = 5; break;
@@ -1515,8 +1455,8 @@
 			int _v726 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			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;
@@ -1571,12 +1511,12 @@
 		}
 		case SPELL_AIR_INVISIBILITY:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: LODWORD(v733) = 600 * v2; amount = v2; break;
-				case 2: LODWORD(v733) = 600 * v2; amount = 2 * v2; break;
-				case 3: LODWORD(v733) = 600 * v2; amount = 3 * v2; break;
-				case 4: LODWORD(v733) = 3600 * v2; amount = 4 * v2; break;
+				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);
 			}
@@ -1594,7 +1534,7 @@
 				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), v731, amount, 0, 0);
+				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;
@@ -1613,8 +1553,8 @@
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
 				break;
 			}
-			LODWORD(v733) = 3600 * v2;
-			if ( v731 == 1 || v731 == 2 || v731 == 3 )
+			LODWORD(v733) = 3600 * spell_level;
+			if ( skill_level == 1 || skill_level == 2 || skill_level == 3 )
 				amount = 1;
 			else
 				amount = 0;
@@ -1628,7 +1568,7 @@
 			v207 = pCastSpell->uPlayerID + 1;
 			v716 = v206;
 
-			pParty->pPartyBuffs[PARTY_BUFF_FLY].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, v206, v207);
+			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;
 		}
@@ -1695,8 +1635,8 @@
 				}
 				pSpellSprite.stru_24.Reset();
 				pSpellSprite.spell_id = pCastSpell->uSpellID;
-				pSpellSprite.spell_level = v2;
-				pSpellSprite.spell_skill = v731;
+				pSpellSprite.spell_level = spell_level;
+				pSpellSprite.spell_skill = skill_level;
 				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 				pSpellSprite.uAttributes = 0;
 				pSpellSprite.vPosition.x = LODWORD(v718);
@@ -1726,11 +1666,11 @@
 		}
 		case SPELL_WATER_AWAKEN:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: amount = 180 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
+				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);
@@ -1740,7 +1680,7 @@
 			for( int i=0; i < 4; i++ )
 			{
 				pPlayer = &pParty->pPlayers[i];
-				if ( v731 == 4 )
+				if ( skill_level == 4 )
 				{
 					if ( pPlayer->pConditions[Condition_Sleep] )
 					{
@@ -1764,7 +1704,7 @@
 		}
 		case SPELL_WATER_POISON_SPRAY:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
 				case 1: amount = 1; break;
 				case 2: amount = 3; break;
@@ -1780,27 +1720,22 @@
 			{
 				pSpellSprite.stru_24.Reset();
 				pSpellSprite.spell_id = pCastSpell->uSpellID;
-				pSpellSprite.spell_skill = v731;
-				pSpellSprite.spell_level = v2;
+				pSpellSprite.spell_skill = skill_level;
+				pSpellSprite.spell_level = spell_level;
 				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-				pSpellSprite.vPosition.y = pParty->vPosition.y;
-				v51 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-				v671 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-				v660 = pParty->vPosition.y;
-//	LABEL_153:
 				pSpellSprite.uAttributes = 0;
 				pSpellSprite.vPosition.x = pParty->vPosition.x;
-				pSpellSprite.vPosition.z = v51;
-				v52 = pIndoor->GetSector(pParty->vPosition.x, v660, v671);
+				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.uSectorID = v52;
 				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) |= 4u;
+					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;
@@ -1809,8 +1744,8 @@
 			{
 				pSpellSprite.stru_24.Reset();
 				pSpellSprite.spell_id = pCastSpell->uSpellID;
-				pSpellSprite.spell_level = v2;
-				pSpellSprite.spell_skill = v731;
+				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;
@@ -1855,10 +1790,10 @@
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
 				break;
 			}
-			if ( v731 == 2 || v731 != 3 && v731 != 4 )
-				v229 = 600 * v2;
+			if ( skill_level == 2 || skill_level != 3 && skill_level != 4 )
+				v229 = 600 * spell_level;
 			else
-				v229 = 3600 * v2;
+				v229 = 3600 * spell_level;
 			LODWORD(v733) = v229;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
@@ -1868,13 +1803,9 @@
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
-			pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].Apply(
-				pParty->uTimePlayed + (signed int)(signed __int64)((double)(v229 << 7) * 0.033333335),
-				v731,
-				amount,
-				v716,
-				pCastSpell->uPlayerID + 1);
-			if ( v731 == 4 )
+			pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(v229 << 7) * 0.033333335),
+				skill_level, amount, v716, pCastSpell->uPlayerID + 1);
+			if ( skill_level == 4 )
 				pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags = 1;
 			LODWORD(v727) = 1;
 			break;
@@ -1896,22 +1827,14 @@
 				pCastSpell->uSpellID = 0;
 				continue;
 			}
-			if ( v731 == 1 || v731 == 2 )
-			{
+			if ( skill_level == 1 || skill_level == 2 )
 				v241 = (double)v723 * 0.0099999998 + 0.5;
-			}
-			else if ( v731 == 3 )
-			{
+			else if ( skill_level == 3 )
 				v241 = (double)v723 * 0.0099999998 + 0.69999999;
-			}
-			else if ( v731 == 4 )
-			{
+			else if ( skill_level == 4 )
 				v241 = (double)v723 * 0.0099999998 + 0.80000001;
-			}
 			else
-			{
 				v241 = 0.0;
-			}
 			if ( v241 > 1.0 )
 				v241 = 1.0;
 			int uNewCharges = v240->uMaxCharges * v241;
@@ -1926,7 +1849,7 @@
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u);
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
 				pCastSpell->uSpellID = 0;
-				v2 = v723;
+				spell_level = v723;
 				continue;
 			}
 			v240->uAttributes |= 0x40u;
@@ -1939,14 +1862,14 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
         break;
 			uRequiredMana = 0;
-			amount = 10 * v2;
+			amount = 10 * spell_level;
 			v730 = 1;
 			pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID_2];
 			v245 = &pPlayer->pInventoryItemList[a2];
 			ItemDesc *_v725 = &pItemsTable->pItems[v245->uItemID];
 			if ( 
-				v731 == 1 || v731 == 2 && _v725->uEquipType > 2 ||
-				v731 == 3 || v731 == 4 && 
+				skill_level == 1 || skill_level == 2 && _v725->uEquipType > 2 ||
+				skill_level == 3 || skill_level == 4 && 
 				v245->uItemID <= 134 &&
 				v245->uSpecEnchantmentType == 0 &&
 				v245->uEnchantmentType == 0 &&
@@ -1954,17 +1877,17 @@
 				!v245->IsBroken() )
 			{
 				if ( v245->GetValue() < 450 || 
-					(v245->GetValue() < 250 && (v731 == 3 || v731 == 4) && _v725->uEquipType >= 0 && _v725->uEquipType <= 2)
+					(v245->GetValue() < 250 && (skill_level == 3 || skill_level == 4) && _v725->uEquipType >= 0 && _v725->uEquipType <= 2)
 					)
 				{
 					v730 = 0;
 				}
  
                 __debugbreak(); // castspellinfo.cpp(1962): warning C4700: uninitialized local variable 'v271' used
-				if ( rand() % 100 < 10 * v2 || 
-					(rand() % 100 < 80 && (v731 == 3 || v731 == 4 )) ||
+				if ( rand() % 100 < 10 * spell_level || 
+					(rand() % 100 < 80 && (skill_level == 3 || skill_level == 4 )) ||
 					v245->GetValue() < 450 || 
-					(v245->GetValue() < 250 && (v731 == 3 || v731 == 4) && v271 >= 0 && v271 <= 2)
+					(v245->GetValue() < 250 && (skill_level == 3 || skill_level == 4) && v271 >= 0 && v271 <= 2)
 					)
 				{
 					v313 = _v725->uEquipType;
@@ -1989,7 +1912,7 @@
 						LODWORD(v727) = 1;
 						break;
 					}
-					else if ( v731 == 3 || v731 == 4)
+					else if ( skill_level == 3 || skill_level == 4)
 					{
 					v257 = pItemsTable->pSpecialEnchantments_count;
 					v258 = 0;
@@ -2108,10 +2031,10 @@
 		}
 		case SPELL_WATER_TOWN_PORTAL:
 		{
-			amount = 10 * v2;
+			amount = 10 * spell_level;
 			if ( pPlayer->sMana < (signed int)uRequiredMana )
 				break;
-			if ( pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW) && v731 != 4 || rand() % 100 >= amount && v731 != 4 )
+			if ( pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW) && skill_level != 4 || rand() % 100 >= amount && skill_level != 4 )
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
@@ -2125,7 +2048,7 @@
 		}
 		case SPELL_WATER_LLOYDS_BEACON:
 		{
-			LODWORD(v733) = 604800 * v2;
+			LODWORD(v733) = 604800 * spell_level;
 			if ( !_stricmp(pCurrentMapName, "d05.blv") )
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
@@ -2151,11 +2074,11 @@
 		case SPELL_EARTH_STONE_TO_FLESH:
 		{
 			__debugbreak(); // missing GM ?
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: amount = 3600 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
+				case 1: amount = 3600 * spell_level; break;
+				case 2: amount = 3600 * spell_level; break;
+				case 3: amount = 86400 * spell_level; break;
 				case 4: break;
 				default:
 				assert(false);
@@ -2170,7 +2093,7 @@
 				LODWORD(v727) = 1;
 				break;
 			}
-			if ( v731 == 4 )
+			if ( skill_level == 4 )
 			{
 				*(int *)v324 = 0;
 				*((int *)v324 + 1) = 0;
@@ -2191,17 +2114,14 @@
 				break;
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			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.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;
@@ -2231,8 +2151,8 @@
 			pSpellSprite.uType = 4090;
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_level = spell_level;
+			pSpellSprite.spell_skill = skill_level;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			pSpellSprite.vPosition.x = pParty->vPosition.x;
 			pSpellSprite.vPosition.y = pParty->vPosition.y;
@@ -2256,18 +2176,18 @@
 		}
 		case SPELL_SPIRIT_DETECT_LIFE:
 		{
-			v328 = v731 - 2;
+			v328 = skill_level - 2;
 			if ( v328 )
 			{
 				v329 = v328 - 1;
 				if ( v329 && v329 != 1 )
-					v330 = 600 * v2;
+					v330 = 600 * spell_level;
 				else
-					v330 = 3600 * v2;
+					v330 = 3600 * spell_level;
 			}
 			else
 			{
-				v330 = 1800 * v2;
+				v330 = 1800 * spell_level;
 			}
 			LODWORD(v733) = v330;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
@@ -2277,18 +2197,18 @@
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
-			pParty->pPartyBuffs[PARTY_BUFF_DETECT_LIFE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_DETECT_LIFE].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_SPIRIT_FATE:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: amount = 1 * v2; break;
-				case 2: amount = 2 * v2; break;
-				case 3: amount = 4 * v2; break;
-				case 4: amount = 6 * v2; break;
+				case 1: amount = 1 * spell_level; break;
+				case 2: amount = 2 * spell_level; break;
+				case 3: amount = 4 * spell_level; break;
+				case 4: amount = 6 * spell_level; break;
 				default:
 				assert(false);
 			}
@@ -2300,7 +2220,7 @@
 			{
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 
-				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_FATE].Apply(pParty->uTimePlayed + 1280, v731, amount, 0, 0);
+				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_FATE].Apply(pParty->uTimePlayed + 1280, skill_level, amount, 0, 0);
 				LODWORD(v727) = 1;
 				break;
 			}
@@ -2309,7 +2229,7 @@
 				v343 = PID_ID(v342);
 				HIDWORD(v344) = 0 + ((pParty->uTimePlayed + 1280) >> 32);
 				LODWORD(v344) = LODWORD(pParty->uTimePlayed) + 1280;
-				pActors[v343].pActorBuffs[ACTOR_BUFF_FATE].Apply(v344, v731, amount, 0, 0);
+				pActors[v343].pActorBuffs[ACTOR_BUFF_FATE].Apply(v344, skill_level, amount, 0, 0);
 				BYTE2(pActors[v343].uAttributes) |= 8u;
 				//v672 = 0;
 				v661 = &pActors[v343];
@@ -2320,11 +2240,11 @@
 		}
 		case SPELL_SPIRIT_REMOVE_CURSE:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: amount = 3600 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
+				case 1: amount = 3600 * 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);
@@ -2337,7 +2257,7 @@
 				LODWORD(v727) = 1;
 				break;
 			}
-			if ( v731 == 4 )
+			if ( skill_level == 4 )
 			{
 				LODWORD(v351->pConditions[Condition_Cursed]) = 0;
 				HIDWORD(v351->pConditions[Condition_Cursed]) = 0;
@@ -2358,16 +2278,16 @@
 		}
 		case SPELL_SPIRIT_PRESERVATION:
 		{
-			if ( v731 == 4 )
-				LODWORD(v733) = 900 * (v2 + 4);
+			if ( skill_level == 4 )
+				LODWORD(v733) = 900 * (spell_level + 4);
 			else
-				LODWORD(v733) = 300 * (v2 + 12);
+				LODWORD(v733) = 300 * (spell_level + 12);
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			if ( v731 == 1 || v731 == 2 )
+			if ( skill_level == 1 || skill_level == 2 )
 			{
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
-				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), skill_level, 0, 0, 0);
 				LODWORD(v727) = 1;
 				break;
 			}
@@ -2377,7 +2297,7 @@
 			do
 			{
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, a2);
-				v357->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + v717, v731, 0, 0, 0);
+				v357->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + v717, skill_level, 0, 0, 0);
 				++a2;
 				++v357;// = (SpellBuff *)((char *)v357 + 6972);
 			}
@@ -2387,10 +2307,10 @@
 		}
 		case SPELL_SPIRIT_TURN_UNDEAD:
 		{
-			if ( v731 == 1 || v731 == 2)
-				LODWORD(v733) = 60 * (v2 + 3);
+			if ( skill_level == 1 || skill_level == 2)
+				LODWORD(v733) = 60 * (spell_level + 3);
 			else
-				LODWORD(v733) = 300 * v2 + 180;
+				LODWORD(v733) = 300 * spell_level + 180;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			int _v726 = pRenderer->_46A6AC_spell_render_d3d((int)dword_50BF30.data(), 100, 4096);
@@ -2398,8 +2318,8 @@
 			++pSpellSprite.uType;
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_level = spell_level;
+			pSpellSprite.spell_skill = skill_level;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			pSpellSprite.uAttributes = 0;
 			pSpellSprite.uSectorID = 0;
@@ -2419,9 +2339,8 @@
 
 					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
 					pSpellSprite.Create(0, 0, 0, 0);
-					v369->pActorBuffs[ACTOR_BUFF_AFRAID].Apply(
-						pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
-						v731, 0, 0, 0);
+					v369->pActorBuffs[ACTOR_BUFF_AFRAID].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
+						skill_level, 0, 0, 0);
 				}
 			}
 			LODWORD(v727) = 1;
@@ -2429,10 +2348,10 @@
 		}
 		case SPELL_SPIRIT_RAISE_DEAD:
 		{
-			if ( v731 == 4 )
+			if ( skill_level == 4 )
 				amount = 0;
 			else
-				amount = 86400 * v2;
+				amount = 86400 * spell_level;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			pOtherOverlayList->_4418B1(5080, pCastSpell->uPlayerID_2 + 100, 0, 65536);
@@ -2442,7 +2361,7 @@
 				LODWORD(v727) = 1;
 				break;
 			}
-			v14 = v731 == 4;
+			v14 = skill_level == 4;
 			pParty->pPlayers[v373].sHealth = 1;
 			if ( v14 )
 			{
@@ -2470,10 +2389,10 @@
 		}
 		case SPELL_SPIRIT_SHARED_LIFE:
 		{
-			if ( v731 == 4 )
-				amount = 4 * v2;
+			if ( skill_level == 4 )
+				amount = 4 * spell_level;
 			else
-				amount = 3 * v2;
+				amount = 3 * spell_level;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			v381 = 0;
@@ -2524,11 +2443,11 @@
 		}
 		case SPELL_SPIRIT_RESSURECTION:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: amount = 180 * v2; break;
-				case 2: amount = 10800 * v2; break;
-				case 3: amount = 259200 * v2; break;
+				case 1: amount = 180 * spell_level; break;
+				case 2: amount = 10800 * spell_level; break;
+				case 3: amount = 259200 * spell_level; break;
 				case 4: amount = 0; break;
 				default:
 				assert(false);
@@ -2541,7 +2460,7 @@
 			{
 				if ( !(HIDWORD(pParty->pPlayers[v396].pConditions[1]) | LODWORD(pParty->pPlayers[v396].pConditions[1])) )
 					pParty->pPlayers[v396].PlaySound(SPEECH_25, 0);
-				if ( v731 == 4 )
+				if ( skill_level == 4 )
 				{
 					v397 = pCastSpell->uPlayerID_2;
 					LODWORD(pParty->pPlayers[v397].pConditions[16]) = 0;
@@ -2572,11 +2491,11 @@
 		}
 		case SPELL_MIND_CURE_PARALYSIS:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: amount = 3600 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
+				case 1: amount = 3600 * 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);
@@ -2592,7 +2511,7 @@
 				LODWORD(v727) = 1;
 				break;
 			}
-			if ( v731 == 4 )
+			if ( skill_level == 4 )
 			{
 				*(int *)v324 = 0;
 				*((int *)v324 + 1) = 0;
@@ -2608,11 +2527,11 @@
 		}
 		case SPELL_MIND_REMOVE_FEAR:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: amount = 180 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
+				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);
@@ -2629,7 +2548,7 @@
 				LODWORD(v727) = 1;
 				break;
 			}
-			if ( v731 == 4 )
+			if ( skill_level == 4 )
 			{
 				*(int *)v324 = 0;
 				*((int *)v324 + 1) = 0;
@@ -2687,7 +2606,7 @@
 				if ( v420 < 4 )
 				{
 					memcpy(&v683, &_v730->array_000234[v420], sizeof(v683));
-					v2 = v723;
+					spell_level = v723;
 					//v1 = 0;
 				}
 			}
@@ -2724,8 +2643,8 @@
 			ShowStatusBarString(pTmpBuf2.data(), 2u);
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_level = spell_level;
+			pSpellSprite.spell_skill = skill_level;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			pSpellSprite.vPosition.x = _v730->vPosition.x;
 			pSpellSprite.vPosition.y = _v730->vPosition.y;
@@ -2748,11 +2667,11 @@
 		}
 		case SPELL_MIND_BERSERK:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: amount = 300 * v2; break;
-				case 2: amount = 300 * v2; break;
-				case 3: amount = 600 * v2; break;
+				case 1: amount = 300 * spell_level; break;
+				case 2: amount = 300 * spell_level; break;
+				case 3: amount = 600 * spell_level; break;
 				case 4: amount = 3600; break;
 				default:
 				assert(false);
@@ -2772,13 +2691,13 @@
 				pActors[v426].pActorBuffs[ACTOR_BUFF_ENSLAVED].Reset();
 				pActors[v426].pActorBuffs[ACTOR_BUFF_BERSERK].Apply(
 				pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
-				v731, 0, 0, 0);
+				skill_level, 0, 0, 0);
 				pActors[v426].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
 			}
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_level = spell_level;
+			pSpellSprite.spell_skill = skill_level;
 			v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			v61 = v426;
 			v600 = pActors[v61].vPosition.y;
@@ -2809,7 +2728,7 @@
 		{
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			amount = 600 * v2;
+			amount = 600 * spell_level;
 			if (PID_TYPE(a2) != OBJECT_Actor)
 			{
 				LODWORD(v727) = 1;
@@ -2823,12 +2742,12 @@
 				pActors[PID_ID(a2)].pActorBuffs[ACTOR_BUFF_BERSERK].Reset();
 				pActors[PID_ID(a2)].pActorBuffs[ACTOR_BUFF_CHARM].Reset();
 				pActors[PID_ID(a2)].pActorBuffs[ACTOR_BUFF_ENSLAVED].Apply(pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
-				v731, 0, 0, 0);
+				skill_level, 0, 0, 0);
 			}
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_level = spell_level;
+			pSpellSprite.spell_skill = skill_level;
 			v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			v61 = PID_ID(a2);
 			v600 = pActors[v61].vPosition.y;
@@ -2857,10 +2776,10 @@
 		}
 		case SPELL_MIND_MASS_FEAR:
 		{
-			if ( v731 == 4 )
-				amount = 300 * v2;
+			if ( skill_level == 4 )
+				amount = 300 * spell_level;
 			else
-				amount = 180 * v2;
+				amount = 180 * spell_level;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			int _v726 = pRenderer->_46A6AC_spell_render_d3d((int)dword_50BF30.data(), 100, 4096);
@@ -2868,8 +2787,8 @@
 			++pSpellSprite.uType;
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_level = spell_level;
+			pSpellSprite.spell_skill = skill_level;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			pSpellSprite.uAttributes = 0;
 			pSpellSprite.uSectorID = 0;
@@ -2892,7 +2811,7 @@
 				if ( stru_50C198.GetMagicalResistance(v433, 7u) )
 				{
 					v433->pActorBuffs[ACTOR_BUFF_AFRAID].Apply(pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
-						v731, 0, 0, 0);
+						skill_level, 0, 0, 0);
 				}
 			}
 			LODWORD(v727) = 1;
@@ -2900,11 +2819,11 @@
 		}
 		case SPELL_MIND_CURE_INSANITY:
 		{
-			v435 = v731 - 2;
-			if ( v731 == 4 )
+			v435 = skill_level - 2;
+			if ( skill_level == 4 )
 				amount = 0;
 			else
-				amount = 86400 * v2;
+				amount = 86400 * spell_level;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
@@ -2914,7 +2833,7 @@
 			{
 				if ( !(HIDWORD(pParty->pPlayers[v440].pConditions[1]) | LODWORD(pParty->pPlayers[v440].pConditions[1])) )
 					pParty->pPlayers[v440].PlaySound(SPEECH_25, 0);
-				if ( v731 == 4 )
+				if ( skill_level == 4 )
 				{
 					v441 = pCastSpell->uPlayerID_2;
 					LODWORD(pParty->pPlayers[v441].pConditions[5]) = 0;
@@ -2933,12 +2852,12 @@
 		}
 		case SPELL_EARTH_TELEKINESIS:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: amount = 2 * v2; break;
-				case 2: amount = 2 * v2; break;
-				case 3: amount = 3 * v2; break;
-				case 4: amount = 4 * v2; break;
+				case 1: amount = 2 * spell_level; break;
+				case 2: amount = 2 * spell_level; break;
+				case 3: amount = 3 * spell_level; break;
+				case 4: amount = 4 * spell_level; break;
 				default:
 				assert(false);
 			}
@@ -3007,11 +2926,11 @@
 		}
 		case SPELL_BODY_CURE_WEAKNESS:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: amount = 180 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
+				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);
@@ -3027,7 +2946,7 @@
 				LODWORD(v727) = 1;
 				break;
 			}
-			if ( v731 == 4 )
+			if ( skill_level == 4 )
 			{
 				*(int *)v324 = 0;
 				*((int *)v324 + 1) = 0;
@@ -3043,12 +2962,12 @@
 		}
 		case SPELL_BODY_FIRST_AID:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: amount = 2 * v2 + 5; break;
-				case 2: amount = 3 * v2 + 5; break;
-				case 3: amount = 4 * v2 + 5; break;
-				case 4: amount = 5 * v2 + 5; break;
+				case 1: amount = 2 * spell_level + 5; break;
+				case 2: amount = 3 * spell_level + 5; break;
+				case 3: amount = 4 * spell_level + 5; break;
+				case 4: amount = 5 * spell_level + 5; break;
 				default:
 				assert(false);
 			}
@@ -3089,11 +3008,11 @@
 		}
 		case SPELL_BODY_CURE_POISON:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: amount = 3600 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
+				case 1: amount = 3600 * 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);
@@ -3110,7 +3029,7 @@
 				LODWORD(v727) = 1;
 				break;
 			}
-			if ( v731 == 4 )
+			if ( skill_level == 4 )
 			{
 				LODWORD(pParty->pPlayers[v470].pConditions[6]) = 0;
 				HIDWORD(pParty->pPlayers[v470].pConditions[6]) = 0;
@@ -3139,8 +3058,8 @@
 		}
 		case SPELL_BODY_PROTECTION_FROM_MAGIC:
 		{
-			amount = v2;
-			LODWORD(v733) = 3600 * v2;
+			amount = spell_level;
+			LODWORD(v733) = 3600 * spell_level;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
@@ -3149,17 +3068,17 @@
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
-			pParty->pPartyBuffs[PARTY_BUFF_PROTECTION_FROM_MAGIC].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_PROTECTION_FROM_MAGIC].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), skill_level, spell_level, 0, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
 		case SPELL_BODY_HAMMERHANDS:
 		{
-			LODWORD(v733) = 3600 * v2;
-			amount = v2;
+			LODWORD(v733) = 3600 * spell_level;
+			amount = spell_level;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			if ( v731 == 4 )
+			if ( skill_level == 4 )
 			{
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
@@ -3167,26 +3086,26 @@
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 				v732 = (int)v733 << 7;
 				v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-				pParty->pPlayers[0].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
-				pParty->pPlayers[1].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
-				pParty->pPlayers[2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
+				pParty->pPlayers[0].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, spell_level, spell_level, 0);
+				pParty->pPlayers[1].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, spell_level, spell_level, 0);
+				pParty->pPlayers[2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, spell_level, spell_level, 0);
 
-				pParty->pPlayers[3].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4, v2, v2, 0);
+				pParty->pPlayers[3].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4, spell_level, spell_level, 0);
 				LODWORD(v727) = 1;
 				break;
 			}
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 
-			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, v2, 0);
+			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), skill_level, spell_level, spell_level, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
 		case SPELL_BODY_CURE_DISEASE:
 		{
-			if ( v731 == 4 )
+			if ( skill_level == 4 )
 				amount = 0;
 			else
-				amount = 86400 * v2;
+				amount = 86400 * spell_level;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
@@ -3199,7 +3118,7 @@
 				LODWORD(v727) = 1;
 				break;
 			}
-			if ( v731 == 4 )
+			if ( skill_level == 4 )
 			{
 				LODWORD(pParty->pPlayers[v498].pConditions[7]) = 0;
 				HIDWORD(pParty->pPlayers[v498].pConditions[7]) = 0;
@@ -3229,7 +3148,7 @@
 		}
 		case SPELL_BODY_POWER_CURE:
 		{
-			amount = 5 * v2 + 10;
+			amount = 5 * spell_level + 10;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			v501 = pParty->pPlayers.data();
@@ -3247,7 +3166,7 @@
 		}
 		case SPELL_LIGHT_DISPEL_MAGIC:
 		{
-			sRecoveryTime -= v2;
+			sRecoveryTime -= spell_level;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
@@ -3260,8 +3179,8 @@
 			v688.z = 0;
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_level = spell_level;
+			pSpellSprite.spell_skill = skill_level;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			pSpellSprite.uAttributes = 0;
 			pSpellSprite.uSectorID = 0;
@@ -3299,12 +3218,12 @@
 		}
 		case SPELL_LIGHT_SUMMON_ELEMENTAL:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: v733 = 300 * v2; amount = 1; break;
-				case 2: v733 = 300 * v2; amount = 1; break;
-				case 3: v733 = 900 * v2; amount = 3; break;
-				case 4: v733 = 900 * v2; amount = 5; break;
+				case 1: v733 = 300 * spell_level; amount = 1; break;
+				case 2: v733 = 300 * spell_level; amount = 1; break;
+				case 3: v733 = 900 * spell_level; amount = 3; break;
+				case 4: v733 = 900 * spell_level; amount = 5; break;
 				default:
 				assert(false);
 			}
@@ -3333,18 +3252,18 @@
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			sub_44FA4C_spawn_light_elemental(pCastSpell->uPlayerID, v731, v733);
+			sub_44FA4C_spawn_light_elemental(pCastSpell->uPlayerID, skill_level, v733);
 			LODWORD(v727) = 1;
 			break;
 		}
 		case SPELL_LIGHT_DAY_OF_THE_GODS:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: LODWORD(v733) = 10800 * v2; amount = 3 * v2 + 10; break;
-				case 2: LODWORD(v733) = 10800 * v2; amount = 3 * v2 + 10; break;
-				case 3: LODWORD(v733) = 14400 * v2; amount = 4 * v2 + 10; break;
-				case 4: LODWORD(v733) = 18000 * v2; amount = 5 * v2 + 10; break;
+				case 1: LODWORD(v733) = 10800 * spell_level; amount = 3 * spell_level + 10; break;
+				case 2: LODWORD(v733) = 10800 * spell_level; amount = 3 * spell_level + 10; break;
+				case 3: LODWORD(v733) = 14400 * spell_level; amount = 4 * spell_level + 10; break;
+				case 4: LODWORD(v733) = 18000 * spell_level; amount = 5 * spell_level + 10; break;
 				default:
 				assert(false);
 			}
@@ -3356,7 +3275,7 @@
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
-			pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), skill_level, amount, 0, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
@@ -3379,8 +3298,8 @@
 			v694.z = 0;
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_level = spell_level;
+			pSpellSprite.spell_skill = skill_level;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			pSpellSprite.uAttributes = 0;
 			pSpellSprite.uSectorID = 0;
@@ -3413,12 +3332,12 @@
 		}
 		case SPELL_LIGHT_DAY_OF_PROTECTION:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: LODWORD(v733) = 14400 * v2; amount = 4 * v2; break;
-				case 2: LODWORD(v733) = 14400 * v2; amount = 4 * v2; break;
-				case 3: LODWORD(v733) = 14400 * v2; amount = 4 * v2; break;
-				case 4: LODWORD(v733) = 18000 * v2; amount = 5 * v2; break;
+				case 1: LODWORD(v733) = 14400 * spell_level; amount = 4 * spell_level; break;
+				case 2: LODWORD(v733) = 14400 * spell_level; amount = 4 * spell_level; break;
+				case 3: LODWORD(v733) = 14400 * spell_level; amount = 4 * spell_level; break;
+				case 4: LODWORD(v733) = 18000 * spell_level; amount = 5 * spell_level; break;
 				default:
 				assert(false);
 			}
@@ -3435,25 +3354,25 @@
 			v549 = (double)(v730 << 7) * 0.033333335;
 			*((float *)&v733 + 1) = v549;
 			v712 = (signed __int64)v549;
-			pParty->pPartyBuffs[PARTY_BUFF_RESIST_BODY].Apply(pParty->uTimePlayed + (signed __int64)v549, v731, amount, 0, 0);
-			pParty->pPartyBuffs[PARTY_BUFF_RESIST_MIND].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-			pParty->pPartyBuffs[PARTY_BUFF_RESIST_FIRE].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-			pParty->pPartyBuffs[PARTY_BUFF_RESIST_WATER].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-			pParty->pPartyBuffs[PARTY_BUFF_RESIST_AIR].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-			pParty->pPartyBuffs[PARTY_BUFF_RESIST_EARTH].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-			v550 = v2 + 5;
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_BODY].Apply(pParty->uTimePlayed + (signed __int64)v549, skill_level, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_MIND].Apply(pParty->uTimePlayed + v712, skill_level, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_FIRE].Apply(pParty->uTimePlayed + v712, skill_level, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_WATER].Apply(pParty->uTimePlayed + v712, skill_level, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_AIR].Apply(pParty->uTimePlayed + v712, skill_level, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_EARTH].Apply(pParty->uTimePlayed + v712, skill_level, amount, 0, 0);
+			v550 = spell_level + 5;
 			pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(
 				(signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)),
-				v731,
+				skill_level,
 				v550, 0, 0);
 
-			pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v550, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), skill_level, v550, 0, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
 		case SPELL_LIGHT_HOUR_OF_POWER:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
 				case 1: LODWORD(v733) = 4; amount = 4; break;
 				case 2: LODWORD(v733) = 4; amount = 4; break;
@@ -3464,9 +3383,9 @@
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			y = (char *)(60 * (v2 * LODWORD(v733) + 60));
-			v732 = (300 * amount * v2 + 60) << 7;
-			v730 = v2 + 5;
+			y = (char *)(60 * (spell_level * LODWORD(v733) + 60));
+			v732 = (300 * amount * spell_level + 60) << 7;
+			v730 = spell_level + 5;
 			int _v726 = 0;
 			v553 = pParty->pPlayers.data();//[0].pConditions[1];
 			*((float *)&v733) = (double)v732 * 0.033333335;
@@ -3478,14 +3397,14 @@
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
 				//((SpellBuff *)(v553 + 6056))->Apply(
-				v553->pPlayerBuffs[4].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v731, v730, 0, 0);
+				v553->pPlayerBuffs[4].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), skill_level, v730, 0, 0);
 				if ( *(_QWORD *)v553 )
 					_v726 = 1;
 				++v553;
 			}
 			while ( v553 <= &pParty->pPlayers[3] );
-			v562 = v731;
-			pParty->pPartyBuffs[PARTY_BUFF_HEROISM].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v731, v730, 0, 0);
+			v562 = skill_level;
+			pParty->pPartyBuffs[PARTY_BUFF_HEROISM].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), skill_level, v730, 0, 0);
 			pParty->pPartyBuffs[PARTY_BUFF_SHIELD].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v562, 0, 0, 0);
 			pParty->pPartyBuffs[PARTY_BUFF_STONE_SKIN].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v562, v730, 0, 0);
 			if (!_v726)
@@ -3495,10 +3414,10 @@
 			LODWORD(v727) = 1;
 			break;
 		}
-		case SPELL_LIGHT_DIVINE_INTERVENTION:
+		case SPELL_LIGHT_DIVINE_INTERVENTION://Божественное вмешательство
 		{
 			amount = 3;
-			if ( pPlayer->uNumDivineInterventionCastsThisDay >= 3u )
+			if ( pPlayer->uNumDivineInterventionCastsThisDay >= 3 )
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
@@ -3507,48 +3426,34 @@
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			a2 = 0;
-			_this = (ItemGen *)&pPlayers[1];
-			do
+			for ( uint pl_id = 0; pl_id < 4; pl_id++ )
 			{
-				v563 = 0;
-				do
+				for ( v563 = 0; v563 <= 19; v563++)
 				{
-					v564 = _this->uItemID;
-					*(int *)(v563 + _this->uItemID) = 0;
-					v563 += 8;
-					*(int *)(v563 + v564 - 4) = 0;
+				  LODWORD(pPlayers[pl_id]->pConditions[v563]) = 0;
+				  HIDWORD(pPlayers[pl_id]->pConditions[v563]) = 0;
 				}
-				while ( v563 <= 128 );
-				v565 = ((Player *)_this->uItemID)->GetMaxHealth();
-				v566 = (Player **)_this;
-				*(int *)(_this->uItemID + 6460) = v565;
-				v567 = (*v566)->GetMaxMana();
-				*(int *)(_this->uItemID + 6464) = v567;
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, a2);
-				++a2;
-				_this = (ItemGen *)((char *)_this + 4);
+				pPlayers[pl_id]->sHealth = pPlayers[pl_id]->GetMaxHealth();
+				pPlayers[pl_id]->sMana = pPlayers[pl_id]->GetMaxMana();
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pl_id);
 			}
-			while ( (signed int)_this < (signed int)&qword_A750D8 );
-			v571 = pPlayer;
-			v572 = (char *)&pPlayer->sAgeModifier;
 			if ( pPlayer->sAgeModifier + 10 >= 120 )
-				*(short *)v572 = 120;
+				pPlayer->sAgeModifier = 120;
 			else
-				*(short *)v572 = pPlayer->sAgeModifier + 10;
-			sRecoveryTime += -5 * v2;
-			++v571->uNumDivineInterventionCastsThisDay;
+				pPlayer->sAgeModifier = pPlayer->sAgeModifier + 10;
+			sRecoveryTime += -5 * spell_level;
+			++pPlayer->uNumDivineInterventionCastsThisDay;
 			LODWORD(v727) = 1;
 			break;
 		}
 		case SPELL_DARK_REANIMATE:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: amount = 2 * v2; break;
-				case 2: amount = 3 * v2; break;
-				case 3: amount = 4 * v2; break;
-				case 4: amount = 5 * v2; break;
+				case 1: amount = 2 * spell_level; break;
+				case 2: amount = 3 * spell_level; break;
+				case 3: amount = 4 * spell_level; break;
+				case 4: amount = 5 * spell_level; break;
 				default:
 				assert(false);
 			}
@@ -3589,8 +3494,8 @@
 			++pSpellSprite.uType;
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_level = spell_level;
+			pSpellSprite.spell_skill = skill_level;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			pSpellSprite.uAttributes = 0;
 			pSpellSprite.uSectorID = 0;
@@ -3629,13 +3534,13 @@
 		case SPELL_DARK_VAMPIRIC_WEAPON:
 		{
 			amount = 16;
-			if ( v731 == 4 )
+			if ( skill_level == 4 )
 			{
 				LODWORD(v733) = 0;
 			}
 			else
 			{
-				LODWORD(v733) = 3600 * v2;
+				LODWORD(v733) = 3600 * spell_level;
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
@@ -3661,7 +3566,7 @@
 				continue;
 			}
 			v592 = _v733;
-			v14 = v731 == 4;
+			v14 = skill_level == 4;
 			_v733->uSpecEnchantmentType = 16;
 			if ( !v14 )
 			{
@@ -3676,7 +3581,7 @@
 		}
 		case SPELL_DARK_SHARPMETAL:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
 				case 1: amount = 5; break;
 				case 2: amount = 5; break;
@@ -3690,8 +3595,8 @@
 			signed int _v726 = ((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_level = spell_level;
+			pSpellSprite.spell_skill = skill_level;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			pSpellSprite.vPosition.x = pParty->vPosition.x;
 			pSpellSprite.vPosition.y = pParty->vPosition.y;
@@ -3734,11 +3639,11 @@
 		{
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: LODWORD(v733) = 180 * v2; break;
-				case 2: LODWORD(v733) = 180 * v2; break;
-				case 3: LODWORD(v733) = 300 * v2; break;
+				case 1: LODWORD(v733) = 180 * spell_level; break;
+				case 2: LODWORD(v733) = 180 * spell_level; break;
+				case 3: LODWORD(v733) = 300 * spell_level; break;
 				case 4: LODWORD(v733) = 29030400; break;
 				default:
 				assert(false);
@@ -3761,11 +3666,11 @@
 			pActor->pActorBuffs[ACTOR_BUFF_BERSERK].Reset();
 			pActor->pActorBuffs[ACTOR_BUFF_CHARM].Reset();
 			pActor->pActorBuffs[ACTOR_BUFF_ENSLAVED].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
-				v731, 0, 0, 0);
+				skill_level, 0, 0, 0);
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_level = spell_level;
+			pSpellSprite.spell_skill = skill_level;
 			v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			
 			v600 = pActor->vPosition.y;
@@ -3870,22 +3775,22 @@
 		}
 		case SPELL_DARK_PAIN_REFLECTION:
 		{
-			switch (v731)
+			switch (skill_level)
 			{
-				case 1: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 2: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 3: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 4: LODWORD(v733) = 900 * (v2 + 4); break;
+				case 1: LODWORD(v733) = 300 * (spell_level + 12); break;
+				case 2: LODWORD(v733) = 300 * (spell_level + 12); break;
+				case 3: LODWORD(v733) = 300 * (spell_level + 12); break;
+				case 4: LODWORD(v733) = 900 * (spell_level + 4); break;
 				default:
 				assert(false);
 			}
-			amount = v2 + 5;
+			amount = spell_level + 5;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			if ( v731 != 3 && v731 != 4 )
+			if ( skill_level != 3 && skill_level != 4 )
 			{
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
-				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, v716, 0);
+				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), skill_level, amount, v716, 0);
 				LODWORD(v727) = 1;
 				break;
 			}
@@ -3895,7 +3800,7 @@
 			do
 			{
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, a2);
-				v619->pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + v717, v731, amount, v716, 0);
+				v619->pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + v717, skill_level, amount, v716, 0);
 				++a2;
 				++v619;
 			}
@@ -3915,8 +3820,8 @@
 			v707.z = 0;
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->uSpellID;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_level = spell_level;
+			pSpellSprite.spell_skill = skill_level;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			pSpellSprite.uAttributes = 0;
 			pSpellSprite.uSectorID = 0;
@@ -3929,7 +3834,7 @@
 			int _v726 = 0;
 			if ( _v733 > 0 )
 			{
-				_v726 = (_v733 * (7 * v2 + 25));
+				_v726 = (_v733 * (7 * spell_level + 25));
 				do
 				{
 					v625 = dword_50BF30[a2];
@@ -3997,7 +3902,7 @@
 				pCastSpell->uSpellID = 0;
 				continue;
 			}
-			if ( v731 == 4)
+			if ( skill_level == 4)
 				amount = 4;
 			else
 				amount = 3;
@@ -4011,7 +3916,7 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			pParty->armageddon_timer = 256;
-			pParty->armageddonDamage = v2;
+			pParty->armageddonDamage = spell_level;
 			++pPlayer->uNumArmageddonCasts;
 			if ( pParty->bTurnBasedModeOn == 1 )
 				++pTurnEngine->pending_actions;
@@ -4065,7 +3970,7 @@
 		}
 	}
 	pCastSpell->uSpellID = 0;
-	v2 = v723;
+	spell_level = v723;
 	continue;
   }