diff Actor.cpp @ 1295:86a83e12d795

moving files
author Ritor1
date Mon, 17 Jun 2013 17:34:01 +0600
parents fac7751b2dc9
children 5450af4f57ef
line wrap: on
line diff
--- a/Actor.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/Actor.cpp	Mon Jun 17 17:34:01 2013 +0600
@@ -33,7 +33,7 @@
 
 #include "MM7.h"
 #include "SpriteObject.h"
-
+#include "stru298.h"
 
 
 
@@ -3979,3 +3979,821 @@
   }
   return result;
 }
+// 46DF1A: using guessed type int __fastcall 46DF1A_collide_against_actor(int, int);
+//----- (0046DF1A) --------------------------------------------------------
+signed int __fastcall _46DF1A_collide_against_actor(int a1, int a2)
+{
+  Actor *v2; // edi@1
+  unsigned __int16 v3; // ax@1
+  int v4; // esi@6
+  int v5; // ecx@8
+  int v6; // eax@10
+  int v7; // edx@12
+  int v8; // ecx@14
+  int v9; // eax@14
+  int v10; // ebx@14
+  int v11; // esi@14
+  int v12; // ebx@15
+  int v13; // ebx@17
+  unsigned int v14; // eax@20
+  signed int result; // eax@21
+  int v16; // [sp+Ch] [bp-10h]@1
+  int v17; // [sp+10h] [bp-Ch]@14
+  int v18; // [sp+14h] [bp-8h]@14
+  int v19; // [sp+18h] [bp-4h]@14
+
+  v16 = a1;
+  v2 = &pActors[a1];
+  v3 = v2->uAIState;
+  if ( v3 == 11 || v3 == 4 || v3 == 19 || v3 == 5 || v3 == 17 )
+    goto LABEL_25;
+  v4 = v2->uActorRadius;
+  if ( a2 )
+    v4 = a2;
+  v5 = v2->vPosition.x;
+  if ( stru_721530.sMaxX > v5 + v4
+    || stru_721530.sMinX < v5 - v4
+    || (v6 = v2->vPosition.y, stru_721530.sMaxY > v6 + v4)
+    || stru_721530.sMinY < v6 - v4
+    || (v7 = v2->vPosition.z, stru_721530.sMaxZ > v7 + v2->uActorHeight)
+    || stru_721530.sMinZ < v7
+    || (v8 = v5 - stru_721530.normal.x,
+        v9 = v6 - stru_721530.normal.y,
+        v10 = stru_721530.prolly_normal_d + v4,
+        v17 = stru_721530.prolly_normal_d + v4,
+        v11 = (v8 * stru_721530.field_58.y - v9 * stru_721530.field_58.x) >> 16,
+        v18 = v8,
+        v19 = v9,
+        abs((v8 * stru_721530.field_58.y - v9 * stru_721530.field_58.x) >> 16) > v10)
+    || (v12 = (v18 * stru_721530.field_58.x + v19 * stru_721530.field_58.y) >> 16, v12 <= 0)
+    || (signed int)(((unsigned __int64)(stru_721530.field_58.z * (signed __int64)v12) >> 16) + stru_721530.normal.z) < v2->vPosition.z )
+  {
+LABEL_25:
+    result = 0;
+  }
+  else
+  {
+    v13 = v12 - integer_sqrt(v17 * v17 - v11 * v11);
+    if ( v13 < 0 )
+      v13 = 0;
+    if ( v13 < stru_721530.field_7C )
+    {
+      stru_721530.field_7C = v13;
+      v14 = 8 * v16;
+      LOBYTE(v14) = PID(OBJECT_Actor,v16);
+      stru_721530.uFaceID = v14;
+    }
+    result = 1;
+  }
+  return result;
+}
+//----- (00401A91) --------------------------------------------------------
+void __cdecl UpdateActorAI()
+{
+	//unsigned int v0; // esi@4
+	int v1; // eax@7
+	//int v2; // ecx@7
+	//int v3; // eax@7
+	signed int v4; // edi@10
+	Actor *v5; // esi@12
+	signed int sDmg; // eax@14
+	__int16 v7; // cx@14
+	//Player **v8; // esi@20
+	Player *pPlayer; // ecx@21
+	Actor *pActor; // esi@34
+	//__int16 v11; // ax@34
+	//unsigned int v12; // eax@47
+	//signed int v13; // edi@47
+	//SpellBuff *v14; // ebx@47
+	//unsigned int v15; // edi@67
+	//char *v16; // eax@67
+	//unsigned int v17; // edx@67
+	//unsigned int v18; // ecx@67
+	//unsigned __int16 v19; // ax@72
+	//int *v20; // esi@80
+	//Actor *v21; // ebx@80
+	unsigned __int16 v22; // ax@86
+	//signed int v23; // eax@94
+	//unsigned int v24; // eax@102
+	//signed int v25; // edi@102
+	//SpellBuff *v26; // esi@102
+	unsigned int v27; // ecx@123
+	unsigned int v28; // eax@123
+	//unsigned int v29; // eax@127
+	AIDirection *v30; // eax@129
+	unsigned __int16 v31; // ax@132
+	//unsigned int v32; // esi@142
+	int v33; // eax@144
+	int v34; // eax@147
+	char v35; // al@150
+	unsigned int v36; // edi@152
+	signed int v37; // eax@154
+	//unsigned __int8 v38; // sf@158
+	//unsigned __int8 v39; // of@158
+	//signed int v40; // edx@166
+	//unsigned int v41; // ecx@166
+	double v42; // st7@176
+	double v43; // st6@176
+	//bool v44; // eax@189
+	bool v45; // eax@192
+	unsigned __int8 v46; // cl@197
+	double v47; // st7@206
+	//double v48; // st7@207
+	//char v49; // zf@208
+	//char v50; // zf@214
+	//signed int v51; // edx@219
+	//unsigned int v52; // ecx@219
+	__int16 v53; // fps@224
+	//unsigned __int8 v54; // c0@224
+	//unsigned __int8 v55; // c3@224
+	//double v56; // st7@226
+	AIDirection *v57; // eax@246
+	double v58; // st7@246
+	//signed int v59; // [sp-18h] [bp-C8h]@213
+	//int v60; // [sp-14h] [bp-C4h]@144
+	//int v61; // [sp-14h] [bp-C4h]@168
+	//AIDirection *v62; // [sp-14h] [bp-C4h]@213
+	//signed int v63; // [sp-14h] [bp-C4h]@216
+	unsigned int v64; // [sp-14h] [bp-C4h]@219
+	unsigned int v65; // [sp-10h] [bp-C0h]@144
+	char v66; // [sp-10h] [bp-C0h]@147
+	//AIDirection *v67; // [sp-10h] [bp-C0h]@167
+	//int v68; // [sp-10h] [bp-C0h]@168
+	//AIDirection *v69; // [sp-10h] [bp-C0h]@206
+	int v70; // [sp-10h] [bp-C0h]@213
+	//AIDirection *v71; // [sp-10h] [bp-C0h]@216
+	AIDirection v72; // [sp+0h] [bp-B0h]@246
+	AIDirection a3; // [sp+1Ch] [bp-94h]@129
+	AIDirection v74; // [sp+38h] [bp-78h]@246
+	AIDirection v75; // [sp+54h] [bp-5Ch]@129
+	int target_pid_type; // [sp+70h] [bp-40h]@83
+	signed int a1; // [sp+74h] [bp-3Ch]@129
+	int v78; // [sp+78h] [bp-38h]@79
+	AIDirection pDir; // [sp+7Ch] [bp-34h]@129
+	float v80; // [sp+98h] [bp-18h]@33
+	int v81; // [sp+9Ch] [bp-14h]@100
+	//int v82; // [sp+A0h] [bp-10h]@45
+	//unsigned int uActorID; // [sp+A4h] [bp-Ch]@32
+	unsigned int v84; // [sp+A8h] [bp-8h]@11
+	signed int target_pid; // [sp+ACh] [bp-4h]@83
+	AIState uAIState;
+	int v38;
+	
+	if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+		MakeActorAIList_ODM();
+	else
+		MakeActorAIList_BLV();
+	
+	//v0 = 0;
+	if ( uCurrentlyLoadedLevelType != LEVEL_Indoor && pParty->armageddon_timer > 0 )
+	{
+		if ( pParty->armageddon_timer > 417 )
+		{
+			pParty->armageddon_timer = 0;
+		}
+		else
+		{
+			pParty->sRotationY = (stru_5C6E00->uIntegerDoublePi - 1) & (pParty->sRotationY + rand() % 16 - 8);
+			pParty->sRotationX = pParty->sRotationX + rand() % 16 - 8;
+			if ( pParty->sRotationX > 128) 
+				pParty->sRotationX = 128;
+			else if ( pParty->sRotationX < -128 )
+				pParty->sRotationX = -128;
+				
+			pParty->uFlags |= 2u;
+			pParty->armageddon_timer -= pMiscTimer->uTimeElapsed;
+			v4 = pParty->field_16140 + 50;
+			if ( pParty->armageddon_timer <= 0 )
+			{
+				pParty->armageddon_timer = 0;
+				for(int i = 0; i < uNumActors; i++)
+				{
+					pActor=&pActors[i];
+					if ( pActor->CanAct() )
+					{
+						sDmg = stru_50C198.CalcMagicalDamageToActor(pActor, 5, v4);
+						pActor->sCurrentHP -= stru_50C198.CalcMagicalDamageToActor(pActor, 5, v4);
+						if ( sDmg )
+						{
+							if ( pActor->sCurrentHP >= 0 )
+							{
+								Actor::AI_Stun(i, 4, 0);
+							}
+							else
+							{
+								Actor::Die(i);
+								if ( pActor->pMonsterInfo.uExp )
+									GivePartyExp(pMonsterStats->pInfos[pActor->pMonsterInfo.uID].uExp);
+							}
+						}
+					}
+				}
+				for(int i = 1; i <= 4; i++)
+				{
+					pPlayer = pPlayers[i];
+					if ( !pPlayer->pConditions[14] && !pPlayer->pConditions[15] && !pPlayer->pConditions[16] )
+						pPlayer->ReceiveDamage(v4, DMGT_5);
+				}
+			}
+			if (pTurnEngine->field_1C)
+				--pTurnEngine->field_1C;
+		}
+	}
+	
+	if (pParty->bTurnBasedModeOn)
+	{
+		pTurnEngine->_405E14();
+		return;
+	}
+	
+	
+	//uActorID = v0;
+	for (uint i = 0; i < uNumActors; ++i)
+	{
+		pActor = &pActors[i];
+		//LODWORD(v80) = (int)(char *)pActors + 176; // uAIState
+		//do
+		//{
+			//pActor = (Actor *)(LODWORD(v80) - 176);
+			//v11 = *(unsigned int *)LODWORD(v80);
+			//v49 = *(unsigned int *)LODWORD(v80) == 5;
+			ai_near_actors_targets_pid[i] = OBJECT_Player;
+			if (pActor->uAIState == Dead || pActor->uAIState == Removed || pActor->uAIState == Disabled || pActor->uAttributes & 0x0400)
+				continue;
+			
+			if (!pActor->sCurrentHP && pActor->uAIState != Dying)
+				Actor::Die(i);
+			
+			//v84 = *(_QWORD *)(LODWORD(v80) + 84) <= 0i64 ? 0 : 1;
+			//v82 = *(_QWORD *)(LODWORD(v80) + 52) <= 0i64 ? 0 : 1;
+			//v12 = 0;
+			//v13 = 0;
+			//v14 = (SpellBuff *)(LODWORD(v80) + 36);
+			for (uint j = 0; j < 22; ++j)
+			{
+				if (j != 10)
+				pActor->pActorBuffs[j]._4585CA(pParty->uTimePlayed);
+			}
+			/*do
+			{
+				if ( v13 != 10 )
+				{
+					v14->_4585CA(pParty->uTimePlayed);
+					v12 = 0;
+				}
+				++v13;
+				++v14;
+			}
+			while ( v13 < 22 );*/
+			if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime < 0 )
+			//&& SHIDWORD(pActor->pActorBuffs[3].uExpireTime) <= (signed int)v12 && (SHIDWORD(pActor->pActorBuffs[3].uExpireTime) < (signed int)v12
+			// || LODWORD(pActor->pActorBuffs[3].uExpireTime) <= v12) )
+				pActor->uActorHeight = pMonsterList->pMonsters[pActor->pMonsterInfo.uID - 1].uMonsterHeight;
+			if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime > 0 )
+				pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
+			// not sure
+			else  if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime < 0 )
+				pActor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[pActor->pMonsterInfo.uID].uHostilityType;
+			
+			if ((signed __int64)pActor->pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime > 0 
+				|| (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0)
+				continue;
+			
+			//v15 = pMiscTimer->uTimeElapsed;
+			//v16 = (char *)&pActor->pMonsterInfo.uRecoveryTime;
+			//v17 = pActor->uCurrentActionTime;
+			//v18 = pActor->pMonsterInfo.uRecoveryTime;
+			if (pActor->pMonsterInfo.uRecoveryTime)
+			{
+				if (pActor->pMonsterInfo.uRecoveryTime < pMiscTimer->uTimeElapsed)
+					pActor->pMonsterInfo.uRecoveryTime = 0;
+				else 
+					pActor->pMonsterInfo.uRecoveryTime -= pMiscTimer->uTimeElapsed;
+			}
+			
+			pActor->uCurrentActionTime += pMiscTimer->uTimeElapsed;
+			if (pActor->uCurrentActionTime < pActor->uCurrentActionLength)
+				continue;
+			
+			//v19 = actor->uAIState;
+			if (pActor->uAIState == Dying)
+				pActor->uAIState = Dead;
+			else
+			{
+				if (pActor->uAIState != Summoned)
+				{
+					Actor::AI_StandOrBored(i, OBJECT_Player, 256, nullptr);
+					continue;
+				}
+				pActor->uAIState = Standing;
+			}
+			
+			pActor->uCurrentActionTime = 0;
+			pActor->uCurrentActionLength = 0;
+			pActor->UpdateAnimation();
+			//LABEL_78:
+			//++uActorID;
+			//LODWORD(v80) += 836;
+		//}
+		//while ( (signed int)uActorID < (signed int)uNumActors );
+	}
+	
+	
+	v78 = 0;
+	int actor_id = -1;
+	if ( ai_arrays_size > 0 )
+	{
+		//while ( 1 )
+		for(v78 = 0; v78 < ai_arrays_size; ++v78)
+		{
+			actor_id = ai_near_actors_ids[v78];
+			assert(actor_id < uNumActors);
+			
+			//v20 = &ai_near_actors_targets_pid[actor_id];
+			pActor = &pActors[actor_id];
+			Actor::_SelectTarget(actor_id, &ai_near_actors_targets_pid[actor_id], true);
+			if (pActor->pMonsterInfo.uHostilityType && !ai_near_actors_targets_pid[actor_id])
+				pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
+			target_pid = ai_near_actors_targets_pid[actor_id];
+			target_pid_type = PID_TYPE(target_pid);
+			if ( target_pid_type == OBJECT_Actor)
+				v80 = 0.5;
+			else
+				v80 = 1.0;
+			v22 = pActor->uAIState;
+			if ( v22 == Dying || v22 == Dead || v22 == Removed || v22 == Disabled || v22 == Summoned)
+			{
+				continue;
+			}
+			if ( !pActor->sCurrentHP )
+				Actor::Die(actor_id);
+			for(int i=0;i<22;i++)
+			{
+				if ( i != 10 )
+				{
+					pActor->pActorBuffs[i]._4585CA(pParty->uTimePlayed);
+				}
+			}
+			if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime < 0 )
+				pActor->uActorHeight = pMonsterList->pMonsters[pActor->pMonsterInfo.uID - 1].uMonsterHeight;
+			if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime > 0 )
+				pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
+			// not sure
+			else if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime < 0 )
+				pActor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[pActor->pMonsterInfo.uID].uHostilityType;
+			if ( (signed __int64)pActor->pActorBuffs[2].uExpireTime < 0 )
+			{
+				pActor->uAIState = Removed;
+				continue;
+			}
+			if ( (signed __int64)pActor->pActorBuffs[5].uExpireTime > 0
+				|| (signed __int64)pActor->pActorBuffs[6].uExpireTime > 0)
+			{
+				continue;
+			}
+			v27 = pMiscTimer->uTimeElapsed;
+			v28 = pActor->pMonsterInfo.uRecoveryTime;
+			pActor->uCurrentActionTime += pMiscTimer->uTimeElapsed;
+			if ( (signed int)v28 > 0 )
+				pActor->pMonsterInfo.uRecoveryTime = v28 - v27;
+			if ( pActor->pMonsterInfo.uRecoveryTime < 0 )
+				pActor->pMonsterInfo.uRecoveryTime = 0;
+			if ( !(pActor->uAttributes & 0x8000) )
+				pActor->uAttributes |= 0x8000;
+			a1 = PID(OBJECT_Actor,actor_id);
+			v30 = Actor::GetDirectionInfo(PID(OBJECT_Actor,actor_id), target_pid, &a3, 0);
+			memcpy(&v75, v30, sizeof(v75));
+			memcpy(&pDir, &v75, sizeof(pDir));
+			uAIState = pActor->uAIState; 
+			/*if ( v21->pMonsterInfo.uHostilityType != MonsterInfo::Hostility_Friendly
+				&& (signed int)v21->pMonsterInfo.uRecoveryTime <= 0
+				&& v80 * 307.2 >= (double)(signed int)v75.uDistance
+				&& (uAIState == Pursuing || uAIState == Standing || uAIState == Tethered || uAIState == Fidgeting)
+				|| ( v21->pMonsterInfo.uMissleAttack1Type && uAIState == Stunned ) )
+			{
+				v32 = actor_id;
+			}
+			else
+			*/
+			if ( pActor->pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Friendly
+				|| (signed int)pActor->pMonsterInfo.uRecoveryTime > 0
+				|| v80 * 307.2 < (double)(signed int)v75.uDistance
+				|| uAIState != Pursuing && uAIState != Standing && uAIState != Tethered && uAIState != Fidgeting
+				&&  !pActor->pMonsterInfo.uMissleAttack1Type || uAIState != Stunned )
+			{
+				if ( (signed int)pActor->uCurrentActionTime < pActor->uCurrentActionLength )
+				{
+					continue;
+				}
+				else if ( pActor->uAIState == AttackingMelee )
+				{
+					v35 = stru_50C198.special_ability_use_check(pActor, actor_id);
+					stru_50FE08.Add(
+						a1,
+						5120,
+						pActor->vPosition.x,
+						pActor->vPosition.y,
+						pActor->vPosition.z + ((signed int)pActor->uActorHeight >> 1),
+						v35,
+						1
+					);
+				}
+				else if ( pActor->uAIState == AttackingRanged1 )
+				{
+					v34 = pActor->pMonsterInfo.uMissleAttack1Type;
+					Actor::AI_RangedAttack(actor_id, &pDir, v34, 0);
+				}
+				else if ( pActor->uAIState == AttackingRanged2 )
+				{
+					v34 = pActor->pMonsterInfo.uMissleAttack2Type;
+					Actor::AI_RangedAttack(actor_id, &pDir, v34, 1);
+				}
+				else if ( pActor->uAIState == AttackingRanged3 )
+				{
+					v65 = pActor->pMonsterInfo.uSpellSkillAndMastery1;
+					v33 = pActor->pMonsterInfo.uSpell1ID;
+					Actor::AI_SpellAttack(actor_id, &pDir, v33, 2, v65);
+				}
+				else if ( pActor->uAIState == AttackingRanged4 )
+				{
+					v65 = pActor->pMonsterInfo.uSpellSkillAndMastery2;
+					v33 = pActor->pMonsterInfo.uSpell2ID;
+					Actor::AI_SpellAttack(actor_id, &pDir, v33, 3, v65);
+				}
+			}
+
+			v36 = v75.uDistance;
+			if ( pActor->pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Friendly)
+			{
+				if ( target_pid_type == OBJECT_Actor )
+				{
+					v36 = v75.uDistance;
+					//v37 = (unsigned __int8)*(&byte_5C8D1A[89 * (pActor->pMonsterInfo.uID - 1) / 3]
+					//	+ (pActors[PID_ID(target_pid)].pMonsterInfo.uID - 1) / 3);
+                    v37 =pFactionTable->relations[(pActor->pMonsterInfo.uID-1) / 3 + 1][(pActors[PID_ID(target_pid)].pMonsterInfo.uID - 1) / 3 + 1];
+				}
+				else
+				{
+					v37 = 4;
+				}
+				v38=0;
+				if ( v37 == 2 )
+				{
+					//v39 = __OFSUB__(v36, 1024);
+					//v38 = ((v36 - 1024) & 0x80000000u) != 0;
+					v38 = 1024;
+				}
+				else if ( v37 == 3 )
+				{
+					//v39 = __OFSUB__(v36, 2560);
+					//v38 = ((v36 - 2560) & 0x80000000u) != 0;
+					v38 = 2560;
+				}
+				else if ( v37 == 4 )
+				{
+					//v39 = __OFSUB__(v36, 5120);
+					//v38 = ((v36 - 5120) & 0x80000000u) != 0;
+					v38 = 5120;
+				}
+				if ( v37 >= 1 && v37 <= 4 && v36 < v38  || v37 == 1 )
+					pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
+			}
+
+			if ( (signed __int64)pActor->pActorBuffs[4].uExpireTime > 0 )
+			{
+				if ( (signed int)v36 >= 10240 )
+				{
+					Actor::AI_4032B2(actor_id, target_pid, 1024, 0);
+				}
+				else
+				{
+					//peasents after attacked
+					//guard after attacked
+					Actor::AI_Flee(actor_id, target_pid, 0, &pDir);
+				}
+				continue;
+			}
+
+			if ( pActor->pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Long && target_pid )
+			{
+
+				if ( pActor->pMonsterInfo.uAIType == 1 )
+				{
+					if ( pActor->pMonsterInfo.uMovementType == 5 )
+					{
+						Actor::AI_Stand(actor_id, target_pid, (signed __int64)((double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333),	&pDir);
+					}
+					else
+					{
+						Actor::AI_Flee(actor_id, target_pid, 0, &pDir);
+						continue;
+					}
+						
+				}
+				if ( !(pActor->uAttributes & 0x020000) )
+				{
+					if ( pActor->pMonsterInfo.uAIType == 2 || pActor->pMonsterInfo.uAIType == 3)
+					{
+						if ( pActor->pMonsterInfo.uAIType == 2 )
+							v43 = (double)(signed int)pActor->pMonsterInfo.uHP * 0.2;
+						if ( pActor->pMonsterInfo.uAIType == 3 )
+							v43 = (double)(signed int)pActor->pMonsterInfo.uHP * 0.1;
+						v84 = pActor->sCurrentHP;
+						v42 = (double)(signed int)v84;
+						if ( v43 > v42 && (signed int)v36 < 10240 )
+						{
+							Actor::AI_Flee(actor_id, target_pid, 0, &pDir);
+							continue;
+						}
+					}
+				}
+				
+				v81 = v36 - pActor->uActorRadius;
+				if ( target_pid_type == OBJECT_Actor )
+					v81 -= pActors[PID_ID(target_pid)].uActorRadius;
+				if ( v81 < 0 )
+					v81 = 0;
+				rand();
+				pActor->uAttributes &= 0xFFFBFFFF;
+				if ( v81 < 5120 )
+				{
+					v45 = stru_50C198.special_ability_use_check(pActor, actor_id);
+					if ( v45 == 0 )
+					{
+						if ( pActor->pMonsterInfo.uMissleAttack1Type )
+						{
+							if ( (signed int)pActor->pMonsterInfo.uRecoveryTime <= 0 )
+							{
+								Actor::AI_MissileAttack1(actor_id, target_pid, &pDir);
+							}
+							else if ( pActor->pMonsterInfo.uMovementType == 5 )
+							{
+								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v64 = (signed __int64)v47;
+								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+							}
+							else
+							{
+								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								if ( v80 * 307.2 > (double)v81 )
+								{
+									v64 = (signed __int64)v47;
+									Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+								}
+								else
+								{
+									Actor::AI_Pursue1(actor_id, target_pid, actor_id, (signed __int64)v47, &pDir);
+								}
+							}
+						}
+						else
+						{
+							if ( (double)v81 >= v80 * 307.2 )
+							{
+								if ( v81 >= 1024 )
+								{
+									if ( pActor->pMonsterInfo.uMovementType == 5 )
+									{
+										v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+										v64 = (signed __int64)v47;
+										Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+									}
+									else
+									{
+										//monsters
+										Actor::AI_Pursue3(actor_id, target_pid, 0, &pDir);
+									}
+								}
+								else if ( pActor->pMonsterInfo.uMovementType == 5 )
+								{
+									v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+									v64 = (signed __int64)v47;
+									Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+								}
+								else
+								{
+									v70 = (signed __int64)v80 * 307.2;
+									//monsters
+									//guard after player runs away
+									// follow player
+									Actor::AI_Pursue2(actor_id, target_pid, 0, &pDir, v70);
+								}
+							}
+							else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 )
+							{
+								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v64 = (signed __int64)v47;
+								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+							}
+							else
+							{
+								//monsters
+								Actor::AI_MeleeAttack(actor_id, target_pid, &pDir);
+							}
+						}
+						continue;
+					}
+					else if ( v45 == 2 || v45 == 3 )
+					{
+						if ( v45 == 2 )
+							v46 = pActor->pMonsterInfo.uSpell1ID;
+						else
+							v46 = pActor->pMonsterInfo.uSpell2ID;
+						if ( v46 )
+						{
+							if ( (signed int)pActor->pMonsterInfo.uRecoveryTime <= 0 )
+							{
+								if ( v45 == 2 )
+									Actor::AI_SpellAttack1(actor_id, target_pid, &pDir);
+								else
+									Actor::AI_SpellAttack2(actor_id, target_pid, &pDir);
+							}
+							else if ( v80 * 307.2 > (double)v81 || pActor->pMonsterInfo.uMovementType == 5 )
+							{
+								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v64 = (signed __int64)v47;
+								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+							}
+							else
+							{
+								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								Actor::AI_Pursue1(actor_id, target_pid, actor_id, (signed __int64)v47, &pDir);
+							}
+						}
+						else
+						{
+							if ( (double)v81 >= v80 * 307.2 )
+							{
+								if ( v81 >= 1024 )
+								{
+									if ( pActor->pMonsterInfo.uMovementType == 5 )
+									{
+										v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+										v64 = (signed __int64)v47;
+										Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+									}
+									else
+									{
+										Actor::AI_Pursue3(actor_id, target_pid, 256, &pDir);
+									}
+								}
+								else if ( pActor->pMonsterInfo.uMovementType == 5 )
+								{
+									v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+									v64 = (signed __int64)v47;
+									Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+								}
+								else
+								{
+									v70 = (signed __int64)v80 * 307.2;
+									Actor::AI_Pursue2(actor_id, target_pid, 0, &pDir, v70);
+								}
+							}
+							else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 )
+							{
+								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v64 = (signed __int64)v47;
+								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+							}
+							else
+							{
+								Actor::AI_MeleeAttack(actor_id, target_pid, &pDir);
+							}
+						}
+						continue;
+					}
+				}
+			}
+			
+			if ( pActor->pMonsterInfo.uHostilityType != MonsterInfo::Hostility_Long || !target_pid || v81 >= 5120 || v45 != 1 )
+			{
+				if ( !pActor->pMonsterInfo.uMovementType )
+				{
+					Actor::AI_4032B2(actor_id, 4, 1024, 0);
+				}
+				else if ( pActor->pMonsterInfo.uMovementType == 1 )
+				{
+					Actor::AI_4032B2(actor_id, 4, 2560, 0);
+				}
+				else if ( pActor->pMonsterInfo.uMovementType == 2 )
+				{
+					Actor::AI_4032B2(actor_id, 4, 5120, 0);
+				}
+				else if ( pActor->pMonsterInfo.uMovementType == 4 )
+				{
+					Actor::AI_4032B2(actor_id, 4, 10240, 0);
+				}
+				else if ( pActor->pMonsterInfo.uMovementType == 5 )
+				{
+					v57 = Actor::GetDirectionInfo(a1, 4u, &v72, 0);
+					v58 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+					memcpy(&v74, v57, sizeof(v74));
+					memcpy(&pDir, &v74, sizeof(pDir));
+					v64 = (signed __int64)v58;
+					Actor::AI_Stand(actor_id, 4, v64, &pDir);
+				}				
+			}
+			else if ( !pActor->pMonsterInfo.uMissleAttack2Type )
+			{
+				if ( (double)v81 >= v80 * 307.2 )
+				{
+					if ( v81 >= 1024 )
+					{
+						if ( pActor->pMonsterInfo.uMovementType == 5 )
+						{
+							v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+							v64 = (signed __int64)v47;
+							Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+						}
+						else
+						{
+							Actor::AI_Pursue3(actor_id, target_pid, 256, &pDir);
+						}
+					}
+					else if ( pActor->pMonsterInfo.uMovementType == 5 )
+					{
+						v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+						v64 = (signed __int64)v47;
+						Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+					}
+					else
+					{
+						v70 = (signed __int64)v80 * 307.2;
+						Actor::AI_Pursue2(actor_id, target_pid, 0, &pDir, v70);
+					}
+				}
+				else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 )
+				{
+					v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+					v64 = (signed __int64)v47;
+					Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+				}
+				else
+				{
+					Actor::AI_MeleeAttack(actor_id, target_pid, &pDir);
+				}
+			}
+			else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 )
+			{
+				v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+				if ( v80 * 307.2 > (double)v81 || pActor->pMonsterInfo.uMovementType == 5 )
+				{
+					v64 = (signed __int64)v47;
+					Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+				}
+				else
+				{
+					Actor::AI_Pursue1(actor_id, target_pid, actor_id, (signed __int64)v47, &pDir);
+				}
+			}
+			else
+			{
+				Actor::AI_MissileAttack2(actor_id, target_pid, &pDir);
+			}		
+		}
+	}
+}
+//----- (0044665D) --------------------------------------------------------
+// uType:     0 -> any monster
+//            1 -> uParam is GroupID
+//            2 -> uParam is MonsterID
+//            3 -> uParam is ActorID
+// uNumAlive: 0 -> all must be alive
+int __fastcall IsActorAlive(unsigned int uType, unsigned int uParam, unsigned int uNumAlive)
+{
+  unsigned int uAliveActors; // eax@6
+  int v5; // ecx@10
+  unsigned int uTotalActors; // [sp+0h] [bp-4h]@1
+
+  uTotalActors = 0;
+  if ( uType )
+  {
+    if ( uType == 1 )
+    {
+      uAliveActors = SearchActorByGroup(&uTotalActors, uParam);
+    }
+    else
+    {
+      if ( uType == 2 )
+      {
+        uAliveActors = SearchActorByMonsterID(&uTotalActors, uParam);
+      }
+      else
+      {
+        if ( uType != 3 )
+          return 0;
+        uAliveActors = SearchActorByID(&uTotalActors, uParam);
+      }
+    }
+  }
+  else
+  {
+    uAliveActors = SearchAliveActors(&uTotalActors);
+  }
+  v5 = 0;
+  if ( uNumAlive )
+    LOBYTE(v5) = (signed int)uAliveActors >= (signed int)uNumAlive;
+  else
+    LOBYTE(v5) = uTotalActors == uAliveActors;
+  return v5;
+}
\ No newline at end of file