fix(loot): activity reward coins use the reward's ChallengeRating level

ActivityRewards coins were always read from CurrencyTable npcminlevel 1.
Live used the reward row's ChallengeRating as the npcminlevel, and level 1
when the currency index has no row for that level:
- FV foot races (ChallengeRating 4, index 1) gave 36 and 48 coins, which
  only level 4 (30-50) fits; level 1 is 3-5.
- Frakjaw's chest (activity 58, ChallengeRating 6) gave 250 each to a team
  of 2: its currency indices 123-126 only have a level 6 row (500), so DLU
  gave nothing.
- Quickbuilds, wishing wells and chests have ChallengeRating 1; survival
  and the shooting galleries have ratings with no row and keep level 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 12:51:41 -05:00
parent 5092327153
commit 616ca46e95
5 changed files with 79 additions and 31 deletions

View File

@@ -2,9 +2,14 @@
#include "dCommonVars.h"
#include "eLootSourceType.h"
#include <map>
#include <unordered_map>
#include <utility>
#include <vector>
class Entity;
struct CDActivityRewards;
struct CDCurrencyTable;
namespace GameMessages {
struct DropClientLoot;
@@ -28,6 +33,14 @@ namespace Loot {
void DropItem(Entity& player, GameMessages::DropClientLoot& lootMsg, bool useTeam = false, bool forceFfa = false);
void DropActivityLoot(Entity* player, const LWOOBJID source, uint32_t activityID, int32_t rating = 0);
/**
* The coin range {min, max} of an ActivityRewards row, as live rolled it: the reward's ChallengeRating is the
* CurrencyTable npcminlevel, and level 1 is used when the currency index has no row for that level.
* currencyRows are the CurrencyTable rows of the reward's CurrencyIndex. {0, 0} when neither level has a row.
*/
std::pair<uint32_t, uint32_t> GetActivityCoinRange(const std::vector<CDCurrencyTable>& currencyRows, uint32_t challengeRating);
std::pair<uint32_t, uint32_t> GetActivityCoinRange(const CDActivityRewards& reward);
// How far from where it spawns a dropped item lands, as live dropped them (median 10.0 units, uniform direction).
constexpr float ITEM_DROP_DISTANCE = 10.0f;