mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-10-17 12:58:09 +00:00
fix: powerup drops and hardcore loot drops (#1914)
tested the following are now functional ag buff station tiki torch ve rocket part boxes ns statue property behavior extra items from full inventory hardcore drops (items and coins)
This commit is contained in:
@@ -982,7 +982,14 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) {
|
||||
for (const auto item : itemMap | std::views::values) {
|
||||
// Don't drop excluded items or null ones
|
||||
if (!item || Game::entityManager->GetHardcoreExcludedItemDrops().contains(item->GetLot())) continue;
|
||||
GameMessages::SendDropClientLoot(m_Parent, source, item->GetLot(), 0, m_Parent->GetPosition(), item->GetCount());
|
||||
GameMessages::DropClientLoot lootMsg{};
|
||||
lootMsg.target = m_Parent->GetObjectID();
|
||||
lootMsg.ownerID = m_Parent->GetObjectID();
|
||||
lootMsg.sourceID = m_Parent->GetObjectID();
|
||||
lootMsg.item = item->GetLot();
|
||||
lootMsg.count = 1;
|
||||
lootMsg.spawnPos = m_Parent->GetPosition();
|
||||
for (int i = 0; i < item->GetCount(); i++) Loot::DropItem(*m_Parent, lootMsg);
|
||||
item->SetCount(0, false, false);
|
||||
}
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
@@ -1005,12 +1012,24 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) {
|
||||
|
||||
//drop all coins:
|
||||
constexpr auto MAX_TO_DROP_PER_GM = 100'000;
|
||||
GameMessages::DropClientLoot lootMsg{};
|
||||
lootMsg.target = m_Parent->GetObjectID();
|
||||
lootMsg.ownerID = m_Parent->GetObjectID();
|
||||
lootMsg.spawnPos = m_Parent->GetPosition();
|
||||
lootMsg.sourceID = source;
|
||||
lootMsg.item = LOT_NULL;
|
||||
lootMsg.Send();
|
||||
lootMsg.Send(m_Parent->GetSystemAddress());
|
||||
while (coinsToDrop > MAX_TO_DROP_PER_GM) {
|
||||
LOG("Dropping 100,000, %llu left", coinsToDrop);
|
||||
GameMessages::SendDropClientLoot(m_Parent, source, LOT_NULL, MAX_TO_DROP_PER_GM, m_Parent->GetPosition());
|
||||
coinsToDrop -= MAX_TO_DROP_PER_GM;
|
||||
lootMsg.currency = 100'000;
|
||||
lootMsg.Send();
|
||||
lootMsg.Send(m_Parent->GetSystemAddress());
|
||||
coinsToDrop -= 100'000;
|
||||
}
|
||||
GameMessages::SendDropClientLoot(m_Parent, source, LOT_NULL, coinsToDrop, m_Parent->GetPosition());
|
||||
lootMsg.currency = coinsToDrop;
|
||||
lootMsg.Send();
|
||||
lootMsg.Send(m_Parent->GetSystemAddress());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@@ -282,7 +282,14 @@ void InventoryComponent::AddItem(
|
||||
|
||||
case 1:
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
GameMessages::SendDropClientLoot(this->m_Parent, this->m_Parent->GetObjectID(), lot, 0, this->m_Parent->GetPosition(), 1);
|
||||
GameMessages::DropClientLoot lootMsg{};
|
||||
lootMsg.target = m_Parent->GetObjectID();
|
||||
lootMsg.ownerID = m_Parent->GetObjectID();
|
||||
lootMsg.sourceID = m_Parent->GetObjectID();
|
||||
lootMsg.item = lot;
|
||||
lootMsg.count = 1;
|
||||
lootMsg.spawnPos = m_Parent->GetPosition();
|
||||
Loot::DropItem(*m_Parent, lootMsg);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@@ -1067,44 +1067,6 @@ void GameMessages::SendSetNetworkScriptVar(Entity* entity, const SystemAddress&
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void GameMessages::SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID, LOT item, int currency, NiPoint3 spawnPos, int count) {
|
||||
if (Game::config->GetValue("disable_drops") == "1" || !entity) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool bUsePosition = false;
|
||||
NiPoint3 finalPosition;
|
||||
LWOOBJID lootID = LWOOBJID_EMPTY;
|
||||
LWOOBJID owner = entity->GetObjectID();
|
||||
|
||||
if (item != LOT_NULL && item != 0) {
|
||||
lootID = ObjectIDManager::GenerateObjectID();
|
||||
|
||||
Loot::Info info;
|
||||
info.id = lootID;
|
||||
info.count = count;
|
||||
info.lot = item;
|
||||
entity->AddLootItem(info);
|
||||
}
|
||||
|
||||
if (item == LOT_NULL && currency != 0) {
|
||||
entity->RegisterCoinDrop(currency);
|
||||
}
|
||||
|
||||
if (spawnPos != NiPoint3Constant::ZERO) {
|
||||
bUsePosition = true;
|
||||
|
||||
//Calculate where the loot will go:
|
||||
uint16_t degree = GeneralUtils::GenerateRandomNumber<uint16_t>(0, 360);
|
||||
|
||||
double rad = degree * 3.14 / 180;
|
||||
double sin_v = sin(rad) * 4.2;
|
||||
double cos_v = cos(rad) * 4.2;
|
||||
|
||||
finalPosition = NiPoint3(static_cast<float>(spawnPos.GetX() + sin_v), spawnPos.GetY(), static_cast<float>(spawnPos.GetZ() + cos_v));
|
||||
}
|
||||
}
|
||||
|
||||
void GameMessages::SendSetPlayerControlScheme(Entity* entity, eControlScheme controlScheme) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
@@ -153,7 +153,6 @@ namespace GameMessages {
|
||||
void SendStop2DAmbientSound(Entity* entity, bool force, std::string audioGUID, bool result = false);
|
||||
void SendPlay2DAmbientSound(Entity* entity, std::string audioGUID, bool result = false);
|
||||
void SendSetNetworkScriptVar(Entity* entity, const SystemAddress& sysAddr, std::string data);
|
||||
void SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID, LOT item, int currency, NiPoint3 spawnPos = NiPoint3Constant::ZERO, int count = 1);
|
||||
|
||||
void SendSetPlayerControlScheme(Entity* entity, eControlScheme controlScheme);
|
||||
void SendPlayerReachedRespawnCheckpoint(Entity* entity, const NiPoint3& position, const NiQuaternion& rotation);
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include "dChatFilter.h"
|
||||
|
||||
#include "DluAssert.h"
|
||||
#include "Loot.h"
|
||||
|
||||
template <>
|
||||
void Strip::HandleMsg(AddStripMessage& msg) {
|
||||
@@ -148,7 +149,14 @@ void Strip::Spawn(LOT lot, Entity& entity) {
|
||||
// Spawns a specific drop for all
|
||||
void Strip::SpawnDrop(LOT dropLOT, Entity& entity) {
|
||||
for (auto* const player : PlayerManager::GetAllPlayers()) {
|
||||
GameMessages::SendDropClientLoot(player, entity.GetObjectID(), dropLOT, 0, entity.GetPosition());
|
||||
GameMessages::DropClientLoot lootMsg{};
|
||||
lootMsg.target = player->GetObjectID();
|
||||
lootMsg.ownerID = player->GetObjectID();
|
||||
lootMsg.sourceID = entity.GetObjectID();
|
||||
lootMsg.item = dropLOT;
|
||||
lootMsg.count = 1;
|
||||
lootMsg.spawnPos = entity.GetPosition();
|
||||
Loot::DropItem(*player, lootMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -93,17 +93,19 @@ std::map<LOT, LootDropInfo> RollLootMatrix(uint32_t matrixIndex) {
|
||||
|
||||
// Generates a 'random' final position for the loot drop based on its input spawn position.
|
||||
void CalcFinalDropPos(GameMessages::DropClientLoot& lootMsg) {
|
||||
lootMsg.bUsePosition = true;
|
||||
if (lootMsg.spawnPos != NiPoint3Constant::ZERO) {
|
||||
lootMsg.bUsePosition = true;
|
||||
|
||||
//Calculate where the loot will go:
|
||||
uint16_t degree = GeneralUtils::GenerateRandomNumber<uint16_t>(0, 360);
|
||||
//Calculate where the loot will go:
|
||||
uint16_t degree = GeneralUtils::GenerateRandomNumber<uint16_t>(0, 360);
|
||||
|
||||
double rad = degree * 3.14 / 180;
|
||||
double sin_v = sin(rad) * 4.2;
|
||||
double cos_v = cos(rad) * 4.2;
|
||||
double rad = degree * 3.14 / 180;
|
||||
double sin_v = sin(rad) * 4.2;
|
||||
double cos_v = cos(rad) * 4.2;
|
||||
|
||||
const auto [x, y, z] = lootMsg.spawnPos;
|
||||
lootMsg.finalPosition = NiPoint3(static_cast<float>(x + sin_v), y, static_cast<float>(z + cos_v));
|
||||
const auto [x, y, z] = lootMsg.spawnPos;
|
||||
lootMsg.finalPosition = NiPoint3(static_cast<float>(x + sin_v), y, static_cast<float>(z + cos_v));
|
||||
}
|
||||
}
|
||||
|
||||
// Visually drop the loot to all team members, though only the lootMsg.ownerID can pick it up
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "RenderComponent.h"
|
||||
#include "eTerminateType.h"
|
||||
#include "Loot.h"
|
||||
|
||||
void GfTikiTorch::OnStartup(Entity* self) {
|
||||
LightTorch(self);
|
||||
@@ -22,7 +23,14 @@ void GfTikiTorch::OnUse(Entity* self, Entity* killer) {
|
||||
self->SetI64(u"userID", killer->GetObjectID());
|
||||
|
||||
for (int i = 0; i < m_numspawn; i++) {
|
||||
GameMessages::SendDropClientLoot(killer, self->GetObjectID(), 935, 0, self->GetPosition());
|
||||
GameMessages::DropClientLoot lootMsg{};
|
||||
lootMsg.target = killer->GetObjectID();
|
||||
lootMsg.ownerID = killer->GetObjectID();
|
||||
lootMsg.sourceID = self->GetObjectID();
|
||||
lootMsg.item = 935;
|
||||
lootMsg.count = 1;
|
||||
lootMsg.spawnPos = self->GetPosition();
|
||||
Loot::DropItem(*killer, lootMsg);
|
||||
}
|
||||
|
||||
self->AddTimer("InteractionCooldown", 4);
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include "GameMessages.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "TeamManager.h"
|
||||
#include "Loot.h"
|
||||
|
||||
void AgSurvivalBuffStation::OnQuickBuildComplete(Entity* self, Entity* target) {
|
||||
auto destroyableComponent = self->GetComponent<DestroyableComponent>();
|
||||
@@ -55,7 +56,14 @@ void AgSurvivalBuffStation::OnTimerDone(Entity* self, std::string timerName) {
|
||||
for (auto memberID : team) {
|
||||
auto member = Game::entityManager->GetEntity(memberID);
|
||||
if (member != nullptr && !member->GetIsDead()) {
|
||||
GameMessages::SendDropClientLoot(member, self->GetObjectID(), powerupToDrop, 0, self->GetPosition());
|
||||
GameMessages::DropClientLoot lootMsg{};
|
||||
lootMsg.target = member->GetObjectID();
|
||||
lootMsg.ownerID = member->GetObjectID();
|
||||
lootMsg.sourceID = self->GetObjectID();
|
||||
lootMsg.item = powerupToDrop;
|
||||
lootMsg.count = 1;
|
||||
lootMsg.spawnPos = self->GetPosition();
|
||||
Loot::DropItem(*member, lootMsg, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include "EntityInfo.h"
|
||||
#include "DestroyableComponent.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "Loot.h"
|
||||
|
||||
void AgImagSmashable::OnDie(Entity* self, Entity* killer) {
|
||||
bool maxImagGreaterThanZero = false;
|
||||
@@ -18,7 +19,14 @@ void AgImagSmashable::OnDie(Entity* self, Entity* killer) {
|
||||
if (maxImagGreaterThanZero) {
|
||||
int amount = GeneralUtils::GenerateRandomNumber<int>(0, 3);
|
||||
for (int i = 0; i < amount; ++i) {
|
||||
GameMessages::SendDropClientLoot(killer, self->GetObjectID(), 935, 0, self->GetPosition());
|
||||
GameMessages::DropClientLoot lootMsg{};
|
||||
lootMsg.target = killer->GetObjectID();
|
||||
lootMsg.ownerID = killer->GetObjectID();
|
||||
lootMsg.sourceID = self->GetObjectID();
|
||||
lootMsg.item = 935;
|
||||
lootMsg.count = 1;
|
||||
lootMsg.spawnPos = self->GetPosition();
|
||||
Loot::DropItem(*killer, lootMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#include "NsQbImaginationStatue.h"
|
||||
#include "EntityManager.h"
|
||||
#include "GameMessages.h"
|
||||
#include "Loot.h"
|
||||
|
||||
void NsQbImaginationStatue::OnStartup(Entity* self) {
|
||||
|
||||
@@ -35,6 +36,12 @@ void NsQbImaginationStatue::SpawnLoot(Entity* self) {
|
||||
|
||||
if (player == nullptr) return;
|
||||
|
||||
GameMessages::SendDropClientLoot(player, self->GetObjectID(), 935, 0);
|
||||
GameMessages::SendDropClientLoot(player, self->GetObjectID(), 935, 0);
|
||||
GameMessages::DropClientLoot lootMsg{};
|
||||
lootMsg.target = player->GetObjectID();
|
||||
lootMsg.ownerID = player->GetObjectID();
|
||||
lootMsg.sourceID = self->GetObjectID();
|
||||
lootMsg.item = 935;
|
||||
lootMsg.count = 1;
|
||||
Loot::DropItem(*player, lootMsg);
|
||||
Loot::DropItem(*player, lootMsg);
|
||||
}
|
||||
|
Reference in New Issue
Block a user