From 23d0699806ebe02ae32870e7cf6fd5bb239212dd Mon Sep 17 00:00:00 2001 From: otsffs <141402668+otsffs@users.noreply.github.com> Date: Sat, 31 Aug 2024 17:07:04 +0800 Subject: [PATCH 1/2] Adjust enemy stats based on player count - Increase enemy health, mana, and stamina according to the number of players. --- .../Services/Generic/CharacterService.cpp | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/Code/client/Services/Generic/CharacterService.cpp b/Code/client/Services/Generic/CharacterService.cpp index c43734949..293f51c32 100644 --- a/Code/client/Services/Generic/CharacterService.cpp +++ b/Code/client/Services/Generic/CharacterService.cpp @@ -1212,6 +1212,82 @@ void CharacterService::RequestServerAssignment(const entt::entity aEntity) const message.CurrentActorData = BuildActorData(pActor); + // Define a small tolerance value for comparing floating-point numbers. + constexpr float epsilon = 1e-6; + // Only sync living entities, excluding players + // Enable only if the difficulty is sufficiently high + uint32_t difficulty=World::Get().GetServerSettings().Difficulty; + if(difficulty > 2 && !pActor->IsDead() && pActor->GetExtension() && !pActor->GetExtension()->IsPlayer()) + { + // Ensure the current player is in the party + if(World::Get().GetPartyService().IsInParty()) + { + float currentHealth=message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kHealth]; + float maxHealth=message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kHealth]; + // Use tolerance for approximate equality comparison, exclude characters with health ending in 7, as 7 indicates the value has already been reset + if(maxHealth >= 100 && std::fabs(currentHealth - maxHealth) <= epsilon && std::fmod(maxHealth, 10) != 7) + { + // Get the current number of party members + size_t size=World::Get().GetPartyService().GetPartyMembers().size(); + if(size > 1) + { + // rounded to two decimal places + double multiple = std::round(std::log(size) / std::log(2) * 100.0) / 100.0; + // Increase difficulty for Legendary mode + if(difficulty == 5) + multiple*=2; + + float newMaxHealth=maxHealth+(maxHealth*multiple); + + // Ensure the units digit of the new health value is 7 + int roundedNewMaxHealth = static_cast(std::round(newMaxHealth)); + int adjustment = (7 - (roundedNewMaxHealth % 10) + 10) % 10; + roundedNewMaxHealth += adjustment; + + newMaxHealth = static_cast(roundedNewMaxHealth); + spdlog::info("Adjust health based on the number of players: {}",newMaxHealth); + // Force set the local value + pActor->ForceActorValue(ActorValueOwner::ForceMode::PERMANENT, ActorValueInfo::kHealth, newMaxHealth); + pActor->ForceActorValue(ActorValueOwner::ForceMode::DAMAGE, ActorValueInfo::kHealth, newMaxHealth); + // Update the broadcasted value + message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kHealth]=newMaxHealth; + message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kHealth]=newMaxHealth; + + // Calculate new stamina value + float currentStamina=message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kStamina]; + float maxStamina=message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kStamina]; + if(maxStamina >= 50 && std::fabs(currentStamina - maxStamina) <= epsilon) + { + // First calculate the floating-point result, then round it directly to an integer + int tempNewMaxStamina = static_cast(maxStamina + (maxStamina * static_cast(multiple * 0.5))); + + int newMaxStamina = tempNewMaxStamina; + + pActor->ForceActorValue(ActorValueOwner::ForceMode::PERMANENT, ActorValueInfo::kStamina, newMaxStamina); + pActor->ForceActorValue(ActorValueOwner::ForceMode::DAMAGE, ActorValueInfo::kStamina, newMaxStamina); + message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kStamina]=newMaxStamina; + message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kStamina]=newMaxStamina; + } + + // Calculate new magicka value + float currentMagicka=message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kMagicka]; + float maxMagicka=message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kMagicka]; + if(maxMagicka >= 50 && std::fabs(currentMagicka - maxMagicka) <= epsilon) + { + // First calculate the floating-point result, then round it directly to an integer + int tempNewMaxMagicka = static_cast(maxMagicka + (maxMagicka * static_cast(multiple * 0.35))); + + int newMaxMagicka = tempNewMaxMagicka; + pActor->ForceActorValue(ActorValueOwner::ForceMode::PERMANENT, ActorValueInfo::kMagicka, newMaxMagicka); + pActor->ForceActorValue(ActorValueOwner::ForceMode::DAMAGE, ActorValueInfo::kMagicka, newMaxMagicka); + message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kMagicka]=newMaxMagicka; + message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kMagicka]=newMaxMagicka; + } + } + } + } + } + message.FactionsContent = pActor->GetFactions(); // TODO: ft, fallout probably uses skycells for those choppers #if TP_SKYRIM64 From 4695b155764de44e3a5df04acbc7b2e9b425b74a Mon Sep 17 00:00:00 2001 From: otsffs <141402668+otsffs@users.noreply.github.com> Date: Sat, 31 Aug 2024 18:39:01 +0800 Subject: [PATCH 2/2] Formatted code --- .../Services/Generic/CharacterService.cpp | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Code/client/Services/Generic/CharacterService.cpp b/Code/client/Services/Generic/CharacterService.cpp index 293f51c32..c7ae331d1 100644 --- a/Code/client/Services/Generic/CharacterService.cpp +++ b/Code/client/Services/Generic/CharacterService.cpp @@ -1216,28 +1216,28 @@ void CharacterService::RequestServerAssignment(const entt::entity aEntity) const constexpr float epsilon = 1e-6; // Only sync living entities, excluding players // Enable only if the difficulty is sufficiently high - uint32_t difficulty=World::Get().GetServerSettings().Difficulty; + uint32_t difficulty = World::Get().GetServerSettings().Difficulty; if(difficulty > 2 && !pActor->IsDead() && pActor->GetExtension() && !pActor->GetExtension()->IsPlayer()) { // Ensure the current player is in the party if(World::Get().GetPartyService().IsInParty()) { - float currentHealth=message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kHealth]; - float maxHealth=message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kHealth]; + float currentHealth = message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kHealth]; + float maxHealth = message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kHealth]; // Use tolerance for approximate equality comparison, exclude characters with health ending in 7, as 7 indicates the value has already been reset if(maxHealth >= 100 && std::fabs(currentHealth - maxHealth) <= epsilon && std::fmod(maxHealth, 10) != 7) { // Get the current number of party members - size_t size=World::Get().GetPartyService().GetPartyMembers().size(); + size_t size = World::Get().GetPartyService().GetPartyMembers().size(); if(size > 1) { // rounded to two decimal places double multiple = std::round(std::log(size) / std::log(2) * 100.0) / 100.0; // Increase difficulty for Legendary mode if(difficulty == 5) - multiple*=2; + multiple *= 2; - float newMaxHealth=maxHealth+(maxHealth*multiple); + float newMaxHealth = maxHealth + (maxHealth * multiple); // Ensure the units digit of the new health value is 7 int roundedNewMaxHealth = static_cast(std::round(newMaxHealth)); @@ -1245,18 +1245,18 @@ void CharacterService::RequestServerAssignment(const entt::entity aEntity) const roundedNewMaxHealth += adjustment; newMaxHealth = static_cast(roundedNewMaxHealth); - spdlog::info("Adjust health based on the number of players: {}",newMaxHealth); + spdlog::info("Adjust health based on the number of players: {}", newMaxHealth); // Force set the local value pActor->ForceActorValue(ActorValueOwner::ForceMode::PERMANENT, ActorValueInfo::kHealth, newMaxHealth); pActor->ForceActorValue(ActorValueOwner::ForceMode::DAMAGE, ActorValueInfo::kHealth, newMaxHealth); // Update the broadcasted value - message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kHealth]=newMaxHealth; - message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kHealth]=newMaxHealth; + message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kHealth] = newMaxHealth; + message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kHealth] = newMaxHealth; // Calculate new stamina value - float currentStamina=message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kStamina]; - float maxStamina=message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kStamina]; - if(maxStamina >= 50 && std::fabs(currentStamina - maxStamina) <= epsilon) + float currentStamina = message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kStamina]; + float maxStamina = message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kStamina]; + if(maxStamina >= 50 && std::fabs(currentStamina - maxStamina) <= epsilon) { // First calculate the floating-point result, then round it directly to an integer int tempNewMaxStamina = static_cast(maxStamina + (maxStamina * static_cast(multiple * 0.5))); @@ -1265,13 +1265,13 @@ void CharacterService::RequestServerAssignment(const entt::entity aEntity) const pActor->ForceActorValue(ActorValueOwner::ForceMode::PERMANENT, ActorValueInfo::kStamina, newMaxStamina); pActor->ForceActorValue(ActorValueOwner::ForceMode::DAMAGE, ActorValueInfo::kStamina, newMaxStamina); - message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kStamina]=newMaxStamina; - message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kStamina]=newMaxStamina; + message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kStamina] = newMaxStamina; + message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kStamina] = newMaxStamina; } // Calculate new magicka value - float currentMagicka=message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kMagicka]; - float maxMagicka=message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kMagicka]; + float currentMagicka = message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kMagicka]; + float maxMagicka = message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kMagicka]; if(maxMagicka >= 50 && std::fabs(currentMagicka - maxMagicka) <= epsilon) { // First calculate the floating-point result, then round it directly to an integer @@ -1280,8 +1280,8 @@ void CharacterService::RequestServerAssignment(const entt::entity aEntity) const int newMaxMagicka = tempNewMaxMagicka; pActor->ForceActorValue(ActorValueOwner::ForceMode::PERMANENT, ActorValueInfo::kMagicka, newMaxMagicka); pActor->ForceActorValue(ActorValueOwner::ForceMode::DAMAGE, ActorValueInfo::kMagicka, newMaxMagicka); - message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kMagicka]=newMaxMagicka; - message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kMagicka]=newMaxMagicka; + message.CurrentActorData.InitialActorValues.ActorMaxValuesList[ActorValueInfo::kMagicka] = newMaxMagicka; + message.CurrentActorData.InitialActorValues.ActorValuesList[ActorValueInfo::kMagicka] = newMaxMagicka; } } }