From 7aacfc1bf039212ddf60fd54eb2a7ebf52037084 Mon Sep 17 00:00:00 2001 From: wincent Date: Wed, 11 Jan 2023 21:50:21 +0100 Subject: [PATCH] Fixed crashes related to hardcore mode --- dGame/dComponents/DestroyableComponent.cpp | 42 ++++++++++++---------- dGame/dUtilities/SlashCommandHandler.cpp | 13 +++++-- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index e08de3e6..0e8ce56e 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -666,46 +666,46 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 return; } - Smash(source, eKillType::VIOLENT, u"", skillID); //check if hardcore mode is enabled if (Game::config->GetValue("hardcore_mode") == "1") { //check if this is a player: if (m_Parent->GetLOT() == 1) { //get hardcore_lose_uscore_on_death_percent from dconfig: - auto hardcore_lose_uscore_on_death_percent = std::stoi(Game::config->GetValue("hardcore_lose_uscore_on_death_percent")); + auto hardcoreLoseUscoreOnDeathPercent = std::stoi(Game::config->GetValue("hardcore_lose_uscore_on_death_percent")); //remove hardcore_lose_uscore_on_death_percent from the player's uscore: auto* character = m_Parent->GetComponent(); auto uscore = character->GetUScore(); - auto uscore_to_lose = uscore * hardcore_lose_uscore_on_death_percent / 100; - character->SetUScore(uscore - uscore_to_lose); + auto uscoreToLose = uscore * hardcoreLoseUscoreOnDeathPercent / 100; + character->SetUScore(uscore - uscoreToLose); - //get hardcore_dropinventory on death from dconfig: - auto hardcore_dropinventory_on_death = (bool)std::stoi(Game::config->GetValue("hardcore_dropinventory_on_death")); + GameMessages::SendModifyLEGOScore(m_Parent, m_Parent->GetSystemAddress(), -uscoreToLose, eLootSourceType::LOOT_SOURCE_MISSION); - if (hardcore_dropinventory_on_death == false) return; + // Reload the player + EntityManager::Instance()->DestructEntity(m_Parent); + EntityManager::Instance()->ConstructEntity(m_Parent); + + auto hardcoreDropinventoryOnDeath = (bool)std::stoi(Game::config->GetValue("hardcore_dropinventory_on_death")); + + if (hardcoreDropinventoryOnDeath == false) return; //drop all items from inventory: auto* inventory = m_Parent->GetComponent(); //get the items inventory: auto items = inventory->GetInventory(eInventoryType::ITEMS); - for (auto item : items->GetItems()) { - //check if this is an equipped item: - if (item.second->IsEquipped()) { - //unequip the item: - inventory->UnEquipItem(item.second); - } - + auto itemMap = items->GetItems(); + for (const auto& item : itemMap) { //drop the item: GameMessages::SendDropClientLoot(m_Parent, source, item.second->GetLot(), 0, m_Parent->GetPosition(), item.second->GetCount()); - //remove from inventory: - inventory->RemoveItem(item.second->GetLot(), item.second->GetCount()); + item.second->SetCount(0, false, false); } + EntityManager::Instance()->SerializeEntity(m_Parent); + //get character: auto* chars = m_Parent->GetCharacter(); if (chars) { @@ -727,15 +727,19 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 auto maxHealth = GetMaxHealth(); //get the u-score to award from dconfig: - auto hardcore_uscore_enemies_multiplier = std::stoi(Game::config->GetValue("hardcore_uscore_enemies_multiplier")); - int uscore = maxHealth * hardcore_uscore_enemies_multiplier; + auto hardcoreUscoreEnemiesMultiplier = std::stoi(Game::config->GetValue("hardcore_uscore_enemies_multiplier")); + int uscore = maxHealth * hardcoreUscoreEnemiesMultiplier; playerStats->SetUScore(playerStats->GetUScore() + uscore); - GameMessages::SendModifyLEGOScore(player, player->GetSystemAddress(), uscore, eLootSourceType::LOOT_SOURCE_NONE); + GameMessages::SendModifyLEGOScore(player, player->GetSystemAddress(), uscore, eLootSourceType::LOOT_SOURCE_MISSION); + + EntityManager::Instance()->SerializeEntity(m_Parent); } } } } + + Smash(source, eKillType::VIOLENT, u"", skillID); } void DestroyableComponent::Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd) { diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index cc1c82a9..70637990 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1312,7 +1312,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if ((chatCommand == "giveuscore") && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "giveuscore") && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { int32_t uscore; if (!GeneralUtils::TryParse(args[0], uscore)) { @@ -1323,7 +1323,16 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit CharacterComponent* character = entity->GetComponent(); if (character) character->SetUScore(character->GetUScore() + uscore); // LOOT_SOURCE_MODERATION should work but it doesn't. Relog to see uscore changes - GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), uscore, eLootSourceType::LOOT_SOURCE_MODERATION); + + eLootSourceType lootType = eLootSourceType::LOOT_SOURCE_MODERATION; + + int32_t type; + if (args.size() >= 2 && GeneralUtils::TryParse(args[1], type)) + { + lootType = (eLootSourceType) type; + } + + GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), uscore, lootType); } if ((chatCommand == "setlevel") && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) {