mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
fix(currency): SetCurrency names its source the way live did
Live filled SetCurrency's source fields per source type (16,816 decoded live SetCurrency): pickups carry the position the client picked the coins up at (the one in its PickupCurrency) and no source; mission, achievement and activity rewards name the player (object and LOT 1); vendor buys, sells and buybacks name the vendor and its LOT; trades carry the trade ID; death, mail and everything else name nothing. No live SetCurrency sets loot_type. DLU wrote a present source LOT of 0, no object and a zero position for all of them. The position is the one the client uses: for pickups it projects it to the screen as the start of the coin counter animation (LWOCharacterComponent::SetCurrency), so it started from the world origin before. PickupCurrency now reads that position (the client always sends it). The trade ID is an 8-byte object ID in the client; DLU declared it 4 bytes, which only never broke because it was never set. Check: pick up coins and watch the coin counter animate from where the coins were; buy and sell at a vendor, finish a mission and trade coins with another player, and the coin total updates each time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -590,7 +590,38 @@ const NiPoint3& Character::GetRespawnPoint(LWOMAPID map) const {
|
||||
return pair->second;
|
||||
}
|
||||
|
||||
void Character::SetCoins(int64_t newCoins, eLootSourceType lootSource) {
|
||||
CoinSource CoinSource::Object(const Entity& source) {
|
||||
CoinSource coinSource;
|
||||
coinSource.object = source.GetObjectID();
|
||||
coinSource.lot = source.GetLOT();
|
||||
return coinSource;
|
||||
}
|
||||
|
||||
CoinSource CoinSource::Position(const NiPoint3& position) {
|
||||
CoinSource coinSource;
|
||||
coinSource.position = position;
|
||||
return coinSource;
|
||||
}
|
||||
|
||||
CoinSource CoinSource::Trade(const LWOOBJID tradeID) {
|
||||
CoinSource coinSource;
|
||||
coinSource.tradeID = tradeID;
|
||||
return coinSource;
|
||||
}
|
||||
|
||||
GameMessages::SetCurrency Character::MakeSetCurrency(const LWOOBJID player, const int64_t coins, const eLootSourceType coinSource, const CoinSource& source) {
|
||||
GameMessages::SetCurrency setCurrency;
|
||||
setCurrency.target = player;
|
||||
setCurrency.currency = coins;
|
||||
setCurrency.position = source.position;
|
||||
setCurrency.sourceLOT = source.lot;
|
||||
setCurrency.sourceID = source.object;
|
||||
setCurrency.sourceTradeID = source.tradeID;
|
||||
setCurrency.sourceType = coinSource;
|
||||
return setCurrency;
|
||||
}
|
||||
|
||||
void Character::SetCoins(int64_t newCoins, eLootSourceType lootSource, const CoinSource& source) {
|
||||
if (newCoins < 0) {
|
||||
newCoins = 0;
|
||||
}
|
||||
@@ -600,15 +631,7 @@ void Character::SetCoins(int64_t newCoins, eLootSourceType lootSource) {
|
||||
m_Coins = newCoins;
|
||||
|
||||
auto* entity = Game::entityManager->GetEntity(m_ObjectID);
|
||||
GameMessages::SetCurrency setCurrency;
|
||||
setCurrency.target = entity->GetObjectID();
|
||||
setCurrency.currency = m_Coins;
|
||||
setCurrency.lootType = 0;
|
||||
setCurrency.sourceLOT = 0;
|
||||
setCurrency.sourceID = 0;
|
||||
setCurrency.sourceTradeID = 0;
|
||||
setCurrency.sourceType = lootSource;
|
||||
setCurrency.SendToClient(entity->GetSystemAddress());
|
||||
MakeSetCurrency(entity->GetObjectID(), m_Coins, lootSource, source).SendToClient(entity->GetSystemAddress());
|
||||
|
||||
// Live followed every coin gain with CurrencyCollected (the amount gained); losses had none
|
||||
auto* characterComponent = entity->GetComponent<CharacterComponent>();
|
||||
|
||||
Reference in New Issue
Block a user