# HG changeset patch # User Ritor1 # Date 1406276354 -21600 # Node ID 0eb0826e18b35615ae0674a2c9d4d654d7c3c694 # Parent 90349b8048a5c2fc5d626057d5132749eb7ddeb3# Parent e40805af239b843aa16b54935809437525d8f618 Слияние diff -r 90349b8048a5 -r 0eb0826e18b3 Actor.cpp --- a/Actor.cpp Fri Jul 25 14:17:57 2014 +0600 +++ b/Actor.cpp Fri Jul 25 14:19:14 2014 +0600 @@ -2863,11 +2863,13 @@ AIState uAIState; uint v38; + //Build AI array if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor) Actor::MakeActorAIList_ODM(); else Actor::MakeActorAIList_BLV(); + //Armageddon damage mechanic if ( uCurrentlyLoadedLevelType != LEVEL_Indoor && pParty->armageddon_timer > 0 ) { if ( pParty->armageddon_timer > 417 ) @@ -2919,6 +2921,7 @@ } } + //Turn-based mode: return if (pParty->bTurnBasedModeOn) { pTurnEngine->AITurnBasedAction(); @@ -2928,111 +2931,132 @@ for (uint i = 0; i < uNumActors; ++i) { pActor = &pActors[i]; - 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); - - for (uint j = 0; j < 22; ++j) - { - if (j != 10) + ai_near_actors_targets_pid[i] = OBJECT_Player; + + //Skip actor if: Dead / Removed / Disabled / uAttributes & 0x0400 + if (pActor->uAIState == Dead || pActor->uAIState == Removed || pActor->uAIState == Disabled || pActor->uAttributes & 0x0400) + continue; + + //Kill actor if HP == 0 + if (!pActor->sCurrentHP && pActor->uAIState != Dying) + Actor::Die(i); + + //Kill buffs if expired + for (uint j = 0; j < 22; ++j) + { + if (j != 10) pActor->pActorBuffs[j].IsBuffExpiredToTime(pParty->uTimePlayed); - } - if (pActor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime < 0) - pActor->uActorHeight = pMonsterList->pMonsters[pActor->pMonsterInfo.uID - 1].uMonsterHeight; - if (pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime > 0) - pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly; - else if (pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime < 0) - pActor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[pActor->pMonsterInfo.uID].uHostilityType; - - if (pActor->pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime > 0 || - pActor->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0) - continue; + } + + //If shrink expired: reset height + if (pActor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime < 0) + pActor->uActorHeight = pMonsterList->pMonsters[pActor->pMonsterInfo.uID - 1].uMonsterHeight; + + //If Charm still active: make actor friendly + if (pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime > 0) + pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly; + //Else: reset hostilty + else if (pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime < 0) + pActor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[pActor->pMonsterInfo.uID].uHostilityType; + + //If actor Paralyzed or Stoned: skip + if (pActor->pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime > 0 || pActor->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0) + continue; + + //Calculate RecoveryTime + pActor->pMonsterInfo.uRecoveryTime = max(pActor->pMonsterInfo.uRecoveryTime - pMiscTimer->uTimeElapsed, 0); - pActor->pMonsterInfo.uRecoveryTime = max(pActor->pMonsterInfo.uRecoveryTime - pMiscTimer->uTimeElapsed, 0); + pActor->uCurrentActionTime += pMiscTimer->uTimeElapsed; + if (pActor->uCurrentActionTime < pActor->uCurrentActionLength) + continue; - pActor->uCurrentActionTime += pMiscTimer->uTimeElapsed; - if (pActor->uCurrentActionTime < pActor->uCurrentActionLength) - continue; - - if (pActor->uAIState == Dying) - pActor->uAIState = Dead; - else + if (pActor->uAIState == Dying) + pActor->uAIState = Dead; + else + { + if (pActor->uAIState != Summoned) { - if (pActor->uAIState != Summoned) - { - Actor::AI_StandOrBored(i, OBJECT_Player, 256, nullptr); - continue; - } - pActor->uAIState = Standing; + Actor::AI_StandOrBored(i, OBJECT_Player, 256, nullptr); + continue; } + pActor->uAIState = Standing; + } - pActor->uCurrentActionTime = 0; - pActor->uCurrentActionLength = 0; - pActor->UpdateAnimation(); + pActor->uCurrentActionTime = 0; + pActor->uCurrentActionLength = 0; + pActor->UpdateAnimation(); } - - + for(v78 = 0; v78 < ai_arrays_size; ++v78) { uint actor_id = ai_near_actors_ids[v78]; assert(actor_id < uNumActors); - pActor = &pActors[actor_id]; - - v47 = (signed int)(pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333); + pActor = &pActors[actor_id]; + + v47 = (signed int)(pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333); 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) radiusMultiplier = 0.5; else radiusMultiplier = 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].IsBuffExpiredToTime(pParty->uTimePlayed); } + if ( pActor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime < 0 ) pActor->uActorHeight = pMonsterList->pMonsters[pActor->pMonsterInfo.uID - 1].uMonsterHeight; if ( pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime > 0 ) pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly; - // not sure else if ( pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime < 0 ) pActor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[pActor->pMonsterInfo.uID].uHostilityType; + + //If actor is summoned and buff expired: continue and set state to Removed if ( pActor->pActorBuffs[ACTOR_BUFF_SUMMONED].uExpireTime < 0 ) { pActor->uAIState = Removed; continue; } - if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0 - || (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime > 0) + + if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0 || (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_PARALYZED].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); Actor::GetDirectionInfo(PID(OBJECT_Actor,actor_id), target_pid, &a3, 0); - pDir = &a3; + pDir = &a3; uAIState = pActor->uAIState; + if ( pActor->pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Friendly || (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 || radiusMultiplier * 307.2 < pDir->uDistance @@ -3071,12 +3095,13 @@ } v36 = pDir->uDistance; + if ( pActor->pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Friendly) { if ( target_pid_type == OBJECT_Actor ) { v36 = pDir->uDistance; - v37 =pFactionTable->relations[(pActor->pMonsterInfo.uID-1) / 3 + 1][(pActors[PID_ID(target_pid)].pMonsterInfo.uID - 1) / 3 + 1]; + v37 =pFactionTable->relations[(pActor->pMonsterInfo.uID-1) / 3 + 1][(pActors[PID_ID(target_pid)].pMonsterInfo.uID - 1) / 3 + 1]; } else v37 = 4; @@ -3091,14 +3116,13 @@ pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long; } + //If actor afraid: flee or if out of range random move if (pActor->pActorBuffs[ACTOR_BUFF_AFRAID].uExpireTime > 0) { if ( (signed int)v36 >= 10240 ) Actor::AI_RandomMove(actor_id, target_pid, 1024, 0); else { - //peasents after attacked - //guard after attacked Actor::AI_Flee(actor_id, target_pid, 0, pDir); } continue; @@ -3161,23 +3185,23 @@ } } else - { - if ( (double)v81 >= radiusMultiplier * 307.2 ) - { - if (pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY) - Actor::AI_Stand(actor_id, target_pid, v47, pDir); - else if ( v81 >= 1024 )//monsters - Actor::AI_Pursue3(actor_id, target_pid, 0, pDir); - else - { - v70 = (signed int)(radiusMultiplier * 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 ) + { + if ( (double)v81 >= radiusMultiplier * 307.2 ) + { + if (pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY) + Actor::AI_Stand(actor_id, target_pid, v47, pDir); + else if ( v81 >= 1024 )//monsters + Actor::AI_Pursue3(actor_id, target_pid, 0, pDir); + else + { + v70 = (signed int)(radiusMultiplier * 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 ) { Actor::AI_Stand(actor_id, target_pid, v47, pDir); } @@ -3210,19 +3234,19 @@ Actor::AI_Pursue1(actor_id, target_pid, actor_id, v47, pDir); } else - { - if ( (double)v81 >= radiusMultiplier * 307.2 ) - { - if ( pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY ) - Actor::AI_Stand(actor_id, target_pid, v47, pDir); - else if ( v81 >= 1024 ) - Actor::AI_Pursue3(actor_id, target_pid, 256, pDir); - else - { - v70 = (signed int)(radiusMultiplier * 307.2); - Actor::AI_Pursue2(actor_id, target_pid, 0, pDir, v70); - } - } + { + if ( (double)v81 >= radiusMultiplier * 307.2 ) + { + if ( pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY ) + Actor::AI_Stand(actor_id, target_pid, v47, pDir); + else if ( v81 >= 1024 ) + Actor::AI_Pursue3(actor_id, target_pid, 256, pDir); + else + { + v70 = (signed int)(radiusMultiplier * 307.2); + Actor::AI_Pursue2(actor_id, target_pid, 0, pDir, v70); + } + } else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 ) { Actor::AI_Stand(actor_id, target_pid, v47, pDir); @@ -3256,18 +3280,18 @@ } else if ( !pActor->pMonsterInfo.uMissleAttack2Type ) { - if ( (double)v81 >= radiusMultiplier * 307.2 ) - { - if ( pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY ) - Actor::AI_Stand(actor_id, target_pid, v47, pDir); - else if ( v81 >= 1024 ) - Actor::AI_Pursue3(actor_id, target_pid, 256, pDir); - else - { - v70 = (int)(radiusMultiplier * 307.2); - Actor::AI_Pursue2(actor_id, target_pid, 0, pDir, v70); - } - } + if ( (double)v81 >= radiusMultiplier * 307.2 ) + { + if ( pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY ) + Actor::AI_Stand(actor_id, target_pid, v47, pDir); + else if ( v81 >= 1024 ) + Actor::AI_Pursue3(actor_id, target_pid, 256, pDir); + else + { + v70 = (int)(radiusMultiplier * 307.2); + Actor::AI_Pursue2(actor_id, target_pid, 0, pDir, v70); + } + } else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 ) Actor::AI_Stand(actor_id, target_pid, v47, pDir); else diff -r 90349b8048a5 -r 0eb0826e18b3 AudioPlayer.cpp --- a/AudioPlayer.cpp Fri Jul 25 14:17:57 2014 +0600 +++ b/AudioPlayer.cpp Fri Jul 25 14:19:14 2014 +0600 @@ -7,7 +7,7 @@ #include "ZlibWrapper.h" #include "mm7_data.h" -#include "MediaPlayer.h" +#include "VideoPlayer.h" #include "AudioPlayer.h" #include "FrameTableInc.h" #include "Indoor.h" @@ -128,6 +128,7 @@ pSoundList->UnloadSound(i, 1); } } + //_CrtDumpMemoryLeaks(); } //----- (004A9A67) -------------------------------------------------------- @@ -2345,8 +2346,9 @@ if ( this->bPlayerReady ) { - CloseHandle(pMediaPlayer->hMagicVid); - CloseHandle(pMediaPlayer->hMightVid); + free(pSoundHeaders); + CloseHandle(hMagicVid); + CloseHandle(hMightVid); pAudioPlayer->StopChannels(-1, -1); if ( pAudioPlayer->uMixerChannels > 0 ) { diff -r 90349b8048a5 -r 0eb0826e18b3 AudioPlayer.h --- a/AudioPlayer.h Fri Jul 25 14:17:57 2014 +0600 +++ b/AudioPlayer.h Fri Jul 25 14:19:14 2014 +0600 @@ -162,7 +162,7 @@ field_2D4 = 0; s3DSoundVolume = 127; } - + inline ~AudioPlayer(){ Release(); }; void SetMusicVolume(int vol); void SetMasterVolume(float fVolume); void _4AA258(int a2); diff -r 90349b8048a5 -r 0eb0826e18b3 mm7_4.cpp --- a/mm7_4.cpp Fri Jul 25 14:17:57 2014 +0600 +++ b/mm7_4.cpp Fri Jul 25 14:19:14 2014 +0600 @@ -213,7 +213,7 @@ int last_reg_time; // qax@1 int v4; // eax@2 int v5; // edi@5 - bool cursed_flag; // ecx@5 + long long *v6; // ecx@5 char v7; // sf@5 int *v8; // ecx@10 int v9; // edi@15 @@ -258,11 +258,15 @@ if ( !(pParty->pPartyBuffs[PARTY_BUFF_FLY].uFlags & 1) ) { v5 = v4 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uPower; - cursed_flag = pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1].pConditions[Condition_Cursed];//cursed - v7 = cursed_flag < v5; + //cursed_flag = pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1].pConditions[Condition_Cursed];//cursed + //v7 = cursed_flag < v5; //cursed_flag -= v5; - if ( !v7 ) + + v6 = &pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1].pConditions[Condition_Cursed]; + + if ( *v6 < v5 ) { + v6 = 0; pParty->uFlags &= 0xFFFFFFBFu; pParty->bFlying = false; redraw_flag = true;