mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-07-01 17:20:04 +00:00
feat: add messaging system for manager and add example usage to Loot (#1837)
tested that loot still drops at the entities position
This commit is contained in:
parent
c697f8ad97
commit
48510b7315
@ -605,3 +605,14 @@ void EntityManager::FireEventServerSide(Entity* origin, std::string args) {
|
||||
bool EntityManager::IsExcludedFromGhosting(LOT lot) {
|
||||
return std::find(m_GhostingExcludedLOTs.begin(), m_GhostingExcludedLOTs.end(), lot) != m_GhostingExcludedLOTs.end();
|
||||
}
|
||||
|
||||
bool EntityManager::SendMessage(GameMessages::GameMsg& msg) const {
|
||||
bool handled = false;
|
||||
const auto entityItr = m_Entities.find(msg.target);
|
||||
if (entityItr != m_Entities.end()) {
|
||||
auto* const entity = entityItr->second;
|
||||
if (entity) handled = entity->HandleMsg(msg);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
@ -14,6 +14,10 @@ class Player;
|
||||
class User;
|
||||
enum class eReplicaComponentType : uint32_t;
|
||||
|
||||
namespace GameMessages {
|
||||
struct GameMsg;
|
||||
}
|
||||
|
||||
struct SystemAddress;
|
||||
|
||||
class EntityManager {
|
||||
@ -72,6 +76,9 @@ public:
|
||||
const bool GetHardcoreDropinventoryOnDeath() { return m_HardcoreDropinventoryOnDeath; };
|
||||
const uint32_t GetHardcoreUscoreEnemiesMultiplier() { return m_HardcoreUscoreEnemiesMultiplier; };
|
||||
|
||||
// Messaging
|
||||
bool SendMessage(GameMessages::GameMsg& msg) const;
|
||||
|
||||
private:
|
||||
void SerializeEntities();
|
||||
void KillEntities();
|
||||
|
@ -575,7 +575,7 @@ void ActivityInstance::RewardParticipant(Entity* participant) {
|
||||
maxCoins = currencyTable[0].maxvalue;
|
||||
}
|
||||
|
||||
Loot::DropLoot(participant, m_Parent, activityRewards[0].LootMatrixIndex, minCoins, maxCoins);
|
||||
Loot::DropLoot(participant, m_Parent->GetObjectID(), activityRewards[0].LootMatrixIndex, minCoins, maxCoins);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -755,18 +755,18 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
|
||||
|
||||
auto* member = Game::entityManager->GetEntity(specificOwner);
|
||||
|
||||
if (member) Loot::DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins());
|
||||
if (member) Loot::DropLoot(member, m_Parent->GetObjectID(), lootMatrixId, GetMinCoins(), GetMaxCoins());
|
||||
} else {
|
||||
for (const auto memberId : team->members) { // Free for all
|
||||
auto* member = Game::entityManager->GetEntity(memberId);
|
||||
|
||||
if (member == nullptr) continue;
|
||||
|
||||
Loot::DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins());
|
||||
Loot::DropLoot(member, m_Parent->GetObjectID(), lootMatrixId, GetMinCoins(), GetMaxCoins());
|
||||
}
|
||||
}
|
||||
} else { // drop loot for non team user
|
||||
Loot::DropLoot(owner, m_Parent, GetLootMatrixID(), GetMinCoins(), GetMaxCoins());
|
||||
Loot::DropLoot(owner, m_Parent->GetObjectID(), GetLootMatrixID(), GetMinCoins(), GetMaxCoins());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -784,7 +784,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
|
||||
|
||||
coinsTotal -= coinsToLose;
|
||||
|
||||
Loot::DropLoot(m_Parent, m_Parent, -1, coinsToLose, coinsToLose);
|
||||
Loot::DropLoot(m_Parent, m_Parent->GetObjectID(), -1, coinsToLose, coinsToLose);
|
||||
character->SetCoins(coinsTotal, eLootSourceType::PICKUP);
|
||||
}
|
||||
}
|
||||
|
@ -459,7 +459,7 @@ void QuickBuildComponent::CompleteQuickBuild(Entity* const user) {
|
||||
auto* missionComponent = builder->GetComponent<MissionComponent>();
|
||||
if (missionComponent) missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityId);
|
||||
}
|
||||
Loot::DropActivityLoot(builder, m_Parent, m_ActivityId, 1);
|
||||
Loot::DropActivityLoot(builder, m_Parent->GetObjectID(), m_ActivityId, 1);
|
||||
}
|
||||
|
||||
// Notify scripts
|
||||
|
@ -393,7 +393,7 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu
|
||||
}
|
||||
|
||||
const auto score = playersRating * 10 + data->finished;
|
||||
Loot::GiveActivityLoot(player, m_Parent, m_ActivityID, score);
|
||||
Loot::GiveActivityLoot(player, m_Parent->GetObjectID(), m_ActivityID, score);
|
||||
|
||||
// Giving rewards
|
||||
GameMessages::SendNotifyRacingClient(
|
||||
|
@ -6312,6 +6312,10 @@ void GameMessages::SendUpdateInventoryUi(LWOOBJID objectId, const SystemAddress&
|
||||
}
|
||||
|
||||
namespace GameMessages {
|
||||
bool GameMsg::Send() {
|
||||
return Game::entityManager->SendMessage(*this);
|
||||
}
|
||||
|
||||
void GameMsg::Send(const SystemAddress& sysAddr) const {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
@ -54,6 +54,12 @@ namespace GameMessages {
|
||||
GameMsg(MessageType::Game gmId, eGameMasterLevel lvl) : msgId{ gmId }, requiredGmLevel{ lvl } {}
|
||||
GameMsg(MessageType::Game gmId) : GameMsg(gmId, eGameMasterLevel::CIVILIAN) {}
|
||||
virtual ~GameMsg() = default;
|
||||
|
||||
// Sends a message to the entity manager to route to the target
|
||||
bool Send();
|
||||
|
||||
// Sends the message to the specified client or
|
||||
// all clients if UNASSIGNED_SYSTEM_ADDRESS is specified
|
||||
void Send(const SystemAddress& sysAddr) const;
|
||||
virtual void Serialize(RakNet::BitStream& bitStream) const {}
|
||||
virtual bool Deserialize(RakNet::BitStream& bitStream) { return true; }
|
||||
|
@ -214,7 +214,7 @@ void Loot::GiveLoot(Entity* player, std::unordered_map<LOT, int32_t>& result, eL
|
||||
}
|
||||
}
|
||||
|
||||
void Loot::GiveActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating) {
|
||||
void Loot::GiveActivityLoot(Entity* player, const LWOOBJID source, uint32_t activityID, int32_t rating) {
|
||||
CDActivityRewardsTable* activityRewardsTable = CDClientManager::GetTable<CDActivityRewardsTable>();
|
||||
std::vector<CDActivityRewards> activityRewards = activityRewardsTable->Query([activityID](CDActivityRewards entry) { return (entry.objectTemplate == activityID); });
|
||||
|
||||
@ -248,7 +248,7 @@ void Loot::GiveActivityLoot(Entity* player, Entity* source, uint32_t activityID,
|
||||
character->SetCoins(character->GetCoins() + coins, eLootSourceType::ACTIVITY);
|
||||
}
|
||||
|
||||
void Loot::DropLoot(Entity* player, Entity* killedObject, uint32_t matrixIndex, uint32_t minCoins, uint32_t maxCoins) {
|
||||
void Loot::DropLoot(Entity* player, const LWOOBJID source, uint32_t matrixIndex, uint32_t minCoins, uint32_t maxCoins) {
|
||||
player = player->GetOwner(); // if the owner is overwritten, we collect that here
|
||||
|
||||
auto* inventoryComponent = player->GetComponent<InventoryComponent>();
|
||||
@ -258,10 +258,10 @@ void Loot::DropLoot(Entity* player, Entity* killedObject, uint32_t matrixIndex,
|
||||
|
||||
std::unordered_map<LOT, int32_t> result = RollLootMatrix(player, matrixIndex);
|
||||
|
||||
DropLoot(player, killedObject, result, minCoins, maxCoins);
|
||||
DropLoot(player, source, result, minCoins, maxCoins);
|
||||
}
|
||||
|
||||
void Loot::DropLoot(Entity* player, Entity* killedObject, std::unordered_map<LOT, int32_t>& result, uint32_t minCoins, uint32_t maxCoins) {
|
||||
void Loot::DropLoot(Entity* player, const LWOOBJID source, std::unordered_map<LOT, int32_t>& result, uint32_t minCoins, uint32_t maxCoins) {
|
||||
player = player->GetOwner(); // if the owner is overwritten, we collect that here
|
||||
|
||||
auto* inventoryComponent = player->GetComponent<InventoryComponent>();
|
||||
@ -269,9 +269,11 @@ void Loot::DropLoot(Entity* player, Entity* killedObject, std::unordered_map<LOT
|
||||
if (!inventoryComponent)
|
||||
return;
|
||||
|
||||
const auto spawnPosition = killedObject->GetPosition();
|
||||
GameMessages::GetPosition posMsg;
|
||||
posMsg.target = source;
|
||||
posMsg.Send();
|
||||
|
||||
const auto source = killedObject->GetObjectID();
|
||||
const auto spawnPosition = posMsg.pos;
|
||||
|
||||
for (const auto& pair : result) {
|
||||
for (int i = 0; i < pair.second; ++i) {
|
||||
@ -284,7 +286,7 @@ void Loot::DropLoot(Entity* player, Entity* killedObject, std::unordered_map<LOT
|
||||
GameMessages::SendDropClientLoot(player, source, LOT_NULL, coins, spawnPosition);
|
||||
}
|
||||
|
||||
void Loot::DropActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating) {
|
||||
void Loot::DropActivityLoot(Entity* player, const LWOOBJID source, uint32_t activityID, int32_t rating) {
|
||||
CDActivityRewardsTable* activityRewardsTable = CDClientManager::GetTable<CDActivityRewardsTable>();
|
||||
std::vector<CDActivityRewards> activityRewards = activityRewardsTable->Query([activityID](CDActivityRewards entry) { return (entry.objectTemplate == activityID); });
|
||||
|
||||
|
@ -18,8 +18,8 @@ namespace Loot {
|
||||
void CacheMatrix(const uint32_t matrixIndex);
|
||||
void GiveLoot(Entity* player, uint32_t matrixIndex, eLootSourceType lootSourceType = eLootSourceType::NONE);
|
||||
void GiveLoot(Entity* player, std::unordered_map<LOT, int32_t>& result, eLootSourceType lootSourceType = eLootSourceType::NONE);
|
||||
void GiveActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating = 0);
|
||||
void DropLoot(Entity* player, Entity* killedObject, uint32_t matrixIndex, uint32_t minCoins, uint32_t maxCoins);
|
||||
void DropLoot(Entity* player, Entity* killedObject, std::unordered_map<LOT, int32_t>& result, uint32_t minCoins, uint32_t maxCoins);
|
||||
void DropActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating = 0);
|
||||
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 DropLoot(Entity* player, const LWOOBJID source, std::unordered_map<LOT, int32_t>& result, uint32_t minCoins, uint32_t maxCoins);
|
||||
void DropActivityLoot(Entity* player, const LWOOBJID source, uint32_t activityID, int32_t rating = 0);
|
||||
};
|
||||
|
@ -33,10 +33,10 @@ void TreasureChestDragonServer::OnUse(Entity* self, Entity* user) {
|
||||
|
||||
if (memberObject == nullptr) continue;
|
||||
|
||||
Loot::DropActivityLoot(memberObject, self, scriptedActivityComponent->GetActivityID(), rating);
|
||||
Loot::DropActivityLoot(memberObject, self->GetObjectID(), scriptedActivityComponent->GetActivityID(), rating);
|
||||
}
|
||||
} else {
|
||||
Loot::DropActivityLoot(user, self, scriptedActivityComponent->GetActivityID(), rating);
|
||||
Loot::DropActivityLoot(user, self->GetObjectID(), scriptedActivityComponent->GetActivityID(), rating);
|
||||
}
|
||||
|
||||
self->Smash(self->GetObjectID());
|
||||
|
@ -45,7 +45,7 @@ BootyDigServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string
|
||||
if (renderComponent != nullptr)
|
||||
renderComponent->PlayEffect(7730, u"cast", "bootyshine");
|
||||
|
||||
Loot::DropLoot(player, self, 231, 75, 75);
|
||||
Loot::DropLoot(player, self->GetObjectID(), 231, 75, 75);
|
||||
}
|
||||
}
|
||||
} else if (args == "ChestDead") {
|
||||
|
@ -22,7 +22,7 @@ void BaseInteractDropLootServer::BaseUse(Entity* self, Entity* user) {
|
||||
|
||||
self->SetNetworkVar(u"bInUse", true);
|
||||
|
||||
Loot::DropLoot(user, self, lootMatrix, 0, 0);
|
||||
Loot::DropLoot(user, self->GetObjectID(), lootMatrix, 0, 0);
|
||||
|
||||
self->AddCallbackTimer(cooldownTime, [this, self]() {
|
||||
self->SetNetworkVar(u"bInUse", false);
|
||||
|
@ -13,7 +13,7 @@ void GrowingFlower::OnSkillEventFired(Entity* self, Entity* target, const std::s
|
||||
const auto mission1 = self->GetVar<int32_t>(u"missionID");
|
||||
const auto mission2 = self->GetVar<int32_t>(u"missionID2");
|
||||
|
||||
Loot::DropActivityLoot(target, self, self->GetLOT(), 0);
|
||||
Loot::DropActivityLoot(target, self->GetObjectID(), self->GetLOT(), 0);
|
||||
|
||||
auto* missionComponent = target->GetComponent<MissionComponent>();
|
||||
if (missionComponent != nullptr) {
|
||||
|
@ -23,7 +23,7 @@ void WishingWellServer::OnUse(Entity* self, Entity* user) {
|
||||
|
||||
Loot::DropActivityLoot(
|
||||
user,
|
||||
self,
|
||||
self->GetObjectID(),
|
||||
static_cast<uint32_t>(scriptedActivity->GetActivityID()),
|
||||
GeneralUtils::GenerateRandomNumber<int32_t>(1, 1000)
|
||||
);
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "eTerminateType.h"
|
||||
|
||||
void VeMissionConsole::OnUse(Entity* self, Entity* user) {
|
||||
Loot::DropActivityLoot(user, self, 12551);
|
||||
Loot::DropActivityLoot(user, self->GetObjectID(), 12551);
|
||||
|
||||
auto* inventoryComponent = user->GetComponent<InventoryComponent>();
|
||||
if (inventoryComponent != nullptr) {
|
||||
|
@ -14,6 +14,6 @@ void NjDragonEmblemChestServer::OnUse(Entity* self, Entity* user) {
|
||||
|
||||
auto* destroyable = self->GetComponent<DestroyableComponent>();
|
||||
if (destroyable != nullptr) {
|
||||
Loot::DropLoot(user, self, destroyable->GetLootMatrixID(), 0, 0);
|
||||
Loot::DropLoot(user, self->GetObjectID(), destroyable->GetLootMatrixID(), 0, 0);
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ void MinigameTreasureChestServer::OnUse(Entity* self, Entity* user) {
|
||||
|
||||
if (self->GetLOT() == frakjawChestId) activityRating = team->members.size();
|
||||
|
||||
Loot::DropActivityLoot(teamMember, self, sac->GetActivityID(), activityRating);
|
||||
Loot::DropActivityLoot(teamMember, self->GetObjectID(), sac->GetActivityID(), activityRating);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -35,7 +35,7 @@ void MinigameTreasureChestServer::OnUse(Entity* self, Entity* user) {
|
||||
|
||||
if (self->GetLOT() == frakjawChestId) activityRating = 1;
|
||||
|
||||
Loot::DropActivityLoot(user, self, sac->GetActivityID(), activityRating);
|
||||
Loot::DropActivityLoot(user, self->GetObjectID(), sac->GetActivityID(), activityRating);
|
||||
}
|
||||
|
||||
sac->PlayerRemove(user->GetObjectID());
|
||||
|
@ -72,7 +72,7 @@ void ActivityManager::StopActivity(Entity* self, const LWOOBJID playerID, const
|
||||
SetActivityValue(self, playerID, 1, value1);
|
||||
SetActivityValue(self, playerID, 2, value2);
|
||||
|
||||
Loot::GiveActivityLoot(player, self, gameID, CalculateActivityRating(self, playerID));
|
||||
Loot::GiveActivityLoot(player, self->GetObjectID(), gameID, CalculateActivityRating(self, playerID));
|
||||
|
||||
if (sac != nullptr) {
|
||||
sac->PlayerRemove(player->GetObjectID());
|
||||
|
@ -29,7 +29,7 @@ void ScriptedPowerupSpawner::OnTimerDone(Entity* self, std::string message) {
|
||||
renderComponent->PlayEffect(0, u"cast", "N_cast");
|
||||
}
|
||||
|
||||
Loot::DropLoot(owner, self, drops, 0, 0);
|
||||
Loot::DropLoot(owner, self->GetObjectID(), drops, 0, 0);
|
||||
}
|
||||
|
||||
// Increment the current cycle
|
||||
|
@ -11,7 +11,7 @@ void AgPicnicBlanket::OnUse(Entity* self, Entity* user) {
|
||||
self->SetVar<bool>(u"active", true);
|
||||
|
||||
auto lootTable = std::unordered_map<LOT, int32_t>{ {935, 3} };
|
||||
Loot::DropLoot(user, self, lootTable, 0, 0);
|
||||
Loot::DropLoot(user, self->GetObjectID(), lootTable, 0, 0);
|
||||
|
||||
self->AddCallbackTimer(5.0f, [self]() {
|
||||
self->SetVar<bool>(u"active", false);
|
||||
|
@ -572,7 +572,7 @@ void SGCannon::StopGame(Entity* self, bool cancel) {
|
||||
missionComponent->Progress(eMissionTaskType::ACTIVITY, m_CannonLot, 0, "", self->GetVar<int32_t>(TotalScoreVariable));
|
||||
}
|
||||
|
||||
Loot::GiveActivityLoot(player, self, GetGameID(self), self->GetVar<int32_t>(TotalScoreVariable));
|
||||
Loot::GiveActivityLoot(player, self->GetObjectID(), GetGameID(self), self->GetVar<int32_t>(TotalScoreVariable));
|
||||
|
||||
SaveScore(self, player->GetObjectID(),
|
||||
static_cast<float>(self->GetVar<int32_t>(TotalScoreVariable)), static_cast<float>(self->GetVar<uint32_t>(MaxStreakVariable)), percentage);
|
||||
|
Loading…
x
Reference in New Issue
Block a user