diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index fee53aef..7d8046e0 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -424,6 +424,7 @@ void Entity::Initialize() { comp->SetIsSmashable(destCompData[0].isSmashable); comp->SetLootMatrixID(destCompData[0].LootMatrixIndex); + comp->SetCurrencyIndex(destCompData[0].CurrencyIndex); Loot::CacheMatrix(destCompData[0].LootMatrixIndex); // Now get currency information @@ -2252,6 +2253,7 @@ bool Entity::MsgRequestServerObjectInfo(GameMessages::GameMsg& msg) { response.Insert("objectID", std::to_string(m_ObjectID)); response.Insert("serverInfo", true); GameMessages::GetObjectReportInfo info{}; + info.clientID = requestInfo.clientId; info.bVerbose = requestInfo.bVerbose; info.info = response.InsertArray("data"); auto& objectInfo = info.info->PushDebug("Object Details"); diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index fabcd3ef..0658757c 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -3,6 +3,9 @@ #include "Logger.h" #include "Game.h" #include "dConfig.h" +#include "CDLootMatrixTable.h" +#include "CDLootTableTable.h" +#include "CDRarityTableTable.h" #include "Amf3.h" #include "AmfSerialize.h" @@ -1060,38 +1063,89 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) { bool DestroyableComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) { auto& reportInfo = static_cast(msg); - auto& destroyableInfo = reportInfo.info->PushDebug("Destroyable"); - destroyableInfo.PushDebug("Health") = m_iHealth; - destroyableInfo.PushDebug("Max Health") = m_fMaxHealth; - destroyableInfo.PushDebug("Armor") = m_iArmor; - destroyableInfo.PushDebug("Max Armor") = m_fMaxArmor; - destroyableInfo.PushDebug("Imagination") = m_iImagination; - destroyableInfo.PushDebug("Max Imagination") = m_fMaxImagination; - destroyableInfo.PushDebug("Damage To Absorb") = m_DamageToAbsorb; + destroyableInfo.PushDebug("DestructibleComponent DB Table Template ID") = m_ComponentID; + + if (m_CurrencyIndex == -1) { + destroyableInfo.PushDebug("Has Loot Currency") = false; + } else { + destroyableInfo.PushDebug("Loot Currency ID") = m_CurrencyIndex; + auto& detailedCoinInfo = destroyableInfo.PushDebug("Coin Info"); + detailedCoinInfo.PushDebug("Min Coins") = m_MinCoins; + detailedCoinInfo.PushDebug("Max Coins") = m_MaxCoins; + } + + if (m_LootMatrixID == -1 || m_LootMatrixID == 0) { + destroyableInfo.PushDebug("Has Loot Matrix") = false; + } else { + auto& lootInfo = destroyableInfo.PushDebug("Loot Info"); + lootInfo.PushDebug("Loot Matrix ID") = m_LootMatrixID; + auto* const componentsRegistryTable = CDClientManager::GetTable(); + auto* const itemComponentTable = CDClientManager::GetTable(); + auto* const lootMatrixTable = CDClientManager::GetTable(); + auto* const lootTableTable = CDClientManager::GetTable(); + auto* const rarityTableTable = CDClientManager::GetTable(); + + const auto& matrix = lootMatrixTable->GetMatrix(m_LootMatrixID); + + for (const auto& entry : matrix) { + auto& thisEntry = lootInfo.PushDebug("Loot table Index - " + std::to_string(entry.LootTableIndex)); + thisEntry.PushDebug("Percent chance to drop") = entry.percent * 100.0f; + thisEntry.PushDebug("Minimum amount to drop") = entry.minToDrop; + thisEntry.PushDebug("Maximum amount to drop") = entry.maxToDrop; + const auto& lootTable = lootTableTable->GetTable(entry.LootTableIndex); + const auto& rarityTable = rarityTableTable->GetRarityTable(entry.RarityTableIndex); + + auto& thisRarity = thisEntry.PushDebug("Rarity"); + for (const auto& rarity : rarityTable) { + thisRarity.PushDebug("Rarity " + std::to_string(rarity.rarity)) = rarity.randmax; + } + + auto& thisItems = thisEntry.PushDebug("Drop(s) Info"); + for (const auto& loot : lootTable) { + uint32_t itemComponentId = componentsRegistryTable->GetByIDAndType(loot.itemid, eReplicaComponentType::ITEM); + uint32_t rarity = itemComponentTable->GetItemComponentByID(itemComponentId).rarity; + auto title = "%[Objects_" + std::to_string(loot.itemid) + "_name] " + std::to_string(loot.itemid); + if (loot.MissionDrop) title += " - Mission Drop"; + thisItems.PushDebug(title); + } + } + } + + auto* const entity = Game::entityManager->GetEntity(reportInfo.clientID); + destroyableInfo.PushDebug("Is on your team") = entity ? IsFriend(entity) : false; + auto& stats = destroyableInfo.PushDebug("Statistics"); + stats.PushDebug("Health") = m_iHealth; + stats.PushDebug("Maximum Health") = m_fMaxHealth; + stats.PushDebug("Armor") = m_iArmor; + stats.PushDebug("Maximum Armor") = m_fMaxArmor; + stats.PushDebug("Imagination") = m_iImagination; + stats.PushDebug("Maximum Imagination") = m_fMaxImagination; + stats.PushDebug("Damage Absorption Points") = m_DamageToAbsorb; destroyableInfo.PushDebug("Is GM Immune") = m_IsGMImmune; destroyableInfo.PushDebug("Is Shielded") = m_IsShielded; destroyableInfo.PushDebug("Attacks To Block") = m_AttacksToBlock; destroyableInfo.PushDebug("Damage Reduction") = m_DamageReduction; - auto& factions = destroyableInfo.PushDebug("Factions"); - size_t i = 0; + std::stringstream factionsStream; for (const auto factionID : m_FactionIDs) { - factions.PushDebug(std::to_string(i++) + " " + std::to_string(factionID)) = ""; + factionsStream << factionID << " "; } - auto& enemyFactions = destroyableInfo.PushDebug("Enemy Factions"); - i = 0; + + destroyableInfo.PushDebug("Factions") = factionsStream.str(); + + factionsStream.str(""); for (const auto enemyFactionID : m_EnemyFactionIDs) { - enemyFactions.PushDebug(std::to_string(i++) + " " + std::to_string(enemyFactionID)) = ""; + factionsStream << enemyFactionID << " "; } + + destroyableInfo.PushDebug("Enemy Factions") = factionsStream.str(); + destroyableInfo.PushDebug("Is Smashable") = m_IsSmashable; - destroyableInfo.PushDebug("Is Dead") = m_IsDead; destroyableInfo.PushDebug("Is Smashed") = m_IsSmashed; destroyableInfo.PushDebug("Is Module Assembly") = m_IsModuleAssembly; destroyableInfo.PushDebug("Explode Factor") = m_ExplodeFactor; destroyableInfo.PushDebug("Has Threats") = m_HasThreats; - destroyableInfo.PushDebug("Loot Matrix ID") = m_LootMatrixID; - destroyableInfo.PushDebug("Min Coins") = m_MinCoins; - destroyableInfo.PushDebug("Max Coins") = m_MaxCoins; + destroyableInfo.PushDebug("Killer ID") = std::to_string(m_KillerID); // "Scripts"; idk what to do about scripts yet @@ -1106,7 +1160,25 @@ bool DestroyableComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) { immuneCounts.PushDebug("Quickbuild Interrupt") = m_ImmuneToQuickbuildInterruptCount; immuneCounts.PushDebug("Pull To Point") = m_ImmuneToPullToPointCount; - destroyableInfo.PushDebug("Death Behavior") = m_DeathBehavior; + auto& deathInfo = destroyableInfo.PushDebug("Death Info"); + deathInfo.PushDebug("Is Dead") = m_IsDead; + switch (m_DeathBehavior) { + case 0: + deathInfo.PushDebug("Death Behavior") = "Fade"; + break; + case 1: + deathInfo.PushDebug("Death Behavior") = "Stay"; + break; + case 2: + deathInfo.PushDebug("Death Behavior") = "Immediate"; + break; + case -1: + deathInfo.PushDebug("Death Behavior") = "Invulnerable"; + break; + default: + deathInfo.PushDebug("Death Behavior") = "Other"; + break; + } destroyableInfo.PushDebug("Damage Cooldown Timer") = m_DamageCooldownTimer; return true; diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index c6bb0a98..9b3e46af 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -370,6 +370,8 @@ public: */ uint32_t GetLootMatrixID() const { return m_LootMatrixID; } + void SetCurrencyIndex(int32_t currencyIndex) { m_CurrencyIndex = currencyIndex; } + /** * Returns the ID of the entity that killed this entity, if any * @return the ID of the entity that killed this entity, if any @@ -587,6 +589,9 @@ private: */ uint32_t m_LootMatrixID; + // The currency index to determine how much loot to drop + int32_t m_CurrencyIndex{ -1 }; + /** * The min amount of coins that will drop when this entity is smashed */ diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 5c682075..1b52d67a 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -793,6 +793,7 @@ namespace GameMessages { AMFArrayValue* info{}; AMFArrayValue* subCategory{}; bool bVerbose{}; + LWOOBJID clientID{}; GetObjectReportInfo() : GameMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, eGameMasterLevel::DEVELOPER) {} };