Mercurial > mm7
view Party.cpp @ 1688:ece764a4672d
Player::StealFromActor finishing cleanup
author | Grumpy7 |
---|---|
date | Sun, 22 Sep 2013 04:31:34 +0200 |
parents | 51a74615d956 |
children | 8251e59fd7c1 |
line wrap: on
line source
#ifdef _MSC_VER #define _CRT_SECURE_NO_WARNINGS #endif #include "Party.h" #include "MapInfo.h" #include "Time.h" #include "AudioPlayer.h" #include "IconFrameTable.h" #include "Mouse.h" #include "PlayerFrameTable.h" #include "TurnEngine.h" #include "Viewport.h" #include "Actor.h" #include "GUIWindow.h" #include "texts.h" #include "mm7_data.h" #include "MM7.h" #include "Outdoor.h" #include "Indoor.h" #include "Texture.h" #include "LOD.h" #include "Sprites.h" #include "SpriteObject.h" #include "ObjectList.h" #include "Conditions.h" Party *pParty; // idb struct ActionQueue *pPartyActionQueue = new ActionQueue; //----- (0044A56A) -------------------------------------------------------- void Party::CountHirelings() { field_70A = 0; for (int i = 0; i < pNPCStats->uNumNewNPCs; ++i) { auto npc = pNPCStats->pNewNPCData + i; if (npc->Hired() && (!pHirelings[0].pName || strcmp(npc->pName, pHirelings[0].pName))) { if (!pHirelings[1].pName || strcmp(npc->pName, pHirelings[1].pName)) ++field_70A; } } } // inlined //----- (mm6c::004858D0) -------------------------------------------------- void Party::Zero() { uFlags2 = 0; uNumGoldInBank = 0; uCurrentYear = 0; uCurrentMonth = 0; uCurrentMonthWeek = 0; uDaysPlayed = 0; uCurrentHour = 0; uCurrentMinute = 0; uCurrentTimeSecond = 0; field_6FC = 0; days_played_without_rest = 0; vPosition.y = 0; vPosition.z = 0; vPosition.x = 0; uFallStartY = 0; sRotationY = 0; sRotationX = 0; uFallSpeed = 0; field_28 = 0; uDefaultPartyHeight = 120; field_14_radius = 37; y_rotation_granularity = 25; y_rotation_speed = 90; uWalkSpeed = 384; walk_sound_timer = 0; field_24 = 5; field_6FC = 0; field_708 = 15; field_0 = 25; } //inlined //----- (mm6c::0045BE90) -------------------------------------------------- void ActionQueue::Reset() { uNumActions = 0; } //----- (004760C1) -------------------------------------------------------- void ActionQueue::Add(PartyAction action) { if (uNumActions < 30) pActions[uNumActions++] = action; } //----- (00497FC5) -------------------------------------------------------- bool Party::_497FC5_check_party_perception_against_level() { int uMaxPerception; // edi@1 Player *v2; // esi@1 signed int v3; // ebx@1 Player *v4; // ecx@2 signed int v5; // eax@3 bool result; // eax@7 uMaxPerception = 0; v2 = this->pPlayers; v3 = 4; do { if ( v2->CanAct() ) { v5 = v2->GetPerception(); if ( v5 > uMaxPerception ) uMaxPerception = v5; } ++v2; --v3; } while ( v3 ); if ( uLevelMapStatsID && (signed int)uLevelMapStatsID < 77 ) result = uMaxPerception >= 2 * pMapStats->pInfos[uLevelMapStatsID]._per; else result = 0; return result; } //----- (004936E1) -------------------------------------------------------- void Party::SetHoldingItem(ItemGen *pItem) { sub_421B2C_PlaceInInventory_or_DropPickedItem(); memcpy(&pPickedItem, pItem, sizeof(pPickedItem)); pMouse->SetCursorBitmapFromItemID(pPickedItem.uItemID); } //----- (0049370F) -------------------------------------------------------- int Party::GetNextActiveCharacter() { Party *v1; // esi@1 int v2; // eax@4 signed int v4; // ecx@6 Player *v5; // edx@6 Player *v6; // eax@7 Player *v7; // ecx@23 signed int v8; // esi@23 signed int v9; // edx@23 Player **v10; // edi@23 Player *v11; // eax@24 int v12; // [sp+Ch] [bp-4h]@1 v1 = this; v12 = 0; if ( pParty->bTurnBasedModeOn == 1 ) { if ( pTurnEngine->turn_stage != 2 || PID_TYPE(pTurnEngine->pQueue[0].uPackedID) != OBJECT_Player) return 0; v2 = PID_ID(pTurnEngine->pQueue[0].uPackedID); return v2 + 1; } v4 = 0; v5 = v1->pPlayers;//[0].uTimeToRecovery; while ( 1 ) { v6 = ::pPlayers[v4 + 1]; if ( v6->pConditions[2] || v6->pConditions[12] || v6->pConditions[13] || v6->pConditions[14] || v6->pConditions[15] || v6->pConditions[16] || v5->uTimeToRecovery ) { byte_AE3368[v4] = 1; } else if ( !byte_AE3368[v4] ) break; ++v4; ++v5; if ( v4 >= 4 ) break; } if(v4<4) { v12 = v4; byte_AE3368[v4] = 1; } if ( (unsigned __int8)(byte_AE3369 & byte_AE336A & byte_AE336B) & byte_AE3368[0] ) memset(byte_AE3368.data(), 0, 4u); v2 = v12; if ( v12 ) return v2 + 1; v7 = v1->pPlayers;//[0].uSpeedBonus; v8 = 0; v9 = 1; v10 = &::pPlayers[1]; while ( 2 ) { v11 = *v10; if ( !(*v10)->pConditions[2] && !v11->pConditions[12] && !v11->pConditions[13] && !v11->pConditions[14] && !v11->pConditions[15] && !v11->pConditions[16] && !v7->uTimeToRecovery ) { if ( v12 ) { if ( v7->uSpeedBonus > v8 ) { v8 = v7->uSpeedBonus; v12 = v9; } } else { v8 = *(short *)v7; v12 = v9; } } ++v10; ++v9; ++v7; if ( v9 - 1 < 4 ) continue; return v12; } } //----- (00493244) -------------------------------------------------------- bool Party::HasItem(unsigned int uItemID) { Player *v2; // edx@1 signed int v3; // ecx@2 ItemGen *v4; // eax@2 v2 = pParty->pPlayers;//[0].pInventoryItems; while ( v2 <= &pParty->pPlayers[3] ) { v3 = 0; v4 = v2->pInventoryItemList; do { if ( v4->uItemID == uItemID ) return 1; ++v3; ++v4; } while ( v3 < 138 ); ++v2; } return 0; } //----- (00492AD5) -------------------------------------------------------- void Party::SetFood(unsigned int uNumFood) { pUIAnim_Food->uAnimTime = 0; pParty->uNumFoodRations = uNumFood; pUIAnim_Food->uAnimLength = 8 * pIconsFrameTable->pIcons[pUIAnim_Food->uIconID].uAnimLength; } //----- (00492B03) -------------------------------------------------------- void Party::TakeFood(unsigned int uNumFood) { if (pParty->uNumFoodRations <= uNumFood) pParty->uNumFoodRations = 0; else pParty->uNumFoodRations -= uNumFood; pUIAnim_Food->uAnimTime = 0; pUIAnim_Food->uAnimLength = 8 * pIconsFrameTable->pIcons[pUIAnim_Food->uIconID].uAnimLength; } //----- (00492B42) -------------------------------------------------------- void Party::GiveFood(unsigned int _this) { pParty->uNumFoodRations += _this; pUIAnim_Food->uAnimTime = 0; pUIAnim_Food->uAnimLength = 8 * pIconsFrameTable->pIcons[pUIAnim_Food->uIconID].uAnimLength; } //----- (00492B70) -------------------------------------------------------- void Party::SetGold(unsigned int uNumGold) { pParty->uNumGold = uNumGold; pUIAnim_Gold->uAnimTime = 0; pUIAnim_Gold->uAnimLength = 8 * pIconsFrameTable->pIcons[pUIAnim_Gold->uIconID].uAnimLength; pAudioPlayer->PlaySound(SOUND_GoldReceived, 0, 0, -1, 0, 0, 0, 0); } //----- (00492BB6) -------------------------------------------------------- void Party::TakeGold(unsigned int uNumGold) { if ( uNumGold <= pParty->uNumGold ) pParty->uNumGold -= uNumGold; else pParty->uNumGold = 0; pUIAnim_Gold->uAnimTime = 0; pUIAnim_Gold->uAnimLength = 8 * pIconsFrameTable->pIcons[pUIAnim_Gold->uIconID].uAnimLength; pAudioPlayer->PlaySound(SOUND_GoldReceived, 0, 0, -1, 0, 0, 0, 0); } //----- (0049135E) -------------------------------------------------------- unsigned int Party::GetPartyFame() { unsigned __int64 total_exp = 0; for (uint i = 0; i < 4; ++i) total_exp += pPlayers[i].uExperience; return total_exp / 1000; } //----- (0049137D) -------------------------------------------------------- void Party::CreateDefaultParty(char bGiveItems) { Party *pParty; // esi@1 signed __int16 v3; // ax@1 //int pResMagicBase; // ecx@1 Player *pCharacter; // esi@3 //signed int uSpellBookPageCount; // edx@5 int pMagicSkills; // eax@5 int uSkillIdx; // eax@11 //unsigned __int8 v9; // zf@37 //char v10; // sf@37 //unsigned __int8 v11; // of@37 ItemGen *pItems; // eax@38 signed int v13; // ecx@38 int uMaxSP; // eax@42 unsigned int v15; // [sp-4h] [bp-44h]@14 unsigned int v16; // [sp-4h] [bp-44h]@26 int v17; // [sp+10h] [bp-30h]@1 int v18; // [sp+14h] [bp-2Ch]@11 signed int uNumPlayers; // [sp+18h] [bp-28h]@1 ItemGen Dst; // [sp+1Ch] [bp-24h]@10 pParty = this; pHireling1Name[0] = 0; pHireling2Name[0] = 0; pParty->field_709 = 0; memset(pHirelings, 0, 2 * sizeof(*pHirelings)); strcpy(this->pPlayers[0].pName, pGlobalTXT_LocalizationStrings[509]); //Zoltan pParty->pPlayers[0].uPrevFace = 17; pParty->pPlayers[0].uCurrentFace = 17; pParty->pPlayers[0].uPrevVoiceID = 17; pParty->pPlayers[0].uVoiceID = 17; pParty->pPlayers[0].uMight = 30; pParty->pPlayers[0].uIntelligence = 5; pParty->pPlayers[0].uWillpower = 5; pParty->pPlayers[0].uEndurance = 13; pParty->pPlayers[0].uAccuracy = 13; pParty->pPlayers[0].uSpeed = 14; pParty->pPlayers[0].uLuck = 7; pParty->pPlayers[0].pActiveSkills[PLAYER_SKILL_LEATHER] = 1; // leather pParty->pPlayers[0].pActiveSkills[PLAYER_SKILL_ARMSMASTER] = 1; // armsmaster pParty->pPlayers[0].pActiveSkills[PLAYER_SKILL_BOW] = 1; // bow pParty->pPlayers[0].pActiveSkills[PLAYER_SKILL_SWORD] = 1; // sword pParty->pPlayers[1].uPrevFace = 3; pParty->pPlayers[1].uCurrentFace = 3; pParty->pPlayers[1].uPrevVoiceID = 3; pParty->pPlayers[1].uVoiceID = 3; strcpy(pParty->pPlayers[1].pName, pGlobalTXT_LocalizationStrings[506]); //Roderic pParty->pPlayers[1].uMight = 13; pParty->pPlayers[1].uIntelligence = 9; pParty->pPlayers[1].uWillpower = 9; pParty->pPlayers[1].uEndurance = 13; pParty->pPlayers[1].uAccuracy = 13; pParty->pPlayers[1].uSpeed = 13; pParty->pPlayers[1].uLuck = 13; pParty->pPlayers[1].pActiveSkills[PLAYER_SKILL_LEATHER] = 1; // leather pParty->pPlayers[1].pActiveSkills[PLAYER_SKILL_STEALING] = 1; // stealing pParty->pPlayers[1].pActiveSkills[PLAYER_SKILL_DAGGER] = 1; // dagger pParty->pPlayers[1].pActiveSkills[PLAYER_SKILL_TRAP_DISARM] = 1; // disarm trap pParty->pPlayers[2].uPrevFace = 14; pParty->pPlayers[2].uCurrentFace = 14; pParty->pPlayers[2].uPrevVoiceID = 14; pParty->pPlayers[2].uVoiceID = 14; strcpy(pParty->pPlayers[2].pName, pGlobalTXT_LocalizationStrings[508]); // Serena pParty->pPlayers[2].uMight = 12; pParty->pPlayers[2].uIntelligence = 9; pParty->pPlayers[2].uWillpower = 20; pParty->pPlayers[2].uEndurance = 22; pParty->pPlayers[2].uAccuracy = 7; pParty->pPlayers[2].uSpeed = 13; pParty->pPlayers[2].uLuck = 7; pParty->pPlayers[2].pActiveSkills[PLAYER_SKILL_ALCHEMY] = 1; // alchemy pParty->pPlayers[2].pActiveSkills[PLAYER_SKILL_LEATHER] = 1; // leather pParty->pPlayers[2].pActiveSkills[PLAYER_SKILL_BODY] = 1; // body pParty->pPlayers[2].pActiveSkills[PLAYER_SKILL_MACE] = 1; // mace strcpy(pParty->pPlayers[3].pName, pGlobalTXT_LocalizationStrings[507]); // Alexis v3 = 10; pParty->pPlayers[3].uPrevFace = 10; pParty->pPlayers[3].uCurrentFace = 10; //pResMagicBase = (int)&pParty->pPlayers[0].sResMagicBase; pParty->pPlayers[3].uEndurance = 13; pParty->pPlayers[3].uAccuracy = 13; pParty->pPlayers[3].uSpeed = 13; pParty->pPlayers[3].uPrevVoiceID = 10; pParty->pPlayers[3].uVoiceID = 10; pParty->pPlayers[3].uMight = 5; pParty->pPlayers[3].uIntelligence = 30; pParty->pPlayers[3].uWillpower = 9; pParty->pPlayers[3].uLuck = 7; pParty->pPlayers[3].pActiveSkills[PLAYER_SKILL_LEATHER] = 1; // leather pParty->pPlayers[3].pActiveSkills[PLAYER_SKILL_AIR] = 1; // air pParty->pPlayers[3].pActiveSkills[PLAYER_SKILL_FIRE] = 1; // fire pParty->pPlayers[3].pActiveSkills[PLAYER_SKILL_STAFF] = 1; // staff //uNumPlayers = 4; //while ( 1 ) for (uNumPlayers = 0; uNumPlayers < 4; uNumPlayers++) { pCharacter = &pParty->pPlayers[uNumPlayers]; if (pCharacter->classType == PLAYER_CLASS_KNIGHT) pCharacter->sResMagicBase = v3; //player[i].pResMagicBase //uSpellBookPageCount = 0; //pMagicSkills = pPlayers[uNumPlayers].pActiveSkills[12];// Skills //while ( !*(short *)pMagicSkills ) //player[i].skillFire pCharacter->lastOpenedSpellbookPage = 0; for (int i = 0; i < 9; i++)//for Magic Book { //++uSpellBookPageCount; //pMagicSkills++; //if ( uSpellBookPageCount >= 9 ) //goto LABEL_10; if (pPlayers[uNumPlayers].pActiveSkills[12+i]) { pCharacter->lastOpenedSpellbookPage = i; break; } } //LABEL_10: pCharacter->uExpressionTimePassed = 0; Dst.Reset(); if ( bGiveItems ) { pItemsTable->GenerateItem(2, 40, &Dst); //ring pCharacter->AddItem2(-1, &Dst); //uSkillIdx = 0; //v18 = 0; //do for (uSkillIdx = 0; uSkillIdx < 36; uSkillIdx++) { if ( pCharacter->pActiveSkills[uSkillIdx] ) { switch ( uSkillIdx ) { case PLAYER_SKILL_STAFF: v15 = ITEM_STAFF_1; pCharacter->WearItem(v15); break; case PLAYER_SKILL_SWORD: v15 = ITEM_LONGSWORD_1; pCharacter->WearItem(v15); break; case PLAYER_SKILL_DAGGER: v15 = ITEM_DAGGER_1; pCharacter->WearItem(v15); break; case PLAYER_SKILL_AXE: v15 = ITEM_AXE_1; pCharacter->WearItem(v15); break; case PLAYER_SKILL_SPEAR: v15 = ITEM_SPEAR_1; pCharacter->WearItem(v15); break; case PLAYER_SKILL_BOW: v15 = ITEM_CROSSBOW_1; pCharacter->WearItem(v15); break; case PLAYER_SKILL_MACE: v15 = ITEM_MACE_1; pCharacter->WearItem(v15); break; case PLAYER_SKILL_SHIELD: v15 = ITEM_BUCKLER_1; pCharacter->WearItem(v15); break; case PLAYER_SKILL_LEATHER: v15 = ITEM_LEATHER_1; pCharacter->WearItem(v15); break; case PLAYER_SKILL_CHAIN: v15 = ITEM_CHAINMAIL_1; pCharacter->WearItem(v15); break; case PLAYER_SKILL_PLATE: v15 = ITEM_PLATE_1; pCharacter->WearItem(v15); break; case PLAYER_SKILL_FIRE: v16 = ITEM_SPELLBOOK_FIRE_STRIKE; pCharacter->AddItem(-1, v16); break; case PLAYER_SKILL_AIR: v16 = ITEM_SPELLBOOK_AIR_FEATHER_FALL; pCharacter->AddItem(-1, v16); break; case PLAYER_SKILL_WATER: v16 = ITEM_SPELLBOOK_WATER_POISON_SPRAY; pCharacter->AddItem(-1, v16); break; case PLAYER_SKILL_EARTH: v16 = ITEM_SPELLBOOK_EARTH_SLOW; pCharacter->AddItem(-1, v16); break; case PLAYER_SKILL_SPIRIT: v16 = ITEM_SPELLBOOK_SPIRIT_BLESS; pCharacter->AddItem(-1, v16); break; case PLAYER_SKILL_MIND: v16 = ITEM_SPELLBOOK_MIND_MIND_BLAST; pCharacter->AddItem(-1, v16); break; case PLAYER_SKILL_BODY: v16 = ITEM_SPELLBOOK_BODY_FIRST_AID; pCharacter->AddItem(-1, v16); break; case PLAYER_SKILL_ITEM_ID: case PLAYER_SKILL_REPAIR: case PLAYER_SKILL_MEDITATION: case PLAYER_SKILL_PERCEPTION: case PLAYER_SKILL_DIPLOMACY: case PLAYER_SKILL_TRAP_DISARM: case PLAYER_SKILL_LEARNING: pCharacter->AddItem(-1, ITEM_POTION_BOTTLE); v16 = 5 * (rand() % 3 + 40); // simple reagent pCharacter->AddItem(-1, v16); break; case PLAYER_SKILL_DODGE: v16 = ITEM_BOOTS_1; pCharacter->AddItem(-1, v16); break; case PLAYER_SKILL_UNARMED: v16 = ITEM_GAUNTLETS_1; pCharacter->AddItem(-1, v16); break; default: break; } } //uSkillIdx = v18 + 1; //v11 = uSkillIdx > 36; //v9 = v18 == 35; //v10 = uSkillIdx - 35 < 0; } //while (uSkillIdx < 36); pItems = pCharacter->pInventoryItemList; //v13 = 138; for (int i = 0; i < 138; i++) { if ( pItems->uItemID ) pItems->uAttributes |= 1; ++pItems; //--v13; } //while ( v13 ); } pCharacter->sHealth = pCharacter->GetMaxHealth(); pCharacter->sMana = pCharacter->GetMaxMana(); //pCharacter++; //uNumPlayers--; //if (!uNumPlayers) //break; //pResMagicBase = (int)pCharacter; v3 = 10; } } //----- (004917CE) -------------------------------------------------------- int Party::Reset() { //Party *v1; // esi@1 //unsigned __int64 *pTimePlayed; // edi@1 //bool v3; // edx@1 //Player **v4; // eax@1 //Player *v5; // ecx@1 PLAYER_SEX pSex; // cl@3 PLAYER_SEX v7; // al@6 PLAYER_SEX v8; // al@9 PLAYER_SEX v9; // cl@12 //Player *v12; // edx@17 //signed int v13; // edi@18 SpellBuff *v14; // ebx@21 signed int v15; // edi@21 Zero(); field_708 = 15; sEyelevel = 160; uNumGold = 200; uNumFoodRations = 7; alignment = PartyAlignment_Neutral; SetUserInterface(alignment, true); uTimePlayed = 0x21C00u; uLastRegenerationTime = 0x21C00; bTurnBasedModeOn = false; uActiveCharacter = 1; ::pPlayers.ZerothIndex() = pPlayers; for (uint i = 0; i < 4; ++i) ::pPlayers[i + 1] = &pPlayers[i]; pPlayers[0].Reset(PLAYER_CLASS_KNIGHT); pPlayers[1].Reset(PLAYER_CLASS_THEIF); pPlayers[2].Reset(PLAYER_CLASS_CLERIC); pPlayers[3].Reset(PLAYER_CLASS_SORCERER); pPlayers[0].uCurrentFace = 17; pPlayers[0].uPrevVoiceID = 17; pPlayers[0].uVoiceID = 17; pPlayers[0].SetInitialStats(); switch ( pPlayers[0].uVoiceID ) { case 0: case 1: case 2: case 3: case 8: case 9: case 12: case 13: case 16: case 17: case 20: case 23: default: pSex = SEX_MALE; break; case 4: case 5: case 6: case 7: case 10: case 11: case 14: case 15: case 18: case 19: case 21: case 24: pSex = SEX_FEMALE; break; } pPlayers[0].uSex = pSex; pPlayers[0].RandomizeName(); strcpy(pPlayers[0].pName, pGlobalTXT_LocalizationStrings[509]); pPlayers[1].uCurrentFace = 3; pPlayers[1].uPrevVoiceID = 3; pPlayers[1].uVoiceID = 3; pPlayers[1].SetInitialStats(); v7 = SEX_MALE; switch (pPlayers[1].uVoiceID) { case 0: case 1: case 2: case 3: case 8: case 9: case 0xCu: case 0xDu: case 0x10u: case 0x11u: case 0x14u: case 0x17u: v7 = SEX_MALE; break; case 4: case 5: case 6: case 7: case 0xAu: case 0xBu: case 0xEu: case 0xFu: case 0x12u: case 0x13u: case 0x15u: case 0x18u: v7 = SEX_FEMALE; break; default: break; } pPlayers[1].uSex = v7; pPlayers[1].RandomizeName(); strcpy(pPlayers[1].pName, pGlobalTXT_LocalizationStrings[506]); pPlayers[2].uCurrentFace = 14; pPlayers[2].uPrevVoiceID = 14; pPlayers[2].uVoiceID = 14; pPlayers[2].SetInitialStats(); v8 = SEX_MALE; switch (pPlayers[2].uVoiceID) { case 0: case 1: case 2: case 3: case 8: case 9: case 0xCu: case 0xDu: case 0x10u: case 0x11u: case 0x14u: case 0x17u: v8 = SEX_MALE; break; case 4: case 5: case 6: case 7: case 0xAu: case 0xBu: case 0xEu: case 0xFu: case 0x12u: case 0x13u: case 0x15u: case 0x18u: v8 = SEX_FEMALE; break; default: break; } pPlayers[2].uSex = v8; pPlayers[2].RandomizeName(); strcpy(pPlayers[2].pName, pGlobalTXT_LocalizationStrings[508]); pPlayers[3].uCurrentFace = 10; pPlayers[3].uPrevVoiceID = 10; pPlayers[3].uVoiceID = 10; pPlayers[3].SetInitialStats(); v9 = SEX_MALE; switch (pPlayers[3].uVoiceID) { case 0u: case 1u: case 2u: case 3u: case 8u: case 9u: case 0xCu: case 0xDu: case 0x10u: case 0x11u: case 0x14u: case 0x17u: v9 = SEX_MALE; break; case 4u: case 5u: case 6u: case 7u: case 0xAu: case 0xBu: case 0xEu: case 0xFu: case 0x12u: case 0x13u: case 0x15u: case 0x18u: v9 = SEX_FEMALE; break; default: break; } pPlayers[3].uSex = v9; pPlayers[3].RandomizeName(); strcpy(pPlayers[3].pName, pGlobalTXT_LocalizationStrings[507]); for (uint i = 0; i < 4; ++i) { pPlayers[i].uTimeToRecovery = 0; for (uint j = 0; j < 20; ++j) pPlayers[i].pConditions[j] = 0; for (uint j = 0; j < 24; ++j) pPlayers[i].pPlayerBuffs[j].Reset(); pPlayers[i].expression = CHARACTER_EXPRESSION_1; pPlayers[i].uExpressionTimePassed = 0; pPlayers[i].uExpressionTimeLength = rand() % 256 + 128; } for (uint i = 1; i < 20; ++i) pPartyBuffs[i].Reset(); pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 100; // default character ui - stats uFlags = 0; memset(_autonote_bits, 0, 26); memset(_quest_bits, 0, 64); memset(pIsArtifactFound, 0, 29); _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_RED_POTION_ACTIVE, 1); _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_SEASHELL_ACTIVE, 1); _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_LONGBOW_ACTIVE, 1); _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_PLATE_ACTIVE, 1); _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_LUTE_ACTIVE, 1); _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_HAT_ACTIVE, 1); memset(field_3C._shop_ban_times,0,53*sizeof(__int64)); memcpy(pNPCStats->pNewNPCData, pNPCStats->pNPCData, 0x94BCu); memcpy(pNPCStats->pGroups_copy, pNPCStats->pGroups, 0x66u); pNPCStats->pNewNPCData[3].uFlags |= 128;//|= 0x80u; Lady Margaret _494035_timed_effects__water_walking_damage__etc(); pEventTimer->Pause(); return 0; } //----- (0043AD34) -------------------------------------------------------- void Party::Yell() { Actor *v0; // esi@5 int v1; // edi@9 int v2; // ebx@9 int v3; // eax@9 unsigned int v4; // [sp+8h] [bp-4h]@4 if ( (signed __int64)pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime > 0 ) pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset(); if ( pParty->bTurnBasedModeOn != 1 ) { v4 = 0; if ( (signed int)uNumActors > 0 ) { v0 = pActors.data();//[0].pMonsterInfo.uMovementType; do { if ( v0->Actor::CanAct() && v0->pMonsterInfo.uHostilityType != MonsterInfo::Hostility_Long && v0->pMonsterInfo.uMovementType != 5 ) { v1 = abs(v0->vPosition.x - pParty->vPosition.x); v2 = abs(v0->vPosition.y - pParty->vPosition.y); v3 = abs(v0->vPosition.z - pParty->vPosition.z); if (int_get_vector_length(v1, v2, v3) < 512) Actor::AI_Flee(v4, 4, 0, 0); } ++v4; ++v0; } while ( (signed int)v4 < (signed int)uNumActors ); } } } //----- (00491BF9) -------------------------------------------------------- void Party::ResetPosMiscAndSpellBuffs() { Party *v1; // esi@1 Player *v2; // edi@1 SpellBuff *v3; // ebx@2 SpellBuff *v4; // esi@5 signed int v5; // edi@5 signed int v6; // [sp+8h] [bp-8h]@1 signed int v7; // [sp+Ch] [bp-4h]@2 v1 = this; this->vPosition.y = 0; this->vPosition.z = 0; this->vPosition.x = 0; this->uFallStartY = 0; this->sRotationY = 0; this->sRotationX = 0; this->uFallSpeed = 0; this->field_28 = 0; this->uDefaultPartyHeight = 120; this->field_14_radius = 37; this->y_rotation_granularity = 25; this->uWalkSpeed = 384; this->y_rotation_speed = 90; this->field_24 = 5; this->field_6FC = 0; this->field_708 = 15; this->field_0 = 25; v2 = this->pPlayers;//[0].pPlayerBuffs; v6 = 4; do { v3 = v2->pPlayerBuffs; v7 = 24; do { v3->Reset(); ++v3; --v7; } while ( v7 ); ++v2; --v6; } while ( v6 ); v4 = v1->pPartyBuffs; v5 = 20; do { v4->Reset(); ++v4; --v5; } while ( v5 ); } //----- (004909F4) -------------------------------------------------------- void Party::UpdatePlayersAndHirelingsEmotions() { //Player *v1; // esi@2 //unsigned int v2; // eax@3 //__int16 v3; // cx@5 int v4; // edx@27 //signed int v5; // eax@52 //PlayerFrame *v6; // edx@53 //NPCData *v7; // esi@60 //signed int v8; // ebp@61 //int v9; // ebx@62 //unsigned int v10; // edi@62 //signed int v11; // [sp+0h] [bp-4h]@2 //v1 = this->pPlayers;//(char *)&this->pPlayers[0].uExpressionID; for (int i = 0; i < 4; ++i) { auto player = pPlayers + i; player->uExpressionTimePassed += (unsigned short)pMiscTimer->uTimeElapsed; auto condition = player->GetMajorConditionIdx(); if (condition == Condition_Good || condition == Condition_Zombie) { if (player->uExpressionTimePassed < player->uExpressionTimeLength) continue; player->uExpressionTimePassed = 0; if (player->expression != 1 || rand() % 5) { player->expression = CHARACTER_EXPRESSION_1; player->uExpressionTimeLength = rand() % 256 + 32; } else { v4 = rand() % 100; if (v4 < 25) player->expression = CHARACTER_EXPRESSION_13; else if (v4 < 31) player->expression = CHARACTER_EXPRESSION_14; else if (v4 < 37) player->expression = CHARACTER_EXPRESSION_15; else if (v4 < 43) player->expression = CHARACTER_EXPRESSION_16; else if (v4 < 46) player->expression = CHARACTER_EXPRESSION_17; else if (v4 < 52) player->expression = CHARACTER_EXPRESSION_18; else if (v4 < 58) player->expression = CHARACTER_EXPRESSION_19; else if (v4 < 64) player->expression = CHARACTER_EXPRESSION_20; else if (v4 < 70) player->expression = CHARACTER_EXPRESSION_54; else if (v4 < 76) player->expression = CHARACTER_EXPRESSION_55; else if (v4 < 82) player->expression = CHARACTER_EXPRESSION_56; else if (v4 < 88) player->expression = CHARACTER_EXPRESSION_57; else if (v4 < 94) player->expression = CHARACTER_EXPRESSION_29; else player->expression = CHARACTER_EXPRESSION_30; } for (int j = 0; j < pPlayerFrameTable->uNumFrames; ++j) { auto frame = pPlayerFrameTable->pFrames + j; if (frame->expression == player->expression) { player->uExpressionTimeLength = 8 * pPlayerFrameTable->pFrames[j].uAnimLength; break; } } } else if (player->expression != 34 && player->expression != 35 && player->expression != 36 || player->uExpressionTimePassed >= player->uExpressionTimeLength) { player->uExpressionTimeLength = 0; player->uExpressionTimePassed = 0; switch (condition) { case Condition_Dead: player->expression = CHARACTER_EXPRESSION_DEAD; break; case Condition_Pertified: player->expression = CHARACTER_EXPRESSION_PERTIFIED; break; case Condition_Eradicated: player->expression = CHARACTER_EXPRESSION_ERADICATED; break; case Condition_Cursed: player->expression = CHARACTER_EXPRESSION_CURSED; break; case Condition_Weak: player->expression = CHARACTER_EXPRESSION_WEAK; break; case Condition_Sleep: player->expression = CHARACTER_EXPRESSION_SLEEP; break; case Condition_Fear: player->expression = CHARACTER_EXPRESSION_FEAR; break; case Condition_Drunk: player->expression = CHARACTER_EXPRESSION_DRUNK; break; case Condition_Insane: player->expression = CHARACTER_EXPRESSION_INSANE; break; case Condition_Poison1: case Condition_Poison2: case Condition_Poison3: player->expression = CHARACTER_EXPRESSION_POISONED; break; case Condition_Disease1: case Condition_Disease2: case Condition_Disease3: player->expression = CHARACTER_EXPRESSION_DISEASED; break; case Condition_Paralyzed: player->expression = CHARACTER_EXPRESSION_PARALYZED; break; case Condition_Unconcious: player->expression = CHARACTER_EXPRESSION_UNCONCIOUS; break; default: Error("Invalid condition: %u", condition); } } } for (int i = 0; i < 2; ++i) { auto hireling = pParty->pHirelings + i; if (!hireling->evt_C) continue; hireling->evt_B += pMiscTimer->uTimeElapsed; if (hireling->evt_B >= hireling->evt_C) { hireling->evt_A = 0; hireling->evt_B = 0; hireling->evt_C = 0; Assert(sizeof(NPCData) == 0x4C); memset(hireling, 0, sizeof(*hireling)); pParty->field_709 = 0; pParty->CountHirelings(); viewparams->bRedrawGameUI = true; } } } //----- (00490D02) -------------------------------------------------------- void Party::RestAndHeal() { Player *pPlayer; // esi@4 ItemGen *v7; // eax@10 signed int v11; // ecx@26 signed int v12; // [sp-4h] [bp-1Ch]@26 bool have_vessels_soul; // [sp+10h] [bp-8h]@10 /* v1 = pParty->pPartyBuffs; do { v1->Reset(); ++v1; } while ( (signed int)v1 < (signed int)pParty->pPlayers ); v15 = 0; do { pPlayer = &pParty->pPlayers[v15]; v3 = 20; v4 = pPlayer->pPlayerBuffs; do { v4->Reset(); ++v4; --v3; } while ( v3 );*/ for ( uint i = 0; i < 20; ++i ) pParty->pPartyBuffs[i].Reset(); for ( int pPlayerID = 0; pPlayerID < 4; ++pPlayerID ) { pPlayer = &pParty->pPlayers[pPlayerID]; for ( uint i = 0; i < 20; ++i ) pPlayer->pPlayerBuffs[i].Reset(); pPlayer->Zero(); if ( pPlayer->pConditions[14] || pPlayer->pConditions[15] || pPlayer->pConditions[16] )//Dead/Petrified/Eradicated continue; pPlayer->pConditions[13] = 0;//Unconcious pPlayer->pConditions[4] = 0;//Drunk pPlayer->pConditions[3] = 0;//Fear pPlayer->pConditions[2] = 0;//Sleep pPlayer->pConditions[1] = 0;//Weak pPlayer->uTimeToRecovery = 0; pPlayer->sHealth = pPlayer->GetMaxHealth(); pPlayer->sMana = pPlayer->GetMaxMana(); if ( pPlayer->classType == PLAYER_CLASS_LICH ) { have_vessels_soul = false; v7 = pPlayer->pInventoryItemList;//[0].field_1A; for ( uint i = 138; i; --i ) { if ( v7->uItemID == 601 && (unsigned __int8)v7->uHolderPlayer == pPlayerID + 1 ) have_vessels_soul = true; ++v7; } if ( !have_vessels_soul ) { pPlayer->sHealth = pPlayer->GetMaxHealth() / 2; pPlayer->sMana = pPlayer->GetMaxMana() / 2; } } if ( !pPlayer->pConditions[17] )// Zombie { if ( pPlayer->pConditions[10] || pPlayer->pConditions[11] ) { v11 = 4; v12 = 4; } else { if ( !pPlayer->pConditions[8] && !pPlayer->pConditions[9] ) { if ( !pPlayer->pConditions[6] && !pPlayer->pConditions[7] ) { if ( pPlayer->pConditions[5] ) pPlayer->sMana = 0; UpdatePlayersAndHirelingsEmotions(); continue; } pPlayer->sHealth /= 2; pPlayer->sMana = pPlayer->sMana / 2; if ( pPlayer->pConditions[5] ) pPlayer->sMana = 0; UpdatePlayersAndHirelingsEmotions(); continue; } v11 = 3; v12 = 3; } pPlayer->sHealth /= v11; pPlayer->sMana = pPlayer->sMana / v12; if ( pPlayer->pConditions[5] ) pPlayer->sMana = 0; UpdatePlayersAndHirelingsEmotions(); continue; } pPlayer->sMana = 0; pPlayer->sHealth = pPlayer->sHealth / 2; if ( pPlayer->pConditions[5] ) pPlayer->sMana = 0; UpdatePlayersAndHirelingsEmotions(); } pParty->days_played_without_rest = 0; } //----- (004938D1) -------------------------------------------------------- void __fastcall Rest(unsigned int uHoursToSleep) { unsigned int v1; // esi@1 double v2; // st7@3 Player **v3; // esi@3 v1 = uHoursToSleep; if ( uHoursToSleep > 240 ) InitializeActors(); v2 = (double)(7680 * v1) * 0.033333335; pParty->uTimePlayed += (signed __int64)v2; v3 = &pPlayers[1]; do { (*v3)->Recover((signed __int64)v2); ++v3; } while ( (signed int)v3 <= (signed int)&pPlayers[4] ); _494035_timed_effects__water_walking_damage__etc(); } //----- (004B1BDB) -------------------------------------------------------- void RestAndHeal(__int64 uNumMinutes) { signed __int64 v1; // ST2C_8@1 signed __int64 v2; // qax@1 signed __int64 v3; // ST1C_8@1 unsigned __int64 v4; // qax@1 unsigned int v5; // ebx@1 Player *v6; // ebx@1 pParty->pHirelings[0].bHasUsedTheAbility = 0; pParty->pHirelings[1].bHasUsedTheAbility = 0; pParty->uTimePlayed += (signed __int64)((double)(7680 * uNumMinutes) * 0.033333335); v1 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375); v2 = v1 / 60 / 60; v3 = v2; v4 = (unsigned int)v2 / 0x18; v5 = (unsigned int)(v4 / 7) >> 2; pParty->uCurrentTimeSecond = v1 % 60; pParty->uCurrentMinute = v1 / 60 % 60; pParty->uCurrentHour = v3 % 24; pParty->uCurrentMonthWeek = v4 / 7 & 3; pParty->uDaysPlayed = (unsigned int)v4 % 0x1C; pParty->uCurrentMonth = v5 % 0xC; pParty->uCurrentYear = v5 / 0xC + game_starting_year; pParty->RestAndHeal(); dword_507B94 = 1; v6 = pParty->pPlayers;//[0].uNumDivineInterventionCastsThisDay; do { v6->uTimeToRecovery = 0; memset(&v6->uTimeToRecovery, 0, 4u); ++v6; } while ( v6 <= &pParty->pPlayers[3] ); pParty->UpdatePlayersAndHirelingsEmotions(); } //----- (0041F5BE) -------------------------------------------------------- void Sleep6Hours() { if ( _506F18_num_minutes_to_sleep < 6 ) { if ( _506F18_num_minutes_to_sleep ) { Rest(_506F18_num_minutes_to_sleep); _506F18_num_minutes_to_sleep = 0; LoadActualSkyFrame(); } if ( dword_506F14 == 2 ) { pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0); } } else { Rest(6u); _506F18_num_minutes_to_sleep -= 6; LoadActualSkyFrame(); } viewparams->bRedrawGameUI = 1; } //----- (0047752B) -------------------------------------------------------- int GetPartyReputation() { DDM_DLV_Header *v0; // ebx@1 signed int v1; // esi@3 v0 = &pOutdoor->ddm; if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor ) v0 = &pIndoor->dlv; v1 = 0; if ( CheckHiredNPCSpeciality(Pirate) ) v1 += 5; if ( CheckHiredNPCSpeciality(Burglar) ) v1 += 5; if ( CheckHiredNPCSpeciality(Gypsy) ) v1 += 5; if ( CheckHiredNPCSpeciality(Duper) ) v1 += 5; if ( CheckHiredNPCSpeciality(FallenWizard) ) v1 += 5; return v1 + v0->uReputation; } //----- (004269A2) -------------------------------------------------------- void __fastcall GivePartyExp(unsigned int pEXPNum) { signed int pActivePlayerCount; // ecx@1 int pLearningPercent; // eax@13 pActivePlayerCount = 0; for ( uint i = 0; i < 4; ++i ) { if ( !pParty->pPlayers[i].pConditions[13] && !pParty->pPlayers[i].pConditions[14] && !pParty->pPlayers[i].pConditions[15] && !pParty->pPlayers[i].pConditions[16] ) pActivePlayerCount ++; } if ( pActivePlayerCount ) { pEXPNum = pEXPNum / pActivePlayerCount; for ( uint i = 0; i < 4; ++i ) { if ( !pParty->pPlayers[i].pConditions[13] && !pParty->pPlayers[i].pConditions[14] && !pParty->pPlayers[i].pConditions[15] && !pParty->pPlayers[i].pConditions[16] ) { if ( pEXPNum ) { pLearningPercent = pParty->pPlayers[i].GetLearningPercent(); pEXPNum = pEXPNum + pEXPNum * pLearningPercent / 100; pParty->pPlayers[i].uExperience += pEXPNum; if ( pParty->pPlayers[i].uExperience > 4000000000i64 ) { pParty->pPlayers[i].uExperience = 0; } } } } } } //----- (00420C05) -------------------------------------------------------- void __fastcall party_finds_gold(unsigned int uNumGold, int _1_dont_share_with_followers___2_the_same_but_without_a_message__else_normal) { unsigned int v2; // edi@1 int v3; // ebp@1 unsigned int v4; // esi@1 int v5; // ecx@6 NPCData *v6; // eax@6 signed int v7; // edx@8 signed int v8; // ebx@10 char *v9; // edi@11 signed int v10; // ecx@17 int v11; // eax@21 NPCData *v12; // ecx@21 unsigned int v13; // ecx@23 signed int v14; // [sp+Ch] [bp-4h]@6 v2 = 0; v3 = 0; v4 = uNumGold; if ( _1_dont_share_with_followers___2_the_same_but_without_a_message__else_normal ) { if ( _1_dont_share_with_followers___2_the_same_but_without_a_message__else_normal == 1 ) { sprintf(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[467], uNumGold);// You found %lu gold! } else { if ( _1_dont_share_with_followers___2_the_same_but_without_a_message__else_normal == 2 ) pTmpBuf2[0] = 0; } } else { v14 = 0; v5 = 0; v6 = pParty->pHirelings; do { if ( v6->pName ) { v7 = v14++; pTmpBuf[v7] = v5; } ++v6; ++v5; } while ( (signed int)v6 < (signed int)&pParty->pPickedItem ); v8 = 0; if ( (signed int)pNPCStats->uNumNewNPCs > 0 ) { v9 = (char *)pNPCStats->pNewNPCData; do { if ( v9[8] & 0x80 && (!pParty->pHirelings[0].pName || strcmp(*(const char **)v9, pParty->pHirelings[0].pName)) && (!pParty->pHirelings[1].pName || strcmp(*(const char **)v9, pParty->pHirelings[1].pName)) ) { v10 = v14++; pTmpBuf[v10] = v8 + 2; } ++v8; v9 += 76; } while ( v8 < (signed int)pNPCStats->uNumNewNPCs ); v2 = 0; } if ( v14 > 0 ) { do { v11 = (unsigned __int8)pTmpBuf[v2]; v12 = &pNPCStats->pNPCData[v11 + 499]; if ( (unsigned __int8)pTmpBuf[v2] < 2 ) v12 = &pParty->pHirelings[v11]; v13 = v12->uProfession; if ( v13 ) v3 += pNPCStats->pProfessions[v13].uHirePrice;//*(&pNPCStats->field_13A58 + 5 * v13); ++v2; } while ( (signed int)v2 < v14 ); } if ( CheckHiredNPCSpeciality(Factor) ) v4 += (signed int)(10 * v4) / 100; if ( CheckHiredNPCSpeciality(Banker) ) v4 += (signed int)(20 * v4) / 100; if ( CheckHiredNPCSpeciality(Pirate) ) v4 += (signed int)(10 * v4) / 100; if ( v3 ) { v3 = (signed int)(v4 * v3 / 100) / 100; if ( v3 < 1 ) v3 = 1; sprintf(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[466], v4, v3);// You found %lu gold (followers take %lu)! } else { sprintf(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[467], v4);// You found %lu gold! } v2 = 0; } pParty->uNumGold += v4 - v3; pUIAnim_Gold->uAnimTime = v2; pUIAnim_Gold->uAnimLength = 8 * pIconsFrameTable->pIcons[(signed __int16)pUIAnim_Gold->uIconID].uAnimLength; if ( pTmpBuf2[0] ) ShowStatusBarString(pTmpBuf2.data(), 2u); pAudioPlayer->PlaySound(SOUND_GoldReceived, v2, v2, -1, v2, v2, v2, v2); } //----- (00421B2C) -------------------------------------------------------- bool sub_421B2C_PlaceInInventory_or_DropPickedItem() { unsigned int v0; // eax@2 Texture *v1; // ebx@2 int v2; // eax@3 Player *v3; // esi@5 int v4; // eax@6 unsigned __int16 v5; // dx@11 signed int v6; // eax@11 char *v7; // edi@12 __int16 v8; // ax@16 SpriteObject a1; // [sp+4h] [bp-78h]@11 int v11; // [sp+74h] [bp-8h]@2 int v12; // [sp+78h] [bp-4h]@5 if ( !pParty->pPickedItem.uItemID ) return 1; v0 = pIcons_LOD->LoadTexture( pItemsTable->pItems[pParty->pPickedItem.uItemID].pIconName, TEXTURE_16BIT_PALETTE); v1 = pIcons_LOD->GetTexture(v0); v11 = areWeLoadingTexture; if ( uActiveCharacter && (v2 = pPlayers[uActiveCharacter]->AddItem(-1, pParty->pPickedItem.uItemID)) != 0 ) { memcpy(&pPlayers[uActiveCharacter]->pInventoryItemList[v2-1], &pParty->pPickedItem, 0x24u); pMouse->RemoveHoldingItem(); } else { v12 = 0; v3 = pParty->pPlayers; while ( v3 <= &pParty->pPlayers[3] ) { v4 = v3->AddItem(-1, pParty->pPickedItem.uItemID); if ( v4 ) { memcpy(&pParty->pPlayers[v12].pInventoryItemList[v4 - 1], &pParty->pPickedItem, 0x24u); pMouse->RemoveHoldingItem(); break; } ++v12; ++v3; } if ( v12 == 4 ) { v5 = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; v6 = 0; a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; if ( (signed int)pObjectList->uNumObjects <= 0 ) { LOWORD(v6) = 0; } else { v7 = (char *)&pObjectList->pObjects->uObjectID; while ( v5 != *(short *)v7 ) { ++v6; v7 += 56; if ( v6 >= (signed int)pObjectList->uNumObjects ) { LOWORD(v6) = 0; break; } } } a1.spell_caster_pid = OBJECT_Player; a1.uObjectDescID = v6; a1.vPosition.y = pParty->vPosition.y; a1.vPosition.x = pParty->vPosition.x; a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; a1.uSoundID = 0; a1.uFacing = 0; a1.uAttributes = 8; v8 = pIndoor->GetSector( pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); a1.uSpriteFrameID = 0; a1.uSectorID = v8; memcpy(&a1.stru_24, &pParty->pPickedItem, sizeof(a1.stru_24)); a1.Create(pParty->sRotationY, 184, 200, 0); pMouse->RemoveHoldingItem(); } } if ( !v11 ) { v1->Release(); pIcons_LOD->SyncLoadedFilesCount(); } return 1; } bool Party::IsPartyEvil() { return _449B57_test_bit(_quest_bits, 100); } bool Party::IsPartyGood() { return _449B57_test_bit(_quest_bits, 99); }