mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-11 15:23:43 +00:00
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>
57 lines
2.5 KiB
C++
57 lines
2.5 KiB
C++
#pragma once
|
|
|
|
#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;
|
|
};
|
|
|
|
namespace Loot {
|
|
struct Info {
|
|
LWOOBJID id = 0;
|
|
LOT lot = 0;
|
|
int32_t count = 0;
|
|
};
|
|
|
|
using Return = std::map<LOT, int32_t>;
|
|
|
|
Loot::Return RollLootMatrix(Entity* player, uint32_t matrixIndex);
|
|
void CacheMatrix(const uint32_t matrixIndex);
|
|
void GiveLoot(Entity* player, uint32_t matrixIndex, eLootSourceType lootSourceType = eLootSourceType::NONE);
|
|
void GiveLoot(Entity* player, const Loot::Return& result, eLootSourceType lootSourceType = eLootSourceType::NONE);
|
|
void GiveActivityLoot(Entity* player, const LWOOBJID source, uint32_t activityID, int32_t rating = 0);
|
|
void DropLoot(Entity* player, const LWOOBJID source, uint32_t matrixIndex, uint32_t minCoins, uint32_t maxCoins);
|
|
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;
|
|
|
|
/**
|
|
* Fills DropClientLoot's use_position and final_position the way live did (12,501 live DropClientLoot).
|
|
* use_position is set only when a player is the source (activity rewards such as the dragon and BONS chests):
|
|
* otherwise the client spawns the loot at the source object where it is on the client, and only falls back
|
|
* to the spawn position if that object is gone. Coins land where they spawn; items land ITEM_DROP_DISTANCE away
|
|
* at the given angle (radians, around Y).
|
|
* Nothing is set when there is no spawn position.
|
|
*/
|
|
void SetDropPositions(GameMessages::DropClientLoot& lootMsg, bool sourceIsPlayer, float angle);
|
|
};
|