# HG changeset patch # User zipi # Date 1408294174 -3600 # Node ID 104fdbea038661182a260237167e87d7acd33957 # Parent 0f17a30149ec6563e4168dc3f69327b6655a5783 cleaning project part 2 diff -r 0f17a30149ec -r 104fdbea0386 Actor.cpp --- a/Actor.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Actor.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -7,7 +7,7 @@ #include "PaletteManager.h" #include "ErrorHandling.h" #include "VectorTypes.h" -#include "mm7_unsorted_subs.h" + #include "mm7_data.h" #include "DecalBuilder.h" @@ -5522,3 +5522,232 @@ } //while ( (signed int)v53 < v56 ); } + +//----- (00438F8F) -------------------------------------------------------- +void area_of_effect__damage_evaluate() +{ + int attacker_type; // ecx@3 + signed int v3; // eax@3 + unsigned int target_id; // edi@6 + int target_type; // eax@6 + int v10; // edi@8 + Vec3_int_ attacker_coord; // ST04_12@9 + // int v12; // ST0C_4@10 + int v15; // edx@15 + int v19; // edi@15 + int v23; // edx@18 + int v24; // eax@18 + // int v30; // eax@29 + int v31; // edx@29 + int v32; // eax@29 + int v33; // ST24_4@29 + SpriteObject *v36; // [sp+0h] [bp-28h]@0 + int attacker_id; // [sp+10h] [bp-18h]@1 + int v44; // [sp+14h] [bp-14h]@15 + //Vec3_int_ *pVelocity; // [sp+1Ch] [bp-Ch]@2 + signed int a1; // [sp+20h] [bp-8h]@8 + int v48; // [sp+24h] [bp-4h]@8 + + + for (attacker_id = 0; attacker_id < AttackerInfo.count; ++attacker_id) + { + attacker_type = PID_TYPE(AttackerInfo.pIDs[attacker_id]); + v3 = PID_ID(AttackerInfo.pIDs[attacker_id]); + + if (attacker_type == 2) + { + v36 = &pSpriteObjects[v3]; + attacker_type = PID_TYPE(pSpriteObjects[v3].spell_caster_pid); + v3 = PID_ID(pSpriteObjects[v3].spell_caster_pid); + } + + if (AttackerInfo.field_3EC[attacker_id] & 1) + { + target_id = PID_ID(ai_near_actors_targets_pid[v3]); + target_type = PID_TYPE(ai_near_actors_targets_pid[v3]) - 3; + if (target_type) + { + if (target_type == 1)//party damage from monsters(повреждения группе от монстров) + { + v10 = pParty->vPosition.y - AttackerInfo.pYs[attacker_id]; + a1 = pParty->vPosition.x - AttackerInfo.pXs[attacker_id]; + v48 = pParty->vPosition.y - AttackerInfo.pYs[attacker_id]; + if (a1 * a1 + v10 * v10 + + ((signed int)(pParty->vPosition.z + pParty->uPartyHeight) >> (1 - AttackerInfo.pZs[attacker_id])) + * ((signed int)(pParty->vPosition.z + pParty->uPartyHeight) >> (1 - AttackerInfo.pZs[attacker_id])) + < (unsigned int)((AttackerInfo.field_324[attacker_id] + 32) * (AttackerInfo.field_324[attacker_id] + 32))) + { + attacker_coord.x = AttackerInfo.pXs[attacker_id]; + attacker_coord.y = AttackerInfo.pYs[attacker_id]; + attacker_coord.z = AttackerInfo.pZs[attacker_id]; + if (sub_407A1C(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + pParty->sEyelevel, attacker_coord)) + DamagePlayerFromMonster(AttackerInfo.pIDs[attacker_id], AttackerInfo.field_450[attacker_id], &AttackerInfo.vec_4B4[attacker_id], stru_50C198.which_player_to_attack(&pActors[v3])); + } + } + } + else//Actor damage from monsters(повреждение местного жителя) + { + if (SHIDWORD(pActors[target_id].pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime) > 0 + || SHIDWORD(pActors[target_id].pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime) >= 0 + && LODWORD(pActors[target_id].pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime) + || pActors[target_id].CanAct()) + { + v15 = pActors[target_id].vPosition.y - AttackerInfo.pYs[attacker_id]; + a1 = pActors[target_id].vPosition.x - AttackerInfo.pXs[attacker_id]; + v44 = pActors[target_id].vPosition.z; + v19 = AttackerInfo.field_324[attacker_id] + pActors[target_id].uActorRadius; + v48 = v15; + if (a1 * a1 + v15 * v15 + (pActors[target_id].vPosition.z + (pActors[target_id].uActorHeight >> 1) - AttackerInfo.pZs[attacker_id]) + * (pActors[target_id].vPosition.z + (pActors[target_id].uActorHeight >> 1) - AttackerInfo.pZs[attacker_id]) < (unsigned int)(v19 * v19)) + { + attacker_coord.x = AttackerInfo.pXs[attacker_id]; + attacker_coord.y = AttackerInfo.pYs[attacker_id]; + attacker_coord.z = AttackerInfo.pZs[attacker_id]; + if (sub_407A1C(pActors[target_id].vPosition.x, pActors[target_id].vPosition.y, pActors[target_id].vPosition.z + 50, attacker_coord)) + { + Vec3_int_::Normalize(&a1, &v48, &v44); + AttackerInfo.vec_4B4[attacker_id].x = a1; + AttackerInfo.vec_4B4[attacker_id].y = v48; + AttackerInfo.vec_4B4[attacker_id].z = v44; + Actor::ActorDamageFromMonster(AttackerInfo.pIDs[attacker_id], target_id, &AttackerInfo.vec_4B4[attacker_id], AttackerInfo.field_450[attacker_id]); + } + } + } + } + } + else //damage from spells(повреждения от заклов(метеоритный дождь)) + { + v23 = pParty->vPosition.y - AttackerInfo.pYs[attacker_id]; + v24 = ((signed int)pParty->uPartyHeight / 2) - AttackerInfo.pZs[attacker_id]; + a1 = pParty->vPosition.x - AttackerInfo.pXs[attacker_id]; + v48 = pParty->vPosition.y - AttackerInfo.pYs[attacker_id]; + if (a1 * a1 + v23 * v23 + (pParty->vPosition.z + v24) * (pParty->vPosition.z + v24) < (unsigned int)((AttackerInfo.field_324[attacker_id] + 32) * (AttackerInfo.field_324[attacker_id] + 32))) + {//party damage (повреждения группе) + attacker_coord.x = AttackerInfo.pXs[attacker_id]; + attacker_coord.y = AttackerInfo.pYs[attacker_id]; + attacker_coord.z = AttackerInfo.pZs[attacker_id]; + if (sub_407A1C(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + pParty->sEyelevel, attacker_coord)) + { + for (uint i = 0; i < 4; ++i) + { + if (!(HIDWORD(pParty->pPlayers[i].pConditions[Condition_Dead]) | LODWORD(pParty->pPlayers[i].pConditions[Condition_Dead])) + && !pParty->pPlayers[i].pConditions[Condition_Pertified] && !pParty->pPlayers[i].pConditions[Condition_Eradicated]) + DamagePlayerFromMonster(AttackerInfo.pIDs[attacker_id], AttackerInfo.field_450[attacker_id], &AttackerInfo.vec_4B4[attacker_id], i); + } + } + } + if ((signed int)uNumActors > 0) + {//actors damage(повреждения другим участникам) + for (int actorID = 0; (signed int)actorID < (signed int)uNumActors; ++actorID) + { + if (pActors[actorID].CanAct()) + { + //v30 = pActors[actorID].vPosition.y - AttackerInfo.pYs[attacker_id]; + a1 = pActors[actorID].vPosition.x - AttackerInfo.pXs[attacker_id]; + v31 = pActors[actorID].vPosition.z; + v48 = pActors[actorID].vPosition.y - AttackerInfo.pYs[attacker_id]; + v44 = pActors[actorID].vPosition.z; + v32 = (pActors[actorID].uActorHeight / 2) - AttackerInfo.pZs[attacker_id]; + v33 = pActors[actorID].uActorRadius + AttackerInfo.field_324[attacker_id]; + if (a1 * a1 + v48 * v48 + (v31 + v32) * (v31 + v32) < (unsigned int)(v33 * v33)) + { + attacker_coord.x = AttackerInfo.pXs[attacker_id]; + attacker_coord.y = AttackerInfo.pYs[attacker_id]; + attacker_coord.z = AttackerInfo.pZs[attacker_id]; + if (sub_407A1C(pActors[actorID].vPosition.x, pActors[actorID].vPosition.y, pActors[actorID].vPosition.z + 50, attacker_coord))//что делает ф-ция? + { + Vec3_int_::Normalize(&a1, &v48, &v44); + AttackerInfo.vec_4B4[attacker_id].x = a1; + AttackerInfo.vec_4B4[attacker_id].y = v48; + AttackerInfo.vec_4B4[attacker_id].z = v44; + switch (attacker_type) + { + case OBJECT_Player: + Actor::DamageMonsterFromParty(AttackerInfo.pIDs[attacker_id], actorID, &AttackerInfo.vec_4B4[attacker_id]); + break; + case OBJECT_Actor: + if (v36 && pActors[v3].GetActorsRelation(&pActors[actorID])) + Actor::ActorDamageFromMonster(AttackerInfo.pIDs[attacker_id], actorID, &AttackerInfo.vec_4B4[attacker_id], v36->field_61); + break; + case OBJECT_Item: + ItemDamageFromActor(AttackerInfo.pIDs[attacker_id], actorID, &AttackerInfo.vec_4B4[attacker_id]); + break; + } + } + } + } + } + } + } + } + AttackerInfo.count = 0; +} + +//----- (0043AE12) -------------------------------------------------------- +double __fastcall sub_43AE12(signed int a1) +{ + //signed int v1; // ST00_4@1 + signed int v2; // ecx@1 + double v3; // st7@1 + double result; // st7@6 + + v3 = (double)a1; + for (v2 = 0; v2 < 5; ++v2) + { + if (v3 < flt_4E4A80[v2 + 5]) + break; + } + if (v2 <= 0 || v2 >= 5) + { + if (v2) + result = flt_4E4A80[4]; + else + result = flt_4E4A80[0]; + } + else + result = (flt_4E4A80[v2] - flt_4E4A80[v2 - 1]) * (v3 - flt_4E4A80[v2 + 4]) / (flt_4E4A80[v2 + 5] - flt_4E4A80[v2 + 4]) + flt_4E4A80[v2]; + return result; +} + +//----- (0043B057) -------------------------------------------------------- +void ItemDamageFromActor(unsigned int uObjID, unsigned int uActorID, Vec3_int_ *pVelocity) +{ + int v6; // eax@4 + int damage; // edi@4 + int a2a; // [sp+Ch] [bp-4h]@8 + + if (!pActors[uActorID].IsNotAlive()) + { + if (PID_TYPE(uObjID) == OBJECT_Item) + { + if (pSpriteObjects[PID_ID(uObjID)].spell_id) + { + v6 = _43AFE3_calc_spell_damage(pSpriteObjects[PID_ID(uObjID)].spell_id, pSpriteObjects[PID_ID(uObjID)].spell_level, pSpriteObjects[PID_ID(uObjID)].spell_skill, pActors[uActorID].sCurrentHP); + damage = pActors[uActorID].CalcMagicalDamageToActor((DAMAGE_TYPE)0, v6); + pActors[uActorID].sCurrentHP -= damage; + if (damage) + { + if (pActors[uActorID].sCurrentHP > 0) + Actor::AI_Stun(uActorID, uObjID, 0); + else + Actor::Die(uActorID); + a2a = 20 * damage / (signed int)pActors[uActorID].pMonsterInfo.uHP; + if (20 * damage / (signed int)pActors[uActorID].pMonsterInfo.uHP > 10) + a2a = 10; + if (!MonsterStats::BelongsToSupertype(pActors[uActorID].pMonsterInfo.uID, MONSTER_SUPERTYPE_TREANT)) + { + pVelocity->x = fixpoint_mul(a2a, pVelocity->x); + pVelocity->y = fixpoint_mul(a2a, pVelocity->y); + pVelocity->z = fixpoint_mul(a2a, pVelocity->z); + pActors[uActorID].vVelocity.x = 50 * LOWORD(pVelocity->x); + pActors[uActorID].vVelocity.y = 50 * LOWORD(pVelocity->y); + pActors[uActorID].vVelocity.z = 50 * LOWORD(pVelocity->z); + } + Actor::AddBloodsplatOnDamageOverlay(uActorID, 1, damage); + } + else + Actor::AI_Stun(uActorID, uObjID, 0); + } + } + } +} diff -r 0f17a30149ec -r 104fdbea0386 Actor.h --- a/Actor.h Sun Aug 17 15:13:18 2014 +0100 +++ b/Actor.h Sun Aug 17 17:49:34 2014 +0100 @@ -307,3 +307,6 @@ bool __fastcall SpawnActor(unsigned int uMonsterID); int __fastcall sub_44FA4C_spawn_light_elemental(int a1, int a2, int a3); void SpawnEncounter(struct MapInfo *pMapInfo, struct SpawnPointMM7 *spawn, int a3, int a4, int a5); +void area_of_effect__damage_evaluate(); +double __fastcall sub_43AE12(signed int a1); +void ItemDamageFromActor(unsigned int uObjID, unsigned int uActorID, struct Vec3_int_ *pVelocity); diff -r 0f17a30149ec -r 104fdbea0386 Arcomage.cpp --- a/Arcomage.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Arcomage.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -4,7 +4,7 @@ #define _CRT_SECURE_NO_WARNINGS #include -#include "mm7_unsorted_subs.h" + #include "Render.h" #include "Arcomage.h" diff -r 0f17a30149ec -r 104fdbea0386 CastSpellInfo.cpp --- a/CastSpellInfo.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/CastSpellInfo.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -30,7 +30,7 @@ #include "texts.h" #include "LOD.h" #include "Level/Decoration.h" -#include "mm7_unsorted_subs.h" + #include "UI\UIPartyCreation.h" const size_t CastSpellInfoCount = 10; diff -r 0f17a30149ec -r 104fdbea0386 Chest.cpp --- a/Chest.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Chest.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -4,7 +4,7 @@ #define _CRT_SECURE_NO_WARNINGS #include -#include "mm7_unsorted_subs.h" + #include "ErrorHandling.h" #include "BSPModel.h" diff -r 0f17a30149ec -r 104fdbea0386 DecalBuilder.cpp --- a/DecalBuilder.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/DecalBuilder.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -11,7 +11,7 @@ #include "Log.h" #include "mm7_data.h" -#include "mm7_unsorted_subs.h" + #include "stru9.h" diff -r 0f17a30149ec -r 104fdbea0386 Events.cpp --- a/Events.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Events.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -4,7 +4,7 @@ #define _CRT_SECURE_NO_WARNINGS #include -#include "mm7_unsorted_subs.h" + #include "ErrorHandling.h" #include "Weather.h" @@ -1267,3 +1267,101 @@ return result; } +//----- (004613C4) -------------------------------------------------------- +void init_event_triggers() +{ + uint id = pDecorationList->GetDecorIdByName("Event Trigger"); + + num_event_triggers = 0; + for (uint i = 0; i < uNumLevelDecorations; ++i) + if (pLevelDecorations[i].uDecorationDescID == id) + event_triggers[num_event_triggers++] = i; +} + +//----- (0046CC4B) -------------------------------------------------------- +void check_event_triggers() +{ + for (size_t i = 0; i < num_event_triggers; i++) + { + if (pLevelDecorations[event_triggers[i]].uFlags & LEVEL_DECORATION_TRIGGERED_BY_TOUCH + && pLevelDecorations[event_triggers[i]].vPosition.GetDistanceTo(pParty->vPosition) < pLevelDecorations[event_triggers[i]].uTriggerRange) + { + EventProcessor(pLevelDecorations[event_triggers[i]].uEventID, PID(OBJECT_Decoration, i), 1); + } + else if (pLevelDecorations[event_triggers[i]].uFlags & LEVEL_DECORATION_TRIGGERED_BY_MONSTER) + { + for (size_t j = 0; j < uNumActors; j++) + { + if (pLevelDecorations[event_triggers[i]].vPosition.GetDistanceTo(pActors[j].vPosition) < pLevelDecorations[event_triggers[i]].uTriggerRange) + EventProcessor(pLevelDecorations[event_triggers[i]].uEventID, 0, 1); + } + } + else if (pLevelDecorations[event_triggers[i]].uFlags & LEVEL_DECORATION_TRIGGERED_BY_OBJECT) + { + for (size_t j = 0; j < uNumSpriteObjects; j++) + { + if (pLevelDecorations[event_triggers[i]].vPosition.GetDistanceTo(pSpriteObjects[j].vPosition) < pLevelDecorations[event_triggers[i]].uTriggerRange) + EventProcessor(pLevelDecorations[event_triggers[i]].uEventID, 0, 1); + } + } + } +} +// 6836C8: using guessed type int 6836C8_num_decorations_6807E8; + +//----- (004465DF) -------------------------------------------------------- +bool sub_4465DF_check_season(int a1) +{ + unsigned int monthPlusOne; // eax@1 + unsigned int daysPlusOne; // edx@1 + + monthPlusOne = pParty->uCurrentMonth + 1; + daysPlusOne = pParty->uDaysPlayed + 1; + + switch (a1) + { + case 3: //winter 12.21 -> 3.20 + return (monthPlusOne == 12 && daysPlusOne >= 21 || monthPlusOne == 1 || monthPlusOne == 2 || monthPlusOne == 3 && daysPlusOne <= 20); + break; + case 2:// autumn/fall 9.21 -> 12.20 + return (monthPlusOne == 9 && daysPlusOne >= 21 || monthPlusOne == 10 || monthPlusOne == 11 || monthPlusOne == 12 && daysPlusOne <= 20); + break; + case 1://summer 6.21 -> 9.20 + return (monthPlusOne == 6 && daysPlusOne >= 21 || monthPlusOne == 7 || monthPlusOne == 8 || monthPlusOne == 9 && daysPlusOne <= 20); + break; + case 0: //spring 3.21 -> 6.20 + return (monthPlusOne == 3 && daysPlusOne >= 21 || monthPlusOne == 4 || monthPlusOne == 5 || monthPlusOne == 6 && daysPlusOne <= 20); + break; + } + Error("Unknown season"); + return false; +} + +//----- (00448CF4) -------------------------------------------------------- +void __fastcall sub_448CF4_spawn_monsters(__int16 typeindex, __int16 level, int count, int x, int y, int z, int group, unsigned int uUniqueName) +{ + unsigned int map_id; // eax@1 + size_t old_num_actors; // ebx@2 + AIDirection v15; // [sp+28h] [bp-34h]@2 + SpawnPointMM7 pSpawnPoint; // [sp+44h] [bp-18h]@1 + + pSpawnPoint.vPosition.x = x; + pSpawnPoint.vPosition.y = y; + pSpawnPoint.vPosition.z = z; + pSpawnPoint.uGroup = group; + pSpawnPoint.uRadius = 32; + pSpawnPoint.uKind = 3; + pSpawnPoint.uIndex = typeindex + 2 * level + level; + map_id = pMapStats->GetMapInfo(pCurrentMapName); + if (map_id) + { + old_num_actors = uNumActors; + SpawnEncounter(&pMapStats->pInfos[map_id], &pSpawnPoint, 0, count, 0); + Actor::GetDirectionInfo(PID(OBJECT_Actor, old_num_actors), 4, &v15, 1); + for (uint i = (unsigned int)old_num_actors; i < (unsigned int)uNumActors; ++i) + { + pActors[i].PrepareSprites(0); + pActors[i].uYawAngle = v15.uYawAngle; + pActors[i].dword_000334_unique_name = uUniqueName; + } + } +} diff -r 0f17a30149ec -r 104fdbea0386 Events.h --- a/Events.h Sun Aug 17 15:13:18 2014 +0100 +++ b/Events.h Sun Aug 17 17:49:34 2014 +0100 @@ -346,3 +346,7 @@ }; #pragma pack(pop) +void init_event_triggers(); +void check_event_triggers(); +bool sub_4465DF_check_season(int a1); +void __fastcall sub_448CF4_spawn_monsters(__int16 typeindex, __int16 level, int count, int x, int y, int z, int group, unsigned int uUniqueName); diff -r 0f17a30149ec -r 104fdbea0386 GUIWindow.cpp --- a/GUIWindow.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/GUIWindow.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -4,7 +4,7 @@ #define _CRT_SECURE_NO_WARNINGS #include "ErrorHandling.h" -#include "mm7_unsorted_subs.h" + #include "GUIWindow.h" #include "GUIFont.h" #include "Party.h" @@ -3324,3 +3324,701 @@ bountyHunting_text = pNPCTopics[352].pText; } } + +//----- (004B254D) -------------------------------------------------------- +const char * _4B254D_SkillMasteryTeacher(int trainerInfo) +{ + int teacherLevel; // edx@1 + int skillBeingTaught; // ecx@1 + int pClassType; // eax@7 + int currClassMaxMastery; // eax@7 + int pointsInSkillWOutMastery; // ebx@7 + int classBaseId; // eax@8 + unsigned int skillMastery; // eax@29 + unsigned __int16 pointsInSkill; // [sp+1Ch] [bp-10h]@7 + int masteryLevelBeingTaught; // [sp+24h] [bp-8h]@7 + + contract_approved = 0; + teacherLevel = (trainerInfo - 200) % 3; + skillBeingTaught = (trainerInfo - 200) / 3; + Player* activePlayer = pPlayers[uActiveCharacter]; + pClassType = activePlayer->classType; + currClassMaxMastery = byte_4ED970_skill_learn_ability_by_class_table[pClassType][skillBeingTaught]; + masteryLevelBeingTaught = teacherLevel + 2; + dword_F8B1B0_MasteryBeingTaught = masteryLevelBeingTaught; + if (currClassMaxMastery < masteryLevelBeingTaught) + { + classBaseId = pClassType - pClassType % 4; + if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 1][skillBeingTaught] >= masteryLevelBeingTaught) + sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[633], pClassNames[classBaseId + 1]);//Вы должны достичь звания %s для обучения этому уровню навыка. You have to be promoted to %s to learn this skill level. + else if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 2][skillBeingTaught] >= masteryLevelBeingTaught + && byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 3][skillBeingTaught] >= masteryLevelBeingTaught) + sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[634], pClassNames[classBaseId + 2], pClassNames[classBaseId + 3]);//Вы должны достичь звания %s или %s для обучения этому уровню навыка. You have to be promoted to %s or %s to learn this skill level. + else if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 2][skillBeingTaught] >= masteryLevelBeingTaught) + sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[633], pClassNames[classBaseId + 2]);//Вы должны достичь звания %s для обучения этому уровню навыка. You have to be promoted to %s to learn this skill level. + else if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 3][skillBeingTaught] >= masteryLevelBeingTaught) + sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[633], pClassNames[classBaseId + 3]);//Вы должны достичь звания %s для обучения этому уровню навыка. You have to be promoted to %s to learn this skill level. + else + sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[632], pClassNames[pClassType]);//Этот уровень навыка не может быть постигнут классом %s. This skill level can not be learned by the %s class. + return pTmpBuf.data(); + } + if (!activePlayer->CanAct()) + return pNPCTopics[122].pText; //Not in your condition! + pointsInSkill = activePlayer->pActiveSkills[skillBeingTaught]; + pointsInSkillWOutMastery = pointsInSkill & 0x3F; + if (!pointsInSkillWOutMastery) + return pNPCTopics[131].pText; //You must know the skill before you can become an expert in it! + skillMastery = SkillToMastery(pointsInSkill); + if ((signed int)skillMastery > teacherLevel + 1) + return pNPCTopics[teacherLevel + 128].pText; // You are already an SKILLLEVEL in this skill. + dword_F8B1AC_award_bit_number = skillBeingTaught; + if (masteryLevelBeingTaught == 2 && pointsInSkillWOutMastery < 4 + || masteryLevelBeingTaught == 3 && pointsInSkillWOutMastery < 7 + || masteryLevelBeingTaught == 4 && pointsInSkillWOutMastery < 10 + ) + return pNPCTopics[127].pText; //"You don't meet the requirements, and cannot be taught until you do." + switch (dword_F8B1AC_award_bit_number) + { + case PLAYER_SKILL_STAFF: + case PLAYER_SKILL_SWORD: + case PLAYER_SKILL_DAGGER: + case PLAYER_SKILL_AXE: + case PLAYER_SKILL_SPEAR: + case PLAYER_SKILL_BOW: + case PLAYER_SKILL_MACE: + case PLAYER_SKILL_ARMSMASTER: + switch (masteryLevelBeingTaught) + { + case 2: + gold_transaction_amount = 2000; + break; + case 3: + gold_transaction_amount = 5000; + break; + case 4: + gold_transaction_amount = 8000; + break; + } + break; + case PLAYER_SKILL_BLASTER: + switch (masteryLevelBeingTaught) + { + case 2: + gold_transaction_amount = 0; + break; + case 3: + gold_transaction_amount = 0; + break; + case 4: + gold_transaction_amount = 0; + break; + } + break; + case PLAYER_SKILL_SHIELD: + case PLAYER_SKILL_LEATHER: + case PLAYER_SKILL_CHAIN: + case PLAYER_SKILL_PLATE: + switch (masteryLevelBeingTaught) + { + case 2: + gold_transaction_amount = 1000; + break; + case 3: + gold_transaction_amount = 3000; + break; + case 4: + gold_transaction_amount = 7000; + break; + } + break; + case PLAYER_SKILL_FIRE: + case PLAYER_SKILL_AIR: + case PLAYER_SKILL_WATER: + case PLAYER_SKILL_EARTH: + case PLAYER_SKILL_SPIRIT: + case PLAYER_SKILL_MIND: + case PLAYER_SKILL_BODY: + switch (masteryLevelBeingTaught) + { + case 2: + gold_transaction_amount = 1000; + break; + case 3: + gold_transaction_amount = 4000; + break; + case 4: + gold_transaction_amount = 8000; + break; + } + break; + case PLAYER_SKILL_LIGHT: + switch (masteryLevelBeingTaught) + { + case 2: + gold_transaction_amount = 2000; + break; + case 3: + if (!(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 114)) + return pNPCTopics[127].pText; + gold_transaction_amount = 5000; + break; + case 4: + if (!activePlayer->ProfessionOrGuildFlagsCorrect(0x22u, 1) || + !activePlayer->ProfessionOrGuildFlagsCorrect(0x1Au, 1)) + return pNPCTopics[127].pText; + gold_transaction_amount = 8000; + break; + } + break; + case PLAYER_SKILL_DARK: + switch (masteryLevelBeingTaught) + { + case 2: + gold_transaction_amount = 2000; + break; + case 3: + if (!(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 110)) + return pNPCTopics[127].pText; + gold_transaction_amount = 5000; + break; + case 4: + if (!activePlayer->ProfessionOrGuildFlagsCorrect(0x23u, 1) + || !activePlayer->ProfessionOrGuildFlagsCorrect(0x1Bu, 1)) + return pNPCTopics[127].pText; + gold_transaction_amount = 8000; + break; + } + break; + case PLAYER_SKILL_ITEM_ID: + case PLAYER_SKILL_REPAIR: + case PLAYER_SKILL_MEDITATION: + case PLAYER_SKILL_PERCEPTION: + case PLAYER_SKILL_TRAP_DISARM: + case PLAYER_SKILL_MONSTER_ID: + case PLAYER_SKILL_STEALING: + case PLAYER_SKILL_ALCHEMY: + switch (masteryLevelBeingTaught) + { + case 2: + gold_transaction_amount = 500; + break; + case 3: + gold_transaction_amount = 2500; + break; + case 4: + gold_transaction_amount = 6000; + break; + } + break; + case PLAYER_SKILL_MERCHANT: + switch (masteryLevelBeingTaught) + { + case 2: + gold_transaction_amount = 2000; + break; + case 3: + if (activePlayer->GetBaseWillpower() < 50) + return pNPCTopics[127].pText; + gold_transaction_amount = 5000; + break; + case 4: + gold_transaction_amount = 8000; + break; + } + break; + case PLAYER_SKILL_BODYBUILDING: + switch (masteryLevelBeingTaught) + { + case 2: + gold_transaction_amount = 500; + break; + case 3: + if (activePlayer->GetBaseEndurance() < 50) + return pNPCTopics[127].pText; + gold_transaction_amount = 2500; + break; + case 4: + gold_transaction_amount = 6000; + break; + } + break; + case PLAYER_SKILL_DIPLOMACY: + Error("Diplomacy not used"); + break; + case PLAYER_SKILL_TIEVERY: + Error("Thievery not used"); + break; + case PLAYER_SKILL_DODGE: + switch (masteryLevelBeingTaught) + { + case 2: + gold_transaction_amount = 2000; + break; + case 3: + gold_transaction_amount = 5000; + break; + case 4: + if ((activePlayer->pActiveSkills[PLAYER_SKILL_UNARMED] & 63) < 0xA) + return pNPCTopics[127].pText; + gold_transaction_amount = 8000; + break; + } + break; + case PLAYER_SKILL_UNARMED: + switch (masteryLevelBeingTaught) + { + case 2: + gold_transaction_amount = 2000; + break; + case 3: + gold_transaction_amount = 5000; + break; + case 4: + if ((activePlayer->pActiveSkills[PLAYER_SKILL_DODGE] & 63) < 0xA) + return pNPCTopics[127].pText; + gold_transaction_amount = 8000; + break; + } + break; + case PLAYER_SKILL_LEARNING: + switch (masteryLevelBeingTaught) + { + case 2: + gold_transaction_amount = 2000; + break; + case 3: + if (activePlayer->GetBaseIntelligence() < 50) + return pNPCTopics[127].pText; + gold_transaction_amount = 5000; + break; + case 4: + gold_transaction_amount = 8000; + break; + } + break; + default: + Error("Unknown skill"); + } + if (gold_transaction_amount > pParty->uNumGold) + return pNPCTopics[124].pText; //You don't have enough gold! + contract_approved = 1; + if (masteryLevelBeingTaught == 2) + { + sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[534],//Получить степень ^Pr[%s] в навыке ^Pr[%s] за ^I[%lu] золот^L[ой;ых;ых] + pGlobalTXT_LocalizationStrings[433], pSkillNames[dword_F8B1AC_award_bit_number], gold_transaction_amount);//Эксперт + } + else if (masteryLevelBeingTaught == 3) + { + sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[534], + pGlobalTXT_LocalizationStrings[432], pSkillNames[dword_F8B1AC_award_bit_number], gold_transaction_amount);//Мастер + } + else if (masteryLevelBeingTaught == 4) + sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[534], + pGlobalTXT_LocalizationStrings[225], pSkillNames[dword_F8B1AC_award_bit_number], gold_transaction_amount);//Великий Магистр + return pTmpBuf2.data(); +} + +//----- (00495461) -------------------------------------------------------- +char *BuildDialogueString(const char *lpsz, unsigned __int8 uPlayerID, ItemGen *a3, char *a4, int a5, __int64 *a6) +{ + Player *pPlayer; // ebx@3 + const char *pText; // esi@7 + int v17; // eax@10 + signed __int64 v18; // qax@18 + unsigned __int8 *v20; // ebx@32 + int v21; // ecx@34 + int pReputation; // eax@45 + int v29; // eax@68 + __int16 v55[56]; // [sp+10h] [bp-128h]@34 + stru351_summoned_item v56; // [sp+80h] [bp-B8h]@107 + char a1[100]; // [sp+B8h] [bp-80h]@3 + int v63; // [sp+12Ch] [bp-Ch]@32 + + if (IsBadStringPtrA(lpsz, 1)) + return "Invalid String Passed"; + + a1[0] = 0; + pPlayer = &pParty->pPlayers[uPlayerID]; + memset(pTmpBuf2.data(), 0, sizeof(pTmpBuf2)); + + NPCData *npc = nullptr; + if (dword_5C35D4) + npc = HouseNPCData[(unsigned int)((char *)pDialogueNPCCount + -(dword_591080 != 0))]; //- 1 + else + npc = GetNPCData(sDialogue_SpeakingActorNPC_ID); + + //pText = a4; + uint len = strlen(lpsz); + for (int i = 0, dst = 0; i < len; ++i) + { + char c = lpsz[i]; + if (c != '%') + pTmpBuf2[dst++] = c; + else + { + v17 = 10 * (int)(lpsz[i + 1] - '0') + lpsz[i + 2] - '0'; + + switch (v17) + { + case 1://Подробнее + strcat(pTmpBuf2.data(), npc->pName); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 2: + strcat(pTmpBuf2.data(), pPlayer->pName); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 3: + case 4: + strcat(pTmpBuf2.data(), a1); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 5: + v18 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) / 60 / 60 % 24; + pText = pGlobalTXT_LocalizationStrings[397];// "evening" + if (SHIDWORD(v18) <= 0 && SHIDWORD(v18) >= 0 && (unsigned int)v18 >= 5 && SHIDWORD(v18) <= 0) + { + if (SHIDWORD(v18) >= 0 && (unsigned int)v18 >= 11) + { + if (v18 < 20) + pText = pGlobalTXT_LocalizationStrings[396];// "day" + } + else + { + pText = pGlobalTXT_LocalizationStrings[395];// "morning" + } + } + strcat(pTmpBuf2.data(), pText); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 6: + if (pPlayer->uSex) + pText = pGlobalTXT_LocalizationStrings[387];// "lady" + else + pText = pGlobalTXT_LocalizationStrings[385];// "sir" + strcat(pTmpBuf2.data(), pText); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 7: + if (pPlayer->uSex) + pText = pGlobalTXT_LocalizationStrings[389];// "Lady" + else + pText = pGlobalTXT_LocalizationStrings[386];// "Sir" + strcat(pTmpBuf2.data(), pText); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 8: + v63 = 0; + v20 = (unsigned __int8 *)pPlayer->_achieved_awards_bits; + for (uint _i = 0; _i < 28; ++_i) + { + if ((unsigned __int16)_449B57_test_bit(v20, word_4EE150[i])) + { + v21 = v63; + ++v63; + v55[v63] = word_4EE150[i]; + } + } + if (v63) + { + if (dword_A74CDC == -1) + dword_A74CDC = rand() % v63; + pText = (char *)pAwards[v55[dword_A74CDC]].pText;//(char *)dword_723E80_award_related[2 * v55[v24]]; + } + else + pText = (char *)pNPCTopics[55].pText; + strcat(pTmpBuf2.data(), pText); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 9: + if (npc->uSex) + pText = pGlobalTXT_LocalizationStrings[384];// "her" + else + pText = pGlobalTXT_LocalizationStrings[383];// "his" + strcat(pTmpBuf2.data(), pText); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 10: + if (pPlayer->uSex) + pText = pGlobalTXT_LocalizationStrings[389];// "Lady" + else + pText = pGlobalTXT_LocalizationStrings[388];// "Lord" + strcat(pTmpBuf2.data(), pText); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 11: + pReputation = pParty->GetPartyReputation(); + if (pReputation >= 25) + pText = pGlobalTXT_LocalizationStrings[379]; + else//v25 < 25 + { + if (pReputation < 6) + { + if (pReputation >= -5)//6 >= v25 >= -5 + pText = pGlobalTXT_LocalizationStrings[399]; + else// v25 < -5 + { + if (pReputation < -24)//-24 > v25 + pText = pGlobalTXT_LocalizationStrings[434]; + else// -5 > v25 > -24 + pText = pGlobalTXT_LocalizationStrings[402]; + } + } + else//25 > v25 > 6 + pText = pGlobalTXT_LocalizationStrings[392]; + } + strcat(pTmpBuf2.data(), pText); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 12: + pReputation = npc->rep; + if (pReputation >= 25) + pText = pGlobalTXT_LocalizationStrings[379];//Ненавистный + else + { + if (pReputation < 6) + { + if (pReputation >= -5) + pText = pGlobalTXT_LocalizationStrings[399];//Нейтральная + else + { + if (pReputation < -24) + pText = pGlobalTXT_LocalizationStrings[434];//Почтенная + else + pText = pGlobalTXT_LocalizationStrings[402];//Дружелюбный + } + } + else + pText = pGlobalTXT_LocalizationStrings[392];//Недружелюбный + } + strcat(pTmpBuf2.data(), pText); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 13: + strcat(pTmpBuf2.data(), pNPCStats->sub_495366_MispronounceName(pPlayer->pName[0], pPlayer->uSex)); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 14: + if (npc->uSex) + pText = pGlobalTXT_LocalizationStrings[391];// "sister" + else + pText = pGlobalTXT_LocalizationStrings[390];// "brother" + strcat(pTmpBuf2.data(), pText); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 15: + strcat(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[393]);// "daughter" + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 16: + if (npc->uSex) + pText = pGlobalTXT_LocalizationStrings[391];// "sister" + else + pText = pGlobalTXT_LocalizationStrings[390];// "brother" + strcat(pTmpBuf2.data(), pText); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 17://текст наёмного НПС + { + uint pay_percentage = pNPCStats->pProfessions[npc->uProfession].uHirePrice / 100; + if (!pay_percentage) + pay_percentage = 1; + sprintf(a1, "%lu", pay_percentage); + strcat(pTmpBuf2.data(), a1); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + } + case 18: + case 19: + case 20: + case 21: + case 22: + case 26: + strncpy(a1, lpsz + i + 1, 2); + sprintf(a1, "%lu", atoi(a1)); + strcat(pTmpBuf2.data(), a1); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 23: + if (pMapStats->GetMapInfo(pCurrentMapName)) + pText = pMapStats->pInfos[pMapStats->GetMapInfo(pCurrentMapName)].pName; + else + pText = pGlobalTXT_LocalizationStrings[394];// "Unknown" + strcat(pTmpBuf2.data(), pText); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 24://название товара в продаже + sprintfex(a1, format_4E2D80, Color16(255, 255, 155), a3->GetDisplayName()); + strcat(pTmpBuf2.data(), a1); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 25: + v29 = pPlayer->GetBaseBuyingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier); + switch (a5) + { + case 3: + v29 = pPlayer->GetBaseSellingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier); + break; + case 4: + v29 = pPlayer->GetBaseIdentifyPrice(p2DEvents[(signed int)a4 - 1].fPriceMultiplier); + break; + case 5: + v29 = pPlayer->GetBaseRepairPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier); + break; + case 6: + v29 = pPlayer->GetBaseSellingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier) / 2; + break; + } + sprintfex(a1, "%lu", v29); + strcat(pTmpBuf2.data(), a1); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 27://текст продажи + v29 = pPlayer->GetBuyingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier); + if (a5 == 3) + { + v29 = pPlayer->GetPriceSell(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier); + if (a3->IsBroken()) + v29 = 1; + sprintfex(a1, "%lu", v29); + strcat(pTmpBuf2.data(), a1); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + } + if (a5 != 4) + { + if (a5 == 5) + v29 = pPlayer->GetPriceRepair(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier); + else + { + if (a5 == 6) + { + v29 = pPlayer->GetPriceSell(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier) / 2; + if (a3->IsBroken()) + v29 = 1; + if (!v29) + v29 = 1; + sprintfex(a1, "%lu", v29); + strcat(pTmpBuf2.data(), a1); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + } + } + sprintfex(a1, "%lu", v29); + strcat(pTmpBuf2.data(), a1); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + } + sprintfex(a1, "%lu", pPlayer->GetPriceIdentification(p2DEvents[(signed int)a4 - 1].fPriceMultiplier)); + strcat(pTmpBuf2.data(), a1); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 28://профессия + strcat(pTmpBuf2.data(), (char *)p2DEvents[(signed int)a4 - 1].pProprieterTitle); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 29: + sprintfex(a1, "%lu", pPlayer->GetPriceIdentification(p2DEvents[(signed int)a4 - 1].fPriceMultiplier)); + strcat(pTmpBuf2.data(), a1); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 30: + if (!a6) + { + strcat(pTmpBuf2.data(), a4); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + } + init_summoned_item(&v56, *a6); + sprintfex(a1, pGlobalTXT_LocalizationStrings[378], aMonthNames[v56.field_14_exprie_month], v56.field_C_expire_day + 1, v56.field_18_expire_year); + strcat(pTmpBuf2.data(), a1); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + case 31: + case 32: + case 33: + case 34: + strcat(pTmpBuf2.data(), pParty->pPlayers[v17 - 31].pName); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + default: + if (v17 <= 50 || v17 > 70) + { + strncpy(a1, lpsz + i + 1, 2); + sprintf(a1, "%lu", atoi(a1)); + strcat(pTmpBuf2.data(), a1); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + } + if (v17 - 51 >= 20) + { + strcat(pTmpBuf2.data(), a4); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + } + init_summoned_item(&v56, pParty->PartyTimes._s_times[v17 - 51]); + sprintfex(a1, pGlobalTXT_LocalizationStrings[378], aMonthNames[v56.field_14_exprie_month], v56.field_C_expire_day + 1, v56.field_18_expire_year); + strcat(pTmpBuf2.data(), a1); + dst = strlen(pTmpBuf2.data()); + i += 2; + break; + } + } + } + return pTmpBuf2.data(); +} + +//----- (0044C175) -------------------------------------------------------- +void ShowStatusBarString(const char *pString, unsigned int uNumSeconds) +{ + strcpy(GameUI_Footer_TimedString.data(), pString); + GameUI_Footer_TimeLeft = 1000 * uNumSeconds + GetTickCount(); + + for (int i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data()); i > 450; + i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data())) + GameUI_Footer_TimedString[strlen(GameUI_Footer_TimedString.data()) - 1] = 0; +} + +//----- (0044C1D0) -------------------------------------------------------- +void ShowNothingHereStatus() +{ + if (!GameUI_Footer_TimeLeft) + ShowStatusBarString(pGlobalTXT_LocalizationStrings[521], 2);// Nothing here +} + +//----- (0044C28B) -------------------------------------------------------- +int const_2() +{ + return 2; +} diff -r 0f17a30149ec -r 104fdbea0386 GUIWindow.h --- a/GUIWindow.h Sun Aug 17 15:13:18 2014 +0100 +++ b/GUIWindow.h Sun Aug 17 17:49:34 2014 +0100 @@ -622,6 +622,12 @@ void _4B3FE5_training_dialogue(int a4); void OracleDialogue(); void CheckBountyRespawnAndAward(); +const char * _4B254D_SkillMasteryTeacher(int trainerInfo); +char *BuildDialogueString(const char *lpsz, unsigned __int8 uPlayerID, struct ItemGen *a3, char *a4, int a5, __int64 *a6); +void __fastcall DrawTextAtStatusBar(const char *Str, int a5); +void ShowStatusBarString(const char *pString, unsigned int uNumSeconds); +void ShowNothingHereStatus(); +int const_2(); void __fastcall ZBuffer_Fill(int *pZBuffer, int uTextureId, int iZValue); diff -r 0f17a30149ec -r 104fdbea0386 Game.cpp --- a/Game.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Game.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -4,7 +4,7 @@ #define _CRT_SECURE_NO_WARNINGS #include "Arcomage.h" -#include "mm7_unsorted_subs.h" + #include "Vis.h" #include "Weather.h" #include "LightmapBuilder.h" @@ -75,6 +75,7 @@ + Game *pGame; @@ -4484,6 +4485,7 @@ pRenderer->Present(); } + //----- (0046BDC0) -------------------------------------------------------- void UpdateUserInput_and_MapSpecificStuff() { @@ -6209,17 +6211,6 @@ pMouse->SetCursorBitmapFromItemID(pParty->pPickedItem.uItemID); } -//----- (004613C4) -------------------------------------------------------- -void init_event_triggers() -{ - uint id = pDecorationList->GetDecorIdByName("Event Trigger"); - - num_event_triggers = 0; - for (uint i = 0; i < uNumLevelDecorations; ++i) - if (pLevelDecorations[i].uDecorationDescID == id) - event_triggers[num_event_triggers++] = i; -} - //----- (0042F3D6) -------------------------------------------------------- void InitializeTurnBasedAnimations(void *_this) { @@ -6427,4 +6418,1079 @@ pParty->uFlags |= 2; } } -} \ No newline at end of file +} + +//----- (004356FF) -------------------------------------------------------- +void back_to_game() +{ + dword_507BF0_is_there_popup_onscreen = 0; + dword_4E455C = 1; + + extern int no_rightlick_in_inventory; + no_rightlick_in_inventory = false; + + if (pGUIWindow_ScrollWindow) + free_book_subwindow(); + if (!pCurrentScreen && !pGUIWindow_Settings) + pEventTimer->Resume(); + viewparams->bRedrawGameUI = 1; +} + +//----- (00494035) -------------------------------------------------------- +void _494035_timed_effects__water_walking_damage__etc() +{ + signed __int64 v0; // qax@1 + unsigned int v4; // edi@1 + // signed int v12; // edi@29 + int v24; // ecx@60 + int v26; // ecx@64 + int v28; // ecx@68 + int v30; // ecx@72 + int v32; // ecx@76 + int v34; // ecx@80 + int v36; // ecx@84 + int v38; // ecx@88 + int v40; // ecx@92 + int v42; // ecx@96 + bool v43; // ebx@102 + bool v46; // edi@111 + // unsigned int v56; // [sp-8h] [bp-38h]@55 + // int v59; // [sp-4h] [bp-34h]@55 + // unsigned int v61; // [sp+14h] [bp-1Ch]@1 + signed int a2a; // [sp+18h] [bp-18h]@47 + signed int old_day; // [sp+1Ch] [bp-14h]@47 + signed int old_hour; + + old_day = pParty->uDaysPlayed; + old_hour = pParty->uCurrentHour; + //auto prev_time = pEventTimer->uTimeElapsed; + pParty->uTimePlayed += pEventTimer->uTimeElapsed; + v0 = ((signed __int64)(pParty->uTimePlayed * 0.234375) / 60) / 60i64; + v4 = (unsigned int)(((unsigned int)v0 / 24) / 7) >> 2; + pParty->uCurrentTimeSecond = (signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) % 60; + pParty->uCurrentMinute = ((signed __int64)(pParty->uTimePlayed * 0.234375) / 60) % 60; + pParty->uCurrentHour = v0 % 24; + pParty->uCurrentMonthWeek = ((unsigned int)v0 / 24) / 7 & 3; + pParty->uDaysPlayed = (unsigned int)((unsigned int)v0 / 24) % 28; + pParty->uCurrentMonth = v4 % 12; + pParty->uCurrentYear = v4 / 0xC + game_starting_year; + if (pParty->uCurrentHour >= 3 && (old_hour < 3 || pParty->uDaysPlayed > old_day)) // new day dawns + { + pParty->pHirelings[0].bHasUsedTheAbility = false; + pParty->pHirelings[1].bHasUsedTheAbility = false; + + for (uint i = 0; i < pNPCStats->uNumNewNPCs; ++i) + pNPCStats->pNewNPCData[i].bHasUsedTheAbility = false; + + ++pParty->days_played_without_rest; + if (pParty->days_played_without_rest > 1) + { + for (uint i = 0; i < 4; ++i) + pParty->pPlayers[i].SetCondWeakWithBlockCheck(0); + + if (pParty->uNumFoodRations) + Party::TakeFood(1); + else + for (uint i = 0; i < 4; ++i) + pParty->pPlayers[i].sHealth = pParty->pPlayers[i].sHealth / (pParty->days_played_without_rest + 1) + 1; + + if (pParty->days_played_without_rest > 3) + for (uint i = 0; i < 4; ++i) + { + pParty->pPlayers[i].Zero(); + if (!pParty->pPlayers[i].IsPertified() && !pParty->pPlayers[i].IsEradicated() + && !pParty->pPlayers[i].IsDead()) + { + if (rand() % 100 < 5 * pParty->days_played_without_rest) + pParty->pPlayers[i].SetCondDeadWithBlockCheck(0); + if (rand() % 100 < 10 * pParty->days_played_without_rest) + pParty->pPlayers[i].SetCondInsaneWithBlockCheck(0); + } + } + } + if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + pOutdoor->SetFog(); + + for (uint i = 0; i < 4; ++i) + pParty->pPlayers[i].uNumDivineInterventionCastsThisDay = 0; + } + + if (pParty->uFlags & 4 && pParty->field_6FC < (signed __int64)pParty->uTimePlayed)//water damage + { + pParty->field_6FC = (signed __int64)pParty->uTimePlayed + 128; + viewparams->bRedrawGameUI = true; + for (uint pl = 1; pl <= 4; ++pl) + { + if (pPlayers[pl]->WearsItem(ITEM_RELIC_HARECS_LEATHER, EQUIP_ARMOUR) + || pPlayers[pl]->HasEnchantedItemEquipped(71) + || pPlayers[pl]->pPlayerBuffs[PLAYER_BUFF_WATER_WALK].uExpireTime > 0) + pPlayers[pl]->PlayEmotion(CHARACTER_EXPRESSION_37, 0); + else + { + if (!pPlayers[pl]->HasUnderwaterSuitEquipped()) + { + pPlayers[pl]->ReceiveDamage((signed __int64)pPlayers[pl]->GetMaxHealth() * 0.1, DMGT_FIRE); + if (pParty->uFlags & 4) + { + strcpy(GameUI_Footer_TimedString.data(), pGlobalTXT_LocalizationStrings[660]);// Вы тонете! + GameUI_Footer_TimeLeft = 128; + } + } + else + pPlayers[pl]->PlayEmotion(CHARACTER_EXPRESSION_37, 0); + } + } + } + if (pParty->uFlags & 0x200 && pParty->field_6FC < (signed __int64)pParty->uTimePlayed) //lava damage + { + viewparams->bRedrawGameUI = true; + pParty->field_6FC = (signed __int64)pParty->uTimePlayed + 128; + + for (uint pl = 1; pl <= 4; pl++) + { + pPlayers[pl]->ReceiveDamage((signed __int64)pPlayers[pl]->GetMaxHealth() * 0.1, DMGT_FIRE); + if (pParty->uFlags & 0x200) + { + strcpy(GameUI_Footer_TimedString.data(), pGlobalTXT_LocalizationStrings[661]); //Вы горите! + GameUI_Footer_TimeLeft = 128; + } + } + } + _493938_regenerate(); + uint party_condition_flag = 4; + a2a = pEventTimer->uTimeElapsed; + if (pParty->uFlags2 & PARTY_FLAGS_2_RUNNING)//замедление восстановления при беге + { + a2a *= 0.5f; + if (a2a < 1) + a2a = 1; + } + + for (uint pl = 1; pl <= 4; pl++) + { + if (pPlayers[pl]->uTimeToRecovery) + pPlayers[pl]->Recover(a2a);//восстановление активности + if (pPlayers[pl]->GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE) + pPlayers[pl]->sHealth + pPlayers[pl]->uEndurance >= 1 + || (signed __int64)pPlayers[pl]->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime > 0) + { + if (pPlayers[pl]->sHealth < 1) + pPlayers[pl]->SetCondition(Condition_Unconcious, 0); + } + else + pPlayers[pl]->SetCondition(Condition_Dead, 0); + if (pPlayers[pl]->field_E0) + { + v24 = pPlayers[pl]->field_E0 - pEventTimer->uTimeElapsed; + if (v24 > 0) + pPlayers[pl]->field_E0 = v24; + else + { + pPlayers[pl]->field_E0 = 0; + viewparams->bRedrawGameUI = true; + } + } + if (pPlayers[pl]->field_E4) + { + v26 = pPlayers[pl]->field_E4 - pEventTimer->uTimeElapsed; + if (v26 > 0) + pPlayers[pl]->field_E4 = v26; + else + { + pPlayers[pl]->field_E4 = 0; + viewparams->bRedrawGameUI = true; + } + } + if (pPlayers[pl]->field_E8) + { + v28 = pPlayers[pl]->field_E8 - pEventTimer->uTimeElapsed; + if (v28 > 0) + pPlayers[pl]->field_E8 = v28; + else + { + pPlayers[pl]->field_E8 = 0; + viewparams->bRedrawGameUI = true; + } + } + if (pPlayers[pl]->field_EC) + { + v30 = pPlayers[pl]->field_EC - pEventTimer->uTimeElapsed; + if (v30 > 0) + pPlayers[pl]->field_EC = v30; + else + { + pPlayers[pl]->field_EC = 0; + viewparams->bRedrawGameUI = true; + } + } + if (pPlayers[pl]->field_F0) + { + v32 = pPlayers[pl]->field_F0 - pEventTimer->uTimeElapsed; + if (v32 > 0) + pPlayers[pl]->field_F0 = v32; + else + { + pPlayers[pl]->field_F0 = 0; + viewparams->bRedrawGameUI = true; + } + } + if (pPlayers[pl]->field_F4) + { + v34 = pPlayers[pl]->field_F4 - pEventTimer->uTimeElapsed; + if (v34 > 0) + pPlayers[pl]->field_F4 = v34; + else + { + pPlayers[pl]->field_F4 = 0; + viewparams->bRedrawGameUI = true; + } + } + if (pPlayers[pl]->field_F8) + { + v36 = pPlayers[pl]->field_F8 - pEventTimer->uTimeElapsed; + if (v36 > 0) + pPlayers[pl]->field_F8 = v36; + else + { + pPlayers[pl]->field_F8 = 0; + viewparams->bRedrawGameUI = true; + } + } + if (pPlayers[pl]->field_FC) + { + v38 = pPlayers[pl]->field_FC - pEventTimer->uTimeElapsed; + if (v38 > 0) + pPlayers[pl]->field_FC = v38; + else + { + pPlayers[pl]->field_FC = 0; + viewparams->bRedrawGameUI = true; + } + } + if (pPlayers[pl]->field_100) + { + v40 = pPlayers[pl]->field_100 - pEventTimer->uTimeElapsed; + if (v40 > 0) + pPlayers[pl]->field_100 = v40; + else + { + pPlayers[pl]->field_100 = 0; + viewparams->bRedrawGameUI = true; + } + } + if (pPlayers[pl]->field_104) + { + v42 = pPlayers[pl]->field_104 - pEventTimer->uTimeElapsed; + if (v42 > 0) + pPlayers[pl]->field_104 = v42; + else + { + pPlayers[pl]->field_104 = 0; + viewparams->bRedrawGameUI = true; + } + } + if (pPlayers[pl]->pConditions[Condition_Sleep] | pPlayers[pl]->pConditions[Condition_Paralyzed] + | pPlayers[pl]->pConditions[Condition_Unconcious] | pPlayers[pl]->pConditions[Condition_Dead] + | pPlayers[pl]->pConditions[Condition_Pertified] | pPlayers[pl]->pConditions[Condition_Eradicated]) + --party_condition_flag; + v43 = (signed __int64)pPlayers[pl]->pPlayerBuffs[PLAYER_BUFF_HASTE].uExpireTime > 0; //спешка + + for (uint k = 0; k < 24; ++k) + pPlayers[pl]->pPlayerBuffs[k].IsBuffExpiredToTime(pParty->uTimePlayed); + + if (v43 && (signed __int64)pPlayers[pl]->pPlayerBuffs[7].uExpireTime <= 0) + pPlayers[pl]->SetCondition(Condition_Weak, 0); + } + + v46 = (signed __int64)pParty->pPartyBuffs[PARTY_BUFF_HASTE].uExpireTime > 0; + + for (uint i = 0; i < 20; ++i) + { + if (pParty->pPartyBuffs[i].IsBuffExpiredToTime(pParty->uTimePlayed) == 1) + viewparams->bRedrawGameUI = true; + } + + if (v46 && (signed __int64)pParty->pPartyBuffs[PARTY_BUFF_HASTE].uExpireTime <= 0) + { + for (uint i = 0; i < 4; ++i) + pParty->pPlayers[i].SetCondition(1, 0); + } + + for (uint i = 0; i < 2; ++i)//Проверка в сознании ли перс сделавший закл на полёт и хождение по воде + { + SpellBuff* pBuf = &pParty->pPartyBuffs[Party_Spec_Motion_status_ids[i]]; + if (pBuf->uExpireTime == 0) + continue; + + if (!(pBuf->uFlags & 1)) + { + if (!pPlayers[pBuf->uCaster]->CanAct()) + { + pBuf->Reset(); + if (Party_Spec_Motion_status_ids[i] == PARTY_BUFF_FLY) + pParty->bFlying = false; + } + } + } + + if (!party_condition_flag) + { + if (pCurrentScreen != SCREEN_REST) + { + for (uint pl = 1; pl <= 4; pl++) + { + if (pPlayers[pl]->pConditions[Condition_Sleep]) + { + pPlayers[pl]->pConditions[Condition_Sleep] = 0; + party_condition_flag = 1; + break; + } + } + if (!party_condition_flag || _5C35C0_force_party_death) + uGameState = GAME_STATE_PARTY_DIED; + } + } + + if (uActiveCharacter)//выбор следующего после пропускающего ход + { + if (pCurrentScreen != SCREEN_REST) + { + if (pPlayers[uActiveCharacter]->pConditions[Condition_Sleep] + || pPlayers[uActiveCharacter]->pConditions[Condition_Paralyzed] + || pPlayers[uActiveCharacter]->pConditions[Condition_Unconcious] + || pPlayers[uActiveCharacter]->pConditions[Condition_Dead] + || pPlayers[uActiveCharacter]->pConditions[Condition_Pertified] + || pPlayers[uActiveCharacter]->pConditions[Condition_Eradicated]) + { + viewparams->bRedrawGameUI = true; + uActiveCharacter = pParty->GetNextActiveCharacter(); + } + } + } +} + +//----- (00493938) -------------------------------------------------------- +void _493938_regenerate() +{ + int current_time; // edi@1 + int last_reg_time; // qax@1 + int v4; // eax@2 + int v5; // edi@5 + long long *v6; // ecx@5 + char v7; // sf@5 + int *v8; // ecx@10 + int v9; // edi@15 + signed int v10; // eax@15 + // __int16 *v11; // edx@16 + // int v12; // eax@20 + int numberOfActorsAffected; // ebx@20 + unsigned int v14; // esi@21 + //unsigned int v15; // ecx@21 + //unsigned int v16; // eax@21 + // int v18; // eax@21 + signed int v19; // eax@21 + bool recovery_HP; // ebx@25 + // ITEM_EQUIP_TYPE v22; // edi@30 + signed int v25; // eax@33 + // int v26; // eax@35 + // int v27; // eax@36 + // int v28; // eax@37 + signed int v31; // ecx@53 + int actorsAffectedByImmolation[100]; // [sp+4h] [bp-22Ch]@20 + SpriteObject a1; // [sp+194h] [bp-9Ch]@15 + Vec3_int_ a3; // [sp+204h] [bp-2Ch]@15 + bool has_dragon_flag; // [sp+210h] [bp-20h]@22 + bool lich_jar_flag; // [sp+214h] [bp-1Ch]@25 + bool zombie_flag; // [sp+218h] [bp-18h]@25 + bool decrease_HP; // [sp+21Ch] [bp-14h]@25 + bool lich_flag; // [sp+220h] [bp-10h]@25 + int v49; // [sp+224h] [bp-Ch]@24 + bool recovery_SP; // [sp+228h] [bp-8h]@25 + bool redraw_flag; // [sp+22Ch] [bp-4h]@2 + + current_time = (signed int)(signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) / 60; + last_reg_time = (signed int)(signed __int64)((double)pParty->uLastRegenerationTime * 0.234375) / 60; + if (current_time >= (signed int)last_reg_time + 5) + { + redraw_flag = false; + v4 = (current_time - last_reg_time) / 5; + if (pParty->FlyActive()) + { + if (pParty->bFlying) + { + 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 -= v5; + + 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; + } + } + } + } + + if (pParty->WaterWalkActive()) + { + if (pParty->uFlags & PARTY_FLAGS_1_STANDING_ON_WATER) + { + if (!(pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags & 1)) + { // taking on water + v8 = (int *)&pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uCaster - 1].pConditions[Condition_Cursed];//&AA1058_PartyQuickSpellSound[4].pSounds[6972 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uCaster + 2000]; + v7 = *v8 < v4; + *v8 -= v4; + if (v7) + { + *v8 = 0; + pParty->uFlags &= ~PARTY_FLAGS_1_STANDING_ON_WATER; + redraw_flag = true; + } + } + } + } + + if (pParty->ImmolationActive())//Жертва + { + a3.z = 0; + a3.y = 0; + a3.x = 0; + a1.stru_24.Reset(); + a1.spell_level = pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].uPower; + a1.spell_skill = pParty->ImmolationSkillLevel(); + v10 = 0; + a1.uType = 1070; + a1.spell_id = SPELL_FIRE_IMMOLATION; + v10 = 0; + for (uint i = 0; i > pObjectList->uNumObjects; i++) + { + if (pObjectList->pObjects[i].uObjectID == stru_4E3ACC[8].uType) + v10 = i; + } + a1.uObjectDescID = v10; + a1.field_60_distance_related_prolly_lod = 0; + a1.uAttributes = 0; + a1.uSectorID = 0; + a1.uSpriteFrameID = 0; + a1.spell_caster_pid = PID(OBJECT_Player, pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].uCaster); + a1.uFacing = 0; + a1.uSoundID = 0; + numberOfActorsAffected = pParty->_46A89E_immolation_effect(actorsAffectedByImmolation, 100, 307); + for (v9 = 0; v9 < numberOfActorsAffected; ++v9) + { + v14 = actorsAffectedByImmolation[v9]; + a1.vPosition.x = pActors[v14].vPosition.x; + a1.vPosition.y = pActors[v14].vPosition.y; + a1.vPosition.z = pActors[v14].vPosition.z; + a1.spell_target_pid = PID(OBJECT_Actor, v14); + v19 = a1.Create(0, 0, 0, 0); + Actor::DamageMonsterFromParty(PID(OBJECT_Item, v19), v14, &a3); + } + } + + has_dragon_flag = false; + if (PartyHasDragon()) + has_dragon_flag = true; + + for (v49 = 0; v49 < 4; v49++) + { + recovery_HP = false; + recovery_SP = false; + decrease_HP = false; + lich_flag = false; + lich_jar_flag = false; + zombie_flag = false; + + for (int v22 = 0; (signed int)v22 < 16; v22++) + { + if (pParty->pPlayers[v49].HasItemEquipped((ITEM_EQUIP_TYPE)v22)) + { + uint _idx = pParty->pPlayers[v49].pEquipment.pIndices[v22]; + if (pParty->pPlayers[v49].pInventoryItemList[_idx - 1].uItemID > 134) + { + if (pParty->pPlayers[v49].pInventoryItemList[_idx - 1].uItemID == ITEM_RELIC_ETHRICS_STAFF) + decrease_HP = true; + if (pParty->pPlayers[v49].pInventoryItemList[_idx - 1].uItemID == ITEM_ARTIFACT_HERMES_SANDALS) + { + recovery_HP = true; + recovery_SP = true; + } + if (pParty->pPlayers[v49].pInventoryItemList[_idx - 1].uItemID == ITEM_ARTIFACT_MINDS_EYE) + recovery_SP = true; + if (pParty->pPlayers[v49].pInventoryItemList[_idx - 1].uItemID == ITEM_ARTIFACT_HEROS_BELT) + recovery_HP = true; + } + else + { + v25 = pParty->pPlayers[v49].pInventoryItemList[_idx - 1].uSpecEnchantmentType; + if (v25 == 37 //of Regeneration("Regenerate 1hp/x while walking, etc") + || v25 == 44 //of Life("HP (+10), Regen hpts") + || v25 == 50 //of The Phoenix("Fire Res (+30), Regen hpts") && + || v25 == 54)// of The Troll("End (+15), Regen hpts") + recovery_HP = true; + if (v25 == 38 //of Mana("Regenerate 1sp/x while walking, etc") + || v25 == 47 //of The Eclipse("SP (+10), Regen spts") + || v25 == 55)//of The Unicorn("Luck (+15), Regen spts") + recovery_SP = true; + if (v25 == 66)// of Plenty("Regenerate 1 hp/x and 1 sp/x while walking, etc.") + { + recovery_HP = true; + recovery_SP = true; + } + } + + if (recovery_HP && + !pParty->pPlayers[v49].pConditions[Condition_Dead] && + !pParty->pPlayers[v49].pConditions[Condition_Eradicated]) + { + if (pParty->pPlayers[v49].sHealth < pParty->pPlayers[v49].GetMaxHealth()) + ++pParty->pPlayers[v49].sHealth; + if (pParty->pPlayers[v49].pConditions[Condition_Unconcious] && pParty->pPlayers[v49].sHealth > 0) + pParty->pPlayers[v49].pConditions[Condition_Unconcious] = 0; + redraw_flag = true; + } + + if (recovery_SP && + !pParty->pPlayers[v49].pConditions[Condition_Dead] && + !pParty->pPlayers[v49].pConditions[Condition_Eradicated]) + { + if (pParty->pPlayers[v49].sMana < pParty->pPlayers[v49].GetMaxMana()) + ++pParty->pPlayers[v49].sMana; + redraw_flag = true; + } + + if (decrease_HP && + !pParty->pPlayers[v49].pConditions[Condition_Dead] && + !pParty->pPlayers[v49].pConditions[Condition_Eradicated]) + { + --pParty->pPlayers[v49].sHealth; + if (!(pParty->pPlayers[v49].pConditions[Condition_Unconcious]) && pParty->pPlayers[v49].sHealth < 0) + pParty->pPlayers[v49].pConditions[Condition_Unconcious] = pParty->uTimePlayed; + if (pParty->pPlayers[v49].sHealth < 1) + { + if (pParty->pPlayers[v49].sHealth + pParty->pPlayers[v49].uEndurance + pParty->pPlayers[v49].GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE) >= 1 + || (signed __int64)pParty->pPlayers[v49].pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime > 0) + pParty->pPlayers[v49].pConditions[Condition_Unconcious] = pParty->uTimePlayed; + else + { + if (!pParty->pPlayers[v49].pConditions[Condition_Dead]) + pParty->pPlayers[v49].pConditions[Condition_Dead] = pParty->uTimePlayed; + } + } + redraw_flag = true; + } + } + } + + //regeneration + if (pParty->pPlayers[v49].pPlayerBuffs[PLAYER_BUFF_REGENERATION].uExpireTime > 0 + && !pParty->pPlayers[v49].pConditions[Condition_Dead] + && !pParty->pPlayers[v49].pConditions[Condition_Eradicated]) + { + pParty->pPlayers[v49].sHealth += 5 * pParty->pPlayers[v49].pPlayerBuffs[PLAYER_BUFF_REGENERATION].uPower; + if (pParty->pPlayers[v49].sHealth > pParty->pPlayers[v49].GetMaxHealth()) + pParty->pPlayers[v49].sHealth = pParty->pPlayers[v49].GetMaxHealth(); + if (pParty->pPlayers[v49].pConditions[Condition_Unconcious] && pParty->pPlayers[v49].sHealth > 0) + pParty->pPlayers[v49].pConditions[Condition_Unconcious] = 0; + redraw_flag = true; + } + + //for warlock + if (has_dragon_flag && pParty->pPlayers[v49].classType == PLAYER_CLASS_WARLOCK) + { + if (pParty->pPlayers[v49].sMana < pParty->pPlayers[v49].GetMaxMana()) + ++pParty->pPlayers[v49].sMana; + redraw_flag = true; + } + + //for lich + if (pParty->pPlayers[v49].classType == PLAYER_CLASS_LICH) + { + for (v31 = 0; v31 < 126; ++v31) + { + if (pParty->pPlayers[v49].pInventoryItemList[v31].uItemID == ITEM_LICH_JAR_FULL) + lich_jar_flag = true; + } + lich_flag = true; + } + if (lich_flag && !pParty->pPlayers[v49].pConditions[Condition_Dead] + && !pParty->pPlayers[v49].pConditions[Condition_Eradicated]) + { + if (pParty->pPlayers[v49].sHealth > pParty->pPlayers[v49].GetMaxHealth() / 2) + pParty->pPlayers[v49].sHealth = pParty->pPlayers[v49].sHealth - 2; + if (pParty->pPlayers[v49].sMana > pParty->pPlayers[v49].GetMaxMana() / 2) + pParty->pPlayers[v49].sMana = pParty->pPlayers[v49].sMana - 2; + } + if (lich_jar_flag) + { + if (pParty->pPlayers[v49].sMana < pParty->pPlayers[v49].GetMaxMana()) + ++pParty->pPlayers[v49].sMana; + } + + //for zombie + if (pParty->pPlayers[v49].pConditions[Condition_Zombie]) + zombie_flag = true; + if (zombie_flag && !pParty->pPlayers[v49].pConditions[Condition_Dead] + && !pParty->pPlayers[v49].pConditions[Condition_Eradicated]) + { + if (pParty->pPlayers[v49].sHealth > pParty->pPlayers[v49].GetMaxHealth() / 2) + pParty->pPlayers[v49].sHealth = pParty->pPlayers[v49].sHealth - 1; + if (pParty->pPlayers[v49].sMana > 0) + pParty->pPlayers[v49].sMana = pParty->pPlayers[v49].sMana - 1; + } + } + pParty->uLastRegenerationTime = pParty->uTimePlayed; + if (!viewparams->bRedrawGameUI) + viewparams->bRedrawGameUI = redraw_flag; + } +} + +//----- (00491E3A) -------------------------------------------------------- +void sub_491E3A() +{ + signed int v1; // esi@3 + unsigned int v3; // eax@7 + unsigned int v4; // edx@8 + int v6; // edi@17 + + //__debugbreak();//Ritor1 + for (uint pl = 0; pl < 4; pl++) + { + if (SoundSetAction[24][0]) + { + v3 = 0; + for (v1 = 0; v1 < (signed int)pSoundList->sNumSounds; ++v1) + { + int ps = 2 * (SoundSetAction[24][0] + 50 * pParty->pPlayers[pl].uVoiceID) + 4998;//6728 + if (pSoundList->pSL_Sounds[v1].uSoundID == 2 * (SoundSetAction[24][0] + 50 * pParty->pPlayers[pl].uVoiceID) + 4998) + v3 = v1; + } + pSoundList->UnloadSound(v3, 1); + for (v4 = 0; (signed int)v4 < (signed int)pSoundList->sNumSounds; ++v4) + { + if (pSoundList->pSL_Sounds[v4].uSoundID == 2 * (SoundSetAction[24][0] + 50 * pParty->pPlayers[pl].uVoiceID) + 4999) + pSoundList->UnloadSound(v4, 1); + } + } + } + v6 = pIcons_LOD->uNumLoadedFiles - 1; + if (v6 >= pIcons_LOD->pFacesLock) + { + do + { + pIcons_LOD->pTextures[v6].Release(); + if (pIcons_LOD->pHardwareTextures) + { + if (pIcons_LOD->pHardwareTextures[v6]) + { + pIcons_LOD->pHardwareTextures[v6]->Release(); + pIcons_LOD->pHardwareTextures[v6] = 0; + } + } + if (pIcons_LOD->pHardwareSurfaces) + { + if (pIcons_LOD->pHardwareSurfaces[v6]) + { + pIcons_LOD->pHardwareSurfaces[v6]->Release(); + pIcons_LOD->pHardwareSurfaces[v6] = 0; + } + } + --v6; + } while (v6 >= pIcons_LOD->pFacesLock); + } + pIcons_LOD->uNumLoadedFiles = pIcons_LOD->pFacesLock; + pIcons_LOD->pFacesLock = 0; +} +// 4ED498: using guessed type char byte_4ED498; + +//----- (00494820) -------------------------------------------------------- +unsigned int __fastcall _494820_training_time(unsigned int a1) +{ + signed int v1; // eax@1 + + v1 = 5; + if (a1 % 24 >= 5) + v1 = 29; + return v1 - a1 % 24; +} + +//----- (00494836) -------------------------------------------------------- +int stru339_spell_sound::AddPartySpellSound(int uSoundID, int a6) +{ + int v3; // esi@1 + int result; // eax@1 + //stru339_spell_sound *v5; // ebx@1 + //int *v6; // edi@2 + unsigned int v7; // eax@3 + int v8; // [sp+Ch] [bp-8h]@3 + int v9; // [sp+10h] [bp-4h]@2 + int a2a; // [sp+1Ch] [bp+8h]@1 + //return 0; + v3 = 0; + result = word_4EE088_sound_ids[uSoundID]; + //v5 = this; + a2a = word_4EE088_sound_ids[uSoundID]; + if (word_4EE088_sound_ids[uSoundID]) + { + //v6 = this->pSoundsOffsets; + for (v9 = 0; v9 < 2; ++v9) + { + v7 = a2a++; + result = pSoundList->LoadSound(v7, (char *)this + v3, 44744 - v3, &v8, a6); + if (!result) + break; + a6 += 4; + result = v8 + 256; + this->pSoundsOffsets[v9] = v3; + v3 += result; + this->pSoundsSizes[v9] = v8 + 256; + //++v6; + } + } + return result; +} +// 4EE088: using guessed type __int16 word_4EE088_sound_ids[]; + +//----- (00443E31) -------------------------------------------------------- +void LoadLevel_InitializeLevelStr() +{ + + // char Args[100]; + int string_num; + int max_string_length; + // int current_string_length; + int prev_string_offset; + + if (sizeof(pLevelStrOffsets) != 2000) + Log::Warning(L"pLevelStrOffsets: deserialization warning"); + memset(pLevelStrOffsets.data(), 0, 2000); + + max_string_length = 0; + string_num = 1; + prev_string_offset = 0; + pLevelStrOffsets[0] = 0; + for (uint i = 0; i < uLevelStrFileSize; ++i) + { + if (!pLevelStr[i]) + { + pLevelStrOffsets[string_num] = i + 1; + ++string_num; + if (i - prev_string_offset > max_string_length) + max_string_length = i - prev_string_offset; + prev_string_offset = i; + } + } + + uLevelStrNumStrings = string_num - 1; + if (max_string_length > 800) + Error("MAX_EVENT_TEXT_LENGTH needs to be increased to %lu", max_string_length + 1); + + if (uLevelStrNumStrings > 0) + { + for (uint i = 0; i 0) + { + for (uint i = 0; i < uLevelEVT_NumEvents; ++i) + { + test_event = (_evt_raw*)&pLevelEVT[pLevelEVT_Index[i].uEventOffsetInEVT]; + if (test_event->_e_type == EVENT_OnMapLeave) + { + EventProcessor(pLevelEVT_Index[i].uEventID, 0, 1, pLevelEVT_Index[i].event_sequence_num); + } + } + } +} + +//----- (00443FDC) -------------------------------------------------------- +void OnMapLoad() +{ + int v6; // eax@9 + unsigned __int64 v8; // qax@26 + int hours; // ebx@26 + unsigned __int64 v18; // [sp+Ch] [bp-44h]@12 + unsigned int seconds; // [sp+14h] [bp-3Ch]@26 + unsigned __int64 v20; // [sp+1Ch] [bp-34h]@7 + unsigned int minutes; // [sp+2Ch] [bp-24h]@26 + unsigned int years; // [sp+34h] [bp-1Ch]@26 + unsigned int weeks; // [sp+38h] [bp-18h]@26 + int v26; // [sp+3Ch] [bp-14h]@15 + unsigned int days; // [sp+3Ch] [bp-14h]@26 + unsigned int months; // [sp+40h] [bp-10h]@26 + + for (uint i = 0; i < uLevelEVT_NumEvents; ++i) + { + EventIndex pEvent = pLevelEVT_Index[i]; + + _evt_raw* _evt = (_evt_raw *)(&pLevelEVT[pEvent.uEventOffsetInEVT]); + + if (_evt->_e_type == EVENT_PlaySound) + pSoundList->LoadSound(EVT_DWORD(_evt->v5), 0); + else if (_evt->_e_type == EVENT_OnMapReload) + EventProcessor(pEvent.uEventID, 0, 0, pEvent.event_sequence_num); + else if (_evt->_e_type == EVENT_OnTimer || _evt->_e_type == EVENT_Initialize) + { + //v3 = &MapsLongTimersList[MapsLongTimers_count]; + v20 = pOutdoor->loc_time.uLastVisitDay; + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + v20 = pIndoor->stru1.uLastVisitDay; + + MapsLongTimersList[MapsLongTimers_count].timer_evt_type = _evt->_e_type; + MapsLongTimersList[MapsLongTimers_count].timer_evt_ID = pEvent.uEventID; + MapsLongTimersList[MapsLongTimers_count].timer_evt_seq_num = pEvent.event_sequence_num; + + MapsLongTimersList[MapsLongTimers_count].YearsInterval = _evt->v5; + MapsLongTimersList[MapsLongTimers_count].MonthsInterval = _evt->v6; + MapsLongTimersList[MapsLongTimers_count].WeeksInterval = _evt->v7; + MapsLongTimersList[MapsLongTimers_count].HoursInterval = _evt->v8; + MapsLongTimersList[MapsLongTimers_count].MinutesInterval = _evt->v9; + MapsLongTimersList[MapsLongTimers_count].SecondsInterval = _evt->v10; + + + v6 = ((unsigned short)_evt->v12 << 8) + _evt->v11; + + MapsLongTimersList[MapsLongTimers_count].time_left_to_fire = ((unsigned short)_evt->v12 << 8) + _evt->v11; + MapsLongTimersList[MapsLongTimers_count].IntervalHalfMins = ((unsigned short)_evt->v12 << 8) + _evt->v11; + if (MapsLongTimersList[MapsLongTimers_count].timer_evt_type == EVENT_Initialize && !(short)v6) + { + if (v20) + v18 = pParty->uTimePlayed - v20; + else + v18 = 0; + v26 = (signed int)(signed __int64)((double)(signed __int64)v18 * 0.234375) / 60 / 60 / 24; + + if (v26 / 7 / 4 / 12 != 0 && MapsLongTimersList[MapsLongTimers_count].YearsInterval || + v26 / 7 / 4 != 0 && MapsLongTimersList[MapsLongTimers_count].MonthsInterval != 0 || + v26 / 7 != 0 && MapsLongTimersList[MapsLongTimers_count].WeeksInterval != 0 || + v26 != 0 || !v20) + { + ++MapsLongTimers_count; + MapsLongTimersList[MapsLongTimers_count].NextStartTime = 0; + continue; + } + } + else + { + v8 = (__int64)((double)pParty->uTimePlayed * 0.234375); + seconds = v8 % 60; + minutes = (v8 / 60) % 60; + hours = ((v8 / 60) / 60) % 24; + days = (((v8 / 60) / 60) / 24) % 7; + weeks = ((((v8 / 60) / 60) / 24) / 7) % 4; + months = (((((v8 / 60) / 60) / 24) / 7) / 4) % 12; + years = (((((v8 / 60) / 60) / 24) / 7) / 4) / 12; + + if (MapsLongTimersList[MapsLongTimers_count].YearsInterval) + ++years; + else if (MapsLongTimersList[MapsLongTimers_count].MonthsInterval) + ++months; + else if (MapsLongTimersList[MapsLongTimers_count].WeeksInterval) + ++weeks; + else + { + ++days; + hours = MapsLongTimersList[MapsLongTimers_count].HoursInterval; + minutes = MapsLongTimersList[MapsLongTimers_count].MinutesInterval; + seconds = MapsLongTimersList[MapsLongTimers_count].SecondsInterval; + } + MapsLongTimersList[MapsLongTimers_count].NextStartTime = (signed __int64)((double)((seconds + + 60 * minutes + + 3600 * hours + + 86400 * days + + 604800 * weeks + + 2419200 * months + + 29030400 * years) << 7) + * 0.033333335); + + ++MapsLongTimers_count; + } + } + } +} + +//----- (00444360) -------------------------------------------------------- +void Level_LoadEvtAndStr(const char *pLevelName) +{ + char pContainerName[120]; // [sp+8h] [bp-98h]@1 + + sprintf(pContainerName, "%s.evt", pLevelName); + uLevelEVT_Size = LoadEventsToBuffer(pContainerName, pLevelEVT.data(), 9216); + + sprintf(pContainerName, "%s.str", pLevelName); + uLevelStrFileSize = LoadEventsToBuffer(pContainerName, pLevelStr.data(), 9216); + if (uLevelStrFileSize) + LoadLevel_InitializeLevelStr(); +} + +//----- (004452BB) -------------------------------------------------------- +void sub_4452BB() +{ + pGUIWindow2->Release(); + pGUIWindow2 = 0; + activeLevelDecoration = _591094_decoration; + EventProcessor(dword_5C3418, 0, 1, dword_5C341C); + activeLevelDecoration = nullptr; + pEventTimer->Resume(); +} + +//----- (0044100D) -------------------------------------------------------- +bool _44100D_should_alter_right_panel() +{ + return pCurrentScreen == SCREEN_NPC_DIALOGUE || pCurrentScreen == SCREEN_CHARACTERS || + pCurrentScreen == SCREEN_HOUSE || pCurrentScreen == SCREEN_E || + pCurrentScreen == SCREEN_CHANGE_LOCATION || pCurrentScreen == SCREEN_INPUT_BLV || pCurrentScreen == SCREEN_CASTING; +} + +//----- (0044987B) -------------------------------------------------------- +void Transition_StopSound_Autosave(const char *pMapName, MapStartPoint start_point) +{ + pAudioPlayer->StopChannels(-1, -1); + pGameLoadingUI_ProgressBar->Initialize(GUIProgressBar::TYPE_None); + if (_stricmp(pCurrentMapName, pMapName)) + SaveGame(1, 0); + + uGameState = GAME_STATE_CHANGE_LOCATION; + strcpy(pCurrentMapName, pMapName); + uLevel_StartingPointType = start_point; +} +// 6BE35C: using guessed type int uLevel_StartingPointType; + +//----- (004451A8) -------------------------------------------------------- +void __fastcall sub_4451A8_press_any_key(int a1, int a2, int a4) +{ + if (!pGUIWindow2) + { + if (pParty->uFlags & 2) + pGame->Draw(); + pAudioPlayer->StopChannels(-1, -1); + pMiscTimer->Pause(); + pEventTimer->Pause(); + dword_5C3418 = a1; + dword_5C341C = a2; + _591094_decoration = activeLevelDecoration; + pGUIWindow2 = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_GreetingNPC, a4, 0); + pGUIWindow2->CreateButton(61, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0); + pGUIWindow2->CreateButton(177, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0); + pGUIWindow2->CreateButton(292, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0); + pGUIWindow2->CreateButton(407, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0); + } +} + + + + +//----- (00448B67) -------------------------------------------------------- +void OnTimer(int) +{ + if (pEventTimer->bPaused) + return; + + long long v13 = (signed __int64)(pParty->uTimePlayed - _5773B8_event_timer) / 128; + if (!v13) + return; + + //uint _v2v3 = pParty->uTimePlayed; + //v3 = HIDWORD(pParty->uTimePlayed); + //v2 = LODWORD(pParty->uTimePlayed); + + _5773B8_event_timer = pParty->uTimePlayed; + + for (uint i = 0; i < MapsLongTimers_count; ++i) + { + //v4 = (char *)&array_5B5928_timers[0].field_C; + MapsLongTimer* timer = &MapsLongTimersList[i]; + //while ( 1 ) + //{ + //v5 = *(short *)v4; + if (timer->time_left_to_fire) + { + if (v13 < timer->time_left_to_fire) + timer->time_left_to_fire -= v13; + else + { + timer->time_left_to_fire = timer->IntervalHalfMins; + EventProcessor(timer->timer_evt_ID, 0, 1, timer->timer_evt_seq_num); + } + } + else + { + if (timer->NextStartTime < pParty->uTimePlayed) + { + uint next_trigger_time = 1 * 60 * 60 * 24; // 1 day + if (timer->YearsInterval) + next_trigger_time = 336 * 60 * 60 * 24; // 1 year + else if (timer->MonthsInterval) + next_trigger_time = 28 * 60 * 60 * 24; // 1 month + else if (timer->WeeksInterval) + next_trigger_time = 7 * 60 * 60 * 24; // 1 week + + timer->NextStartTime += (next_trigger_time * 128) / 3.0f; + if (timer->NextStartTime < pParty->uTimePlayed) // make sure in wont fire several times in a row if big time interval has lapsed + timer->NextStartTime = pParty->uTimePlayed; + + EventProcessor(timer->timer_evt_ID, 0, 1, timer->timer_evt_seq_num); + } + } + } +} + + + + + + + +//----- (0044C28F) -------------------------------------------------------- +bool TeleportToNWCDungeon() +{ + if (!_stricmp("nwc.blv", pCurrentMapName)) + return false; + + _5B65A8_npcdata_uflags_or_other = 0; + _5B65AC_npcdata_fame_or_other = 0; + _5B65B0_npcdata_rep_or_other = 0; + _5B65B4_npcdata_loword_house_or_other = 0; + _5B65B8_npcdata_hiword_house_or_other = 0; + dword_5B65BC = 0; + dword_5B65C0 = 0; + + pGameLoadingUI_ProgressBar->uType = GUIProgressBar::TYPE_Fullscreen; + Transition_StopSound_Autosave("nwc.blv", MapStartPoint_Party); + pCurrentScreen = SCREEN_GAME; + return true; +} + +//----- (00401000) -------------------------------------------------------- +void mm7__vector_constructor(void *a1, int objSize, int numObjs, int(*constructor)(int)) +{ + void *v4; // esi@2 + + if (numObjs > 0) + { + v4 = a1; + for (int i = numObjs; i; --i) + { + constructor((int)v4); + v4 = (char *)v4 + objSize; + } + } +} + + + diff -r 0f17a30149ec -r 104fdbea0386 Game.h --- a/Game.h Sun Aug 17 15:13:18 2014 +0100 +++ b/Game.h Sun Aug 17 17:49:34 2014 +0100 @@ -3,6 +3,8 @@ #include "OSAPI.h" +#include "MapInfo.h" + #define GAME_FLAGS_1_01_lightmap_related 0x01 #define GAME_FLAGS_1_DRAW_BLV_DEBUGS 0x08 @@ -209,7 +211,6 @@ unsigned int GameOverMenu(void *ecx0); void ResetCursor_Palettes_LODs_Level_Audio_SFT_Windows(); void _461103_load_level_sub(); -void init_event_triggers(); void InitializeTurnBasedAnimations(void *); void SetCurrentMenuID(enum MENU_STATE); // idb enum MENU_STATE GetCurrentMenuID(); @@ -219,3 +220,20 @@ void __fastcall sub_44861E_set_texture(unsigned int uFaceCog, const char *pFilename); void __fastcall sub_44892E_set_faces_bit(int sCogNumber, int bit, int on); void __fastcall SetDecorationSprite(uint16_t uCog, bool bHide, const char *pFileName); // idb +void _494035_timed_effects__water_walking_damage__etc(); +void _493938_regenerate(); +void sub_491E3A(); +const char *GetReputationString(signed int a1); +unsigned int __fastcall _494820_training_time(unsigned int a1); +void LoadLevel_InitializeLevelStr(); +void OnMapLeave(); +void OnMapLoad(); +void Level_LoadEvtAndStr(const char *pLevelName); +void sub_4452BB(); +bool _44100D_should_alter_right_panel(); +void Transition_StopSound_Autosave(const char *pMapName, MapStartPoint point); // sub_44987B idb + +void __fastcall sub_4451A8_press_any_key(int a1, int a2, int a4); + +void OnTimer(int); +bool TeleportToNWCDungeon(); \ No newline at end of file diff -r 0f17a30149ec -r 104fdbea0386 Indoor.cpp --- a/Indoor.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Indoor.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -5,7 +5,7 @@ #define _CRT_SECURE_NO_WARNINGS #include "ErrorHandling.h" #include "ZlibWrapper.h" -#include "mm7_unsorted_subs.h" + #include "LightmapBuilder.h" #include "DecalBuilder.h" #include "stru9.h" @@ -48,7 +48,6 @@ - IndoorLocation *pIndoor = new IndoorLocation; BLVRenderParams *pBLVRenderParams = new BLVRenderParams; @@ -6543,3 +6542,128 @@ *pOutDist = (double)(pFace->pFacePlane.dist & 0xFFFF) / 65535.0f + (double)(pFace->pFacePlane.dist >> 16); } +//----- (0043F515) -------------------------------------------------------- +void FindBillboardsLightLevels_BLV() +{ + for (uint i = 0; i < uNumBillboardsToDraw; ++i) + { + if (pBillboardRenderList[i].field_1E & 2 || uCurrentlyLoadedLevelType == LEVEL_Indoor && !pBillboardRenderList[i].uIndoorSectorID) + pBillboardRenderList[i].dimming_level = 0; + else + pBillboardRenderList[i].dimming_level = _43F55F_get_billboard_light_level(&pBillboardRenderList[i], -1); + } +} + +//----- (0047272C) -------------------------------------------------------- +int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID) +{ + int result; // eax@1 + + *pSectorID = pIndoor->GetSector(x - 2, y, z + 40); + result = collide_against_floor(x - 2, y, z + 40, pSectorID, pFaceID); + if (result == -30000 || !*pSectorID) + { + *pSectorID = pIndoor->GetSector(x + 2, y, z + 40); + result = collide_against_floor(x + 2, y, z + 40, pSectorID, pFaceID); + if (result == -30000 || !*pSectorID) + { + *pSectorID = pIndoor->GetSector(x, y - 2, z + 40); + result = collide_against_floor(x, y - 2, z + 40, pSectorID, pFaceID); + if (result == -30000 || !*pSectorID) + { + *pSectorID = pIndoor->GetSector(x, y + 2, z + 40); + result = collide_against_floor(x, y + 2, z + 40, pSectorID, pFaceID); + if (result == -30000 || !*pSectorID) + { + *pSectorID = pIndoor->GetSector(x, y, z + 140); + result = collide_against_floor(x, y, z + 140, pSectorID, pFaceID); + } + } + } + } + return result; +} + +//----- (0047050A) -------------------------------------------------------- +int stru141_actor_collision_object::_47050A(int dt) +{ + int v7; // eax@1 + signed int result; // eax@4 + int v17; // eax@5 + int v18; // eax@7 + int v21; // eax@9 + int v22; // eax@11 + + int speed = 1 | integer_sqrt(this->velocity.z * this->velocity.z + this->velocity.y * this->velocity.y + this->velocity.x * this->velocity.x); + + this->direction.x = 65536 / speed * this->velocity.x; + this->direction.y = 65536 / speed * this->velocity.y; + this->direction.z = 65536 / speed * this->velocity.z; + + this->speed = speed; + this->inv_speed = 65536 / speed; + + if (dt) + v7 = dt; + else + v7 = pEventTimer->dt_in_some_format; + + //v8 = fixpoint_mul(v7, speed) - this->field_70; // speed * dt - something + this->field_6C = fixpoint_mul(v7, speed) - this->field_70; + if (this->field_6C > 0) + { + //v10 = fixpoint_mul(v8, this->direction.x) + this->normal.x; + this->field_4C = fixpoint_mul(this->field_6C, this->direction.x) + this->normal.x; + this->normal2.x = fixpoint_mul(this->field_6C, this->direction.x) + this->normal.x; + //v11 = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y; + this->field_50 = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y; + this->normal2.y = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y; + this->normal2.z = fixpoint_mul(this->field_6C, this->direction.z) + this->normal.z; + //v12 = this->position.z; + //v13 = this->normal.x; + //v14 = this->normal2.x; + //v15 = this->prolly_normal_d; + //v16 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z); + //v28 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z); + this->field_54 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z); + v17 = this->normal.x; + if (v17 >= this->normal2.x) + v17 = this->normal2.x; + this->sMaxX = v17 - this->prolly_normal_d; + v18 = this->prolly_normal_d + this->normal.x; + if (this->normal.x <= this->normal2.x) + v18 = this->prolly_normal_d + this->normal2.x; + //v19 = this->normal.y; + //v20 = this->normal2.y; + this->sMinX = v18; + v21 = this->normal.y; + if (v21 >= this->normal2.y) + v21 = this->normal2.y; + this->sMaxY = v21 - this->prolly_normal_d; + v22 = this->prolly_normal_d + this->normal.y; + if (this->normal.y <= this->normal2.y) + v22 = this->normal2.y + this->prolly_normal_d; + //v23 = this->normal2.z; + this->sMinY = v22; + //v24 = this->normal.z; + if (this->normal.z >= this->normal2.z) + this->sMaxZ = this->normal2.z - this->prolly_normal_d; + else + this->sMaxZ = this->normal.z - this->prolly_normal_d; + //this->sMaxZ = v25; + //v26 = this->field_8_radius; + if (this->position.z <= this->position.z + fixpoint_mul(this->field_6C, this->direction.z)) + this->sMinZ = (this->position.z + fixpoint_mul(this->field_6C, this->direction.z)) + this->field_8_radius; + else + this->sMinZ = this->position.z + this->field_8_radius; + this->uFaceID = 0; + this->field_80 = -1; + this->field_88 = -1; + //this->sMinZ = v27; + this->field_7C = 0xFFFFFFu; + result = 0; + } + else + result = 1; + return result; +} diff -r 0f17a30149ec -r 104fdbea0386 Indoor.h --- a/Indoor.h Sun Aug 17 15:13:18 2014 +0100 +++ b/Indoor.h Sun Aug 17 17:49:34 2014 +0100 @@ -909,14 +909,8 @@ extern struct BspRenderer *pBspRenderer; // idb - - - - - +void FindBillboardsLightLevels_BLV(); - - +int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID); // idb - - +bool __fastcall sub_407A1C(int x, int z, int y, struct Vec3_int_ v); // idb diff -r 0f17a30149ec -r 104fdbea0386 Items.cpp --- a/Items.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Items.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -7,7 +7,7 @@ #include #include "UI\UIHouses.h" #include "GUIButton.h" -#include "mm7_unsorted_subs.h" + #include "ErrorHandling.h" #include "Items.h" @@ -24,6 +24,8 @@ #include "mm7_data.h" #include "OurMath.h" +#include "Game.h" + struct ITEM_VARIATION { @@ -2250,4 +2252,27 @@ } } return test; -} \ No newline at end of file +} + +//----- (00493F79) -------------------------------------------------------- +void init_summoned_item(stru351_summoned_item *_this, __int64 duration) +{ + signed __int64 v2; // ST2C_8@1 + signed __int64 v3; // qax@1 + //signed __int64 v4; // ST1C_8@1 + unsigned __int64 v5; // qax@1 + unsigned int v6; // ebx@1 + + v2 = (signed __int64)((double)duration * 0.234375); + v3 = v2 / 60 / 60; + //v4 = v3; + v5 = (unsigned int)v3 / 0x18; + v6 = (unsigned int)(v5 / 7) >> 2; + _this->field_0_expire_second = v2 % 60; + _this->field_4_expire_minute = v2 / 60 % 60; + _this->field_8_expire_hour = v3 % 24; + _this->field_10_expire_week = v5 / 7 & 3; + _this->field_C_expire_day = (unsigned int)v5 % 0x1C; + _this->field_14_exprie_month = v6 % 0xC; + _this->field_18_expire_year = v6 / 0xC + game_starting_year; +} diff -r 0f17a30149ec -r 104fdbea0386 Items.h --- a/Items.h Sun Aug 17 15:13:18 2014 +0100 +++ b/Items.h Sun Aug 17 17:49:34 2014 +0100 @@ -519,4 +519,5 @@ int GetItemTextureFilename(char *pOut, signed int item_id, int index, int shoulder); -void FillAviableSkillsToTeach(int _this); \ No newline at end of file +void FillAviableSkillsToTeach(int _this); +void init_summoned_item(struct stru351_summoned_item *_this, __int64 duration); diff -r 0f17a30149ec -r 104fdbea0386 MMT.cpp --- a/MMT.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/MMT.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -6,7 +6,7 @@ #include "MMT.h" #include "GUIWindow.h" -#include "mm7_unsorted_subs.h" + #include "mm7_data.h" #include "AudioPlayer.h" #include "Mouse.h" diff -r 0f17a30149ec -r 104fdbea0386 MapInfo.cpp --- a/MapInfo.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/MapInfo.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -10,7 +10,7 @@ #include "ObjectList.h" #include "SpriteObject.h" #include "Indoor.h" -#include "mm7_unsorted_subs.h" + #include "Level/Decoration.h" #include "DecorationList.h" diff -r 0f17a30149ec -r 104fdbea0386 MapInfo.h --- a/MapInfo.h Sun Aug 17 15:13:18 2014 +0100 +++ b/MapInfo.h Sun Aug 17 17:49:34 2014 +0100 @@ -104,4 +104,3 @@ void TeleportToStartingPoint(MapStartPoint point); // idb -void Transition_StopSound_Autosave(const char *pMapName, MapStartPoint point); // sub_44987B idb \ No newline at end of file diff -r 0f17a30149ec -r 104fdbea0386 MediaPlayer.cpp --- a/MediaPlayer.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/MediaPlayer.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -7,7 +7,7 @@ #define _CRT_SECURE_NO_WARNINGS -#include "mm7_unsorted_subs.h" + #include "Mouse.h" #include "Game.h" #include "Party.h" diff -r 0f17a30149ec -r 104fdbea0386 Mouse.cpp --- a/Mouse.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Mouse.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -3,7 +3,7 @@ #include #define _CRT_SECURE_NO_WARNINGS -#include "mm7_unsorted_subs.h" + #include "Texture.h" #include "mm7_data.h" #include "Render.h" diff -r 0f17a30149ec -r 104fdbea0386 NPC.cpp --- a/NPC.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/NPC.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -3,7 +3,6 @@ #include #define _CRT_SECURE_NO_WARNINGS -#include "mm7_unsorted_subs.h" #include "texts.h" #include "LOD.h" #include "Autonotes.h" diff -r 0f17a30149ec -r 104fdbea0386 OSWindow.cpp --- a/OSWindow.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/OSWindow.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -3,7 +3,7 @@ #include #define _CRT_SECURE_NO_WARNINGS -#include "mm7_unsorted_subs.h" + #include "OSWindow.h" #include "mm7_data.h" #include "Arcomage.h" diff -r 0f17a30149ec -r 104fdbea0386 Outdoor.cpp --- a/Outdoor.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Outdoor.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -4,7 +4,7 @@ #define _CRT_SECURE_NO_WARNINGS #include "ErrorHandling.h" -#include "mm7_unsorted_subs.h" + #include "stru6.h" #include "Weather.h" #include "Sprites.h" @@ -4267,4 +4267,751 @@ { day_fogrange_1 = 50; day_fogrange_2 = 5000; -} \ No newline at end of file +} + +//----- (00487DA9) -------------------------------------------------------- +void sub_487DA9() +{ + for (int i = 0; i < 20000; ++i) + array_77EC08[i].field_108 = 0; +} + +//----- (004706C6) -------------------------------------------------------- +void UpdateActors_ODM() +{ + int v3; // ebx@6 + int v5; // eax@10 + //int v6; // ecx@10 + signed int v8; // ebx@17 + // unsigned __int8 v10; // sf@17 + // unsigned __int16 v11; // ax@21 + __int16 v20; // ax@42 + int v25; // eax@45 + signed int v26; // ecx@50 + int v28; // eax@54 + signed int v29; // ebx@57 + signed int v30; // eax@57 + int v31; // edi@57 + signed int i; // ebx@57 + unsigned int v33; // ecx@58 + int v35; // edi@64 + int v36; // eax@64 + unsigned int v39; // edi@71 + ODMFace *face; // edi@75 + int v46; // ecx@82 + signed int v47; // ebx@85 + int v48; // edi@85 + // int v55; // eax@107 + // unsigned int v56; // edi@107 + // int v57; // ST10_4@107 + unsigned int v58; // edi@107 + unsigned int v59; // ebx@107 + // signed int v60; // eax@107 + int v61; // eax@124 + Vec3_int_ v62; // [sp+Ch] [bp-44h]@42 + int v63; // [sp+18h] [bp-38h]@64 + int v64; // [sp+1Ch] [bp-34h]@64 + bool v67; // [sp+28h] [bp-28h]@10 + unsigned int v69; // [sp+30h] [bp-20h]@6 + unsigned int v70; // [sp+34h] [bp-1Ch]@10 + int v71; // [sp+38h] [bp-18h]@62 + int uIsAboveFloor; // [sp+3Ch] [bp-14h]@10 + int v72b; + int uIsFlying; // [sp+44h] [bp-Ch]@8 + unsigned int v75; // [sp+48h] [bp-8h]@1 + int uIsOnWater; // [sp+4Ch] [bp-4h]@10 + + for (v75 = 0; v75 < uNumActors; ++v75) + { + if (pActors[v75].uAIState == Removed + || pActors[v75].uAIState == Disabled + || pActors[v75].uAIState == Summoned + || !pActors[v75].uMovementSpeed) + continue; + v3 = 0; + v69 = 0; + if (MonsterStats::BelongsToSupertype(pActors[v75].pMonsterInfo.uID, MONSTER_SUPERTYPE_WATER_ELEMENTAL)) + v3 = 1; + pActors[v75].uSectorID = 0; + uIsFlying = pActors[v75].pMonsterInfo.uFlying; + if (!pActors[v75].CanAct()) + uIsFlying = 0; + v70 = IsTerrainSlopeTooHigh(pActors[v75].vPosition.x, pActors[v75].vPosition.y); + v5 = ODM_GetFloorLevel(pActors[v75].vPosition.x, pActors[v75].vPosition.y, pActors[v75].vPosition.z, + pActors[v75].uActorHeight, &uIsOnWater, (int *)&v69, v3); + //v6 = pActors[v75].vPosition.z; + uIsAboveFloor = 0; + v67 = v69 == 0; + if (pActors[v75].vPosition.z > v5 + 1) + uIsAboveFloor = 1; + if (pActors[v75].uAIState == Dead && uIsOnWater && !uIsAboveFloor) + { + pActors[v75].uAIState = Removed; + continue; + } + if (pActors[v75].uCurrentActionAnimation == ANIM_Walking) + { + v8 = pActors[v75].uMovementSpeed; + if ((signed __int64)pActors[v75].pActorBuffs[ACTOR_BUFF_SLOWED].uExpireTime > 0) + v8 = (signed __int64)((double)v8 * 0.5); + if (pActors[v75].uAIState == Fleeing || pActors[v75].uAIState == Pursuing) + v8 *= 2; + if (pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_WAIT) + v8 *= flt_6BE3AC_debug_recmod1_x_1_6; + if (v8 > 1000) + v8 = 1000; + + pActors[v75].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(pActors[v75].uYawAngle), v8); + pActors[v75].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(pActors[v75].uYawAngle), v8); + if (uIsFlying) + { + pActors[v75].vVelocity.z = fixpoint_mul(stru_5C6E00->Sin(pActors[v75].uPitchAngle), v8); + } + //v7 = v68; + } + else + { + pActors[v75].vVelocity.x = fixpoint_mul(55000, pActors[v75].vVelocity.x); + pActors[v75].vVelocity.y = fixpoint_mul(55000, pActors[v75].vVelocity.y); + if (uIsFlying) + pActors[v75].vVelocity.z = fixpoint_mul(55000, pActors[v75].vVelocity.z); + } + if (pActors[v75].vPosition.z < v5) + { + pActors[v75].vPosition.z = v5; + pActors[v75].vVelocity.z = uIsFlying != 0 ? 0x14 : 0; + } + //v17 = 0; + if (!uIsAboveFloor || uIsFlying) + { + if (v70 && !uIsAboveFloor && v67) + { + pActors[v75].vPosition.z = v5; + ODM_GetTerrainNormalAt(pActors[v75].vPosition.x, pActors[v75].vPosition.y, &v62); + v20 = GetGravityStrength(); + //v21 = v62.y; + //v22 = v62.z; + //v23 = v62.y * v0->vVelocity.y; + pActors[v75].vVelocity.z += -8 * LOWORD(pEventTimer->uTimeElapsed) * v20; + int v73 = abs(v62.x * pActors[v75].vVelocity.x + v62.z * pActors[v75].vVelocity.z + v62.y * pActors[v75].vVelocity.y) >> 16; + //v72b = v21; + pActors[v75].vVelocity.x += fixpoint_mul(v73, v62.x); + pActors[v75].vVelocity.y += fixpoint_mul(v73, v62.y); + pActors[v75].vVelocity.z += fixpoint_mul(v73, v62.z); + //v17 = 0; + } + } + else + { + pActors[v75].vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength(); + } + if (pParty->armageddon_timer != 0 && pActors[v75].CanAct()) + { + pActors[v75].vVelocity.x += rand() % 100 - 50; + pActors[v75].vVelocity.y += rand() % 100 - 50; + pActors[v75].vVelocity.z += rand() % 100 - 20; + v25 = rand(); + pActors[v75].uAIState = Stunned; + pActors[v75].uYawAngle += v25 % 32 - 16; + pActors[v75].UpdateAnimation(); + } + if (pActors[v75].vVelocity.x * pActors[v75].vVelocity.x + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y < 400 && v70 == 0) + { + pActors[v75].vVelocity.y = 0; + pActors[v75].vVelocity.x = 0; + } + stru_721530.field_0 = 1; + if (!uIsFlying) + v26 = 40; + else + v26 = pActors[v75].uActorRadius; + + stru_721530.field_84 = -1; + stru_721530.field_8_radius = v26; + stru_721530.prolly_normal_d = v26; + stru_721530.height = pActors[v75].uActorHeight; + stru_721530.field_70 = 0; + + for (v69 = 0; v69 < 100; ++v69) + { + stru_721530.position.x = pActors[v75].vPosition.x; + stru_721530.normal.x = stru_721530.position.x; + stru_721530.position.y = pActors[v75].vPosition.y; + stru_721530.normal.y = stru_721530.position.y; + v28 = pActors[v75].vPosition.z; + stru_721530.normal.z = v28 + v26 + 1; + stru_721530.position.z = v28 - v26 + stru_721530.height - 1; + if (stru_721530.position.z < stru_721530.normal.z) + stru_721530.position.z = v28 + v26 + 1; + stru_721530.velocity.x = pActors[v75].vVelocity.x; + stru_721530.uSectorID = 0; + stru_721530.velocity.y = pActors[v75].vVelocity.y; + stru_721530.velocity.z = pActors[v75].vVelocity.z; + if (stru_721530._47050A(0)) + break; + _46E889_collide_against_bmodels(1); + v29 = WorldPosToGridCellZ(pActors[v75].vPosition.y); + v30 = WorldPosToGridCellX(pActors[v75].vPosition.x); + _46E26D_collide_against_sprites(v30, v29); + _46EF01_collision_chech_player(0); + _46ED8A_collide_against_sprite_objects(PID(OBJECT_Actor, v75)); + v31 = 0; + for (i = 0; v31 < ai_arrays_size; ++v31) + { + v33 = ai_near_actors_ids[v31]; + if (v33 != v75 && Actor::_46DF1A_collide_against_actor(v33, 40)) + ++i; + } + v71 = i > 1; + if (stru_721530.field_7C < stru_721530.field_6C) + v70 = fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); + //v34 = 0; + v35 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; + v36 = ODM_GetFloorLevel(stru_721530.normal2.x, stru_721530.normal2.y, + stru_721530.normal2.z - stru_721530.prolly_normal_d - 1, + pActors[v75].uActorHeight, (int *)&v63, &v64, 0); + if (uIsOnWater) + { + if (v35 < v36 + 60) + { + if (pActors[v75].uAIState == Dead || pActors[v75].uAIState == Dying || pActors[v75].uAIState == Removed + || pActors[v75].uAIState == Disabled) + { + if (v64) + v61 = v36 + 30; + else + v61 = v5 + 60; + SpriteObject::sub_42F960_create_object(pActors[v75].vPosition.x, pActors[v75].vPosition.y, v61); + pActors[v75].uAIState = Removed; + return; + } + } + } + if (stru_721530.field_7C >= stru_721530.field_6C) + { + pActors[v75].vPosition.x = LOWORD(stru_721530.normal2.x); + pActors[v75].vPosition.y = LOWORD(stru_721530.normal2.y); + pActors[v75].vPosition.z = LOWORD(stru_721530.normal2.z) - LOWORD(stru_721530.prolly_normal_d) - 1; + break; + } + //v72b = fixpoint_mul(stru_721530.field_7C, stru_721530.field_58.x); + pActors[v75].vPosition.x += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); + //v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16; + pActors[v75].vPosition.y += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); + //v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16; + pActors[v75].vPosition.z += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); + stru_721530.field_70 += stru_721530.field_7C; + v39 = PID_ID(stru_721530.uFaceID); + switch (PID_TYPE(stru_721530.uFaceID)) + { + case OBJECT_Actor: + if (pTurnEngine->turn_stage != TE_ATTACK && pTurnEngine->turn_stage != TE_MOVEMENT || pParty->bTurnBasedModeOn != TE_WAIT) + { + //if(pParty->bTurnBasedModeOn == 1) + //v34 = 0; + if (pActors[v75].pMonsterInfo.uHostilityType) + { + if (v71 == 0) + Actor::AI_Flee(v75, stru_721530.uFaceID, 0, (AIDirection *)0); + else + Actor::AI_StandOrBored(v75, 4, 0, (AIDirection *)0); + } + else if (v71) + Actor::AI_StandOrBored(v75, 4, 0, (AIDirection *)0); + else if (pActors[v39].pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Friendly) + Actor::AI_Flee(v75, stru_721530.uFaceID, 0, (AIDirection *)0); + else + Actor::AI_FaceObject(v75, stru_721530.uFaceID, 0, (AIDirection *)0); + } + break; + case OBJECT_Player: + if (!pActors[v75].GetActorsRelation(0)) + { + Actor::AI_FaceObject(v75, stru_721530.uFaceID, 0, (AIDirection *)0); + break; + } + //v52 = HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) == 0; + //v53 = SHIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) < 0; + pActors[v75].vVelocity.y = 0; + pActors[v75].vVelocity.x = 0; + //if ( !v53 && (!(v53 | v52) || LODWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) > 0) ) + if ((signed __int64)pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime < 0) + pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset(); + viewparams->bRedrawGameUI = 1; + break; + case OBJECT_Decoration: + v47 = integer_sqrt(pActors[v75].vVelocity.x * pActors[v75].vVelocity.x + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y); + v48 = stru_5C6E00->Atan2(pActors[v75].vPosition.x - pLevelDecorations[v39].vPosition.x, + pActors[v75].vPosition.y - pLevelDecorations[v39].vPosition.y); + //v49 = v48; + pActors[v75].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(v48), v47); + pActors[v75].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(v48), v47); + break; + case OBJECT_BModel: + face = &pOutdoor->pBModels[stru_721530.uFaceID >> 9].pFaces[v39 & 0x3F]; + if (!face->Ethereal()) + { + if (face->uPolygonType == 3) + { + pActors[v75].vVelocity.z = 0; + pActors[v75].vPosition.z = LOWORD(pOutdoor->pBModels[stru_721530.uFaceID >> 9].pVertices.pVertices[face->pVertexIDs[0]].z) + 1; + if (pActors[v75].vVelocity.x * pActors[v75].vVelocity.x + + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y < 400) + { + pActors[v75].vVelocity.y = 0; + pActors[v75].vVelocity.x = 0; + } + } + else + { + v72b = abs(face->pFacePlane.vNormal.y * pActors[v75].vVelocity.y + face->pFacePlane.vNormal.z * pActors[v75].vVelocity.z + + face->pFacePlane.vNormal.x * pActors[v75].vVelocity.x) >> 16; + if ((stru_721530.speed >> 3) > v72b) + v72b = stru_721530.speed >> 3; + + pActors[v75].vVelocity.x += fixpoint_mul(v72b, face->pFacePlane.vNormal.x); + pActors[v75].vVelocity.y += fixpoint_mul(v72b, face->pFacePlane.vNormal.y); + pActors[v75].vVelocity.z += fixpoint_mul(v72b, face->pFacePlane.vNormal.z); + if (face->uPolygonType != 4) + { + v46 = stru_721530.prolly_normal_d + - ((face->pFacePlane.dist + + face->pFacePlane.vNormal.x * pActors[v75].vPosition.x + + face->pFacePlane.vNormal.y * pActors[v75].vPosition.y + + face->pFacePlane.vNormal.z * pActors[v75].vPosition.z) >> 16); + if (v46 > 0) + { + pActors[v75].vPosition.x += fixpoint_mul(v46, face->pFacePlane.vNormal.x); + pActors[v75].vPosition.y += fixpoint_mul(v46, face->pFacePlane.vNormal.y); + pActors[v75].vPosition.z += fixpoint_mul(v46, face->pFacePlane.vNormal.z); + } + pActors[v75].uYawAngle = stru_5C6E00->Atan2(pActors[v75].vVelocity.x, pActors[v75].vVelocity.y); + } + } + } + break; + } + + pActors[v75].vVelocity.x = fixpoint_mul(58500, pActors[v75].vVelocity.x); + pActors[v75].vVelocity.y = fixpoint_mul(58500, pActors[v75].vVelocity.y); + pActors[v75].vVelocity.z = fixpoint_mul(58500, pActors[v75].vVelocity.z); + + v26 = stru_721530.prolly_normal_d; + } + + v58 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(WorldPosToGridCellX(pActors[v75].vPosition.x), WorldPosToGridCellZ(pActors[v75].vPosition.y) - 1) >> 1) & 1; + v59 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(WorldPosToGridCellX(pActors[v75].vPosition.x), WorldPosToGridCellZ(pActors[v75].vPosition.y) - 1) >> 1) & 1; + if (WorldPosToGridCellX(pActors[v75].vPosition.x) == WorldPosToGridCellX(pActors[v75].vPosition.x) + && WorldPosToGridCellZ(pActors[v75].vPosition.y) == WorldPosToGridCellZ(pActors[v75].vPosition.y) + && v58 || v67 != 0) + { + if (MonsterStats::BelongsToSupertype(pActors[v75].pMonsterInfo.uID, MONSTER_SUPERTYPE_WATER_ELEMENTAL)) + { + v58 = v58 == 0; + v59 = v59 == 0; + } + if (!uIsFlying && v58 && !v59) + { + pActors[v75].vPosition.x = pActors[v75].vPosition.x; + pActors[v75].vPosition.y = pActors[v75].vPosition.y; + if (pActors[v75].CanAct()) + { + pActors[v75].uYawAngle -= 32; + pActors[v75].uCurrentActionTime = 0; + pActors[v75].uCurrentActionLength = 128; + pActors[v75].uAIState = Fleeing; + } + } + } + } +} + +//----- (0047A384) -------------------------------------------------------- +void ODM_LoadAndInitialize(const char *pLevelFilename, ODMRenderParams *thisa) +{ + int v2; // ebx@3 + unsigned int v3; // eax@3 + MapInfo *v4; // edi@4 + //int v5; // eax@8 + //SpawnPointMM7 *v6; // edx@14 + size_t v7; // eax@19 + //char *v8; // eax@19 + //char *v9; // eax@21 + char Source[120]; // [sp+Ch] [bp-84h]@19 + const char *pFilename; // [sp+84h] [bp-Ch]@1 + //unsigned int v12; // [sp+88h] [bp-8h]@12 + //int v13; // [sp+8Ch] [bp-4h]@11 + int v; + + pFilename = pLevelFilename; + //thisa->AllocSoftwareDrawBuffers(); + pODMRenderParams->Initialize(); + pWeather->bRenderSnow = false; + pRenderer->ClearZBuffer(0, 479); + //thisa = (ODMRenderParams *)1; + GetAlertStatus(); + if (_A750D8_player_speech_timer) + _A750D8_player_speech_timer = 0; + v2 = pMapStats->GetMapInfo(pCurrentMapName); + v3 = 0; + if (v2) + { + v4 = &pMapStats->pInfos[v2]; + v3 = v4->uRespawnIntervalDays; + } + else + v4 = (MapInfo *)1; + day_attrib &= ~DAY_ATTRIB_FOG; + dword_6BE13C_uCurrentlyLoadedLocationID = v2; + pOutdoor->Initialize( + pFilename, + (unsigned int)(signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) / 0x3C / 0x3C / 0x18 + 1, + v3, + &v); + if (!(dword_6BE364_game_settings_1 & GAME_SETTINGS_2000)) + { + Actor::InitializeActors(); + SpriteObject::InitializeSpriteObjects(); + } + dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_2000; + //v5 = 0; + if (!v2) + v = 0; + if (v == 1) + { + //v13 = 0; + for (uint i = 0; i < pOutdoor->uNumSpawnPoints; ++i) + { + //v12 = 0; + //while ( 1 ) + //{ + SpawnPointMM7* spawn = pOutdoor->pSpawnPoints + i; + //v6 = &pOutdoor->pSpawnPoints[v12 / 0x18]; + if (spawn->uKind == 3) + SpawnEncounter(v4, spawn, 0, 0, 0); + else + v4->SpawnRandomTreasure(spawn); + //++v13; + //v12 += 24; + //if ( v13 >= (signed int)pOutdoor->uNumSpawnPoints ) + // break; + //v5 = 0; + //} + } + RespawnGlobalDecorations(); + } + pOutdoor->PrepareDecorations(); + pOutdoor->ArrangeSpriteObjects(); + pOutdoor->InitalizeActors(v2); + pOutdoor->MessWithLUN(); + v7 = strlen("levels\\"); + strcpy(Source, &pFilename[v7]); + strcpy(pOutdoor->pLevelFilename, Source); + pWeather->Initialize(); + pGame->pIndoorCameraD3D->sRotationY = pParty->sRotationY; + pGame->pIndoorCameraD3D->sRotationX = pParty->sRotationX; + //pODMRenderParams->RotationToInts(); + pOutdoor->UpdateSunlightVectors(); + + float fov_rad; + float fov_rad_inv; + //----- (0042394D) -------------------------------------------------------- + //void IndoorCamera::Initialize(int degFov, unsigned int uViewportWidth, unsigned int uViewportHeight) + { + //pIndoorCamera->Initialize(65, viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1, + // viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y + 1); + + int uViewportWidth = viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1; + + extern float _calc_fov(int viewport_width, int angle_degree); + fov_rad = _calc_fov(uViewportWidth, 65); + fov_rad_inv = 65536.0 / fov_rad; + } + pODMRenderParams->int_fov_rad = (signed __int64)fov_rad; + pODMRenderParams->int_fov_rad_inv = (signed __int64)fov_rad_inv; + + for (int i = 0; i < 20000; ++i) + { + array_77EC08[i].ptr_38 = &stru_8019C8; + + array_77EC08[i].ptr_48 = nullptr; + } + + MM7Initialization(); +} + +//----- (0047C370) -------------------------------------------------------- +unsigned int GetLevelFogColor() +{ + signed __int64 v1; // qax@5 + int v2; // eax@6 + + if (bUnderwater) + return 0xFF258F5C; + + if (day_attrib & DAY_ATTRIB_FOG) + { + if (pWeather->bNight) // night-time fog + { + __debugbreak(); // decompilation can be inaccurate, please send savegame to Nomad + v2 = -(pWeather->bNight != 1); + return (v2 & 0xE0E0E1) - 0xE0E0E1; + } + else + { + v1 = (signed __int64)((1.0 - pOutdoor->fFogDensity) * 200.0 + pOutdoor->fFogDensity * 31.0); + return v1 | (((unsigned int)v1 | (((unsigned int)v1 | 0xFFFFFF00) << 8)) << 8); + } + } + + return 0; +} + +//----- (0047C3D7) -------------------------------------------------------- +int __fastcall sub_47C3D7_get_fog_specular(int a1, int a2, float a3) +{ + int v3; // ecx@1 + signed int v7; // ecx@11 + + v3 = pWeather->bNight; + if (bUnderwater == 1) + v3 = 0; + if (pParty->armageddon_timer || !(day_attrib & DAY_ATTRIB_FOG) && !bUnderwater) + return 0xFF000000; + if (v3) + { + if (a3 < (double)day_fogrange_1) + { + v7 = 0; + if (a3 == 0.0) + v7 = 216; + if (a2) + v7 = 248; + return (-1 - v7) << 24; + } + else + { + if (a3 > (double)day_fogrange_2) + { + v7 = 216; + if (a3 == 0.0) + v7 = 216; + if (a2) + v7 = 248; + return (-1 - v7) << 24; + } + v7 = (signed __int64)((a3 - (double)day_fogrange_1) / ((double)day_fogrange_2 - (double)day_fogrange_1) * 216.0); + } + } + else + { + if (a3 < (double)day_fogrange_1) + { + v7 = 0; + if (a3 == 0.0) + v7 = 216; + if (a2) + v7 = 248; + return (-1 - v7) << 24; + } + else + { + if (a3 > (double)day_fogrange_2) + { + v7 = 216; + if (a3 == 0.0) + v7 = 216; + if (a2) + v7 = 248; + return (-1 - v7) << 24; + } + else + v7 = floorf(((a3 - (double)day_fogrange_1) * 216.0 / ((double)day_fogrange_2 - (double)day_fogrange_1)) + 0.5f); + } + } + if (v7 > 216) + v7 = 216; + else + { + if (a3 == 0.0) + v7 = 216; + } + if (a2) + v7 = 248; + return (-1 - v7) << 24; +} + + +//----- (0047F44B) -------------------------------------------------------- +unsigned int WorldPosToGridCellX(int sWorldPosX) +{ + return (sWorldPosX >> 9) + 64; // sar is in original exe, resulting -880 / 512 = -1 + // and -880 sar 9 = -2 +} + +//----- (0047F458) -------------------------------------------------------- +unsigned int WorldPosToGridCellZ(int sWorldPosZ) +{ + return 64 - (sWorldPosZ >> 9); // sar is in original exe, resulting -880 / 512 = -1 + // and -880 sar 9 = -2 +} + +//----- (0047F469) -------------------------------------------------------- +int GridCellToWorldPosX(int a1) +{ + return (a1 - 64) << 9; +} + +//----- (0047F476) -------------------------------------------------------- +int GridCellToWorldPosZ(int a1) +{ + return (64 - a1) << 9; +} + + + +//----- (00481ED9) -------------------------------------------------------- +void sub_481ED9_MessWithODMRenderParams() +{ + stru_8019C8._48616B_frustum_odm(65536, 0, 0, 0, 65536, 0); + pODMRenderParams->uNumPolygons = 0; + //pODMRenderParams->uNumEdges = 0; + //pODMRenderParams->uNumSpans = 0; + //pODMRenderParams->uNumSurfs = 0; + pODMRenderParams->uNumBillboards = 0; + pODMRenderParams->field_44 = 0; +} + +//----- (004823F4) -------------------------------------------------------- +bool IsTerrainSlopeTooHigh(int pos_x, int pos_z) +{ + //unsigned int v2; // ebx@1 + //unsigned int v3; // edi@1 + //int v4; // eax@1 + //int v6; // esi@5 + //int v7; // ecx@6 + //int v8; // edx@6 + //int v9; // eax@6 + //int y_min; // esi@10 + //int v11; // [sp+14h] [bp-8h]@1 + //int v12; // [sp+18h] [bp-4h]@1 + + //v12 = a1; + //v11 = a2; + unsigned int grid_x = WorldPosToGridCellX(pos_x); + unsigned int grid_z = WorldPosToGridCellZ(pos_z) - 1; + + int party_grid_x1 = GridCellToWorldPosX(grid_x); + //dword_76D56C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1); + //dword_76D570_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1); + //dword_76D574_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x); + int party_grid_z1 = GridCellToWorldPosZ(grid_z); + //dword_76D55C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z); + //dword_76D560_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1); + //dword_76D564_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1); + int party_x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z); + int party_x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z); + int party_x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1); + int party_x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); + //dword_76D554_terrain_cell_world_pos_around_party_y = v4; + if (party_x1z1_y == party_x2z1_y && + party_x2z1_y == party_x2z2_y && + party_x2z2_y == party_x1z2_y) + return false; + + int dx = abs(pos_x - party_grid_x1), + dz = abs(party_grid_z1 - pos_z); + + int y1, y2, y3; + if (dz >= dx) + { + y1 = party_x1z2_y; // lower-left triangle + y2 = party_x2z2_y; // y3 | \ + y3 = party_x1z1_y; // | \ + /* | \ + |______ \ + y1 y2 */ + } + else + { + y1 = party_x2z1_y; // upper-right + y2 = party_x1z1_y; // y2_______ y1 + y3 = party_x2z2_y; // \ | + /* \ | + \ | + y3 */ + } + + int y_min = min(y1, min(y2, y3));// не верно при подъёме на склон + int y_max = max(y1, max(y2, y3)); + return (y_max - y_min) > 512; +} + +//----- (0048257A) -------------------------------------------------------- +int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *pIsOnWater, int bFloatAboveWater) +{ + // int result; // eax@9 + int v8; // ebx@11 + int v9; // eax@11 + int v10; // ecx@11 + int v13; // [sp+10h] [bp-8h]@11 + signed int v14; // [sp+14h] [bp-4h]@3 + int v15; // [sp+24h] [bp+Ch]@11 + + unsigned int grid_x = WorldPosToGridCellX(a1); + unsigned int grid_z = WorldPosToGridCellZ(a2) - 1; + + int grid_x1 = GridCellToWorldPosX(grid_x), + grid_x2 = GridCellToWorldPosX(grid_x + 1); + int grid_z1 = GridCellToWorldPosZ(grid_z), + grid_z2 = GridCellToWorldPosZ(grid_z + 1); + + int y_x1z1 = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z), + y_x2z1 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z), + y_x2z2 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1), + y_x1z2 = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); + //v4 = WorldPosToGridCellX(a1); + //v5 = WorldPosToGridCellZ(v12) - 1; + //dword_76D538_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4); + //dword_76D53C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1); + //dword_76D540_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1); + //dword_76D544_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4); + //dword_76D528_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5); + //dword_76D52C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5); + //dword_76D530_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1); + //dword_76D534_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1); + //dword_76D518_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5); + //dword_76D51C_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5); + //dword_76D520_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5 + 1); + //dword_76D524_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5 + 1); + *pIsOnWater = false; + if (pOutdoor->ActuallyGetSomeOtherTileInfo(grid_x, grid_z) & 2) + *pIsOnWater = true; + v14 = 0; + if (!bFloatAboveWater && *pIsOnWater) + v14 = -60; + if (y_x1z1 != y_x2z1 || + y_x2z1 != y_x2z2 || + y_x2z2 != y_x1z2) + { + if (abs(grid_z1 - a2) >= abs(a1 - grid_x1)) + { + v8 = y_x1z2; + v9 = y_x2z2; + v10 = y_x1z1; + v15 = a1 - grid_x1; + v13 = a2 - grid_z2; + } + else + { + v8 = y_x2z1; + v9 = y_x1z1; + v10 = y_x2z2; + v15 = grid_x2 - a1; + v13 = grid_z1 - a2; + } + return v14 + v8 + fixpoint_mul(v13, (v10 - v8) * 128) + fixpoint_mul(v15, (v9 - v8) * 128); + } + else + return y_x1z1; +} diff -r 0f17a30149ec -r 104fdbea0386 Outdoor.h --- a/Outdoor.h Sun Aug 17 15:13:18 2014 +0100 +++ b/Outdoor.h Sun Aug 17 17:49:34 2014 +0100 @@ -256,6 +256,17 @@ char Is_out15odm_underwater(); void SetUnderwaterFog(); void ODM_Project(unsigned int uNumVertices); +void sub_487DA9(); +void ODM_LoadAndInitialize(const char *pLevelFilename, struct ODMRenderParams *thisa); +unsigned int GetLevelFogColor(); +int __fastcall sub_47C3D7_get_fog_specular(int a1, int a2, float a3); +unsigned int WorldPosToGridCellX(int); // weak +unsigned int WorldPosToGridCellZ(int); // weak +int GridCellToWorldPosX(int); // weak +int GridCellToWorldPosZ(int); // weak +void sub_481ED9_MessWithODMRenderParams(); +bool IsTerrainSlopeTooHigh(int pos_x, int pos_y); +int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *a3, int a4); diff -r 0f17a30149ec -r 104fdbea0386 Party.cpp --- a/Party.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Party.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -4,7 +4,7 @@ #define _CRT_SECURE_NO_WARNINGS #include "ErrorHandling.h" -#include "mm7_unsorted_subs.h" + #include "Party.h" #include "MapInfo.h" #include "Timer.h" @@ -29,6 +29,9 @@ #include "ObjectList.h" #include "Conditions.h" + +#include "Game.h" + Party *pParty; // idb struct ActionQueue *pPartyActionQueue = new ActionQueue; @@ -1215,4 +1218,38 @@ new_travel_time = 1; return new_travel_time; } -// 6BD07C: using guessed type int uDefaultTravelTime_ByFoot; \ No newline at end of file +// 6BD07C: using guessed type int uDefaultTravelTime_ByFoot; + +//----- (00449B57) -------------------------------------------------------- +bool _449B57_test_bit(unsigned __int8 *a1, __int16 a2) +{ + return (a1[(a2 - 1) >> 3] & (0x80u >> (a2 - 1) % 8)) != 0; +} + +//----- (00449B7E) -------------------------------------------------------- +void _449B7E_toggle_bit(unsigned char *pArray, __int16 a2, unsigned __int16 bToggle) +{ + signed int v3; // esi@1 + unsigned char set_bit; // edx@1 + + v3 = a2 - 1; + set_bit = 0x80 >> v3 % 8; + if (bToggle) + pArray[v3 / 8] |= set_bit; + else + pArray[v3 / 8] &= ~set_bit; +} + +//----- (004760D5) -------------------------------------------------------- +PartyAction ActionQueue::Next() +{ + if (!uNumActions) + return PARTY_INVALID; + + PartyAction result = pActions[0]; + for (unsigned int i = 0; i < uNumActions - 1; ++i) + pActions[i] = pActions[i + 1]; + --uNumActions; + + return result; +} diff -r 0f17a30149ec -r 104fdbea0386 Party.h --- a/Party.h Sun Aug 17 15:13:18 2014 +0100 +++ b/Party.h Sun Aug 17 17:49:34 2014 +0100 @@ -328,3 +328,6 @@ void __fastcall Rest(unsigned int uHoursToSleep); void RestAndHeal(__int64 uNumMinutes); // idb int GetTravelTime(); + +bool _449B57_test_bit(unsigned __int8 *a1, __int16 a2); +void _449B7E_toggle_bit(unsigned char *pArray, __int16 a2, unsigned __int16 bToggle); // idb diff -r 0f17a30149ec -r 104fdbea0386 Player.cpp --- a/Player.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Player.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -5,7 +5,7 @@ #define _CRT_SECURE_NO_WARNINGS #include "VectorTypes.h" #include "stru6.h" -#include "mm7_unsorted_subs.h" + #include "ErrorHandling.h" #include "Player.h" diff -r 0f17a30149ec -r 104fdbea0386 Render.cpp --- a/Render.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Render.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -3,7 +3,8 @@ #include #define _CRT_SECURE_NO_WARNINGS -#include "mm7_unsorted_subs.h" +#include "VectorTypes.h" + #include "ZlibWrapper.h" #include "ErrorHandling.h" @@ -38,6 +39,8 @@ #include "Level/Decoration.h" #include "Vis.h" #include "Registry.h" +#include "Weather.h" + //#pragma comment(lib, "lib\\legacy_dx\\lib\\ddraw.lib") //#pragma comment(lib, "lib\\legacy_dx\\lib\\dxguid.lib") @@ -9524,3 +9527,2079 @@ + (__PAIR__(v10, (unsigned __int16)a4 >> 2) & 0x1C00)); } +//----- (0047C4FC) -------------------------------------------------------- +int __fastcall GetActorTintColor(int max_dimm, int min_dimm, float distance, int a4, RenderBillboard *a5) +{ + //int v5; // esi@1 + signed int v6; // edx@1 + //signed int result; // eax@2 + int v8; // eax@3 + double v9; // st7@12 + //double v10; // ST0C_8@18 + int v11; // ecx@28 + //signed int v12; // edi@28 + //double v13; // ST0C_8@33 + //double v14; // ST0C_8@34 + double v15; // st7@44 + //double v16; // ST0C_8@44 + //double v17; // ST0C_8@44 + int v18; // ST14_4@44 + //double v19; // ST0C_8@44 + signed int v20; // [sp+10h] [bp-4h]@10 + // float a3a; // [sp+1Ch] [bp+8h]@33 + //float a3b; // [sp+1Ch] [bp+8h]@34 + float a3c; // [sp+1Ch] [bp+8h]@44 + //float a3d; // [sp+1Ch] [bp+8h]@44 + //float a4b; // [sp+20h] [bp+Ch]@18 + //int a4a; // [sp+20h] [bp+Ch]@33 + //float a4c; // [sp+20h] [bp+Ch]@44 + //float a4d; // [sp+20h] [bp+Ch]@44 + int a5a; // [sp+24h] [bp+10h]@44 + + //v5 = a2; + v6 = 0; + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + return 8 * (31 - max_dimm) | ((8 * (31 - max_dimm) | ((31 - max_dimm) << 11)) << 8); + + if (pParty->armageddon_timer) + return 0xFFFF0000; + + v8 = pWeather->bNight; + if (bUnderwater) + v8 = 0; + if (v8) + { + v20 = 1; + if ((signed __int64)pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uExpireTime > 0) + v20 = pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uPower; + v9 = (double)v20 * 1024.0; + if (a4) + { + v6 = 216; + goto LABEL_20; + } + if (distance <= v9) + { + if (distance > 0.0) + { + //a4b = distance * 216.0 / v9; + //v10 = a4b + 6.7553994e15; + //v6 = LODWORD(v10); + v6 = floorf(0.5f + distance * 216.0 / v9); + if (v6 > 216) + { + v6 = 216; + goto LABEL_20; + } + } + } + else + { + v6 = 216; + } + if (distance != 0.0) + { + LABEL_20: + if (a5) + v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3); + if (v6 > 216) + v6 = 216; + return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8); + } + //LABEL_19: + v6 = 216; + goto LABEL_20; + } + + + + if (fabsf(distance) < 1.0e-6f) + return 0xFFF8F8F8; + + // dim in measured in 8-steps + v11 = 8 * (max_dimm - min_dimm); + //v12 = v11; + if (v11 >= 0) + { + if (v11 > 216) + v11 = 216; + } + else + v11 = 0; + + float fog_density_mult = 216.0f; + if (a4) + fog_density_mult += distance / (double)pODMRenderParams->shading_dist_shade * 32.0; + + v6 = v11 + floorf(pOutdoor->fFogDensity * fog_density_mult + 0.5f); + /*if ( a4 ) + { + //a3b = pOutdoor->fFogDensity * 216.0; + //v14 = a3b + 6.7553994e15; + //a4a = floorf(a3b + 0.5f);//LODWORD(v14); + } + else + { + //a3a = (distance / (double)pODMRenderParams->shading_dist_shade * 32.0 + 216.0) * pOutdoor->fFogDensity; + //v13 = a3a + 6.7553994e15; + //a4a = floorf(a3a + 0.5f);//LODWORD(v13); + } + v6 = a4a + v11;*/ + if (a5) + v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3); + if (v6 > 216) + v6 = 216; + if (v6 < v11) + v6 = v11; + if (v6 > 8 * pOutdoor->max_terrain_dimming_level) + v6 = 8 * pOutdoor->max_terrain_dimming_level; + if (!bUnderwater) + return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8); + else + { + v15 = (double)(255 - v6) * 0.0039215689; + a3c = v15; + //a4c = v15 * 16.0; + //v16 = a4c + 6.7553994e15; + a5a = floorf(v15 * 16.0 + 0.5f);//LODWORD(v16); + //a4d = a3c * 194.0; + //v17 = a4d + 6.7553994e15; + v18 = floorf(a3c * 194.0 + 0.5f);//LODWORD(v17); + //a3d = a3c * 153.0; + //v19 = a3d + 6.7553994e15; + return (int)floorf(a3c * 153.0 + 0.5f)/*LODWORD(v19)*/ | ((v18 | (a5a << 8)) << 8); + } +} +// 6BE3C4: using guessed type char bUnderwater; + +//----- (0043F55F) -------------------------------------------------------- +int __fastcall _43F55F_get_billboard_light_level(RenderBillboard *a1, int uBaseLightLevel) +{ + signed int v3; // ecx@2 + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + v3 = pIndoor->pSectors[a1->uIndoorSectorID].uMinAmbientLightLevel; + else + { + if (uBaseLightLevel == -1) + v3 = a1->dimming_level; + else + v3 = uBaseLightLevel; + } + return _43F5C8_get_point_light_level_with_respect_to_lights(v3, a1->uIndoorSectorID, a1->world_x, a1->world_y, a1->world_z); +} + +//----- (0043F5C8) -------------------------------------------------------- +int __fastcall _43F5C8_get_point_light_level_with_respect_to_lights(unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z) +{ + // int v5; // esi@1 + signed int v6; // edi@1 + int v8; // eax@6 + int v9; // ebx@6 + unsigned int v10; // ecx@6 + unsigned int v11; // edx@9 + unsigned int v12; // edx@11 + signed int v13; // ecx@12 + BLVLightMM7 *v16; // esi@20 + int v17; // ebx@21 + // int v18; // eax@24 + // int v19; // ebx@24 + // unsigned int v20; // ecx@24 + // int v21; // edx@25 + // unsigned int v22; // edx@27 + // unsigned int v23; // edx@29 + signed int v24; // ecx@30 + int v26; // ebx@35 + // int v27; // eax@38 + // int v28; // ebx@38 + // unsigned int v29; // ecx@38 + // int v30; // edx@39 + // unsigned int v31; // edx@41 + // unsigned int v32; // edx@43 + //signed int v33; // ecx@44 + int v37; // [sp+Ch] [bp-18h]@37 + // int v38; // [sp+10h] [bp-14h]@5 + int v39; // [sp+10h] [bp-14h]@23 + int v40; // [sp+10h] [bp-14h]@36 + int v42; // [sp+14h] [bp-10h]@22 + unsigned int v43; // [sp+18h] [bp-Ch]@12 + unsigned int v44; // [sp+18h] [bp-Ch]@30 + unsigned int v45; // [sp+18h] [bp-Ch]@44 + + v6 = uBaseLightLevel; + for (uint i = 0; i < pMobileLightsStack->uNumLightsActive; ++i) + { + MobileLight* p = &pMobileLightsStack->pLights[i]; + + float distX = abs(p->vPosition.x - x); + if (distX <= p->uRadius) + { + float distY = abs(p->vPosition.y - y); + if (distY <= p->uRadius) + { + float distZ = abs(p->vPosition.z - z); + if (distZ <= p->uRadius) + { + v8 = distX; + v9 = distY; + v10 = distZ; + if (distX < distY) + { + v8 = distY; + v9 = distX; + } + if (v8 < distZ) + { + v11 = v8; + v8 = distZ; + v10 = v11; + } + if (v9 < (signed int)v10) + { + v12 = v10; + v10 = v9; + v9 = v12; + } + v43 = ((unsigned int)(11 * v9) / 32) + (v10 / 4) + v8; + v13 = p->uRadius; + if ((signed int)v43 < v13) + v6 += ((unsigned __int64)(30i64 * (signed int)(v43 << 16) / v13) >> 16) - 30; + } + } + } + } + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + BLVSector* pSector = &pIndoor->pSectors[uSectorID]; + + for (uint i = 0; i < pSector->uNumLights; ++i) + { + v16 = pIndoor->pLights + pSector->pLights[i]; + if (~v16->uAtributes & 8) + { + v17 = abs(v16->vPosition.x - x); + if (v17 <= v16->uRadius) + { + v42 = abs(v16->vPosition.y - y); + if (v42 <= v16->uRadius) + { + v39 = abs(v16->vPosition.z - z); + if (v39 <= v16->uRadius) + { + v44 = int_get_vector_length(v17, v42, v39); + v24 = v16->uRadius; + if ((signed int)v44 < v24) + v6 += ((unsigned __int64)(30i64 * (signed int)(v44 << 16) / v24) >> 16) - 30; + } + } + } + } + } + } + + for (uint i = 0; i < pStationaryLightsStack->uNumLightsActive; ++i) + { + //StationaryLight* p = &pStationaryLightsStack->pLights[i]; + v26 = abs(pStationaryLightsStack->pLights[i].vPosition.x - x); + if (v26 <= pStationaryLightsStack->pLights[i].uRadius) + { + v40 = abs(pStationaryLightsStack->pLights[i].vPosition.y - y); + if (v40 <= pStationaryLightsStack->pLights[i].uRadius) + { + v37 = abs(pStationaryLightsStack->pLights[i].vPosition.z - z); + if (v37 <= pStationaryLightsStack->pLights[i].uRadius) + { + v45 = int_get_vector_length(v26, v40, v37); + //v33 = pStationaryLightsStack->pLights[i].uRadius; + if ((signed int)v45 < pStationaryLightsStack->pLights[i].uRadius) + v6 += ((unsigned __int64)(30i64 * (signed int)(v45 << 16) / pStationaryLightsStack->pLights[i].uRadius) >> 16) - 30; + } + } + } + } + + if (v6 <= 31) + { + if (v6 < 0) + v6 = 0; + } + else + v6 = 31; + return v6; +} + +//----- (0049D700) -------------------------------------------------------- +unsigned int __fastcall GetMaxMipLevels(unsigned int uDim) +{ + int v2; // ecx@1 + unsigned int v3; // eax@1 + + v2 = 0; + v3 = uDim - 1; + while (v3 & 1) + { + v3 >>= 1; + ++v2; + } + return v3 == 0 ? v2 : 0; +} + +//----- (0046E44E) -------------------------------------------------------- +int _46E44E_collide_against_faces_and_portals(unsigned int b1) +{ + BLVSector *pSector; // edi@1 + signed int v2; // ebx@1 + BLVFace *pFace; // esi@2 + __int16 pNextSector; // si@10 + int pArrayNum; // ecx@12 + unsigned __int8 v6; // sf@12 + unsigned __int8 v7; // of@12 + int result; // eax@14 + //int v10; // ecx@15 + int pFloor; // eax@16 + int v15; // eax@24 + int v16; // edx@25 + int v17; // eax@29 + unsigned int v18; // eax@33 + int v21; // eax@35 + int v22; // ecx@36 + int v23; // eax@40 + unsigned int v24; // eax@44 + int a3; // [sp+10h] [bp-48h]@28 + int v26; // [sp+14h] [bp-44h]@15 + int i; // [sp+18h] [bp-40h]@1 + int a10; // [sp+1Ch] [bp-3Ch]@1 + int v29; // [sp+20h] [bp-38h]@14 + int v32; // [sp+2Ch] [bp-2Ch]@15 + int pSectorsArray[10]; // [sp+30h] [bp-28h]@1 + + pSector = &pIndoor->pSectors[stru_721530.uSectorID]; + i = 1; + a10 = b1; + pSectorsArray[0] = stru_721530.uSectorID; + for (v2 = 0; v2 < pSector->uNumPortals; ++v2) + { + pFace = &pIndoor->pFaces[pSector->pPortals[v2]]; + if (stru_721530.sMaxX <= pFace->pBounding.x2 && stru_721530.sMinX >= pFace->pBounding.x1 + && stru_721530.sMaxY <= pFace->pBounding.y2 && stru_721530.sMinY >= pFace->pBounding.y1 + && stru_721530.sMaxZ <= pFace->pBounding.z2 && stru_721530.sMinZ >= pFace->pBounding.z1 + && abs((pFace->pFacePlane_old.dist + + stru_721530.normal.x * pFace->pFacePlane_old.vNormal.x + + stru_721530.normal.y * pFace->pFacePlane_old.vNormal.y + + stru_721530.normal.z * pFace->pFacePlane_old.vNormal.z) >> 16) <= stru_721530.field_6C + 16) + { + pNextSector = pFace->uSectorID == stru_721530.uSectorID ? pFace->uBackSectorID : pFace->uSectorID;//FrontSectorID + pArrayNum = i++; + v7 = i < 10; + v6 = i - 10 < 0; + pSectorsArray[pArrayNum] = pNextSector; + if (!(v6 ^ v7)) + break; + } + } + result = 0; + for (v29 = 0; v29 < i; v29++) + { + pSector = &pIndoor->pSectors[pSectorsArray[v29]]; + v32 = pSector->uNumFloors + pSector->uNumWalls + pSector->uNumCeilings; + for (v26 = 0; v26 < v32; v26++) + { + pFloor = pSector->pFloors[v26]; + pFace = &pIndoor->pFaces[pSector->pFloors[v26]]; + if (!pFace->Portal() + && stru_721530.sMaxX <= pFace->pBounding.x2 && stru_721530.sMinX >= pFace->pBounding.x1 + && stru_721530.sMaxY <= pFace->pBounding.y2 && stru_721530.sMinY >= pFace->pBounding.y1 + && stru_721530.sMaxZ <= pFace->pBounding.z2 && stru_721530.sMinZ >= pFace->pBounding.z1 + && pFloor != stru_721530.field_84) + { + v15 = (pFace->pFacePlane_old.dist + stru_721530.normal.x * pFace->pFacePlane_old.vNormal.x + + stru_721530.normal.y * pFace->pFacePlane_old.vNormal.y + + stru_721530.normal.z * pFace->pFacePlane_old.vNormal.z) >> 16; + if (v15 > 0) + { + v16 = (pFace->pFacePlane_old.dist + stru_721530.normal2.x * pFace->pFacePlane_old.vNormal.x + + stru_721530.normal2.y * pFace->pFacePlane_old.vNormal.y + + stru_721530.normal2.z * pFace->pFacePlane_old.vNormal.z) >> 16; + if (v15 <= stru_721530.prolly_normal_d || v16 <= stru_721530.prolly_normal_d) + { + if (v16 <= v15) + { + a3 = stru_721530.field_6C; + if (sub_47531C(stru_721530.prolly_normal_d, &a3, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, + stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, pFace, a10)) + { + v17 = a3; + } + else + { + a3 = stru_721530.field_6C + stru_721530.prolly_normal_d; + if (!sub_475D85(&stru_721530.normal, &stru_721530.direction, &a3, pFace)) + goto LABEL_34; + v17 = a3 - stru_721530.prolly_normal_d; + a3 -= stru_721530.prolly_normal_d; + } + if (v17 < stru_721530.field_7C) + { + stru_721530.field_7C = v17; + v18 = 8 * pSector->pFloors[v26]; + LOBYTE(v18) = v18 | 6; + stru_721530.uFaceID = v18; + } + } + } + } + LABEL_34: + if (!(stru_721530.field_0 & 1) + || (v21 = (pFace->pFacePlane_old.dist + stru_721530.position.x * pFace->pFacePlane_old.vNormal.x + + stru_721530.position.y * pFace->pFacePlane_old.vNormal.y + + stru_721530.position.z * pFace->pFacePlane_old.vNormal.z) >> 16, v21 <= 0) + || (v22 = (pFace->pFacePlane_old.dist + stru_721530.field_4C * pFace->pFacePlane_old.vNormal.x + + stru_721530.field_50 * pFace->pFacePlane_old.vNormal.y + + stru_721530.field_54 * pFace->pFacePlane_old.vNormal.z) >> 16, v21 > stru_721530.prolly_normal_d) + && v22 > stru_721530.prolly_normal_d || v22 > v21) + continue; + a3 = stru_721530.field_6C; + if (sub_47531C(stru_721530.field_8_radius, &a3, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, + stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, pFace, a10)) + { + v23 = a3; + goto LABEL_43; + } + a3 = stru_721530.field_6C + stru_721530.field_8_radius; + if (sub_475D85(&stru_721530.position, &stru_721530.direction, &a3, pFace)) + { + v23 = a3 - stru_721530.prolly_normal_d; + a3 -= stru_721530.prolly_normal_d; + LABEL_43: + if (v23 < stru_721530.field_7C) + { + stru_721530.field_7C = v23; + v24 = 8 * pSector->pFloors[v26]; + LOBYTE(v24) = v24 | 6; + stru_721530.uFaceID = v24; + } + } + } + } + result = v29 + 1; + } + return result; +} +// 46E44E: using guessed type int var_28[10]; + +//----- (0046E889) -------------------------------------------------------- +int __fastcall _46E889_collide_against_bmodels(unsigned int ecx0) +{ + int result; // eax@1 + //int v3; // ebx@9 + int v8; // eax@19 + int v9; // ecx@20 + int v10; // eax@24 + unsigned int v14; // eax@28 + int v15; // eax@30 + int v16; // ecx@31 + unsigned int v17; // eax@36 + int v21; // eax@42 + unsigned int v22; // eax@43 + //int a11; // [sp+70h] [bp-18h]@1 + //int a10; // [sp+80h] [bp-8h]@1 + int a2; // [sp+84h] [bp-4h]@23 + + //a11 = ecx0; + + BLVFace face; // [sp+Ch] [bp-7Ch]@1 + + result = 0; + for (uint i = 0; i < (signed int)pOutdoor->uNumBModels; ++i) + { + if (stru_721530.sMaxX <= pOutdoor->pBModels[i].sMaxX && stru_721530.sMinX >= pOutdoor->pBModels[i].sMinX + && stru_721530.sMaxY <= pOutdoor->pBModels[i].sMaxY && stru_721530.sMinY >= pOutdoor->pBModels[i].sMinY + && stru_721530.sMaxZ <= pOutdoor->pBModels[i].sMaxZ && stru_721530.sMinZ >= pOutdoor->pBModels[i].sMinZ) + { + for (uint j = 0; j < pOutdoor->pBModels[i].uNumFaces; ++j) + { + if (stru_721530.sMaxX <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x2 && stru_721530.sMinX >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x1 + && stru_721530.sMaxY <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y2 && stru_721530.sMinY >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y1 + && stru_721530.sMaxZ <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z2 && stru_721530.sMinZ >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z1) + { + face.pFacePlane_old.vNormal.x = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.x; + face.pFacePlane_old.vNormal.y = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.y; + face.pFacePlane_old.vNormal.z = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.z; + + face.pFacePlane_old.dist = pOutdoor->pBModels[i].pFaces[j].pFacePlane.dist; //incorrect + + face.uAttributes = pOutdoor->pBModels[i].pFaces[j].uAttributes; + + face.pBounding.x1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x1; + face.pBounding.y1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y1; + face.pBounding.z1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z1; + + face.pBounding.x2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x2; + face.pBounding.y2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y2; + face.pBounding.z2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z2; + + face.zCalc1 = pOutdoor->pBModels[i].pFaces[j].zCalc1; + face.zCalc2 = pOutdoor->pBModels[i].pFaces[j].zCalc2; + face.zCalc3 = pOutdoor->pBModels[i].pFaces[j].zCalc3; + + face.pXInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements; + face.pYInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pYInterceptDisplacements; + face.pZInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pZInterceptDisplacements; + + face.uPolygonType = (PolygonType)pOutdoor->pBModels[i].pFaces[j].uPolygonType; + + face.uNumVertices = pOutdoor->pBModels[i].pFaces[j].uNumVertices; + + face.uBitmapID = pOutdoor->pBModels[i].pFaces[j].uTextureID; + + face.pVertexIDs = pOutdoor->pBModels[i].pFaces[j].pVertexIDs; + + if (!face.Ethereal() && !face.Portal()) + { + v8 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.normal.x + + face.pFacePlane_old.vNormal.y * stru_721530.normal.y + + face.pFacePlane_old.vNormal.z * stru_721530.normal.z) >> 16; + if (v8 > 0) + { + v9 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.normal2.x + + face.pFacePlane_old.vNormal.y * stru_721530.normal2.y + + face.pFacePlane_old.vNormal.z * stru_721530.normal2.z) >> 16; + if (v8 <= stru_721530.prolly_normal_d || v9 <= stru_721530.prolly_normal_d) + { + if (v9 <= v8) + { + a2 = stru_721530.field_6C; + if (sub_4754BF(stru_721530.prolly_normal_d, &a2, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, + stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, &face, i, ecx0)) + { + v10 = a2; + } + else + { + a2 = stru_721530.prolly_normal_d + stru_721530.field_6C; + if (!sub_475F30(&a2, &face, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, + stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, i)) + goto LABEL_29; + v10 = a2 - stru_721530.prolly_normal_d; + a2 -= stru_721530.prolly_normal_d; + } + if (v10 < stru_721530.field_7C) + { + stru_721530.field_7C = v10; + v14 = 8 * (j | (i << 6)); + LOBYTE(v14) = v14 | 6; + stru_721530.uFaceID = v14; + } + } + } + } + LABEL_29: + if (stru_721530.field_0 & 1) + { + v15 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.position.x + + face.pFacePlane_old.vNormal.y * stru_721530.position.y + + face.pFacePlane_old.vNormal.z * stru_721530.position.z) >> 16; + if (v15 > 0) + { + v16 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.field_4C + + face.pFacePlane_old.vNormal.y * stru_721530.field_50 + + face.pFacePlane_old.vNormal.z * stru_721530.field_54) >> 16; + if (v15 <= stru_721530.prolly_normal_d || v16 <= stru_721530.prolly_normal_d) + { + if (v16 <= v15) + { + a2 = stru_721530.field_6C; + if (sub_4754BF(stru_721530.field_8_radius, &a2, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, + stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, &face, i, ecx0)) + { + if (a2 < stru_721530.field_7C) + { + stru_721530.field_7C = a2; + v17 = 8 * (j | (i << 6)); + LOBYTE(v17) = v17 | 6; + stru_721530.uFaceID = v17; + } + } + else + { + a2 = stru_721530.field_6C + stru_721530.field_8_radius; + if (sub_475F30(&a2, &face, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, + stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, i)) + { + v21 = a2 - stru_721530.prolly_normal_d; + a2 -= stru_721530.prolly_normal_d; + if (a2 < stru_721530.field_7C) + { + stru_721530.field_7C = v21; + v22 = 8 * (j | (i << 6)); + LOBYTE(v22) = v22 | 6; + stru_721530.uFaceID = v22; + } + } + } + } + } + } + } + } + } + } + } + result = i; + } + return result; +} + +//----- (0046ED1B) -------------------------------------------------------- +int collide_against_floor(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID) +{ + uint uFaceID = -1; + int floor_level = BLV_GetFloorLevel(x, y, z, *pSectorID, &uFaceID); + + if (floor_level != -30000 && floor_level <= z + 50) + { + *pFaceID = uFaceID; + return floor_level; + } + + uint uSectorID = pIndoor->GetSector(x, y, z); + *pSectorID = uSectorID; + + floor_level = BLV_GetFloorLevel(x, y, z, uSectorID, &uFaceID); + if (uSectorID && floor_level != -30000) + *pFaceID = uFaceID; + else return -30000; + return floor_level; +} + +//----- (0046ED8A) -------------------------------------------------------- +void __fastcall _46ED8A_collide_against_sprite_objects(unsigned int _this) +{ + ObjectDesc *object; // edx@4 + int v10; // ecx@12 + int v11; // esi@13 + + for (uint i = 0; i < uNumSpriteObjects; ++i) + { + if (pSpriteObjects[i].uObjectDescID) + { + object = &pObjectList->pObjects[pSpriteObjects[i].uObjectDescID]; + if (!(object->uFlags & OBJECT_DESC_NO_COLLISION)) + { + if (stru_721530.sMaxX <= pSpriteObjects[i].vPosition.x + object->uRadius && stru_721530.sMinX >= pSpriteObjects[i].vPosition.x - object->uRadius + && stru_721530.sMaxY <= pSpriteObjects[i].vPosition.y + object->uRadius && stru_721530.sMinY >= pSpriteObjects[i].vPosition.y - object->uRadius + && stru_721530.sMaxZ <= pSpriteObjects[i].vPosition.z + object->uHeight && stru_721530.sMinZ >= pSpriteObjects[i].vPosition.z) + { + if (abs(((pSpriteObjects[i].vPosition.x - stru_721530.normal.x) * stru_721530.direction.y + - (pSpriteObjects[i].vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16) + <= object->uHeight + stru_721530.prolly_normal_d) + { + v10 = ((pSpriteObjects[i].vPosition.x - stru_721530.normal.x) * stru_721530.direction.x + + (pSpriteObjects[i].vPosition.y - stru_721530.normal.y) * stru_721530.direction.y) >> 16; + if (v10 > 0) + { + v11 = stru_721530.normal.z + ((unsigned __int64)(stru_721530.direction.z * (signed __int64)v10) >> 16); + if (v11 >= pSpriteObjects[i].vPosition.z - stru_721530.prolly_normal_d) + { + if (v11 <= object->uHeight + stru_721530.prolly_normal_d + pSpriteObjects[i].vPosition.z) + { + if (v10 < stru_721530.field_7C) + sub_46DEF2(_this, i); + } + } + } + } + } + } + } + } +} + +//----- (0046EF01) -------------------------------------------------------- +int _46EF01_collision_chech_player(int a1) +{ + int result; // eax@1 + int v3; // ebx@7 + int v4; // esi@7 + int v5; // edi@8 + int v6; // ecx@9 + int v7; // edi@12 + int v10; // [sp+14h] [bp-8h]@7 + int v11; // [sp+18h] [bp-4h]@7 + + result = pParty->vPosition.x; + //v9 = pParty->uPartyHeight; + if (stru_721530.sMaxX <= pParty->vPosition.x + (2 * pParty->field_14_radius) && stru_721530.sMinX >= pParty->vPosition.x - (2 * pParty->field_14_radius) + && stru_721530.sMaxY <= pParty->vPosition.y + (2 * pParty->field_14_radius) && stru_721530.sMinY >= pParty->vPosition.y - (2 * pParty->field_14_radius) + && stru_721530.sMaxZ <= pParty->vPosition.z + pParty->uPartyHeight && stru_721530.sMinZ >= pParty->vPosition.z) + { + v3 = stru_721530.prolly_normal_d + (2 * pParty->field_14_radius); + v11 = pParty->vPosition.x - stru_721530.normal.x; + v4 = ((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y + - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16; + v10 = pParty->vPosition.y - stru_721530.normal.y; + result = abs(((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y + - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16); + if (result <= stru_721530.prolly_normal_d + (2 * pParty->field_14_radius)) + { + result = v10 * stru_721530.direction.y; + v5 = (v10 * stru_721530.direction.y + v11 * stru_721530.direction.x) >> 16; + if (v5 > 0) + { + v6 = fixpoint_mul(stru_721530.direction.z, v5) + stru_721530.normal.z; + result = pParty->vPosition.z; + if (v6 >= pParty->vPosition.z) + { + result = pParty->uPartyHeight + pParty->vPosition.z; + if (v6 <= (signed int)(pParty->uPartyHeight + pParty->vPosition.z) || a1) + { + result = integer_sqrt(v3 * v3 - v4 * v4); + v7 = v5 - integer_sqrt(v3 * v3 - v4 * v4); + if (v7 < 0) + v7 = 0; + if (v7 < stru_721530.field_7C) + { + stru_721530.field_7C = v7; + stru_721530.uFaceID = 4; + } + } + } + } + } + } + return result; +} + +//----- (0046E0B2) -------------------------------------------------------- +void _46E0B2_collide_against_decorations() +{ + BLVSector *sector; // ebp@1 + LevelDecoration *decor; // edi@2 + DecorationDesc *decor_desc; // esi@3 + int v8; // ebx@10 + int v9; // esi@11 + int v11; // eax@12 + int v12; // esi@14 + unsigned int v13; // eax@17 + signed int i; // [sp+4h] [bp-14h]@1 + int v15; // [sp+8h] [bp-10h]@10 + int v16; // [sp+Ch] [bp-Ch]@10 + int v17; // [sp+10h] [bp-8h]@10 + + sector = &pIndoor->pSectors[stru_721530.uSectorID]; + for (i = 0; i < sector->uNumDecorations; ++i) + { + decor = &pLevelDecorations[sector->pDecorationIDs[i]]; + if (!(decor->uFlags & LEVEL_DECORATION_INVISIBLE)) + { + decor_desc = &pDecorationList->pDecorations[decor->uDecorationDescID]; + if (!decor_desc->CanMoveThrough()) + { + if (stru_721530.sMaxX <= decor->vPosition.x + decor_desc->uRadius && stru_721530.sMinX >= decor->vPosition.x - decor_desc->uRadius + && stru_721530.sMaxY <= decor->vPosition.y + decor_desc->uRadius && stru_721530.sMinY >= decor->vPosition.y - decor_desc->uRadius + && stru_721530.sMaxZ <= decor->vPosition.z + decor_desc->uDecorationHeight && stru_721530.sMinZ >= decor->vPosition.z) + { + v16 = decor->vPosition.x - stru_721530.normal.x; + v15 = decor->vPosition.y - stru_721530.normal.y; + v8 = stru_721530.prolly_normal_d + decor_desc->uRadius; + v17 = ((decor->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y + - (decor->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16; + if (abs(v17) <= stru_721530.prolly_normal_d + decor_desc->uRadius) + { + v9 = (v16 * stru_721530.direction.x + v15 * stru_721530.direction.y) >> 16; + if (v9 > 0) + { + v11 = stru_721530.normal.z + fixpoint_mul(stru_721530.direction.z, v9); + if (v11 >= decor->vPosition.z) + { + if (v11 <= decor_desc->uDecorationHeight + decor->vPosition.z) + { + v12 = v9 - integer_sqrt(v8 * v8 - v17 * v17); + if (v12 < 0) + v12 = 0; + if (v12 < stru_721530.field_7C) + { + stru_721530.field_7C = v12; + v13 = 8 * sector->pDecorationIDs[i]; + LOBYTE(v13) = v13 | 5; + stru_721530.uFaceID = v13; + } + } + } + } + } + } + } + } + } +} + +//----- (0046F04E) -------------------------------------------------------- +int _46F04E_collide_against_portals() +{ + unsigned int v1; // eax@1 + BLVFace *face; // eax@3 + int v4; // ecx@9 + int v5; // edx@9 + signed int result; // eax@21 + unsigned int v10; // [sp+8h] [bp-Ch]@1 + int a3; // [sp+Ch] [bp-8h]@13 + int v12; // [sp+10h] [bp-4h]@15 + + v1 = 0xFFFFFFu; + v10 = 0xFFFFFFu; + for (uint i = 0; i < pIndoor->pSectors[stru_721530.uSectorID].uNumPortals; ++i) + { + if (pIndoor->pSectors[stru_721530.uSectorID].pPortals[i] != stru_721530.field_80) + { + face = &pIndoor->pFaces[pIndoor->pSectors[stru_721530.uSectorID].pPortals[i]]; + if (stru_721530.sMaxX <= face->pBounding.x2 && stru_721530.sMinX >= face->pBounding.x1 + && stru_721530.sMaxY <= face->pBounding.y2 && stru_721530.sMinY >= face->pBounding.y1 + && stru_721530.sMaxZ <= face->pBounding.z2 && stru_721530.sMinZ >= face->pBounding.z1) + { + v4 = (stru_721530.normal.x * face->pFacePlane_old.vNormal.x + face->pFacePlane_old.dist + + stru_721530.normal.y * face->pFacePlane_old.vNormal.y + + stru_721530.normal.z * face->pFacePlane_old.vNormal.z) >> 16; + v5 = (stru_721530.normal2.z * face->pFacePlane_old.vNormal.z + face->pFacePlane_old.dist + + stru_721530.normal2.x * face->pFacePlane_old.vNormal.x + + stru_721530.normal2.y * face->pFacePlane_old.vNormal.y) >> 16; + if ((v4 < stru_721530.prolly_normal_d || v5 < stru_721530.prolly_normal_d) + && (v4 > -stru_721530.prolly_normal_d || v5 > -stru_721530.prolly_normal_d) + && (a3 = stru_721530.field_6C, sub_475D85(&stru_721530.normal, &stru_721530.direction, &a3, face)) + && a3 < (signed int)v10) + { + v10 = a3; + v12 = pIndoor->pSectors[stru_721530.uSectorID].pPortals[i]; + } + } + } + } + v1 = v10; + if (stru_721530.field_7C >= (signed int)v1 && (signed int)v1 <= stru_721530.field_6C) + { + stru_721530.field_80 = v12; + if (pIndoor->pFaces[v12].uSectorID == stru_721530.uSectorID) + stru_721530.uSectorID = pIndoor->pFaces[v12].uBackSectorID; + else + stru_721530.uSectorID = pIndoor->pFaces[v12].uSectorID; + stru_721530.field_7C = 268435455; + result = 0; + } + else + result = 1; + return result; +} + +//----- (0046DEF2) -------------------------------------------------------- +unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID) +{ + unsigned int result; // eax@1 + + result = uLayingItemID; + if (pObjectList->pObjects[pSpriteObjects[uLayingItemID].uObjectDescID].uFlags & 0x10) + result = _46BFFA_check_object_intercept(uLayingItemID, a2); + return result; +} + +//----- (0047253E) -------------------------------------------------------- +void UpdateObjects() +{ + ObjectDesc *object; // eax@5 + int v5; // ecx@6 + signed int v7; // eax@9 + signed int v11; // eax@17 + int v12; // edi@27 + int v18; // [sp+4h] [bp-10h]@27 + int v19; // [sp+8h] [bp-Ch]@27 + + for (uint i = 0; i < uNumSpriteObjects; ++i) + { + if (pSpriteObjects[i].uAttributes & OBJECT_40) + pSpriteObjects[i].uAttributes &= ~OBJECT_40; + else + { + object = &pObjectList->pObjects[pSpriteObjects[i].uObjectDescID]; + if (pSpriteObjects[i].AttachedToActor()) + { + v5 = PID_ID(pSpriteObjects[i].spell_target_pid); + pSpriteObjects[i].vPosition.x = pActors[v5].vPosition.x; + pSpriteObjects[i].vPosition.y = pActors[v5].vPosition.y; + pSpriteObjects[i].vPosition.z = pActors[v5].vPosition.z + pActors[v5].uActorHeight; + if (!pSpriteObjects[i].uObjectDescID) + continue; + pSpriteObjects[i].uSpriteFrameID += pEventTimer->uTimeElapsed; + if (!(object->uFlags & OBJECT_DESC_TEMPORARY)) + continue; + if (pSpriteObjects[i].uSpriteFrameID >= 0) + { + v7 = object->uLifetime; + if (pSpriteObjects[i].uAttributes & ITEM_BROKEN) + v7 = pSpriteObjects[i].field_20; + if (pSpriteObjects[i].uSpriteFrameID < v7) + continue; + } + SpriteObject::OnInteraction(i); + continue; + } + if (pSpriteObjects[i].uObjectDescID) + { + pSpriteObjects[i].uSpriteFrameID += pEventTimer->uTimeElapsed; + if (object->uFlags & OBJECT_DESC_TEMPORARY) + { + if (pSpriteObjects[i].uSpriteFrameID < 0) + { + SpriteObject::OnInteraction(i); + continue; + } + v11 = object->uLifetime; + if (pSpriteObjects[i].uAttributes & ITEM_BROKEN) + v11 = pSpriteObjects[i].field_20; + } + if (!(object->uFlags & OBJECT_DESC_TEMPORARY) || pSpriteObjects[i].uSpriteFrameID < v11) + { + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + SpriteObject::UpdateObject_fn0_BLV(i); + else + SpriteObject::UpdateObject_fn0_ODM(i); + if (pParty->bTurnBasedModeOn != 1 || !(pSpriteObjects[i].uSectorID & 4)) + continue; + v12 = abs(pParty->vPosition.x - pSpriteObjects[i].vPosition.x); + v18 = abs(pParty->vPosition.y - pSpriteObjects[i].vPosition.y); + v19 = abs(pParty->vPosition.z - pSpriteObjects[i].vPosition.z); + if (int_get_vector_length(v12, v18, v19) <= 5120) + continue; + SpriteObject::OnInteraction(i); + continue; + } + if (!(object->uFlags & OBJECT_DESC_INTERACTABLE)) + { + SpriteObject::OnInteraction(i); + continue; + } + _46BFFA_check_object_intercept(i, PID(OBJECT_Item, i)); + } + } + } +} + +//----- (0047531C) -------------------------------------------------------- +bool sub_47531C(int a1, int *a2, int pos_x, int pos_y, int pos_z, int dir_x, int dir_y, int dir_z, BLVFace *face, int a10) +{ + int v11; // ST1C_4@3 + int v12; // edi@3 + int v13; // esi@3 + int v14; // edi@4 + signed __int64 v15; // qtt@6 + //__int16 v16; // si@7 + int a7a; // [sp+30h] [bp+18h]@7 + int a9b; // [sp+38h] [bp+20h]@3 + int a9a; // [sp+38h] [bp+20h]@3 + int a10b; // [sp+3Ch] [bp+24h]@3 + signed int a10a; // [sp+3Ch] [bp+24h]@4 + int a10c; // [sp+3Ch] [bp+24h]@5 + + if (a10 && face->Ethereal()) + return 0; + v11 = fixpoint_mul(dir_x, face->pFacePlane_old.vNormal.x); + a10b = fixpoint_mul(dir_y, face->pFacePlane_old.vNormal.y); + a9b = fixpoint_mul(dir_z, face->pFacePlane_old.vNormal.z); + v12 = v11 + a9b + a10b; + a9a = v11 + a9b + a10b; + v13 = (a1 << 16) + - pos_x * face->pFacePlane_old.vNormal.x + - pos_y * face->pFacePlane_old.vNormal.y + - pos_z * face->pFacePlane_old.vNormal.z + - face->pFacePlane_old.dist; + if (abs((a1 << 16) + - pos_x * face->pFacePlane_old.vNormal.x + - pos_y * face->pFacePlane_old.vNormal.y + - pos_z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist) >= a1 << 16) + { + a10c = abs(v13) >> 14; + if (a10c > abs(v12)) + return 0; + LODWORD(v15) = v13 << 16; + HIDWORD(v15) = v13 >> 16; + v14 = a1; + a10a = v15 / a9a; + } + else + { + a10a = 0; + v14 = abs(v13) >> 16; + } + //v16 = pos_y + ((unsigned int)fixpoint_mul(a10a, dir_y) >> 16); + LOWORD(a7a) = (short)pos_x + ((unsigned int)fixpoint_mul(a10a, dir_x) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.x); + HIWORD(a7a) = pos_y + ((unsigned int)fixpoint_mul(a10a, dir_y) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.y); + if (!sub_475665(face, a7a, (short)pos_z + ((unsigned int)fixpoint_mul(a10a, dir_z) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.z))) + return 0; + *a2 = a10a >> 16; + if (a10a >> 16 < 0) + *a2 = 0; + return 1; +} + + +//----- (004754BF) -------------------------------------------------------- +bool sub_4754BF(int a1, int *a2, int X, int Y, int Z, int dir_x, int dir_y, int dir_z, BLVFace *face, int a10, int a11) +{ + int v12; // ST1C_4@3 + int v13; // edi@3 + int v14; // esi@3 + int v15; // edi@4 + signed __int64 v16; // qtt@6 + //__int16 v17; // si@7 + int a7a; // [sp+30h] [bp+18h]@7 + int a1b; // [sp+38h] [bp+20h]@3 + int a1a; // [sp+38h] [bp+20h]@3 + int a11b; // [sp+40h] [bp+28h]@3 + signed int a11a; // [sp+40h] [bp+28h]@4 + int a11c; // [sp+40h] [bp+28h]@5 + + if (a11 && face->Ethereal()) + return false; + v12 = fixpoint_mul(dir_x, face->pFacePlane_old.vNormal.x); + a11b = fixpoint_mul(dir_y, face->pFacePlane_old.vNormal.y); + a1b = fixpoint_mul(dir_z, face->pFacePlane_old.vNormal.z); + v13 = v12 + a1b + a11b; + a1a = v12 + a1b + a11b; + v14 = (a1 << 16) + - X * face->pFacePlane_old.vNormal.x + - Y * face->pFacePlane_old.vNormal.y + - Z * face->pFacePlane_old.vNormal.z + - face->pFacePlane_old.dist; + if (abs((a1 << 16) + - X * face->pFacePlane_old.vNormal.x + - Y * face->pFacePlane_old.vNormal.y + - Z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist) >= a1 << 16) + { + a11c = abs(v14) >> 14; + if (a11c > abs(v13)) + return false; + LODWORD(v16) = v14 << 16; + HIDWORD(v16) = v14 >> 16; + v15 = a1; + a11a = v16 / a1a; + } + else + { + a11a = 0; + v15 = abs(v14) >> 16; + } + //v17 = Y + ((unsigned int)fixpoint_mul(a11a, dir_y) >> 16); + LOWORD(a7a) = (short)X + ((unsigned int)fixpoint_mul(a11a, dir_x) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.x); + HIWORD(a7a) = Y + ((unsigned int)fixpoint_mul(a11a, dir_y) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.y); + if (!sub_4759C9(face, a10, a7a, (short)Z + ((unsigned int)fixpoint_mul(a11a, dir_z) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.z))) + return false; + *a2 = a11a >> 16; + if (a11a >> 16 < 0) + *a2 = 0; + return true; +} + +//----- (00475665) -------------------------------------------------------- +int sub_475665(BLVFace *face, int a2, __int16 a3) +{ + bool v16; // edi@14 + signed int v20; // ebx@18 + int v21; // edi@20 + signed int v22; // ST14_4@22 + signed __int64 v23; // qtt@22 + signed int result; // eax@25 + int v25; // [sp+14h] [bp-10h]@14 + int v26; // [sp+1Ch] [bp-8h]@2 + signed int v27; // [sp+20h] [bp-4h]@2 + signed int v28; // [sp+30h] [bp+Ch]@2 + signed int v29; // [sp+30h] [bp+Ch]@7 + signed int v30; // [sp+30h] [bp+Ch]@11 + signed int v31; // [sp+30h] [bp+Ch]@14 + + if (face->uAttributes & FACE_XY_PLANE) + { + v26 = (signed __int16)a2; + v27 = SHIWORD(a2); + if (face->uNumVertices) + { + for (v28 = 0; v28 < face->uNumVertices; v28++) + { + word_720C10_intercepts_xs[2 * v28] = face->pXInterceptDisplacements[v28] + pIndoor->pVertices[face->pVertexIDs[v28]].x; + word_720B40_intercepts_zs[2 * v28] = face->pYInterceptDisplacements[v28] + pIndoor->pVertices[face->pVertexIDs[v28]].y; + word_720C10_intercepts_xs[2 * v28 + 1] = face->pXInterceptDisplacements[v28 + 1] + pIndoor->pVertices[face->pVertexIDs[v28 + 1]].x; + word_720B40_intercepts_zs[2 * v28 + 1] = face->pYInterceptDisplacements[v28 + 1] + pIndoor->pVertices[face->pVertexIDs[v28 + 1]].y; + } + } + } + else + { + if (face->uAttributes & FACE_XZ_PLANE) + { + v26 = (signed __int16)a2; + v27 = a3; + if (face->uNumVertices) + { + for (v29 = 0; v29 < face->uNumVertices; v29++) + { + word_720C10_intercepts_xs[2 * v29] = face->pXInterceptDisplacements[v29] + pIndoor->pVertices[face->pVertexIDs[v29]].x; + word_720B40_intercepts_zs[2 * v29] = face->pZInterceptDisplacements[v29] + pIndoor->pVertices[face->pVertexIDs[v29]].z; + word_720C10_intercepts_xs[2 * v29 + 1] = face->pXInterceptDisplacements[v29 + 1] + pIndoor->pVertices[face->pVertexIDs[v29 + 1]].x; + word_720B40_intercepts_zs[2 * v29 + 1] = face->pZInterceptDisplacements[v29 + 1] + pIndoor->pVertices[face->pVertexIDs[v29 + 1]].z; + } + } + } + else + { + v26 = SHIWORD(a2); + v27 = a3; + if (face->uNumVertices) + { + for (v30 = 0; v30 < face->uNumVertices; v30++) + { + word_720C10_intercepts_xs[2 * v30] = face->pYInterceptDisplacements[v30] + pIndoor->pVertices[face->pVertexIDs[v30]].y; + word_720B40_intercepts_zs[2 * v30] = face->pZInterceptDisplacements[v30] + pIndoor->pVertices[face->pVertexIDs[v30]].z; + word_720C10_intercepts_xs[2 * v30 + 1] = face->pYInterceptDisplacements[v30 + 1] + pIndoor->pVertices[face->pVertexIDs[v30 + 1]].y; + word_720B40_intercepts_zs[2 * v30 + 1] = face->pZInterceptDisplacements[v30 + 1] + pIndoor->pVertices[face->pVertexIDs[v30 + 1]].z; + } + } + } + } + v31 = 0; + word_720C10_intercepts_xs[2 * face->uNumVertices] = word_720C10_intercepts_xs[0]; + word_720B40_intercepts_zs[2 * face->uNumVertices] = word_720B40_intercepts_zs[0]; + v16 = word_720B40_intercepts_zs[0] >= v27; + if (2 * face->uNumVertices <= 0) + return 0; + for (v25 = 0; v25 < 2 * face->uNumVertices; ++v25) + { + if (v31 >= 2) + break; + if (v16 ^ (word_720B40_intercepts_zs[v25 + 1] >= v27)) + { + if (word_720C10_intercepts_xs[v25 + 1] >= v26) + v20 = 0; + else + v20 = 2; + v21 = v20 | (word_720C10_intercepts_xs[v25] < v26); + if (v21 != 3) + { + v22 = word_720C10_intercepts_xs[v25 + 1] - word_720C10_intercepts_xs[v25]; + LODWORD(v23) = v22 << 16; + HIDWORD(v23) = v22 >> 16; + if (!v21 + || (word_720C10_intercepts_xs[v25] + ((signed int)(((unsigned __int64)(v23 + / (word_720B40_intercepts_zs[v25 + 1] - word_720B40_intercepts_zs[v25]) + * ((v27 - (signed int)word_720B40_intercepts_zs[v25]) << 16)) >> 16) + + 32768) >> 16) >= v26)) + ++v31; + } + } + v16 = word_720B40_intercepts_zs[v25 + 1] >= v27; + } + result = 1; + if (v31 != 1) + result = 0; + return result; +} + +//----- (004759C9) -------------------------------------------------------- +bool __fastcall sub_4759C9(BLVFace *face, int a2, int a3, __int16 a4) +{ + bool v12; // edi@14 + signed int v16; // ebx@18 + int v17; // edi@20 + signed int v18; // ST14_4@22 + signed __int64 v19; // qtt@22 + bool result; // eax@25 + int v21; // [sp+14h] [bp-10h]@14 + signed int v22; // [sp+18h] [bp-Ch]@1 + int v23; // [sp+1Ch] [bp-8h]@2 + signed int v24; // [sp+20h] [bp-4h]@2 + signed int a4d; // [sp+30h] [bp+Ch]@14 + + if (face->uAttributes & FACE_XY_PLANE) + { + v23 = (signed __int16)a3; + v24 = SHIWORD(a3); + if (face->uNumVertices) + { + for (v22 = 0; v22 < face->uNumVertices; ++v22) + { + word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pXInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].x); + word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pYInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].y); + word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pXInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].x); + word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pYInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].y); + } + } + } + else + { + if (face->uAttributes & FACE_XZ_PLANE) + { + v23 = (signed __int16)a3; + v24 = a4; + if (face->uNumVertices) + { + for (v22 = 0; v22 < face->uNumVertices; ++v22) + { + word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pXInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].x); + word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pZInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].z); + word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pXInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].x); + word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pZInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].z); + } + } + } + else + { + v23 = SHIWORD(a3); + v24 = a4; + if (face->uNumVertices) + { + for (v22 = 0; v22 < face->uNumVertices; ++v22) + { + word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pYInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].y); + word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pZInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].z); + word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pYInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].y); + word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pZInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].z); + } + } + } + } + a4d = 0; + word_720A70_intercepts_xs_plus_xs[2 * face->uNumVertices] = word_720A70_intercepts_xs_plus_xs[0]; + word_7209A0_intercepts_ys_plus_ys[2 * face->uNumVertices] = word_7209A0_intercepts_ys_plus_ys[0]; + v12 = word_7209A0_intercepts_ys_plus_ys[0] >= v24; + if (2 * face->uNumVertices <= 0) + return 0; + for (v21 = 0; v21 < 2 * face->uNumVertices; ++v21) + { + if (a4d >= 2) + break; + if (v12 ^ (word_7209A0_intercepts_ys_plus_ys[v21 + 1] >= v24)) + { + if (word_720A70_intercepts_xs_plus_xs[v21 + 1] >= v23) + v16 = 0; + else + v16 = 2; + v17 = v16 | (word_720A70_intercepts_xs_plus_xs[v21] < v23); + if (v17 != 3) + { + v18 = word_720A70_intercepts_xs_plus_xs[v21 + 1] - word_720A70_intercepts_xs_plus_xs[v21]; + LODWORD(v19) = v18 << 16; + HIDWORD(v19) = v18 >> 16; + if (!v17 + || (word_720A70_intercepts_xs_plus_xs[v21] + ((signed int)(((unsigned __int64)(v19 + / (word_7209A0_intercepts_ys_plus_ys[v21 + 1] - word_7209A0_intercepts_ys_plus_ys[v21]) + * ((v24 - (signed int)word_7209A0_intercepts_ys_plus_ys[v21]) << 16)) >> 16) + + 0x8000) >> 16) >= v23)) + ++a4d; + } + } + v12 = word_7209A0_intercepts_ys_plus_ys[v21 + 1] >= v24; + } + result = 1; + if (a4d != 1) + result = 0; + return result; +} + +//----- (00475D85) -------------------------------------------------------- +bool __fastcall sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, BLVFace *a4) +{ + BLVFace *v4; // ebx@1 + int v5; // ST24_4@2 + int v6; // ST28_4@2 + int v7; // edi@2 + int v8; // eax@5 + signed int v9; // esi@5 + signed __int64 v10; // qtt@10 + Vec3_int_ *v11; // esi@11 + int v12; // ST14_4@11 + Vec3_int_ *v14; // [sp+Ch] [bp-18h]@1 + Vec3_int_ *v15; // [sp+14h] [bp-10h]@1 + // int v16; // [sp+18h] [bp-Ch]@2 + int v17; // [sp+20h] [bp-4h]@10 + int a4b; // [sp+30h] [bp+Ch]@2 + int a4c; // [sp+30h] [bp+Ch]@9 + signed int a4a; // [sp+30h] [bp+Ch]@10 + + v4 = a4; + v15 = a2; + v14 = a1; + v5 = fixpoint_mul(a2->x, a4->pFacePlane_old.vNormal.x); + a4b = fixpoint_mul(a2->y, a4->pFacePlane_old.vNormal.y); + v6 = fixpoint_mul(a2->z, v4->pFacePlane_old.vNormal.z); + v7 = v5 + v6 + a4b; + //(v16 = v5 + v6 + a4b) == 0; + if (a4->uAttributes & 0x20000000 || !v7 || v7 > 0 && !v4->Portal()) + return 0; + v8 = v4->pFacePlane_old.vNormal.z * a1->z; + v9 = -(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x); + if (v7 <= 0) + { + if (v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x < 0) + return 0; + } + else + { + if (v9 < 0) + return 0; + } + a4c = abs(-(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x)) >> 14; + v11 = v14; + LODWORD(v10) = v9 << 16; + HIDWORD(v10) = v9 >> 16; + a4a = v10 / v7; + v17 = v10 / v7; + LOWORD(v12) = LOWORD(v14->x) + (((unsigned int)fixpoint_mul(v17, v15->x) + 0x8000) >> 16); + HIWORD(v12) = LOWORD(v11->y) + (((unsigned int)fixpoint_mul(v17, v15->y) + 0x8000) >> 16); + if (a4c > abs(v7) || (v17 > *a3 << 16) || !sub_475665(v4, v12, LOWORD(v11->z) + (((unsigned int)fixpoint_mul(v17, v15->z) + 0x8000) >> 16))) + return 0; + *a3 = a4a >> 16; + return 1; +} + +//----- (00475F30) -------------------------------------------------------- +bool __fastcall sub_475F30(int *a1, BLVFace *a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) +{ + int v10; // ST20_4@2 + int v11; // ST28_4@2 + int v12; // ST24_4@2 + int v13; // zf@2 + int v14; // edi@2 + signed int v16; // esi@5 + int v17; // ST20_4@9 + signed __int64 v18; // qtt@10 + int v19; // ST14_4@11 + int v22; // [sp+1Ch] [bp-8h]@2 + int v23; // [sp+1Ch] [bp-8h]@10 + signed int v24; // [sp+20h] [bp-4h]@10 + + v10 = fixpoint_mul(a6, a2->pFacePlane_old.vNormal.x); + v11 = fixpoint_mul(a7, a2->pFacePlane_old.vNormal.y); + v12 = fixpoint_mul(a8, a2->pFacePlane_old.vNormal.z); + v13 = v10 + v12 + v11; + v14 = v10 + v12 + v11; + v22 = v10 + v12 + v11; + if (a2->Ethereal() || !v13 || v14 > 0 && !a2->Portal()) + return 0; + v16 = -(a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z); + if (v14 <= 0) + { + if (a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z < 0) + return 0; + } + else + { + if (v16 < 0) + return 0; + } + v17 = abs(-(a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z)) >> 14; + LODWORD(v18) = v16 << 16; + HIDWORD(v18) = v16 >> 16; + v24 = v18 / v22; + v23 = v18 / v22; + LOWORD(v19) = a3 + (((unsigned int)fixpoint_mul(v23, a6) + 0x8000) >> 16); + HIWORD(v19) = a4 + (((unsigned int)fixpoint_mul(v23, a7) + 0x8000) >> 16); + if (v17 > abs(v14) || v23 > *a1 << 16 || !sub_4759C9(a2, a9, v19, a5 + (((unsigned int)fixpoint_mul(v23, a8) + 0x8000) >> 16))) + return 0; + *a1 = v24 >> 16; + return 1; +} + +//----- (00479089) -------------------------------------------------------- +bool __fastcall IsBModelVisible(unsigned int uModelID, int *reachable) +{ + int v3; // edi@1 + int v4; // ebx@1 + int v9; // eax@3 + signed int v11; // esi@6 + int v12; // esi@8 + bool result; // eax@9 + int v17; // [sp+1Ch] [bp-10h]@1 + int v19; // [sp+20h] [bp-Ch]@3 + int angle; // [sp+24h] [bp-8h]@1 + + angle = (signed int)(pODMRenderParams->uCameraFovInDegrees << 11) / 360 / 2; + v3 = pOutdoor->pBModels[uModelID].vBoundingCenter.x - pGame->pIndoorCameraD3D->vPartyPos.x; + v4 = pOutdoor->pBModels[uModelID].vBoundingCenter.y - pGame->pIndoorCameraD3D->vPartyPos.y; + stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX); + v17 = v3 * stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY) + v4 * stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); + if (pGame->pIndoorCameraD3D->sRotationX) + v17 = fixpoint_mul(v17, stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX)); + v19 = v4 * stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY) - v3 * stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); + v9 = int_get_vector_length(abs(v3), abs(v4), 0); + //v10 = v14 * 188; + //v22 = v9; + *reachable = false; + if (v9 < pOutdoor->pBModels[uModelID].sBoundingRadius + 256) + *reachable = true; + if (v19 >= 0) + v11 = fixpoint_mul(stru_5C6E00->Sin(angle), v17) - fixpoint_mul(stru_5C6E00->Cos(angle), v19); + else + v11 = fixpoint_mul(stru_5C6E00->Cos(angle), v19) + fixpoint_mul(stru_5C6E00->Sin(angle), v17); + v12 = v11 >> 16; + if (v9 <= pODMRenderParams->shading_dist_mist + 2048) + { + //if ( abs(v12) > *(int *)((char *)&pOutdoor->pBModels->sBoundingRadius + v10) + 512 ) + if (abs(v12) > pOutdoor->pBModels[uModelID].sBoundingRadius + 512) + { + result = v12 < 0; + LOBYTE(result) = v12 >= 0; + return result; + } + else + return true; + } + return false; +} + +//----- (00479295) -------------------------------------------------------- +int Polygon::_479295() +{ + int v3; // ecx@4 + int v4; // eax@4 + int v5; // edx@4 + // int v6; // ST14_4@5 + Vec3_int_ thisa; // [sp+Ch] [bp-10h]@8 + int v11; // [sp+18h] [bp-4h]@4 + + if (!this->pODMFace->pFacePlane.vNormal.z) + { + v3 = this->pODMFace->pFacePlane.vNormal.x; + v4 = -this->pODMFace->pFacePlane.vNormal.y; + v5 = 0; + v11 = 65536; + } + else if ((this->pODMFace->pFacePlane.vNormal.x || this->pODMFace->pFacePlane.vNormal.y) + && abs(this->pODMFace->pFacePlane.vNormal.z) < 59082) + { + thisa.x = -this->pODMFace->pFacePlane.vNormal.y; + thisa.y = this->pODMFace->pFacePlane.vNormal.x; + thisa.z = 0; + thisa.Normalize_float(); + v4 = thisa.x; + v3 = thisa.y; + v5 = 0; + v11 = 65536; + } + else + { + v3 = 0; + v4 = 65536; + v11 = 0; + v5 = -65536; + } + sTextureDeltaU = this->pODMFace->sTextureDeltaU; + sTextureDeltaV = this->pODMFace->sTextureDeltaV; + ptr_38->_48616B_frustum_odm(v4, v3, 0, 0, v5, v11); + return 1; +} + + +unsigned short *LoadTgaTexture(const wchar_t *filename, int *out_width = nullptr, int *out_height = nullptr) +{ +#pragma pack(push, 1) + struct TGAHeader + { + unsigned char tgaSkip; + unsigned char colourmaptype; // type of colour map 0=none, 1=has palette + unsigned char tgaType; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed + + short colourmapstart; // first colour map entry in palette + short colourmaplength; // number of colours in palette + char colourmapbits; // number of bits per palette entry 15,16,24,32 + + //unsigned char tgaDontCare2[9]; + short xstart; // image x origin + short ystart; // image y origin + + unsigned short tgaWidth; + unsigned short tgaHeight; + unsigned char tgaBPP; + + char descriptor; // image descriptor bits: 00vhaaaa + // h horizontal flip + // v vertical flip + // a alpha bits + }; +#pragma pack(pop) + + if (out_width) + *out_width = 0; + if (out_height) + *out_height = 0; + + DWORD w; + void* file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); + if (file == INVALID_HANDLE_VALUE) + return nullptr; + + TGAHeader header; + ReadFile(file, &header, sizeof(header), &w, nullptr); + SetFilePointer(file, header.tgaSkip, nullptr, FILE_CURRENT); + + if (header.tgaBPP != 24 || header.tgaType != 2) + { + CloseHandle(file); + return nullptr; + } + + int imgSize = header.tgaWidth * header.tgaHeight * 3; + unsigned char* pixels = new unsigned char[imgSize]; + ReadFile(file, pixels, imgSize, &w, nullptr); + CloseHandle(file); + + if (w != imgSize) + { + delete[] pixels; + return nullptr; + } + + if (out_width) + *out_width = header.tgaWidth; + if (out_height) + *out_height = header.tgaHeight; + + unsigned short* pixels_16bit = new unsigned short[imgSize / 3]; + for (int i = 0; i < imgSize / 3; ++i) + { + pixels_16bit[i] = (pixels[i * 3] / 8 & 0x1F) | + ((pixels[i * 3 + 1] / 4 & 0x3F) << 5) | + ((pixels[i * 3 + 2] / 8 & 0x1F) << 11); + } + delete[] pixels; + return pixels_16bit; +} + +unsigned short *skybox_xn, *skybox_xp, +*skybox_yn, *skybox_yp, +*skybox_zn, *skybox_zp; +int skybox_width, skybox_height; + +IDirect3DTexture2 *skybox_texture; +IDirectDrawSurface4 *skybox_surface; + +bool Skybox_Initialize(const wchar_t *skybox_name) +{ + wchar_t xn_filename[1024], xp_filename[1024], + yn_filename[1024], yp_filename[1024], + zn_filename[1024], zp_filename[1024]; + swprintf(xn_filename, wcslen(L"%s_xn.tga"), L"%s_xn.tga", skybox_name); swprintf(xp_filename, wcslen(L"%s_xp.tga"), L"%s_xp.tga", skybox_name); + swprintf(yn_filename, wcslen(L"%s_yn.tga"), L"%s_yn.tga", skybox_name); swprintf(yp_filename, wcslen(L"%s_yp.tga"), L"%s_yp.tga", skybox_name); + swprintf(zn_filename, wcslen(L"%s_zn.tga"), L"%s_zn.tga", skybox_name); swprintf(zp_filename, wcslen(L"%s_zp.tga"), L"%s_zp.tga", skybox_name); + + int xn_width, xn_height; + skybox_xn = LoadTgaTexture(xn_filename, &xn_width, &xn_height); + if (!skybox_xn) + return false; + + int xp_width, xp_height; + skybox_xp = LoadTgaTexture(xp_filename, &xp_width, &xp_height); + if (!skybox_xp || xp_width != xn_width || xp_height != xn_height) + { + delete[] skybox_xn; + delete[] skybox_xp; + return false; + } + + int yn_width, yn_height; + skybox_yn = LoadTgaTexture(yn_filename, &yn_width, &yn_height); + if (!skybox_yn || yn_width != xn_width || yn_height != xn_height) + { + delete[] skybox_xn; + delete[] skybox_xp; + delete[] skybox_yn; + return false; + } + + int yp_width, yp_height; + skybox_yp = LoadTgaTexture(yp_filename, &yp_width, &yp_height); + if (!skybox_yp || yp_width != xn_width || yp_height != xn_height) + { + delete[] skybox_xn; + delete[] skybox_xp; + delete[] skybox_yn; + delete[] skybox_yp; + return false; + } + + int zn_width, zn_height; + skybox_zn = LoadTgaTexture(zn_filename, &zn_width, &zn_height); + if (!skybox_zn || zn_width != xn_width || zn_height != xn_height) + { + delete[] skybox_xn; + delete[] skybox_xp; + delete[] skybox_yn; + delete[] skybox_yp; + delete[] skybox_zn; + return false; + } + + int zp_width, zp_height; + skybox_zp = LoadTgaTexture(zp_filename, &zp_width, &zp_height); + if (!skybox_zp || zp_width != xn_width || zp_height != xn_height) + { + delete[] skybox_xn; + delete[] skybox_xp; + delete[] skybox_yn; + delete[] skybox_yp; + delete[] skybox_zn; + delete[] skybox_zp; + return false; + } + + skybox_width = xn_width; + skybox_height = xn_height; + + __debugbreak(); + //if (!pRenderer->pRenderD3D->CreateTexture(skybox_width, skybox_height, &skybox_surface, &skybox_texture, + //false, false, pRenderer->uMinDeviceTextureDim)) + return false; + + return true; +} + +struct vector +{ + float x, y, z; +}; + +struct matrix +{ + float m[4][4]; +}; + +void VectorNormalize(vector *v) +{ + float invmag = 1.0f / sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); + v->x *= invmag; + v->y *= invmag; + v->z *= invmag; +} + +void MatrixRotationAxis(matrix *pout, CONST vector *pv, float angle) +{ + memset(pout, 0, sizeof(matrix)); + pout->m[3][0] = 0; + pout->m[3][1] = 0; + pout->m[3][2] = 0; + pout->m[3][3] = 1; + + vector v; + v.x = pv->x; v.y = pv->y; v.z = pv->z; + VectorNormalize(&v); + + pout->m[0][0] = (1.0f - cos(angle)) * v.x * v.x + cos(angle); + pout->m[1][0] = (1.0f - cos(angle)) * v.x * v.y - sin(angle) * v.z; + pout->m[2][0] = (1.0f - cos(angle)) * v.x * v.z + sin(angle) * v.y; + pout->m[0][1] = (1.0f - cos(angle)) * v.y * v.x + sin(angle) * v.z; + pout->m[1][1] = (1.0f - cos(angle)) * v.y * v.y + cos(angle); + pout->m[2][1] = (1.0f - cos(angle)) * v.y * v.z - sin(angle) * v.x; + pout->m[0][2] = (1.0f - cos(angle)) * v.z * v.x - sin(angle) * v.y; + pout->m[1][2] = (1.0f - cos(angle)) * v.z * v.y + sin(angle) * v.x; + pout->m[2][2] = (1.0f - cos(angle)) * v.z * v.z + cos(angle); +} + +void VectorTransform(const matrix *m, const vector *v, vector *out) +{ + out->x = m->m[0][0] * v->x + m->m[1][0] * v->y + m->m[2][0] * v->z + m->m[3][0]; + out->y = m->m[0][1] * v->x + m->m[1][1] * v->y + m->m[2][1] * v->z + m->m[3][1]; + out->z = m->m[0][2] * v->x + m->m[1][2] * v->y + m->m[2][2] * v->z + m->m[3][2]; +} + +bool DrawSkyD3D_Skybox() +{ + static bool initialized = false, + initialization_failed = false; + if (initialization_failed) + return false; + + static int last_camera_rot_y, + last_camera_rot_x; + if (!initialized) + { + if (!Skybox_Initialize(L"data/skybox/stars")) + { + initialization_failed = true; + return false; + } + initialized = true; + + last_camera_rot_y = pParty->sRotationY + 1; // force update for the first run + last_camera_rot_x = pParty->sRotationX + 1; + } + + /* + r(y) = + cos y 0 sin y 0 + 0 1 0 0 + -sin y 0 cos y 0 + 0 0 0 1 + + x cos y - z sin y + y + x sin y + z cos y + 1 + + + + r(x) = // should be r(right) actually + 1 0 0 0 + 0 cos x -sin x 0 + 0 sin x cos x 0 + 0 0 0 1 + + + x + y cos x + z sin x + -y sin x + z cos x + 1 + + */ + + if (last_camera_rot_y == pParty->sRotationY && + last_camera_rot_x == pParty->sRotationX) + { + draw: + struct RenderVertexD3D3 v[6]; + + v[0].pos.x = pViewport->uScreen_TL_X; + v[0].pos.y = pViewport->uScreen_TL_Y; + v[0].pos.z = 0.99989998; + v[0].rhw = 1; + v[0].diffuse = -1; + v[0].specular = 0; + v[0].texcoord.x = 0; + v[0].texcoord.y = 0; + + v[1].pos.x = pViewport->uScreen_TL_X + pViewport->uScreenWidth; + v[1].pos.y = pViewport->uScreen_TL_Y + pViewport->uScreenHeight; + v[1].pos.z = 0.99989998; + v[1].rhw = 1; + v[1].diffuse = -1; + v[1].specular = 0; + v[1].texcoord.x = (float)pViewport->uScreenWidth / skybox_width; + v[1].texcoord.y = (float)pViewport->uScreenHeight / skybox_height; + + v[2].pos.x = pViewport->uScreen_TL_X + pViewport->uScreenWidth; + v[2].pos.y = pViewport->uScreen_TL_Y; + v[2].pos.z = 0.99989998; + v[2].rhw = 1; + v[2].diffuse = -1; + v[2].specular = 0; + v[2].texcoord.x = (float)pViewport->uScreenWidth / skybox_width; + v[2].texcoord.y = 0; + + memcpy(&v[3], &v[0], sizeof(*v)); + + v[4].pos.x = pViewport->uScreen_TL_X; + v[4].pos.y = pViewport->uScreen_TL_Y + pViewport->uScreenHeight; + v[4].pos.z = 0.99989998; + v[4].rhw = 1; + v[4].diffuse = -1; + v[4].specular = 0; + v[4].texcoord.x = 0; + v[4].texcoord.y = (float)pViewport->uScreenHeight / skybox_height; + + memcpy(&v[5], &v[1], sizeof(*v)); + + __debugbreak(); + /* + pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); + pRenderer->pRenderD3D->pDevice->SetTexture(0, skybox_texture); + pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v, 6, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTLIGHT); + */ + return true; + } + + + DDSURFACEDESC2 desc; + desc.dwSize = sizeof(desc); + if (!pRenderer->LockSurface_DDraw4(skybox_surface, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY)) + return false; + + last_camera_rot_y = pParty->sRotationY; + last_camera_rot_x = pParty->sRotationX; + + float aspect = (float)pViewport->uScreenWidth / (float)pViewport->uScreenHeight; + float fov_x = 3.141592f * (pODMRenderParams->uCameraFovInDegrees + 0) / 360.0f; + float fov_y = fov_x / aspect; + + float ray_dx = fov_x / (float)pViewport->uScreenWidth, + ray_dy = fov_y / (float)pViewport->uScreenHeight; + float party_angle_x = 2 * 3.141592653589 * pParty->sRotationX / 2048.0, + party_angle_y = 2 * 3.141592653589 * pParty->sRotationY / 2048.0; + for (int y = 0; y < pViewport->uScreenHeight; ++y) + for (int x = 0; x < pViewport->uScreenWidth; ++x) + { + float angle_x = party_angle_x - (y - pViewport->uScreenHeight / 2) * ray_dy; + float angle_y = party_angle_y - (x - pViewport->uScreenWidth / 2) * ray_dx; + + float _dir_x_ = 1, + _dir_y_ = 0, + _dir_z_ = 0; + + float dir_x_ = _dir_x_ * cosf(angle_y);// - _dir_z_ * sinf(angle_y); // rotation around y + //float dir_y_ = _dir_y_; + float dir_z_ = _dir_x_ * sinf(angle_y);// + _dir_z_ * cosf(angle_y); + + //float dir_x = dir_x_; // rotation around x + //float dir_y = /*dir_y_ * cosf(angle_x)*/ + dir_z_ * sinf(angle_x); + //float dir_z = /*-dir_y_ * sinf(angle_x)*/ + dir_z_ * cosf(angle_x); + + vector right; // rotate around right actually to avoid space distortion + right.x = /*dir_y * 0*/ -dir_z_ * 1; + right.y = /*dir_z_ * 0 - dir_x_ * */0; + right.z = dir_x_ * 1/* - dir_y_ * 0*/; + //VectorNormalize(&right); + + matrix rightMatrix; + MatrixRotationAxis(&rightMatrix, &right, angle_x); + + vector v1, v2; + v1.x = dir_x_; v1.y = 0; v1.z = dir_z_; + VectorTransform(&rightMatrix, &v1, &v2); + + float dir_x = v2.x, + dir_y = v2.y, + dir_z = v2.z; + + float abs_dir_x = fabsf(dir_x), + abs_dir_y = fabsf(dir_y), + abs_dir_z = fabsf(dir_z); + + unsigned short color = (0x1F << 11) | (0x1F << 5) | (5); //default to orange + if (abs_dir_x >= abs_dir_y) + { + if (abs_dir_x >= abs_dir_z) + { + if (dir_x >= 0) + { + float instersect_y = dir_y / (2.0f * dir_x); // plane equation for this side is x + 0.5 = 0 + float instersect_z = dir_z / (2.0f * dir_x); + + float u = 1.0f - (instersect_z + 0.5f), + v = 1.0f - (instersect_y + 0.5f); + + int tx = u * (skybox_width - 1), + ty = v * (skybox_height - 1); + + color = skybox_xp[ty * skybox_width + tx]; + //color = ty * 0x1F / skybox_height; + } + else + { + float instersect_y = dir_y / (2.0f * dir_x); + float instersect_z = dir_z / (2.0f * dir_x); + + float u = 1.0f - (instersect_z + 0.5f), + v = instersect_y + 0.5f; + + int tx = u * (skybox_width - 1), + ty = v * (skybox_height - 1); + + color = skybox_xn[ty * skybox_width + tx]; + //color = tx * 0x1F / skybox_height; + } + } + else if (dir_z >= 0) + goto DIR_ZP; + else + goto DIR_ZN; + } + else if (abs_dir_y >= abs_dir_z) + { + if (dir_y >= 0) + { + float instersect_x = dir_x / (2.0f * dir_y); + float instersect_z = dir_z / (2.0f * dir_y); + + float u = instersect_x + 0.5f, + v = instersect_z + 0.5f; + + int tx = u * (skybox_width - 1), + ty = v * (skybox_height - 1); + + color = skybox_yp[ty * skybox_width + tx]; + //color = tx * 0x1F / skybox_height; + } + /*else should never be seen i guess + { + __debugbreak(); + // -y + //Log::Warning(L"(%03u, %03u): -y", x, y); + }*/ + } + else if (dir_z >= 0) + { + DIR_ZP: + // +z + float instersect_x = dir_x / (2.0f * dir_z); + float instersect_y = dir_y / (2.0f * dir_z); + //float intersect_z = 0.5f; + + float u = instersect_x + 0.5f, + v = -instersect_y + 0.5f; + + int tx = u * (skybox_width - 1), + ty = v * (skybox_height - 1); + + color = skybox_zp[ty * skybox_width + tx]; + } + else + { + DIR_ZN: + // -z + float instersect_x = -dir_x / (2.0f * dir_z); + float instersect_y = -dir_y / (2.0f * dir_z); + //float intersect_z = -0.5f; + + float u = 1.0f - instersect_x - 0.5f, + v = -instersect_y + 0.5f; + + int tx = u * (skybox_width - 1), + ty = v * (skybox_height - 1); + + color = skybox_zn[ty * skybox_width + tx]; + } + + //pRenderer->pTargetSurface[(pViewport->uScreenY + y) * pRenderer->uTargetSurfacePitch + pViewport->uScreenX + x] = color; + ((unsigned __int16 *)((char *)desc.lpSurface + y * desc.lPitch))[x] = color; + } + + ErrD3D((skybox_surface)->Unlock(0)); + goto draw; +} + +//----- (00485F53) -------------------------------------------------------- +void sr_485F53(Vec2_int_ *v) +{ + ++v->y; + if (v->y > 1000) + v->y = 0; +} + +//----- (0048607B) -------------------------------------------------------- +void Polygon::Create_48607B(stru149 *a2) +{ + this->pTexture = 0; + this->ptr_38 = a2; +} + +//----- (00486089) -------------------------------------------------------- +void Polygon::_normalize_v_18() +{ + //double v2; // st7@1 + //double v3; // st6@1 + //double v5; // st5@1 + + // v2 = (double)this->v_18.x; + //v3 = (double)this->v_18.y; + // v5 = (double)this->v_18.z; + float len = sqrt((double)this->v_18.z * (double)this->v_18.z + (double)this->v_18.y * (double)this->v_18.y + (double)this->v_18.x * (double)this->v_18.x); + if (fabsf(len) < 1e-6f) + { + v_18.x = 0; + v_18.y = 0; + v_18.z = 65536; + } + else + { + v_18.x = round_to_int((double)this->v_18.x / len * 65536.0); + v_18.y = round_to_int((double)this->v_18.y / len * 65536.0); + v_18.y = round_to_int((double)this->v_18.z / len * 65536.0); + } +} + +//----- (0048616B) -------------------------------------------------------- +void stru149::_48616B_frustum_odm(int a2, int a3, int a4, int a5, int a6, int a7) +{ + int v7; // ebx@1 + int v9; // edi@1 + int v11; // edx@1 + int v17; // ST0C_4@6 + int v19; // ST0C_4@9 + int v24; // [sp+14h] [bp-14h]@1 + int v25; // [sp+18h] [bp-10h]@1 + int v27; // [sp+24h] [bp-4h]@1 + + v25 = pGame->pIndoorCameraD3D->int_cosine_x; + v7 = pGame->pIndoorCameraD3D->int_sine_y; + v27 = pGame->pIndoorCameraD3D->int_sine_x; + //v8 = -pIndoorCamera->pos.y; + v9 = pGame->pIndoorCameraD3D->int_cosine_y; + //v26 = -pIndoorCamera->pos.z; + v11 = pGame->pIndoorCameraD3D->int_cosine_y * -pGame->pIndoorCameraD3D->vPartyPos.x + pGame->pIndoorCameraD3D->int_sine_y * -pGame->pIndoorCameraD3D->vPartyPos.y; + v24 = pGame->pIndoorCameraD3D->int_cosine_y * -pGame->pIndoorCameraD3D->vPartyPos.y - pGame->pIndoorCameraD3D->int_sine_y * -pGame->pIndoorCameraD3D->vPartyPos.x; + if (pGame->pIndoorCameraD3D->sRotationX) + { + this->field_0_party_dir_x = fixpoint_mul(v11, pGame->pIndoorCameraD3D->int_cosine_x) + + fixpoint_mul((-pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x); + this->field_4_party_dir_y = v24; + this->field_8_party_dir_z = fixpoint_mul((-pGame->pIndoorCameraD3D->vPartyPos.z) << 16, v25) - fixpoint_mul(v11, v27); + } + else + { + this->field_0_party_dir_x = v11; + this->field_4_party_dir_y = v24; + this->field_8_party_dir_z = (-pGame->pIndoorCameraD3D->vPartyPos.z) << 16; + } + + if (pGame->pIndoorCameraD3D->sRotationX) + { + v17 = fixpoint_mul(a2, v9) + fixpoint_mul(a3, v7); + + this->angle_from_north = fixpoint_mul(v17, v25) + fixpoint_mul(a4, v27); + this->angle_from_west = fixpoint_mul(a3, v9) - fixpoint_mul(a2, v7); + this->viewing_angle_from_west_east = fixpoint_mul(a4, v25) - fixpoint_mul(v17, v27); + } + else + { + this->angle_from_north = fixpoint_mul(a2, v9) + fixpoint_mul(a3, v7); + this->angle_from_west = fixpoint_mul(a3, v9) - fixpoint_mul(a2, v7); + this->viewing_angle_from_west_east = a4; + } + + if (pGame->pIndoorCameraD3D->sRotationX) + { + v19 = fixpoint_mul(a5, v9) + fixpoint_mul(a6, v7); + + this->angle_from_east = fixpoint_mul(v19, v25) + fixpoint_mul(a7, v27); + this->angle_from_south = fixpoint_mul(a6, v9) - fixpoint_mul(a5, v7); + this->viewing_angle_from_north_south = fixpoint_mul(a7, v25) - fixpoint_mul(v19, v27); + } + else + { + this->angle_from_east = fixpoint_mul(a5, v9) + fixpoint_mul(a6, v7); + this->angle_from_south = fixpoint_mul(a6, v9) - fixpoint_mul(a5, v7); + this->viewing_angle_from_north_south = a7; + } + + this->angle_from_east = -this->angle_from_east; + this->angle_from_south = -this->angle_from_south; + this->viewing_angle_from_north_south = -this->viewing_angle_from_north_south; + + this->field_24 = fixpoint_dot(this->angle_from_north, this->field_0_party_dir_x, + this->angle_from_west, this->field_4_party_dir_y, + this->viewing_angle_from_west_east, this->field_8_party_dir_z); + this->field_28 = fixpoint_dot(this->angle_from_east, this->field_0_party_dir_x, + this->angle_from_south, this->field_4_party_dir_y, + this->viewing_angle_from_north_south, this->field_8_party_dir_z); +} + +//----- (0048694B) -------------------------------------------------------- +void stru149::_48694B_frustum_sky() +{ + this->angle_from_east = -this->angle_from_east; + this->angle_from_south = -this->angle_from_south; + this->viewing_angle_from_north_south = -this->viewing_angle_from_north_south; + + this->field_24 = fixpoint_dot(this->angle_from_north, this->field_0_party_dir_x, + this->angle_from_west, this->field_4_party_dir_y, + this->viewing_angle_from_west_east, this->field_8_party_dir_z); + this->field_28 = fixpoint_dot(this->angle_from_east, this->field_0_party_dir_x, + this->angle_from_south, this->field_4_party_dir_y, + this->viewing_angle_from_north_south, this->field_8_party_dir_z); +} + diff -r 0f17a30149ec -r 104fdbea0386 Render.h --- a/Render.h Sun Aug 17 15:13:18 2014 +0100 +++ b/Render.h Sun Aug 17 17:49:34 2014 +0100 @@ -2,6 +2,7 @@ #include #include +#include #include "lib\legacy_dx\d3d.h" #include "OSWindow.h" @@ -11,6 +12,181 @@ #include "IRender.h" +#pragma pack(push, 1) +struct DDM_DLV_Header +{ + //----- (00462607) -------------------------------------------------------- + inline DDM_DLV_Header() + { + this->uLastRepawnDay = 0; + this->uNumRespawns = 0; + this->uReputation = 0; + this->field_C_alert = 0; + this->uNumFacesInBModels = 0; + this->uNumDecorations = 0; + this->uNumBModels = 0; + } + + + int uNumRespawns; + int uLastRepawnDay; + int uReputation; + int field_C_alert; + unsigned int uNumFacesInBModels; + unsigned int uNumDecorations; + unsigned int uNumBModels; + int field_1C; + int field_20; + int field_24; +}; +#pragma pack(pop) + + +struct ODMFace; + + +/* 141 */ +// stru148 +#pragma pack(push, 1) +struct Polygon +{ + inline Polygon() + { + uNumVertices = 0; + } + + int _479295(); + //void _48276F_sr(); + void _normalize_v_18(); + void Create_48607B(struct stru149 *a2); + + float field_0; + float field_4; + float field_8; + float field_C; + float field_10; + unsigned int uNumVertices; + Vec3_int_ v_18; + int field_24; + int sTextureDeltaU; + int sTextureDeltaV; + __int16 flags; + __int16 field_32; + int field_34; + struct stru149 *ptr_38; + struct Texture *pTexture; + struct Span *_unused_prolly_head; + struct Span *_unused_prolly_tail; + int **ptr_48; + unsigned __int16 uTileBitmapID; + __int16 field_4E; + __int16 field_50; + __int16 field_52; + ODMFace *pODMFace; + char dimming_level; + char field_59; + char field_5A; + char field_5B; + char terrain_grid_z; + char terrain_grid_x; + unsigned __int8 uBModelID; + unsigned __int8 uBModelFaceID; + struct Edge *pEdgeList1[20]; + unsigned int uEdgeList1Size; + struct Edge *pEdgeList2[20]; + unsigned int uEdgeList2Size; + char field_108; + char field_109; + char field_10A; + char field_10B; +}; +#pragma pack(pop) +extern std::array array_77EC08; + + +/* 142 */ +#pragma pack(push, 1) +struct stru149 +{ + void _48616B_frustum_odm(int a2, int a3, int a4, int a5, int a6, int a7); + void _48653D_frustum_blv(int a2, int a3, int a4, int a5, int a6, int a7); + void _48694B_frustum_sky(); + + int field_0_party_dir_x; + int field_4_party_dir_y; + int field_8_party_dir_z; + int angle_from_north;//field_C + int angle_from_west;//field_10 + int viewing_angle_from_west_east; + int angle_from_east;//field_18 + int angle_from_south;//field_1C + int viewing_angle_from_north_south;//field_20 + int field_24; + int field_28; +}; +#pragma pack(pop) +extern stru149 stru_8019C8; + +/* 88 */ +#pragma pack(push, 1) +struct ODMRenderParams +{ + //----- (00462684) -------------------------------------------------------- + ODMRenderParams() + { + uPickDepth = 0; + this->shading_dist_shade = 2048; + shading_dist_shademist = 4096; + shading_dist_mist = 8192; + int_fov_rad = 0; + this->bNoSky = 0; + this->bDoNotRenderDecorations = 0; + this->field_5C = 0; + this->field_60 = 0; + this->outdoor_no_wavy_water = 0; + this->outdoor_no_mist = 0; + } + + void Initialize(); + + int uPickDepth; + int shading_dist_shade; + int shading_dist_shademist; + int shading_dist_mist; + unsigned int uCameraFovInDegrees; + int int_fov_rad; // 157 struct IndoorCamera::fov_rad + int int_fov_rad_inv; // 157 struct IndoorCamera::fov_rad_inv + int _unused_camera_rotation_y_int_sine; // merged with BLVRenderParams equivalents + int _unused_camera_rotation_y_int_cosine; // into IndoorCameraD3D + int _unused_camera_rotation_x_int_sine; // --//-- + int _unused_camera_rotation_x_int_cosine; // --//-- + int uNumPolygons; + unsigned int _unused_uNumEdges; + unsigned int _unused_uNumSurfs; + unsigned int _unused_uNumSpans; + unsigned int uNumBillboards; + float field_40; + int field_44; + int outdoor_grid_band_3; + int field_4C; + int field_50; + unsigned int bNoSky; + unsigned int bDoNotRenderDecorations; + int field_5C; + int field_60; + int outdoor_no_wavy_water; + int outdoor_no_mist; + int building_gamme; + int terrain_gamma; + + unsigned int uMapGridCellX; // moved from 157 struct IndoorCamera::0C + unsigned int uMapGridCellZ; // moved from 157 struct IndoorCamera::10 +}; +#pragma pack(pop) +extern ODMRenderParams *pODMRenderParams; + + + struct Render: public IRender { Render(); @@ -268,4 +444,26 @@ //int windowed_mode_height; }; -unsigned int __fastcall _452442_color_cvt(unsigned __int16 a1, unsigned __int16 a2, int a3, int a4); \ No newline at end of file +unsigned int __fastcall _452442_color_cvt(unsigned __int16 a1, unsigned __int16 a2, int a3, int a4); + +int __fastcall GetActorTintColor(int max_dim, int min_dim, float distance, int a4, struct RenderBillboard *a5); +int __fastcall _43F55F_get_billboard_light_level(struct RenderBillboard *a1, int uBaseLightLevel); +int __fastcall _43F5C8_get_point_light_level_with_respect_to_lights(unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z); +unsigned int __fastcall GetMaxMipLevels(unsigned int uDim); +int _46E44E_collide_against_faces_and_portals(unsigned int b1); // idb +int __fastcall _46E889_collide_against_bmodels(unsigned int ecx0); +int collide_against_floor(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID); // idb +void __fastcall _46ED8A_collide_against_sprite_objects(unsigned int _this); +int _46EF01_collision_chech_player(int a1); // idb +void _46E0B2_collide_against_decorations(); +int _46F04E_collide_against_portals(); +unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID); +void UpdateObjects(); +bool sub_47531C(int a1, int *a2, int pos_x, int pos_y, int pos_z, int dir_x, int dir_y, int dir_z, struct BLVFace *face, int a10); +bool sub_4754BF(int a1, int *a2, int X, int Y, int Z, int dir_x, int dir_y, int dir_z, struct BLVFace *face, int a10, int a11); +int sub_475665(struct BLVFace *face, int a2, __int16 a3); +bool __fastcall sub_4759C9(struct BLVFace *face, int a2, int a3, __int16 a4); +bool __fastcall sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, struct BLVFace *a4); +bool __fastcall sub_475F30(int *a1, struct BLVFace *a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9); + +bool __fastcall IsBModelVisible(unsigned int uModelID, int *unused); diff -r 0f17a30149ec -r 104fdbea0386 SaveLoad.cpp --- a/SaveLoad.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/SaveLoad.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -5,7 +5,7 @@ #define _CRT_SECURE_NO_WARNINGS #include #include -#include "mm7_unsorted_subs.h" + #include "ErrorHandling.h" #include "ZlibWrapper.h" diff -r 0f17a30149ec -r 104fdbea0386 SpriteObject.cpp --- a/SpriteObject.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/SpriteObject.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -21,7 +21,7 @@ #include "Events.h" #include "AudioPlayer.h" #include "Level/Decoration.h" -#include "mm7_unsorted_subs.h" + #include "mm7_data.h" #include "MM7.h" @@ -2020,3 +2020,36 @@ } +//----- (0043A97E) -------------------------------------------------------- +void __fastcall sub_43A97E(unsigned int uLayingItemID, signed int a2) +{ + if (PID_TYPE(a2) == OBJECT_Player) + { + layingitem_vel_50FDFC.x = pSpriteObjects[uLayingItemID].vVelocity.x; + layingitem_vel_50FDFC.y = pSpriteObjects[uLayingItemID].vVelocity.y; + layingitem_vel_50FDFC.z = pSpriteObjects[uLayingItemID].vVelocity.z; + + Vec3_int_::Normalize(&layingitem_vel_50FDFC.x, &layingitem_vel_50FDFC.y, &layingitem_vel_50FDFC.z); + DamagePlayerFromMonster(PID(OBJECT_Item, uLayingItemID), pSpriteObjects[uLayingItemID].field_61, &layingitem_vel_50FDFC, -1); + } + else if (PID_TYPE(a2) == OBJECT_Actor) + { + layingitem_vel_50FDFC.x = pSpriteObjects[uLayingItemID].vVelocity.x; + layingitem_vel_50FDFC.y = pSpriteObjects[uLayingItemID].vVelocity.y; + layingitem_vel_50FDFC.z = pSpriteObjects[uLayingItemID].vVelocity.z; + + Vec3_int_::Normalize(&layingitem_vel_50FDFC.x, &layingitem_vel_50FDFC.y, &layingitem_vel_50FDFC.z); + switch (PID_TYPE(pSpriteObjects[uLayingItemID].spell_caster_pid)) + { + case OBJECT_Actor: + Actor::ActorDamageFromMonster(PID(OBJECT_Item, uLayingItemID), PID_ID(a2), &layingitem_vel_50FDFC, pSpriteObjects[uLayingItemID].field_61); + break; + case OBJECT_Player: + Actor::DamageMonsterFromParty(PID(OBJECT_Item, uLayingItemID), PID_ID(a2), &layingitem_vel_50FDFC); + break; + case OBJECT_Item: + ItemDamageFromActor(PID(OBJECT_Item, uLayingItemID), PID_ID(a2), &layingitem_vel_50FDFC); + break; + } + } +} diff -r 0f17a30149ec -r 104fdbea0386 SpriteObject.h --- a/SpriteObject.h Sun Aug 17 15:13:18 2014 +0100 +++ b/SpriteObject.h Sun Aug 17 17:49:34 2014 +0100 @@ -58,4 +58,5 @@ extern size_t uNumSpriteObjects; extern std::array pSpriteObjects; -bool __fastcall _46BFFA_check_object_intercept(unsigned int uLayingItemID, signed int a2); \ No newline at end of file +bool __fastcall _46BFFA_check_object_intercept(unsigned int uLayingItemID, signed int a2); +void __fastcall sub_43A97E(unsigned int uLayingItemID, signed int a2); // idb diff -r 0f17a30149ec -r 104fdbea0386 TurnEngine.cpp --- a/TurnEngine.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/TurnEngine.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -4,7 +4,7 @@ #define _CRT_SECURE_NO_WARNINGS -#include "mm7_unsorted_subs.h" + #include "MM7.h" #include "mm7_data.h" #include "Actor.h" @@ -21,7 +21,7 @@ #include "TurnEngine.h" -#include "TurnEngine.h" +#include "Game.h" struct stru262_TurnBased *pTurnEngine = new stru262_TurnBased; diff -r 0f17a30149ec -r 104fdbea0386 UI/Books/UIMapBook.cpp --- a/UI/Books/UIMapBook.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/Books/UIMapBook.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -1,7 +1,6 @@ #define _CRT_SECURE_NO_WARNINGS #include "UIMapBook.h" #include "..\..\Events.h" -#include "..\..\mm7_unsorted_subs.h" #include "..\..\MM7.h" #include "..\..\Render.h" #include "..\..\Mouse.h" @@ -20,6 +19,8 @@ // #include "..\..\mm7_data.h" + + std::array<__int16, 6> pTownPortalBook_xs = {{260, 324, 147, 385, 390, 19}}; std::array<__int16, 6> pTownPortalBook_ys = {{206, 84, 182, 239, 17, 283}}; diff -r 0f17a30149ec -r 104fdbea0386 UI/Books/UINotesBooks.cpp --- a/UI/Books/UINotesBooks.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/Books/UINotesBooks.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -1,5 +1,4 @@ #define _CRT_SECURE_NO_WARNINGS -#include "..\..\mm7_unsorted_subs.h" #include "..\..\MM7.h" #include "..\..\Render.h" #include "..\..\Mouse.h" diff -r 0f17a30149ec -r 104fdbea0386 UI/UICharacter.cpp --- a/UI/UICharacter.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/UICharacter.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -5,7 +5,6 @@ #define _CRT_SECURE_NO_WARNINGS #include #include "UICharacter.h" -#include "..\mm7_unsorted_subs.h" #include "..\MM7.h" #include "..\MapInfo.h" #include "..\Game.h" diff -r 0f17a30149ec -r 104fdbea0386 UI/UIGame.h --- a/UI/UIGame.h Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/UIGame.h Sun Aug 17 17:49:34 2014 +0100 @@ -1,3 +1,5 @@ #pragma once void GameUI_WritePointedObjectStatusString(); -void __fastcall GameUI_OnPlayerPortraitLeftClick(unsigned int uPlayerID); // idb \ No newline at end of file +void __fastcall GameUI_OnPlayerPortraitLeftClick(unsigned int uPlayerID); // idb + +__int16 __fastcall sub_441A4E(int a1); diff -r 0f17a30149ec -r 104fdbea0386 UI/UIGuilds.cpp --- a/UI/UIGuilds.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/UIGuilds.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -3,7 +3,6 @@ #include #define _CRT_SECURE_NO_WARNINGS -#include "..\mm7_unsorted_subs.h" #include "..\Items.h" #include "..\GUIWindow.h" #include "..\mm7_data.h" diff -r 0f17a30149ec -r 104fdbea0386 UI/UIHouses.cpp --- a/UI/UIHouses.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/UIHouses.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -7,7 +7,6 @@ #include "UIPartyCreation.h" #include "UIShops.h" #include "..\GUIButton.h" -#include "..\mm7_unsorted_subs.h" #include "..\SaveLoad.h" #include "..\Texture.h" #include "..\mm7_data.h" diff -r 0f17a30149ec -r 104fdbea0386 UI/UIHouses.h --- a/UI/UIHouses.h Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/UIHouses.h Sun Aug 17 17:49:34 2014 +0100 @@ -148,4 +148,6 @@ extern int uHouse_ExitPic; // weak extern int dword_591080; // weak extern BuildingType in_current_building_type; // 00F8B198 -extern HOUSE_DIALOGUE_MENU dialog_menu_id; // 00F8B19C \ No newline at end of file +extern HOUSE_DIALOGUE_MENU dialog_menu_id; // 00F8B19C + +int HouseDialogPressCloseBtn(); diff -r 0f17a30149ec -r 104fdbea0386 UI/UIMainMenu.cpp --- a/UI/UIMainMenu.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/UIMainMenu.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -17,7 +17,6 @@ #include "..\texts.h" #include "..\mm7_data.h" -#include "..\mm7_unsorted_subs.h" #include "..\Game.h" diff -r 0f17a30149ec -r 104fdbea0386 UI/UIPartyCreation.cpp --- a/UI/UIPartyCreation.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/UIPartyCreation.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -4,7 +4,6 @@ #define _CRT_SECURE_NO_WARNINGS #include "UIPartyCreation.h" -#include "..\mm7_unsorted_subs.h" #include "..\Mouse.h" #include "..\Keyboard.h" #include "..\ErrorHandling.h" diff -r 0f17a30149ec -r 104fdbea0386 UI/UIPopup.cpp --- a/UI/UIPopup.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/UIPopup.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -7,7 +7,6 @@ #include "Books\UIMapBook.h" #include "UIShops.h" #include "..\MM7.h" -#include "..\mm7_unsorted_subs.h" #include "..\Mouse.h" diff -r 0f17a30149ec -r 104fdbea0386 UI/UIRest.cpp --- a/UI/UIRest.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/UIRest.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -3,7 +3,6 @@ #include #define _CRT_SECURE_NO_WARNINGS -#include "..\mm7_unsorted_subs.h" #include "..\GUIWindow.h" #include "..\GUIFont.h" #include "..\Party.h" diff -r 0f17a30149ec -r 104fdbea0386 UI/UISaveLoad.cpp --- a/UI/UISaveLoad.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/UISaveLoad.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -19,7 +19,6 @@ #include "..\texts.h" #include "..\mm7_data.h" -#include "..\mm7_unsorted_subs.h" #include "..\Game.h" diff -r 0f17a30149ec -r 104fdbea0386 UI/UIShops.cpp --- a/UI/UIShops.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/UIShops.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -4,7 +4,6 @@ #define _CRT_SECURE_NO_WARNINGS #include "UIShops.h" -#include "..\mm7_unsorted_subs.h" #include "..\Items.h" #include "..\GUIWindow.h" #include "..\mm7_data.h" diff -r 0f17a30149ec -r 104fdbea0386 UI/UITransition.cpp --- a/UI/UITransition.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/UITransition.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -6,7 +6,6 @@ #include #include "..\ErrorHandling.h" -#include "..\mm7_unsorted_subs.h" #include "..\mm7_data.h" #include "..\MediaPlayer.h" #include "..\MapInfo.h" diff -r 0f17a30149ec -r 104fdbea0386 UI/UiGame.cpp --- a/UI/UiGame.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/UI/UiGame.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -4,7 +4,6 @@ #define _CRT_SECURE_NO_WARNINGS #include "..\Events.h" -#include "..\mm7_unsorted_subs.h" #include "..\Texture.h" #include "..\MM7.h" #include "..\ErrorHandling.h" @@ -40,6 +39,10 @@ #include "..\Chest.h" #include "UIGame.h" +#include "..\Overlays.h" + +#include "..\Sprites.h" +#include "..\PaletteManager.h" int uTextureID_GameUI_CharSelectionFrame; // 50C98C @@ -2164,3 +2167,96 @@ } Error("Invalid condition (%u)", uConditionIdx); } + +//----- (00495430) -------------------------------------------------------- +const char * GetReputationString(signed int a1) +{ + if (a1 >= 25) + return pGlobalTXT_LocalizationStrings[379]; // Hated + else if (a1 >= 6) + return pGlobalTXT_LocalizationStrings[392]; // Unfriendly + else if (a1 >= -5) + return pGlobalTXT_LocalizationStrings[399]; // Neutral; + else if (a1 >= -24) + return pGlobalTXT_LocalizationStrings[402]; // Friendly + else + return pGlobalTXT_LocalizationStrings[434]; // Respected; +} + +//----- (00441A4E) -------------------------------------------------------- +__int16 __fastcall sub_441A4E(int a1)//for blessing +{ + __int16 result; // ax@1 + int v2; // ebx@1 + // char *v3; // esi@1 + // int v4; // edi@4 + bool v5; // ecx@4 + SpriteFrame *pFrame; // eax@6 + //SpriteFrame *v7; // edi@6 + int v8; // eax@6 + // unsigned __int16 v9; // ax@6 + RenderBillboardTransform_local0 v10; // [sp+Ch] [bp-5Ch]@1 + int v11; // [sp+5Ch] [bp-Ch]@6 + int v12; // [sp+60h] [bp-8h]@1 + //int v13; // [sp+64h] [bp-4h]@6 + + v10.sParentBillboardID = -1; + v10.pTarget = pRenderer->pTargetSurface; + v10.pTargetZ = pRenderer->pActiveZBuffer; + v10.uTargetPitch = pRenderer->GetRenderWidth(); + result = 0; + v2 = a1; + v10.uViewportX = 0; + v10.uViewportY = 0; + v10.uViewportZ = window->GetWidth() - 1; + v10.uViewportW = window->GetHeight() - 1; + v12 = 0; + //v3 = (char *)&pOtherOverlayList->pOverlays[0].field_C; + //do + for (uint i = 0; i < 50; ++i) + { + if (pOtherOverlayList->pOverlays[i].field_6 > 0) + { + result = pOtherOverlayList->pOverlays[i].field_0; + if (pOtherOverlayList->pOverlays[i].field_0 >= 300) + { + //v4 = result; + v5 = pOtherOverlayList->pOverlays[i].field_0 == v2 + 320 + || pOtherOverlayList->pOverlays[i].field_0 == v2 + 330 + || pOtherOverlayList->pOverlays[i].field_0 == v2 + 340 + || pOtherOverlayList->pOverlays[i].field_0 == v2 + 350; + pOtherOverlayList->pOverlays[i].field_0 = v2 + 310; + if (pOtherOverlayList->pOverlays[i].field_0 == v2 + 310 || v5) + { + if (!pOtherOverlayList->pOverlays[i].field_0) + { + pFrame = pSpriteFrameTable->GetFrame(pOverlayList->pOverlays[pOtherOverlayList->pOverlays[i].field_2].uSpriteFramesetID, + pOtherOverlayList->pOverlays[i].field_4); + //v7 = v6; + v11 = pOtherOverlayList->pOverlays[i].field_E; + //v13 = pFrame->scale; + //v13 = fixpoint_mul(v11, pFrame->scale); + v10.uScreenSpaceX = pOtherOverlayList->pOverlays[i].field_8; + v10.uScreenSpaceY = pOtherOverlayList->pOverlays[i].field_A; + v10._screenspace_x_scaler_packedfloat = fixpoint_mul(v11, pFrame->scale); + v10._screenspace_y_scaler_packedfloat = fixpoint_mul(v11, pFrame->scale); + v10.pPalette = PaletteManager::Get_Dark_or_Red_LUT(pFrame->uPaletteIndex, 0, 1); + v8 = pOtherOverlayList->pOverlays[i].field_2; + v10.sZValue = 0; + v10.uFlags = 0; + //v9 = pOverlayList->pOverlays[v8].uOverlayType; + if (!pOverlayList->pOverlays[v8].uOverlayType || pOverlayList->pOverlays[v8].uOverlayType == 2) + v10.uScreenSpaceY += pSprites_LOD->pSpriteHeaders[pFrame->pHwSpriteIDs[0]].uHeight / 2; + result = pSprites_LOD->pSpriteHeaders[pFrame->pHwSpriteIDs[0]]._4AD2D1(&v10, 0); + ++v12; + if (v12 == 5) + break; + } + } + } + } + //v3 += 20; + } + //while ( (signed int)v3 < (signed int)&pOverlayList->pOverlays ); + return result; +} diff -r 0f17a30149ec -r 104fdbea0386 VectorTypes.cpp --- a/VectorTypes.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/VectorTypes.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -66,3 +66,11 @@ } template Vec3; + +//----- (004369DB) -------------------------------------------------------- +void Vec3_float_::Normalize() +{ + this->x = (1.0 / sqrt(this->x * this->x + this->y * this->y + this->z * this->z)) * this->x; + this->y = (1.0 / sqrt(this->x * this->x + this->y * this->y + this->z * this->z)) * this->y; + this->z = (1.0 / sqrt(this->x * this->x + this->y * this->y + this->z * this->z)) * this->z; +} \ No newline at end of file diff -r 0f17a30149ec -r 104fdbea0386 Viewport.cpp --- a/Viewport.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Viewport.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -5,7 +5,7 @@ #define _CRT_SECURE_NO_WARNINGS #include "Viewport.h" -#include "mm7_unsorted_subs.h" + #include "Party.h" #include "Indoor.h" #include "OurMath.h" diff -r 0f17a30149ec -r 104fdbea0386 Vis.cpp --- a/Vis.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/Vis.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -16,7 +16,7 @@ #include "ErrorHandling.h" #include "mm7_data.h" -#include "mm7_unsorted_subs.h" + #include "MM7.h" #include "Level/Decoration.h" diff -r 0f17a30149ec -r 104fdbea0386 _deleted.cpp --- a/_deleted.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/_deleted.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -2,6 +2,14 @@ /* +void reset_some_strus_flt_2Cs(); +double get_shading_dist_mist(); +void CreateAsyncMouse(); +void CreateAsyncKeyboard(); +double GetFogDensityByTime(struct OutdoorLocation *_this); +//void ShowMM7IntroVideo_and_LoadingScreen(); + + // 128 #pragma pack(push, 1) struct stru11 diff -r 0f17a30149ec -r 104fdbea0386 mm7_3.cpp --- a/mm7_3.cpp Sun Aug 17 15:13:18 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3825 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "ErrorHandling.h" -#include "Weather.h" -#include "Sprites.h" -#include "stru6.h" -#include "MapInfo.h" -#include "Game.h" -#include "GUIWindow.h" -#include "GUIFont.h" -#include "GUIProgressBar.h" -#include "Party.h" -#include "AudioPlayer.h" -#include "Outdoor.h" -#include "Overlays.h" -#include "LOD.h" -#include "Log.h" -#include "Actor.h" -#include "Events.h" -#include "Viewport.h" -#include "OurMath.h" -#include "SpriteObject.h" -#include "ObjectList.h" -#include "PaletteManager.h" -#include "DecorationList.h" -#include "Timer.h" -#include "TurnEngine.h" -#include "Events2D.h" -#include "MapsLongTimer.h" -#include "stru298.h" -#include "texts.h" -#include "Level/Decoration.h" -#include "mm7_unsorted_subs.h" -#include "mm7_data.h" -#include "SaveLoad.h" - -#include "MM7.h" - - -//----- (0044100D) -------------------------------------------------------- -bool _44100D_should_alter_right_panel() -{ - return pCurrentScreen == SCREEN_NPC_DIALOGUE || pCurrentScreen == SCREEN_CHARACTERS || - pCurrentScreen == SCREEN_HOUSE || pCurrentScreen == SCREEN_E || - pCurrentScreen == SCREEN_CHANGE_LOCATION || pCurrentScreen == SCREEN_INPUT_BLV || pCurrentScreen == SCREEN_CASTING; -} - - -//----- (0046E44E) -------------------------------------------------------- -int _46E44E_collide_against_faces_and_portals(unsigned int b1) -{ - BLVSector *pSector; // edi@1 - signed int v2; // ebx@1 - BLVFace *pFace; // esi@2 - __int16 pNextSector; // si@10 - int pArrayNum; // ecx@12 - unsigned __int8 v6; // sf@12 - unsigned __int8 v7; // of@12 - int result; // eax@14 - //int v10; // ecx@15 - int pFloor; // eax@16 - int v15; // eax@24 - int v16; // edx@25 - int v17; // eax@29 - unsigned int v18; // eax@33 - int v21; // eax@35 - int v22; // ecx@36 - int v23; // eax@40 - unsigned int v24; // eax@44 - int a3; // [sp+10h] [bp-48h]@28 - int v26; // [sp+14h] [bp-44h]@15 - int i; // [sp+18h] [bp-40h]@1 - int a10; // [sp+1Ch] [bp-3Ch]@1 - int v29; // [sp+20h] [bp-38h]@14 - int v32; // [sp+2Ch] [bp-2Ch]@15 - int pSectorsArray[10]; // [sp+30h] [bp-28h]@1 - - pSector = &pIndoor->pSectors[stru_721530.uSectorID]; - i = 1; - a10 = b1; - pSectorsArray[0] = stru_721530.uSectorID; - for ( v2 = 0; v2 < pSector->uNumPortals; ++v2 ) - { - pFace = &pIndoor->pFaces[pSector->pPortals[v2]]; - if ( stru_721530.sMaxX <= pFace->pBounding.x2 && stru_721530.sMinX >= pFace->pBounding.x1 - && stru_721530.sMaxY <= pFace->pBounding.y2 && stru_721530.sMinY >= pFace->pBounding.y1 - && stru_721530.sMaxZ <= pFace->pBounding.z2 && stru_721530.sMinZ >= pFace->pBounding.z1 - && abs((pFace->pFacePlane_old.dist - + stru_721530.normal.x * pFace->pFacePlane_old.vNormal.x - + stru_721530.normal.y * pFace->pFacePlane_old.vNormal.y - + stru_721530.normal.z * pFace->pFacePlane_old.vNormal.z) >> 16) <= stru_721530.field_6C + 16 ) - { - pNextSector = pFace->uSectorID == stru_721530.uSectorID ? pFace->uBackSectorID : pFace->uSectorID;//FrontSectorID - pArrayNum = i++; - v7 = i < 10; - v6 = i - 10 < 0; - pSectorsArray[pArrayNum] = pNextSector; - if ( !(v6 ^ v7) ) - break; - } - } - result = 0; - for ( v29 = 0; v29 < i; v29++ ) - { - pSector = &pIndoor->pSectors[pSectorsArray[v29]]; - v32 = pSector->uNumFloors + pSector->uNumWalls + pSector->uNumCeilings; - for ( v26 = 0; v26 < v32; v26++ ) - { - pFloor = pSector->pFloors[v26]; - pFace = &pIndoor->pFaces[pSector->pFloors[v26]]; - if ( !pFace->Portal() - && stru_721530.sMaxX <= pFace->pBounding.x2 && stru_721530.sMinX >= pFace->pBounding.x1 - && stru_721530.sMaxY <= pFace->pBounding.y2 && stru_721530.sMinY >= pFace->pBounding.y1 - && stru_721530.sMaxZ <= pFace->pBounding.z2 && stru_721530.sMinZ >= pFace->pBounding.z1 - && pFloor != stru_721530.field_84 ) - { - v15 = ( pFace->pFacePlane_old.dist + stru_721530.normal.x * pFace->pFacePlane_old.vNormal.x - + stru_721530.normal.y * pFace->pFacePlane_old.vNormal.y - + stru_721530.normal.z * pFace->pFacePlane_old.vNormal.z ) >> 16; - if ( v15 > 0 ) - { - v16 = ( pFace->pFacePlane_old.dist + stru_721530.normal2.x * pFace->pFacePlane_old.vNormal.x - + stru_721530.normal2.y * pFace->pFacePlane_old.vNormal.y - + stru_721530.normal2.z * pFace->pFacePlane_old.vNormal.z ) >> 16; - if ( v15 <= stru_721530.prolly_normal_d || v16 <= stru_721530.prolly_normal_d ) - { - if ( v16 <= v15 ) - { - a3 = stru_721530.field_6C; - if ( sub_47531C(stru_721530.prolly_normal_d, &a3, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, - stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, pFace, a10) ) - { - v17 = a3; - } - else - { - a3 = stru_721530.field_6C + stru_721530.prolly_normal_d; - if ( !sub_475D85(&stru_721530.normal, &stru_721530.direction, &a3, pFace) ) - goto LABEL_34; - v17 = a3 - stru_721530.prolly_normal_d; - a3 -= stru_721530.prolly_normal_d; - } - if ( v17 < stru_721530.field_7C ) - { - stru_721530.field_7C = v17; - v18 = 8 * pSector->pFloors[v26]; - LOBYTE(v18) = v18 | 6; - stru_721530.uFaceID = v18; - } - } - } - } -LABEL_34: - if ( !(stru_721530.field_0 & 1) - || (v21 = ( pFace->pFacePlane_old.dist + stru_721530.position.x * pFace->pFacePlane_old.vNormal.x - + stru_721530.position.y * pFace->pFacePlane_old.vNormal.y - + stru_721530.position.z * pFace->pFacePlane_old.vNormal.z) >> 16, v21 <= 0) - || (v22 = ( pFace->pFacePlane_old.dist + stru_721530.field_4C * pFace->pFacePlane_old.vNormal.x - + stru_721530.field_50 * pFace->pFacePlane_old.vNormal.y - + stru_721530.field_54 * pFace->pFacePlane_old.vNormal.z) >> 16, v21 > stru_721530.prolly_normal_d) - && v22 > stru_721530.prolly_normal_d || v22 > v21 ) - continue; - a3 = stru_721530.field_6C; - if ( sub_47531C(stru_721530.field_8_radius, &a3, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, - stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, pFace, a10) ) - { - v23 = a3; - goto LABEL_43; - } - a3 = stru_721530.field_6C + stru_721530.field_8_radius; - if ( sub_475D85(&stru_721530.position, &stru_721530.direction, &a3, pFace) ) - { - v23 = a3 - stru_721530.prolly_normal_d; - a3 -= stru_721530.prolly_normal_d; -LABEL_43: - if ( v23 < stru_721530.field_7C ) - { - stru_721530.field_7C = v23; - v24 = 8 * pSector->pFloors[v26]; - LOBYTE(v24) = v24 | 6; - stru_721530.uFaceID = v24; - } - } - } - } - result = v29 + 1; - } - return result; -} -// 46E44E: using guessed type int var_28[10]; - -//----- (0046E889) -------------------------------------------------------- -int __fastcall _46E889_collide_against_bmodels(unsigned int ecx0) -{ - int result; // eax@1 - //int v3; // ebx@9 - int v8; // eax@19 - int v9; // ecx@20 - int v10; // eax@24 - unsigned int v14; // eax@28 - int v15; // eax@30 - int v16; // ecx@31 - unsigned int v17; // eax@36 - int v21; // eax@42 - unsigned int v22; // eax@43 - //int a11; // [sp+70h] [bp-18h]@1 - //int a10; // [sp+80h] [bp-8h]@1 - int a2; // [sp+84h] [bp-4h]@23 - - //a11 = ecx0; - - BLVFace face; // [sp+Ch] [bp-7Ch]@1 - - result = 0; - for ( uint i = 0; i < (signed int)pOutdoor->uNumBModels; ++i ) - { - if ( stru_721530.sMaxX <= pOutdoor->pBModels[i].sMaxX && stru_721530.sMinX >= pOutdoor->pBModels[i].sMinX - && stru_721530.sMaxY <= pOutdoor->pBModels[i].sMaxY && stru_721530.sMinY >= pOutdoor->pBModels[i].sMinY - && stru_721530.sMaxZ <= pOutdoor->pBModels[i].sMaxZ && stru_721530.sMinZ >= pOutdoor->pBModels[i].sMinZ ) - { - for ( uint j = 0; j < pOutdoor->pBModels[i].uNumFaces; ++j ) - { - if ( stru_721530.sMaxX <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x2 && stru_721530.sMinX >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x1 - && stru_721530.sMaxY <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y2 && stru_721530.sMinY >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y1 - && stru_721530.sMaxZ <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z2 && stru_721530.sMinZ >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z1 ) - { - face.pFacePlane_old.vNormal.x = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.x; - face.pFacePlane_old.vNormal.y = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.y; - face.pFacePlane_old.vNormal.z = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.z; - - face.pFacePlane_old.dist = pOutdoor->pBModels[i].pFaces[j].pFacePlane.dist; //incorrect - - face.uAttributes = pOutdoor->pBModels[i].pFaces[j].uAttributes; - - face.pBounding.x1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x1; - face.pBounding.y1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y1; - face.pBounding.z1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z1; - - face.pBounding.x2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x2; - face.pBounding.y2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y2; - face.pBounding.z2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z2; - - face.zCalc1 = pOutdoor->pBModels[i].pFaces[j].zCalc1; - face.zCalc2 = pOutdoor->pBModels[i].pFaces[j].zCalc2; - face.zCalc3 = pOutdoor->pBModels[i].pFaces[j].zCalc3; - - face.pXInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements; - face.pYInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pYInterceptDisplacements; - face.pZInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pZInterceptDisplacements; - - face.uPolygonType = (PolygonType)pOutdoor->pBModels[i].pFaces[j].uPolygonType; - - face.uNumVertices = pOutdoor->pBModels[i].pFaces[j].uNumVertices; - - face.uBitmapID = pOutdoor->pBModels[i].pFaces[j].uTextureID; - - face.pVertexIDs = pOutdoor->pBModels[i].pFaces[j].pVertexIDs; - - if ( !face.Ethereal() && !face.Portal() ) - { - v8 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.normal.x - + face.pFacePlane_old.vNormal.y * stru_721530.normal.y - + face.pFacePlane_old.vNormal.z * stru_721530.normal.z ) >> 16; - if ( v8 > 0 ) - { - v9 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.normal2.x - + face.pFacePlane_old.vNormal.y * stru_721530.normal2.y - + face.pFacePlane_old.vNormal.z * stru_721530.normal2.z) >> 16; - if ( v8 <= stru_721530.prolly_normal_d || v9 <= stru_721530.prolly_normal_d ) - { - if ( v9 <= v8 ) - { - a2 = stru_721530.field_6C; - if ( sub_4754BF(stru_721530.prolly_normal_d, &a2, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, - stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, &face, i, ecx0) ) - { - v10 = a2; - } - else - { - a2 = stru_721530.prolly_normal_d + stru_721530.field_6C; - if ( !sub_475F30( &a2, &face, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, - stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, i) ) - goto LABEL_29; - v10 = a2 - stru_721530.prolly_normal_d; - a2 -= stru_721530.prolly_normal_d; - } - if ( v10 < stru_721530.field_7C ) - { - stru_721530.field_7C = v10; - v14 = 8 * (j | (i << 6)); - LOBYTE(v14) = v14 | 6; - stru_721530.uFaceID = v14; - } - } - } - } -LABEL_29: - if ( stru_721530.field_0 & 1 ) - { - v15 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.position.x - + face.pFacePlane_old.vNormal.y * stru_721530.position.y - + face.pFacePlane_old.vNormal.z * stru_721530.position.z) >> 16; - if ( v15 > 0 ) - { - v16 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.field_4C - + face.pFacePlane_old.vNormal.y * stru_721530.field_50 - + face.pFacePlane_old.vNormal.z * stru_721530.field_54) >> 16; - if ( v15 <= stru_721530.prolly_normal_d || v16 <= stru_721530.prolly_normal_d ) - { - if ( v16 <= v15 ) - { - a2 = stru_721530.field_6C; - if ( sub_4754BF(stru_721530.field_8_radius, &a2, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, - stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, &face, i, ecx0) ) - { - if ( a2 < stru_721530.field_7C ) - { - stru_721530.field_7C = a2; - v17 = 8 * (j | (i << 6)); - LOBYTE(v17) = v17 | 6; - stru_721530.uFaceID = v17; - } - } - else - { - a2 = stru_721530.field_6C + stru_721530.field_8_radius; - if ( sub_475F30(&a2, &face, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, - stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, i) ) - { - v21 = a2 - stru_721530.prolly_normal_d; - a2 -= stru_721530.prolly_normal_d; - if ( a2 < stru_721530.field_7C ) - { - stru_721530.field_7C = v21; - v22 = 8 * (j | (i << 6)); - LOBYTE(v22) = v22 | 6; - stru_721530.uFaceID = v22; - } - } - } - } - } - } - } - } - } - } - } - result = i; - } - return result; -} - -//----- (0046ED1B) -------------------------------------------------------- -int collide_against_floor(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID) -{ - uint uFaceID = -1; - int floor_level = BLV_GetFloorLevel(x, y, z, *pSectorID, &uFaceID); - - if (floor_level != -30000 && floor_level <= z + 50) - { - *pFaceID = uFaceID; - return floor_level; - } - - uint uSectorID = pIndoor->GetSector(x, y, z); - *pSectorID = uSectorID; - - floor_level = BLV_GetFloorLevel(x, y, z, uSectorID, &uFaceID); - if (uSectorID && floor_level != -30000) - *pFaceID = uFaceID; - else return -30000; - return floor_level; -} - -//----- (0046ED8A) -------------------------------------------------------- -void __fastcall _46ED8A_collide_against_sprite_objects(unsigned int _this) -{ - ObjectDesc *object; // edx@4 - int v10; // ecx@12 - int v11; // esi@13 - - for ( uint i = 0; i < uNumSpriteObjects; ++i ) - { - if ( pSpriteObjects[i].uObjectDescID ) - { - object = &pObjectList->pObjects[pSpriteObjects[i].uObjectDescID]; - if ( !(object->uFlags & OBJECT_DESC_NO_COLLISION) ) - { - if ( stru_721530.sMaxX <= pSpriteObjects[i].vPosition.x + object->uRadius && stru_721530.sMinX >= pSpriteObjects[i].vPosition.x - object->uRadius - && stru_721530.sMaxY <= pSpriteObjects[i].vPosition.y + object->uRadius && stru_721530.sMinY >= pSpriteObjects[i].vPosition.y - object->uRadius - && stru_721530.sMaxZ <= pSpriteObjects[i].vPosition.z + object->uHeight && stru_721530.sMinZ >= pSpriteObjects[i].vPosition.z ) - { - if ( abs(((pSpriteObjects[i].vPosition.x - stru_721530.normal.x) * stru_721530.direction.y - - (pSpriteObjects[i].vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16) - <= object->uHeight + stru_721530.prolly_normal_d ) - { - v10 = ((pSpriteObjects[i].vPosition.x - stru_721530.normal.x) * stru_721530.direction.x - + (pSpriteObjects[i].vPosition.y - stru_721530.normal.y) * stru_721530.direction.y) >> 16; - if ( v10 > 0 ) - { - v11 = stru_721530.normal.z + ((unsigned __int64)(stru_721530.direction.z * (signed __int64)v10) >> 16); - if ( v11 >= pSpriteObjects[i].vPosition.z - stru_721530.prolly_normal_d ) - { - if ( v11 <= object->uHeight + stru_721530.prolly_normal_d + pSpriteObjects[i].vPosition.z ) - { - if ( v10 < stru_721530.field_7C ) - sub_46DEF2(_this, i); - } - } - } - } - } - } - } - } -} - -//----- (0046EF01) -------------------------------------------------------- -int _46EF01_collision_chech_player(int a1) -{ - int result; // eax@1 - int v3; // ebx@7 - int v4; // esi@7 - int v5; // edi@8 - int v6; // ecx@9 - int v7; // edi@12 - int v10; // [sp+14h] [bp-8h]@7 - int v11; // [sp+18h] [bp-4h]@7 - - result = pParty->vPosition.x; - //v9 = pParty->uPartyHeight; - if ( stru_721530.sMaxX <= pParty->vPosition.x + (2 * pParty->field_14_radius) && stru_721530.sMinX >= pParty->vPosition.x - (2 * pParty->field_14_radius) - && stru_721530.sMaxY <= pParty->vPosition.y + (2 * pParty->field_14_radius) && stru_721530.sMinY >= pParty->vPosition.y - (2 * pParty->field_14_radius) - && stru_721530.sMaxZ <= pParty->vPosition.z + pParty->uPartyHeight && stru_721530.sMinZ >= pParty->vPosition.z ) - { - v3 = stru_721530.prolly_normal_d + (2 * pParty->field_14_radius); - v11 = pParty->vPosition.x - stru_721530.normal.x; - v4 = ((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y - - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16; - v10 = pParty->vPosition.y - stru_721530.normal.y; - result = abs(((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y - - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16); - if ( result <= stru_721530.prolly_normal_d + (2 * pParty->field_14_radius) ) - { - result = v10 * stru_721530.direction.y; - v5 = (v10 * stru_721530.direction.y + v11 * stru_721530.direction.x) >> 16; - if ( v5 > 0 ) - { - v6 = fixpoint_mul(stru_721530.direction.z, v5) + stru_721530.normal.z; - result = pParty->vPosition.z; - if ( v6 >= pParty->vPosition.z ) - { - result = pParty->uPartyHeight + pParty->vPosition.z; - if ( v6 <= (signed int)(pParty->uPartyHeight + pParty->vPosition.z) || a1 ) - { - result = integer_sqrt(v3 * v3 - v4 * v4); - v7 = v5 - integer_sqrt(v3 * v3 - v4 * v4); - if ( v7 < 0 ) - v7 = 0; - if ( v7 < stru_721530.field_7C ) - { - stru_721530.field_7C = v7; - stru_721530.uFaceID = 4; - } - } - } - } - } - } - return result; -} - -//----- (0046F04E) -------------------------------------------------------- -int _46F04E_collide_against_portals() -{ - unsigned int v1; // eax@1 - BLVFace *face; // eax@3 - int v4; // ecx@9 - int v5; // edx@9 - signed int result; // eax@21 - unsigned int v10; // [sp+8h] [bp-Ch]@1 - int a3; // [sp+Ch] [bp-8h]@13 - int v12; // [sp+10h] [bp-4h]@15 - - v1 = 0xFFFFFFu; - v10 = 0xFFFFFFu; - for ( uint i = 0; i < pIndoor->pSectors[stru_721530.uSectorID].uNumPortals; ++i ) - { - if ( pIndoor->pSectors[stru_721530.uSectorID].pPortals[i] != stru_721530.field_80 ) - { - face = &pIndoor->pFaces[pIndoor->pSectors[stru_721530.uSectorID].pPortals[i]]; - if ( stru_721530.sMaxX <= face->pBounding.x2 && stru_721530.sMinX >= face->pBounding.x1 - && stru_721530.sMaxY <= face->pBounding.y2 && stru_721530.sMinY >= face->pBounding.y1 - && stru_721530.sMaxZ <= face->pBounding.z2 && stru_721530.sMinZ >= face->pBounding.z1 ) - { - v4 = (stru_721530.normal.x * face->pFacePlane_old.vNormal.x + face->pFacePlane_old.dist - + stru_721530.normal.y * face->pFacePlane_old.vNormal.y - + stru_721530.normal.z * face->pFacePlane_old.vNormal.z) >> 16; - v5 = (stru_721530.normal2.z * face->pFacePlane_old.vNormal.z + face->pFacePlane_old.dist - + stru_721530.normal2.x * face->pFacePlane_old.vNormal.x - + stru_721530.normal2.y * face->pFacePlane_old.vNormal.y) >> 16; - if ( (v4 < stru_721530.prolly_normal_d || v5 < stru_721530.prolly_normal_d) - && (v4 > -stru_721530.prolly_normal_d || v5 > -stru_721530.prolly_normal_d) - && (a3 = stru_721530.field_6C, sub_475D85(&stru_721530.normal, &stru_721530.direction, &a3, face)) - && a3 < (signed int)v10 ) - { - v10 = a3; - v12 = pIndoor->pSectors[stru_721530.uSectorID].pPortals[i]; - } - } - } - } - v1 = v10; - if ( stru_721530.field_7C >= (signed int)v1 && (signed int)v1 <= stru_721530.field_6C ) - { - stru_721530.field_80 = v12; - if ( pIndoor->pFaces[v12].uSectorID == stru_721530.uSectorID ) - stru_721530.uSectorID = pIndoor->pFaces[v12].uBackSectorID; - else - stru_721530.uSectorID = pIndoor->pFaces[v12].uSectorID; - stru_721530.field_7C = 268435455; - result = 0; - } - else - result = 1; - return result; -} - -//----- (0047050A) -------------------------------------------------------- -int stru141_actor_collision_object::_47050A(int dt) -{ - int v7; // eax@1 - signed int result; // eax@4 - int v17; // eax@5 - int v18; // eax@7 - int v21; // eax@9 - int v22; // eax@11 - - int speed = 1 | integer_sqrt(this->velocity.z * this->velocity.z + this->velocity.y * this->velocity.y + this->velocity.x * this->velocity.x); - - this->direction.x = 65536 / speed * this->velocity.x; - this->direction.y = 65536 / speed * this->velocity.y; - this->direction.z = 65536 / speed * this->velocity.z; - - this->speed = speed; - this->inv_speed = 65536 / speed; - - if (dt) - v7 = dt; - else - v7 = pEventTimer->dt_in_some_format; - - //v8 = fixpoint_mul(v7, speed) - this->field_70; // speed * dt - something - this->field_6C = fixpoint_mul(v7, speed) - this->field_70; - if ( this->field_6C > 0 ) - { - //v10 = fixpoint_mul(v8, this->direction.x) + this->normal.x; - this->field_4C = fixpoint_mul(this->field_6C, this->direction.x) + this->normal.x; - this->normal2.x = fixpoint_mul(this->field_6C, this->direction.x) + this->normal.x; - //v11 = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y; - this->field_50 = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y; - this->normal2.y = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y; - this->normal2.z = fixpoint_mul(this->field_6C, this->direction.z) + this->normal.z; - //v12 = this->position.z; - //v13 = this->normal.x; - //v14 = this->normal2.x; - //v15 = this->prolly_normal_d; - //v16 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z); - //v28 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z); - this->field_54 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z); - v17 = this->normal.x; - if ( v17 >= this->normal2.x ) - v17 = this->normal2.x; - this->sMaxX = v17 - this->prolly_normal_d; - v18 = this->prolly_normal_d + this->normal.x; - if ( this->normal.x <= this->normal2.x ) - v18 = this->prolly_normal_d + this->normal2.x; - //v19 = this->normal.y; - //v20 = this->normal2.y; - this->sMinX = v18; - v21 = this->normal.y; - if ( v21 >= this->normal2.y ) - v21 = this->normal2.y; - this->sMaxY = v21 - this->prolly_normal_d; - v22 = this->prolly_normal_d + this->normal.y; - if ( this->normal.y <= this->normal2.y ) - v22 = this->normal2.y + this->prolly_normal_d; - //v23 = this->normal2.z; - this->sMinY = v22; - //v24 = this->normal.z; - if ( this->normal.z >= this->normal2.z ) - this->sMaxZ = this->normal2.z - this->prolly_normal_d; - else - this->sMaxZ = this->normal.z - this->prolly_normal_d; - //this->sMaxZ = v25; - //v26 = this->field_8_radius; - if ( this->position.z <= this->position.z + fixpoint_mul(this->field_6C, this->direction.z) ) - this->sMinZ = (this->position.z + fixpoint_mul(this->field_6C, this->direction.z)) + this->field_8_radius; - else - this->sMinZ = this->position.z + this->field_8_radius; - this->uFaceID = 0; - this->field_80 = -1; - this->field_88 = -1; - //this->sMinZ = v27; - this->field_7C = 0xFFFFFFu; - result = 0; - } - else - result = 1; - return result; -} - -//----- (004706C6) -------------------------------------------------------- -void UpdateActors_ODM() -{ - int v3; // ebx@6 - int v5; // eax@10 - //int v6; // ecx@10 - signed int v8; // ebx@17 -// unsigned __int8 v10; // sf@17 -// unsigned __int16 v11; // ax@21 - __int16 v20; // ax@42 - int v25; // eax@45 - signed int v26; // ecx@50 - int v28; // eax@54 - signed int v29; // ebx@57 - signed int v30; // eax@57 - int v31; // edi@57 - signed int i; // ebx@57 - unsigned int v33; // ecx@58 - int v35; // edi@64 - int v36; // eax@64 - unsigned int v39; // edi@71 - ODMFace *face; // edi@75 - int v46; // ecx@82 - signed int v47; // ebx@85 - int v48; // edi@85 -// int v55; // eax@107 -// unsigned int v56; // edi@107 -// int v57; // ST10_4@107 - unsigned int v58; // edi@107 - unsigned int v59; // ebx@107 -// signed int v60; // eax@107 - int v61; // eax@124 - Vec3_int_ v62; // [sp+Ch] [bp-44h]@42 - int v63; // [sp+18h] [bp-38h]@64 - int v64; // [sp+1Ch] [bp-34h]@64 - bool v67; // [sp+28h] [bp-28h]@10 - unsigned int v69; // [sp+30h] [bp-20h]@6 - unsigned int v70; // [sp+34h] [bp-1Ch]@10 - int v71; // [sp+38h] [bp-18h]@62 - int uIsAboveFloor; // [sp+3Ch] [bp-14h]@10 - int v72b; - int uIsFlying; // [sp+44h] [bp-Ch]@8 - unsigned int v75; // [sp+48h] [bp-8h]@1 - int uIsOnWater; // [sp+4Ch] [bp-4h]@10 - - for (v75 = 0; v75 < uNumActors; ++v75) - { - if ( pActors[v75].uAIState == Removed - || pActors[v75].uAIState == Disabled - || pActors[v75].uAIState == Summoned - || !pActors[v75].uMovementSpeed ) - continue; - v3 = 0; - v69 = 0; - if ( MonsterStats::BelongsToSupertype(pActors[v75].pMonsterInfo.uID, MONSTER_SUPERTYPE_WATER_ELEMENTAL) ) - v3 = 1; - pActors[v75].uSectorID = 0; - uIsFlying = pActors[v75].pMonsterInfo.uFlying; - if ( !pActors[v75].CanAct() ) - uIsFlying = 0; - v70 = IsTerrainSlopeTooHigh(pActors[v75].vPosition.x, pActors[v75].vPosition.y); - v5 = ODM_GetFloorLevel(pActors[v75].vPosition.x, pActors[v75].vPosition.y, pActors[v75].vPosition.z, - pActors[v75].uActorHeight, &uIsOnWater, (int *)&v69, v3); - //v6 = pActors[v75].vPosition.z; - uIsAboveFloor = 0; - v67 = v69 == 0; - if ( pActors[v75].vPosition.z > v5 + 1 ) - uIsAboveFloor = 1; - if ( pActors[v75].uAIState == Dead && uIsOnWater && !uIsAboveFloor ) - { - pActors[v75].uAIState = Removed; - continue; - } - if ( pActors[v75].uCurrentActionAnimation == ANIM_Walking ) - { - v8 = pActors[v75].uMovementSpeed; - if ( (signed __int64)pActors[v75].pActorBuffs[ACTOR_BUFF_SLOWED].uExpireTime > 0 ) - v8 = (signed __int64)((double)v8 * 0.5); - if ( pActors[v75].uAIState == Fleeing || pActors[v75].uAIState == Pursuing ) - v8 *= 2; - if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_WAIT ) - v8 *= flt_6BE3AC_debug_recmod1_x_1_6; - if ( v8 > 1000 ) - v8 = 1000; - - pActors[v75].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(pActors[v75].uYawAngle), v8); - pActors[v75].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(pActors[v75].uYawAngle), v8); - if ( uIsFlying ) - { - pActors[v75].vVelocity.z = fixpoint_mul(stru_5C6E00->Sin(pActors[v75].uPitchAngle), v8); - } - //v7 = v68; - } - else - { - pActors[v75].vVelocity.x = fixpoint_mul(55000, pActors[v75].vVelocity.x); - pActors[v75].vVelocity.y = fixpoint_mul(55000, pActors[v75].vVelocity.y); - if ( uIsFlying ) - pActors[v75].vVelocity.z = fixpoint_mul(55000, pActors[v75].vVelocity.z); - } - if ( pActors[v75].vPosition.z < v5 ) - { - pActors[v75].vPosition.z = v5; - pActors[v75].vVelocity.z = uIsFlying != 0 ? 0x14 : 0; - } - //v17 = 0; - if ( !uIsAboveFloor || uIsFlying ) - { - if ( v70 && !uIsAboveFloor && v67 ) - { - pActors[v75].vPosition.z = v5; - ODM_GetTerrainNormalAt(pActors[v75].vPosition.x, pActors[v75].vPosition.y, &v62); - v20 = GetGravityStrength(); - //v21 = v62.y; - //v22 = v62.z; - //v23 = v62.y * v0->vVelocity.y; - pActors[v75].vVelocity.z += -8 * LOWORD(pEventTimer->uTimeElapsed) * v20; - int v73 = abs(v62.x * pActors[v75].vVelocity.x + v62.z * pActors[v75].vVelocity.z + v62.y * pActors[v75].vVelocity.y) >> 16; - //v72b = v21; - pActors[v75].vVelocity.x += fixpoint_mul(v73, v62.x); - pActors[v75].vVelocity.y += fixpoint_mul(v73, v62.y); - pActors[v75].vVelocity.z += fixpoint_mul(v73, v62.z); - //v17 = 0; - } - } - else - { - pActors[v75].vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength(); - } - if ( pParty->armageddon_timer != 0 && pActors[v75].CanAct() ) - { - pActors[v75].vVelocity.x += rand() % 100 - 50; - pActors[v75].vVelocity.y += rand() % 100 - 50; - pActors[v75].vVelocity.z += rand() % 100 - 20; - v25 = rand(); - pActors[v75].uAIState = Stunned; - pActors[v75].uYawAngle += v25 % 32 - 16; - pActors[v75].UpdateAnimation(); - } - if ( pActors[v75].vVelocity.x * pActors[v75].vVelocity.x + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y < 400 && v70 == 0 ) - { - pActors[v75].vVelocity.y = 0; - pActors[v75].vVelocity.x = 0; - } - stru_721530.field_0 = 1; - if ( !uIsFlying ) - v26 = 40; - else - v26 = pActors[v75].uActorRadius; - - stru_721530.field_84 = -1; - stru_721530.field_8_radius = v26; - stru_721530.prolly_normal_d = v26; - stru_721530.height = pActors[v75].uActorHeight; - stru_721530.field_70 = 0; - - for ( v69 = 0; v69 < 100; ++v69 ) - { - stru_721530.position.x = pActors[v75].vPosition.x; - stru_721530.normal.x = stru_721530.position.x; - stru_721530.position.y = pActors[v75].vPosition.y; - stru_721530.normal.y = stru_721530.position.y; - v28 = pActors[v75].vPosition.z; - stru_721530.normal.z = v28 + v26 + 1; - stru_721530.position.z = v28 - v26 + stru_721530.height - 1; - if ( stru_721530.position.z < stru_721530.normal.z ) - stru_721530.position.z = v28 + v26 + 1; - stru_721530.velocity.x = pActors[v75].vVelocity.x; - stru_721530.uSectorID = 0; - stru_721530.velocity.y = pActors[v75].vVelocity.y; - stru_721530.velocity.z = pActors[v75].vVelocity.z; - if ( stru_721530._47050A(0) ) - break; - _46E889_collide_against_bmodels(1); - v29 = WorldPosToGridCellZ(pActors[v75].vPosition.y); - v30 = WorldPosToGridCellX(pActors[v75].vPosition.x); - _46E26D_collide_against_sprites(v30, v29); - _46EF01_collision_chech_player(0); - _46ED8A_collide_against_sprite_objects(PID(OBJECT_Actor,v75)); - v31 = 0; - for ( i = 0; v31 < ai_arrays_size; ++v31 ) - { - v33 = ai_near_actors_ids[v31]; - if ( v33 != v75 && Actor::_46DF1A_collide_against_actor(v33, 40) ) - ++i; - } - v71 = i > 1; - if ( stru_721530.field_7C < stru_721530.field_6C ) - v70 = fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); - //v34 = 0; - v35 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; - v36 = ODM_GetFloorLevel(stru_721530.normal2.x, stru_721530.normal2.y, - stru_721530.normal2.z - stru_721530.prolly_normal_d - 1, - pActors[v75].uActorHeight, (int *)&v63, &v64, 0); - if ( uIsOnWater ) - { - if ( v35 < v36 + 60 ) - { - if ( pActors[v75].uAIState == Dead || pActors[v75].uAIState == Dying || pActors[v75].uAIState == Removed - || pActors[v75].uAIState == Disabled ) - { - if ( v64 ) - v61 = v36 + 30; - else - v61 = v5 + 60; - SpriteObject::sub_42F960_create_object(pActors[v75].vPosition.x, pActors[v75].vPosition.y, v61); - pActors[v75].uAIState = Removed; - return; - } - } - } - if ( stru_721530.field_7C >= stru_721530.field_6C ) - { - pActors[v75].vPosition.x = LOWORD(stru_721530.normal2.x); - pActors[v75].vPosition.y = LOWORD(stru_721530.normal2.y); - pActors[v75].vPosition.z = LOWORD(stru_721530.normal2.z) - LOWORD(stru_721530.prolly_normal_d) - 1; - break; - } - //v72b = fixpoint_mul(stru_721530.field_7C, stru_721530.field_58.x); - pActors[v75].vPosition.x += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); - //v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16; - pActors[v75].vPosition.y += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); - //v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16; - pActors[v75].vPosition.z += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); - stru_721530.field_70 += stru_721530.field_7C; - v39 = PID_ID(stru_721530.uFaceID); - switch ( PID_TYPE(stru_721530.uFaceID) ) - { - case OBJECT_Actor: - if ( pTurnEngine->turn_stage != TE_ATTACK && pTurnEngine->turn_stage != TE_MOVEMENT || pParty->bTurnBasedModeOn != TE_WAIT ) - { - //if(pParty->bTurnBasedModeOn == 1) - //v34 = 0; - if ( pActors[v75].pMonsterInfo.uHostilityType ) - { - if ( v71 == 0 ) - Actor::AI_Flee(v75, stru_721530.uFaceID, 0, (AIDirection *)0); - else - Actor::AI_StandOrBored(v75, 4, 0, (AIDirection *)0); - } - else if ( v71 ) - Actor::AI_StandOrBored(v75, 4, 0, (AIDirection *)0); - else if ( pActors[v39].pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Friendly ) - Actor::AI_Flee(v75, stru_721530.uFaceID, 0, (AIDirection *)0); - else - Actor::AI_FaceObject(v75, stru_721530.uFaceID, 0, (AIDirection *)0); - } - break; - case OBJECT_Player: - if ( !pActors[v75].GetActorsRelation(0) ) - { - Actor::AI_FaceObject(v75, stru_721530.uFaceID, 0, (AIDirection *)0); - break; - } - //v52 = HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) == 0; - //v53 = SHIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) < 0; - pActors[v75].vVelocity.y = 0; - pActors[v75].vVelocity.x = 0; - //if ( !v53 && (!(v53 | v52) || LODWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) > 0) ) - if ( (signed __int64)pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime < 0) - pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset(); - viewparams->bRedrawGameUI = 1; - break; - case OBJECT_Decoration: - v47 = integer_sqrt(pActors[v75].vVelocity.x * pActors[v75].vVelocity.x + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y); - v48 = stru_5C6E00->Atan2( pActors[v75].vPosition.x - pLevelDecorations[v39].vPosition.x, - pActors[v75].vPosition.y - pLevelDecorations[v39].vPosition.y); - //v49 = v48; - pActors[v75].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(v48), v47); - pActors[v75].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(v48), v47); - break; - case OBJECT_BModel: - face = &pOutdoor->pBModels[stru_721530.uFaceID >> 9].pFaces[v39 & 0x3F]; - if ( !face->Ethereal() ) - { - if ( face->uPolygonType == 3 ) - { - pActors[v75].vVelocity.z = 0; - pActors[v75].vPosition.z = LOWORD(pOutdoor->pBModels[stru_721530.uFaceID >> 9].pVertices.pVertices[face->pVertexIDs[0]].z) + 1; - if ( pActors[v75].vVelocity.x * pActors[v75].vVelocity.x - + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y < 400 ) - { - pActors[v75].vVelocity.y = 0; - pActors[v75].vVelocity.x = 0; - } - } - else - { - v72b = abs(face->pFacePlane.vNormal.y * pActors[v75].vVelocity.y + face->pFacePlane.vNormal.z * pActors[v75].vVelocity.z - + face->pFacePlane.vNormal.x * pActors[v75].vVelocity.x) >> 16; - if ( (stru_721530.speed >> 3) > v72b ) - v72b = stru_721530.speed >> 3; - - pActors[v75].vVelocity.x += fixpoint_mul(v72b, face->pFacePlane.vNormal.x); - pActors[v75].vVelocity.y += fixpoint_mul(v72b, face->pFacePlane.vNormal.y); - pActors[v75].vVelocity.z += fixpoint_mul(v72b, face->pFacePlane.vNormal.z); - if ( face->uPolygonType != 4 ) - { - v46 = stru_721530.prolly_normal_d - - ((face->pFacePlane.dist - + face->pFacePlane.vNormal.x * pActors[v75].vPosition.x - + face->pFacePlane.vNormal.y * pActors[v75].vPosition.y - + face->pFacePlane.vNormal.z * pActors[v75].vPosition.z) >> 16); - if ( v46 > 0 ) - { - pActors[v75].vPosition.x += fixpoint_mul(v46, face->pFacePlane.vNormal.x); - pActors[v75].vPosition.y += fixpoint_mul(v46, face->pFacePlane.vNormal.y); - pActors[v75].vPosition.z += fixpoint_mul(v46, face->pFacePlane.vNormal.z); - } - pActors[v75].uYawAngle = stru_5C6E00->Atan2(pActors[v75].vVelocity.x, pActors[v75].vVelocity.y); - } - } - } - break; - } - - pActors[v75].vVelocity.x = fixpoint_mul(58500, pActors[v75].vVelocity.x); - pActors[v75].vVelocity.y = fixpoint_mul(58500, pActors[v75].vVelocity.y); - pActors[v75].vVelocity.z = fixpoint_mul(58500, pActors[v75].vVelocity.z); - - v26 = stru_721530.prolly_normal_d; - } - - v58 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(WorldPosToGridCellX(pActors[v75].vPosition.x), WorldPosToGridCellZ(pActors[v75].vPosition.y) - 1) >> 1) & 1; - v59 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(WorldPosToGridCellX(pActors[v75].vPosition.x), WorldPosToGridCellZ(pActors[v75].vPosition.y) - 1) >> 1) & 1; - if ( WorldPosToGridCellX(pActors[v75].vPosition.x) == WorldPosToGridCellX(pActors[v75].vPosition.x) - && WorldPosToGridCellZ(pActors[v75].vPosition.y) == WorldPosToGridCellZ(pActors[v75].vPosition.y) - && v58 || v67 != 0 ) - { - if ( MonsterStats::BelongsToSupertype(pActors[v75].pMonsterInfo.uID, MONSTER_SUPERTYPE_WATER_ELEMENTAL) ) - { - v58 = v58 == 0; - v59 = v59 == 0; - } - if ( !uIsFlying && v58 && !v59 ) - { - pActors[v75].vPosition.x = pActors[v75].vPosition.x; - pActors[v75].vPosition.y = pActors[v75].vPosition.y; - if ( pActors[v75].CanAct() ) - { - pActors[v75].uYawAngle -= 32; - pActors[v75].uCurrentActionTime = 0; - pActors[v75].uCurrentActionLength = 128; - pActors[v75].uAIState = Fleeing; - } - } - } - } -} - -//----- (0047253E) -------------------------------------------------------- -void UpdateObjects() -{ - ObjectDesc *object; // eax@5 - int v5; // ecx@6 - signed int v7; // eax@9 - signed int v11; // eax@17 - int v12; // edi@27 - int v18; // [sp+4h] [bp-10h]@27 - int v19; // [sp+8h] [bp-Ch]@27 - - for (uint i = 0; i < uNumSpriteObjects; ++i) - { - if (pSpriteObjects[i].uAttributes & OBJECT_40) - pSpriteObjects[i].uAttributes &= ~OBJECT_40; - else - { - object = &pObjectList->pObjects[pSpriteObjects[i].uObjectDescID]; - if (pSpriteObjects[i].AttachedToActor()) - { - v5 = PID_ID(pSpriteObjects[i].spell_target_pid); - pSpriteObjects[i].vPosition.x = pActors[v5].vPosition.x; - pSpriteObjects[i].vPosition.y = pActors[v5].vPosition.y; - pSpriteObjects[i].vPosition.z = pActors[v5].vPosition.z + pActors[v5].uActorHeight; - if ( !pSpriteObjects[i].uObjectDescID ) - continue; - pSpriteObjects[i].uSpriteFrameID += pEventTimer->uTimeElapsed; - if ( !(object->uFlags & OBJECT_DESC_TEMPORARY)) - continue; - if ( pSpriteObjects[i].uSpriteFrameID >= 0 ) - { - v7 = object->uLifetime; - if (pSpriteObjects[i].uAttributes & ITEM_BROKEN) - v7 = pSpriteObjects[i].field_20; - if ( pSpriteObjects[i].uSpriteFrameID < v7 ) - continue; - } - SpriteObject::OnInteraction(i); - continue; - } - if ( pSpriteObjects[i].uObjectDescID ) - { - pSpriteObjects[i].uSpriteFrameID += pEventTimer->uTimeElapsed; - if ( object->uFlags & OBJECT_DESC_TEMPORARY ) - { - if ( pSpriteObjects[i].uSpriteFrameID < 0 ) - { - SpriteObject::OnInteraction(i); - continue; - } - v11 = object->uLifetime; - if (pSpriteObjects[i].uAttributes & ITEM_BROKEN) - v11 = pSpriteObjects[i].field_20; - } - if ( !(object->uFlags & OBJECT_DESC_TEMPORARY) || pSpriteObjects[i].uSpriteFrameID < v11 ) - { - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) - SpriteObject::UpdateObject_fn0_BLV(i); - else - SpriteObject::UpdateObject_fn0_ODM(i); - if ( pParty->bTurnBasedModeOn != 1 || !(pSpriteObjects[i].uSectorID & 4) ) - continue; - v12 = abs(pParty->vPosition.x - pSpriteObjects[i].vPosition.x); - v18 = abs(pParty->vPosition.y - pSpriteObjects[i].vPosition.y); - v19 = abs(pParty->vPosition.z - pSpriteObjects[i].vPosition.z); - if ( int_get_vector_length(v12, v18, v19) <= 5120 ) - continue; - SpriteObject::OnInteraction(i); - continue; - } - if ( !(object->uFlags & OBJECT_DESC_INTERACTABLE) ) - { - SpriteObject::OnInteraction(i); - continue; - } - _46BFFA_check_object_intercept(i, PID(OBJECT_Item,i)); - } - } - } -} - -//----- (0047272C) -------------------------------------------------------- -int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID) -{ - int result; // eax@1 - - *pSectorID = pIndoor->GetSector(x - 2, y, z + 40); - result = collide_against_floor(x - 2, y, z + 40, pSectorID, pFaceID); - if ( result == -30000 || !*pSectorID ) - { - *pSectorID = pIndoor->GetSector(x + 2, y, z + 40); - result = collide_against_floor(x + 2, y, z + 40, pSectorID, pFaceID); - if ( result == -30000 || !*pSectorID ) - { - *pSectorID = pIndoor->GetSector(x, y - 2, z + 40); - result = collide_against_floor(x, y - 2, z + 40, pSectorID, pFaceID); - if ( result == -30000 || !*pSectorID ) - { - *pSectorID = pIndoor->GetSector(x, y + 2, z + 40); - result = collide_against_floor(x, y + 2, z + 40, pSectorID, pFaceID); - if ( result == -30000 || !*pSectorID ) - { - *pSectorID = pIndoor->GetSector(x, y, z + 140); - result = collide_against_floor(x, y, z + 140, pSectorID, pFaceID); - } - } - } - } - return result; -} - -//----- (0047531C) -------------------------------------------------------- -bool sub_47531C(int a1, int *a2, int pos_x, int pos_y, int pos_z, int dir_x, int dir_y, int dir_z, BLVFace *face, int a10) -{ - int v11; // ST1C_4@3 - int v12; // edi@3 - int v13; // esi@3 - int v14; // edi@4 - signed __int64 v15; // qtt@6 - //__int16 v16; // si@7 - int a7a; // [sp+30h] [bp+18h]@7 - int a9b; // [sp+38h] [bp+20h]@3 - int a9a; // [sp+38h] [bp+20h]@3 - int a10b; // [sp+3Ch] [bp+24h]@3 - signed int a10a; // [sp+3Ch] [bp+24h]@4 - int a10c; // [sp+3Ch] [bp+24h]@5 - - if ( a10 && face->Ethereal() ) - return 0; - v11 = fixpoint_mul(dir_x, face->pFacePlane_old.vNormal.x); - a10b = fixpoint_mul(dir_y, face->pFacePlane_old.vNormal.y); - a9b = fixpoint_mul(dir_z, face->pFacePlane_old.vNormal.z); - v12 = v11 + a9b + a10b; - a9a = v11 + a9b + a10b; - v13 = (a1 << 16) - - pos_x * face->pFacePlane_old.vNormal.x - - pos_y * face->pFacePlane_old.vNormal.y - - pos_z * face->pFacePlane_old.vNormal.z - - face->pFacePlane_old.dist; - if ( abs((a1 << 16) - - pos_x * face->pFacePlane_old.vNormal.x - - pos_y * face->pFacePlane_old.vNormal.y - - pos_z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist) >= a1 << 16 ) - { - a10c = abs(v13) >> 14; - if ( a10c > abs(v12) ) - return 0; - LODWORD(v15) = v13 << 16; - HIDWORD(v15) = v13 >> 16; - v14 = a1; - a10a = v15 / a9a; - } - else - { - a10a = 0; - v14 = abs(v13) >> 16; - } - //v16 = pos_y + ((unsigned int)fixpoint_mul(a10a, dir_y) >> 16); - LOWORD(a7a) = (short)pos_x + ((unsigned int)fixpoint_mul(a10a, dir_x) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.x); - HIWORD(a7a) = pos_y + ((unsigned int)fixpoint_mul(a10a, dir_y) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.y); - if ( !sub_475665(face, a7a, (short)pos_z + ((unsigned int)fixpoint_mul(a10a, dir_z) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.z)) ) - return 0; - *a2 = a10a >> 16; - if ( a10a >> 16 < 0 ) - *a2 = 0; - return 1; -} - -//----- (004754BF) -------------------------------------------------------- -bool sub_4754BF(int a1, int *a2, int X, int Y, int Z, int dir_x, int dir_y, int dir_z, BLVFace *face, int a10, int a11) -{ - int v12; // ST1C_4@3 - int v13; // edi@3 - int v14; // esi@3 - int v15; // edi@4 - signed __int64 v16; // qtt@6 - //__int16 v17; // si@7 - int a7a; // [sp+30h] [bp+18h]@7 - int a1b; // [sp+38h] [bp+20h]@3 - int a1a; // [sp+38h] [bp+20h]@3 - int a11b; // [sp+40h] [bp+28h]@3 - signed int a11a; // [sp+40h] [bp+28h]@4 - int a11c; // [sp+40h] [bp+28h]@5 - - if ( a11 && face->Ethereal() ) - return false; - v12 = fixpoint_mul(dir_x, face->pFacePlane_old.vNormal.x); - a11b = fixpoint_mul(dir_y, face->pFacePlane_old.vNormal.y); - a1b = fixpoint_mul(dir_z, face->pFacePlane_old.vNormal.z); - v13 = v12 + a1b + a11b; - a1a = v12 + a1b + a11b; - v14 = (a1 << 16) - - X * face->pFacePlane_old.vNormal.x - - Y * face->pFacePlane_old.vNormal.y - - Z * face->pFacePlane_old.vNormal.z - - face->pFacePlane_old.dist; - if ( abs((a1 << 16) - - X * face->pFacePlane_old.vNormal.x - - Y * face->pFacePlane_old.vNormal.y - - Z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist) >= a1 << 16 ) - { - a11c = abs(v14) >> 14; - if ( a11c > abs(v13) ) - return false; - LODWORD(v16) = v14 << 16; - HIDWORD(v16) = v14 >> 16; - v15 = a1; - a11a = v16 / a1a; - } - else - { - a11a = 0; - v15 = abs(v14) >> 16; - } - //v17 = Y + ((unsigned int)fixpoint_mul(a11a, dir_y) >> 16); - LOWORD(a7a) = (short)X + ((unsigned int)fixpoint_mul(a11a, dir_x) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.x); - HIWORD(a7a) = Y + ((unsigned int)fixpoint_mul(a11a, dir_y) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.y); - if ( !sub_4759C9(face, a10, a7a, (short)Z + ((unsigned int)fixpoint_mul(a11a, dir_z) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.z)) ) - return false; - *a2 = a11a >> 16; - if ( a11a >> 16 < 0 ) - *a2 = 0; - return true; -} - -//----- (00475665) -------------------------------------------------------- -int sub_475665(BLVFace *face, int a2, __int16 a3) -{ - bool v16; // edi@14 - signed int v20; // ebx@18 - int v21; // edi@20 - signed int v22; // ST14_4@22 - signed __int64 v23; // qtt@22 - signed int result; // eax@25 - int v25; // [sp+14h] [bp-10h]@14 - int v26; // [sp+1Ch] [bp-8h]@2 - signed int v27; // [sp+20h] [bp-4h]@2 - signed int v28; // [sp+30h] [bp+Ch]@2 - signed int v29; // [sp+30h] [bp+Ch]@7 - signed int v30; // [sp+30h] [bp+Ch]@11 - signed int v31; // [sp+30h] [bp+Ch]@14 - - if ( face->uAttributes & FACE_XY_PLANE ) - { - v26 = (signed __int16)a2; - v27 = SHIWORD(a2); - if ( face->uNumVertices ) - { - for ( v28 = 0; v28 < face->uNumVertices; v28++ ) - { - word_720C10_intercepts_xs[2 * v28] = face->pXInterceptDisplacements[v28] + pIndoor->pVertices[face->pVertexIDs[v28]].x; - word_720B40_intercepts_zs[2 * v28] = face->pYInterceptDisplacements[v28] + pIndoor->pVertices[face->pVertexIDs[v28]].y; - word_720C10_intercepts_xs[2 * v28 + 1] = face->pXInterceptDisplacements[v28 + 1] + pIndoor->pVertices[face->pVertexIDs[v28 + 1]].x; - word_720B40_intercepts_zs[2 * v28 + 1] = face->pYInterceptDisplacements[v28 + 1] + pIndoor->pVertices[face->pVertexIDs[v28 + 1]].y; - } - } - } - else - { - if ( face->uAttributes & FACE_XZ_PLANE ) - { - v26 = (signed __int16)a2; - v27 = a3; - if ( face->uNumVertices ) - { - for ( v29 = 0; v29 < face->uNumVertices; v29++ ) - { - word_720C10_intercepts_xs[2 * v29] = face->pXInterceptDisplacements[v29] + pIndoor->pVertices[face->pVertexIDs[v29]].x; - word_720B40_intercepts_zs[2 * v29] = face->pZInterceptDisplacements[v29] + pIndoor->pVertices[face->pVertexIDs[v29]].z; - word_720C10_intercepts_xs[2 * v29 + 1] = face->pXInterceptDisplacements[v29 + 1] + pIndoor->pVertices[face->pVertexIDs[v29 + 1]].x; - word_720B40_intercepts_zs[2 * v29 + 1] = face->pZInterceptDisplacements[v29 + 1] + pIndoor->pVertices[face->pVertexIDs[v29 + 1]].z; - } - } - } - else - { - v26 = SHIWORD(a2); - v27 = a3; - if ( face->uNumVertices ) - { - for ( v30 = 0; v30 < face->uNumVertices; v30++ ) - { - word_720C10_intercepts_xs[2 * v30] = face->pYInterceptDisplacements[v30] + pIndoor->pVertices[face->pVertexIDs[v30]].y; - word_720B40_intercepts_zs[2 * v30] = face->pZInterceptDisplacements[v30] + pIndoor->pVertices[face->pVertexIDs[v30]].z; - word_720C10_intercepts_xs[2 * v30 + 1] = face->pYInterceptDisplacements[v30 + 1] + pIndoor->pVertices[face->pVertexIDs[v30 + 1]].y; - word_720B40_intercepts_zs[2 * v30 + 1] = face->pZInterceptDisplacements[v30 + 1] + pIndoor->pVertices[face->pVertexIDs[v30 + 1]].z; - } - } - } - } - v31 = 0; - word_720C10_intercepts_xs[2 * face->uNumVertices] = word_720C10_intercepts_xs[0]; - word_720B40_intercepts_zs[2 * face->uNumVertices] = word_720B40_intercepts_zs[0]; - v16 = word_720B40_intercepts_zs[0] >= v27; - if ( 2 * face->uNumVertices <= 0 ) - return 0; - for ( v25 = 0; v25 < 2 * face->uNumVertices; ++v25 ) - { - if ( v31 >= 2 ) - break; - if ( v16 ^ (word_720B40_intercepts_zs[v25 + 1] >= v27) ) - { - if ( word_720C10_intercepts_xs[v25 + 1] >= v26 ) - v20 = 0; - else - v20 = 2; - v21 = v20 | (word_720C10_intercepts_xs[v25] < v26); - if ( v21 != 3 ) - { - v22 = word_720C10_intercepts_xs[v25 + 1] - word_720C10_intercepts_xs[v25]; - LODWORD(v23) = v22 << 16; - HIDWORD(v23) = v22 >> 16; - if ( !v21 - || (word_720C10_intercepts_xs[v25] + ((signed int)(((unsigned __int64)(v23 - / (word_720B40_intercepts_zs[v25 + 1] - word_720B40_intercepts_zs[v25]) - * ((v27 - (signed int)word_720B40_intercepts_zs[v25]) << 16)) >> 16) - + 32768) >> 16) >= v26) ) - ++v31; - } - } - v16 = word_720B40_intercepts_zs[v25 + 1] >= v27; - } - result = 1; - if ( v31 != 1 ) - result = 0; - return result; -} - -//----- (004759C9) -------------------------------------------------------- -bool __fastcall sub_4759C9(BLVFace *face, int a2, int a3, __int16 a4) -{ - bool v12; // edi@14 - signed int v16; // ebx@18 - int v17; // edi@20 - signed int v18; // ST14_4@22 - signed __int64 v19; // qtt@22 - bool result; // eax@25 - int v21; // [sp+14h] [bp-10h]@14 - signed int v22; // [sp+18h] [bp-Ch]@1 - int v23; // [sp+1Ch] [bp-8h]@2 - signed int v24; // [sp+20h] [bp-4h]@2 - signed int a4d; // [sp+30h] [bp+Ch]@14 - - if ( face->uAttributes & FACE_XY_PLANE ) - { - v23 = (signed __int16)a3; - v24 = SHIWORD(a3); - if ( face->uNumVertices ) - { - for ( v22 = 0; v22 < face->uNumVertices; ++v22 ) - { - word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pXInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].x); - word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pYInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].y); - word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pXInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].x); - word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pYInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].y); - } - } - } - else - { - if ( face->uAttributes & FACE_XZ_PLANE ) - { - v23 = (signed __int16)a3; - v24 = a4; - if ( face->uNumVertices ) - { - for ( v22 = 0; v22 < face->uNumVertices; ++v22 ) - { - word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pXInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].x); - word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pZInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].z); - word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pXInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].x); - word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pZInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].z); - } - } - } - else - { - v23 = SHIWORD(a3); - v24 = a4; - if ( face->uNumVertices ) - { - for ( v22 = 0; v22 < face->uNumVertices; ++v22 ) - { - word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pYInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].y); - word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pZInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].z); - word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pYInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].y); - word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pZInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].z); - } - } - } - } - a4d = 0; - word_720A70_intercepts_xs_plus_xs[2 * face->uNumVertices] = word_720A70_intercepts_xs_plus_xs[0]; - word_7209A0_intercepts_ys_plus_ys[2 * face->uNumVertices] = word_7209A0_intercepts_ys_plus_ys[0]; - v12 = word_7209A0_intercepts_ys_plus_ys[0] >= v24; - if ( 2 * face->uNumVertices <= 0 ) - return 0; - for ( v21 = 0; v21 < 2 * face->uNumVertices; ++v21 ) - { - if ( a4d >= 2 ) - break; - if ( v12 ^ (word_7209A0_intercepts_ys_plus_ys[v21 + 1] >= v24) ) - { - if ( word_720A70_intercepts_xs_plus_xs[v21 + 1] >= v23 ) - v16 = 0; - else - v16 = 2; - v17 = v16 | (word_720A70_intercepts_xs_plus_xs[v21] < v23); - if ( v17 != 3 ) - { - v18 = word_720A70_intercepts_xs_plus_xs[v21 + 1] - word_720A70_intercepts_xs_plus_xs[v21]; - LODWORD(v19) = v18 << 16; - HIDWORD(v19) = v18 >> 16; - if ( !v17 - || (word_720A70_intercepts_xs_plus_xs[v21] + ((signed int)(((unsigned __int64)(v19 - / (word_7209A0_intercepts_ys_plus_ys[v21 + 1] - word_7209A0_intercepts_ys_plus_ys[v21]) - * ((v24 - (signed int)word_7209A0_intercepts_ys_plus_ys[v21]) << 16)) >> 16) - + 0x8000) >> 16) >= v23) ) - ++a4d; - } - } - v12 = word_7209A0_intercepts_ys_plus_ys[v21 + 1] >= v24; - } - result = 1; - if ( a4d != 1 ) - result = 0; - return result; -} - -//----- (00475D85) -------------------------------------------------------- -bool __fastcall sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, BLVFace *a4) -{ - BLVFace *v4; // ebx@1 - int v5; // ST24_4@2 - int v6; // ST28_4@2 - int v7; // edi@2 - int v8; // eax@5 - signed int v9; // esi@5 - signed __int64 v10; // qtt@10 - Vec3_int_ *v11; // esi@11 - int v12; // ST14_4@11 - Vec3_int_ *v14; // [sp+Ch] [bp-18h]@1 - Vec3_int_ *v15; // [sp+14h] [bp-10h]@1 -// int v16; // [sp+18h] [bp-Ch]@2 - int v17; // [sp+20h] [bp-4h]@10 - int a4b; // [sp+30h] [bp+Ch]@2 - int a4c; // [sp+30h] [bp+Ch]@9 - signed int a4a; // [sp+30h] [bp+Ch]@10 - - v4 = a4; - v15 = a2; - v14 = a1; - v5 = fixpoint_mul(a2->x, a4->pFacePlane_old.vNormal.x); - a4b = fixpoint_mul(a2->y, a4->pFacePlane_old.vNormal.y); - v6 = fixpoint_mul(a2->z, v4->pFacePlane_old.vNormal.z); - v7 = v5 + v6 + a4b; - //(v16 = v5 + v6 + a4b) == 0; - if ( a4->uAttributes & 0x20000000 || !v7 || v7 > 0 && !v4->Portal()) - return 0; - v8 = v4->pFacePlane_old.vNormal.z * a1->z; - v9 = -(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x); - if ( v7 <= 0 ) - { - if ( v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x < 0 ) - return 0; - } - else - { - if ( v9 < 0 ) - return 0; - } - a4c = abs(-(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x)) >> 14; - v11 = v14; - LODWORD(v10) = v9 << 16; - HIDWORD(v10) = v9 >> 16; - a4a = v10 / v7; - v17 = v10 / v7; - LOWORD(v12) = LOWORD(v14->x) + (((unsigned int)fixpoint_mul(v17, v15->x) + 0x8000) >> 16); - HIWORD(v12) = LOWORD(v11->y) + (((unsigned int)fixpoint_mul(v17, v15->y) + 0x8000) >> 16); - if ( a4c > abs(v7) || ( v17 > *a3 << 16) || !sub_475665(v4, v12, LOWORD(v11->z) + (((unsigned int)fixpoint_mul(v17, v15->z) + 0x8000) >> 16)) ) - return 0; - *a3 = a4a >> 16; - return 1; -} - -//----- (00475F30) -------------------------------------------------------- -bool __fastcall sub_475F30(int *a1, BLVFace *a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) -{ - int v10; // ST20_4@2 - int v11; // ST28_4@2 - int v12; // ST24_4@2 - int v13; // zf@2 - int v14; // edi@2 - signed int v16; // esi@5 - int v17; // ST20_4@9 - signed __int64 v18; // qtt@10 - int v19; // ST14_4@11 - int v22; // [sp+1Ch] [bp-8h]@2 - int v23; // [sp+1Ch] [bp-8h]@10 - signed int v24; // [sp+20h] [bp-4h]@10 - - v10 = fixpoint_mul(a6, a2->pFacePlane_old.vNormal.x); - v11 = fixpoint_mul(a7, a2->pFacePlane_old.vNormal.y); - v12 = fixpoint_mul(a8, a2->pFacePlane_old.vNormal.z); - v13 = v10 + v12 + v11; - v14 = v10 + v12 + v11; - v22 = v10 + v12 + v11; - if ( a2->Ethereal() || !v13 || v14 > 0 && !a2->Portal()) - return 0; - v16 = -(a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z); - if ( v14 <= 0 ) - { - if ( a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z < 0 ) - return 0; - } - else - { - if ( v16 < 0 ) - return 0; - } - v17 = abs(-(a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z)) >> 14; - LODWORD(v18) = v16 << 16; - HIDWORD(v18) = v16 >> 16; - v24 = v18 / v22; - v23 = v18 / v22; - LOWORD(v19) = a3 + (((unsigned int)fixpoint_mul(v23, a6) + 0x8000) >> 16); - HIWORD(v19) = a4 + (((unsigned int)fixpoint_mul(v23, a7) + 0x8000) >> 16); - if ( v17 > abs(v14) || v23 > *a1 << 16 || !sub_4759C9(a2, a9, v19, a5 + (((unsigned int)fixpoint_mul(v23, a8) + 0x8000) >> 16)) ) - return 0; - *a1 = v24 >> 16; - return 1; -} - -//----- (004760D5) -------------------------------------------------------- -PartyAction ActionQueue::Next() -{ - if (!uNumActions) - return PARTY_INVALID; - - PartyAction result = pActions[0]; - for (unsigned int i = 0; i < uNumActions - 1; ++i) - pActions[i] = pActions[i + 1]; - --uNumActions; - - return result; -} - -//----- (004775ED) -------------------------------------------------------- -int stru6_stru1_indoor_sw_billboard::_4775ED(float a2) -{ - char *v2; // edi@1 - //int v3; // eax@1 - char *v4; // edx@2 - char *v5; // esi@3 - double v6; // st7@6 - signed __int64 v7; // ST84_8@6 - double v8; // ST0C_8@6 - int v9; // esi@6 - double v10; // ST44_8@6 - int v11; // ecx@6 - double v12; // ST34_8@6 - int v13; // ecx@6 - double v14; // ST14_8@6 - double v15; // st7@8 - unsigned int v16; // ecx@8 - signed __int64 v17; // ST64_8@8 - double v18; // ST24_8@8 - int v19; // edi@8 - double v20; // ST3C_8@8 - int v21; // ecx@8 - double v22; // ST2C_8@8 - int v23; // ST9C_4@8 - double v24; // ST1C_8@8 - int *v25; // edi@8 - int v26; // esi@8 - int *v27; // edi@10 - int v28; // esi@10 -// int result; // eax@12 - __int64 v30; // [sp+A8h] [bp-30h]@8 - float v31; // [sp+B0h] [bp-28h]@6 - float v32; // [sp+B4h] [bp-24h]@6 - int v33; // [sp+B8h] [bp-20h]@6 - int v34; // [sp+BCh] [bp-1Ch]@2 - stru6_stru1_indoor_sw_billboard *v35; // [sp+C0h] [bp-18h]@1 - float v36; // [sp+C4h] [bp-14h]@6 - int v37; // [sp+C8h] [bp-10h]@6 - int v38; // [sp+CCh] [bp-Ch]@1 - float v39; // [sp+D0h] [bp-8h]@6 - int *v40; // [sp+D4h] [bp-4h]@2 - -// __debugbreak();//нужно почистить, срабатывает при применении закла Точечный взрыв и при стрельбе из жезла - v2 = (char *)&this->field_64[4 * this->uNumVertices]; - v38 = 0; - *(int *)v2 = this->field_64[0]; - v2 += 4; - *(int *)v2 = this->field_64[1]; - v2 += 4; - *(int *)v2 = this->field_64[2]; - *((int *)v2 + 1) = this->field_64[3]; - //v3 = this->uNumVertices; - v35 = this; - if ( this->uNumVertices > 0 ) - { - v40 = &this->field_64[20]; - v4 = (char *)&this->field_64[3] + 3; - - //while ( 1 ) - for ( v34 = this->uNumVertices; v34; --v34 ) - { - v5 = v4 - 15; - if ( *(float *)(v4 - 15) <= (double)a2 && *(float *)(v4 + 1) <= (double)a2 ) - { - v4 += 16; - //--v34; - //if ( !v34 ) - //return this->uNumVertices = v38; - continue; - } - if ( *(float *)v5 <= (double)a2 ) - { - v6 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5); - v7 = (unsigned __int8)v4[16] - (unsigned int)(unsigned __int8)*v4; - v36 = v6; - v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v6 + *(float *)(v4 - 11); - v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v6 + *(float *)(v4 - 7); - *(float *)&v37 = (double)v7 * v6; - v8 = *(float *)&v37 + 6.7553994e15; - v9 = (unsigned __int8)*v4; - *(float *)&v37 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36; - v10 = *(float *)&v37 + 6.7553994e15; - v11 = (unsigned __int8)*(v4 - 2); - v37 = LODWORD(v10) + (unsigned __int8)*(v4 - 1); - v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v11) * v36; - v12 = v39 + 6.7553994e15; - v13 = LODWORD(v12) + (unsigned __int8)*(v4 - 2); - v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36; - v14 = v39 + 6.7553994e15; - v33 = (LODWORD(v14) + (*(int *)(v4 - 3) & 0xFF)) | ((v13 | ((v37 | ((LODWORD(v8) + v9) << 8)) << 8)) << 8); - //this = v35; - v5 = (char *)&v30 + 4; - } - else if ( *(float *)(v4 + 1) <= (double)a2 ) - { - v15 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5); - v16 = (unsigned __int8)*v4; - HIDWORD(v30) = LODWORD(a2); - v17 = (unsigned __int8)v4[16] - v16; - v36 = v15; - v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v15 + *(float *)(v4 - 11); - v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v15 + *(float *)(v4 - 7); - v39 = (double)v17 * v15; - v18 = v39 + 6.7553994e15; - v19 = (unsigned __int8)*v4; - v39 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36; - v20 = v39 + 6.7553994e15; - v21 = (unsigned __int8)*(v4 - 2); - v37 = LODWORD(v20) + (unsigned __int8)*(v4 - 1); - v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v21) * v36; - v22 = v39 + 6.7553994e15; - v23 = LODWORD(v22) + (unsigned __int8)*(v4 - 2); - v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36; - v24 = v39 + 6.7553994e15; - v33 = (LODWORD(v24) + (*(int *)(v4 - 3) & 0xFF)) | ((v23 | ((v37 | ((LODWORD(v18) + v19) << 8)) << 8)) << 8); - v25 = v40; - *v40 = *(int *)v5; - v26 = (int)(v5 + 4); - ++v25; - *v25 = *(int *)v26; - v26 += 4; - ++v25; - ++v38; - v40 += 4; - *v25 = *(int *)v26; - v25[1] = *(int *)(v26 + 4); - v5 = (char *)&v30 + 4; - } - v27 = v40; - ++v38; - *v40 = *(int *)v5; - v28 = (int)(v5 + 4); - ++v27; - *v27 = *(int *)v28; - v28 += 4; - ++v27; - v40 += 4; - *v27 = *(int *)v28; - v27[1] = *(int *)(v28 + 4); - v4 += 16; - //--v34; - //if ( !v34 ) - //return this->uNumVertices = v38; - } - } - return this->uNumVertices = v38; -} - -//----- (00477927) -------------------------------------------------------- -int stru6_stru1_indoor_sw_billboard::_477927(float a2) -{ - char *v2; // edi@1 - int v3; // eax@1 - char *v4; // edx@2 - char *v5; // esi@3 - double v6; // st7@6 - signed __int64 v7; // ST84_8@6 - double v8; // ST0C_8@6 - int v9; // esi@6 - double v10; // ST44_8@6 - int v11; // ecx@6 - double v12; // ST34_8@6 - int v13; // ecx@6 - double v14; // ST14_8@6 - double v15; // st7@8 - unsigned int v16; // ecx@8 - signed __int64 v17; // ST64_8@8 - double v18; // ST24_8@8 - int v19; // edi@8 - double v20; // ST3C_8@8 - int v21; // ecx@8 - double v22; // ST2C_8@8 - int v23; // ST9C_4@8 - double v24; // ST1C_8@8 - int *v25; // edi@8 - int v26; // esi@8 - int *v27; // edi@10 - int v28; // esi@10 -// int result; // eax@12 - __int64 v30; // [sp+A8h] [bp-30h]@8 - float v31; // [sp+B0h] [bp-28h]@6 - float v32; // [sp+B4h] [bp-24h]@6 - int v33; // [sp+B8h] [bp-20h]@6 - int v34; // [sp+BCh] [bp-1Ch]@2 - stru6_stru1_indoor_sw_billboard *v35; // [sp+C0h] [bp-18h]@1 - float v36; // [sp+C4h] [bp-14h]@6 - int v37; // [sp+C8h] [bp-10h]@6 - int v38; // [sp+CCh] [bp-Ch]@1 - float v39; // [sp+D0h] [bp-8h]@6 - int *v40; // [sp+D4h] [bp-4h]@2 - - __debugbreak();//нужно почистить - v2 = (char *)&this->field_64[4 * this->uNumVertices]; - v38 = 0; - *(int *)v2 = this->field_64[0]; - v2 += 4; - *(int *)v2 = this->field_64[1]; - v2 += 4; - *(int *)v2 = this->field_64[2]; - *((int *)v2 + 1) = this->field_64[3]; - v3 = this->uNumVertices; - v35 = this; - if ( v3 > 0 ) - { - v40 = &this->field_64[20]; - v4 = (char *)&this->field_64[3] + 3; - v34 = v3; - while ( 1 ) - { - v5 = v4 - 15; - if ( *(float *)(v4 - 15) >= (double)a2 && *(float *)(v4 + 1) >= (double)a2 ) - { - v4 += 16; - --v34; - if ( !v34 ) - return this->uNumVertices = v38; - continue; - } - if ( *(float *)v5 >= (double)a2 ) - { - v6 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5); - v7 = (unsigned __int8)v4[16] - (unsigned int)(unsigned __int8)*v4; - v36 = v6; - v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v6 + *(float *)(v4 - 11); - v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v6 + *(float *)(v4 - 7); - *(float *)&v37 = (double)v7 * v6; - v8 = *(float *)&v37 + 6.7553994e15; - v9 = (unsigned __int8)*v4; - *(float *)&v37 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36; - v10 = *(float *)&v37 + 6.7553994e15; - v11 = (unsigned __int8)*(v4 - 2); - v37 = LODWORD(v10) + (unsigned __int8)*(v4 - 1); - v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v11) * v36; - v12 = v39 + 6.7553994e15; - v13 = LODWORD(v12) + (unsigned __int8)*(v4 - 2); - v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36; - v14 = v39 + 6.7553994e15; - v33 = (LODWORD(v14) + (*(int *)(v4 - 3) & 0xFF)) | ((v13 | ((v37 | ((LODWORD(v8) + v9) << 8)) << 8)) << 8); - //this = v35; - v5 = (char *)&v30 + 4; - } - else if ( *(float *)(v4 + 1) >= (double)a2 ) - { - v15 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5); - v16 = (unsigned __int8)*v4; - HIDWORD(v30) = LODWORD(a2); - v17 = (unsigned __int8)v4[16] - v16; - v36 = v15; - v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v15 + *(float *)(v4 - 11); - v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v15 + *(float *)(v4 - 7); - v39 = (double)v17 * v15; - v18 = v39 + 6.7553994e15; - v19 = (unsigned __int8)*v4; - v39 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36; - v20 = v39 + 6.7553994e15; - v21 = (unsigned __int8)*(v4 - 2); - v37 = LODWORD(v20) + (unsigned __int8)*(v4 - 1); - v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v21) * v36; - v22 = v39 + 6.7553994e15; - v23 = LODWORD(v22) + (unsigned __int8)*(v4 - 2); - v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36; - v24 = v39 + 6.7553994e15; - v33 = (LODWORD(v24) + (*(int *)(v4 - 3) & 0xFF)) | ((v23 | ((v37 | ((LODWORD(v18) + v19) << 8)) << 8)) << 8); - v25 = v40; - *v40 = *(int *)v5; - v26 = (int)(v5 + 4); - ++v25; - *v25 = *(int *)v26; - v26 += 4; - ++v25; - ++v38; - v40 += 4; - *v25 = *(int *)v26; - v25[1] = *(int *)(v26 + 4); - v5 = (char *)&v30 + 4; - } - v27 = v40; - ++v38; - *v40 = *(int *)v5; - v28 = (int)(v5 + 4); - ++v27; - *v27 = *(int *)v28; - v28 += 4; - ++v27; - v40 += 4; - *v27 = *(int *)v28; - v27[1] = *(int *)(v28 + 4); - v4 += 16; - --v34; - if ( !v34 ) - return this->uNumVertices = v38; - } - } - return this->uNumVertices = v38; -} - -//----- (00477C61) -------------------------------------------------------- -int stru6_stru1_indoor_sw_billboard::sub_477C61() -{ - //stru6_stru1_indoor_sw_billboard *v1; // ebx@1 - int v2; // ecx@2 - int v3; // eax@3 - double v4; // st7@4 - double v5; // st7@5 - double v6; // st6@5 - double v7; // st5@6 - float v8; // ST30_4@8 - float v9; // ST24_4@8 - double v10; // st7@8 - double v11; // st6@8 - double v12; // st5@8 - float v13; // ST24_4@13 - int v14; // esi@13 - char *v15; // esi@15 - //signed int v16; // eax@16 -// __int16 v17; // fps@16 -// unsigned __int8 v18; // c2@16 -// unsigned __int8 v19; // c3@16 - double v20; // st6@16 - float v21; // ST18_4@17 - float v22; // ST2C_4@17 - float v23; // ST34_4@17 - float v24; // ST24_4@17 - double v25; // st7@17 - double v26; // st6@17 - float v27; // ST34_4@18 - float v28; // ST30_4@18 - int v29; // eax@19 - signed int v31; // [sp+8h] [bp-28h]@15 - float v32; // [sp+Ch] [bp-24h]@16 - float v33; // [sp+14h] [bp-1Ch]@16 - float v34; // [sp+18h] [bp-18h]@16 - float v35; // [sp+1Ch] [bp-14h]@17 - float v36; // [sp+20h] [bp-10h]@4 - float v37; // [sp+24h] [bp-Ch]@4 - float v38; // [sp+24h] [bp-Ch]@16 - float v39; // [sp+28h] [bp-8h]@9 - float v40; // [sp+28h] [bp-8h]@16 - float v41; // [sp+2Ch] [bp-4h]@6 - float v42; // [sp+2Ch] [bp-4h]@9 - - //__debugbreak();//нужно почистить, срабатывает при применении закла Точечный взрыв - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) - { - - if ( this->uNumVertices > 0 ) - { - v3 = (int)&this->field_14[1]; - //do - for ( v2 = 0; v2 < this->uNumVertices; ++v2 ) - { - v4 = *(float *)(v3 - 4); - LODWORD(v37) = *(int *)v3; - LODWORD(v36) = *(int *)(v3 + 4); - if (pGame->pIndoorCameraD3D->sRotationX) - { - v5 = v4 - (double)pGame->pIndoorCameraD3D->vPartyPos.x; - v6 = v37 - (double)pGame->pIndoorCameraD3D->vPartyPos.y; - //if ( pRenderer->pRenderD3D ) - //{ - v41 = pGame->pIndoorCameraD3D->fRotationYSine * v6 + pGame->pIndoorCameraD3D->fRotationYCosine * v5; - v7 = pGame->pIndoorCameraD3D->fRotationYSine * v5 - pGame->pIndoorCameraD3D->fRotationYCosine * v6; - /*} - else - { - v41 = pBLVRenderParams->fCosineY * v5 - pBLVRenderParams->fSineY * v6; - v7 = pBLVRenderParams->fSineY * v5 + pBLVRenderParams->fCosineY * v6; - }*/ - v8 = v7; - v9 = v36 - (double)pGame->pIndoorCameraD3D->vPartyPos.z; - v10 = pGame->pIndoorCameraD3D->fRotationXCosine * v41 - pGame->pIndoorCameraD3D->fRotationXSine * v9; - v11 = v8; - v12 = pGame->pIndoorCameraD3D->fRotationXCosine * v9 + pGame->pIndoorCameraD3D->fRotationXSine * v41; - } - else - { - v42 = v4 - (double)pGame->pIndoorCameraD3D->vPartyPos.x; - v39 = v37 - (double)pGame->pIndoorCameraD3D->vPartyPos.y; - //if ( pRenderer->pRenderD3D ) - //{ - v10 = pGame->pIndoorCameraD3D->fRotationYSine * v39 + pGame->pIndoorCameraD3D->fRotationYCosine * v42; - v11 = pGame->pIndoorCameraD3D->fRotationYSine * v42 - pGame->pIndoorCameraD3D->fRotationYCosine * v39; - /*} - else - { - v10 = pBLVRenderParams->fCosineY * v42 - pBLVRenderParams->fSineY * v39; - v11 = pBLVRenderParams->fSineY * v42 + pBLVRenderParams->fCosineY * v39; - }*/ - v12 = v36 - (double)pGame->pIndoorCameraD3D->vPartyPos.z; - } - v13 = v12; - //++v2; - *(int *)(v3 + 84) = LODWORD(v13); - v14 = *(int *)(v3 + 8); - *(float *)(v3 + 76) = v10; - *(int *)(v3 + 88) = v14; - *(float *)(v3 + 80) = v11; - v3 += 16; - } - //while ( v2 < this->uNumVertices ); - } - } - else - { - v15 = (char *)&this->field_14[1]; - //do - for ( v31 = 3; v31; --v31 ) - { - v40 = (double)stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX) * 0.0000152587890625; - v32 = (double)stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX) * 0.0000152587890625; - v34 = (double)stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY) * 0.0000152587890625; - v33 = (double)stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY) * 0.0000152587890625; - //v16 = stru_5C6E00->Sin(pODMRenderParams->rotation_y); - LODWORD(v38) = *(int *)v15; - //UNDEF(v17); - v20 = *((float *)v15 - 1) - (double)pGame->pIndoorCameraD3D->vPartyPos.x; - //if ( v19 | v18 ) - if (pGame->pIndoorCameraD3D->vPartyPos.x == 0) - { - v27 = v20; - LODWORD(v35) = *((int *)v15 + 1); - v28 = v38 - (double)pGame->pIndoorCameraD3D->vPartyPos.y; - v25 = v33 * v28 + v34 * v27; - v26 = v34 * v28 - v33 * v27; - } - else - { - v21 = v20; - v22 = v38 - (double)pGame->pIndoorCameraD3D->vPartyPos.y; - v23 = v33 * v22 + v34 * v21; - v24 = *((float *)v15 + 1) - (double)pGame->pIndoorCameraD3D->vPartyPos.z; - v25 = v32 * v24 + v40 * v23; - v26 = v34 * v22 - v33 * v21; - v35 = v40 * v24 - v32 * v23; - } - *((int *)v15 + 21) = LODWORD(v35); - v29 = *((int *)v15 + 2); - *((float *)v15 + 19) = v25; - *((int *)v15 + 22) = v29; - *((float *)v15 + 20) = v26; - v15 += 16; - //--v31; - } - //while ( v31 ); - } - this->uNumVertices = 3; - return 1; -} - -//----- (00477F63) -------------------------------------------------------- -bool stru6_stru1_indoor_sw_billboard::sub_477F63() -{ - signed int v1; // ebx@1 - double v3; // st7@2 - //int v4; // edx@4 - char *v5; // ecx@5 - int v6; // edi@5 - float v7; // ST08_4@13 - signed int v9; // [sp+Ch] [bp-8h]@1 - float v10; // [sp+10h] [bp-4h]@2 - - //__debugbreak();// почистить - v1 = 0; - v9 = 0; - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) - { - v10 = 16192.0; - v3 = (double)pBLVRenderParams->fov_rad_fixpoint * 0.000015258789; - } - else if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) - { - v10 = (double)pODMRenderParams->shading_dist_mist; - v3 = 8.0; - } - else - __debugbreak();//Error - if ( this->uNumVertices <= 0 ) - { - memcpy(&this->field_14[40], &this->field_14[20], 16 * this->uNumVertices); - return this->uNumVertices != 0; - } - v5 = (char *)&this->field_14[20]; - for ( v6 = 0; v6 < this->uNumVertices; v6++ ) - { - if ( v3 >= *(float *)v5 || *(float *)v5 >= (double)v10 ) - { - if ( v3 < *(float *)v5 ) - v9 = 1; - else - v1 = 1; - } - v5 += 16; - } - if ( !v1 ) - { - if ( v9 ) - { - this->_477927(v10); - return this->uNumVertices != 0; - } - memcpy(&this->field_14[40], &this->field_14[20], 16 * this->uNumVertices); - return this->uNumVertices != 0; - } - v7 = v3; - _4775ED(v7); - return this->uNumVertices != 0; -} - -//----- (0047802A) -------------------------------------------------------- -int stru6_stru1_indoor_sw_billboard::sub_47802A() -{ - double v6; // st7@4 - signed int v16; // [sp+38h] [bp-Ch]@1 - int a6; // [sp+3Ch] [bp-8h]@5 - int a5; // [sp+40h] [bp-4h]@5 - -// __debugbreak(); //необходимо проверить this->field_B4[i*4+16] - v16 = 0; - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) - { - for(int i = 0; i < this->uNumVertices; i++) - { - v6 = (double)pBLVRenderParams->fov_rad_fixpoint * 0.000015258789 / this->field_B4[i*4]; - //if ( pRenderer->pRenderD3D ) - { - pGame->pIndoorCameraD3D->Project(round_to_int(this->field_B4[i*4]), round_to_int(this->field_B4[i*4+1]), round_to_int(this->field_B4[i*4+2]), - &a5, &a6); - this->field_B4[i*4+16] = (double)a5; - this->field_B4[i*4+17] = (double)a6; - this->field_B4[i*4+18] = round_to_int(this->field_B4[i*4]); - } - /*else - { - this->field_B4[i*4+16] = (double)pBLVRenderParams->uViewportCenterX - v6 * this->field_B4[i*4+1]; - this->field_B4[i*4+17] = (double)pBLVRenderParams->uViewportCenterY - v6 * this->field_B4[i*4+2]; - this->field_B4[i*4+18] = this->field_B4[i*4]; - }*/ - this->field_B4[i*4+19] = this->field_B4[i*4+3]; - if ( (double)(signed int)pViewport->uViewportTL_X <= this->field_B4[i*4+16] && (double)(signed int)pViewport->uViewportBR_X > this->field_B4[i*4+16] - && (double)(signed int)pViewport->uViewportTL_Y <= this->field_B4[i*4+17] && (double)(signed int)pViewport->uViewportBR_Y > this->field_B4[i*4+17] ) - v16 = 1; - } - } - else - { - for(int i = 0; i < this->uNumVertices; i++) - { - this->field_B4[i*4+20] = (double)pViewport->uScreenCenterX - (double)pODMRenderParams->int_fov_rad / this->field_B4[i*4] * this->field_B4[i*4+1]; - this->field_B4[i*4+21] = (double)pViewport->uScreenCenterY - (double)pODMRenderParams->int_fov_rad / this->field_B4[i*4] * this->field_B4[i*4+2]; - *((int *)&this->field_B4[i*4+22]) = (int)this->field_B4[i*4]; - *((int *)&this->field_B4[i*4+23]) = this->field_B4[i*4+3]; - if ( (double)(signed int)pViewport->uViewportTL_X <= this->field_B4[i*4+20] && (double)(signed int)pViewport->uViewportBR_X > this->field_B4[i*4+20] - && (double)(signed int)pViewport->uViewportTL_Y <= this->field_B4[i*4+21] && (double)(signed int)pViewport->uViewportBR_Y > this->field_B4[i*4+21] ) - v16 = 1; - } - } - return v16; -} - -// 73C84C: using guessed type char static_RenderBuildingsD3D_byte_73C84C_init_flag; - -//----- (00479089) -------------------------------------------------------- -bool __fastcall IsBModelVisible(unsigned int uModelID, int *reachable) -{ - int v3; // edi@1 - int v4; // ebx@1 - int v9; // eax@3 - signed int v11; // esi@6 - int v12; // esi@8 - bool result; // eax@9 - int v17; // [sp+1Ch] [bp-10h]@1 - int v19; // [sp+20h] [bp-Ch]@3 - int angle; // [sp+24h] [bp-8h]@1 - - angle = (signed int)(pODMRenderParams->uCameraFovInDegrees << 11) / 360 / 2; - v3 = pOutdoor->pBModels[uModelID].vBoundingCenter.x - pGame->pIndoorCameraD3D->vPartyPos.x; - v4 = pOutdoor->pBModels[uModelID].vBoundingCenter.y - pGame->pIndoorCameraD3D->vPartyPos.y; - stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX); - v17 = v3 * stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY) + v4 * stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); - if (pGame->pIndoorCameraD3D->sRotationX) - v17 = fixpoint_mul(v17, stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX)); - v19 = v4 * stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY) - v3 * stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); - v9 = int_get_vector_length(abs(v3), abs(v4), 0); - //v10 = v14 * 188; - //v22 = v9; - *reachable = false; - if ( v9 < pOutdoor->pBModels[uModelID].sBoundingRadius + 256 ) - *reachable = true; - if ( v19 >= 0 ) - v11 = fixpoint_mul(stru_5C6E00->Sin(angle), v17) - fixpoint_mul(stru_5C6E00->Cos(angle), v19); - else - v11 = fixpoint_mul(stru_5C6E00->Cos(angle), v19) + fixpoint_mul(stru_5C6E00->Sin(angle), v17); - v12 = v11 >> 16; - if ( v9 <= pODMRenderParams->shading_dist_mist + 2048 ) - { - //if ( abs(v12) > *(int *)((char *)&pOutdoor->pBModels->sBoundingRadius + v10) + 512 ) - if ( abs(v12) > pOutdoor->pBModels[uModelID].sBoundingRadius + 512 ) - { - result = v12 < 0; - LOBYTE(result) = v12 >= 0; - return result; - } - else - return true; - } - return false; -} - -//----- (00479295) -------------------------------------------------------- -int Polygon::_479295() -{ - int v3; // ecx@4 - int v4; // eax@4 - int v5; // edx@4 -// int v6; // ST14_4@5 - Vec3_int_ thisa; // [sp+Ch] [bp-10h]@8 - int v11; // [sp+18h] [bp-4h]@4 - - if ( !this->pODMFace->pFacePlane.vNormal.z ) - { - v3 = this->pODMFace->pFacePlane.vNormal.x; - v4 = -this->pODMFace->pFacePlane.vNormal.y; - v5 = 0; - v11 = 65536; - } - else if ( (this->pODMFace->pFacePlane.vNormal.x || this->pODMFace->pFacePlane.vNormal.y) - && abs(this->pODMFace->pFacePlane.vNormal.z) < 59082 ) - { - thisa.x = -this->pODMFace->pFacePlane.vNormal.y; - thisa.y = this->pODMFace->pFacePlane.vNormal.x; - thisa.z = 0; - thisa.Normalize_float(); - v4 = thisa.x; - v3 = thisa.y; - v5 = 0; - v11 = 65536; - } - else - { - v3 = 0; - v4 = 65536; - v11 = 0; - v5 = -65536; - } - sTextureDeltaU = this->pODMFace->sTextureDeltaU; - sTextureDeltaV = this->pODMFace->sTextureDeltaV; - ptr_38->_48616B_frustum_odm(v4, v3, 0, 0, v5, v11); - return 1; -} - - -unsigned short *LoadTgaTexture(const wchar_t *filename, int *out_width = nullptr, int *out_height = nullptr) -{ - #pragma pack(push, 1) - struct TGAHeader - { - unsigned char tgaSkip; - unsigned char colourmaptype; // type of colour map 0=none, 1=has palette - unsigned char tgaType; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed - - short colourmapstart; // first colour map entry in palette - short colourmaplength; // number of colours in palette - char colourmapbits; // number of bits per palette entry 15,16,24,32 - - //unsigned char tgaDontCare2[9]; - short xstart; // image x origin - short ystart; // image y origin - - unsigned short tgaWidth; - unsigned short tgaHeight; - unsigned char tgaBPP; - - char descriptor; // image descriptor bits: 00vhaaaa - // h horizontal flip - // v vertical flip - // a alpha bits - }; - #pragma pack(pop) - - if (out_width) - *out_width = 0; - if (out_height) - *out_height = 0; - - DWORD w; - void* file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); - if (file == INVALID_HANDLE_VALUE) - return nullptr; - - TGAHeader header; - ReadFile(file, &header, sizeof(header), &w, nullptr); - SetFilePointer(file, header.tgaSkip, nullptr, FILE_CURRENT); - - if (header.tgaBPP != 24 || header.tgaType != 2) - { - CloseHandle(file); - return nullptr; - } - - int imgSize = header.tgaWidth * header.tgaHeight * 3; - unsigned char* pixels = new unsigned char[imgSize]; - ReadFile(file, pixels, imgSize, &w, nullptr); - CloseHandle(file); - - if (w != imgSize) - { - delete [] pixels; - return nullptr; - } - - if (out_width) - *out_width = header.tgaWidth; - if (out_height) - *out_height = header.tgaHeight; - - unsigned short* pixels_16bit = new unsigned short[imgSize / 3]; - for (int i = 0; i < imgSize / 3; ++i) - { - pixels_16bit[i] = (pixels[i * 3] / 8 & 0x1F) | - ((pixels[i * 3 + 1] / 4 & 0x3F) << 5) | - ((pixels[i * 3 + 2] / 8 & 0x1F) << 11); - } - delete [] pixels; - return pixels_16bit; -} - -unsigned short *skybox_xn, *skybox_xp, - *skybox_yn, *skybox_yp, - *skybox_zn, *skybox_zp; -int skybox_width, skybox_height; - -IDirect3DTexture2 *skybox_texture; -IDirectDrawSurface4 *skybox_surface; - -bool Skybox_Initialize(const wchar_t *skybox_name) -{ - wchar_t xn_filename[1024], xp_filename[1024], - yn_filename[1024], yp_filename[1024], - zn_filename[1024], zp_filename[1024]; - swprintf(xn_filename, wcslen(L"%s_xn.tga"), L"%s_xn.tga", skybox_name); swprintf(xp_filename, wcslen(L"%s_xp.tga"), L"%s_xp.tga", skybox_name); - swprintf(yn_filename, wcslen(L"%s_yn.tga"), L"%s_yn.tga", skybox_name); swprintf(yp_filename, wcslen(L"%s_yp.tga"), L"%s_yp.tga", skybox_name); - swprintf(zn_filename, wcslen(L"%s_zn.tga"), L"%s_zn.tga", skybox_name); swprintf(zp_filename, wcslen(L"%s_zp.tga"), L"%s_zp.tga", skybox_name); - - int xn_width, xn_height; - skybox_xn = LoadTgaTexture(xn_filename, &xn_width, &xn_height); - if (!skybox_xn) - return false; - - int xp_width, xp_height; - skybox_xp = LoadTgaTexture(xp_filename, &xp_width, &xp_height); - if (!skybox_xp || xp_width != xn_width || xp_height != xn_height) - { - delete [] skybox_xn; - delete [] skybox_xp; - return false; - } - - int yn_width, yn_height; - skybox_yn = LoadTgaTexture(yn_filename, &yn_width, &yn_height); - if (!skybox_yn || yn_width != xn_width || yn_height != xn_height) - { - delete [] skybox_xn; - delete [] skybox_xp; - delete [] skybox_yn; - return false; - } - - int yp_width, yp_height; - skybox_yp = LoadTgaTexture(yp_filename, &yp_width, &yp_height); - if (!skybox_yp || yp_width != xn_width || yp_height != xn_height) - { - delete [] skybox_xn; - delete [] skybox_xp; - delete [] skybox_yn; - delete [] skybox_yp; - return false; - } - - int zn_width, zn_height; - skybox_zn = LoadTgaTexture(zn_filename, &zn_width, &zn_height); - if (!skybox_zn || zn_width != xn_width || zn_height != xn_height) - { - delete [] skybox_xn; - delete [] skybox_xp; - delete [] skybox_yn; - delete [] skybox_yp; - delete [] skybox_zn; - return false; - } - - int zp_width, zp_height; - skybox_zp = LoadTgaTexture(zp_filename, &zp_width, &zp_height); - if (!skybox_zp || zp_width != xn_width || zp_height != xn_height) - { - delete [] skybox_xn; - delete [] skybox_xp; - delete [] skybox_yn; - delete [] skybox_yp; - delete [] skybox_zn; - delete [] skybox_zp; - return false; - } - - skybox_width = xn_width; - skybox_height = xn_height; - - __debugbreak(); - //if (!pRenderer->pRenderD3D->CreateTexture(skybox_width, skybox_height, &skybox_surface, &skybox_texture, - //false, false, pRenderer->uMinDeviceTextureDim)) - return false; - - return true; -} - -struct vector -{ - float x, y, z; -}; - -struct matrix -{ - float m[4][4]; -}; - -void VectorNormalize(vector *v) -{ - float invmag = 1.0f / sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); - v->x *= invmag; - v->y *= invmag; - v->z *= invmag; -} - -void MatrixRotationAxis(matrix *pout, CONST vector *pv, float angle) -{ - memset(pout, 0, sizeof(matrix)); - pout->m[3][0] = 0; - pout->m[3][1] = 0; - pout->m[3][2] = 0; - pout->m[3][3] = 1; - - vector v; - v.x = pv->x; v.y = pv->y; v.z = pv->z; - VectorNormalize(&v); - - pout->m[0][0] = (1.0f - cos(angle)) * v.x * v.x + cos(angle); - pout->m[1][0] = (1.0f - cos(angle)) * v.x * v.y - sin(angle) * v.z; - pout->m[2][0] = (1.0f - cos(angle)) * v.x * v.z + sin(angle) * v.y; - pout->m[0][1] = (1.0f - cos(angle)) * v.y * v.x + sin(angle) * v.z; - pout->m[1][1] = (1.0f - cos(angle)) * v.y * v.y + cos(angle); - pout->m[2][1] = (1.0f - cos(angle)) * v.y * v.z - sin(angle) * v.x; - pout->m[0][2] = (1.0f - cos(angle)) * v.z * v.x - sin(angle) * v.y; - pout->m[1][2] = (1.0f - cos(angle)) * v.z * v.y + sin(angle) * v.x; - pout->m[2][2] = (1.0f - cos(angle)) * v.z * v.z + cos(angle); -} - -void VectorTransform(const matrix *m, const vector *v, vector *out) -{ - out->x = m->m[0][0] * v->x + m->m[1][0] * v->y + m->m[2][0] * v->z + m->m[3][0]; - out->y = m->m[0][1] * v->x + m->m[1][1] * v->y + m->m[2][1] * v->z + m->m[3][1]; - out->z = m->m[0][2] * v->x + m->m[1][2] * v->y + m->m[2][2] * v->z + m->m[3][2]; -} - -bool DrawSkyD3D_Skybox() -{ - static bool initialized = false, - initialization_failed = false; - if (initialization_failed) - return false; - - static int last_camera_rot_y, - last_camera_rot_x; - if (!initialized) - { - if (!Skybox_Initialize(L"data/skybox/stars")) - { - initialization_failed = true; - return false; - } - initialized = true; - - last_camera_rot_y = pParty->sRotationY + 1; // force update for the first run - last_camera_rot_x = pParty->sRotationX + 1; - } - - /* - r(y) = -cos y 0 sin y 0 -0 1 0 0 --sin y 0 cos y 0 -0 0 0 1 - -x cos y - z sin y -y -x sin y + z cos y -1 - - - -r(x) = // should be r(right) actually -1 0 0 0 -0 cos x -sin x 0 -0 sin x cos x 0 -0 0 0 1 - - -x -y cos x + z sin x --y sin x + z cos x -1 - - */ - - if (last_camera_rot_y == pParty->sRotationY && - last_camera_rot_x == pParty->sRotationX) - { -draw: - struct RenderVertexD3D3 v[6]; - - v[0].pos.x = pViewport->uScreen_TL_X; - v[0].pos.y = pViewport->uScreen_TL_Y; - v[0].pos.z = 0.99989998; - v[0].rhw = 1; - v[0].diffuse = -1; - v[0].specular = 0; - v[0].texcoord.x = 0; - v[0].texcoord.y = 0; - - v[1].pos.x = pViewport->uScreen_TL_X + pViewport->uScreenWidth; - v[1].pos.y = pViewport->uScreen_TL_Y + pViewport->uScreenHeight; - v[1].pos.z = 0.99989998; - v[1].rhw = 1; - v[1].diffuse = -1; - v[1].specular = 0; - v[1].texcoord.x = (float)pViewport->uScreenWidth / skybox_width; - v[1].texcoord.y = (float)pViewport->uScreenHeight / skybox_height; - - v[2].pos.x = pViewport->uScreen_TL_X + pViewport->uScreenWidth; - v[2].pos.y = pViewport->uScreen_TL_Y; - v[2].pos.z = 0.99989998; - v[2].rhw = 1; - v[2].diffuse = -1; - v[2].specular = 0; - v[2].texcoord.x = (float)pViewport->uScreenWidth / skybox_width; - v[2].texcoord.y = 0; - - memcpy(&v[3], &v[0], sizeof(*v)); - - v[4].pos.x = pViewport->uScreen_TL_X; - v[4].pos.y = pViewport->uScreen_TL_Y + pViewport->uScreenHeight; - v[4].pos.z = 0.99989998; - v[4].rhw = 1; - v[4].diffuse = -1; - v[4].specular = 0; - v[4].texcoord.x = 0; - v[4].texcoord.y = (float)pViewport->uScreenHeight / skybox_height; - - memcpy(&v[5], &v[1], sizeof(*v)); - - __debugbreak(); - /* - pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); - pRenderer->pRenderD3D->pDevice->SetTexture(0, skybox_texture); - pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v, 6, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTLIGHT); -*/ - return true; - } - - - DDSURFACEDESC2 desc; - desc.dwSize = sizeof(desc); - if (!pRenderer->LockSurface_DDraw4(skybox_surface, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY)) - return false; - - last_camera_rot_y = pParty->sRotationY; - last_camera_rot_x = pParty->sRotationX; - - float aspect = (float)pViewport->uScreenWidth / (float)pViewport->uScreenHeight; - float fov_x = 3.141592f * (pODMRenderParams->uCameraFovInDegrees + 0) / 360.0f; - float fov_y = fov_x / aspect; - - float ray_dx = fov_x / (float)pViewport->uScreenWidth, - ray_dy = fov_y / (float)pViewport->uScreenHeight; - float party_angle_x = 2 * 3.141592653589 * pParty->sRotationX / 2048.0, - party_angle_y = 2 * 3.141592653589 * pParty->sRotationY / 2048.0; - for (int y = 0; y < pViewport->uScreenHeight; ++y) - for (int x = 0; x < pViewport->uScreenWidth; ++x) - { - float angle_x = party_angle_x - (y - pViewport->uScreenHeight / 2) * ray_dy; - float angle_y = party_angle_y - (x - pViewport->uScreenWidth / 2) * ray_dx; - - float _dir_x_ = 1, - _dir_y_ = 0, - _dir_z_ = 0; - - float dir_x_ = _dir_x_ * cosf(angle_y);// - _dir_z_ * sinf(angle_y); // rotation around y - //float dir_y_ = _dir_y_; - float dir_z_ = _dir_x_ * sinf(angle_y);// + _dir_z_ * cosf(angle_y); - - //float dir_x = dir_x_; // rotation around x - //float dir_y = /*dir_y_ * cosf(angle_x)*/ + dir_z_ * sinf(angle_x); - //float dir_z = /*-dir_y_ * sinf(angle_x)*/ + dir_z_ * cosf(angle_x); - - vector right; // rotate around right actually to avoid space distortion - right.x = /*dir_y * 0*/ - dir_z_ * 1; - right.y = /*dir_z_ * 0 - dir_x_ * */0; - right.z = dir_x_ * 1/* - dir_y_ * 0*/; - //VectorNormalize(&right); - - matrix rightMatrix; - MatrixRotationAxis(&rightMatrix, &right, angle_x); - - vector v1, v2; - v1.x = dir_x_; v1.y = 0; v1.z = dir_z_; - VectorTransform(&rightMatrix, &v1, &v2); - - float dir_x = v2.x, - dir_y = v2.y, - dir_z = v2.z; - - float abs_dir_x = fabsf(dir_x), - abs_dir_y = fabsf(dir_y), - abs_dir_z = fabsf(dir_z); - - unsigned short color = (0x1F << 11) | (0x1F << 5) | (5); //default to orange - if (abs_dir_x >= abs_dir_y) - { - if (abs_dir_x >= abs_dir_z) - { - if (dir_x >= 0) - { - float instersect_y = dir_y / (2.0f * dir_x); // plane equation for this side is x + 0.5 = 0 - float instersect_z = dir_z / (2.0f * dir_x); - - float u = 1.0f - (instersect_z + 0.5f), - v = 1.0f - (instersect_y + 0.5f); - - int tx = u * (skybox_width - 1), - ty = v * (skybox_height - 1); - - color = skybox_xp[ty * skybox_width + tx]; - //color = ty * 0x1F / skybox_height; - } - else - { - float instersect_y = dir_y / (2.0f * dir_x); - float instersect_z = dir_z / (2.0f * dir_x); - - float u = 1.0f - (instersect_z + 0.5f), - v = instersect_y + 0.5f; - - int tx = u * (skybox_width - 1), - ty = v * (skybox_height - 1); - - color = skybox_xn[ty * skybox_width + tx]; - //color = tx * 0x1F / skybox_height; - } - } - else if (dir_z >= 0) - goto DIR_ZP; - else - goto DIR_ZN; - } - else if (abs_dir_y >= abs_dir_z) - { - if (dir_y >= 0) - { - float instersect_x = dir_x / (2.0f * dir_y); - float instersect_z = dir_z / (2.0f * dir_y); - - float u = instersect_x + 0.5f, - v = instersect_z + 0.5f; - - int tx = u * (skybox_width - 1), - ty = v * (skybox_height - 1); - - color = skybox_yp[ty * skybox_width + tx]; - //color = tx * 0x1F / skybox_height; - } - /*else should never be seen i guess - { - __debugbreak(); - // -y - //Log::Warning(L"(%03u, %03u): -y", x, y); - }*/ - } - else if (dir_z >= 0) - { -DIR_ZP: - // +z - float instersect_x = dir_x / (2.0f * dir_z); - float instersect_y = dir_y / (2.0f * dir_z); - //float intersect_z = 0.5f; - - float u = instersect_x + 0.5f, - v = -instersect_y + 0.5f; - - int tx = u * (skybox_width - 1), - ty = v * (skybox_height - 1); - - color = skybox_zp[ty * skybox_width + tx]; - } - else - { -DIR_ZN: - // -z - float instersect_x = -dir_x / (2.0f * dir_z); - float instersect_y = -dir_y / (2.0f * dir_z); - //float intersect_z = -0.5f; - - float u = 1.0f - instersect_x - 0.5f, - v = -instersect_y + 0.5f; - - int tx = u * (skybox_width - 1), - ty = v * (skybox_height - 1); - - color = skybox_zn[ty * skybox_width + tx]; - } - - //pRenderer->pTargetSurface[(pViewport->uScreenY + y) * pRenderer->uTargetSurfacePitch + pViewport->uScreenX + x] = color; - ((unsigned __int16 *)((char *)desc.lpSurface + y * desc.lPitch))[x] = color; - } - - ErrD3D((skybox_surface)->Unlock(0)); - goto draw; -} -//----- (0047A384) -------------------------------------------------------- -void ODM_LoadAndInitialize(const char *pLevelFilename, ODMRenderParams *thisa) -{ - int v2; // ebx@3 - unsigned int v3; // eax@3 - MapInfo *v4; // edi@4 - //int v5; // eax@8 - //SpawnPointMM7 *v6; // edx@14 - size_t v7; // eax@19 - //char *v8; // eax@19 - //char *v9; // eax@21 - char Source[120]; // [sp+Ch] [bp-84h]@19 - const char *pFilename; // [sp+84h] [bp-Ch]@1 - //unsigned int v12; // [sp+88h] [bp-8h]@12 - //int v13; // [sp+8Ch] [bp-4h]@11 - int v; - - pFilename = pLevelFilename; - //thisa->AllocSoftwareDrawBuffers(); - pODMRenderParams->Initialize(); - pWeather->bRenderSnow = false; - pRenderer->ClearZBuffer(0, 479); - //thisa = (ODMRenderParams *)1; - GetAlertStatus(); - if ( _A750D8_player_speech_timer ) - _A750D8_player_speech_timer = 0; - v2 = pMapStats->GetMapInfo(pCurrentMapName); - v3 = 0; - if ( v2 ) - { - v4 = &pMapStats->pInfos[v2]; - v3 = v4->uRespawnIntervalDays; - } - else - v4 = (MapInfo *)1; - day_attrib &= ~DAY_ATTRIB_FOG; - dword_6BE13C_uCurrentlyLoadedLocationID = v2; - pOutdoor->Initialize( - pFilename, - (unsigned int)(signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) / 0x3C / 0x3C / 0x18 + 1, - v3, - &v); - if ( !(dword_6BE364_game_settings_1 & GAME_SETTINGS_2000) ) - { - Actor::InitializeActors(); - SpriteObject::InitializeSpriteObjects(); - } - dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_2000; - //v5 = 0; - if ( !v2 ) - v = 0; - if ( v == 1 ) - { - //v13 = 0; - for (uint i = 0; i < pOutdoor->uNumSpawnPoints; ++i) - { - //v12 = 0; - //while ( 1 ) - //{ - SpawnPointMM7* spawn = pOutdoor->pSpawnPoints + i; - //v6 = &pOutdoor->pSpawnPoints[v12 / 0x18]; - if (spawn->uKind == 3 ) - SpawnEncounter(v4, spawn, 0, 0, 0); - else - v4->SpawnRandomTreasure(spawn); - //++v13; - //v12 += 24; - //if ( v13 >= (signed int)pOutdoor->uNumSpawnPoints ) - // break; - //v5 = 0; - //} - } - RespawnGlobalDecorations(); - } - pOutdoor->PrepareDecorations(); - pOutdoor->ArrangeSpriteObjects(); - pOutdoor->InitalizeActors(v2); - pOutdoor->MessWithLUN(); - v7 = strlen("levels\\"); - strcpy(Source, &pFilename[v7]); - strcpy(pOutdoor->pLevelFilename, Source); - pWeather->Initialize(); - pGame->pIndoorCameraD3D->sRotationY = pParty->sRotationY; - pGame->pIndoorCameraD3D->sRotationX = pParty->sRotationX; - //pODMRenderParams->RotationToInts(); - pOutdoor->UpdateSunlightVectors(); - - float fov_rad; - float fov_rad_inv; - //----- (0042394D) -------------------------------------------------------- - //void IndoorCamera::Initialize(int degFov, unsigned int uViewportWidth, unsigned int uViewportHeight) - { - //pIndoorCamera->Initialize(65, viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1, - // viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y + 1); - - int uViewportWidth = viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1; - - extern float _calc_fov(int viewport_width, int angle_degree); - fov_rad = _calc_fov(uViewportWidth, 65); - fov_rad_inv = 65536.0 / fov_rad; - } - pODMRenderParams->int_fov_rad = (signed __int64)fov_rad; - pODMRenderParams->int_fov_rad_inv = (signed __int64)fov_rad_inv; - - for (int i = 0; i < 20000; ++i) - { - array_77EC08[i].ptr_38 = &stru_8019C8; - - array_77EC08[i].ptr_48 = nullptr; - } - - MM7Initialization(); -} - -//----- (0047C370) -------------------------------------------------------- -unsigned int GetLevelFogColor() -{ - signed __int64 v1; // qax@5 - int v2; // eax@6 - - if (bUnderwater) - return 0xFF258F5C; - - if (day_attrib & DAY_ATTRIB_FOG) - { - if ( pWeather->bNight ) // night-time fog - { - __debugbreak(); // decompilation can be inaccurate, please send savegame to Nomad - v2 = -(pWeather->bNight != 1); - return (v2 & 0xE0E0E1) - 0xE0E0E1; - } - else - { - v1 = (signed __int64)((1.0 - pOutdoor->fFogDensity) * 200.0 + pOutdoor->fFogDensity * 31.0); - return v1 | (((unsigned int)v1 | (((unsigned int)v1 | 0xFFFFFF00) << 8)) << 8); - } - } - - return 0; -} - -//----- (0047C3D7) -------------------------------------------------------- -int __fastcall sub_47C3D7_get_fog_specular(int a1, int a2, float a3) -{ - int v3; // ecx@1 - signed int v7; // ecx@11 - - v3 = pWeather->bNight; - if ( bUnderwater == 1 ) - v3 = 0; - if ( pParty->armageddon_timer || !(day_attrib & DAY_ATTRIB_FOG) && !bUnderwater ) - return 0xFF000000; - if ( v3 ) - { - if ( a3 < (double)day_fogrange_1 ) - { - v7 = 0; - if ( a3 == 0.0 ) - v7 = 216; - if ( a2 ) - v7 = 248; - return (-1 - v7) << 24; - } - else - { - if ( a3 > (double)day_fogrange_2 ) - { - v7 = 216; - if ( a3 == 0.0 ) - v7 = 216; - if ( a2 ) - v7 = 248; - return (-1 - v7) << 24; - } - v7 = (signed __int64)((a3 - (double)day_fogrange_1) / ((double)day_fogrange_2 - (double)day_fogrange_1) * 216.0); - } - } - else - { - if ( a3 < (double)day_fogrange_1 ) - { - v7 = 0; - if ( a3 == 0.0 ) - v7 = 216; - if ( a2 ) - v7 = 248; - return (-1 - v7) << 24; - } - else - { - if ( a3 > (double)day_fogrange_2 ) - { - v7 = 216; - if ( a3 == 0.0 ) - v7 = 216; - if ( a2 ) - v7 = 248; - return (-1 - v7) << 24; - } - else - v7 = floorf(((a3 - (double)day_fogrange_1) * 216.0 / ((double)day_fogrange_2 - (double)day_fogrange_1)) + 0.5f); - } - } - if ( v7 > 216 ) - v7 = 216; - else - { - if ( a3 == 0.0 ) - v7 = 216; - } - if ( a2 ) - v7 = 248; - return (-1 - v7) << 24; -} - -//----- (0047C4FC) -------------------------------------------------------- -int __fastcall GetActorTintColor(int max_dimm, int min_dimm, float distance, int a4, RenderBillboard *a5) -{ - //int v5; // esi@1 - signed int v6; // edx@1 - //signed int result; // eax@2 - int v8; // eax@3 - double v9; // st7@12 - //double v10; // ST0C_8@18 - int v11; // ecx@28 - //signed int v12; // edi@28 - //double v13; // ST0C_8@33 - //double v14; // ST0C_8@34 - double v15; // st7@44 - //double v16; // ST0C_8@44 - //double v17; // ST0C_8@44 - int v18; // ST14_4@44 - //double v19; // ST0C_8@44 - signed int v20; // [sp+10h] [bp-4h]@10 -// float a3a; // [sp+1Ch] [bp+8h]@33 - //float a3b; // [sp+1Ch] [bp+8h]@34 - float a3c; // [sp+1Ch] [bp+8h]@44 - //float a3d; // [sp+1Ch] [bp+8h]@44 - //float a4b; // [sp+20h] [bp+Ch]@18 - //int a4a; // [sp+20h] [bp+Ch]@33 - //float a4c; // [sp+20h] [bp+Ch]@44 - //float a4d; // [sp+20h] [bp+Ch]@44 - int a5a; // [sp+24h] [bp+10h]@44 - - //v5 = a2; - v6 = 0; - - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - return 8 * (31 - max_dimm) | ((8 * (31 - max_dimm) | ((31 - max_dimm) << 11)) << 8); - - if (pParty->armageddon_timer) - return 0xFFFF0000; - - v8 = pWeather->bNight; - if (bUnderwater) - v8 = 0; - if ( v8 ) - { - v20 = 1; - if ( (signed __int64)pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uExpireTime > 0 ) - v20 = pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uPower; - v9 = (double)v20 * 1024.0; - if ( a4 ) - { - v6 = 216; - goto LABEL_20; - } - if ( distance <= v9 ) - { - if ( distance > 0.0 ) - { - //a4b = distance * 216.0 / v9; - //v10 = a4b + 6.7553994e15; - //v6 = LODWORD(v10); - v6 = floorf(0.5f + distance * 216.0 / v9); - if (v6 > 216 ) - { - v6 = 216; - goto LABEL_20; - } - } - } - else - { - v6 = 216; - } - if ( distance != 0.0 ) - { -LABEL_20: - if ( a5 ) - v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3); - if ( v6 > 216 ) - v6 = 216; - return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8); - } -//LABEL_19: - v6 = 216; - goto LABEL_20; - } - - - - if (fabsf(distance) < 1.0e-6f) - return 0xFFF8F8F8; - - // dim in measured in 8-steps - v11 = 8 * (max_dimm - min_dimm); - //v12 = v11; - if ( v11 >= 0 ) - { - if ( v11 > 216 ) - v11 = 216; - } - else - v11 = 0; - - float fog_density_mult = 216.0f; - if (a4) - fog_density_mult += distance / (double)pODMRenderParams->shading_dist_shade * 32.0; - - v6 = v11 + floorf(pOutdoor->fFogDensity * fog_density_mult + 0.5f); - /*if ( a4 ) - { - //a3b = pOutdoor->fFogDensity * 216.0; - //v14 = a3b + 6.7553994e15; - //a4a = floorf(a3b + 0.5f);//LODWORD(v14); - } - else - { - //a3a = (distance / (double)pODMRenderParams->shading_dist_shade * 32.0 + 216.0) * pOutdoor->fFogDensity; - //v13 = a3a + 6.7553994e15; - //a4a = floorf(a3a + 0.5f);//LODWORD(v13); - } - v6 = a4a + v11;*/ - if ( a5 ) - v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3); - if ( v6 > 216 ) - v6 = 216; - if ( v6 < v11 ) - v6 = v11; - if ( v6 > 8 * pOutdoor->max_terrain_dimming_level ) - v6 = 8 * pOutdoor->max_terrain_dimming_level; - if ( !bUnderwater ) - return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8); - else - { - v15 = (double)(255 - v6) * 0.0039215689; - a3c = v15; - //a4c = v15 * 16.0; - //v16 = a4c + 6.7553994e15; - a5a = floorf(v15 * 16.0 + 0.5f);//LODWORD(v16); - //a4d = a3c * 194.0; - //v17 = a4d + 6.7553994e15; - v18 = floorf(a3c * 194.0 + 0.5f);//LODWORD(v17); - //a3d = a3c * 153.0; - //v19 = a3d + 6.7553994e15; - return (int)floorf(a3c * 153.0 + 0.5f)/*LODWORD(v19)*/ | ((v18 | (a5a << 8)) << 8); - } -} -// 6BE3C4: using guessed type char bUnderwater; - -//----- (0047F44B) -------------------------------------------------------- -unsigned int WorldPosToGridCellX(int sWorldPosX) -{ - return (sWorldPosX >> 9) + 64; // sar is in original exe, resulting -880 / 512 = -1 - // and -880 sar 9 = -2 -} - -//----- (0047F458) -------------------------------------------------------- -unsigned int WorldPosToGridCellZ(int sWorldPosZ) -{ - return 64 - (sWorldPosZ >> 9); // sar is in original exe, resulting -880 / 512 = -1 - // and -880 sar 9 = -2 -} - -//----- (0047F469) -------------------------------------------------------- -int GridCellToWorldPosX(int a1) -{ - return (a1 - 64) << 9; -} - -//----- (0047F476) -------------------------------------------------------- -int GridCellToWorldPosZ(int a1) -{ - return (64 - a1) << 9; -} - - - -//----- (00481ED9) -------------------------------------------------------- -void sub_481ED9_MessWithODMRenderParams() -{ - stru_8019C8._48616B_frustum_odm(65536, 0, 0, 0, 65536, 0); - pODMRenderParams->uNumPolygons = 0; - //pODMRenderParams->uNumEdges = 0; - //pODMRenderParams->uNumSpans = 0; - //pODMRenderParams->uNumSurfs = 0; - pODMRenderParams->uNumBillboards = 0; - pODMRenderParams->field_44 = 0; -} - -//----- (004823F4) -------------------------------------------------------- -bool IsTerrainSlopeTooHigh(int pos_x, int pos_z) -{ - //unsigned int v2; // ebx@1 - //unsigned int v3; // edi@1 - //int v4; // eax@1 - //int v6; // esi@5 - //int v7; // ecx@6 - //int v8; // edx@6 - //int v9; // eax@6 - //int y_min; // esi@10 - //int v11; // [sp+14h] [bp-8h]@1 - //int v12; // [sp+18h] [bp-4h]@1 - - //v12 = a1; - //v11 = a2; - unsigned int grid_x = WorldPosToGridCellX(pos_x); - unsigned int grid_z = WorldPosToGridCellZ(pos_z) - 1; - - int party_grid_x1 = GridCellToWorldPosX(grid_x); - //dword_76D56C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1); - //dword_76D570_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1); - //dword_76D574_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x); - int party_grid_z1 = GridCellToWorldPosZ(grid_z); - //dword_76D55C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z); - //dword_76D560_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1); - //dword_76D564_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1); - int party_x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z); - int party_x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z); - int party_x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1); - int party_x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); - //dword_76D554_terrain_cell_world_pos_around_party_y = v4; - if (party_x1z1_y == party_x2z1_y && - party_x2z1_y == party_x2z2_y && - party_x2z2_y == party_x1z2_y ) - return false; - - int dx = abs(pos_x - party_grid_x1), - dz = abs(party_grid_z1 - pos_z); - - int y1, y2, y3; - if (dz >= dx) - { - y1 = party_x1z2_y; // lower-left triangle - y2 = party_x2z2_y; // y3 | \ - y3 = party_x1z1_y; // | \ - /* | \ - |______ \ - y1 y2 */ - } - else - { - y1 = party_x2z1_y; // upper-right - y2 = party_x1z1_y; // y2_______ y1 - y3 = party_x2z2_y; // \ | - /* \ | - \ | - y3 */ - } - - int y_min = min(y1, min(y2, y3));// не верно при подъёме на склон - int y_max = max(y1, max(y2, y3)); - return (y_max - y_min) > 512; -} - -//----- (0048257A) -------------------------------------------------------- -int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *pIsOnWater, int bFloatAboveWater) -{ -// int result; // eax@9 - int v8; // ebx@11 - int v9; // eax@11 - int v10; // ecx@11 - int v13; // [sp+10h] [bp-8h]@11 - signed int v14; // [sp+14h] [bp-4h]@3 - int v15; // [sp+24h] [bp+Ch]@11 - - unsigned int grid_x = WorldPosToGridCellX(a1); - unsigned int grid_z = WorldPosToGridCellZ(a2) - 1; - - int grid_x1 = GridCellToWorldPosX(grid_x), - grid_x2 = GridCellToWorldPosX(grid_x + 1); - int grid_z1 = GridCellToWorldPosZ(grid_z), - grid_z2 = GridCellToWorldPosZ(grid_z + 1); - - int y_x1z1 = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z), - y_x2z1 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z), - y_x2z2 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1), - y_x1z2 = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); - //v4 = WorldPosToGridCellX(a1); - //v5 = WorldPosToGridCellZ(v12) - 1; - //dword_76D538_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4); - //dword_76D53C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1); - //dword_76D540_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1); - //dword_76D544_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4); - //dword_76D528_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5); - //dword_76D52C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5); - //dword_76D530_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1); - //dword_76D534_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1); - //dword_76D518_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5); - //dword_76D51C_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5); - //dword_76D520_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5 + 1); - //dword_76D524_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5 + 1); - *pIsOnWater = false; - if ( pOutdoor->ActuallyGetSomeOtherTileInfo(grid_x, grid_z) & 2 ) - *pIsOnWater = true; - v14 = 0; - if ( !bFloatAboveWater && *pIsOnWater ) - v14 = -60; - if ( y_x1z1 != y_x2z1 || - y_x2z1 != y_x2z2 || - y_x2z2 != y_x1z2 ) - { - if ( abs(grid_z1 - a2) >= abs(a1 - grid_x1) ) - { - v8 = y_x1z2; - v9 = y_x2z2; - v10 = y_x1z1; - v15 = a1 - grid_x1; - v13 = a2 - grid_z2; - } - else - { - v8 = y_x2z1; - v9 = y_x1z1; - v10 = y_x2z2; - v15 = grid_x2 - a1; - v13 = grid_z1 - a2; - } - return v14 + v8 + fixpoint_mul(v13, (v10 - v8) * 128) + fixpoint_mul(v15, (v9 - v8) * 128); - } - else - return y_x1z1; -} - -//----- (00485F53) -------------------------------------------------------- -void sr_485F53(Vec2_int_ *v) -{ - ++v->y; - if ( v->y > 1000 ) - v->y = 0; -} - -//----- (0048607B) -------------------------------------------------------- -void Polygon::Create_48607B(stru149 *a2) -{ - this->pTexture = 0; - this->ptr_38 = a2; -} - -//----- (00486089) -------------------------------------------------------- -void Polygon::_normalize_v_18() -{ - //double v2; // st7@1 - //double v3; // st6@1 - //double v5; // st5@1 - - // v2 = (double)this->v_18.x; - //v3 = (double)this->v_18.y; - // v5 = (double)this->v_18.z; - float len = sqrt((double)this->v_18.z * (double)this->v_18.z + (double)this->v_18.y * (double)this->v_18.y + (double)this->v_18.x * (double)this->v_18.x); - if (fabsf(len) < 1e-6f) - { - v_18.x = 0; - v_18.y = 0; - v_18.z = 65536; - } - else - { - v_18.x = round_to_int((double)this->v_18.x / len * 65536.0); - v_18.y = round_to_int((double)this->v_18.y / len * 65536.0); - v_18.y = round_to_int((double)this->v_18.z / len * 65536.0); - } -} - -//----- (0048616B) -------------------------------------------------------- -void stru149::_48616B_frustum_odm(int a2, int a3, int a4, int a5, int a6, int a7) -{ - int v7; // ebx@1 - int v9; // edi@1 - int v11; // edx@1 - int v17; // ST0C_4@6 - int v19; // ST0C_4@9 - int v24; // [sp+14h] [bp-14h]@1 - int v25; // [sp+18h] [bp-10h]@1 - int v27; // [sp+24h] [bp-4h]@1 - - v25 = pGame->pIndoorCameraD3D->int_cosine_x; - v7 = pGame->pIndoorCameraD3D->int_sine_y; - v27 = pGame->pIndoorCameraD3D->int_sine_x; - //v8 = -pIndoorCamera->pos.y; - v9 = pGame->pIndoorCameraD3D->int_cosine_y; - //v26 = -pIndoorCamera->pos.z; - v11 = pGame->pIndoorCameraD3D->int_cosine_y * -pGame->pIndoorCameraD3D->vPartyPos.x + pGame->pIndoorCameraD3D->int_sine_y * -pGame->pIndoorCameraD3D->vPartyPos.y; - v24 = pGame->pIndoorCameraD3D->int_cosine_y * -pGame->pIndoorCameraD3D->vPartyPos.y - pGame->pIndoorCameraD3D->int_sine_y * -pGame->pIndoorCameraD3D->vPartyPos.x; - if (pGame->pIndoorCameraD3D->sRotationX) - { - this->field_0_party_dir_x = fixpoint_mul(v11, pGame->pIndoorCameraD3D->int_cosine_x) + - fixpoint_mul((-pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x); - this->field_4_party_dir_y = v24; - this->field_8_party_dir_z = fixpoint_mul((-pGame->pIndoorCameraD3D->vPartyPos.z) << 16, v25) - fixpoint_mul(v11, v27); - } - else - { - this->field_0_party_dir_x = v11; - this->field_4_party_dir_y = v24; - this->field_8_party_dir_z = (-pGame->pIndoorCameraD3D->vPartyPos.z) << 16; - } - - if (pGame->pIndoorCameraD3D->sRotationX) - { - v17 = fixpoint_mul(a2, v9) + fixpoint_mul(a3, v7); - - this->angle_from_north = fixpoint_mul(v17, v25) + fixpoint_mul(a4, v27); - this->angle_from_west = fixpoint_mul(a3, v9) - fixpoint_mul(a2, v7); - this->viewing_angle_from_west_east = fixpoint_mul(a4, v25) - fixpoint_mul(v17, v27); - } - else - { - this->angle_from_north = fixpoint_mul(a2, v9) + fixpoint_mul(a3, v7); - this->angle_from_west = fixpoint_mul(a3, v9) - fixpoint_mul(a2, v7); - this->viewing_angle_from_west_east = a4; - } - - if (pGame->pIndoorCameraD3D->sRotationX) - { - v19 = fixpoint_mul(a5, v9) + fixpoint_mul(a6, v7); - - this->angle_from_east = fixpoint_mul(v19, v25) + fixpoint_mul(a7, v27); - this->angle_from_south = fixpoint_mul(a6, v9) - fixpoint_mul(a5, v7); - this->viewing_angle_from_north_south = fixpoint_mul(a7, v25) - fixpoint_mul(v19, v27); - } - else - { - this->angle_from_east = fixpoint_mul(a5, v9) + fixpoint_mul(a6, v7); - this->angle_from_south = fixpoint_mul(a6, v9) - fixpoint_mul(a5, v7); - this->viewing_angle_from_north_south = a7; - } - - this->angle_from_east = -this->angle_from_east; - this->angle_from_south = -this->angle_from_south; - this->viewing_angle_from_north_south = -this->viewing_angle_from_north_south; - - this->field_24 = fixpoint_dot(this->angle_from_north, this->field_0_party_dir_x, - this->angle_from_west, this->field_4_party_dir_y, - this->viewing_angle_from_west_east, this->field_8_party_dir_z); - this->field_28 = fixpoint_dot(this->angle_from_east, this->field_0_party_dir_x, - this->angle_from_south, this->field_4_party_dir_y, - this->viewing_angle_from_north_south, this->field_8_party_dir_z); -} - -//----- (0048694B) -------------------------------------------------------- -void stru149::_48694B_frustum_sky() -{ - this->angle_from_east = -this->angle_from_east; - this->angle_from_south = -this->angle_from_south; - this->viewing_angle_from_north_south = -this->viewing_angle_from_north_south; - - this->field_24 = fixpoint_dot(this->angle_from_north, this->field_0_party_dir_x, - this->angle_from_west, this->field_4_party_dir_y, - this->viewing_angle_from_west_east, this->field_8_party_dir_z); - this->field_28 = fixpoint_dot(this->angle_from_east, this->field_0_party_dir_x, - this->angle_from_south, this->field_4_party_dir_y, - this->viewing_angle_from_north_south, this->field_8_party_dir_z); -} - - -//----- (00441A4E) -------------------------------------------------------- -__int16 __fastcall sub_441A4E(int a1)//for blessing -{ - __int16 result; // ax@1 - int v2; // ebx@1 -// char *v3; // esi@1 -// int v4; // edi@4 - bool v5; // ecx@4 - SpriteFrame *pFrame; // eax@6 - //SpriteFrame *v7; // edi@6 - int v8; // eax@6 -// unsigned __int16 v9; // ax@6 - RenderBillboardTransform_local0 v10; // [sp+Ch] [bp-5Ch]@1 - int v11; // [sp+5Ch] [bp-Ch]@6 - int v12; // [sp+60h] [bp-8h]@1 - //int v13; // [sp+64h] [bp-4h]@6 - - v10.sParentBillboardID = -1; - v10.pTarget = pRenderer->pTargetSurface; - v10.pTargetZ = pRenderer->pActiveZBuffer; - v10.uTargetPitch = pRenderer->GetRenderWidth(); - result = 0; - v2 = a1; - v10.uViewportX = 0; - v10.uViewportY = 0; - v10.uViewportZ = window->GetWidth() - 1; - v10.uViewportW = window->GetHeight() - 1; - v12 = 0; - //v3 = (char *)&pOtherOverlayList->pOverlays[0].field_C; - //do - for ( uint i = 0; i < 50; ++i ) - { - if ( pOtherOverlayList->pOverlays[i].field_6 > 0 ) - { - result = pOtherOverlayList->pOverlays[i].field_0; - if ( pOtherOverlayList->pOverlays[i].field_0 >= 300 ) - { - //v4 = result; - v5 = pOtherOverlayList->pOverlays[i].field_0 == v2 + 320 - || pOtherOverlayList->pOverlays[i].field_0 == v2 + 330 - || pOtherOverlayList->pOverlays[i].field_0 == v2 + 340 - || pOtherOverlayList->pOverlays[i].field_0 == v2 + 350; - pOtherOverlayList->pOverlays[i].field_0 = v2 + 310; - if ( pOtherOverlayList->pOverlays[i].field_0 == v2 + 310 || v5 ) - { - if ( !pOtherOverlayList->pOverlays[i].field_0 ) - { - pFrame = pSpriteFrameTable->GetFrame(pOverlayList->pOverlays[pOtherOverlayList->pOverlays[i].field_2].uSpriteFramesetID, - pOtherOverlayList->pOverlays[i].field_4); - //v7 = v6; - v11 = pOtherOverlayList->pOverlays[i].field_E; - //v13 = pFrame->scale; - //v13 = fixpoint_mul(v11, pFrame->scale); - v10.uScreenSpaceX = pOtherOverlayList->pOverlays[i].field_8; - v10.uScreenSpaceY = pOtherOverlayList->pOverlays[i].field_A; - v10._screenspace_x_scaler_packedfloat = fixpoint_mul(v11, pFrame->scale); - v10._screenspace_y_scaler_packedfloat = fixpoint_mul(v11, pFrame->scale); - v10.pPalette = PaletteManager::Get_Dark_or_Red_LUT(pFrame->uPaletteIndex, 0, 1); - v8 = pOtherOverlayList->pOverlays[i].field_2; - v10.sZValue = 0; - v10.uFlags = 0; - //v9 = pOverlayList->pOverlays[v8].uOverlayType; - if ( !pOverlayList->pOverlays[v8].uOverlayType || pOverlayList->pOverlays[v8].uOverlayType == 2 ) - v10.uScreenSpaceY += pSprites_LOD->pSpriteHeaders[pFrame->pHwSpriteIDs[0]].uHeight / 2; - result = pSprites_LOD->pSpriteHeaders[pFrame->pHwSpriteIDs[0]]._4AD2D1(&v10, 0); - ++v12; - if ( v12 == 5 ) - break; - } - } - } - } - //v3 += 20; - } - //while ( (signed int)v3 < (signed int)&pOverlayList->pOverlays ); - return result; -} - - -//----- (00443E31) -------------------------------------------------------- -void LoadLevel_InitializeLevelStr() - { - -// char Args[100]; - int string_num; - int max_string_length; -// int current_string_length; - int prev_string_offset; - - if (sizeof(pLevelStrOffsets) != 2000) - Log::Warning(L"pLevelStrOffsets: deserialization warning"); - memset(pLevelStrOffsets.data(), 0, 2000); - - max_string_length = 0; - string_num = 1; - prev_string_offset = 0; - pLevelStrOffsets[0]=0; - for (uint i = 0; i < uLevelStrFileSize; ++i) - { - if ( !pLevelStr[i] ) - { - pLevelStrOffsets[string_num] = i + 1; - ++string_num; - if ( i - prev_string_offset > max_string_length ) - max_string_length = i - prev_string_offset; - prev_string_offset = i; - } - } - - uLevelStrNumStrings = string_num - 1; - if ( max_string_length > 800 ) - Error("MAX_EVENT_TEXT_LENGTH needs to be increased to %lu", max_string_length+1); - - if ( uLevelStrNumStrings > 0 ) - { - for(uint i = 0; i 0 ) - { - for (uint i = 0; i < uLevelEVT_NumEvents; ++i) - { - test_event=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[i].uEventOffsetInEVT]; - if ( test_event->_e_type == EVENT_OnMapLeave ) - { - EventProcessor(pLevelEVT_Index[i].uEventID, 0, 1, pLevelEVT_Index[i].event_sequence_num); - } - } - } -} - -//----- (00443FDC) -------------------------------------------------------- -void OnMapLoad() -{ - int v6; // eax@9 - unsigned __int64 v8; // qax@26 - int hours; // ebx@26 - unsigned __int64 v18; // [sp+Ch] [bp-44h]@12 - unsigned int seconds; // [sp+14h] [bp-3Ch]@26 - unsigned __int64 v20; // [sp+1Ch] [bp-34h]@7 - unsigned int minutes; // [sp+2Ch] [bp-24h]@26 - unsigned int years; // [sp+34h] [bp-1Ch]@26 - unsigned int weeks; // [sp+38h] [bp-18h]@26 - int v26; // [sp+3Ch] [bp-14h]@15 - unsigned int days; // [sp+3Ch] [bp-14h]@26 - unsigned int months; // [sp+40h] [bp-10h]@26 - - for (uint i = 0; i < uLevelEVT_NumEvents; ++i) - { - EventIndex pEvent = pLevelEVT_Index[i]; - - _evt_raw* _evt = (_evt_raw *)(&pLevelEVT[pEvent.uEventOffsetInEVT]); - - if (_evt->_e_type == EVENT_PlaySound) - pSoundList->LoadSound(EVT_DWORD(_evt->v5), 0); - else if (_evt->_e_type == EVENT_OnMapReload) - EventProcessor(pEvent.uEventID, 0, 0, pEvent.event_sequence_num); - else if (_evt->_e_type == EVENT_OnTimer || _evt->_e_type == EVENT_Initialize) - { - //v3 = &MapsLongTimersList[MapsLongTimers_count]; - v20 = pOutdoor->loc_time.uLastVisitDay; - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - v20 = pIndoor->stru1.uLastVisitDay; - - MapsLongTimersList[MapsLongTimers_count].timer_evt_type = _evt->_e_type; - MapsLongTimersList[MapsLongTimers_count].timer_evt_ID = pEvent.uEventID; - MapsLongTimersList[MapsLongTimers_count].timer_evt_seq_num = pEvent.event_sequence_num; - - MapsLongTimersList[MapsLongTimers_count].YearsInterval = _evt->v5; - MapsLongTimersList[MapsLongTimers_count].MonthsInterval = _evt->v6; - MapsLongTimersList[MapsLongTimers_count].WeeksInterval = _evt->v7; - MapsLongTimersList[MapsLongTimers_count].HoursInterval = _evt->v8; - MapsLongTimersList[MapsLongTimers_count].MinutesInterval = _evt->v9; - MapsLongTimersList[MapsLongTimers_count].SecondsInterval = _evt->v10; - - - v6 = ((unsigned short)_evt->v12 << 8) + _evt->v11; - - MapsLongTimersList[MapsLongTimers_count].time_left_to_fire = ((unsigned short)_evt->v12 << 8) + _evt->v11; - MapsLongTimersList[MapsLongTimers_count].IntervalHalfMins = ((unsigned short)_evt->v12 << 8) + _evt->v11; - if (MapsLongTimersList[MapsLongTimers_count].timer_evt_type == EVENT_Initialize && !(short)v6 ) - { - if ( v20 ) - v18 = pParty->uTimePlayed - v20; - else - v18 = 0; - v26 = (signed int)(signed __int64)((double)(signed __int64)v18 * 0.234375) / 60 / 60 / 24; - - if ( v26 / 7 / 4 / 12 != 0 && MapsLongTimersList[MapsLongTimers_count].YearsInterval || - v26 / 7 / 4 != 0 && MapsLongTimersList[MapsLongTimers_count].MonthsInterval != 0 || - v26 / 7 != 0 && MapsLongTimersList[MapsLongTimers_count].WeeksInterval != 0 || - v26 != 0 || !v20) - { - ++MapsLongTimers_count; - MapsLongTimersList[MapsLongTimers_count].NextStartTime = 0; - continue; - } - } - else - { - v8 = (__int64)((double)pParty->uTimePlayed * 0.234375); - seconds = v8 % 60; - minutes = (v8 / 60) % 60; - hours = ((v8 / 60) / 60) % 24; - days = (((v8 / 60) / 60) / 24) % 7; - weeks = ((((v8 / 60) / 60) / 24) / 7) % 4; - months = (((((v8 / 60) / 60) / 24) / 7) / 4) % 12; - years = (((((v8 / 60) / 60) / 24) / 7) / 4) / 12; - - if ( MapsLongTimersList[MapsLongTimers_count].YearsInterval ) - ++years; - else if ( MapsLongTimersList[MapsLongTimers_count].MonthsInterval ) - ++months; - else if ( MapsLongTimersList[MapsLongTimers_count].WeeksInterval ) - ++weeks; - else - { - ++days; - hours = MapsLongTimersList[MapsLongTimers_count].HoursInterval; - minutes = MapsLongTimersList[MapsLongTimers_count].MinutesInterval; - seconds = MapsLongTimersList[MapsLongTimers_count].SecondsInterval; - } - MapsLongTimersList[MapsLongTimers_count].NextStartTime = (signed __int64)((double)((seconds - + 60 * minutes - + 3600 * hours - + 86400 * days - + 604800 * weeks - + 2419200 * months - + 29030400 * years) << 7) - * 0.033333335); - - ++MapsLongTimers_count; - } - } - } -} - -//----- (00444360) -------------------------------------------------------- -void Level_LoadEvtAndStr(const char *pLevelName) -{ - char pContainerName[120]; // [sp+8h] [bp-98h]@1 - - sprintf(pContainerName, "%s.evt", pLevelName); - uLevelEVT_Size = LoadEventsToBuffer(pContainerName, pLevelEVT.data(), 9216); - - sprintf(pContainerName, "%s.str", pLevelName); - uLevelStrFileSize = LoadEventsToBuffer(pContainerName, pLevelStr.data(), 9216); - if (uLevelStrFileSize) - LoadLevel_InitializeLevelStr(); -} - - -//----- (004451A8) -------------------------------------------------------- -void __fastcall sub_4451A8_press_any_key(int a1, int a2, int a4) -{ - if ( !pGUIWindow2 ) - { - if ( pParty->uFlags & 2 ) - pGame->Draw(); - pAudioPlayer->StopChannels(-1, -1); - pMiscTimer->Pause(); - pEventTimer->Pause(); - dword_5C3418 = a1; - dword_5C341C = a2; - _591094_decoration = activeLevelDecoration; - pGUIWindow2 = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_GreetingNPC, a4, 0); - pGUIWindow2->CreateButton( 61, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0); - pGUIWindow2->CreateButton(177, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0); - pGUIWindow2->CreateButton(292, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0); - pGUIWindow2->CreateButton(407, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0); - } -} - -//----- (004452BB) -------------------------------------------------------- -void sub_4452BB() -{ - pGUIWindow2->Release(); - pGUIWindow2 = 0; - activeLevelDecoration = _591094_decoration; - EventProcessor(dword_5C3418, 0, 1, dword_5C341C); - activeLevelDecoration = nullptr; - pEventTimer->Resume(); -} - -//----- (004465DF) -------------------------------------------------------- -bool sub_4465DF_check_season(int a1) -{ - unsigned int monthPlusOne; // eax@1 - unsigned int daysPlusOne; // edx@1 - - monthPlusOne = pParty->uCurrentMonth + 1; - daysPlusOne = pParty->uDaysPlayed + 1; - - switch (a1) - { - case 3: //winter 12.21 -> 3.20 - return (monthPlusOne == 12 && daysPlusOne >= 21 || monthPlusOne == 1 || monthPlusOne == 2 || monthPlusOne == 3 && daysPlusOne <= 20); - break; - case 2:// autumn/fall 9.21 -> 12.20 - return (monthPlusOne == 9 && daysPlusOne >= 21 || monthPlusOne == 10 || monthPlusOne == 11 || monthPlusOne == 12 && daysPlusOne <= 20); - break; - case 1://summer 6.21 -> 9.20 - return (monthPlusOne == 6 && daysPlusOne >= 21 || monthPlusOne == 7 || monthPlusOne == 8 || monthPlusOne == 9 && daysPlusOne <= 20); - break; - case 0: //spring 3.21 -> 6.20 - return (monthPlusOne == 3 && daysPlusOne >= 21 || monthPlusOne == 4 || monthPlusOne == 5 || monthPlusOne == 6 && daysPlusOne <= 20); - break; - } - Error("Unknown season"); - return false; -} - - -//----- (00448B67) -------------------------------------------------------- -void OnTimer(int) -{ - if (pEventTimer->bPaused) - return; - - long long v13 = (signed __int64)(pParty->uTimePlayed - _5773B8_event_timer) / 128; - if (!v13) - return; - - //uint _v2v3 = pParty->uTimePlayed; - //v3 = HIDWORD(pParty->uTimePlayed); - //v2 = LODWORD(pParty->uTimePlayed); - - _5773B8_event_timer = pParty->uTimePlayed; - - for (uint i = 0; i < MapsLongTimers_count; ++i) - { - //v4 = (char *)&array_5B5928_timers[0].field_C; - MapsLongTimer* timer = &MapsLongTimersList[i]; - //while ( 1 ) - //{ - //v5 = *(short *)v4; - if (timer->time_left_to_fire) - { - if (v13 < timer->time_left_to_fire) - timer->time_left_to_fire -= v13; - else - { - timer->time_left_to_fire = timer->IntervalHalfMins; - EventProcessor(timer->timer_evt_ID, 0, 1, timer->timer_evt_seq_num); - } - } - else - { - if (timer->NextStartTime < pParty->uTimePlayed) - { - uint next_trigger_time = 1 * 60 * 60 * 24; // 1 day - if (timer->YearsInterval) - next_trigger_time = 336 * 60 * 60 * 24; // 1 year - else if (timer->MonthsInterval) - next_trigger_time = 28 * 60 * 60 * 24; // 1 month - else if (timer->WeeksInterval) - next_trigger_time = 7 * 60 * 60 * 24; // 1 week - - timer->NextStartTime += (next_trigger_time * 128) / 3.0f; - if (timer->NextStartTime < pParty->uTimePlayed) // make sure in wont fire several times in a row if big time interval has lapsed - timer->NextStartTime = pParty->uTimePlayed; - - EventProcessor(timer->timer_evt_ID, 0, 1, timer->timer_evt_seq_num); - } - } - } -} - - -//----- (00448CF4) -------------------------------------------------------- -void __fastcall sub_448CF4_spawn_monsters(__int16 typeindex, __int16 level, int count, int x, int y, int z, int group, unsigned int uUniqueName) -{ - unsigned int map_id; // eax@1 - size_t old_num_actors; // ebx@2 - AIDirection v15; // [sp+28h] [bp-34h]@2 - SpawnPointMM7 pSpawnPoint; // [sp+44h] [bp-18h]@1 - - pSpawnPoint.vPosition.x = x; - pSpawnPoint.vPosition.y = y; - pSpawnPoint.vPosition.z = z; - pSpawnPoint.uGroup = group; - pSpawnPoint.uRadius = 32; - pSpawnPoint.uKind = 3; - pSpawnPoint.uIndex = typeindex + 2 * level + level; - map_id = pMapStats->GetMapInfo(pCurrentMapName); - if ( map_id ) - { - old_num_actors = uNumActors; - SpawnEncounter(&pMapStats->pInfos[map_id], &pSpawnPoint, 0, count, 0); - Actor::GetDirectionInfo(PID(OBJECT_Actor, old_num_actors), 4, &v15, 1); - for ( uint i = (unsigned int)old_num_actors; i < (unsigned int)uNumActors; ++i ) - { - pActors[i].PrepareSprites(0); - pActors[i].uYawAngle = v15.uYawAngle; - pActors[i].dword_000334_unique_name = uUniqueName; - } - } -} - -//----- (0044987B) -------------------------------------------------------- -void Transition_StopSound_Autosave(const char *pMapName, MapStartPoint start_point) -{ - pAudioPlayer->StopChannels(-1, -1); - pGameLoadingUI_ProgressBar->Initialize(GUIProgressBar::TYPE_None); - if ( _stricmp(pCurrentMapName, pMapName) ) - SaveGame(1, 0); - - uGameState = GAME_STATE_CHANGE_LOCATION; - strcpy(pCurrentMapName, pMapName); - uLevel_StartingPointType = start_point; -} -// 6BE35C: using guessed type int uLevel_StartingPointType; - -//----- (00449B57) -------------------------------------------------------- -bool _449B57_test_bit( unsigned __int8 *a1, __int16 a2 ) -{ - return (a1[(a2 - 1) >> 3] & (0x80u >> (a2 - 1) % 8)) != 0; -} - -//----- (00449B7E) -------------------------------------------------------- -void _449B7E_toggle_bit(unsigned char *pArray, __int16 a2, unsigned __int16 bToggle) -{ - signed int v3; // esi@1 - unsigned char set_bit; // edx@1 - - v3 = a2 - 1; - set_bit = 0x80 >> v3 % 8; - if ( bToggle ) - pArray[v3 / 8] |= set_bit; - else - pArray[v3 / 8] &= ~set_bit; -} - -//----- (0044C175) -------------------------------------------------------- -void ShowStatusBarString( const char *pString, unsigned int uNumSeconds ) -{ - strcpy(GameUI_Footer_TimedString.data(), pString); - GameUI_Footer_TimeLeft = 1000 * uNumSeconds + GetTickCount(); - - for (int i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data()); i > 450; - i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data()) ) - GameUI_Footer_TimedString[strlen(GameUI_Footer_TimedString.data()) - 1] = 0; -} - -//----- (0044C1D0) -------------------------------------------------------- -void ShowNothingHereStatus() -{ - if ( !GameUI_Footer_TimeLeft ) - ShowStatusBarString(pGlobalTXT_LocalizationStrings[521], 2);// Nothing here -} - -//----- (0044C28B) -------------------------------------------------------- -int const_2() -{ - return 2; -} - -//----- (0044C28F) -------------------------------------------------------- -bool TeleportToNWCDungeon() -{ - if (!_stricmp("nwc.blv", pCurrentMapName)) - return false; - - _5B65A8_npcdata_uflags_or_other = 0; - _5B65AC_npcdata_fame_or_other = 0; - _5B65B0_npcdata_rep_or_other = 0; - _5B65B4_npcdata_loword_house_or_other = 0; - _5B65B8_npcdata_hiword_house_or_other = 0; - dword_5B65BC = 0; - dword_5B65C0 = 0; - - pGameLoadingUI_ProgressBar->uType = GUIProgressBar::TYPE_Fullscreen; - Transition_StopSound_Autosave("nwc.blv", MapStartPoint_Party); - pCurrentScreen = SCREEN_GAME; - return true; -} - -//----- (00401000) -------------------------------------------------------- -void mm7__vector_constructor(void *a1, int objSize, int numObjs, int ( *constructor)(int)) -{ - void *v4; // esi@2 - - if ( numObjs > 0 ) - { - v4 = a1; - for ( int i = numObjs; i; --i ) - { - constructor((int)v4); - v4 = (char *)v4 + objSize; - } - } -} - -//----- (0040261D) -------------------------------------------------------- -void stru298::Add(__int16 uID, __int16 a3, __int16 x, __int16 y, __int16 z, char a7, char a8) -{ - if (count < 100) - { - pIDs[count] = uID; - pXs[count] = x; - pYs[count] = y; - pZs[count] = z; - field_324[count] = a3; - field_3EC[count] = a8; - field_450[count++] = a7; - } -} - - diff -r 0f17a30149ec -r 104fdbea0386 mm7_4.cpp --- a/mm7_4.cpp Sun Aug 17 15:13:18 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1604 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS - -#include "ErrorHandling.h" -#include "VectorTypes.h" -#include "mm7_unsorted_subs.h" -#include "MM7.h" -#include "MapInfo.h" -#include "Game.h" -#include "GUIWindow.h" -#include "GUIFont.h" -#include "Party.h" -#include "AudioPlayer.h" -#include "Outdoor.h" -#include "LOD.h" -#include "Actor.h" -#include "Events.h" -#include "Viewport.h" -#include "FrameTableInc.h" -#include "OurMath.h" -#include "SpriteObject.h" -#include "ObjectList.h" -#include "DecorationList.h" -#include "Timer.h" -#include "PlayerFrameTable.h" -#include "Awards.h" -#include "texts.h" -#include "UI\UIHouses.h" -#include "Lights.h" -#include "Level/Decoration.h" -#include "mm7_data.h" -#include "UI\UIArena.h" - -//----- (0046CC4B) -------------------------------------------------------- -void check_event_triggers() -{ - for (size_t i = 0; i < num_event_triggers; i++) - { - if (pLevelDecorations[event_triggers[i]].uFlags & LEVEL_DECORATION_TRIGGERED_BY_TOUCH - && pLevelDecorations[event_triggers[i]].vPosition.GetDistanceTo(pParty->vPosition) < pLevelDecorations[event_triggers[i]].uTriggerRange) - { - EventProcessor(pLevelDecorations[event_triggers[i]].uEventID, PID(OBJECT_Decoration,i), 1); - } - else if (pLevelDecorations[event_triggers[i]].uFlags & LEVEL_DECORATION_TRIGGERED_BY_MONSTER) - { - for (size_t j = 0; j < uNumActors; j++) - { - if (pLevelDecorations[event_triggers[i]].vPosition.GetDistanceTo(pActors[j].vPosition) < pLevelDecorations[event_triggers[i]].uTriggerRange) - EventProcessor(pLevelDecorations[event_triggers[i]].uEventID, 0, 1); - } - } - else if (pLevelDecorations[event_triggers[i]].uFlags & LEVEL_DECORATION_TRIGGERED_BY_OBJECT) - { - for (size_t j = 0; j < uNumSpriteObjects; j++) - { - if (pLevelDecorations[event_triggers[i]].vPosition.GetDistanceTo(pSpriteObjects[j].vPosition) < pLevelDecorations[event_triggers[i]].uTriggerRange) - EventProcessor(pLevelDecorations[event_triggers[i]].uEventID, 0, 1); - } - } - } -} -// 6836C8: using guessed type int 6836C8_num_decorations_6807E8; - -//----- (0046DEF2) -------------------------------------------------------- -unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID) -{ - unsigned int result; // eax@1 - - result = uLayingItemID; - if ( pObjectList->pObjects[pSpriteObjects[uLayingItemID].uObjectDescID].uFlags & 0x10 ) - result = _46BFFA_check_object_intercept(uLayingItemID, a2); - return result; -} - -//----- (0046E0B2) -------------------------------------------------------- -void _46E0B2_collide_against_decorations() -{ - BLVSector *sector; // ebp@1 - LevelDecoration *decor; // edi@2 - DecorationDesc *decor_desc; // esi@3 - int v8; // ebx@10 - int v9; // esi@11 - int v11; // eax@12 - int v12; // esi@14 - unsigned int v13; // eax@17 - signed int i; // [sp+4h] [bp-14h]@1 - int v15; // [sp+8h] [bp-10h]@10 - int v16; // [sp+Ch] [bp-Ch]@10 - int v17; // [sp+10h] [bp-8h]@10 - - sector = &pIndoor->pSectors[stru_721530.uSectorID]; - for ( i = 0; i < sector->uNumDecorations; ++i ) - { - decor = &pLevelDecorations[sector->pDecorationIDs[i]]; - if (!(decor->uFlags & LEVEL_DECORATION_INVISIBLE)) - { - decor_desc = &pDecorationList->pDecorations[decor->uDecorationDescID]; - if (!decor_desc->CanMoveThrough()) - { - if ( stru_721530.sMaxX <= decor->vPosition.x + decor_desc->uRadius && stru_721530.sMinX >= decor->vPosition.x - decor_desc->uRadius - && stru_721530.sMaxY <= decor->vPosition.y + decor_desc->uRadius && stru_721530.sMinY >= decor->vPosition.y - decor_desc->uRadius - && stru_721530.sMaxZ <= decor->vPosition.z + decor_desc->uDecorationHeight && stru_721530.sMinZ >= decor->vPosition.z ) - { - v16 = decor->vPosition.x - stru_721530.normal.x; - v15 = decor->vPosition.y - stru_721530.normal.y; - v8 = stru_721530.prolly_normal_d + decor_desc->uRadius; - v17 = ((decor->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y - - (decor->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16; - if ( abs(v17) <= stru_721530.prolly_normal_d + decor_desc->uRadius ) - { - v9 = (v16 * stru_721530.direction.x + v15 * stru_721530.direction.y) >> 16; - if ( v9 > 0 ) - { - v11 = stru_721530.normal.z + fixpoint_mul(stru_721530.direction.z, v9); - if ( v11 >= decor->vPosition.z ) - { - if ( v11 <= decor_desc->uDecorationHeight + decor->vPosition.z ) - { - v12 = v9 - integer_sqrt(v8 * v8 - v17 * v17); - if ( v12 < 0 ) - v12 = 0; - if ( v12 < stru_721530.field_7C ) - { - stru_721530.field_7C = v12; - v13 = 8 * sector->pDecorationIDs[i]; - LOBYTE(v13) = v13 | 5; - stru_721530.uFaceID = v13; - } - } - } - } - } - } - } - } - } -} - -//----- (00487DA9) -------------------------------------------------------- -void sub_487DA9() -{ - for (int i = 0; i < 20000; ++i) - array_77EC08[i].field_108 = 0; -} - -//----- (00491E3A) -------------------------------------------------------- -void sub_491E3A() -{ - signed int v1; // esi@3 - unsigned int v3; // eax@7 - unsigned int v4; // edx@8 - int v6; // edi@17 - - //__debugbreak();//Ritor1 - for ( uint pl = 0; pl < 4; pl++ ) - { - if (SoundSetAction[24][0]) - { - v3 = 0; - for ( v1 = 0; v1 < (signed int)pSoundList->sNumSounds; ++v1 ) - { - int ps = 2 * (SoundSetAction[24][0] + 50 * pParty->pPlayers[pl].uVoiceID) + 4998;//6728 - if ( pSoundList->pSL_Sounds[v1].uSoundID == 2 * (SoundSetAction[24][0] + 50 * pParty->pPlayers[pl].uVoiceID) + 4998 ) - v3 = v1; - } - pSoundList->UnloadSound(v3, 1); - for ( v4 = 0; (signed int)v4 < (signed int)pSoundList->sNumSounds; ++v4 ) - { - if ( pSoundList->pSL_Sounds[v4].uSoundID == 2 * (SoundSetAction[24][0] + 50 * pParty->pPlayers[pl].uVoiceID) + 4999 ) - pSoundList->UnloadSound(v4, 1); - } - } - } - v6 = pIcons_LOD->uNumLoadedFiles - 1; - if ( v6 >= pIcons_LOD->pFacesLock ) - { - do - { - pIcons_LOD->pTextures[v6].Release(); - if ( pIcons_LOD->pHardwareTextures ) - { - if ( pIcons_LOD->pHardwareTextures[v6] ) - { - pIcons_LOD->pHardwareTextures[v6]->Release(); - pIcons_LOD->pHardwareTextures[v6] = 0; - } - } - if ( pIcons_LOD->pHardwareSurfaces ) - { - if ( pIcons_LOD->pHardwareSurfaces[v6] ) - { - pIcons_LOD->pHardwareSurfaces[v6]->Release(); - pIcons_LOD->pHardwareSurfaces[v6] = 0; - } - } - --v6; - } - while ( v6 >= pIcons_LOD->pFacesLock ); - } - pIcons_LOD->uNumLoadedFiles = pIcons_LOD->pFacesLock; - pIcons_LOD->pFacesLock = 0; -} -// 4ED498: using guessed type char byte_4ED498; - -//----- (00493938) -------------------------------------------------------- -void _493938_regenerate() -{ - int current_time; // edi@1 - int last_reg_time; // qax@1 - int v4; // eax@2 - int v5; // edi@5 - long long *v6; // ecx@5 - char v7; // sf@5 - int *v8; // ecx@10 - int v9; // edi@15 - signed int v10; // eax@15 -// __int16 *v11; // edx@16 -// int v12; // eax@20 - int numberOfActorsAffected; // ebx@20 - unsigned int v14; // esi@21 - //unsigned int v15; // ecx@21 - //unsigned int v16; // eax@21 -// int v18; // eax@21 - signed int v19; // eax@21 - bool recovery_HP; // ebx@25 -// ITEM_EQUIP_TYPE v22; // edi@30 - signed int v25; // eax@33 -// int v26; // eax@35 -// int v27; // eax@36 -// int v28; // eax@37 - signed int v31; // ecx@53 - int actorsAffectedByImmolation[100]; // [sp+4h] [bp-22Ch]@20 - SpriteObject a1; // [sp+194h] [bp-9Ch]@15 - Vec3_int_ a3; // [sp+204h] [bp-2Ch]@15 - bool has_dragon_flag; // [sp+210h] [bp-20h]@22 - bool lich_jar_flag; // [sp+214h] [bp-1Ch]@25 - bool zombie_flag; // [sp+218h] [bp-18h]@25 - bool decrease_HP; // [sp+21Ch] [bp-14h]@25 - bool lich_flag; // [sp+220h] [bp-10h]@25 - int v49; // [sp+224h] [bp-Ch]@24 - bool recovery_SP; // [sp+228h] [bp-8h]@25 - bool redraw_flag; // [sp+22Ch] [bp-4h]@2 - - current_time = (signed int)(signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) / 60; - last_reg_time = (signed int)(signed __int64)((double)pParty->uLastRegenerationTime * 0.234375) / 60; - if ( current_time >= (signed int)last_reg_time + 5 ) - { - redraw_flag = false; - v4 = (current_time - last_reg_time) / 5; - if (pParty->FlyActive()) - { - if ( pParty->bFlying ) - { - 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 -= v5; - - 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; - } - } - } - } - - if (pParty->WaterWalkActive()) - { - if (pParty->uFlags & PARTY_FLAGS_1_STANDING_ON_WATER ) - { - if ( !(pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags & 1) ) - { // taking on water - v8 = (int *)&pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uCaster - 1].pConditions[Condition_Cursed];//&AA1058_PartyQuickSpellSound[4].pSounds[6972 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uCaster + 2000]; - v7 = *v8 < v4; - *v8 -= v4; - if ( v7 ) - { - *v8 = 0; - pParty->uFlags &= ~PARTY_FLAGS_1_STANDING_ON_WATER; - redraw_flag = true; - } - } - } - } - - if (pParty->ImmolationActive())//Жертва - { - a3.z = 0; - a3.y = 0; - a3.x = 0; - a1.stru_24.Reset(); - a1.spell_level = pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].uPower; - a1.spell_skill = pParty->ImmolationSkillLevel(); - v10 = 0; - a1.uType = 1070; - a1.spell_id = SPELL_FIRE_IMMOLATION; - v10 = 0; - for (uint i = 0; i > pObjectList->uNumObjects; i++) - { - if (pObjectList->pObjects[i].uObjectID == stru_4E3ACC[8].uType) - v10 = i; - } - a1.uObjectDescID = v10; - a1.field_60_distance_related_prolly_lod = 0; - a1.uAttributes = 0; - a1.uSectorID = 0; - a1.uSpriteFrameID = 0; - a1.spell_caster_pid = PID(OBJECT_Player, pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].uCaster); - a1.uFacing = 0; - a1.uSoundID = 0; - numberOfActorsAffected = pParty->_46A89E_immolation_effect(actorsAffectedByImmolation, 100, 307); - for ( v9 = 0; v9 < numberOfActorsAffected; ++v9 ) - { - v14 = actorsAffectedByImmolation[v9]; - a1.vPosition.x = pActors[v14].vPosition.x; - a1.vPosition.y = pActors[v14].vPosition.y; - a1.vPosition.z = pActors[v14].vPosition.z; - a1.spell_target_pid = PID(OBJECT_Actor,v14); - v19 = a1.Create(0, 0, 0, 0); - Actor::DamageMonsterFromParty(PID(OBJECT_Item,v19), v14, &a3); - } - } - - has_dragon_flag = false; - if (PartyHasDragon()) - has_dragon_flag = true; - - for ( v49 = 0; v49 < 4; v49++ ) - { - recovery_HP = false; - recovery_SP = false; - decrease_HP = false; - lich_flag = false; - lich_jar_flag = false; - zombie_flag = false; - - for ( int v22 = 0; (signed int)v22 < 16; v22++ ) - { - if ( pParty->pPlayers[v49].HasItemEquipped((ITEM_EQUIP_TYPE)v22) ) - { - uint _idx = pParty->pPlayers[v49].pEquipment.pIndices[v22]; - if ( pParty->pPlayers[v49].pInventoryItemList[_idx - 1].uItemID > 134 ) - { - if ( pParty->pPlayers[v49].pInventoryItemList[_idx - 1].uItemID == ITEM_RELIC_ETHRICS_STAFF ) - decrease_HP = true; - if ( pParty->pPlayers[v49].pInventoryItemList[_idx - 1].uItemID == ITEM_ARTIFACT_HERMES_SANDALS ) - { - recovery_HP = true; - recovery_SP = true; - } - if ( pParty->pPlayers[v49].pInventoryItemList[_idx - 1].uItemID == ITEM_ARTIFACT_MINDS_EYE ) - recovery_SP = true; - if ( pParty->pPlayers[v49].pInventoryItemList[_idx - 1].uItemID == ITEM_ARTIFACT_HEROS_BELT ) - recovery_HP = true; - } - else - { - v25 = pParty->pPlayers[v49].pInventoryItemList[_idx - 1].uSpecEnchantmentType; - if ( v25 == 37 //of Regeneration("Regenerate 1hp/x while walking, etc") - || v25 == 44 //of Life("HP (+10), Regen hpts") - || v25 == 50 //of The Phoenix("Fire Res (+30), Regen hpts") && - || v25 == 54 )// of The Troll("End (+15), Regen hpts") - recovery_HP = true; - if ( v25 == 38 //of Mana("Regenerate 1sp/x while walking, etc") - || v25 == 47 //of The Eclipse("SP (+10), Regen spts") - || v25 == 55 )//of The Unicorn("Luck (+15), Regen spts") - recovery_SP = true; - if ( v25 == 66 )// of Plenty("Regenerate 1 hp/x and 1 sp/x while walking, etc.") - { - recovery_HP = true; - recovery_SP = true; - } - } - - if (recovery_HP && - !pParty->pPlayers[v49].pConditions[Condition_Dead] && - !pParty->pPlayers[v49].pConditions[Condition_Eradicated]) - { - if ( pParty->pPlayers[v49].sHealth < pParty->pPlayers[v49].GetMaxHealth() ) - ++pParty->pPlayers[v49].sHealth; - if ( pParty->pPlayers[v49].pConditions[Condition_Unconcious] && pParty->pPlayers[v49].sHealth > 0 ) - pParty->pPlayers[v49].pConditions[Condition_Unconcious] = 0; - redraw_flag = true; - } - - if (recovery_SP && - !pParty->pPlayers[v49].pConditions[Condition_Dead] && - !pParty->pPlayers[v49].pConditions[Condition_Eradicated]) - { - if ( pParty->pPlayers[v49].sMana < pParty->pPlayers[v49].GetMaxMana() ) - ++pParty->pPlayers[v49].sMana; - redraw_flag = true; - } - - if (decrease_HP && - !pParty->pPlayers[v49].pConditions[Condition_Dead] && - !pParty->pPlayers[v49].pConditions[Condition_Eradicated] ) - { - --pParty->pPlayers[v49].sHealth; - if ( !(pParty->pPlayers[v49].pConditions[Condition_Unconcious]) && pParty->pPlayers[v49].sHealth < 0 ) - pParty->pPlayers[v49].pConditions[Condition_Unconcious] = pParty->uTimePlayed; - if ( pParty->pPlayers[v49].sHealth < 1 ) - { - if ( pParty->pPlayers[v49].sHealth + pParty->pPlayers[v49].uEndurance + pParty->pPlayers[v49].GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE) >= 1 - || (signed __int64)pParty->pPlayers[v49].pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime > 0 ) - pParty->pPlayers[v49].pConditions[Condition_Unconcious] = pParty->uTimePlayed; - else - { - if ( !pParty->pPlayers[v49].pConditions[Condition_Dead] ) - pParty->pPlayers[v49].pConditions[Condition_Dead] = pParty->uTimePlayed; - } - } - redraw_flag = true; - } - } - } - - //regeneration - if ( pParty->pPlayers[v49].pPlayerBuffs[PLAYER_BUFF_REGENERATION].uExpireTime > 0 - && !pParty->pPlayers[v49].pConditions[Condition_Dead] - && !pParty->pPlayers[v49].pConditions[Condition_Eradicated] ) - { - pParty->pPlayers[v49].sHealth += 5 * pParty->pPlayers[v49].pPlayerBuffs[PLAYER_BUFF_REGENERATION].uPower; - if ( pParty->pPlayers[v49].sHealth > pParty->pPlayers[v49].GetMaxHealth() ) - pParty->pPlayers[v49].sHealth = pParty->pPlayers[v49].GetMaxHealth(); - if ( pParty->pPlayers[v49].pConditions[Condition_Unconcious] && pParty->pPlayers[v49].sHealth > 0 ) - pParty->pPlayers[v49].pConditions[Condition_Unconcious] = 0; - redraw_flag = true; - } - - //for warlock - if ( has_dragon_flag && pParty->pPlayers[v49].classType == PLAYER_CLASS_WARLOCK ) - { - if ( pParty->pPlayers[v49].sMana < pParty->pPlayers[v49].GetMaxMana() ) - ++pParty->pPlayers[v49].sMana; - redraw_flag = true; - } - - //for lich - if ( pParty->pPlayers[v49].classType == PLAYER_CLASS_LICH ) - { - for ( v31 = 0; v31 < 126; ++v31 ) - { - if ( pParty->pPlayers[v49].pInventoryItemList[v31].uItemID == ITEM_LICH_JAR_FULL ) - lich_jar_flag = true; - } - lich_flag = true; - } - if ( lich_flag && !pParty->pPlayers[v49].pConditions[Condition_Dead] - && !pParty->pPlayers[v49].pConditions[Condition_Eradicated] ) - { - if ( pParty->pPlayers[v49].sHealth > pParty->pPlayers[v49].GetMaxHealth() / 2 ) - pParty->pPlayers[v49].sHealth = pParty->pPlayers[v49].sHealth - 2; - if ( pParty->pPlayers[v49].sMana > pParty->pPlayers[v49].GetMaxMana() / 2 ) - pParty->pPlayers[v49].sMana = pParty->pPlayers[v49].sMana - 2; - } - if ( lich_jar_flag ) - { - if ( pParty->pPlayers[v49].sMana < pParty->pPlayers[v49].GetMaxMana() ) - ++pParty->pPlayers[v49].sMana; - } - - //for zombie - if ( pParty->pPlayers[v49].pConditions[Condition_Zombie] ) - zombie_flag = true; - if ( zombie_flag && !pParty->pPlayers[v49].pConditions[Condition_Dead] - && !pParty->pPlayers[v49].pConditions[Condition_Eradicated] ) - { - if ( pParty->pPlayers[v49].sHealth > pParty->pPlayers[v49].GetMaxHealth() / 2 ) - pParty->pPlayers[v49].sHealth = pParty->pPlayers[v49].sHealth - 1; - if ( pParty->pPlayers[v49].sMana > 0 ) - pParty->pPlayers[v49].sMana = pParty->pPlayers[v49].sMana - 1; - } - } - pParty->uLastRegenerationTime = pParty->uTimePlayed; - if ( !viewparams->bRedrawGameUI ) - viewparams->bRedrawGameUI = redraw_flag; - } -} - -//----- (00493F79) -------------------------------------------------------- -void init_summoned_item(stru351_summoned_item *_this, __int64 duration) -{ - signed __int64 v2; // ST2C_8@1 - signed __int64 v3; // qax@1 - //signed __int64 v4; // ST1C_8@1 - unsigned __int64 v5; // qax@1 - unsigned int v6; // ebx@1 - - v2 = (signed __int64)((double)duration * 0.234375); - v3 = v2 / 60 / 60; - //v4 = v3; - v5 = (unsigned int)v3 / 0x18; - v6 = (unsigned int)(v5 / 7) >> 2; - _this->field_0_expire_second = v2 % 60; - _this->field_4_expire_minute = v2 / 60 % 60; - _this->field_8_expire_hour = v3 % 24; - _this->field_10_expire_week = v5 / 7 & 3; - _this->field_C_expire_day = (unsigned int)v5 % 0x1C; - _this->field_14_exprie_month = v6 % 0xC; - _this->field_18_expire_year = v6 / 0xC + game_starting_year; -} - -//----- (00494035) -------------------------------------------------------- -void _494035_timed_effects__water_walking_damage__etc() -{ - signed __int64 v0; // qax@1 - unsigned int v4; // edi@1 -// signed int v12; // edi@29 - int v24; // ecx@60 - int v26; // ecx@64 - int v28; // ecx@68 - int v30; // ecx@72 - int v32; // ecx@76 - int v34; // ecx@80 - int v36; // ecx@84 - int v38; // ecx@88 - int v40; // ecx@92 - int v42; // ecx@96 - bool v43; // ebx@102 - bool v46; // edi@111 -// unsigned int v56; // [sp-8h] [bp-38h]@55 -// int v59; // [sp-4h] [bp-34h]@55 -// unsigned int v61; // [sp+14h] [bp-1Ch]@1 - signed int a2a; // [sp+18h] [bp-18h]@47 - signed int old_day; // [sp+1Ch] [bp-14h]@47 - signed int old_hour; - - old_day = pParty->uDaysPlayed; - old_hour = pParty->uCurrentHour; - //auto prev_time = pEventTimer->uTimeElapsed; - pParty->uTimePlayed += pEventTimer->uTimeElapsed; - v0 = ((signed __int64)(pParty->uTimePlayed * 0.234375) / 60)/60i64; - v4 = (unsigned int)(((unsigned int)v0 / 24) / 7) >> 2; - pParty->uCurrentTimeSecond = (signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) % 60; - pParty->uCurrentMinute = ((signed __int64)(pParty->uTimePlayed * 0.234375) / 60) % 60; - pParty->uCurrentHour = v0 % 24; - pParty->uCurrentMonthWeek = ((unsigned int)v0 / 24) / 7 & 3; - pParty->uDaysPlayed = (unsigned int)((unsigned int)v0 / 24) % 28; - pParty->uCurrentMonth = v4 % 12; - pParty->uCurrentYear = v4 / 0xC + game_starting_year; - if ( pParty->uCurrentHour >= 3 && (old_hour < 3 || pParty->uDaysPlayed > old_day) ) // new day dawns - { - pParty->pHirelings[0].bHasUsedTheAbility = false; - pParty->pHirelings[1].bHasUsedTheAbility = false; - - for (uint i = 0; i < pNPCStats->uNumNewNPCs; ++i) - pNPCStats->pNewNPCData[i].bHasUsedTheAbility = false; - - ++pParty->days_played_without_rest; - if (pParty->days_played_without_rest > 1) - { - for (uint i = 0; i < 4; ++i) - pParty->pPlayers[i].SetCondWeakWithBlockCheck(0); - - if (pParty->uNumFoodRations) - Party::TakeFood(1); - else - for (uint i = 0; i < 4; ++i) - pParty->pPlayers[i].sHealth = pParty->pPlayers[i].sHealth / (pParty->days_played_without_rest + 1) + 1; - - if (pParty->days_played_without_rest > 3) - for ( uint i = 0; i < 4; ++i ) - { - pParty->pPlayers[i].Zero(); - if (!pParty->pPlayers[i].IsPertified() && !pParty->pPlayers[i].IsEradicated() - && !pParty->pPlayers[i].IsDead()) - { - if (rand() % 100 < 5 * pParty->days_played_without_rest) - pParty->pPlayers[i].SetCondDeadWithBlockCheck(0); - if (rand() % 100 < 10 * pParty->days_played_without_rest) - pParty->pPlayers[i].SetCondInsaneWithBlockCheck(0); - } - } - } - if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) - pOutdoor->SetFog(); - - for (uint i = 0; i < 4; ++i) - pParty->pPlayers[i].uNumDivineInterventionCastsThisDay = 0; - } - - if ( pParty->uFlags & 4 && pParty->field_6FC < (signed __int64)pParty->uTimePlayed )//water damage - { - pParty->field_6FC = (signed __int64)pParty->uTimePlayed + 128; - viewparams->bRedrawGameUI = true; - for ( uint pl = 1; pl <= 4; ++pl ) - { - if ( pPlayers[pl]->WearsItem(ITEM_RELIC_HARECS_LEATHER, EQUIP_ARMOUR) - || pPlayers[pl]->HasEnchantedItemEquipped(71) - || pPlayers[pl]->pPlayerBuffs[PLAYER_BUFF_WATER_WALK].uExpireTime > 0 ) - pPlayers[pl]->PlayEmotion(CHARACTER_EXPRESSION_37, 0); - else - { - if ( !pPlayers[pl]->HasUnderwaterSuitEquipped() ) - { - pPlayers[pl]->ReceiveDamage((signed __int64)pPlayers[pl]->GetMaxHealth() * 0.1, DMGT_FIRE); - if ( pParty->uFlags & 4 ) - { - strcpy(GameUI_Footer_TimedString.data(), pGlobalTXT_LocalizationStrings[660]);// Вы тонете! - GameUI_Footer_TimeLeft = 128; - } - } - else - pPlayers[pl]->PlayEmotion(CHARACTER_EXPRESSION_37, 0); - } - } - } - if ( pParty->uFlags & 0x200 && pParty->field_6FC < (signed __int64)pParty->uTimePlayed ) //lava damage - { - viewparams->bRedrawGameUI = true; - pParty->field_6FC = (signed __int64)pParty->uTimePlayed + 128; - - for ( uint pl = 1; pl <= 4; pl++ ) - { - pPlayers[pl]->ReceiveDamage((signed __int64)pPlayers[pl]->GetMaxHealth() * 0.1, DMGT_FIRE); - if ( pParty->uFlags & 0x200 ) - { - strcpy(GameUI_Footer_TimedString.data(), pGlobalTXT_LocalizationStrings[661]); //Вы горите! - GameUI_Footer_TimeLeft = 128; - } - } - } - _493938_regenerate(); - uint party_condition_flag = 4; - a2a = pEventTimer->uTimeElapsed; - if ( pParty->uFlags2 & PARTY_FLAGS_2_RUNNING )//замедление восстановления при беге - { - a2a *= 0.5f; - if (a2a < 1) - a2a = 1; - } - - for ( uint pl = 1; pl <= 4; pl++ ) - { - if ( pPlayers[pl]->uTimeToRecovery ) - pPlayers[pl]->Recover(a2a);//восстановление активности - if ( pPlayers[pl]->GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE) + pPlayers[pl]->sHealth + pPlayers[pl]->uEndurance >= 1 - || (signed __int64)pPlayers[pl]->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime > 0 ) - { - if ( pPlayers[pl]->sHealth < 1 ) - pPlayers[pl]->SetCondition(Condition_Unconcious, 0); - } - else - pPlayers[pl]->SetCondition(Condition_Dead, 0); - if ( pPlayers[pl]->field_E0 ) - { - v24 = pPlayers[pl]->field_E0 - pEventTimer->uTimeElapsed; - if ( v24 > 0 ) - pPlayers[pl]->field_E0 = v24; - else - { - pPlayers[pl]->field_E0 = 0; - viewparams->bRedrawGameUI = true; - } - } - if ( pPlayers[pl]->field_E4 ) - { - v26 = pPlayers[pl]->field_E4 - pEventTimer->uTimeElapsed; - if ( v26 > 0 ) - pPlayers[pl]->field_E4 = v26; - else - { - pPlayers[pl]->field_E4 = 0; - viewparams->bRedrawGameUI = true; - } - } - if ( pPlayers[pl]->field_E8 ) - { - v28 = pPlayers[pl]->field_E8 - pEventTimer->uTimeElapsed; - if ( v28 > 0 ) - pPlayers[pl]->field_E8 = v28; - else - { - pPlayers[pl]->field_E8 = 0; - viewparams->bRedrawGameUI = true; - } - } - if ( pPlayers[pl]->field_EC ) - { - v30 = pPlayers[pl]->field_EC - pEventTimer->uTimeElapsed; - if ( v30 > 0 ) - pPlayers[pl]->field_EC = v30; - else - { - pPlayers[pl]->field_EC = 0; - viewparams->bRedrawGameUI = true; - } - } - if ( pPlayers[pl]->field_F0 ) - { - v32 = pPlayers[pl]->field_F0 - pEventTimer->uTimeElapsed; - if ( v32 > 0 ) - pPlayers[pl]->field_F0 = v32; - else - { - pPlayers[pl]->field_F0 = 0; - viewparams->bRedrawGameUI = true; - } - } - if ( pPlayers[pl]->field_F4 ) - { - v34 = pPlayers[pl]->field_F4 - pEventTimer->uTimeElapsed; - if ( v34 > 0 ) - pPlayers[pl]->field_F4 = v34; - else - { - pPlayers[pl]->field_F4 = 0; - viewparams->bRedrawGameUI = true; - } - } - if ( pPlayers[pl]->field_F8 ) - { - v36 = pPlayers[pl]->field_F8 - pEventTimer->uTimeElapsed; - if ( v36 > 0 ) - pPlayers[pl]->field_F8 = v36; - else - { - pPlayers[pl]->field_F8 = 0; - viewparams->bRedrawGameUI = true; - } - } - if ( pPlayers[pl]->field_FC ) - { - v38 = pPlayers[pl]->field_FC - pEventTimer->uTimeElapsed; - if ( v38 > 0 ) - pPlayers[pl]->field_FC = v38; - else - { - pPlayers[pl]->field_FC = 0; - viewparams->bRedrawGameUI = true; - } - } - if ( pPlayers[pl]->field_100 ) - { - v40 = pPlayers[pl]->field_100 - pEventTimer->uTimeElapsed; - if ( v40 > 0 ) - pPlayers[pl]->field_100 = v40; - else - { - pPlayers[pl]->field_100 = 0; - viewparams->bRedrawGameUI = true; - } - } - if ( pPlayers[pl]->field_104 ) - { - v42 = pPlayers[pl]->field_104 - pEventTimer->uTimeElapsed; - if ( v42 > 0 ) - pPlayers[pl]->field_104 = v42; - else - { - pPlayers[pl]->field_104 = 0; - viewparams->bRedrawGameUI = true; - } - } - if ( pPlayers[pl]->pConditions[Condition_Sleep] | pPlayers[pl]->pConditions[Condition_Paralyzed] - | pPlayers[pl]->pConditions[Condition_Unconcious] | pPlayers[pl]->pConditions[Condition_Dead] - | pPlayers[pl]->pConditions[Condition_Pertified] | pPlayers[pl]->pConditions[Condition_Eradicated] ) - --party_condition_flag; - v43 = (signed __int64)pPlayers[pl]->pPlayerBuffs[PLAYER_BUFF_HASTE].uExpireTime > 0; //спешка - - for ( uint k = 0; k < 24; ++k ) - pPlayers[pl]->pPlayerBuffs[k].IsBuffExpiredToTime(pParty->uTimePlayed); - - if ( v43 && (signed __int64)pPlayers[pl]->pPlayerBuffs[7].uExpireTime <= 0 ) - pPlayers[pl]->SetCondition(Condition_Weak, 0); - } - - v46 = (signed __int64)pParty->pPartyBuffs[PARTY_BUFF_HASTE].uExpireTime > 0; - - for (uint i = 0; i < 20; ++i) - { - if (pParty->pPartyBuffs[i].IsBuffExpiredToTime(pParty->uTimePlayed) == 1) - viewparams->bRedrawGameUI = true; - } - - if ( v46 && (signed __int64)pParty->pPartyBuffs[PARTY_BUFF_HASTE].uExpireTime <= 0 ) - { - for (uint i = 0; i < 4; ++i) - pParty->pPlayers[i].SetCondition(1, 0); - } - - for (uint i = 0; i < 2; ++i)//Проверка в сознании ли перс сделавший закл на полёт и хождение по воде - { - SpellBuff* pBuf = &pParty->pPartyBuffs[Party_Spec_Motion_status_ids[i]]; - if (pBuf->uExpireTime == 0) - continue; - - if ( !(pBuf->uFlags & 1) ) - { - if (!pPlayers[pBuf->uCaster]->CanAct()) - { - pBuf->Reset(); - if (Party_Spec_Motion_status_ids[i] == PARTY_BUFF_FLY ) - pParty->bFlying = false; - } - } - } - - if ( !party_condition_flag ) - { - if ( pCurrentScreen != SCREEN_REST ) - { - for ( uint pl = 1; pl <= 4; pl++ ) - { - if ( pPlayers[pl]->pConditions[Condition_Sleep] ) - { - pPlayers[pl]->pConditions[Condition_Sleep] = 0; - party_condition_flag = 1; - break; - } - } - if ( !party_condition_flag || _5C35C0_force_party_death ) - uGameState = GAME_STATE_PARTY_DIED; - } - } - - if ( uActiveCharacter )//выбор следующего после пропускающего ход - { - if ( pCurrentScreen != SCREEN_REST ) - { - if ( pPlayers[uActiveCharacter]->pConditions[Condition_Sleep] - || pPlayers[uActiveCharacter]->pConditions[Condition_Paralyzed] - || pPlayers[uActiveCharacter]->pConditions[Condition_Unconcious] - || pPlayers[uActiveCharacter]->pConditions[Condition_Dead] - || pPlayers[uActiveCharacter]->pConditions[Condition_Pertified] - || pPlayers[uActiveCharacter]->pConditions[Condition_Eradicated] ) - { - viewparams->bRedrawGameUI = true; - uActiveCharacter = pParty->GetNextActiveCharacter(); - } - } - } -} - -//----- (00494820) -------------------------------------------------------- -unsigned int __fastcall _494820_training_time(unsigned int a1) -{ - signed int v1; // eax@1 - - v1 = 5; - if ( a1 % 24 >= 5 ) - v1 = 29; - return v1 - a1 % 24; -} - -//----- (00494836) -------------------------------------------------------- -int stru339_spell_sound::AddPartySpellSound(int uSoundID, int a6) -{ - int v3; // esi@1 - int result; // eax@1 - //stru339_spell_sound *v5; // ebx@1 - //int *v6; // edi@2 - unsigned int v7; // eax@3 - int v8; // [sp+Ch] [bp-8h]@3 - int v9; // [sp+10h] [bp-4h]@2 - int a2a; // [sp+1Ch] [bp+8h]@1 - //return 0; - v3 = 0; - result = word_4EE088_sound_ids[uSoundID]; - //v5 = this; - a2a = word_4EE088_sound_ids[uSoundID]; - if ( word_4EE088_sound_ids[uSoundID] ) - { - //v6 = this->pSoundsOffsets; - for ( v9 = 0; v9 < 2; ++v9 ) - { - v7 = a2a++; - result = pSoundList->LoadSound(v7, (char *)this + v3, 44744 - v3, &v8, a6); - if ( !result ) - break; - a6 += 4; - result = v8 + 256; - this->pSoundsOffsets[v9] = v3; - v3 += result; - this->pSoundsSizes[v9] = v8 + 256; - //++v6; - } - } - return result; -} -// 4EE088: using guessed type __int16 word_4EE088_sound_ids[]; - - - -//----- (00495430) -------------------------------------------------------- -const char * GetReputationString( signed int a1 ) - { - if (a1 >= 25) - return pGlobalTXT_LocalizationStrings[379]; // Hated - else if (a1 >= 6) - return pGlobalTXT_LocalizationStrings[392]; // Unfriendly - else if (a1 >= -5) - return pGlobalTXT_LocalizationStrings[399]; // Neutral; - else if (a1 >= -24) - return pGlobalTXT_LocalizationStrings[402]; // Friendly - else - return pGlobalTXT_LocalizationStrings[434]; // Respected; -} - -//----- (00495461) -------------------------------------------------------- -char *BuildDialogueString(const char *lpsz, unsigned __int8 uPlayerID, ItemGen *a3, char *a4, int a5, __int64 *a6) -{ - Player *pPlayer; // ebx@3 - const char *pText; // esi@7 - int v17; // eax@10 - signed __int64 v18; // qax@18 - unsigned __int8 *v20; // ebx@32 - int v21; // ecx@34 - int pReputation; // eax@45 - int v29; // eax@68 - __int16 v55[56]; // [sp+10h] [bp-128h]@34 - stru351_summoned_item v56; // [sp+80h] [bp-B8h]@107 - char a1[100]; // [sp+B8h] [bp-80h]@3 - int v63; // [sp+12Ch] [bp-Ch]@32 - - if ( IsBadStringPtrA(lpsz, 1) ) - return "Invalid String Passed"; - - a1[0] = 0; - pPlayer = &pParty->pPlayers[uPlayerID]; - memset(pTmpBuf2.data(), 0, sizeof(pTmpBuf2)); - - NPCData *npc = nullptr; - if ( dword_5C35D4 ) - npc = HouseNPCData[(unsigned int)((char *)pDialogueNPCCount + -(dword_591080 != 0))]; //- 1 - else - npc = GetNPCData(sDialogue_SpeakingActorNPC_ID); - - //pText = a4; - uint len = strlen(lpsz); - for (int i = 0, dst = 0; i < len; ++i) - { - char c = lpsz[i]; - if (c != '%') - pTmpBuf2[dst++] = c; - else - { - v17 = 10 * (int)(lpsz[i + 1] - '0') + lpsz[i + 2] - '0'; - - switch ( v17 ) - { - case 1://Подробнее - strcat(pTmpBuf2.data(), npc->pName); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 2: - strcat(pTmpBuf2.data(), pPlayer->pName); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 3: - case 4: - strcat(pTmpBuf2.data(), a1); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 5: - v18 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) / 60 / 60 % 24; - pText = pGlobalTXT_LocalizationStrings[397];// "evening" - if ( SHIDWORD(v18) <= 0 && SHIDWORD(v18) >= 0 && (unsigned int)v18 >= 5 && SHIDWORD(v18) <= 0 ) - { - if ( SHIDWORD(v18) >= 0 && (unsigned int)v18 >= 11 ) - { - if ( v18 < 20 ) - pText = pGlobalTXT_LocalizationStrings[396];// "day" - } - else - { - pText = pGlobalTXT_LocalizationStrings[395];// "morning" - } - } - strcat(pTmpBuf2.data(), pText); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 6: - if ( pPlayer->uSex ) - pText = pGlobalTXT_LocalizationStrings[387];// "lady" - else - pText = pGlobalTXT_LocalizationStrings[385];// "sir" - strcat(pTmpBuf2.data(), pText); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 7: - if ( pPlayer->uSex ) - pText = pGlobalTXT_LocalizationStrings[389];// "Lady" - else - pText = pGlobalTXT_LocalizationStrings[386];// "Sir" - strcat(pTmpBuf2.data(), pText); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 8: - v63 = 0; - v20 = (unsigned __int8 *)pPlayer->_achieved_awards_bits; - for ( uint _i = 0; _i < 28; ++_i ) - { - if ( (unsigned __int16)_449B57_test_bit(v20, word_4EE150[i]) ) - { - v21 = v63; - ++v63; - v55[v63] = word_4EE150[i]; - } - } - if ( v63 ) - { - if ( dword_A74CDC == -1 ) - dword_A74CDC = rand() % v63; - pText = (char *)pAwards[v55[dword_A74CDC]].pText;//(char *)dword_723E80_award_related[2 * v55[v24]]; - } - else - pText = (char *)pNPCTopics[55].pText; - strcat(pTmpBuf2.data(), pText); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 9: - if ( npc->uSex ) - pText = pGlobalTXT_LocalizationStrings[384];// "her" - else - pText = pGlobalTXT_LocalizationStrings[383];// "his" - strcat(pTmpBuf2.data(), pText); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 10: - if ( pPlayer->uSex ) - pText = pGlobalTXT_LocalizationStrings[389];// "Lady" - else - pText = pGlobalTXT_LocalizationStrings[388];// "Lord" - strcat(pTmpBuf2.data(), pText); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 11: - pReputation = pParty->GetPartyReputation(); - if ( pReputation >= 25 ) - pText = pGlobalTXT_LocalizationStrings[379]; - else//v25 < 25 - { - if ( pReputation < 6 ) - { - if ( pReputation >= -5 )//6 >= v25 >= -5 - pText = pGlobalTXT_LocalizationStrings[399]; - else// v25 < -5 - { - if ( pReputation < -24 )//-24 > v25 - pText = pGlobalTXT_LocalizationStrings[434]; - else// -5 > v25 > -24 - pText = pGlobalTXT_LocalizationStrings[402]; - } - } - else//25 > v25 > 6 - pText = pGlobalTXT_LocalizationStrings[392]; - } - strcat(pTmpBuf2.data(), pText); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 12: - pReputation = npc->rep; - if ( pReputation >= 25 ) - pText = pGlobalTXT_LocalizationStrings[379];//Ненавистный - else - { - if ( pReputation < 6 ) - { - if ( pReputation >= -5 ) - pText = pGlobalTXT_LocalizationStrings[399];//Нейтральная - else - { - if ( pReputation < -24 ) - pText = pGlobalTXT_LocalizationStrings[434];//Почтенная - else - pText = pGlobalTXT_LocalizationStrings[402];//Дружелюбный - } - } - else - pText = pGlobalTXT_LocalizationStrings[392];//Недружелюбный - } - strcat(pTmpBuf2.data(), pText); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 13: - strcat(pTmpBuf2.data(), pNPCStats->sub_495366_MispronounceName(pPlayer->pName[0], pPlayer->uSex)); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 14: - if ( npc->uSex ) - pText = pGlobalTXT_LocalizationStrings[391];// "sister" - else - pText = pGlobalTXT_LocalizationStrings[390];// "brother" - strcat(pTmpBuf2.data(), pText); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 15: - strcat(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[393]);// "daughter" - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 16: - if ( npc->uSex ) - pText = pGlobalTXT_LocalizationStrings[391];// "sister" - else - pText = pGlobalTXT_LocalizationStrings[390];// "brother" - strcat(pTmpBuf2.data(), pText); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 17://текст наёмного НПС - { - uint pay_percentage = pNPCStats->pProfessions[npc->uProfession].uHirePrice / 100; - if ( !pay_percentage ) - pay_percentage = 1; - sprintf(a1, "%lu", pay_percentage); - strcat(pTmpBuf2.data(), a1); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - } - case 18: - case 19: - case 20: - case 21: - case 22: - case 26: - strncpy(a1, lpsz + i + 1, 2); - sprintf(a1, "%lu", atoi(a1)); - strcat(pTmpBuf2.data(), a1); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 23: - if ( pMapStats->GetMapInfo(pCurrentMapName) ) - pText = pMapStats->pInfos[pMapStats->GetMapInfo(pCurrentMapName)].pName; - else - pText = pGlobalTXT_LocalizationStrings[394];// "Unknown" - strcat(pTmpBuf2.data(), pText); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 24://название товара в продаже - sprintfex(a1, format_4E2D80, Color16(255, 255, 155), a3->GetDisplayName()); - strcat(pTmpBuf2.data(), a1); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 25: - v29 = pPlayer->GetBaseBuyingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier); - switch ( a5 ) - { - case 3: - v29 = pPlayer->GetBaseSellingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier); - break; - case 4: - v29 = pPlayer->GetBaseIdentifyPrice(p2DEvents[(signed int)a4 - 1].fPriceMultiplier); - break; - case 5: - v29 = pPlayer->GetBaseRepairPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier); - break; - case 6: - v29 = pPlayer->GetBaseSellingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier) / 2; - break; - } - sprintfex(a1, "%lu", v29); - strcat(pTmpBuf2.data(), a1); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 27://текст продажи - v29 = pPlayer->GetBuyingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier); - if ( a5 == 3 ) - { - v29 = pPlayer->GetPriceSell(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier); - if (a3->IsBroken()) - v29 = 1; - sprintfex(a1, "%lu", v29); - strcat(pTmpBuf2.data(), a1); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - } - if ( a5 != 4 ) - { - if ( a5 == 5 ) - v29 = pPlayer->GetPriceRepair(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier); - else - { - if ( a5 == 6 ) - { - v29 = pPlayer->GetPriceSell(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier) / 2; - if (a3->IsBroken()) - v29 = 1; - if (!v29) - v29 = 1; - sprintfex(a1, "%lu", v29); - strcat(pTmpBuf2.data(), a1); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - } - } - sprintfex(a1, "%lu", v29); - strcat(pTmpBuf2.data(), a1); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - } - sprintfex(a1, "%lu", pPlayer->GetPriceIdentification(p2DEvents[(signed int)a4 - 1].fPriceMultiplier)); - strcat(pTmpBuf2.data(), a1); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 28://профессия - strcat(pTmpBuf2.data(), (char *)p2DEvents[(signed int)a4 - 1].pProprieterTitle); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 29: - sprintfex(a1, "%lu", pPlayer->GetPriceIdentification(p2DEvents[(signed int)a4 - 1].fPriceMultiplier)); - strcat(pTmpBuf2.data(), a1); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 30: - if ( !a6 ) - { - strcat(pTmpBuf2.data(), a4); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - } - init_summoned_item(&v56, *a6); - sprintfex(a1, pGlobalTXT_LocalizationStrings[378], aMonthNames[v56.field_14_exprie_month], v56.field_C_expire_day + 1, v56.field_18_expire_year); - strcat(pTmpBuf2.data(), a1); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - case 31: - case 32: - case 33: - case 34: - strcat(pTmpBuf2.data(), pParty->pPlayers[v17 - 31].pName); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - default: - if ( v17 <= 50 || v17 > 70 ) - { - strncpy(a1, lpsz + i + 1, 2); - sprintf(a1, "%lu", atoi(a1)); - strcat(pTmpBuf2.data(), a1); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - } - if ( v17 - 51 >= 20 ) - { - strcat(pTmpBuf2.data(), a4); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - } - init_summoned_item(&v56, pParty->PartyTimes._s_times[v17-51]); - sprintfex(a1, pGlobalTXT_LocalizationStrings[378], aMonthNames[v56.field_14_exprie_month], v56.field_C_expire_day + 1, v56.field_18_expire_year); - strcat(pTmpBuf2.data(), a1); - dst = strlen(pTmpBuf2.data()); - i += 2; - break; - } - } - } - return pTmpBuf2.data(); -} - -//----- (0049D700) -------------------------------------------------------- -unsigned int __fastcall GetMaxMipLevels(unsigned int uDim) -{ - int v2; // ecx@1 - unsigned int v3; // eax@1 - - v2 = 0; - v3 = uDim - 1; - while ( v3 & 1 ) - { - v3 >>= 1; - ++v2; - } - return v3 == 0 ? v2 : 0; -} - - -//----- (004B254D) -------------------------------------------------------- -const char * _4B254D_SkillMasteryTeacher(int trainerInfo) -{ - int teacherLevel; // edx@1 - int skillBeingTaught; // ecx@1 - int pClassType; // eax@7 - int currClassMaxMastery; // eax@7 - int pointsInSkillWOutMastery; // ebx@7 - int classBaseId; // eax@8 - unsigned int skillMastery; // eax@29 - unsigned __int16 pointsInSkill; // [sp+1Ch] [bp-10h]@7 - int masteryLevelBeingTaught; // [sp+24h] [bp-8h]@7 - - contract_approved = 0; - teacherLevel = (trainerInfo - 200) % 3; - skillBeingTaught = (trainerInfo - 200) / 3; - Player* activePlayer = pPlayers[uActiveCharacter]; - pClassType = activePlayer->classType; - currClassMaxMastery = byte_4ED970_skill_learn_ability_by_class_table[pClassType][skillBeingTaught]; - masteryLevelBeingTaught = teacherLevel + 2; - dword_F8B1B0_MasteryBeingTaught = masteryLevelBeingTaught; - if ( currClassMaxMastery < masteryLevelBeingTaught ) - { - classBaseId = pClassType - pClassType % 4; - if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 1][skillBeingTaught] >= masteryLevelBeingTaught) - sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[633], pClassNames[classBaseId + 1]);//Вы должны достичь звания %s для обучения этому уровню навыка. You have to be promoted to %s to learn this skill level. - else if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 2][skillBeingTaught] >= masteryLevelBeingTaught - && byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 3][skillBeingTaught] >= masteryLevelBeingTaught) - sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[634], pClassNames[classBaseId + 2], pClassNames[classBaseId + 3]);//Вы должны достичь звания %s или %s для обучения этому уровню навыка. You have to be promoted to %s or %s to learn this skill level. - else if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 2][skillBeingTaught] >= masteryLevelBeingTaught) - sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[633], pClassNames[classBaseId + 2]);//Вы должны достичь звания %s для обучения этому уровню навыка. You have to be promoted to %s to learn this skill level. - else if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 3][skillBeingTaught] >= masteryLevelBeingTaught) - sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[633], pClassNames[classBaseId + 3]);//Вы должны достичь звания %s для обучения этому уровню навыка. You have to be promoted to %s to learn this skill level. - else - sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[632], pClassNames[pClassType]);//Этот уровень навыка не может быть постигнут классом %s. This skill level can not be learned by the %s class. - return pTmpBuf.data(); - } - if ( !activePlayer->CanAct() ) - return pNPCTopics[122].pText; //Not in your condition! - pointsInSkill = activePlayer->pActiveSkills[skillBeingTaught]; - pointsInSkillWOutMastery = pointsInSkill & 0x3F; - if ( !pointsInSkillWOutMastery ) - return pNPCTopics[131].pText; //You must know the skill before you can become an expert in it! - skillMastery = SkillToMastery(pointsInSkill); - if ( (signed int)skillMastery > teacherLevel + 1 ) - return pNPCTopics[teacherLevel + 128].pText; // You are already an SKILLLEVEL in this skill. - dword_F8B1AC_award_bit_number = skillBeingTaught; - if ( masteryLevelBeingTaught == 2 && pointsInSkillWOutMastery < 4 - || masteryLevelBeingTaught == 3 && pointsInSkillWOutMastery < 7 - || masteryLevelBeingTaught == 4 && pointsInSkillWOutMastery < 10 - ) - return pNPCTopics[127].pText; //"You don't meet the requirements, and cannot be taught until you do." - switch (dword_F8B1AC_award_bit_number) - { - case PLAYER_SKILL_STAFF: - case PLAYER_SKILL_SWORD: - case PLAYER_SKILL_DAGGER: - case PLAYER_SKILL_AXE: - case PLAYER_SKILL_SPEAR: - case PLAYER_SKILL_BOW: - case PLAYER_SKILL_MACE: - case PLAYER_SKILL_ARMSMASTER: - switch (masteryLevelBeingTaught) - { - case 2: - gold_transaction_amount = 2000; - break; - case 3: - gold_transaction_amount = 5000; - break; - case 4: - gold_transaction_amount = 8000; - break; - } - break; - case PLAYER_SKILL_BLASTER: - switch (masteryLevelBeingTaught) - { - case 2: - gold_transaction_amount = 0; - break; - case 3: - gold_transaction_amount = 0; - break; - case 4: - gold_transaction_amount = 0; - break; - } - break; - case PLAYER_SKILL_SHIELD: - case PLAYER_SKILL_LEATHER: - case PLAYER_SKILL_CHAIN: - case PLAYER_SKILL_PLATE: - switch (masteryLevelBeingTaught) - { - case 2: - gold_transaction_amount = 1000; - break; - case 3: - gold_transaction_amount = 3000; - break; - case 4: - gold_transaction_amount = 7000; - break; - } - break; - case PLAYER_SKILL_FIRE: - case PLAYER_SKILL_AIR: - case PLAYER_SKILL_WATER: - case PLAYER_SKILL_EARTH: - case PLAYER_SKILL_SPIRIT: - case PLAYER_SKILL_MIND: - case PLAYER_SKILL_BODY: - switch (masteryLevelBeingTaught) - { - case 2: - gold_transaction_amount = 1000; - break; - case 3: - gold_transaction_amount = 4000; - break; - case 4: - gold_transaction_amount = 8000; - break; - } - break; - case PLAYER_SKILL_LIGHT: - switch (masteryLevelBeingTaught) - { - case 2: - gold_transaction_amount = 2000; - break; - case 3: - if ( !(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 114) ) - return pNPCTopics[127].pText; - gold_transaction_amount = 5000; - break; - case 4: - if ( !activePlayer->ProfessionOrGuildFlagsCorrect(0x22u, 1) || - !activePlayer->ProfessionOrGuildFlagsCorrect(0x1Au, 1)) - return pNPCTopics[127].pText; - gold_transaction_amount = 8000; - break; - } - break; - case PLAYER_SKILL_DARK: - switch (masteryLevelBeingTaught) - { - case 2: - gold_transaction_amount = 2000; - break; - case 3: - if ( !(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 110) ) - return pNPCTopics[127].pText; - gold_transaction_amount = 5000; - break; - case 4: - if ( !activePlayer->ProfessionOrGuildFlagsCorrect(0x23u, 1) - || !activePlayer->ProfessionOrGuildFlagsCorrect(0x1Bu, 1)) - return pNPCTopics[127].pText; - gold_transaction_amount = 8000; - break; - } - break; - case PLAYER_SKILL_ITEM_ID: - case PLAYER_SKILL_REPAIR: - case PLAYER_SKILL_MEDITATION: - case PLAYER_SKILL_PERCEPTION: - case PLAYER_SKILL_TRAP_DISARM: - case PLAYER_SKILL_MONSTER_ID: - case PLAYER_SKILL_STEALING: - case PLAYER_SKILL_ALCHEMY: - switch (masteryLevelBeingTaught) - { - case 2: - gold_transaction_amount = 500; - break; - case 3: - gold_transaction_amount = 2500; - break; - case 4: - gold_transaction_amount = 6000; - break; - } - break; - case PLAYER_SKILL_MERCHANT: - switch (masteryLevelBeingTaught) - { - case 2: - gold_transaction_amount = 2000; - break; - case 3: - if ( activePlayer->GetBaseWillpower() < 50 ) - return pNPCTopics[127].pText; - gold_transaction_amount = 5000; - break; - case 4: - gold_transaction_amount = 8000; - break; - } - break; - case PLAYER_SKILL_BODYBUILDING: - switch (masteryLevelBeingTaught) - { - case 2: - gold_transaction_amount = 500; - break; - case 3: - if ( activePlayer->GetBaseEndurance() < 50 ) - return pNPCTopics[127].pText; - gold_transaction_amount = 2500; - break; - case 4: - gold_transaction_amount = 6000; - break; - } - break; - case PLAYER_SKILL_DIPLOMACY: - Error("Diplomacy not used"); - break; - case PLAYER_SKILL_TIEVERY: - Error("Thievery not used"); - break; - case PLAYER_SKILL_DODGE: - switch (masteryLevelBeingTaught) - { - case 2: - gold_transaction_amount = 2000; - break; - case 3: - gold_transaction_amount = 5000; - break; - case 4: - if ( (activePlayer->pActiveSkills[PLAYER_SKILL_UNARMED] & 63) < 0xA ) - return pNPCTopics[127].pText; - gold_transaction_amount = 8000; - break; - } - break; - case PLAYER_SKILL_UNARMED: - switch (masteryLevelBeingTaught) - { - case 2: - gold_transaction_amount = 2000; - break; - case 3: - gold_transaction_amount = 5000; - break; - case 4: - if ( (activePlayer->pActiveSkills[PLAYER_SKILL_DODGE] & 63) < 0xA ) - return pNPCTopics[127].pText; - gold_transaction_amount = 8000; - break; - } - break; - case PLAYER_SKILL_LEARNING: - switch (masteryLevelBeingTaught) - { - case 2: - gold_transaction_amount = 2000; - break; - case 3: - if ( activePlayer->GetBaseIntelligence() < 50 ) - return pNPCTopics[127].pText; - gold_transaction_amount = 5000; - break; - case 4: - gold_transaction_amount = 8000; - break; - } - break; - default: - Error("Unknown skill"); - } - if ( gold_transaction_amount > pParty->uNumGold ) - return pNPCTopics[124].pText; //You don't have enough gold! - contract_approved = 1; - if ( masteryLevelBeingTaught == 2 ) - { - sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[534],//Получить степень ^Pr[%s] в навыке ^Pr[%s] за ^I[%lu] золот^L[ой;ых;ых] - pGlobalTXT_LocalizationStrings[433], pSkillNames[dword_F8B1AC_award_bit_number], gold_transaction_amount);//Эксперт - } - else if ( masteryLevelBeingTaught == 3 ) - { - sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[534], - pGlobalTXT_LocalizationStrings[432], pSkillNames[dword_F8B1AC_award_bit_number], gold_transaction_amount);//Мастер - } - else if ( masteryLevelBeingTaught == 4 ) - sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[534], - pGlobalTXT_LocalizationStrings[225], pSkillNames[dword_F8B1AC_award_bit_number], gold_transaction_amount);//Великий Магистр - return pTmpBuf2.data(); -} - - - - diff -r 0f17a30149ec -r 104fdbea0386 mm7_5.cpp --- a/mm7_5.cpp Sun Aug 17 15:13:18 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,486 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "ErrorHandling.h" -#include "LightmapBuilder.h" -#include "mm7.h" -#include "GUIWindow.h" -#include "Party.h" -#include "Outdoor.h" -#include "LOD.h" -#include "Actor.h" -#include "Viewport.h" -#include "OurMath.h" -#include "SpriteObject.h" -#include "Timer.h" -#include "stru298.h" -#include "Lights.h" -#include "Level/Decoration.h" -#include "mm7_unsorted_subs.h" -#include "mm7_data.h" - - -//----- (004356FF) -------------------------------------------------------- -void back_to_game() -{ - dword_507BF0_is_there_popup_onscreen = 0; - dword_4E455C = 1; - - extern int no_rightlick_in_inventory; - no_rightlick_in_inventory = false; - - if ( pGUIWindow_ScrollWindow ) - free_book_subwindow(); - if ( !pCurrentScreen && !pGUIWindow_Settings ) - pEventTimer->Resume(); - viewparams->bRedrawGameUI = 1; -} - -//----- (004369DB) -------------------------------------------------------- -void Vec3_float_::Normalize() -{ - this->x = (1.0 / sqrt(this->x * this->x + this->y * this->y + this->z * this->z)) * this->x; - this->y = (1.0 / sqrt(this->x * this->x + this->y * this->y + this->z * this->z)) * this->y; - this->z = (1.0 / sqrt(this->x * this->x + this->y * this->y + this->z * this->z)) * this->z; -} - -//----- (00438F8F) -------------------------------------------------------- -void area_of_effect__damage_evaluate() -{ - int attacker_type; // ecx@3 - signed int v3; // eax@3 - unsigned int target_id; // edi@6 - int target_type; // eax@6 - int v10; // edi@8 - Vec3_int_ attacker_coord; // ST04_12@9 -// int v12; // ST0C_4@10 - int v15; // edx@15 - int v19; // edi@15 - int v23; // edx@18 - int v24; // eax@18 -// int v30; // eax@29 - int v31; // edx@29 - int v32; // eax@29 - int v33; // ST24_4@29 - SpriteObject *v36; // [sp+0h] [bp-28h]@0 - int attacker_id; // [sp+10h] [bp-18h]@1 - int v44; // [sp+14h] [bp-14h]@15 - //Vec3_int_ *pVelocity; // [sp+1Ch] [bp-Ch]@2 - signed int a1; // [sp+20h] [bp-8h]@8 - int v48; // [sp+24h] [bp-4h]@8 - - - for ( attacker_id = 0; attacker_id < AttackerInfo.count; ++attacker_id ) - { - attacker_type = PID_TYPE(AttackerInfo.pIDs[attacker_id]); - v3 = PID_ID(AttackerInfo.pIDs[attacker_id]); - - if ( attacker_type == 2 ) - { - v36 = &pSpriteObjects[v3]; - attacker_type = PID_TYPE(pSpriteObjects[v3].spell_caster_pid); - v3 = PID_ID(pSpriteObjects[v3].spell_caster_pid); - } - - if ( AttackerInfo.field_3EC[attacker_id] & 1 ) - { - target_id = PID_ID(ai_near_actors_targets_pid[v3]); - target_type = PID_TYPE(ai_near_actors_targets_pid[v3]) - 3; - if ( target_type ) - { - if ( target_type == 1 )//party damage from monsters(повреждения группе от монстров) - { - v10 = pParty->vPosition.y - AttackerInfo.pYs[attacker_id]; - a1 = pParty->vPosition.x - AttackerInfo.pXs[attacker_id]; - v48 = pParty->vPosition.y - AttackerInfo.pYs[attacker_id]; - if ( a1 * a1 + v10 * v10 - + ((signed int)(pParty->vPosition.z + pParty->uPartyHeight) >> (1 - AttackerInfo.pZs[attacker_id])) - * ((signed int)(pParty->vPosition.z + pParty->uPartyHeight) >> (1 - AttackerInfo.pZs[attacker_id])) - < (unsigned int)((AttackerInfo.field_324[attacker_id] + 32) * (AttackerInfo.field_324[attacker_id] + 32)) ) - { - attacker_coord.x = AttackerInfo.pXs[attacker_id]; - attacker_coord.y = AttackerInfo.pYs[attacker_id]; - attacker_coord.z = AttackerInfo.pZs[attacker_id]; - if ( sub_407A1C(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + pParty->sEyelevel, attacker_coord) ) - DamagePlayerFromMonster(AttackerInfo.pIDs[attacker_id], AttackerInfo.field_450[attacker_id], &AttackerInfo.vec_4B4[attacker_id], stru_50C198.which_player_to_attack(&pActors[v3])); - } - } - } - else//Actor damage from monsters(повреждение местного жителя) - { - if ( SHIDWORD(pActors[target_id].pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime) > 0 - || SHIDWORD(pActors[target_id].pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime) >= 0 - && LODWORD(pActors[target_id].pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime) - || pActors[target_id].CanAct() ) - { - v15 = pActors[target_id].vPosition.y - AttackerInfo.pYs[attacker_id]; - a1 = pActors[target_id].vPosition.x - AttackerInfo.pXs[attacker_id]; - v44 = pActors[target_id].vPosition.z; - v19 = AttackerInfo.field_324[attacker_id] + pActors[target_id].uActorRadius; - v48 = v15; - if ( a1 * a1 + v15 * v15 + (pActors[target_id].vPosition.z + (pActors[target_id].uActorHeight >> 1) - AttackerInfo.pZs[attacker_id]) - * (pActors[target_id].vPosition.z + (pActors[target_id].uActorHeight >> 1) - AttackerInfo.pZs[attacker_id]) < (unsigned int)(v19 * v19) ) - { - attacker_coord.x = AttackerInfo.pXs[attacker_id]; - attacker_coord.y = AttackerInfo.pYs[attacker_id]; - attacker_coord.z = AttackerInfo.pZs[attacker_id]; - if ( sub_407A1C(pActors[target_id].vPosition.x, pActors[target_id].vPosition.y, pActors[target_id].vPosition.z + 50, attacker_coord) ) - { - Vec3_int_::Normalize(&a1, &v48, &v44); - AttackerInfo.vec_4B4[attacker_id].x = a1; - AttackerInfo.vec_4B4[attacker_id].y = v48; - AttackerInfo.vec_4B4[attacker_id].z = v44; - Actor::ActorDamageFromMonster(AttackerInfo.pIDs[attacker_id], target_id, &AttackerInfo.vec_4B4[attacker_id], AttackerInfo.field_450[attacker_id]); - } - } - } - } - } - else //damage from spells(повреждения от заклов(метеоритный дождь)) - { - v23 = pParty->vPosition.y - AttackerInfo.pYs[attacker_id]; - v24 = ((signed int)pParty->uPartyHeight / 2) - AttackerInfo.pZs[attacker_id]; - a1 = pParty->vPosition.x - AttackerInfo.pXs[attacker_id]; - v48 = pParty->vPosition.y - AttackerInfo.pYs[attacker_id]; - if ( a1 * a1 + v23 * v23 + (pParty->vPosition.z + v24) * (pParty->vPosition.z + v24) < (unsigned int)((AttackerInfo.field_324[attacker_id] + 32) * (AttackerInfo.field_324[attacker_id] + 32)) ) - {//party damage (повреждения группе) - attacker_coord.x = AttackerInfo.pXs[attacker_id]; - attacker_coord.y = AttackerInfo.pYs[attacker_id]; - attacker_coord.z = AttackerInfo.pZs[attacker_id]; - if ( sub_407A1C(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + pParty->sEyelevel, attacker_coord) ) - { - for ( uint i = 0; i < 4; ++i ) - { - if ( !(HIDWORD(pParty->pPlayers[i].pConditions[Condition_Dead]) | LODWORD(pParty->pPlayers[i].pConditions[Condition_Dead])) - && !pParty->pPlayers[i].pConditions[Condition_Pertified] && !pParty->pPlayers[i].pConditions[Condition_Eradicated] ) - DamagePlayerFromMonster(AttackerInfo.pIDs[attacker_id], AttackerInfo.field_450[attacker_id], &AttackerInfo.vec_4B4[attacker_id], i); - } - } - } - if ( (signed int)uNumActors > 0 ) - {//actors damage(повреждения другим участникам) - for ( int actorID = 0; (signed int)actorID < (signed int)uNumActors; ++actorID ) - { - if ( pActors[actorID].CanAct() ) - { - //v30 = pActors[actorID].vPosition.y - AttackerInfo.pYs[attacker_id]; - a1 = pActors[actorID].vPosition.x - AttackerInfo.pXs[attacker_id]; - v31 = pActors[actorID].vPosition.z; - v48 = pActors[actorID].vPosition.y - AttackerInfo.pYs[attacker_id]; - v44 = pActors[actorID].vPosition.z; - v32 = (pActors[actorID].uActorHeight / 2) - AttackerInfo.pZs[attacker_id]; - v33 = pActors[actorID].uActorRadius + AttackerInfo.field_324[attacker_id]; - if ( a1 * a1 + v48 * v48 + (v31 + v32) * (v31 + v32) < (unsigned int)(v33 * v33) ) - { - attacker_coord.x = AttackerInfo.pXs[attacker_id]; - attacker_coord.y = AttackerInfo.pYs[attacker_id]; - attacker_coord.z = AttackerInfo.pZs[attacker_id]; - if ( sub_407A1C(pActors[actorID].vPosition.x, pActors[actorID].vPosition.y, pActors[actorID].vPosition.z + 50, attacker_coord) )//что делает ф-ция? - { - Vec3_int_::Normalize(&a1, &v48, &v44); - AttackerInfo.vec_4B4[attacker_id].x = a1; - AttackerInfo.vec_4B4[attacker_id].y = v48; - AttackerInfo.vec_4B4[attacker_id].z = v44; - switch ( attacker_type ) - { - case OBJECT_Player: - Actor::DamageMonsterFromParty(AttackerInfo.pIDs[attacker_id], actorID, &AttackerInfo.vec_4B4[attacker_id]); - break; - case OBJECT_Actor: - if ( v36 && pActors[v3].GetActorsRelation(&pActors[actorID]) ) - Actor::ActorDamageFromMonster(AttackerInfo.pIDs[attacker_id], actorID, &AttackerInfo.vec_4B4[attacker_id], v36->field_61); - break; - case OBJECT_Item: - ItemDamageFromActor(AttackerInfo.pIDs[attacker_id], actorID, &AttackerInfo.vec_4B4[attacker_id]); - break; - } - } - } - } - } - } - } - } - AttackerInfo.count = 0; -} - - -//----- (0043A97E) -------------------------------------------------------- -void __fastcall sub_43A97E(unsigned int uLayingItemID, signed int a2) -{ - if (PID_TYPE(a2) == OBJECT_Player) - { - layingitem_vel_50FDFC.x = pSpriteObjects[uLayingItemID].vVelocity.x; - layingitem_vel_50FDFC.y = pSpriteObjects[uLayingItemID].vVelocity.y; - layingitem_vel_50FDFC.z = pSpriteObjects[uLayingItemID].vVelocity.z; - - Vec3_int_::Normalize(&layingitem_vel_50FDFC.x, &layingitem_vel_50FDFC.y, &layingitem_vel_50FDFC.z); - DamagePlayerFromMonster(PID(OBJECT_Item, uLayingItemID), pSpriteObjects[uLayingItemID].field_61, &layingitem_vel_50FDFC, -1); - } - else if (PID_TYPE(a2) == OBJECT_Actor) - { - layingitem_vel_50FDFC.x = pSpriteObjects[uLayingItemID].vVelocity.x; - layingitem_vel_50FDFC.y = pSpriteObjects[uLayingItemID].vVelocity.y; - layingitem_vel_50FDFC.z = pSpriteObjects[uLayingItemID].vVelocity.z; - - Vec3_int_::Normalize(&layingitem_vel_50FDFC.x, &layingitem_vel_50FDFC.y, &layingitem_vel_50FDFC.z); - switch (PID_TYPE(pSpriteObjects[uLayingItemID].spell_caster_pid)) - { - case OBJECT_Actor: - Actor::ActorDamageFromMonster(PID(OBJECT_Item, uLayingItemID), PID_ID(a2), &layingitem_vel_50FDFC, pSpriteObjects[uLayingItemID].field_61); - break; - case OBJECT_Player: - Actor::DamageMonsterFromParty(PID(OBJECT_Item, uLayingItemID), PID_ID(a2), &layingitem_vel_50FDFC); - break; - case OBJECT_Item: - ItemDamageFromActor(PID(OBJECT_Item, uLayingItemID), PID_ID(a2), &layingitem_vel_50FDFC); - break; - } - } -} - -//----- (0043AE12) -------------------------------------------------------- -double __fastcall sub_43AE12(signed int a1) -{ - //signed int v1; // ST00_4@1 - signed int v2; // ecx@1 - double v3; // st7@1 - double result; // st7@6 - - v3 = (double)a1; - for ( v2 = 0; v2 < 5; ++v2 ) - { - if ( v3 < flt_4E4A80[v2 + 5] ) - break; - } - if ( v2 <= 0 || v2 >= 5 ) - { - if ( v2 ) - result = flt_4E4A80[4]; - else - result = flt_4E4A80[0]; - } - else - result = (flt_4E4A80[v2] - flt_4E4A80[v2 - 1]) * (v3 - flt_4E4A80[v2 + 4]) / (flt_4E4A80[v2 + 5] - flt_4E4A80[v2 + 4]) + flt_4E4A80[v2]; - return result; -} - -//----- (0043B057) -------------------------------------------------------- -void ItemDamageFromActor(unsigned int uObjID, unsigned int uActorID, Vec3_int_ *pVelocity) -{ - int v6; // eax@4 - int damage; // edi@4 - int a2a; // [sp+Ch] [bp-4h]@8 - - if ( !pActors[uActorID].IsNotAlive() ) - { - if ( PID_TYPE(uObjID) == OBJECT_Item) - { - if ( pSpriteObjects[PID_ID(uObjID)].spell_id ) - { - v6 = _43AFE3_calc_spell_damage(pSpriteObjects[PID_ID(uObjID)].spell_id, pSpriteObjects[PID_ID(uObjID)].spell_level, pSpriteObjects[PID_ID(uObjID)].spell_skill, pActors[uActorID].sCurrentHP); - damage = pActors[uActorID].CalcMagicalDamageToActor((DAMAGE_TYPE)0, v6); - pActors[uActorID].sCurrentHP -= damage; - if ( damage ) - { - if ( pActors[uActorID].sCurrentHP > 0 ) - Actor::AI_Stun(uActorID, uObjID, 0); - else - Actor::Die(uActorID); - a2a = 20 * damage / (signed int)pActors[uActorID].pMonsterInfo.uHP; - if ( 20 * damage / (signed int)pActors[uActorID].pMonsterInfo.uHP > 10 ) - a2a = 10; - if ( !MonsterStats::BelongsToSupertype(pActors[uActorID].pMonsterInfo.uID, MONSTER_SUPERTYPE_TREANT) ) - { - pVelocity->x = fixpoint_mul(a2a, pVelocity->x); - pVelocity->y = fixpoint_mul(a2a, pVelocity->y); - pVelocity->z = fixpoint_mul(a2a, pVelocity->z); - pActors[uActorID].vVelocity.x = 50 * LOWORD(pVelocity->x); - pActors[uActorID].vVelocity.y = 50 * LOWORD(pVelocity->y); - pActors[uActorID].vVelocity.z = 50 * LOWORD(pVelocity->z); - } - Actor::AddBloodsplatOnDamageOverlay(uActorID, 1, damage); - } - else - Actor::AI_Stun(uActorID, uObjID, 0); - } - } - } -} - - -//----- (0043F515) -------------------------------------------------------- -void FindBillboardsLightLevels_BLV() -{ - for (uint i = 0; i < uNumBillboardsToDraw; ++i) - { - if (pBillboardRenderList[i].field_1E & 2 || uCurrentlyLoadedLevelType == LEVEL_Indoor && !pBillboardRenderList[i].uIndoorSectorID) - pBillboardRenderList[i].dimming_level = 0; - else - pBillboardRenderList[i].dimming_level = _43F55F_get_billboard_light_level(&pBillboardRenderList[i], -1); - } -} - -//----- (0043F55F) -------------------------------------------------------- -int __fastcall _43F55F_get_billboard_light_level(RenderBillboard *a1, int uBaseLightLevel) -{ - signed int v3; // ecx@2 - - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) - v3 = pIndoor->pSectors[a1->uIndoorSectorID].uMinAmbientLightLevel; - else - { - if ( uBaseLightLevel == -1 ) - v3 = a1->dimming_level; - else - v3 = uBaseLightLevel; - } - return _43F5C8_get_point_light_level_with_respect_to_lights(v3, a1->uIndoorSectorID, a1->world_x, a1->world_y, a1->world_z); -} - -//----- (0043F5C8) -------------------------------------------------------- -int __fastcall _43F5C8_get_point_light_level_with_respect_to_lights(unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z) -{ -// int v5; // esi@1 - signed int v6; // edi@1 - int v8; // eax@6 - int v9; // ebx@6 - unsigned int v10; // ecx@6 - unsigned int v11; // edx@9 - unsigned int v12; // edx@11 - signed int v13; // ecx@12 - BLVLightMM7 *v16; // esi@20 - int v17; // ebx@21 -// int v18; // eax@24 -// int v19; // ebx@24 -// unsigned int v20; // ecx@24 -// int v21; // edx@25 -// unsigned int v22; // edx@27 -// unsigned int v23; // edx@29 - signed int v24; // ecx@30 - int v26; // ebx@35 -// int v27; // eax@38 -// int v28; // ebx@38 -// unsigned int v29; // ecx@38 -// int v30; // edx@39 -// unsigned int v31; // edx@41 -// unsigned int v32; // edx@43 - //signed int v33; // ecx@44 - int v37; // [sp+Ch] [bp-18h]@37 -// int v38; // [sp+10h] [bp-14h]@5 - int v39; // [sp+10h] [bp-14h]@23 - int v40; // [sp+10h] [bp-14h]@36 - int v42; // [sp+14h] [bp-10h]@22 - unsigned int v43; // [sp+18h] [bp-Ch]@12 - unsigned int v44; // [sp+18h] [bp-Ch]@30 - unsigned int v45; // [sp+18h] [bp-Ch]@44 - - v6 = uBaseLightLevel; - for (uint i = 0; i < pMobileLightsStack->uNumLightsActive; ++i) - { - MobileLight* p = &pMobileLightsStack->pLights[i]; - - float distX = abs(p->vPosition.x - x); - if ( distX <= p->uRadius) - { - float distY = abs(p->vPosition.y - y); - if ( distY <= p->uRadius) - { - float distZ = abs(p->vPosition.z - z); - if ( distZ <= p->uRadius) - { - v8 = distX; - v9 = distY; - v10 = distZ; - if (distX < distY) - { - v8 = distY; - v9 = distX; - } - if ( v8 < distZ ) - { - v11 = v8; - v8 = distZ; - v10 = v11; - } - if ( v9 < (signed int)v10 ) - { - v12 = v10; - v10 = v9; - v9 = v12; - } - v43 = ((unsigned int)(11 * v9) / 32) + (v10 / 4) + v8; - v13 = p->uRadius; - if ( (signed int)v43 < v13 ) - v6 += ((unsigned __int64)(30i64 * (signed int)(v43 << 16) / v13) >> 16) - 30; - } - } - } - } - - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor) - { - BLVSector* pSector = &pIndoor->pSectors[uSectorID]; - - for (uint i = 0; i < pSector->uNumLights; ++i) - { - v16 = pIndoor->pLights + pSector->pLights[i]; - if (~v16->uAtributes & 8) - { - v17 = abs(v16->vPosition.x - x); - if ( v17 <= v16->uRadius ) - { - v42 = abs(v16->vPosition.y - y); - if ( v42 <= v16->uRadius ) - { - v39 = abs(v16->vPosition.z - z); - if ( v39 <= v16->uRadius ) - { - v44 = int_get_vector_length(v17, v42, v39); - v24 = v16->uRadius; - if ( (signed int)v44 < v24 ) - v6 += ((unsigned __int64)(30i64 * (signed int)(v44 << 16) / v24) >> 16) - 30; - } - } - } - } - } - } - - for (uint i = 0; i < pStationaryLightsStack->uNumLightsActive; ++i) - { - //StationaryLight* p = &pStationaryLightsStack->pLights[i]; - v26 = abs(pStationaryLightsStack->pLights[i].vPosition.x - x); - if ( v26 <= pStationaryLightsStack->pLights[i].uRadius) - { - v40 = abs(pStationaryLightsStack->pLights[i].vPosition.y - y); - if ( v40 <= pStationaryLightsStack->pLights[i].uRadius) - { - v37 = abs(pStationaryLightsStack->pLights[i].vPosition.z - z); - if ( v37 <= pStationaryLightsStack->pLights[i].uRadius) - { - v45 = int_get_vector_length(v26, v40, v37); - //v33 = pStationaryLightsStack->pLights[i].uRadius; - if ( (signed int)v45 < pStationaryLightsStack->pLights[i].uRadius ) - v6 += ((unsigned __int64)(30i64 * (signed int)(v45 << 16) / pStationaryLightsStack->pLights[i].uRadius) >> 16) - 30; - } - } - } - } - - if ( v6 <= 31 ) - { - if ( v6 < 0 ) - v6 = 0; - } - else - v6 = 31; - return v6; -} - - - - - diff -r 0f17a30149ec -r 104fdbea0386 mm7_data.h --- a/mm7_data.h Sun Aug 17 15:13:18 2014 +0100 +++ b/mm7_data.h Sun Aug 17 17:49:34 2014 +0100 @@ -10,180 +10,12 @@ typedef unsigned int uint; -#pragma pack(push, 1) -struct DDM_DLV_Header -{ - //----- (00462607) -------------------------------------------------------- - inline DDM_DLV_Header() - { - this->uLastRepawnDay = 0; - this->uNumRespawns = 0; - this->uReputation = 0; - this->field_C_alert = 0; - this->uNumFacesInBModels = 0; - this->uNumDecorations = 0; - this->uNumBModels = 0; - } - - - int uNumRespawns; - int uLastRepawnDay; - int uReputation; - int field_C_alert; - unsigned int uNumFacesInBModels; - unsigned int uNumDecorations; - unsigned int uNumBModels; - int field_1C; - int field_20; - int field_24; -}; -#pragma pack(pop) - - -struct ODMFace; - - -/* 141 */ -// stru148 -#pragma pack(push, 1) -struct Polygon +inline void __fastcall memset32(void *ptr, unsigned __int32 value, int count) { - inline Polygon() - { - uNumVertices = 0; - } - - int _479295(); - //void _48276F_sr(); - void _normalize_v_18(); - void Create_48607B(struct stru149 *a2); - - float field_0; - float field_4; - float field_8; - float field_C; - float field_10; - unsigned int uNumVertices; - Vec3_int_ v_18; - int field_24; - int sTextureDeltaU; - int sTextureDeltaV; - __int16 flags; - __int16 field_32; - int field_34; - struct stru149 *ptr_38; - struct Texture *pTexture; - struct Span *_unused_prolly_head; - struct Span *_unused_prolly_tail; - int **ptr_48; - unsigned __int16 uTileBitmapID; - __int16 field_4E; - __int16 field_50; - __int16 field_52; - ODMFace *pODMFace; - char dimming_level; - char field_59; - char field_5A; - char field_5B; - char terrain_grid_z; - char terrain_grid_x; - unsigned __int8 uBModelID; - unsigned __int8 uBModelFaceID; - struct Edge *pEdgeList1[20]; - unsigned int uEdgeList1Size; - struct Edge *pEdgeList2[20]; - unsigned int uEdgeList2Size; - char field_108; - char field_109; - char field_10A; - char field_10B; -}; -#pragma pack(pop) -extern std::array array_77EC08; - - -/* 142 */ -#pragma pack(push, 1) -struct stru149 -{ - void _48616B_frustum_odm(int a2, int a3, int a4, int a5, int a6, int a7); - void _48653D_frustum_blv(int a2, int a3, int a4, int a5, int a6, int a7); - void _48694B_frustum_sky(); - - int field_0_party_dir_x; - int field_4_party_dir_y; - int field_8_party_dir_z; - int angle_from_north;//field_C - int angle_from_west;//field_10 - int viewing_angle_from_west_east; - int angle_from_east;//field_18 - int angle_from_south;//field_1C - int viewing_angle_from_north_south;//field_20 - int field_24; - int field_28; -}; -#pragma pack(pop) -extern stru149 stru_8019C8; - -/* 88 */ -#pragma pack(push, 1) -struct ODMRenderParams -{ - //----- (00462684) -------------------------------------------------------- - ODMRenderParams() - { - uPickDepth = 0; - this->shading_dist_shade = 2048; - shading_dist_shademist = 4096; - shading_dist_mist = 8192; - int_fov_rad = 0; - this->bNoSky = 0; - this->bDoNotRenderDecorations = 0; - this->field_5C = 0; - this->field_60 = 0; - this->outdoor_no_wavy_water = 0; - this->outdoor_no_mist = 0; - } - - void Initialize(); - - int uPickDepth; - int shading_dist_shade; - int shading_dist_shademist; - int shading_dist_mist; - unsigned int uCameraFovInDegrees; - int int_fov_rad; // 157 struct IndoorCamera::fov_rad - int int_fov_rad_inv; // 157 struct IndoorCamera::fov_rad_inv - int _unused_camera_rotation_y_int_sine; // merged with BLVRenderParams equivalents - int _unused_camera_rotation_y_int_cosine; // into IndoorCameraD3D - int _unused_camera_rotation_x_int_sine; // --//-- - int _unused_camera_rotation_x_int_cosine; // --//-- - int uNumPolygons; - unsigned int _unused_uNumEdges; - unsigned int _unused_uNumSurfs; - unsigned int _unused_uNumSpans; - unsigned int uNumBillboards; - float field_40; - int field_44; - int outdoor_grid_band_3; - int field_4C; - int field_50; - unsigned int bNoSky; - unsigned int bDoNotRenderDecorations; - int field_5C; - int field_60; - int outdoor_no_wavy_water; - int outdoor_no_mist; - int building_gamme; - int terrain_gamma; - - unsigned int uMapGridCellX; // moved from 157 struct IndoorCamera::0C - unsigned int uMapGridCellZ; // moved from 157 struct IndoorCamera::10 -}; -#pragma pack(pop) -extern ODMRenderParams *pODMRenderParams; - - + unsigned __int32* p = (unsigned __int32 *)ptr; + for (int i = 0; i < count; i++) + *p++ = value; +} diff -r 0f17a30149ec -r 104fdbea0386 mm7_unsorted_subs.h --- a/mm7_unsorted_subs.h Sun Aug 17 15:13:18 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -#pragma once -#include -#include - - -//------------------------------------------------------------------------- -// Function declarations -void check_event_triggers(); - - - - -//void ShowMM7IntroVideo_and_LoadingScreen(); - -bool __fastcall sub_407A1C(int x, int z, int y, struct Vec3_int_ v); // idb -void reset_some_strus_flt_2Cs(); -double get_shading_dist_mist(); -void area_of_effect__damage_evaluate(); -void __fastcall sub_43A97E(unsigned int uLayingItemID, signed int a2); // idb -double __fastcall sub_43AE12(signed int a1); -void ItemDamageFromActor(unsigned int uObjID, unsigned int uActorID, struct Vec3_int_ *pVelocity); -void FindBillboardsLightLevels_BLV(); -int __fastcall _43F55F_get_billboard_light_level(struct RenderBillboard *a1, int uBaseLightLevel); -int __fastcall _43F5C8_get_point_light_level_with_respect_to_lights(unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z); -bool _44100D_should_alter_right_panel(); -__int16 __fastcall sub_441A4E(int a1); -void LoadLevel_InitializeLevelStr(); -void OnMapLeave(); -void OnMapLoad(); -void Level_LoadEvtAndStr(const char *pLevelName); -void __fastcall sub_4451A8_press_any_key(int a1, int a2, int a4); -void CreateAsyncMouse(); -void CreateAsyncKeyboard(); -const char * _4B254D_SkillMasteryTeacher(int trainerInfo); -void __fastcall DrawTextAtStatusBar(const char *Str, int a5); -int HouseDialogPressCloseBtn(); -bool __fastcall IsBModelVisible(unsigned int uModelID, int *unused); -void ODM_LoadAndInitialize(const char *pLevelFilename, struct ODMRenderParams *thisa); -unsigned int GetLevelFogColor(); -int __fastcall sub_47C3D7_get_fog_specular(int a1, int a2, float a3); -int __fastcall GetActorTintColor(int max_dim, int min_dim, float distance, int a4, struct RenderBillboard *a5); -unsigned int WorldPosToGridCellX(int); // weak -unsigned int WorldPosToGridCellZ(int); // weak -int GridCellToWorldPosX(int); // weak -int GridCellToWorldPosZ(int); // weak -void sub_481ED9_MessWithODMRenderParams(); -bool IsTerrainSlopeTooHigh(int pos_x, int pos_y); -int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *a3, int a4); -void sub_487DA9(); -double GetFogDensityByTime(struct OutdoorLocation *_this); -void sub_491E3A(); -void _493938_regenerate(); -void init_summoned_item(struct stru351_summoned_item *_this, __int64 duration); -void _494035_timed_effects__water_walking_damage__etc(); -unsigned int __fastcall _494820_training_time(unsigned int a1); -const char *GetReputationString(signed int a1); -char *BuildDialogueString(const char *lpsz, unsigned __int8 uPlayerID, struct ItemGen *a3, char *a4, int a5, __int64 *a6); -unsigned int __fastcall GetMaxMipLevels(unsigned int uDim); -unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID); -void _46E0B2_collide_against_decorations(); -int _46E44E_collide_against_faces_and_portals(unsigned int b1); // idb -int __fastcall _46E889_collide_against_bmodels(unsigned int ecx0); -int collide_against_floor(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID); // idb -void __fastcall _46ED8A_collide_against_sprite_objects(unsigned int _this); -int _46EF01_collision_chech_player(int a1); // idb -int _46F04E_collide_against_portals(); -void UpdateObjects(); -int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID); // idb -bool sub_47531C(int a1, int *a2, int pos_x, int pos_y, int pos_z, int dir_x, int dir_y, int dir_z, struct BLVFace *face, int a10); -bool sub_4754BF(int a1, int *a2, int X, int Y, int Z, int dir_x, int dir_y, int dir_z, struct BLVFace *face, int a10, int a11); -int sub_475665(struct BLVFace *face, int a2, __int16 a3); -bool __fastcall sub_4759C9(struct BLVFace *face, int a2, int a3, __int16 a4); -bool __fastcall sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, struct BLVFace *a4); -bool __fastcall sub_475F30(int *a1, struct BLVFace *a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9); -void sub_4452BB(); -bool sub_4465DF_check_season(int a1); -void OnTimer(int); -void __fastcall sub_448CF4_spawn_monsters(__int16 typeindex, __int16 level, int count, int x, int y, int z, int group, unsigned int uUniqueName); -bool _449B57_test_bit(unsigned __int8 *a1, __int16 a2); -void _449B7E_toggle_bit(unsigned char *pArray, __int16 a2, unsigned __int16 bToggle); // idb -void ShowStatusBarString(const char *pString, unsigned int uNumSeconds); -void ShowNothingHereStatus(); -int const_2(); -bool TeleportToNWCDungeon(); -inline void __fastcall memset32(void *ptr, unsigned __int32 value, int count) -{ - unsigned __int32* p = (unsigned __int32 *)ptr; - for ( int i=0; i < count; i++ ) - *p++ = value; -} - diff -r 0f17a30149ec -r 104fdbea0386 stru298.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stru298.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -0,0 +1,21 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#include "stru298.h" + + +//----- (0040261D) -------------------------------------------------------- +void stru298::Add(__int16 uID, __int16 a3, __int16 x, __int16 y, __int16 z, char a7, char a8) +{ + if (count < 100) + { + pIDs[count] = uID; + pXs[count] = x; + pYs[count] = y; + pZs[count] = z; + field_324[count] = a3; + field_3EC[count] = a8; + field_450[count++] = a7; + } +} diff -r 0f17a30149ec -r 104fdbea0386 stru298.h --- a/stru298.h Sun Aug 17 15:13:18 2014 +0100 +++ b/stru298.h Sun Aug 17 17:49:34 2014 +0100 @@ -1,4 +1,5 @@ #pragma once +#include "VectorTypes.h" /* 303 */ #pragma pack(push, 1) diff -r 0f17a30149ec -r 104fdbea0386 stru6.cpp --- a/stru6.cpp Sun Aug 17 15:13:18 2014 +0100 +++ b/stru6.cpp Sun Aug 17 17:49:34 2014 +0100 @@ -29,6 +29,7 @@ #include "MM7.h" +#include "Indoor.h" @@ -1603,3 +1604,563 @@ pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell97c")); pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell97c")); } + +//----- (004775ED) -------------------------------------------------------- +int stru6_stru1_indoor_sw_billboard::_4775ED(float a2) +{ + char *v2; // edi@1 + //int v3; // eax@1 + char *v4; // edx@2 + char *v5; // esi@3 + double v6; // st7@6 + signed __int64 v7; // ST84_8@6 + double v8; // ST0C_8@6 + int v9; // esi@6 + double v10; // ST44_8@6 + int v11; // ecx@6 + double v12; // ST34_8@6 + int v13; // ecx@6 + double v14; // ST14_8@6 + double v15; // st7@8 + unsigned int v16; // ecx@8 + signed __int64 v17; // ST64_8@8 + double v18; // ST24_8@8 + int v19; // edi@8 + double v20; // ST3C_8@8 + int v21; // ecx@8 + double v22; // ST2C_8@8 + int v23; // ST9C_4@8 + double v24; // ST1C_8@8 + int *v25; // edi@8 + int v26; // esi@8 + int *v27; // edi@10 + int v28; // esi@10 + // int result; // eax@12 + __int64 v30; // [sp+A8h] [bp-30h]@8 + float v31; // [sp+B0h] [bp-28h]@6 + float v32; // [sp+B4h] [bp-24h]@6 + int v33; // [sp+B8h] [bp-20h]@6 + int v34; // [sp+BCh] [bp-1Ch]@2 + stru6_stru1_indoor_sw_billboard *v35; // [sp+C0h] [bp-18h]@1 + float v36; // [sp+C4h] [bp-14h]@6 + int v37; // [sp+C8h] [bp-10h]@6 + int v38; // [sp+CCh] [bp-Ch]@1 + float v39; // [sp+D0h] [bp-8h]@6 + int *v40; // [sp+D4h] [bp-4h]@2 + + // __debugbreak();//нужно почистить, срабатывает при применении закла Точечный взрыв и при стрельбе из жезла + v2 = (char *)&this->field_64[4 * this->uNumVertices]; + v38 = 0; + *(int *)v2 = this->field_64[0]; + v2 += 4; + *(int *)v2 = this->field_64[1]; + v2 += 4; + *(int *)v2 = this->field_64[2]; + *((int *)v2 + 1) = this->field_64[3]; + //v3 = this->uNumVertices; + v35 = this; + if (this->uNumVertices > 0) + { + v40 = &this->field_64[20]; + v4 = (char *)&this->field_64[3] + 3; + + //while ( 1 ) + for (v34 = this->uNumVertices; v34; --v34) + { + v5 = v4 - 15; + if (*(float *)(v4 - 15) <= (double)a2 && *(float *)(v4 + 1) <= (double)a2) + { + v4 += 16; + //--v34; + //if ( !v34 ) + //return this->uNumVertices = v38; + continue; + } + if (*(float *)v5 <= (double)a2) + { + v6 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5); + v7 = (unsigned __int8)v4[16] - (unsigned int)(unsigned __int8)*v4; + v36 = v6; + v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v6 + *(float *)(v4 - 11); + v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v6 + *(float *)(v4 - 7); + *(float *)&v37 = (double)v7 * v6; + v8 = *(float *)&v37 + 6.7553994e15; + v9 = (unsigned __int8)*v4; + *(float *)&v37 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36; + v10 = *(float *)&v37 + 6.7553994e15; + v11 = (unsigned __int8)*(v4 - 2); + v37 = LODWORD(v10) + (unsigned __int8)*(v4 - 1); + v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v11) * v36; + v12 = v39 + 6.7553994e15; + v13 = LODWORD(v12) + (unsigned __int8)*(v4 - 2); + v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36; + v14 = v39 + 6.7553994e15; + v33 = (LODWORD(v14) + (*(int *)(v4 - 3) & 0xFF)) | ((v13 | ((v37 | ((LODWORD(v8) + v9) << 8)) << 8)) << 8); + //this = v35; + v5 = (char *)&v30 + 4; + } + else if (*(float *)(v4 + 1) <= (double)a2) + { + v15 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5); + v16 = (unsigned __int8)*v4; + HIDWORD(v30) = LODWORD(a2); + v17 = (unsigned __int8)v4[16] - v16; + v36 = v15; + v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v15 + *(float *)(v4 - 11); + v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v15 + *(float *)(v4 - 7); + v39 = (double)v17 * v15; + v18 = v39 + 6.7553994e15; + v19 = (unsigned __int8)*v4; + v39 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36; + v20 = v39 + 6.7553994e15; + v21 = (unsigned __int8)*(v4 - 2); + v37 = LODWORD(v20) + (unsigned __int8)*(v4 - 1); + v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v21) * v36; + v22 = v39 + 6.7553994e15; + v23 = LODWORD(v22) + (unsigned __int8)*(v4 - 2); + v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36; + v24 = v39 + 6.7553994e15; + v33 = (LODWORD(v24) + (*(int *)(v4 - 3) & 0xFF)) | ((v23 | ((v37 | ((LODWORD(v18) + v19) << 8)) << 8)) << 8); + v25 = v40; + *v40 = *(int *)v5; + v26 = (int)(v5 + 4); + ++v25; + *v25 = *(int *)v26; + v26 += 4; + ++v25; + ++v38; + v40 += 4; + *v25 = *(int *)v26; + v25[1] = *(int *)(v26 + 4); + v5 = (char *)&v30 + 4; + } + v27 = v40; + ++v38; + *v40 = *(int *)v5; + v28 = (int)(v5 + 4); + ++v27; + *v27 = *(int *)v28; + v28 += 4; + ++v27; + v40 += 4; + *v27 = *(int *)v28; + v27[1] = *(int *)(v28 + 4); + v4 += 16; + //--v34; + //if ( !v34 ) + //return this->uNumVertices = v38; + } + } + return this->uNumVertices = v38; +} + +//----- (00477927) -------------------------------------------------------- +int stru6_stru1_indoor_sw_billboard::_477927(float a2) +{ + char *v2; // edi@1 + int v3; // eax@1 + char *v4; // edx@2 + char *v5; // esi@3 + double v6; // st7@6 + signed __int64 v7; // ST84_8@6 + double v8; // ST0C_8@6 + int v9; // esi@6 + double v10; // ST44_8@6 + int v11; // ecx@6 + double v12; // ST34_8@6 + int v13; // ecx@6 + double v14; // ST14_8@6 + double v15; // st7@8 + unsigned int v16; // ecx@8 + signed __int64 v17; // ST64_8@8 + double v18; // ST24_8@8 + int v19; // edi@8 + double v20; // ST3C_8@8 + int v21; // ecx@8 + double v22; // ST2C_8@8 + int v23; // ST9C_4@8 + double v24; // ST1C_8@8 + int *v25; // edi@8 + int v26; // esi@8 + int *v27; // edi@10 + int v28; // esi@10 + // int result; // eax@12 + __int64 v30; // [sp+A8h] [bp-30h]@8 + float v31; // [sp+B0h] [bp-28h]@6 + float v32; // [sp+B4h] [bp-24h]@6 + int v33; // [sp+B8h] [bp-20h]@6 + int v34; // [sp+BCh] [bp-1Ch]@2 + stru6_stru1_indoor_sw_billboard *v35; // [sp+C0h] [bp-18h]@1 + float v36; // [sp+C4h] [bp-14h]@6 + int v37; // [sp+C8h] [bp-10h]@6 + int v38; // [sp+CCh] [bp-Ch]@1 + float v39; // [sp+D0h] [bp-8h]@6 + int *v40; // [sp+D4h] [bp-4h]@2 + + __debugbreak();//нужно почистить + v2 = (char *)&this->field_64[4 * this->uNumVertices]; + v38 = 0; + *(int *)v2 = this->field_64[0]; + v2 += 4; + *(int *)v2 = this->field_64[1]; + v2 += 4; + *(int *)v2 = this->field_64[2]; + *((int *)v2 + 1) = this->field_64[3]; + v3 = this->uNumVertices; + v35 = this; + if (v3 > 0) + { + v40 = &this->field_64[20]; + v4 = (char *)&this->field_64[3] + 3; + v34 = v3; + while (1) + { + v5 = v4 - 15; + if (*(float *)(v4 - 15) >= (double)a2 && *(float *)(v4 + 1) >= (double)a2) + { + v4 += 16; + --v34; + if (!v34) + return this->uNumVertices = v38; + continue; + } + if (*(float *)v5 >= (double)a2) + { + v6 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5); + v7 = (unsigned __int8)v4[16] - (unsigned int)(unsigned __int8)*v4; + v36 = v6; + v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v6 + *(float *)(v4 - 11); + v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v6 + *(float *)(v4 - 7); + *(float *)&v37 = (double)v7 * v6; + v8 = *(float *)&v37 + 6.7553994e15; + v9 = (unsigned __int8)*v4; + *(float *)&v37 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36; + v10 = *(float *)&v37 + 6.7553994e15; + v11 = (unsigned __int8)*(v4 - 2); + v37 = LODWORD(v10) + (unsigned __int8)*(v4 - 1); + v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v11) * v36; + v12 = v39 + 6.7553994e15; + v13 = LODWORD(v12) + (unsigned __int8)*(v4 - 2); + v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36; + v14 = v39 + 6.7553994e15; + v33 = (LODWORD(v14) + (*(int *)(v4 - 3) & 0xFF)) | ((v13 | ((v37 | ((LODWORD(v8) + v9) << 8)) << 8)) << 8); + //this = v35; + v5 = (char *)&v30 + 4; + } + else if (*(float *)(v4 + 1) >= (double)a2) + { + v15 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5); + v16 = (unsigned __int8)*v4; + HIDWORD(v30) = LODWORD(a2); + v17 = (unsigned __int8)v4[16] - v16; + v36 = v15; + v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v15 + *(float *)(v4 - 11); + v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v15 + *(float *)(v4 - 7); + v39 = (double)v17 * v15; + v18 = v39 + 6.7553994e15; + v19 = (unsigned __int8)*v4; + v39 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36; + v20 = v39 + 6.7553994e15; + v21 = (unsigned __int8)*(v4 - 2); + v37 = LODWORD(v20) + (unsigned __int8)*(v4 - 1); + v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v21) * v36; + v22 = v39 + 6.7553994e15; + v23 = LODWORD(v22) + (unsigned __int8)*(v4 - 2); + v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36; + v24 = v39 + 6.7553994e15; + v33 = (LODWORD(v24) + (*(int *)(v4 - 3) & 0xFF)) | ((v23 | ((v37 | ((LODWORD(v18) + v19) << 8)) << 8)) << 8); + v25 = v40; + *v40 = *(int *)v5; + v26 = (int)(v5 + 4); + ++v25; + *v25 = *(int *)v26; + v26 += 4; + ++v25; + ++v38; + v40 += 4; + *v25 = *(int *)v26; + v25[1] = *(int *)(v26 + 4); + v5 = (char *)&v30 + 4; + } + v27 = v40; + ++v38; + *v40 = *(int *)v5; + v28 = (int)(v5 + 4); + ++v27; + *v27 = *(int *)v28; + v28 += 4; + ++v27; + v40 += 4; + *v27 = *(int *)v28; + v27[1] = *(int *)(v28 + 4); + v4 += 16; + --v34; + if (!v34) + return this->uNumVertices = v38; + } + } + return this->uNumVertices = v38; +} + +//----- (00477C61) -------------------------------------------------------- +int stru6_stru1_indoor_sw_billboard::sub_477C61() +{ + //stru6_stru1_indoor_sw_billboard *v1; // ebx@1 + int v2; // ecx@2 + int v3; // eax@3 + double v4; // st7@4 + double v5; // st7@5 + double v6; // st6@5 + double v7; // st5@6 + float v8; // ST30_4@8 + float v9; // ST24_4@8 + double v10; // st7@8 + double v11; // st6@8 + double v12; // st5@8 + float v13; // ST24_4@13 + int v14; // esi@13 + char *v15; // esi@15 + //signed int v16; // eax@16 + // __int16 v17; // fps@16 + // unsigned __int8 v18; // c2@16 + // unsigned __int8 v19; // c3@16 + double v20; // st6@16 + float v21; // ST18_4@17 + float v22; // ST2C_4@17 + float v23; // ST34_4@17 + float v24; // ST24_4@17 + double v25; // st7@17 + double v26; // st6@17 + float v27; // ST34_4@18 + float v28; // ST30_4@18 + int v29; // eax@19 + signed int v31; // [sp+8h] [bp-28h]@15 + float v32; // [sp+Ch] [bp-24h]@16 + float v33; // [sp+14h] [bp-1Ch]@16 + float v34; // [sp+18h] [bp-18h]@16 + float v35; // [sp+1Ch] [bp-14h]@17 + float v36; // [sp+20h] [bp-10h]@4 + float v37; // [sp+24h] [bp-Ch]@4 + float v38; // [sp+24h] [bp-Ch]@16 + float v39; // [sp+28h] [bp-8h]@9 + float v40; // [sp+28h] [bp-8h]@16 + float v41; // [sp+2Ch] [bp-4h]@6 + float v42; // [sp+2Ch] [bp-4h]@9 + + //__debugbreak();//нужно почистить, срабатывает при применении закла Точечный взрыв + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + + if (this->uNumVertices > 0) + { + v3 = (int)&this->field_14[1]; + //do + for (v2 = 0; v2 < this->uNumVertices; ++v2) + { + v4 = *(float *)(v3 - 4); + LODWORD(v37) = *(int *)v3; + LODWORD(v36) = *(int *)(v3 + 4); + if (pGame->pIndoorCameraD3D->sRotationX) + { + v5 = v4 - (double)pGame->pIndoorCameraD3D->vPartyPos.x; + v6 = v37 - (double)pGame->pIndoorCameraD3D->vPartyPos.y; + //if ( pRenderer->pRenderD3D ) + //{ + v41 = pGame->pIndoorCameraD3D->fRotationYSine * v6 + pGame->pIndoorCameraD3D->fRotationYCosine * v5; + v7 = pGame->pIndoorCameraD3D->fRotationYSine * v5 - pGame->pIndoorCameraD3D->fRotationYCosine * v6; + /*} + else + { + v41 = pBLVRenderParams->fCosineY * v5 - pBLVRenderParams->fSineY * v6; + v7 = pBLVRenderParams->fSineY * v5 + pBLVRenderParams->fCosineY * v6; + }*/ + v8 = v7; + v9 = v36 - (double)pGame->pIndoorCameraD3D->vPartyPos.z; + v10 = pGame->pIndoorCameraD3D->fRotationXCosine * v41 - pGame->pIndoorCameraD3D->fRotationXSine * v9; + v11 = v8; + v12 = pGame->pIndoorCameraD3D->fRotationXCosine * v9 + pGame->pIndoorCameraD3D->fRotationXSine * v41; + } + else + { + v42 = v4 - (double)pGame->pIndoorCameraD3D->vPartyPos.x; + v39 = v37 - (double)pGame->pIndoorCameraD3D->vPartyPos.y; + //if ( pRenderer->pRenderD3D ) + //{ + v10 = pGame->pIndoorCameraD3D->fRotationYSine * v39 + pGame->pIndoorCameraD3D->fRotationYCosine * v42; + v11 = pGame->pIndoorCameraD3D->fRotationYSine * v42 - pGame->pIndoorCameraD3D->fRotationYCosine * v39; + /*} + else + { + v10 = pBLVRenderParams->fCosineY * v42 - pBLVRenderParams->fSineY * v39; + v11 = pBLVRenderParams->fSineY * v42 + pBLVRenderParams->fCosineY * v39; + }*/ + v12 = v36 - (double)pGame->pIndoorCameraD3D->vPartyPos.z; + } + v13 = v12; + //++v2; + *(int *)(v3 + 84) = LODWORD(v13); + v14 = *(int *)(v3 + 8); + *(float *)(v3 + 76) = v10; + *(int *)(v3 + 88) = v14; + *(float *)(v3 + 80) = v11; + v3 += 16; + } + //while ( v2 < this->uNumVertices ); + } + } + else + { + v15 = (char *)&this->field_14[1]; + //do + for (v31 = 3; v31; --v31) + { + v40 = (double)stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX) * 0.0000152587890625; + v32 = (double)stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX) * 0.0000152587890625; + v34 = (double)stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY) * 0.0000152587890625; + v33 = (double)stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY) * 0.0000152587890625; + //v16 = stru_5C6E00->Sin(pODMRenderParams->rotation_y); + LODWORD(v38) = *(int *)v15; + //UNDEF(v17); + v20 = *((float *)v15 - 1) - (double)pGame->pIndoorCameraD3D->vPartyPos.x; + //if ( v19 | v18 ) + if (pGame->pIndoorCameraD3D->vPartyPos.x == 0) + { + v27 = v20; + LODWORD(v35) = *((int *)v15 + 1); + v28 = v38 - (double)pGame->pIndoorCameraD3D->vPartyPos.y; + v25 = v33 * v28 + v34 * v27; + v26 = v34 * v28 - v33 * v27; + } + else + { + v21 = v20; + v22 = v38 - (double)pGame->pIndoorCameraD3D->vPartyPos.y; + v23 = v33 * v22 + v34 * v21; + v24 = *((float *)v15 + 1) - (double)pGame->pIndoorCameraD3D->vPartyPos.z; + v25 = v32 * v24 + v40 * v23; + v26 = v34 * v22 - v33 * v21; + v35 = v40 * v24 - v32 * v23; + } + *((int *)v15 + 21) = LODWORD(v35); + v29 = *((int *)v15 + 2); + *((float *)v15 + 19) = v25; + *((int *)v15 + 22) = v29; + *((float *)v15 + 20) = v26; + v15 += 16; + //--v31; + } + //while ( v31 ); + } + this->uNumVertices = 3; + return 1; +} + +//----- (00477F63) -------------------------------------------------------- +bool stru6_stru1_indoor_sw_billboard::sub_477F63() +{ + signed int v1; // ebx@1 + double v3; // st7@2 + //int v4; // edx@4 + char *v5; // ecx@5 + int v6; // edi@5 + float v7; // ST08_4@13 + signed int v9; // [sp+Ch] [bp-8h]@1 + float v10; // [sp+10h] [bp-4h]@2 + + //__debugbreak();// почистить + v1 = 0; + v9 = 0; + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + v10 = 16192.0; + v3 = (double)pBLVRenderParams->fov_rad_fixpoint * 0.000015258789; + } + else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + { + v10 = (double)pODMRenderParams->shading_dist_mist; + v3 = 8.0; + } + else + __debugbreak();//Error + if (this->uNumVertices <= 0) + { + memcpy(&this->field_14[40], &this->field_14[20], 16 * this->uNumVertices); + return this->uNumVertices != 0; + } + v5 = (char *)&this->field_14[20]; + for (v6 = 0; v6 < this->uNumVertices; v6++) + { + if (v3 >= *(float *)v5 || *(float *)v5 >= (double)v10) + { + if (v3 < *(float *)v5) + v9 = 1; + else + v1 = 1; + } + v5 += 16; + } + if (!v1) + { + if (v9) + { + this->_477927(v10); + return this->uNumVertices != 0; + } + memcpy(&this->field_14[40], &this->field_14[20], 16 * this->uNumVertices); + return this->uNumVertices != 0; + } + v7 = v3; + _4775ED(v7); + return this->uNumVertices != 0; +} + +//----- (0047802A) -------------------------------------------------------- +int stru6_stru1_indoor_sw_billboard::sub_47802A() +{ + double v6; // st7@4 + signed int v16; // [sp+38h] [bp-Ch]@1 + int a6; // [sp+3Ch] [bp-8h]@5 + int a5; // [sp+40h] [bp-4h]@5 + + // __debugbreak(); //необходимо проверить this->field_B4[i*4+16] + v16 = 0; + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + for (int i = 0; i < this->uNumVertices; i++) + { + v6 = (double)pBLVRenderParams->fov_rad_fixpoint * 0.000015258789 / this->field_B4[i * 4]; + //if ( pRenderer->pRenderD3D ) + { + pGame->pIndoorCameraD3D->Project(round_to_int(this->field_B4[i * 4]), round_to_int(this->field_B4[i * 4 + 1]), round_to_int(this->field_B4[i * 4 + 2]), + &a5, &a6); + this->field_B4[i * 4 + 16] = (double)a5; + this->field_B4[i * 4 + 17] = (double)a6; + this->field_B4[i * 4 + 18] = round_to_int(this->field_B4[i * 4]); + } + /*else + { + this->field_B4[i*4+16] = (double)pBLVRenderParams->uViewportCenterX - v6 * this->field_B4[i*4+1]; + this->field_B4[i*4+17] = (double)pBLVRenderParams->uViewportCenterY - v6 * this->field_B4[i*4+2]; + this->field_B4[i*4+18] = this->field_B4[i*4]; + }*/ + this->field_B4[i * 4 + 19] = this->field_B4[i * 4 + 3]; + if ((double)(signed int)pViewport->uViewportTL_X <= this->field_B4[i * 4 + 16] && (double)(signed int)pViewport->uViewportBR_X > this->field_B4[i * 4 + 16] + && (double)(signed int)pViewport->uViewportTL_Y <= this->field_B4[i * 4 + 17] && (double)(signed int)pViewport->uViewportBR_Y > this->field_B4[i * 4 + 17]) + v16 = 1; + } + } + else + { + for (int i = 0; i < this->uNumVertices; i++) + { + this->field_B4[i * 4 + 20] = (double)pViewport->uScreenCenterX - (double)pODMRenderParams->int_fov_rad / this->field_B4[i * 4] * this->field_B4[i * 4 + 1]; + this->field_B4[i * 4 + 21] = (double)pViewport->uScreenCenterY - (double)pODMRenderParams->int_fov_rad / this->field_B4[i * 4] * this->field_B4[i * 4 + 2]; + *((int *)&this->field_B4[i * 4 + 22]) = (int)this->field_B4[i * 4]; + *((int *)&this->field_B4[i * 4 + 23]) = this->field_B4[i * 4 + 3]; + if ((double)(signed int)pViewport->uViewportTL_X <= this->field_B4[i * 4 + 20] && (double)(signed int)pViewport->uViewportBR_X > this->field_B4[i * 4 + 20] + && (double)(signed int)pViewport->uViewportTL_Y <= this->field_B4[i * 4 + 21] && (double)(signed int)pViewport->uViewportBR_Y > this->field_B4[i * 4 + 21]) + v16 = 1; + } + } + return v16; +}