|
|
|
|
@ -2247,6 +2247,11 @@ void OperatePedestal(Player &player, Object &pedestal, bool sendmsg)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int ClampU8(int v) |
|
|
|
|
{ |
|
|
|
|
return std::clamp(v, 0, 255); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void OperateShrineMysterious(DiabloGenerator &rng, Player &player) |
|
|
|
|
{ |
|
|
|
|
if (&player != MyPlayer) |
|
|
|
|
@ -2284,43 +2289,32 @@ void OperateShrineHidden(DiabloGenerator &rng, Player &player)
|
|
|
|
|
if (&player != MyPlayer) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
int cnt = 0; |
|
|
|
|
for (const auto &item : player.InvBody) { |
|
|
|
|
if (!item.isEmpty()) |
|
|
|
|
cnt++; |
|
|
|
|
std::array<int, NUM_INVLOC> eligible {}; |
|
|
|
|
int eligibleCount = 0; |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < NUM_INVLOC; i++) { |
|
|
|
|
const Item &it = player.InvBody[i]; |
|
|
|
|
if (!it.isEmpty() && IsNoneOf(it._iMaxDur, 0, DUR_INDESTRUCTIBLE)) |
|
|
|
|
eligible[eligibleCount++] = i; |
|
|
|
|
} |
|
|
|
|
if (cnt > 0) { |
|
|
|
|
for (auto &item : player.InvBody) { |
|
|
|
|
if (!item.isEmpty() |
|
|
|
|
&& item._iMaxDur != DUR_INDESTRUCTIBLE |
|
|
|
|
&& item._iMaxDur != 0) { |
|
|
|
|
item._iDurability += 10; |
|
|
|
|
item._iMaxDur += 10; |
|
|
|
|
if (item._iDurability > item._iMaxDur) |
|
|
|
|
item._iDurability = item._iMaxDur; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
while (true) { |
|
|
|
|
cnt = 0; |
|
|
|
|
for (auto &item : player.InvBody) { |
|
|
|
|
if (!item.isEmpty() && item._iMaxDur != DUR_INDESTRUCTIBLE && item._iMaxDur != 0) { |
|
|
|
|
cnt++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (cnt == 0) |
|
|
|
|
break; |
|
|
|
|
const int r = rng.generateRnd(NUM_INVLOC); |
|
|
|
|
if (player.InvBody[r].isEmpty() || player.InvBody[r]._iMaxDur == DUR_INDESTRUCTIBLE || player.InvBody[r]._iMaxDur == 0) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
player.InvBody[r]._iDurability -= 20; |
|
|
|
|
player.InvBody[r]._iMaxDur -= 20; |
|
|
|
|
if (player.InvBody[r]._iDurability <= 0) |
|
|
|
|
player.InvBody[r]._iDurability = 1; |
|
|
|
|
if (player.InvBody[r]._iMaxDur <= 0) |
|
|
|
|
player.InvBody[r]._iMaxDur = 1; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if (eligibleCount == 0) { |
|
|
|
|
InitDiabloMsg(EMSG_SHRINE_HIDDEN); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Pick the one item that will receive the net -10 effect.
|
|
|
|
|
const int cursedSlot = eligible[rng.generateRnd(eligibleCount)]; |
|
|
|
|
|
|
|
|
|
for (int k = 0; k < eligibleCount; k++) { |
|
|
|
|
Item &it = player.InvBody[eligible[k]]; |
|
|
|
|
const int delta = (eligible[k] == cursedSlot) ? -10 : 10; |
|
|
|
|
it._iMaxDur = ClampU8(it._iMaxDur + delta); |
|
|
|
|
if (it._iMaxDur == 0) |
|
|
|
|
it._iMaxDur = 1; |
|
|
|
|
it._iDurability = ClampU8(it._iDurability + delta); |
|
|
|
|
if (it._iDurability == 0) |
|
|
|
|
it._iDurability = 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
InitDiabloMsg(EMSG_SHRINE_HIDDEN); |
|
|
|
|
|