comparison Player.cpp @ 1704:cc1d68c17e19

Слияние
author Ritor1
date Mon, 23 Sep 2013 09:34:23 +0600
parents ef42788fef1d
children be43171d7bc6 f8414042db1f
comparison
equal deleted inserted replaced
1703:ffef0fe0b59d 1704:cc1d68c17e19
58 {{14, 30, 1, 2}, {11, 25, 1, 1}, {11, 25, 1, 1}, {14, 30, 1, 2}, { 7, 15, 2, 1}, { 7, 15, 2, 1}, {9, 20, 1, 1}} 58 {{14, 30, 1, 2}, {11, 25, 1, 1}, {11, 25, 1, 1}, {14, 30, 1, 2}, { 7, 15, 2, 1}, { 7, 15, 2, 1}, {9, 20, 1, 1}}
59 }; 59 };
60 60
61 61
62 62
63 std::array<int, 5> StealingMasteryBonuses = {0, 100, 200, 300, 500}; //dword_4EDEA0 //the zeroth element isn't accessed, it just helps avoid -1 indexing, originally 4 element array off by one
64 std::array<int, 5> StealingRandomBonuses = {-200, -100, 0, 100, 200}; //dword_4EDEB4
65 std::array<int, 5> StealingEnchantmentBonusForSkill = {0, 2, 4, 6, 10}; //dword_4EDEC4 //the zeroth element isn't accessed, it just helps avoid -1 indexing, originally 4 element array off by one
63 66
64 67
65 68
66 // available skills per class ( 9 classes X 37 skills ) 69 // available skills per class ( 9 classes X 37 skills )
67 // 0 - not available 70 // 0 - not available
128 {100, 75, 40, 10}, //Endurance 131 {100, 75, 40, 10}, //Endurance
129 {100, 100, 40, 10}, //Accuracy 132 {100, 100, 40, 10}, //Accuracy
130 {100, 100, 40, 10}, //Speed 133 {100, 100, 40, 10}, //Speed
131 {100, 100, 100, 100}}; //Luck 134 {100, 100, 100, 100}}; //Luck
132 135
133 signed int pAgeingTable[4] = {50, 100, 150, 0xFFFF}; 136 unsigned int pAgeingTable[4] = {50, 100, 150, 0xFFFF};
134 137
135 std::array<unsigned int, 18> pConditionImportancyTable = {{16, 15, 14, 17, 13, 2, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 1, 0}}; 138 std::array<unsigned int, 18> pConditionImportancyTable = {{16, 15, 14, 17, 13, 2, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 1, 0}};
136 139
137 short param_to_bonus_table[29] = {500, 400, 350, 300, 275, 250, 225, 200, 175, 140 short param_to_bonus_table[29] = {500, 400, 350, 300, 275, 250, 225, 200, 175,
138 150, 125, 100, 75, 50, 40, 35, 30, 25, 21, 141 150, 125, 100, 75, 50, 40, 35, 30, 25, 21,
1531 + itemBonus 1534 + itemBonus
1532 + this->*attrBonus; 1535 + this->*attrBonus;
1533 } 1536 }
1534 1537
1535 //----- (0048CCF5) -------------------------------------------------------- 1538 //----- (0048CCF5) --------------------------------------------------------
1536 int Player::GetActualAttack(int a2) 1539 int Player::GetActualAttack( bool a2 )
1537 { 1540 {
1538 int v3; // eax@1 1541 int v3; // eax@1
1539 int v4; // edi@1 1542 int v4; // edi@1
1540 int v5; // ebx@1 1543 int v5; // ebx@1
1541 int v6; // ebp@1 1544 int v6; // ebp@1
1702 v7 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v6; 1705 v7 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v6;
1703 v3 = this->_ranged_atk_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v7; 1706 v3 = this->_ranged_atk_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v7;
1704 } 1707 }
1705 else 1708 else
1706 { 1709 {
1707 v3 = GetActualAttack(1); 1710 v3 = GetActualAttack(true);
1708 } 1711 }
1709 return v3; 1712 return v3;
1710 } 1713 }
1711 1714
1712 //----- (0048D124) -------------------------------------------------------- 1715 //----- (0048D124) --------------------------------------------------------
2009 } 2012 }
2010 return false; 2013 return false;
2011 } 2014 }
2012 2015
2013 //----- (0048D76C) -------------------------------------------------------- 2016 //----- (0048D76C) --------------------------------------------------------
2014 bool Player::StealFromShop(ItemGen *itemToSteal, int a3, int reputation, int a5, int *a6) //check stealing in IDA pro once I get home. The whole thing looks odd, dword_4EDEB4 and dword_4EDEA0 are never filled, might be a bug, might me on purpose 2017 int Player::StealFromShop( ItemGen *itemToSteal, int extraStealDifficulty, int reputation, int a5, int *fineIfFailed ) //returns an int, but is the return value is compared to zero, so might change to bool
2015 { 2018 {
2016 unsigned __int16 v6; // cx@8 2019 unsigned __int16 v6; // cx@8
2017 int v7; // edi@8 2020 int v7; // edi@8
2018 unsigned int v8; // ebx@8 2021 unsigned int v8; // ebx@8
2019 unsigned int itemvalue; // esi@8 2022 unsigned int itemvalue; // esi@8
2020 int v10; // eax@8 2023 int v10; // eax@8
2021 int v11; // edi@12 2024 int currMaxItemValue; // edi@12
2022 bool result; // eax@13
2023 2025
2024 if ( !itemToSteal 2026 if ( !itemToSteal
2025 || this->pConditions[16] 2027 || this->IsEradicated()
2026 || this->pConditions[14] 2028 || this->IsDead()
2027 || this->pConditions[15] 2029 || this->IsPertified()
2028 || this->pConditions[4] 2030 || this->IsDrunk()
2029 || this->pConditions[13] 2031 || this->IsUnconcious()
2030 || this->pConditions[2] ) 2032 || this->IsAsleep() )
2031 { 2033 {
2032 result = 0; 2034 return 0;
2033 } 2035 }
2034 else 2036 else
2035 { 2037 {
2036 v6 = this->pActiveSkills[34]; 2038 v6 = this->pActiveSkills[34];
2037 v7 = v6 & 0x3F; 2039 v7 = v6 & 0x3F;
2038 v8 = SkillToMastery(v6); 2040 v8 = SkillToMastery(v6);
2039 itemvalue = itemToSteal->GetValue(); 2041 itemvalue = itemToSteal->GetValue();
2040 v10 = pItemsTable->pItems[itemToSteal->uItemID].uEquipType; 2042 v10 = pItemsTable->pItems[itemToSteal->uItemID].uEquipType;
2041 if ( !pItemsTable->pItems[itemToSteal->uItemID].uEquipType || v10 == 1 || v10 == 2 ) 2043 if ( v10 == EQUIP_OFF_HAND || v10 == EQUIP_MAIN_HAND || v10 == EQUIP_BOW )
2042 itemvalue *= 3; 2044 itemvalue *= 3;
2043 v11 = dword_4EDEB4[rand() % 100 / 20] + v7 * dword_4EDEA0[v8]; 2045 currMaxItemValue = StealingRandomBonuses[rand() % 5] + v7 * StealingMasteryBonuses[v8];
2044 *a6 = 100 * (reputation + a3) + itemvalue + (a5 != 0 ? 0x1F4 : 0); 2046 *fineIfFailed = 100 * (reputation + extraStealDifficulty) + itemvalue;
2047 if (a5)
2048 {
2049 *fineIfFailed += 500;
2050 }
2045 if ( rand() % 100 >= 5 ) 2051 if ( rand() % 100 >= 5 )
2046 { 2052 {
2047 if ( *a6 > v11 ) 2053 if ( *fineIfFailed > currMaxItemValue )
2048 result = *a6 - v11 < 500; 2054 if (*fineIfFailed - currMaxItemValue < 500)
2049 else
2050 result = 2;
2051 }
2052 else
2053 {
2054 result = 0;
2055 }
2056 }
2057 return result;
2058 }
2059 // 4EDEA0: using guessed type int dword_4EDEA0[];
2060 // 4EDEB4: using guessed type int dword_4EDEB4[];
2061
2062 //----- (0048D88B) --------------------------------------------------------
2063 int Player::StealFromActor(unsigned int uActorID, int _steal_perm, int reputation)
2064 {
2065 Player *v4; // esi@1
2066 Actor *v5; // edi@1
2067 unsigned __int16 v6; // cx@10
2068 int v7; // ebx@10
2069 unsigned int v8; // esi@10
2070 int v9; // eax@10
2071 int v10; // esi@10
2072 int v11; // eax@13
2073 signed int v12; // ebx@15
2074 signed int v13; // edx@15
2075 int v14; // ecx@15
2076 unsigned __int16 v15; // si@21
2077 unsigned int v16; // ebx@24
2078 int v17; // esi@24
2079 const void *v18; // eax@29
2080 unsigned int v19; // esi@31
2081 int v20; // eax@34
2082 char v21; // zf@36
2083 unsigned int v22; // ST0C_4@39
2084 char *v23; // esi@39
2085 const char *v25; // [sp-Ch] [bp-48h]@40
2086 int v26; // [sp-8h] [bp-44h]@40
2087 ItemGen v27; // [sp+8h] [bp-34h]@15
2088 unsigned int v28; // [sp+2Ch] [bp-10h]@10
2089 int v29; // [sp+30h] [bp-Ch]@10
2090 int v30; // [sp+34h] [bp-8h]@10
2091 Player *v31; // [sp+38h] [bp-4h]@1
2092 signed int _steal_perma; // [sp+48h] [bp+Ch]@12
2093
2094 v4 = this;
2095 v5 = &pActors[uActorID];
2096 v31 = this;
2097 if ( &pActors[uActorID]
2098 && !this->pConditions[16]
2099 && !this->pConditions[14]
2100 && !this->pConditions[15]
2101 && !this->pConditions[4]
2102 && !this->pConditions[13]
2103 && !this->pConditions[2] )
2104 {
2105 if ( !(BYTE2(v5->uAttributes) & 0x80) )
2106 pActors[uActorID].SetRandomGoldIfTheresNoItem();
2107 v6 = v4->pActiveSkills[34];
2108 v7 = v6 & 0x3F;
2109 v8 = SkillToMastery(v6);
2110 v9 = rand();
2111 v28 = 4 * v8;
2112 v30 = dword_4EDEA0[v8];
2113 v29 = dword_4EDEB4[v9 % 100 / 20];
2114 v10 = v5->pMonsterInfo.uLevel + 100 * (_steal_perm + reputation);
2115 if ( rand() % 100 < 5 || v10 > v29 + v7 * v30 || (_steal_perma = 2, BYTE2(v5->uAttributes) & 8) )
2116 {
2117 Actor::AggroSurroundingPeasants(uActorID, 1);
2118 _steal_perma = 0;
2119 v26 = (int)v31->pName;
2120 v25 = pGlobalTXT_LocalizationStrings[376];
2121 }
2122 else
2123 {
2124 v11 = rand();
2125 if ( v11 % 100 >= 40 )
2126 {
2127 if ( v11 % 100 >= 70 )
2128 { 2055 {
2129 v19 = 0; 2056 return 1;
2130 if ( v7 > 0 )
2131 {
2132 do
2133 {
2134 --v7;
2135 v19 += rand() % dword_4EDEC4[v28 / 4] + 1;
2136 }
2137 while ( v7 );
2138 }
2139 if ( pItemsTable->pItems[v5->array_000234[3].uItemID].uEquipType != 18 )
2140 return _steal_perma;
2141 v20 = (int)&v5->array_000234[3].uSpecEnchantmentType;
2142 if ( (signed int)v19 > v5->array_000234[3].uSpecEnchantmentType )
2143 v19 = v5->array_000234[3].uSpecEnchantmentType;
2144 v21 = *(int *)v20 == v19;
2145 *(int *)v20 -= v19;
2146 if ( v21 )
2147 v5->array_000234[3].uItemID = 0;
2148 if ( v19 )
2149 {
2150 party_finds_gold(v19, 2);
2151 v22 = v19;
2152 v23 = pTmpBuf2.data();
2153 sprintf(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[302], v31->pName, v22);
2154 LABEL_43:
2155 ShowStatusBarString(v23, 2u);
2156 return _steal_perma;
2157 }
2158 } 2057 }
2159 else 2058 else
2160 { 2059 {
2161 v27.Reset(); 2060 return 0;
2162 v12 = 0;
2163 v13 = 0;
2164 v14 = (int)v5->array_000234;
2165 while ( !*(int *)v14 || pItemsTable->pItems[*(int *)v14].uEquipType == 18 )
2166 {
2167 ++v13;
2168 v14 += 36;
2169 if ( v13 >= 4 )
2170 goto LABEL_21;
2171 }
2172 v12 = 1;
2173 LABEL_21:
2174 v15 = v5->uCarriedItemID;
2175 if ( v15 || v12 )
2176 {
2177 v27.Reset();
2178 if ( v15 )
2179 {
2180 v16 = (signed __int16)v15;
2181 v5->uCarriedItemID = 0;
2182 v27.uItemID = (signed __int16)v15;
2183 v17 = (signed __int16)v15;
2184 if ( pItemsTable->pItems[v17].uEquipType == 12 )
2185 v27.uNumCharges = rand() % 6 + pItemsTable->pItems[v17].uDamageMod + 1;
2186 if ( pItemsTable->pItems[v17].uEquipType == 14 )
2187 {
2188 if ( v16 != 220 )
2189 v27.uEnchantmentType = 2 * rand() % 4 + 2;
2190 }
2191 }
2192 else
2193 {
2194 v18 = &v5->array_000234[rand() % 4];
2195 memcpy(&v27, v18, sizeof(v27));
2196 ((ItemGen *)v18)->Reset();
2197 v16 = v27.uItemID;
2198 }
2199 sub_421B2C_PlaceInInventory_or_DropPickedItem();
2200 sprintf(
2201 pTmpBuf2.data(),
2202 pGlobalTXT_LocalizationStrings[304],
2203 v31->pName,
2204 pItemsTable->pItems[v16].pUnidentifiedName);
2205 ShowStatusBarString(pTmpBuf2.data(), 2u);
2206 sub_421B2C_PlaceInInventory_or_DropPickedItem();
2207 memcpy(&pParty->pPickedItem, &v27, sizeof(pParty->pPickedItem));
2208 pMouse->SetCursorBitmapFromItemID(v16);
2209 return _steal_perma;
2210 }
2211 } 2061 }
2212 } 2062 else
2213 v26 = (int)v31->pName; 2063 return 2;
2214 v25 = pGlobalTXT_LocalizationStrings[377]; 2064 }
2215 } 2065 else
2216 v23 = pTmpBuf2.data(); 2066 {
2217 sprintfex(pTmpBuf2.data(), v25, v26); 2067 return 0;
2218 goto LABEL_43; 2068 }
2219 } 2069 }
2220 return 0; 2070 }
2071 // 4EDEA0: using guessed type int dword_4EDEA0[];
2072 // 4EDEB4: using guessed type int dword_4EDEB4[];
2073
2074 //----- (0048D88B) --------------------------------------------------------
2075 int Player::StealFromActor(unsigned int uActorID, int _steal_perm, int reputation)
2076 {
2077 Actor *actroPtr; // edi@1
2078 int v7; // ebx@10
2079 unsigned int stealingMastery; // esi@10
2080 int fineIfFailed; // esi@10
2081 int v11; // eax@13
2082 bool HasFullItemSlots; // ebx@15
2083 unsigned __int16 carriedItemId; // si@21
2084 unsigned int enchBonusSum; // esi@31
2085 int *enchTypePtr; // eax@34
2086 ItemGen tempItem; // [sp+8h] [bp-34h]@15
2087 int currMaxItemValue;
2088
2089 actroPtr = &pActors[uActorID];
2090 if ( !actroPtr
2091 || this->IsEradicated()
2092 || this->IsDead()
2093 || this->IsPertified()
2094 || this->IsDrunk()
2095 || this->IsUnconcious()
2096 || this->IsAsleep() )
2097 {
2098 return 0;
2099 }
2100 pGlobalTXT_LocalizationStrings[1];
2101 if ( !(BYTE2(actroPtr->uAttributes) & 0x80) )
2102 actroPtr->SetRandomGoldIfTheresNoItem();
2103 unsigned __int16 v6 = this->pActiveSkills[34];
2104 v7 = v6 & 0x3F;
2105 stealingMastery = SkillToMastery(v6);
2106 int v30 = StealingMasteryBonuses[stealingMastery];
2107 int v29 = StealingRandomBonuses[rand() % 5];
2108 fineIfFailed = actroPtr->pMonsterInfo.uLevel + 100 * (_steal_perm + reputation);
2109 currMaxItemValue = v29 + v7 * v30;
2110 pGlobalTXT_LocalizationStrings[200];
2111 if ( false && (rand() % 100 < 5 || fineIfFailed > currMaxItemValue || BYTE2(actroPtr->uAttributes) & 8) )
2112 {
2113 Actor::AggroSurroundingPeasants(uActorID, 1);
2114 sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[376], this->pName);
2115 ShowStatusBarString(pTmpBuf2.data(), 2u);
2116 return 0;
2117 }
2118 else
2119 {
2120 v11 = rand();
2121 if ( v11 % 100 >= 70 ) //stealing gold
2122 {
2123 enchBonusSum = 0;
2124 for (int i = 0; i < v7; i++)
2125 {
2126 enchBonusSum += rand() % StealingEnchantmentBonusForSkill[stealingMastery] + 1;
2127 }
2128 if ( pItemsTable->pItems[actroPtr->array_000234[3].uItemID].uEquipType != EQUIP_GOLD )
2129 return 2;
2130 enchTypePtr = &actroPtr->array_000234[3].uSpecEnchantmentType;
2131 if ( (int)enchBonusSum >= *enchTypePtr )
2132 {
2133 actroPtr->array_000234[3].uItemID = 0;
2134 *enchTypePtr = 0;
2135 }
2136 else
2137 {
2138 *enchTypePtr -= enchBonusSum;
2139 }
2140 if ( enchBonusSum )
2141 {
2142 party_finds_gold(enchBonusSum, 2);
2143 sprintf(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[302], this->pName, enchBonusSum); //%stole %d gold
2144 }
2145 else
2146 {
2147 sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[377], this->pName); //%s failed to steal anything
2148 }
2149 ShowStatusBarString(pTmpBuf2.data(), 2u);
2150 return 2;
2151 }
2152 else if ( v11 % 100 >= 40 ) //stealing an item
2153 {
2154 tempItem.Reset();
2155 HasFullItemSlots = false;
2156 int i;
2157 for (i = 0; i < 4; i++)
2158 {
2159 if ( actroPtr->array_000234[i].uItemID != 0 && pItemsTable->pItems[actroPtr->array_000234[i].uItemID].uEquipType != EQUIP_GOLD )
2160 break;
2161 }
2162 if (i == 4)
2163 HasFullItemSlots = true;
2164 carriedItemId = actroPtr->uCarriedItemID;
2165 if ( carriedItemId != 0 || HasFullItemSlots )
2166 {
2167 tempItem.Reset();
2168 if ( carriedItemId != 0 )
2169 {
2170 actroPtr->uCarriedItemID = 0;
2171 tempItem.uItemID = carriedItemId;
2172 if ( pItemsTable->pItems[carriedItemId].uEquipType == EQUIP_WAND )
2173 tempItem.uNumCharges = rand() % 6 + pItemsTable->pItems[carriedItemId].uDamageMod + 1;
2174 else if ( pItemsTable->pItems[carriedItemId].uEquipType == EQUIP_POTION && carriedItemId != ITEM_POTION_BOTTLE)
2175 tempItem.uEnchantmentType = 2 * rand() % 4 + 2;
2176 }
2177 else
2178 {
2179 ItemGen* itemToSteal = &actroPtr->array_000234[rand() % 4];
2180 memcpy(&tempItem, itemToSteal, sizeof(tempItem));
2181 itemToSteal->Reset();
2182 carriedItemId = tempItem.uItemID;
2183 }
2184 sub_421B2C_PlaceInInventory_or_DropPickedItem();
2185 sprintf(
2186 pTmpBuf2.data(),
2187 pGlobalTXT_LocalizationStrings[304], // Official //TODO: add a normal "%d stole %d" message
2188 this->pName,
2189 pItemsTable->pItems[carriedItemId].pUnidentifiedName);
2190 ShowStatusBarString(pTmpBuf2.data(), 2u);
2191 sub_421B2C_PlaceInInventory_or_DropPickedItem();
2192 memcpy(&pParty->pPickedItem, &tempItem, sizeof(ItemGen));
2193 pMouse->SetCursorBitmapFromItemID(carriedItemId);
2194 return 2;
2195 }
2196 }
2197 sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[377], this->pName); //%s failed to steal anything
2198 ShowStatusBarString(pTmpBuf2.data(), 2u);
2199 return 2;
2200 }
2221 } 2201 }
2222 // 4EDEA0: using guessed type int dword_4EDEA0[]; 2202 // 4EDEA0: using guessed type int dword_4EDEA0[];
2223 // 4EDEB4: using guessed type int dword_4EDEB4[]; 2203 // 4EDEB4: using guessed type int dword_4EDEB4[];
2224 // 4EDEC4: using guessed type int dword_4EDEC4[]; 2204 // 4EDEC4: using guessed type int dword_4EDEC4[];
2225 2205
2286 PlaySound(SPEECH_24, 0); 2266 PlaySound(SPEECH_24, 0);
2287 return recieved_dmg; 2267 return recieved_dmg;
2288 } 2268 }
2289 2269
2290 //----- (0048DCF6) -------------------------------------------------------- 2270 //----- (0048DCF6) --------------------------------------------------------
2291 int Player::_48DCF6(int a2, Actor *pActor) //TODO check this with IDA to see what the uninitialized vars are supposed to contain 2271 int Player::ReceiveSpecialAttackEffect( int attType, struct Actor *pActor )
2292 { 2272 {
2273 SPECIAL_ATTACK_TYPE attTypeCast = (SPECIAL_ATTACK_TYPE) attType;
2293 signed int v3; // edi@1 2274 signed int v3; // edi@1
2294 signed int v4; // ebx@1 2275 signed int v4; // ebx@1
2295 Player *v5; // esi@1
2296 int v6; // eax@2 2276 int v6; // eax@2
2297 int v7; // eax@5
2298 int v8; // eax@8 2277 int v8; // eax@8
2299 int v9; // ebx@8
2300 int v10; // eax@8 2278 int v10; // eax@8
2301 int v11; // ebx@8 2279 int v11; // ebx@8
2302 signed int v12; // edx@9
2303 ItemGen *v13; // eax@9 2280 ItemGen *v13; // eax@9
2304 int v14; // edx@16
2305 unsigned int v15; // edx@17
2306 int v16; // edx@26
2307 unsigned int v17; // edx@27
2308 signed int v19; // edx@38
2309 int *v20; // ecx@38
2310 signed int v21; // eax@40
2311 int v22; // eax@49 2281 int v22; // eax@49
2312 signed int v23; // ebx@49 2282 signed int v23; // ebx@49
2313 unsigned int v24; // eax@60
2314 int v25; // ecx@61
2315 int v26; // ebx@74
2316 void *v27; // ecx@76 2283 void *v27; // ecx@76
2317 unsigned int v28; // ebx@78
2318 signed int result; // eax@86
2319 SoundID v30; // [sp-20h] [bp-C0h]@56
2320 signed int v31; // [sp-1Ch] [bp-BCh]@56
2321 unsigned int v32; // [sp-18h] [bp-B8h]@56
2322 signed int v33; // [sp-14h] [bp-B4h]@56
2323 signed int v34; // [sp-10h] [bp-B0h]@56
2324 int v35; // [sp-Ch] [bp-ACh]@56
2325 unsigned int v36; // [sp-8h] [bp-A8h]@51
2326 unsigned int v37; // [sp-8h] [bp-A8h]@56
2327 unsigned int v38; // [sp-8h] [bp-A8h]@57
2328 unsigned int v39; // [sp-8h] [bp-A8h]@68
2329 enum CHARACTER_ATTRIBUTE_TYPE v40; // [sp-4h] [bp-A4h]@4
2330 int v41; // [sp-4h] [bp-A4h]@51
2331 int v42; // [sp-4h] [bp-A4h]@56
2332 int v43; // [sp-4h] [bp-A4h]@57
2333 signed int v44; // [sp-4h] [bp-A4h]@59
2334 int v45; // [sp-4h] [bp-A4h]@68
2335 char v46[140]; // [sp+Ch] [bp-94h]@13 2284 char v46[140]; // [sp+Ch] [bp-94h]@13
2336 unsigned int v47; // [sp+98h] [bp-8h]@1 2285 unsigned int v47; // [sp+98h] [bp-8h]@1
2337 int v48; // [sp+9Ch] [bp-4h]@1 2286 ItemGen* v48; // [sp+9Ch] [bp-4h]@1
2338 2287
2339 v3 = 0;
2340 v4 = 0; 2288 v4 = 0;
2341 v5 = this;
2342 v47 = 0; 2289 v47 = 0;
2343 v48 = 0; 2290 switch ( attTypeCast )
2344 switch ( a2 ) 2291 {
2345 { 2292 case SPECIAL_ATTACK_CURSE:
2346 case 1:
2347 v6 = GetActualWillpower(); 2293 v6 = GetActualWillpower();
2348 goto LABEL_46; 2294 v11 = GetParameterBonus(v6);
2349 case 2: 2295 break;
2350 case 3: 2296 case SPECIAL_ATTACK_WEAK:
2351 case 4: 2297 case SPECIAL_ATTACK_SLEEP:
2352 case 9: 2298 case SPECIAL_ATTACK_DRUNK:
2353 case 10: 2299 case SPECIAL_ATTACK_DISEASE1:
2354 case 11: 2300 case SPECIAL_ATTACK_DISEASE2:
2355 case 13: 2301 case SPECIAL_ATTACK_DISEASE3:
2356 case 21: 2302 case SPECIAL_ATTACK_UNCONSCIOUS:
2303 case SPECIAL_ATTACK_AGING:
2357 v6 = GetActualEndurance(); 2304 v6 = GetActualEndurance();
2358 goto LABEL_46; 2305 v11 = GetParameterBonus(v6);
2359 case 5: 2306 break;
2360 case 12: 2307 case SPECIAL_ATTACK_INSANE:
2361 case 23: 2308 case SPECIAL_ATTACK_PARALYZED:
2362 v40 = (CHARACTER_ATTRIBUTE_TYPE)14; 2309 case SPECIAL_ATTACK_FEAR:
2363 goto LABEL_5; 2310 v11 = GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_MIND);
2364 case 15: 2311 break;
2365 v40 = (CHARACTER_ATTRIBUTE_TYPE)13; 2312 case SPECIAL_ATTACK_PETRIFIED:
2366 goto LABEL_5; 2313 v11 = GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_EARTH);
2367 case 6: 2314 break;
2368 case 7: 2315 case SPECIAL_ATTACK_POISON1:
2369 case 8: 2316 case SPECIAL_ATTACK_POISON2:
2370 case 14: 2317 case SPECIAL_ATTACK_POISON3:
2371 case 16: 2318 case SPECIAL_ATTACK_DEAD:
2372 v40 = (CHARACTER_ATTRIBUTE_TYPE)15; 2319 case SPECIAL_ATTACK_ERADICATED:
2373 LABEL_5: 2320 v11 = GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_BODY);
2374 v7 = GetActualResistance(v40); 2321 break;
2375 goto LABEL_47; 2322 case SPECIAL_ATTACK_MANA_DRAIN:
2376 case 22:
2377 v8 = GetActualWillpower(); 2323 v8 = GetActualWillpower();
2378 v9 = GetParameterBonus(v8);
2379 v10 = GetActualIntelligence(); 2324 v10 = GetActualIntelligence();
2380 v11 = (GetParameterBonus(v10) + v9) >> 1; 2325 v11 = (GetParameterBonus(v10) + GetParameterBonus(v8)) / 2;
2381 break; 2326 break;
2382 case 17: 2327 case SPECIAL_ATTACK_BREAK_ANY:
2383 v12 = 0; 2328 for (int i = 0; i < 138; i++)
2384 v13 = this->pInventoryItemList; 2329 {
2385 do 2330 v13 = &this->pInventoryItemList[i];
2386 { 2331 if ( v13->uItemID > 0 && v13->uItemID <= 134 && !v13->IsBroken())
2387 if ( (signed int)v13->uItemID > 0 && (signed int)v13->uItemID <= 134 && !v13->IsBroken()) 2332 v46[v4++] = i;
2388 v46[v4++] = v12; 2333 }
2389 ++v12; 2334 if ( !v4 )
2390 ++v13; 2335 return 0;
2391 } 2336 v48 = &this->pInventoryItemList[v46[rand() % v4]];
2392 while ( v12 < 138 ); 2337 v11 = 3 * (pItemsTable->pItems[v48->uItemID].uMaterial + pItemsTable->pItems[v48->uItemID].uDamageMod);
2393 goto LABEL_36; 2338 break;
2394 case 18: 2339 case SPECIAL_ATTACK_BREAK_ARMOR:
2395 v14 = 0; 2340 for (int i = 0; i < 16; i++ )
2396 do 2341 {
2397 { 2342 if ( HasItemEquipped((ITEM_EQUIP_TYPE)i) )
2398 if ( HasItemEquipped((ITEM_EQUIP_TYPE)v14) )
2399 { 2343 {
2400 __debugbreak(); // player.cpp(2871): warning C4700: uninitialized local variable 'v15' used 2344 if ( i == EQUIP_ARMOUR )
2401 if ( v15 == EQUIP_ARMOUR ) 2345 v46[v4++] = this->pEquipment.uArmor - 1;
2402 v46[v4++] = LOBYTE(v5->pEquipment.uArmor) - 1; 2346 if ( (i == EQUIP_OFF_HAND || i == EQUIP_MAIN_HAND) && GetEquippedItemEquipType((ITEM_EQUIP_TYPE)i) == EQUIP_SHIELD )
2403 if ( (!v15 || v15 == 1) && GetEquippedItemEquipType((ITEM_EQUIP_TYPE)v15) == 4 ) 2347 v46[v4++] = this->pEquipment.pIndices[i] - 1;
2404 v46[v4++] = *((char *)&v5->pEquipment.uShield + 4 * v15) - 1;
2405 } 2348 }
2406 v14 = v15 + 1; 2349 }
2407 } 2350 if ( !v4 )
2408 while ( v14 < 16 ); 2351 return 0;
2409 goto LABEL_36; 2352 v48 = &this->pInventoryItemList[v46[rand() % v4]];
2410 case 19: 2353 v11 = 3 * (pItemsTable->pItems[v48->uItemID].uMaterial + pItemsTable->pItems[v48->uItemID].uDamageMod);
2411 v16 = 0; 2354 break;
2412 do 2355 case SPECIAL_ATTACK_BREAK_WEAPON:
2413 { 2356 for (int i = 0; i < 16; i++ )
2414 if ( HasItemEquipped((ITEM_EQUIP_TYPE)v16) ) 2357 {
2358 if ( HasItemEquipped((ITEM_EQUIP_TYPE)i) )
2415 { 2359 {
2416 __debugbreak(); // player.cpp(2886): warning C4700: uninitialized local variable 'v17' used 2360 if ( i == EQUIP_BOW )
2417 if ( v17 == 2 ) 2361 v46[v4++] = LOBYTE(this->pEquipment.uBow) - 1;
2418 v46[v4++] = LOBYTE(v5->pEquipment.uBow) - 1; 2362 if ( (i == EQUIP_OFF_HAND || i == EQUIP_MAIN_HAND)
2419 if ( (!v17 || v17 == 1) 2363 && (GetEquippedItemEquipType((ITEM_EQUIP_TYPE)i) == EQUIP_OFF_HAND || GetEquippedItemEquipType((ITEM_EQUIP_TYPE)i) == EQUIP_MAIN_HAND) )
2420 && (!GetEquippedItemEquipType((ITEM_EQUIP_TYPE)v17) || GetEquippedItemEquipType((ITEM_EQUIP_TYPE)v17) == 1) ) 2364 v46[v4++] = this->pEquipment.pIndices[i] - 1;
2421 v46[v4++] = *((char *)&v5->pEquipment.uShield + 4 * v17) - 1;
2422 } 2365 }
2423 v16 = v17 + 1; 2366 }
2424 }
2425 while ( v16 < 16 );
2426 LABEL_36:
2427 if ( !v4 ) 2367 if ( !v4 )
2428 goto LABEL_87; 2368 return 0;
2429 v48 = (int)&v5->pInventoryItemList[(unsigned __int8)v46[rand() % v4]]; 2369 v48 = &this->pInventoryItemList[v46[rand() % v4]];
2430 v11 = 3 * (pItemsTable->pItems[*(int *)v48].uMaterial + pItemsTable->pItems[*(int *)v48].uDamageMod); 2370 v11 = 3 * (pItemsTable->pItems[v48->uItemID].uMaterial + pItemsTable->pItems[v48->uItemID].uDamageMod);
2431 break; 2371 break;
2432 case 20: 2372 case SPECIAL_ATTACK_STEAL:
2433 v19 = 0; 2373 for ( int i = 0; i < 126; i++ )
2434 v20 = this->pInventoryMatrix; 2374 {
2435 do 2375 int ItemPosInList = this->pInventoryMatrix[i];
2436 { 2376 if (ItemPosInList > 0)
2437 if ( *v20 > 0 )
2438 { 2377 {
2439 v21 = *(int *)&v5->pInventoryItemList[*v20-1]; 2378 ItemGen* v21 = &this->pInventoryItemList[ItemPosInList - 1];
2440 if ( v21 > 0 ) 2379 if ( v21->uItemID > 0 && v21->uItemID <= 134 )
2441 { 2380 {
2442 if ( v21 <= 134 ) 2381 v46[v4++] = i;
2443 v46[v4++] = v19;
2444 } 2382 }
2445 } 2383 }
2446 ++v19; 2384 }
2447 ++v20;
2448 }
2449 while ( v19 < 126 );
2450 if ( !v4 ) 2385 if ( !v4 )
2451 goto LABEL_87; 2386 return 0;
2452 v47 = (unsigned __int8)v46[rand() % v4]; 2387 v47 = v46[rand() % v4];
2453 v6 = GetActualAccuracy(); 2388 v6 = GetActualAccuracy();
2454 LABEL_46: 2389 v11 = GetParameterBonus(v6);
2455 v7 = GetParameterBonus(v6);
2456 LABEL_47:
2457 v11 = v7;
2458 break; 2390 break;
2459 default: 2391 default:
2460 v11 = 0; 2392 v11 = 0;
2461 break; 2393 break;
2462 } 2394 }
2463 v22 = GetActualLuck(); 2395 v22 = GetActualLuck();
2464 v23 = GetParameterBonus(v22) + v11 + 30; 2396 v23 = GetParameterBonus(v22) + v11 + 30;
2465 if ( rand() % v23 >= 30 ) 2397 if ( rand() % v23 >= 30 )
2466 { 2398 {
2467 LABEL_87: 2399 return 0;
2468 result = 0;
2469 } 2400 }
2470 else 2401 else
2471 { 2402 {
2472 switch ( a2 ) 2403 for ( v3 = 0; v3 < 4; v3++ )
2473 { 2404 {
2474 case 1: 2405 if ( this == pPlayers[v3 + 1] )
2475 v41 = 1; 2406 break;
2476 v36 = 0; 2407 }
2477 goto LABEL_56; 2408
2478 case 2: 2409 switch ( attTypeCast )
2479 v41 = 1; 2410 {
2480 v36 = 1; 2411 case SPECIAL_ATTACK_CURSE:
2481 goto LABEL_56; 2412 SetCondition(Condition_Cursed, 1);
2482 case 3: 2413 pAudioPlayer->PlaySound((SoundID)221, 0, 0, -1, 0, 0, 0, 0);
2483 v41 = 1; 2414 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2484 v36 = 2; 2415 return 1;
2485 goto LABEL_56; 2416 break;
2486 case 23: 2417 case SPECIAL_ATTACK_WEAK:
2487 v41 = 1; 2418 SetCondition(Condition_Weak, 1);
2488 v36 = 3; 2419 pAudioPlayer->PlaySound((SoundID)221, 0, 0, -1, 0, 0, 0, 0);
2489 goto LABEL_56; 2420 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2490 case 4: 2421 return 1;
2491 v41 = 1; 2422 break;
2492 v36 = 4; 2423 case SPECIAL_ATTACK_SLEEP:
2493 LABEL_56: 2424 SetCondition(Condition_Sleep, 1);
2494 SetCondition(v36, v41); 2425 pAudioPlayer->PlaySound((SoundID)221, 0, 0, -1, 0, 0, 0, 0);
2495 v42 = 0; 2426 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2496 v37 = 0; 2427 return 1;
2497 v35 = 0; 2428 break;
2498 v34 = 0; 2429 case SPECIAL_ATTACK_DRUNK:
2499 v33 = -1; 2430 SetCondition(Condition_Drunk, 1);
2500 v32 = 0; 2431 pAudioPlayer->PlaySound((SoundID)221, 0, 0, -1, 0, 0, 0, 0);
2501 v31 = 0; 2432 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2502 v30 = (SoundID)221; 2433 return 1;
2503 goto LABEL_83; 2434 break;
2504 case 5: 2435 case SPECIAL_ATTACK_INSANE:
2505 v43 = 1; 2436 SetCondition(Condition_Insane, 1);
2506 v38 = 5; 2437 pAudioPlayer->PlaySound((SoundID)224, 0, 0, -1, 0, 0, 0, 0);
2507 goto LABEL_70; 2438 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2508 case 6: 2439 return 1;
2509 case 7: 2440 break;
2510 case 8: 2441 case SPECIAL_ATTACK_POISON1:
2511 if ( a2 == 6 ) 2442 SetCondition(Condition_Poison1, 1);
2443 pAudioPlayer->PlaySound((SoundID)222, 0, 0, -1, 0, 0, 0, 0);
2444 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2445 return 1;
2446 break;
2447 case SPECIAL_ATTACK_POISON2:
2448 SetCondition(Condition_Poison2, 1);
2449 pAudioPlayer->PlaySound((SoundID)222, 0, 0, -1, 0, 0, 0, 0);
2450 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2451 return 1;
2452 break;
2453 case SPECIAL_ATTACK_POISON3:
2454 SetCondition(Condition_Poison3, 1);
2455 pAudioPlayer->PlaySound((SoundID)222, 0, 0, -1, 0, 0, 0, 0);
2456 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2457 return 1;
2458 break;
2459 case SPECIAL_ATTACK_DISEASE1:
2460 SetCondition(Condition_Disease1, 1);
2461 pAudioPlayer->PlaySound((SoundID)222, 0, 0, -1, 0, 0, 0, 0);
2462 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2463 return 1;
2464 break;
2465 case SPECIAL_ATTACK_DISEASE2:
2466 SetCondition(Condition_Disease2, 1);
2467 pAudioPlayer->PlaySound((SoundID)222, 0, 0, -1, 0, 0, 0, 0);
2468 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2469 return 1;
2470 break;
2471 case SPECIAL_ATTACK_DISEASE3:
2472 SetCondition(Condition_Disease3, 1);
2473 pAudioPlayer->PlaySound((SoundID)222, 0, 0, -1, 0, 0, 0, 0);
2474 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2475 return 1;
2476 break;
2477 case SPECIAL_ATTACK_PARALYZED:
2478 SetCondition(Condition_Paralyzed, 1);
2479 pAudioPlayer->PlaySound((SoundID)224, 0, 0, -1, 0, 0, 0, 0);
2480 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2481 return 1;
2482 break;
2483 case SPECIAL_ATTACK_UNCONSCIOUS:
2484 SetCondition(Condition_Unconcious, 1);
2485 pAudioPlayer->PlaySound((SoundID)224, 0, 0, -1, 0, 0, 0, 0);
2486 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2487 return 1;
2488 break;
2489 case SPECIAL_ATTACK_DEAD:
2490 SetCondition(Condition_Dead, 1);
2491 pAudioPlayer->PlaySound((SoundID)225, 0, 0, -1, 0, 0, 0, 0);
2492 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2493 return 1;
2494 break;
2495 case SPECIAL_ATTACK_PETRIFIED:
2496 SetCondition(Condition_Pertified, 1);
2497 pAudioPlayer->PlaySound((SoundID)225, 0, 0, -1, 0, 0, 0, 0);
2498 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2499 return 1;
2500 break;
2501 case SPECIAL_ATTACK_ERADICATED:
2502 SetCondition(Condition_Eradicated, 1);
2503 pAudioPlayer->PlaySound((SoundID)225, 0, 0, -1, 0, 0, 0, 0);
2504 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2505 return 1;
2506 break;
2507 case SPECIAL_ATTACK_BREAK_ANY:
2508 case SPECIAL_ATTACK_BREAK_ARMOR:
2509 case SPECIAL_ATTACK_BREAK_WEAPON:
2510 if ( !(v48->uAttributes & ITEM_ENCHANTED) )
2512 { 2511 {
2513 v44 = 6; 2512 PlaySound(SPEECH_40, 0);
2514 goto LABEL_60; 2513 v48->SetBroken();
2514 pAudioPlayer->PlaySound((SoundID)47, 0, 0, -1, 0, 0, 0, 0);
2515 } 2515 }
2516 v25 = 2 * (a2 != 8) + 8;
2517 goto LABEL_65;
2518 case 9:
2519 if ( a2 == 6 )
2520 {
2521 v44 = 7;
2522 LABEL_60:
2523 v24 = v44;
2524 }
2525 else
2526 {
2527 v25 = 2 * (a2 != 8) + 9;
2528 LABEL_65:
2529 v24 = v25;
2530 }
2531 SetCondition(v24, 1);
2532 v42 = 0;
2533 v37 = 0;
2534 v35 = 0;
2535 v34 = 0;
2536 v33 = -1;
2537 v32 = 0;
2538 v31 = 0;
2539 v30 = (SoundID)222;
2540 LABEL_83:
2541 pAudioPlayer->PlaySound(v30, v31, v32, v33, v34, v35, v37, v42);
2542 do
2543 {
2544 LABEL_84:
2545 if ( v5 == pPlayers[v3 + 1] )
2546 break;
2547 ++v3;
2548 }
2549 while ( v3 < 4 );
2550 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3); 2516 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2551 result = 1; 2517 return 1;
2552 break; 2518 break;
2553 case 12: 2519 case SPECIAL_ATTACK_STEAL:
2554 v43 = 1;
2555 v38 = 12;
2556 goto LABEL_70;
2557 case 15:
2558 v45 = 1;
2559 v39 = 15;
2560 goto LABEL_73;
2561 case 13:
2562 v43 = 1;
2563 v38 = 13;
2564 LABEL_70:
2565 SetCondition(v38, v43);
2566 v42 = 0;
2567 v37 = 0;
2568 v35 = 0;
2569 v34 = 0;
2570 v33 = -1;
2571 v32 = 0;
2572 v31 = 0;
2573 v30 = (SoundID)224;
2574 goto LABEL_83;
2575 case 14:
2576 v45 = 1;
2577 v39 = 14;
2578 goto LABEL_73;
2579 case 16:
2580 v45 = 1;
2581 v39 = 16;
2582 LABEL_73:
2583 SetCondition(v39, v45);
2584 v42 = 0;
2585 v37 = 0;
2586 v35 = 0;
2587 v34 = 0;
2588 v33 = -1;
2589 v32 = 0;
2590 v31 = 0;
2591 v30 = (SoundID)225;
2592 goto LABEL_83;
2593 case 17:
2594 case 18:
2595 case 19:
2596 v26 = v48;
2597 if ( *(char *)(v48 + 21) & 2 )
2598 goto LABEL_84;
2599 PlaySound(SPEECH_40, 0);
2600 *(int *)(v26 + 20) |= 2u;
2601 goto LABEL_79;
2602 case 20:
2603 PlaySound(SPEECH_40, 0); 2520 PlaySound(SPEECH_40, 0);
2604 v27 = pActor->array_000234; 2521 v27 = pActor->array_000234;
2605 if ( pActor->array_000234[0].uItemID ) 2522 if ( pActor->array_000234[0].uItemID )
2606 { 2523 {
2607 v27 = &pActor->array_000234[1]; 2524 v27 = &pActor->array_000234[1];
2608 if ( pActor->array_000234[1].uItemID ) 2525 if ( pActor->array_000234[1].uItemID )
2609 goto LABEL_84; 2526 {
2527 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2528 return 1;
2529 }
2610 } 2530 }
2611 v28 = v47; 2531 memcpy(v27, &this->pInventoryItemList[this->pInventoryMatrix[v47]-1], 0x24u);
2612 memcpy(v27, &v5->pInventoryItemList[v5->pInventoryMatrix[v47]-1], 0x24u); 2532 RemoveItemAtInventoryIndex(v47);
2613 RemoveItemAtInventoryIndex(v28); 2533 pAudioPlayer->PlaySound((SoundID)47, 0, 0, -1, 0, 0, 0, 0);
2614 LABEL_79: 2534 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2615 v42 = 0; 2535 return 1;
2616 v37 = 0; 2536 break;
2617 v35 = 0; 2537 case SPECIAL_ATTACK_AGING:
2618 v34 = 0;
2619 v33 = -1;
2620 v32 = 0;
2621 v31 = 0;
2622 v30 = (SoundID)47;
2623 goto LABEL_83;
2624 case 21:
2625 PlaySound(SPEECH_42, 0); 2538 PlaySound(SPEECH_42, 0);
2626 ++v5->sAgeModifier; 2539 ++this->sAgeModifier;
2627 goto LABEL_82; 2540 pAudioPlayer->PlaySound((SoundID)226, 0, 0, -1, 0, 0, 0, 0);
2628 case 22: 2541 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2542 return 1;
2543 break;
2544 case SPECIAL_ATTACK_MANA_DRAIN:
2629 PlaySound(SPEECH_41, 0); 2545 PlaySound(SPEECH_41, 0);
2630 v5->sMana = 0; 2546 this->sMana = 0;
2631 LABEL_82: 2547 pAudioPlayer->PlaySound((SoundID)226, 0, 0, -1, 0, 0, 0, 0);
2632 v42 = 0; 2548 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2633 v37 = 0; 2549 return 1;
2634 v35 = 0; 2550 break;
2635 v34 = 0; 2551 case SPECIAL_ATTACK_FEAR:
2636 v33 = -1; 2552 SetCondition(Condition_Fear, 1);
2637 v32 = 0; 2553 pAudioPlayer->PlaySound((SoundID)221, 0, 0, -1, 0, 0, 0, 0);
2638 v31 = 0; 2554 pGame->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
2639 v30 = (SoundID)226; 2555 return 1;
2640 goto LABEL_83; 2556 break;
2641 default: 2557 default:
2642 goto LABEL_87; 2558 return 0;
2643 } 2559 }
2644 } 2560 }
2645 return result;
2646 } 2561 }
2647 2562
2648 // 48DCF6: using guessed type char var_94[140]; 2563 // 48DCF6: using guessed type char var_94[140];
2649 2564
2650 //----- (0048E1A3) -------------------------------------------------------- 2565 //----- (0048E1A3) --------------------------------------------------------
4417 } 4332 }
4418 4333
4419 //----- (004908A8) -------------------------------------------------------- 4334 //----- (004908A8) --------------------------------------------------------
4420 bool Player::DiscardConditionIfLastsLongerThan(unsigned int uCondition, unsigned __int64 uTime) 4335 bool Player::DiscardConditionIfLastsLongerThan(unsigned int uCondition, unsigned __int64 uTime)
4421 { 4336 {
4422 if ( pConditions[uCondition] && (uTime < pConditions[uCondition]) ) 4337 if ( pConditions[uCondition] && (uTime < (signed long long)pConditions[uCondition]) )
4423 { 4338 {
4424 pConditions[uCondition] = 0i64; 4339 pConditions[uCondition] = 0i64;
4425 return true; 4340 return true;
4426 } 4341 }
4427 else 4342 else
4504 thisb->SetRecoveryTime(100); 4419 thisb->SetRecoveryTime(100);
4505 pTurnEngine->ApplyPlayerAction(); 4420 pTurnEngine->ApplyPlayerAction();
4506 } 4421 }
4507 else 4422 else
4508 { 4423 {
4509 thisb->SetRecoveryTime(flt_6BE3A4_debug_recmod1 * 213.3333333333333); 4424 thisb->SetRecoveryTime((int)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
4510 } 4425 }
4511 } 4426 }
4512 pMouse->RemoveHoldingItem(); 4427 pMouse->RemoveHoldingItem();
4513 return; 4428 return;
4514 } 4429 }
4799 thisb->SetRecoveryTime(100); 4714 thisb->SetRecoveryTime(100);
4800 pTurnEngine->ApplyPlayerAction(); 4715 pTurnEngine->ApplyPlayerAction();
4801 } 4716 }
4802 else 4717 else
4803 { 4718 {
4804 thisb->SetRecoveryTime(flt_6BE3A4_debug_recmod1 * 213.3333333333333); 4719 thisb->SetRecoveryTime((int)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
4805 } 4720 }
4806 } 4721 }
4807 pMouse->RemoveHoldingItem(); 4722 pMouse->RemoveHoldingItem();
4808 return; 4723 return;
4809 } 4724 }
7465 } 7380 }
7466 7381
7467 7382
7468 7383
7469 //----- (00439FCB) -------------------------------------------------------- 7384 //----- (00439FCB) --------------------------------------------------------
7470 void __fastcall DamagePlayerFromMonster(unsigned int uObjID, int a2, Vec3_int_ *pPos, unsigned int a4) 7385 void __fastcall DamagePlayerFromMonster(unsigned int uObjID, int element, Vec3_int_ *pPos, unsigned int a4)
7471 { 7386 {
7472 signed int v4; // esi@1
7473 unsigned int v5; // ecx@1
7474 Player *playerPtr; // ebx@3 7387 Player *playerPtr; // ebx@3
7475 Actor *actorPtr; // esi@3 7388 Actor *actorPtr; // esi@3
7476 unsigned int v8; // eax@4 7389 unsigned int v8; // eax@4
7477 int v11; // edx@8 7390 int spellId; // eax@38
7478 int v14; // edx@16
7479 enum SoundID v17; // eax@24
7480 unsigned __int16 v21; // ax@29
7481 signed int v22; // edi@36
7482 int v23; // eax@38
7483 signed int v24; // eax@44
7484 AIState v25; // cx@47
7485 signed int v26; // eax@49
7486 int v27; // eax@54
7487 int v34; // edi@61
7488 int v35; // eax@70
7489 int v36; // st7@70
7490 SpriteObject *v37; // ebx@77
7491 int v38; // edi@77
7492 int v39; // esi@77
7493 int v40; // eax@77
7494 int v41; // eax@77
7495 Player *v43; // eax@81
7496 //Actor *actorPtr; // esi@82
7497 Player *v45; // edi@84
7498 unsigned __int16 v46; // ax@84
7499 int v48; // eax@107
7500 unsigned __int16 v49; // ax@116
7501 int v50; // ebx@123
7502 unsigned __int16 v51; // ax@124
7503 int v53; // eax@128
7504 signed int v54; // eax@134
7505 unsigned __int16 v55; // cx@137
7506 signed int recvdMagicDmg; // eax@139 7391 signed int recvdMagicDmg; // eax@139
7507 int v57; // eax@144
7508 int v64; // ebx@151
7509 int v65; // eax@161
7510 int v66; // st7@161
7511 signed int v68; // eax@170
7512 int v69; // ecx@170
7513 int v70; // eax@171
7514 int v72[4]; // [sp+30h] [bp-24h]@164 7392 int v72[4]; // [sp+30h] [bp-24h]@164
7515 signed int v74; // [sp+44h] [bp-10h]@1
7516 int healthBeforeRecvdDamage; // [sp+48h] [bp-Ch]@3 7393 int healthBeforeRecvdDamage; // [sp+48h] [bp-Ch]@3
7517 unsigned int uActorID; // [sp+4Ch] [bp-8h]@1 7394 unsigned int uActorID; // [sp+4Ch] [bp-8h]@1
7518 int dmgToReceive; // [sp+50h] [bp-4h]@26 7395
7519 7396 uActorID = PID_ID(uObjID);
7520 v4 = PID_ID(uObjID); 7397 if ( PID_TYPE(uObjID) != 2)
7521 v5 = PID_TYPE(uObjID) - 2;
7522 v74 = a2;
7523 uActorID = v4;
7524 if ( v5 )
7525 { 7398 {
7526 playerPtr = &pParty->pPlayers[a4]; 7399 playerPtr = &pParty->pPlayers[a4];
7527 actorPtr = &pActors[v4]; 7400 actorPtr = &pActors[uActorID];
7528 healthBeforeRecvdDamage = playerPtr->sHealth; 7401 healthBeforeRecvdDamage = playerPtr->sHealth;
7529 if ( v5 != 1 || !stru_50C198.ActorHitOrMiss(actorPtr, playerPtr) ) 7402 if ( PID_TYPE(uObjID) != 3 || !stru_50C198.ActorHitOrMiss(actorPtr, playerPtr) )
7530 return; 7403 return;
7531 v8 = playerPtr->pEquipment.uArmor; 7404 v8 = playerPtr->pEquipment.uArmor;
7405 SoundID soundToPlay;
7532 if ( !v8 7406 if ( !v8
7533 || playerPtr->pInventoryItemList[v8 - 1].IsBroken() 7407 || playerPtr->pInventoryItemList[v8 - 1].IsBroken()
7534 || 7408 ||
7535 (pItemsTable->pItems[playerPtr->pInventoryItemList[v8 - 1].uItemID].uSkillType != PLAYER_SKILL_CHAIN 7409 (pItemsTable->pItems[playerPtr->pInventoryItemList[v8 - 1].uItemID].uSkillType != PLAYER_SKILL_CHAIN
7536 && pItemsTable->pItems[playerPtr->pInventoryItemList[v8 - 1].uItemID].uSkillType != PLAYER_SKILL_PLATE 7410 && pItemsTable->pItems[playerPtr->pInventoryItemList[v8 - 1].uItemID].uSkillType != PLAYER_SKILL_PLATE
7537 ) 7411 )
7538 ) 7412 )
7539 { 7413 {
7540 v14 = rand() % 4; 7414 int randVal = rand() % 4;
7541 switch (v14) 7415 switch (randVal)
7542 { 7416 {
7543 case 0 : v17 = (SoundID)108; break; 7417 case 0 : soundToPlay = (SoundID)108; break;
7544 case 1 : v17 = (SoundID)109; break; 7418 case 1 : soundToPlay = (SoundID)109; break;
7545 case 2 : v17 = (SoundID)110; break; 7419 case 2 : soundToPlay = (SoundID)110; break;
7546 case 3 : v17 = (SoundID)44; break; 7420 case 3 : soundToPlay = (SoundID)44; break;
7547 } 7421 }
7548 } 7422 }
7549 else 7423 else
7550 { 7424 {
7551 v11 = rand() % 4; 7425 int randVal = rand() % 4;
7552 switch (v11) 7426 switch (randVal)
7553 { 7427 {
7554 case 0 : v17 = (SoundID)105; break; 7428 case 0 : soundToPlay = (SoundID)105; break;
7555 case 1 : v17 = (SoundID)106; break; 7429 case 1 : soundToPlay = (SoundID)106; break;
7556 case 2 : v17 = (SoundID)107; break; 7430 case 2 : soundToPlay = (SoundID)107; break;
7557 case 3 : v17 = (SoundID)45; break; 7431 case 3 : soundToPlay = (SoundID)45; break;
7558 } 7432 }
7559 } 7433 }
7560 pAudioPlayer->PlaySound(v17, PID(OBJECT_Player,a4 + 80), 0, -1, 0, 0, 0, 0); 7434 pAudioPlayer->PlaySound(soundToPlay, PID(OBJECT_Player,a4 + 80), 0, -1, 0, 0, 0, 0);
7561 dmgToReceive = Actor::_43B3E0_CalcDamage(actorPtr, v74); 7435 int dmgToReceive = Actor::_43B3E0_CalcDamage(actorPtr, element);
7562 if ( actorPtr->pActorBuffs[3].uExpireTime > 0 ) 7436 if ( actorPtr->pActorBuffs[3].uExpireTime > 0 )
7563 { 7437 {
7564 v21 = actorPtr->pActorBuffs[3].uPower; 7438 __int16 spellPower = actorPtr->pActorBuffs[3].uPower;
7565 if ( v21 ) 7439 if ( spellPower )
7566 dmgToReceive /= (signed int)v21; 7440 dmgToReceive /= (signed int)spellPower;
7567 } 7441 }
7568 switch (v74) 7442 int damageType;
7569 { 7443 switch (element)
7570 case 0: v22 = actorPtr->pMonsterInfo.uAttack1Type; 7444 {
7445 case 0: damageType = actorPtr->pMonsterInfo.uAttack1Type;
7571 break; 7446 break;
7572 case 1: v22 = actorPtr->pMonsterInfo.uAttack2Type; 7447 case 1: damageType = actorPtr->pMonsterInfo.uAttack2Type;
7573 break; 7448 break;
7574 case 2: v23 = actorPtr->pMonsterInfo.uSpell1ID; 7449 case 2: spellId = actorPtr->pMonsterInfo.uSpell1ID;
7575 v22 = LOBYTE(pSpellStats->pInfos[v23].uSchool); 7450 damageType = LOBYTE(pSpellStats->pInfos[spellId].uSchool);
7576 break; 7451 break;
7577 case 3: v23 = actorPtr->pMonsterInfo.uSpell2ID; 7452 case 3: spellId = actorPtr->pMonsterInfo.uSpell2ID;
7578 v22 = LOBYTE(pSpellStats->pInfos[v23].uSchool); 7453 damageType = LOBYTE(pSpellStats->pInfos[spellId].uSchool);
7579 break; 7454 break;
7580 case 4: v22 = actorPtr->pMonsterInfo.field_3C_some_special_attack; 7455 case 4: damageType = actorPtr->pMonsterInfo.field_3C_some_special_attack;
7581 break; 7456 break;
7582 default: 7457 default:
7583 case 5: v22 = 4; //yes, the original just assigned the value 4 7458 case 5: damageType = 4; //yes, the original just assigned the value 4
7584 break; 7459 break;
7585 } 7460 }
7586 if ( !(dword_6BE368_debug_settings_2 & 0x10) ) 7461 if ( !(dword_6BE368_debug_settings_2 & 0x10) )
7587 { 7462 {
7588 v24 = playerPtr->ReceiveDamage(dmgToReceive, (DAMAGE_TYPE)v22); 7463 dmgToReceive = playerPtr->ReceiveDamage(dmgToReceive, (DAMAGE_TYPE)damageType);
7589 if ( playerPtr->pPlayerBuffs[10].uExpireTime > 0 ) 7464 if ( playerPtr->pPlayerBuffs[10].uExpireTime > 0 )
7590 { 7465 {
7591 v25 = actorPtr->uAIState; 7466 int actorState = actorPtr->uAIState;
7592 if ( v25 != Dying && v25 != Dead) 7467 if ( actorState != Dying && actorState != Dead)
7593 { 7468 {
7594 v26 = stru_50C198.CalcMagicalDamageToActor(actorPtr, v22, v24); 7469 int reflectedDamage = stru_50C198.CalcMagicalDamageToActor(actorPtr, damageType, dmgToReceive);
7595 actorPtr->sCurrentHP -= v26; 7470 actorPtr->sCurrentHP -= reflectedDamage;
7596 if ( v26 >= 0 ) 7471 if ( reflectedDamage >= 0 )
7597 { 7472 {
7598 if ( actorPtr->sCurrentHP >= 1 ) 7473 if ( actorPtr->sCurrentHP >= 1 )
7599 { 7474 {
7600 Actor::AI_Stun(uActorID, PID(OBJECT_Player,a4), 0); 7475 Actor::AI_Stun(uActorID, PID(OBJECT_Player,a4), 0); //todo extract this branch to a function once Actor::functions are changed to nonstatic actor functions
7601 Actor::AggroSurroundingPeasants(uActorID, 1); 7476 Actor::AggroSurroundingPeasants(uActorID, 1);
7602 } 7477 }
7603 else 7478 else
7604 { 7479 {
7605 if ( pMonsterStats->pInfos[actorPtr->pMonsterInfo.uID].bQuestMonster & 1 && pRenderer->pRenderD3D && pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS) 7480 if ( pMonsterStats->pInfos[actorPtr->pMonsterInfo.uID].bQuestMonster & 1 && pRenderer->pRenderD3D && pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS)
7606 { 7481 {
7607 v27 = byte_4D864C && BYTE2(pGame->uFlags) & 8 ? 10 * actorPtr->uActorRadius : actorPtr->uActorRadius; 7482 int splatRadius = byte_4D864C && BYTE2(pGame->uFlags) & 8 ? 10 * actorPtr->uActorRadius : actorPtr->uActorRadius;
7608 pDecalBuilder->AddBloodsplat(actorPtr->vPosition.x, actorPtr->vPosition.y, actorPtr->vPosition.z, 1.0, 0.0, 0.0, (float)v27, 0, 0); 7483 pDecalBuilder->AddBloodsplat(actorPtr->vPosition.x, actorPtr->vPosition.y, actorPtr->vPosition.z, 1.0, 0.0, 0.0, (float)splatRadius, 0, 0);
7609 } 7484 }
7610 Actor::Die(uActorID); 7485 Actor::Die(uActorID);
7611 Actor::ApplyFineForKillingPeasant(uActorID); 7486 Actor::ApplyFineForKillingPeasant(uActorID);
7612 Actor::AggroSurroundingPeasants(uActorID, 1); 7487 Actor::AggroSurroundingPeasants(uActorID, 1);
7613 if ( actorPtr->pMonsterInfo.uExp ) 7488 if ( actorPtr->pMonsterInfo.uExp )
7614 GivePartyExp(pMonsterStats->pInfos[actorPtr->pMonsterInfo.uID].uExp); 7489 GivePartyExp(pMonsterStats->pInfos[actorPtr->pMonsterInfo.uID].uExp);
7615 v34 = SPEECH_51; 7490 int speechToPlay = SPEECH_51;
7616 if ( rand() % 100 < 20 ) 7491 if ( rand() % 100 < 20 )
7617 v34 = ((signed int)actorPtr->pMonsterInfo.uHP >= 100) + 1; 7492 speechToPlay = actorPtr->pMonsterInfo.uHP >= 100 ? 2 : 1;
7618 playerPtr->PlaySound((PlayerSpeech)v34, 0); 7493 playerPtr->PlaySound((PlayerSpeech)speechToPlay, 0);
7619 } 7494 }
7620 } 7495 }
7621 } 7496 }
7622 } 7497 }
7623 if ( !(dword_6BE368_debug_settings_2 & 0x10) 7498 if ( !(dword_6BE368_debug_settings_2 & 0x10)
7624 && actorPtr->pMonsterInfo.uSpecialAttack 7499 && actorPtr->pMonsterInfo.uSpecialAttackType
7625 && rand() % 100 < actorPtr->pMonsterInfo.uLevel * actorPtr->pMonsterInfo.uSpecialAttackType ) 7500 && rand() % 100 < actorPtr->pMonsterInfo.uLevel * actorPtr->pMonsterInfo.uSpecialAttackLevel )
7626 { 7501 {
7627 playerPtr->_48DCF6(actorPtr->pMonsterInfo.uSpecialAttack, actorPtr); 7502 playerPtr->ReceiveSpecialAttackEffect(actorPtr->pMonsterInfo.uSpecialAttackType, actorPtr);
7628 } 7503 }
7629 } 7504 }
7630 if ( !pParty->bTurnBasedModeOn ) 7505 if ( !pParty->bTurnBasedModeOn )
7631 { 7506 {
7632 v35 = playerPtr->GetActualEndurance(); 7507 int actEndurance = playerPtr->GetActualEndurance();
7633 v36 = (int)((20 - playerPtr->GetParameterBonus(v35)) * flt_6BE3A4_debug_recmod1 * 2.133333333333333); 7508 int recoveryTime = (int)((20 - playerPtr->GetParameterBonus(actEndurance)) * flt_6BE3A4_debug_recmod1 * 2.133333333333333);
7634 playerPtr->SetRecoveryTime(v36); 7509 playerPtr->SetRecoveryTime(recoveryTime);
7635 } 7510 }
7636 int yellThreshold = playerPtr->GetMaxHealth() / 4; 7511 int yellThreshold = playerPtr->GetMaxHealth() / 4;
7637 if ( yellThreshold < playerPtr->sHealth && yellThreshold >= healthBeforeRecvdDamage && playerPtr->sHealth > 0 ) 7512 if ( yellThreshold < playerPtr->sHealth && yellThreshold >= healthBeforeRecvdDamage && playerPtr->sHealth > 0 )
7638 { 7513 {
7639 playerPtr->PlaySound(SPEECH_48, 0); 7514 playerPtr->PlaySound(SPEECH_48, 0);
7641 viewparams->bRedrawGameUI = 1; 7516 viewparams->bRedrawGameUI = 1;
7642 return; 7517 return;
7643 } 7518 }
7644 else 7519 else
7645 { 7520 {
7646 v37 = &pSpriteObjects[uActorID]; 7521 SpriteObject* v37 = &pSpriteObjects[uActorID];
7647 v38 = PID_TYPE(v37->spell_caster_pid); 7522 int uActorType = PID_TYPE(v37->spell_caster_pid);
7648 v39 = PID_ID(v37->spell_caster_pid); 7523 int uActorID = PID_ID(v37->spell_caster_pid);
7649 v40 = PID_TYPE(v37->spell_caster_pid); 7524 if ( uActorType == 2 )
7650 uActorID = PID_ID(v37->spell_caster_pid); 7525 {
7651 v41 = v40 - 2; 7526 Player *playerPtr; // eax@81
7652 if ( v40 == 2 )
7653 {
7654 if ( a4 != -1 ) 7527 if ( a4 != -1 )
7655 { 7528 {
7656 v43 = &pParty->pPlayers[a4]; 7529 playerPtr = &pParty->pPlayers[a4];
7657 } 7530 }
7658 else 7531 else
7659 { 7532 {
7660 v74 = 0; 7533 element = 0;
7661 for (int i = 1; i <= 4; i++) 7534 for (int i = 1; i <= 4; i++)
7662 { 7535 {
7663 v72[v74] = i; 7536 v72[element] = i;
7664 v74++; 7537 element++;
7665 } 7538 }
7666 if ( v74 ) 7539 if ( element )
7667 { 7540 {
7668 v43 = &pParty->pPlayers[v72[rand() % v74]];//&stru_AA1058[3].pSounds[6972 * *(&v72 + rand() % v74) + 40552]; 7541 playerPtr = &pParty->pPlayers[v72[rand() % element]];//&stru_AA1058[3].pSounds[6972 * *(&v72 + rand() % v74) + 40552];
7669 } 7542 }
7670 } 7543 }
7671 if ( v38 != OBJECT_Player || v37->spell_id != SPELL_BOW_ARROW) 7544 int v68;
7672 { 7545 int v69;
7673 v70 = v43->GetMaxHealth(); 7546 if ( uActorType != OBJECT_Player || v37->spell_id != SPELL_BOW_ARROW)
7674 v68 = _43AFE3_calc_spell_damage(v37->spell_id, v37->spell_level, v37->spell_skill, v70); 7547 {
7548 int playerMaxHp = playerPtr->GetMaxHealth();
7549 v68 = _43AFE3_calc_spell_damage(v37->spell_id, v37->spell_level, v37->spell_skill, playerMaxHp);
7675 v69 = LOBYTE(pSpellStats->pInfos[v37->spell_id].uSchool); 7550 v69 = LOBYTE(pSpellStats->pInfos[v37->spell_id].uSchool);
7676 } 7551 }
7677 else 7552 else
7678 { 7553 {
7679 v68 = pParty->pPlayers[uActorID].CalculateRangedDamageTo(0); 7554 v68 = pParty->pPlayers[uActorID].CalculateRangedDamageTo(0);
7680 v69 = 0; 7555 v69 = 0;
7681 } 7556 }
7682 v43->ReceiveDamage(v68, (DAMAGE_TYPE)v69); 7557 playerPtr->ReceiveDamage(v68, (DAMAGE_TYPE)v69);
7683 if ( v38 == OBJECT_Player && !qword_A750D8 ) 7558 if ( uActorType == OBJECT_Player && !qword_A750D8 )
7684 { 7559 {
7685 qword_A750D8 = 256i64; 7560 qword_A750D8 = 256i64;
7686 PlayerSpeechID = SPEECH_44; 7561 PlayerSpeechID = SPEECH_44;
7687 uSpeakingCharacter = uActorID + 1; 7562 uSpeakingCharacter = uActorID + 1;
7688 } 7563 }
7689 return; 7564 return;
7690 } 7565 }
7691 else if ( v40 == 3 ) 7566 else if ( uActorType == 3 )
7692 { 7567 {
7693 actorPtr = &pActors[v39]; 7568 Actor *actorPtr = &pActors[uActorID];
7694 if ( a4 == -1 ) 7569 if ( a4 == -1 )
7695 a4 = stru_50C198.which_player_would_attack(actorPtr); 7570 a4 = stru_50C198.which_player_would_attack(actorPtr);
7696 v45 = &pParty->pPlayers[a4]; 7571 Player *playerPtr = &pParty->pPlayers[a4];
7697 dmgToReceive = Actor::_43B3E0_CalcDamage(actorPtr, v74); 7572 int dmgToReceive = Actor::_43B3E0_CalcDamage(actorPtr, element);
7698 v46 = v37->uType; 7573 unsigned __int16 spriteType = v37->uType;
7699 if ( v37->uType == 545 ) 7574 if ( v37->uType == 545 )
7700 { 7575 {
7701 v51 = v45->GetActualSkillLevel(PLAYER_SKILL_UNARMED); 7576 __int16 skillLevel = playerPtr->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
7702 if ( SkillToMastery(v51) >= 4 && rand() % 100 < (v51 & 0x3F) ) 7577 if ( SkillToMastery(skillLevel) >= 4 && rand() % 100 < (skillLevel & 0x3F) )
7703 { 7578 {
7704 sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[637], v45->pName); 7579 sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[637], playerPtr->pName);
7705 ShowStatusBarString(pTmpBuf.data(), 2u); 7580 ShowStatusBarString(pTmpBuf.data(), 2u);
7706 v45->PlaySound(SPEECH_6, 0); 7581 playerPtr->PlaySound(SPEECH_6, 0);
7707 return; 7582 return;
7708 } 7583 }
7709 } 7584 }
7710 else if ( v46 == 555 7585 else if ( spriteType == 555
7711 || v46 == 510 7586 || spriteType == 510
7712 || v46 == 500 7587 || spriteType == 500
7713 || v46 == 515 7588 || spriteType == 515
7714 || v46 == 505 7589 || spriteType == 505
7715 || v46 == 530 7590 || spriteType == 530
7716 || v46 == 525 7591 || spriteType == 525
7717 || v46 == 520 7592 || spriteType == 520
7718 || v46 == 535 7593 || spriteType == 535
7719 || v46 == 540 ) 7594 || spriteType == 540 )
7720 { 7595 {
7721 if ( !stru_50C198.ActorHitOrMiss(actorPtr, v45) ) 7596 if ( !stru_50C198.ActorHitOrMiss(actorPtr, playerPtr) )
7722 return; 7597 return;
7723 if ( (signed __int64)v45->pPlayerBuffs[13].uExpireTime > 0 ) 7598 if ( playerPtr->pPlayerBuffs[13].uExpireTime > 0 )
7724 dmgToReceive >>= 1; 7599 dmgToReceive >>= 1;
7725 if ( v45->HasEnchantedItemEquipped(36) ) 7600 if ( playerPtr->HasEnchantedItemEquipped(36) )
7726 dmgToReceive >>= 1; 7601 dmgToReceive >>= 1;
7727 if ( v45->HasEnchantedItemEquipped(69) ) 7602 if ( playerPtr->HasEnchantedItemEquipped(69) )
7728 dmgToReceive >>= 1; 7603 dmgToReceive >>= 1;
7729 if ( v45->HasItemEquipped(EQUIP_ARMOUR) 7604 if ( playerPtr->HasItemEquipped(EQUIP_ARMOUR)
7730 && v45->pInventoryItemList[v45->pEquipment.uArmor-1].uItemID == ITEM_ARTIFACT_GOVERNORS_ARMOR ) 7605 && playerPtr->pInventoryItemList[playerPtr->pEquipment.uArmor-1].uItemID == ITEM_ARTIFACT_GOVERNORS_ARMOR )
7731 dmgToReceive >>= 1; 7606 dmgToReceive >>= 1;
7732 if ( v45->HasItemEquipped(EQUIP_MAIN_HAND)) 7607 if ( playerPtr->HasItemEquipped(EQUIP_MAIN_HAND))
7733 { 7608 {
7734 v48 = v45->pInventoryItemList[v45->pEquipment.uMainHand - 1].uItemID; 7609 int itemId = playerPtr->pInventoryItemList[playerPtr->pEquipment.uMainHand - 1].uItemID;
7735 if ( v48 == ITEM_RELIC_KELEBRIM || v48 == ITEM_ARTIFACT_ELFBANE || (v45->GetEquippedItemEquipType(EQUIP_MAIN_HAND) == EQUIP_SHIELD && SkillToMastery(v45->pActiveSkills[PLAYER_SKILL_SHIELD]) == 4)) 7610 if ( itemId == ITEM_RELIC_KELEBRIM || itemId == ITEM_ARTIFACT_ELFBANE || (playerPtr->GetEquippedItemEquipType(EQUIP_MAIN_HAND) == EQUIP_SHIELD && SkillToMastery(playerPtr->pActiveSkills[PLAYER_SKILL_SHIELD]) == 4))
7736 dmgToReceive >>= 1; 7611 dmgToReceive >>= 1;
7737 } 7612 }
7738 if ( v45->HasItemEquipped(EQUIP_OFF_HAND)) 7613 if ( playerPtr->HasItemEquipped(EQUIP_OFF_HAND))
7739 { 7614 {
7740 v48 = v45->pInventoryItemList[v45->pEquipment.uShield - 1].uItemID; 7615 int itemId = playerPtr->pInventoryItemList[playerPtr->pEquipment.uShield - 1].uItemID;
7741 if ( v48 == ITEM_RELIC_KELEBRIM || v48 == ITEM_ARTIFACT_ELFBANE || (v45->GetEquippedItemEquipType(EQUIP_OFF_HAND) == EQUIP_SHIELD && SkillToMastery(v45->pActiveSkills[PLAYER_SKILL_SHIELD]) == 4)) 7616 if ( itemId == ITEM_RELIC_KELEBRIM || itemId == ITEM_ARTIFACT_ELFBANE || (playerPtr->GetEquippedItemEquipType(EQUIP_OFF_HAND) == EQUIP_SHIELD && SkillToMastery(playerPtr->pActiveSkills[PLAYER_SKILL_SHIELD]) == 4))
7742 dmgToReceive >>= 1; 7617 dmgToReceive >>= 1;
7743 } 7618 }
7744 } 7619 }
7745 if ( actorPtr->pActorBuffs[3].uExpireTime > 0 ) 7620 if ( actorPtr->pActorBuffs[3].uExpireTime > 0 )
7746 { 7621 {
7747 v49 = actorPtr->pActorBuffs[3].uPower; 7622 int spellPower = actorPtr->pActorBuffs[3].uPower;
7748 if ( v49 ) 7623 if ( spellPower )
7749 dmgToReceive /= (signed int)v49; 7624 dmgToReceive /= (signed int)spellPower;
7750 } 7625 }
7751 switch(v74) 7626 int damageType;
7627 switch(element)
7752 { 7628 {
7753 case 0: 7629 case 0:
7754 v50 = actorPtr->pMonsterInfo.uAttack1Type; 7630 damageType = actorPtr->pMonsterInfo.uAttack1Type;
7755 break; 7631 break;
7756 case 1: 7632 case 1:
7757 v50 = actorPtr->pMonsterInfo.uAttack2Type; 7633 damageType = actorPtr->pMonsterInfo.uAttack2Type;
7758 break; 7634 break;
7759 case 2: 7635 case 2:
7760 v53 = actorPtr->pMonsterInfo.uSpell1ID; 7636 spellId = actorPtr->pMonsterInfo.uSpell1ID;
7761 v50 = LOBYTE(pSpellStats->pInfos[v53].uSchool); 7637 damageType = LOBYTE(pSpellStats->pInfos[spellId].uSchool);
7762 break; 7638 break;
7763 case 3: 7639 case 3:
7764 v53 = actorPtr->pMonsterInfo.uSpell2ID; 7640 spellId = actorPtr->pMonsterInfo.uSpell2ID;
7765 v50 = LOBYTE(pSpellStats->pInfos[v53].uSchool); 7641 damageType = LOBYTE(pSpellStats->pInfos[spellId].uSchool);
7766 break; 7642 break;
7767 case 4: 7643 case 4:
7768 v50 = actorPtr->pMonsterInfo.field_3C_some_special_attack; 7644 damageType = actorPtr->pMonsterInfo.field_3C_some_special_attack;
7769 break; 7645 break;
7770 case 5: 7646 case 5:
7771 v50 = 4; 7647 damageType = 4;
7772 break; 7648 break;
7773 } 7649 }
7774 if ( !(dword_6BE368_debug_settings_2 & 0x10) ) 7650 if ( !(dword_6BE368_debug_settings_2 & 0x10) )
7775 { 7651 {
7776 v54 = v45->ReceiveDamage(dmgToReceive, (DAMAGE_TYPE)v50); 7652 int reflectedDmg = playerPtr->ReceiveDamage(dmgToReceive, (DAMAGE_TYPE)damageType);
7777 if ( v45->pPlayerBuffs[10].uExpireTime > 0 ) 7653 if ( playerPtr->pPlayerBuffs[10].uExpireTime > 0 )
7778 { 7654 {
7779 v55 = actorPtr->uAIState; 7655 unsigned __int16 actorState = actorPtr->uAIState;
7780 if ( v55 != Dying && v55 != Dead) 7656 if ( actorState != Dying && actorState != Dead)
7781 { 7657 {
7782 recvdMagicDmg = stru_50C198.CalcMagicalDamageToActor(actorPtr, v50, v54); 7658 recvdMagicDmg = stru_50C198.CalcMagicalDamageToActor(actorPtr, damageType, reflectedDmg);
7783 actorPtr->sCurrentHP -= recvdMagicDmg; 7659 actorPtr->sCurrentHP -= recvdMagicDmg;
7784 if ( recvdMagicDmg >= 0 ) 7660 if ( recvdMagicDmg >= 0 )
7785 { 7661 {
7786 if ( actorPtr->sCurrentHP >= 1 ) 7662 if ( actorPtr->sCurrentHP >= 1 )
7787 { 7663 {
7790 } 7666 }
7791 else 7667 else
7792 { 7668 {
7793 if ( pMonsterStats->pInfos[actorPtr->pMonsterInfo.uID].bQuestMonster & 1 && pRenderer->pRenderD3D && pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS ) 7669 if ( pMonsterStats->pInfos[actorPtr->pMonsterInfo.uID].bQuestMonster & 1 && pRenderer->pRenderD3D && pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS )
7794 { 7670 {
7795 v57 = byte_4D864C && BYTE2(pGame->uFlags) & 8 ? 10 * actorPtr->uActorRadius : actorPtr->uActorRadius; 7671 int splatRadius = byte_4D864C && BYTE2(pGame->uFlags) & 8 ? 10 * actorPtr->uActorRadius : actorPtr->uActorRadius;
7796 pDecalBuilder->AddBloodsplat(actorPtr->vPosition.x, actorPtr->vPosition.y, actorPtr->vPosition.z, 1.0, 0.0, 0.0, (float)v57, 0, 0); 7672 pDecalBuilder->AddBloodsplat(actorPtr->vPosition.x, actorPtr->vPosition.y, actorPtr->vPosition.z, 1.0, 0.0, 0.0, (float)splatRadius, 0, 0);
7797 } 7673 }
7798 Actor::Die(uActorID); 7674 Actor::Die(uActorID);
7799 Actor::ApplyFineForKillingPeasant(uActorID); 7675 Actor::ApplyFineForKillingPeasant(uActorID);
7800 Actor::AggroSurroundingPeasants(uActorID, 1); 7676 Actor::AggroSurroundingPeasants(uActorID, 1);
7801 if ( actorPtr->pMonsterInfo.uExp ) 7677 if ( actorPtr->pMonsterInfo.uExp )
7802 GivePartyExp(pMonsterStats->pInfos[actorPtr->pMonsterInfo.uID].uExp); 7678 GivePartyExp(pMonsterStats->pInfos[actorPtr->pMonsterInfo.uID].uExp);
7803 v64 = SPEECH_51; 7679 int speechToPlay = SPEECH_51;
7804 if ( rand() % 100 < 20 ) 7680 if ( rand() % 100 < 20 )
7805 v64 = ((signed int)actorPtr->pMonsterInfo.uHP >= 100) + 1; 7681 speechToPlay = actorPtr->pMonsterInfo.uHP >= 100 ? 2 : 1;
7806 v45->PlaySound((PlayerSpeech)v64, 0); 7682 playerPtr->PlaySound((PlayerSpeech)speechToPlay, 0);
7807 } 7683 }
7808 } 7684 }
7809 } 7685 }
7810 } 7686 }
7811 } 7687 }
7812 if ( !v74 7688 if ( !element
7813 && !(dword_6BE368_debug_settings_2 & 0x10) 7689 && !(dword_6BE368_debug_settings_2 & 0x10)
7814 && actorPtr->pMonsterInfo.uSpecialAttack 7690 && actorPtr->pMonsterInfo.uSpecialAttackType
7815 && rand() % 100 < actorPtr->pMonsterInfo.uLevel * actorPtr->pMonsterInfo.uSpecialAttackType ) 7691 && rand() % 100 < actorPtr->pMonsterInfo.uLevel * actorPtr->pMonsterInfo.uSpecialAttackLevel )
7816 { 7692 {
7817 v45->_48DCF6(actorPtr->pMonsterInfo.uSpecialAttack, actorPtr); 7693 playerPtr->ReceiveSpecialAttackEffect(actorPtr->pMonsterInfo.uSpecialAttackType, actorPtr);
7818 } 7694 }
7819 if ( !pParty->bTurnBasedModeOn ) 7695 if ( !pParty->bTurnBasedModeOn )
7820 { 7696 {
7821 v65 = v45->GetActualEndurance(); 7697 int actEnd = playerPtr->GetActualEndurance();
7822 v66 = (int)((20 - v45->GetParameterBonus(v65)) 7698 int recTime = (int)((20 - playerPtr->GetParameterBonus(actEnd))
7823 * flt_6BE3A4_debug_recmod1 7699 * flt_6BE3A4_debug_recmod1
7824 * 2.133333333333333); 7700 * 2.133333333333333);
7825 v45->SetRecoveryTime(v66); 7701 playerPtr->SetRecoveryTime(recTime);
7826 } 7702 }
7827 return; 7703 return;
7828 } 7704 }
7829 else 7705 else
7830 { 7706 {
7831 return; 7707 return;
7832 } 7708 }
7833 } 7709 }
7834 } 7710 }
7835 //----- (00421EA6) -------------------------------------------------------- 7711 //----- (00421EA6) --------------------------------------------------------
7836 void OnInventoryLeftClick() 7712 void Player::OnInventoryLeftClick()
7837 { 7713 {
7838 Player *v0; // ebx@1
7839 signed int v1; // eax@2
7840 signed int v2; // ecx@2 7714 signed int v2; // ecx@2
7841 int v3; // eax@2 7715 int v3; // eax@2
7842 char v4; // sf@2 7716 int invMatrixIndex; // eax@2
7843 int v5; // eax@2
7844 unsigned int v6; // eax@7 7717 unsigned int v6; // eax@7
7845 unsigned int v7; // esi@12 7718 unsigned int pickedItemId; // esi@12
7846 unsigned int v8; // eax@12 7719 unsigned int invItemIndex; // eax@12
7847 unsigned int v9; // eax@16 7720 unsigned int v9; // eax@16
7848 unsigned int v10; // eax@18 7721 unsigned int v10; // eax@18
7849 ItemGen this_; // [sp+Ch] [bp-3Ch]@1 7722 ItemGen tmpItem; // [sp+Ch] [bp-3Ch]@1
7850 POINT a2; // [sp+30h] [bp-18h]@4 7723 POINT a2; // [sp+30h] [bp-18h]@4
7851 unsigned int v13; // [sp+38h] [bp-10h]@13
7852 unsigned int pY; // [sp+3Ch] [bp-Ch]@2 7724 unsigned int pY; // [sp+3Ch] [bp-Ch]@2
7853 unsigned int pX; // [sp+40h] [bp-8h]@2 7725 unsigned int pX; // [sp+40h] [bp-8h]@2
7854 int a4; // [sp+44h] [bp-4h]@2 7726
7855
7856 v0 = pPlayers[uActiveCharacter];
7857 if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 103 ) 7727 if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 103 )
7858 { 7728 {
7859 pMouse->GetClickPos(&pX, &pY); 7729 pMouse->GetClickPos(&pX, &pY);
7860 pY = pY - 17; 7730 v3 = Player::INVETORYSLOTSWIDTH * ((pY - 17) / 32);
7861 v2 =pX - 14; 7731 v2 = (pX - 14) / 32;
7862 pX = v2; 7732 invMatrixIndex = v2 + v3;
7863 v3 = 14 * (pY >> 5); 7733 if ( v2 + v3 >= 0 )
7864 v2 >>= 5; 7734 {
7865 v4 = v2 + v3 < 0; 7735 if ( invMatrixIndex <= 126 && pMouse->GetCursorPos(&a2)->x < 462
7866 v5 = v2 + v3;
7867 a4 = v5;
7868 if ( !v4 )
7869 {
7870 if ( v5 <= 126 && pMouse->GetCursorPos(&a2)->x < 462
7871 && pMouse->GetCursorPos(&a2)->x >= 14 ) 7736 && pMouse->GetCursorPos(&a2)->x >= 14 )
7872 { 7737 {
7873 if ( unk_50C9A0 ) 7738 if ( _50C9A0_IsEnchantingInProgress )
7874 { 7739 {
7875 v6 = v0->GetItemIDAtInventoryIndex(&a4); 7740 v6 = this->GetItemIDAtInventoryIndex(&invMatrixIndex);
7876 if ( v6 ) 7741 if ( v6 )
7877 { 7742 {
7878 *((char *)pGUIWindow_Settings->ptr_1C + 8) &= 0x7Fu; 7743 *((char *)pGUIWindow_Settings->ptr_1C + 8) &= 0x7Fu;
7879 *((short *)pGUIWindow_Settings->ptr_1C + 2) = uActiveCharacter - 1; 7744 *((short *)pGUIWindow_Settings->ptr_1C + 2) = uActiveCharacter - 1;
7880 *((int *)pGUIWindow_Settings->ptr_1C + 3) = v6 - 1; 7745 *((int *)pGUIWindow_Settings->ptr_1C + 3) = v6 - 1;
7881 *((short *)pGUIWindow_Settings->ptr_1C + 3) = a4; 7746 *((short *)pGUIWindow_Settings->ptr_1C + 3) = invMatrixIndex;
7882 ptr_50C9A4 = (ItemGen *)&v0->pInventoryItemList[v6-1]; 7747 ptr_50C9A4_ItemToEnchant = &this->pInventoryItemList[v6-1];
7883 unk_50C9A0 = 0; 7748 _50C9A0_IsEnchantingInProgress = 0;
7884 if ( pMessageQueue_50CBD0->uNumMessages ) 7749 if ( pMessageQueue_50CBD0->uNumMessages )
7885 pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0; 7750 pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
7886 pMouse->SetCursorBitmap("MICON1"); 7751 pMouse->SetCursorBitmap("MICON1");
7887 dword_50C9D0 = 113; 7752 _50C9D0_AfterEnchClickEventId = 113;
7888 dword_50C9D4 = 0; 7753 _50C9D4_AfterEnchClickEventSecondParam = 0;
7889 dword_50C9D8 = 256; 7754 _50C9D8_AfterEnchClickEventTimeout = 256;
7890 } 7755 }
7891 return; 7756 return;
7892 } 7757 }
7893 if ( ptr_50C9A4 ) 7758 if ( ptr_50C9A4_ItemToEnchant )
7894 return; 7759 return;
7895 v7 = pParty->pPickedItem.uItemID; 7760 pickedItemId = pParty->pPickedItem.uItemID;
7896 v8 = v0->GetItemIDAtInventoryIndex(&a4); 7761 invItemIndex = this->GetItemIDAtInventoryIndex(&invMatrixIndex);
7897 if ( !v7 ) 7762 if (!pickedItemId)
7898 { 7763 {
7899 if ( !v8 ) 7764 if ( !invItemIndex )
7900 return; 7765 return;
7901 memcpy(&pParty->pPickedItem, &v0->pInventoryItemList[v8-1], sizeof(pParty->pPickedItem)); 7766 else
7902 v0->RemoveItemAtInventoryIndex(a4); 7767 {
7903 v9 = pParty->pPickedItem.uItemID; 7768 memcpy(&pParty->pPickedItem, &this->pInventoryItemList[invItemIndex-1], sizeof(pParty->pPickedItem));
7904 pMouse->SetCursorBitmap(pItemsTable->pItems[v9].pIconName); 7769 this->RemoveItemAtInventoryIndex(invMatrixIndex);
7905 return; 7770 v9 = pParty->pPickedItem.uItemID;
7771 pMouse->SetCursorBitmap(pItemsTable->pItems[v9].pIconName);
7772 return;
7773 }
7906 } 7774 }
7907 v13 = v8; 7775 else
7908 if ( v8 )
7909 { 7776 {
7910 a2.y = (LONG)&v0->pInventoryItemList[v8-1]; 7777 if ( invItemIndex )
7911 memcpy(&this_, (const void *)a2.y, sizeof(this_));
7912 v0->RemoveItemAtInventoryIndex(a4);
7913 pX = v0->AddItem2(a4, &pParty->pPickedItem);
7914 if ( !pX )
7915 { 7778 {
7916 pX = v0->AddItem2(0xFFFFFFFFu, &pParty->pPickedItem); 7779 ItemGen* invItemPtr = &this->pInventoryItemList[invItemIndex-1];
7917 if ( !pX ) 7780 memcpy(&tmpItem, invItemPtr, sizeof(tmpItem));
7781 this->RemoveItemAtInventoryIndex(invMatrixIndex);
7782 int emptyIndex = this->AddItem2(invMatrixIndex, &pParty->pPickedItem);
7783 if ( !emptyIndex )
7918 { 7784 {
7919 v0->PutItemArInventoryIndex(this_.uItemID, v13 - 1, a4); 7785 emptyIndex = this->AddItem2(-1, &pParty->pPickedItem);
7920 memcpy((void *)a2.y, &this_, sizeof(ItemGen)); 7786 if ( !emptyIndex )
7787 {
7788 this->PutItemArInventoryIndex(tmpItem.uItemID, invItemIndex - 1, invMatrixIndex);
7789 memcpy(invItemPtr, &tmpItem, sizeof(ItemGen));
7790 return;
7791 }
7792 }
7793 v9 = tmpItem.uItemID;
7794 memcpy(&pParty->pPickedItem, &tmpItem, sizeof(ItemGen));
7795 pMouse->SetCursorBitmap(pItemsTable->pItems[pParty->pPickedItem.uItemID].pIconName);
7796 return;
7797 }
7798 else
7799 {
7800 v10 = this->AddItem(invMatrixIndex, pickedItemId);
7801 if ( v10 )
7802 {
7803 memcpy(&this->pInventoryItemList[v10-1], &pParty->pPickedItem, sizeof(ItemGen));
7804 pMouse->RemoveHoldingItem();
7805 return;
7806 }
7807 v10 = this->AddItem(-1, pickedItemId);
7808 if ( v10 )
7809 {
7810 memcpy(&this->pInventoryItemList[v10-1], &pParty->pPickedItem, sizeof(ItemGen));
7811 pMouse->RemoveHoldingItem();
7921 return; 7812 return;
7922 } 7813 }
7923 } 7814 }
7924 v9 = this_.uItemID;
7925 memcpy(&pParty->pPickedItem, &this_, sizeof(pParty->pPickedItem));
7926 pMouse->SetCursorBitmap(pItemsTable->pItems[v9].pIconName);
7927 return;
7928 } 7815 }
7929 v10 = v0->AddItem(a4, v7);
7930 pX = v10;
7931 if ( v10 || (v10 = v0->AddItem(-1, pParty->pPickedItem.uItemID), (pX = v10) != 0) )
7932 {
7933 memcpy(&v0->pInventoryItemList[v10-1], &pParty->pPickedItem, 0x24u);
7934 pMouse->RemoveHoldingItem();
7935 }
7936 } 7816 }
7937 } 7817 }
7938 } 7818 }
7939 } 7819 }
7940 7820
7982 bool Player::IsParalyzed() 7862 bool Player::IsParalyzed()
7983 { 7863 {
7984 return pConditions[Condition_Paralyzed] != 0; 7864 return pConditions[Condition_Paralyzed] != 0;
7985 } 7865 }
7986 7866
7867 bool Player::IsDrunk()
7868 {
7869 return pConditions[Condition_Drunk] != 0;
7870 }
7871
7987 void Player::SetCursed( bool state ) 7872 void Player::SetCursed( bool state )
7988 { 7873 {
7989 pConditions[Condition_Cursed] = state; 7874 pConditions[Condition_Cursed] = state;
7990 } 7875 }
7991 7876