Merge remote-tracking branch 'upstream/main'

This commit is contained in:
EmosewaMC 2022-12-19 17:59:56 -08:00
commit da07a70d4d
11 changed files with 208 additions and 84 deletions

View File

@ -0,0 +1,21 @@
#pragma once
#ifndef __ECHARACTERVERSION__H__
#define __ECHARACTERVERSION__H__
#include <cstdint>
enum class eCharacterVersion : uint32_t {
// Versions from the live game
RELEASE = 0, // Initial release of the game
LIVE, // Fixes for the 1.9 release bug fixes for missions leading up to joining a faction
// New versions for DLU fixes
// Fixes the "Joined a faction" player flag not being set properly
PLAYER_FACTION_FLAGS,
// Fixes vault size value
VAULT_SIZE,
// Fixes speed base value in level component
UP_TO_DATE, // will become SPEED_BASE
};
#endif //!__ECHARACTERVERSION__H__

View File

@ -769,8 +769,8 @@ no_ghosting:
auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>(); auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>();
auto* levelComponent = GetComponent<LevelProgressionComponent>(); auto* levelComponent = GetComponent<LevelProgressionComponent>();
if (controllablePhysicsComponent != nullptr && levelComponent->GetLevel() >= 20) { if (controllablePhysicsComponent && levelComponent) {
controllablePhysicsComponent->SetSpeedMultiplier(525.0f / 500.0f); controllablePhysicsComponent->SetSpeedMultiplier(levelComponent->GetSpeedBase() / 500.0f);
} }
} }
} }

View File

@ -103,6 +103,7 @@ void Trade::SetAccepted(LWOOBJID participant, bool value) {
} }
Complete(); Complete();
TradingManager::Instance()->CancelTrade(m_TradeId);
} }
} }
@ -121,33 +122,59 @@ void Trade::Complete() {
if (inventoryA == nullptr || inventoryB == nullptr || characterA == nullptr || characterB == nullptr || missionsA == nullptr || missionsB == nullptr) return; if (inventoryA == nullptr || inventoryB == nullptr || characterA == nullptr || characterB == nullptr || missionsA == nullptr || missionsB == nullptr) return;
// First verify both players have the coins and items requested for the trade.
if (characterA->GetCoins() < m_CoinsA || characterB->GetCoins() < m_CoinsB) {
Game::logger->Log("TradingManager", "Possible coin trade cheating attempt! Aborting trade.");
return;
}
for (const auto& tradeItem : m_ItemsA) {
auto* itemToRemove = inventoryA->FindItemById(tradeItem.itemId);
if (itemToRemove) {
if (itemToRemove->GetCount() < tradeItem.itemCount) {
Game::logger->Log("TradingManager", "Possible cheating attempt from %s in trading!!! Aborting trade", characterA->GetName().c_str());
return;
}
} else {
Game::logger->Log("TradingManager", "Possible cheating attempt from %s in trading due to item not being available!!!", characterA->GetName().c_str());
return;
}
}
for (const auto& tradeItem : m_ItemsB) {
auto* itemToRemove = inventoryB->FindItemById(tradeItem.itemId);
if (itemToRemove) {
if (itemToRemove->GetCount() < tradeItem.itemCount) {
Game::logger->Log("TradingManager", "Possible cheating attempt from %s in trading!!! Aborting trade", characterB->GetName().c_str());
return;
}
} else {
Game::logger->Log("TradingManager", "Possible cheating attempt from %s in trading due to item not being available!!! Aborting trade", characterB->GetName().c_str());
return;
}
}
// Now actually do the trade.
characterA->SetCoins(characterA->GetCoins() - m_CoinsA + m_CoinsB, eLootSourceType::LOOT_SOURCE_TRADE); characterA->SetCoins(characterA->GetCoins() - m_CoinsA + m_CoinsB, eLootSourceType::LOOT_SOURCE_TRADE);
characterB->SetCoins(characterB->GetCoins() - m_CoinsB + m_CoinsA, eLootSourceType::LOOT_SOURCE_TRADE); characterB->SetCoins(characterB->GetCoins() - m_CoinsB + m_CoinsA, eLootSourceType::LOOT_SOURCE_TRADE);
for (const auto& tradeItem : m_ItemsA) { for (const auto& tradeItem : m_ItemsA) {
inventoryA->RemoveItem(tradeItem.itemLot, tradeItem.itemCount, INVALID, true); auto* itemToRemove = inventoryA->FindItemById(tradeItem.itemId);
if (itemToRemove) itemToRemove->SetCount(itemToRemove->GetCount() - tradeItem.itemCount);
missionsA->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, tradeItem.itemLot, LWOOBJID_EMPTY, "", -tradeItem.itemCount); missionsA->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, tradeItem.itemLot, LWOOBJID_EMPTY, "", -tradeItem.itemCount);
}
for (const auto& tradeItem : m_ItemsB) {
inventoryB->RemoveItem(tradeItem.itemLot, tradeItem.itemCount, INVALID, true);
missionsB->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, tradeItem.itemLot, LWOOBJID_EMPTY, "", -tradeItem.itemCount);
}
for (const auto& tradeItem : m_ItemsA) {
inventoryB->AddItem(tradeItem.itemLot, tradeItem.itemCount, eLootSourceType::LOOT_SOURCE_TRADE); inventoryB->AddItem(tradeItem.itemLot, tradeItem.itemCount, eLootSourceType::LOOT_SOURCE_TRADE);
} }
for (const auto& tradeItem : m_ItemsB) { for (const auto& tradeItem : m_ItemsB) {
auto* itemToRemove = inventoryB->FindItemById(tradeItem.itemId);
if (itemToRemove) itemToRemove->SetCount(itemToRemove->GetCount() - tradeItem.itemCount);
missionsB->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, tradeItem.itemLot, LWOOBJID_EMPTY, "", -tradeItem.itemCount);
inventoryA->AddItem(tradeItem.itemLot, tradeItem.itemCount, eLootSourceType::LOOT_SOURCE_TRADE); inventoryA->AddItem(tradeItem.itemLot, tradeItem.itemCount, eLootSourceType::LOOT_SOURCE_TRADE);
} }
TradingManager::Instance()->CancelTrade(m_TradeId);
characterA->SaveXMLToDatabase(); characterA->SaveXMLToDatabase();
characterB->SaveXMLToDatabase(); characterB->SaveXMLToDatabase();
return;
} }
void Trade::Cancel() { void Trade::Cancel() {

View File

@ -7,85 +7,44 @@
void SpeedBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { void SpeedBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
if (m_AffectsCaster) { if (m_AffectsCaster) branch.target = context->caster;
branch.target = context->caster;
}
auto* target = EntityManager::Instance()->GetEntity(branch.target); auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (!target) return;
if (target == nullptr) {
return;
}
auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>(); auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return;
if (controllablePhysicsComponent == nullptr) { controllablePhysicsComponent->AddSpeedboost(m_RunSpeed);
return;
}
const auto current = controllablePhysicsComponent->GetSpeedMultiplier();
controllablePhysicsComponent->SetSpeedMultiplier(current + ((m_RunSpeed - 500.0f) / 500.0f));
EntityManager::Instance()->SerializeEntity(target); EntityManager::Instance()->SerializeEntity(target);
if (branch.duration > 0.0f) { if (branch.duration > 0.0f) {
context->RegisterTimerBehavior(this, branch); context->RegisterTimerBehavior(this, branch);
} else if (branch.start > 0) { } else if (branch.start > 0) {
controllablePhysicsComponent->SetIgnoreMultipliers(true);
context->RegisterEndBehavior(this, branch); context->RegisterEndBehavior(this, branch);
} }
} }
void SpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { void SpeedBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* target = EntityManager::Instance()->GetEntity(branch.target); Handle(context, bitStream, branch);
if (target == nullptr) {
return;
}
auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent == nullptr) {
return;
}
const auto current = controllablePhysicsComponent->GetSpeedMultiplier();
controllablePhysicsComponent->SetSpeedMultiplier(current - ((m_RunSpeed - 500.0f) / 500.0f));
EntityManager::Instance()->SerializeEntity(target);
} }
void SpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { void SpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {
auto* target = EntityManager::Instance()->GetEntity(branch.target); auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (!target) return;
if (target == nullptr) {
return;
}
auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>(); auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return;
if (controllablePhysicsComponent == nullptr) { controllablePhysicsComponent->RemoveSpeedboost(m_RunSpeed);
return; EntityManager::Instance()->SerializeEntity(target);
} }
const auto current = controllablePhysicsComponent->GetSpeedMultiplier(); void SpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {
End(context, branch, second);
controllablePhysicsComponent->SetIgnoreMultipliers(false);
controllablePhysicsComponent->SetSpeedMultiplier(current - ((m_RunSpeed - 500.0f) / 500.0f));
EntityManager::Instance()->SerializeEntity(target);
} }
void SpeedBehavior::Load() { void SpeedBehavior::Load() {
m_RunSpeed = GetFloat("run_speed"); m_RunSpeed = GetFloat("run_speed");
if (m_RunSpeed < 500.0f) {
m_RunSpeed = 500.0f;
}
m_AffectsCaster = GetBoolean("affects_caster"); m_AffectsCaster = GetBoolean("affects_caster");
} }

View File

@ -13,6 +13,8 @@ public:
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override;
void End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; void End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override;

View File

@ -12,6 +12,7 @@
#include "EntityManager.h" #include "EntityManager.h"
#include "Character.h" #include "Character.h"
#include "dZoneManager.h" #include "dZoneManager.h"
#include "LevelProgressionComponent.h"
ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Component(entity) { ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Component(entity) {
m_Position = {}; m_Position = {};
@ -73,13 +74,7 @@ void ControllablePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bo
outBitStream->Write0(); //This contains info about immunities, but for now I'm leaving it out. outBitStream->Write0(); //This contains info about immunities, but for now I'm leaving it out.
} }
if (m_SpeedMultiplier < 1.0f) { if (m_IgnoreMultipliers) m_DirtyCheats = false;
m_DirtyCheats = false;
}
if (m_IgnoreMultipliers) {
m_DirtyCheats = false;
}
outBitStream->Write(m_DirtyCheats); outBitStream->Write(m_DirtyCheats);
if (m_DirtyCheats) { if (m_DirtyCheats) {
@ -263,7 +258,7 @@ void ControllablePhysicsComponent::RemovePickupRadiusScale(float value) {
if (pos != m_ActivePickupRadiusScales.end()) { if (pos != m_ActivePickupRadiusScales.end()) {
m_ActivePickupRadiusScales.erase(pos); m_ActivePickupRadiusScales.erase(pos);
} else { } else {
Game::logger->Log("ControllablePhysicsComponent", "Warning: Could not find pickup radius %f in list of active radii. List has %i active radii.", value, m_ActivePickupRadiusScales.size()); Game::logger->LogDebug("ControllablePhysicsComponent", "Warning: Could not find pickup radius %f in list of active radii. List has %i active radii.", value, m_ActivePickupRadiusScales.size());
return; return;
} }
@ -276,3 +271,30 @@ void ControllablePhysicsComponent::RemovePickupRadiusScale(float value) {
} }
EntityManager::Instance()->SerializeEntity(m_Parent); EntityManager::Instance()->SerializeEntity(m_Parent);
} }
void ControllablePhysicsComponent::AddSpeedboost(float value) {
m_ActiveSpeedBoosts.push_back(value);
m_SpeedBoost = value;
SetSpeedMultiplier(value / 500.0f); // 500 being the base speed
}
void ControllablePhysicsComponent::RemoveSpeedboost(float value) {
const auto pos = std::find(m_ActiveSpeedBoosts.begin(), m_ActiveSpeedBoosts.end(), value);
if (pos != m_ActiveSpeedBoosts.end()) {
m_ActiveSpeedBoosts.erase(pos);
} else {
Game::logger->LogDebug("ControllablePhysicsComponent", "Warning: Could not find speedboost %f in list of active speedboosts. List has %i active speedboosts.", value, m_ActiveSpeedBoosts.size());
return;
}
// Recalculate speedboost since we removed one
m_SpeedBoost = 0.0f;
if (m_ActiveSpeedBoosts.size() == 0) { // no active speed boosts left, so return to base speed
auto* levelProgressionComponent = m_Parent->GetComponent<LevelProgressionComponent>();
if (levelProgressionComponent) m_SpeedBoost = levelProgressionComponent->GetSpeedBase();
} else { // Used the last applied speedboost
m_SpeedBoost = m_ActiveSpeedBoosts.back();
}
SetSpeedMultiplier(m_SpeedBoost / 500.0f); // 500 being the base speed
EntityManager::Instance()->SerializeEntity(m_Parent);
}

View File

@ -257,6 +257,13 @@ public:
*/ */
std::vector<float> GetActivePickupRadiusScales() { return m_ActivePickupRadiusScales; }; std::vector<float> GetActivePickupRadiusScales() { return m_ActivePickupRadiusScales; };
void AddSpeedboost(float value);
void RemoveSpeedboost(float value);
std::vector<float> GetActiveSpeedboosts() { return m_ActivePickupRadiusScales; };
private: private:
/** /**
* The entity that owns this component * The entity that owns this component
@ -372,6 +379,16 @@ private:
* If the entity is teleporting * If the entity is teleporting
*/ */
bool m_IsTeleporting; bool m_IsTeleporting;
/**
* The list of speed boosts for this entity
*/
std::vector<float> m_ActiveSpeedBoosts;
/**
* The active speed boost for this entity
*/
float m_SpeedBoost;
}; };
#endif // CONTROLLABLEPHYSICSCOMPONENT_H #endif // CONTROLLABLEPHYSICSCOMPONENT_H

View File

@ -7,6 +7,8 @@
LevelProgressionComponent::LevelProgressionComponent(Entity* parent) : Component(parent) { LevelProgressionComponent::LevelProgressionComponent(Entity* parent) : Component(parent) {
m_Parent = parent; m_Parent = parent;
m_Level = 1; m_Level = 1;
m_SpeedBase = 500.0f;
m_CharacterVersion = eCharacterVersion::LIVE;
} }
void LevelProgressionComponent::UpdateXml(tinyxml2::XMLDocument* doc) { void LevelProgressionComponent::UpdateXml(tinyxml2::XMLDocument* doc) {
@ -16,7 +18,8 @@ void LevelProgressionComponent::UpdateXml(tinyxml2::XMLDocument* doc) {
return; return;
} }
level->SetAttribute("l", m_Level); level->SetAttribute("l", m_Level);
level->SetAttribute("sb", m_SpeedBase);
level->SetAttribute("cv", static_cast<uint32_t>(m_CharacterVersion));
} }
void LevelProgressionComponent::LoadFromXml(tinyxml2::XMLDocument* doc) { void LevelProgressionComponent::LoadFromXml(tinyxml2::XMLDocument* doc) {
@ -26,7 +29,10 @@ void LevelProgressionComponent::LoadFromXml(tinyxml2::XMLDocument* doc) {
return; return;
} }
level->QueryAttribute("l", &m_Level); level->QueryAttribute("l", &m_Level);
level->QueryAttribute("sb", &m_SpeedBase);
uint32_t characterVersion;
level->QueryAttribute("cv", &characterVersion);
m_CharacterVersion = static_cast<eCharacterVersion>(characterVersion);
} }
void LevelProgressionComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { void LevelProgressionComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) {
@ -60,7 +66,8 @@ void LevelProgressionComponent::HandleLevelUp() {
} }
break; break;
case 9: case 9:
controllablePhysicsComponent->SetSpeedMultiplier(static_cast<float>(reward->value) / 500.0f); SetSpeedBase(static_cast<float>(reward->value) );
controllablePhysicsComponent->SetSpeedMultiplier(GetSpeedBase() / 500.0f);
break; break;
case 11: case 11:
case 12: case 12:
@ -72,3 +79,9 @@ void LevelProgressionComponent::HandleLevelUp() {
// Tell the client we have finished sending level rewards. // Tell the client we have finished sending level rewards.
if (rewardingItem) GameMessages::NotifyLevelRewards(m_Parent->GetObjectID(), m_Parent->GetSystemAddress(), m_Level, !rewardingItem); if (rewardingItem) GameMessages::NotifyLevelRewards(m_Parent->GetObjectID(), m_Parent->GetSystemAddress(), m_Level, !rewardingItem);
} }
void LevelProgressionComponent::SetRetroactiveBaseSpeed(){
if (m_Level >= 20) m_SpeedBase = 525.0f;
auto* controllablePhysicsComponent = m_Parent->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent) controllablePhysicsComponent->SetSpeedMultiplier(m_SpeedBase / 500.0f);
}

View File

@ -3,11 +3,13 @@
#include "Entity.h" #include "Entity.h"
#include "GameMessages.h" #include "GameMessages.h"
#include "Component.h" #include "Component.h"
#include "eCharacterVersion.h"
/** /**
* Component that handles level progression and serilization. * Component that handles level progression and serilization.
* *
*/ */
class LevelProgressionComponent : public Component { class LevelProgressionComponent : public Component {
public: public:
static const uint32_t ComponentType = eReplicaComponentType::COMPONENT_TYPE_LEVEL_PROGRESSION; static const uint32_t ComponentType = eReplicaComponentType::COMPONENT_TYPE_LEVEL_PROGRESSION;
@ -44,11 +46,40 @@ public:
*/ */
void SetLevel(uint32_t level) { m_Level = level; m_DirtyLevelInfo = true; } void SetLevel(uint32_t level) { m_Level = level; m_DirtyLevelInfo = true; }
/**
* Gets the current Speed Base of the entity
* @return the current Speed Base of the entity
*/
const uint32_t GetSpeedBase() const { return m_SpeedBase; }
/**
* Sets the Speed Base of the entity
* @param SpeedBase the Speed Base to set
*/
void SetSpeedBase(uint32_t SpeedBase) { m_SpeedBase = SpeedBase; }
/** /**
* Gives the player rewards for the last level that they leveled up from * Gives the player rewards for the last level that they leveled up from
*/ */
void HandleLevelUp(); void HandleLevelUp();
/**
* Gets the current Character Version of the entity
* @return the current Character Version of the entity
*/
const eCharacterVersion GetCharacterVersion() const { return m_CharacterVersion; }
/**
* Sets the Character Version of the entity
* @param CharacterVersion the Character Version to set
*/
void SetCharacterVersion(eCharacterVersion CharacterVersion) { m_CharacterVersion = CharacterVersion; }
/**
* Set the Base Speed retroactively of the entity
*/
void SetRetroactiveBaseSpeed();
private: private:
/** /**
* whether the level is dirty * whether the level is dirty
@ -59,4 +90,15 @@ private:
* Level of the entity * Level of the entity
*/ */
uint32_t m_Level; uint32_t m_Level;
/**
* The base speed of the entity
*/
float m_SpeedBase;
/**
* The Character format version
*/
eCharacterVersion m_CharacterVersion;
}; };

View File

@ -5736,16 +5736,16 @@ void GameMessages::HandleClientItemConsumed(RakNet::BitStream* inStream, Entity*
} }
auto* item = inventory->FindItemById(itemConsumed); auto* item = inventory->FindItemById(itemConsumed);
if (item == nullptr) { if (item == nullptr) {
return; return;
} }
LOT itemLot = item->GetLot();
item->Consume(); item->Consume();
auto* missions = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION)); auto* missions = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION));
if (missions != nullptr) { if (missions != nullptr) {
missions->Progress(MissionTaskType::MISSION_TASK_TYPE_FOOD, item->GetLot()); missions->Progress(MissionTaskType::MISSION_TASK_TYPE_FOOD, itemLot);
} }
} }

View File

@ -56,6 +56,7 @@
#include "Player.h" #include "Player.h"
#include "PropertyManagementComponent.h" #include "PropertyManagementComponent.h"
#include "AssetManager.h" #include "AssetManager.h"
#include "LevelProgressionComponent.h"
#include "eBlueprintSaveResponseType.h" #include "eBlueprintSaveResponseType.h"
#include "ZCompression.h" #include "ZCompression.h"
@ -993,9 +994,29 @@ void HandlePacket(Packet* packet) {
player->GetComponent<CharacterComponent>()->RocketUnEquip(player); player->GetComponent<CharacterComponent>()->RocketUnEquip(player);
} }
c->SetRetroactiveFlags(); // Do charxml fixes here
auto* levelComponent = player->GetComponent<LevelProgressionComponent>();
if (!levelComponent) return;
auto version = levelComponent->GetCharacterVersion();
switch(version) {
case eCharacterVersion::RELEASE:
// TODO: Implement, super low priority
case eCharacterVersion::LIVE:
Game::logger->Log("WorldServer", "Updating Character Flags");
c->SetRetroactiveFlags();
levelComponent->SetCharacterVersion(eCharacterVersion::PLAYER_FACTION_FLAGS);
case eCharacterVersion::PLAYER_FACTION_FLAGS:
Game::logger->Log("WorldServer", "Updating Vault Size");
player->RetroactiveVaultSize(); player->RetroactiveVaultSize();
levelComponent->SetCharacterVersion(eCharacterVersion::VAULT_SIZE);
case eCharacterVersion::VAULT_SIZE:
Game::logger->Log("WorldServer", "Updaing Speedbase");
levelComponent->SetRetroactiveBaseSpeed();
levelComponent->SetCharacterVersion(eCharacterVersion::UP_TO_DATE);
case eCharacterVersion::UP_TO_DATE:
break;
}
player->GetCharacter()->SetTargetScene(""); player->GetCharacter()->SetTargetScene("");