mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-22 05:27:19 +00:00
chore: Assorted pet improvements (#1402)
* Assorted pet improvements * remove unecessary include * updates to address some feedback * fixed database code for testing * Removed reference member (for now) * Removed cmake flag
This commit is contained in:
parent
fbdcc17bb5
commit
4a50c60559
@ -51,7 +51,7 @@ set(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "" FORCE)
|
|||||||
# Disabled no-register
|
# Disabled no-register
|
||||||
# Disabled unknown pragmas because Linux doesn't understand Windows pragmas.
|
# Disabled unknown pragmas because Linux doesn't understand Windows pragmas.
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -fPIC")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wuninitialized -fPIC")
|
||||||
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0 _GLIBCXX_USE_CXX17_ABI=0)
|
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0 _GLIBCXX_USE_CXX17_ABI=0)
|
||||||
|
|
||||||
if(NOT APPLE)
|
if(NOT APPLE)
|
||||||
|
13
dCommon/dEnums/ePetAbilityType.h
Normal file
13
dCommon/dEnums/ePetAbilityType.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef __EPETABILITYTYPE__H__
|
||||||
|
#define __EPETABILITYTYPE__H__
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
enum class ePetAbilityType : uint32_t {
|
||||||
|
Invalid,
|
||||||
|
GoToObject,
|
||||||
|
JumpOnObject,
|
||||||
|
DigAtPosition
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //!__EPETABILITYTYPE__H__
|
@ -4,9 +4,13 @@
|
|||||||
// Static Variables
|
// Static Variables
|
||||||
static CppSQLite3DB* conn = new CppSQLite3DB();
|
static CppSQLite3DB* conn = new CppSQLite3DB();
|
||||||
|
|
||||||
|
// Status Variables
|
||||||
|
bool CDClientDatabase::isConnected = false;
|
||||||
|
|
||||||
//! Opens a connection with the CDClient
|
//! Opens a connection with the CDClient
|
||||||
void CDClientDatabase::Connect(const std::string& filename) {
|
void CDClientDatabase::Connect(const std::string& filename) {
|
||||||
conn->open(filename.c_str());
|
conn->open(filename.c_str());
|
||||||
|
isConnected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Queries the CDClient
|
//! Queries the CDClient
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
|
|
||||||
//! The CDClient Database namespace
|
//! The CDClient Database namespace
|
||||||
namespace CDClientDatabase {
|
namespace CDClientDatabase {
|
||||||
|
/**
|
||||||
|
* Boolean defining the connection status of CDClient
|
||||||
|
*/
|
||||||
|
extern bool isConnected;
|
||||||
|
|
||||||
//! Opens a connection with the CDClient
|
//! Opens a connection with the CDClient
|
||||||
/*!
|
/*!
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "CDAnimationsTable.h"
|
#include "CDAnimationsTable.h"
|
||||||
#include "CDBehaviorParameterTable.h"
|
#include "CDBehaviorParameterTable.h"
|
||||||
#include "CDBehaviorTemplateTable.h"
|
#include "CDBehaviorTemplateTable.h"
|
||||||
|
#include "CDClientDatabase.h"
|
||||||
#include "CDComponentsRegistryTable.h"
|
#include "CDComponentsRegistryTable.h"
|
||||||
#include "CDCurrencyTableTable.h"
|
#include "CDCurrencyTableTable.h"
|
||||||
#include "CDDestructibleComponentTable.h"
|
#include "CDDestructibleComponentTable.h"
|
||||||
@ -39,6 +40,8 @@
|
|||||||
#include "CDRailActivatorComponent.h"
|
#include "CDRailActivatorComponent.h"
|
||||||
#include "CDRewardCodesTable.h"
|
#include "CDRewardCodesTable.h"
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
#ifndef CDCLIENT_CACHE_ALL
|
#ifndef CDCLIENT_CACHE_ALL
|
||||||
// Uncomment this to cache the full cdclient database into memory. This will make the server load faster, but will use more memory.
|
// Uncomment this to cache the full cdclient database into memory. This will make the server load faster, but will use more memory.
|
||||||
// A vanilla CDClient takes about 46MB of memory + the regular world data.
|
// A vanilla CDClient takes about 46MB of memory + the regular world data.
|
||||||
@ -51,7 +54,16 @@
|
|||||||
#define CDCLIENT_DONT_CACHE_TABLE(x)
|
#define CDCLIENT_DONT_CACHE_TABLE(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CDClientManager::CDClientManager() {
|
class CDClientConnectionException : public std::exception {
|
||||||
|
public:
|
||||||
|
virtual const char* what() const throw() {
|
||||||
|
return "CDClientDatabase is not connected!";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void CDClientManager::LoadValuesFromDatabase() {
|
||||||
|
if (!CDClientDatabase::isConnected) throw CDClientConnectionException();
|
||||||
|
|
||||||
CDActivityRewardsTable::Instance().LoadValuesFromDatabase();
|
CDActivityRewardsTable::Instance().LoadValuesFromDatabase();
|
||||||
CDActivitiesTable::Instance().LoadValuesFromDatabase();
|
CDActivitiesTable::Instance().LoadValuesFromDatabase();
|
||||||
CDCLIENT_DONT_CACHE_TABLE(CDAnimationsTable::Instance().LoadValuesFromDatabase());
|
CDCLIENT_DONT_CACHE_TABLE(CDAnimationsTable::Instance().LoadValuesFromDatabase());
|
||||||
@ -79,6 +91,7 @@ CDClientManager::CDClientManager() {
|
|||||||
CDCLIENT_DONT_CACHE_TABLE(CDObjectsTable::Instance().LoadValuesFromDatabase());
|
CDCLIENT_DONT_CACHE_TABLE(CDObjectsTable::Instance().LoadValuesFromDatabase());
|
||||||
CDPhysicsComponentTable::Instance().LoadValuesFromDatabase();
|
CDPhysicsComponentTable::Instance().LoadValuesFromDatabase();
|
||||||
CDPackageComponentTable::Instance().LoadValuesFromDatabase();
|
CDPackageComponentTable::Instance().LoadValuesFromDatabase();
|
||||||
|
CDPetComponentTable::Instance().LoadValuesFromDatabase();
|
||||||
CDProximityMonitorComponentTable::Instance().LoadValuesFromDatabase();
|
CDProximityMonitorComponentTable::Instance().LoadValuesFromDatabase();
|
||||||
CDPropertyEntranceComponentTable::Instance().LoadValuesFromDatabase();
|
CDPropertyEntranceComponentTable::Instance().LoadValuesFromDatabase();
|
||||||
CDPropertyTemplateTable::Instance().LoadValuesFromDatabase();
|
CDPropertyTemplateTable::Instance().LoadValuesFromDatabase();
|
||||||
@ -92,3 +105,9 @@ CDClientManager::CDClientManager() {
|
|||||||
CDVendorComponentTable::Instance().LoadValuesFromDatabase();
|
CDVendorComponentTable::Instance().LoadValuesFromDatabase();
|
||||||
CDZoneTableTable::Instance().LoadValuesFromDatabase();
|
CDZoneTableTable::Instance().LoadValuesFromDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDClientManager::LoadValuesFromDefaults() {
|
||||||
|
LOG("Loading default CDClient tables!");
|
||||||
|
|
||||||
|
CDPetComponentTable::Instance().LoadValuesFromDefaults();
|
||||||
|
}
|
||||||
|
@ -11,7 +11,10 @@
|
|||||||
*/
|
*/
|
||||||
class CDClientManager : public Singleton<CDClientManager> {
|
class CDClientManager : public Singleton<CDClientManager> {
|
||||||
public:
|
public:
|
||||||
CDClientManager();
|
CDClientManager() = default;
|
||||||
|
|
||||||
|
void LoadValuesFromDatabase();
|
||||||
|
void LoadValuesFromDefaults();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch a table from CDClient
|
* Fetch a table from CDClient
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
#include "CDPetComponentTable.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// Default entries for fallback
|
||||||
|
CDPetComponent defaultEntry{
|
||||||
|
.id = 0,
|
||||||
|
UNUSED_ENTRY(.minTameUpdateTime = 60.0f,)
|
||||||
|
UNUSED_ENTRY(.maxTameUpdateTime = 300.0f,)
|
||||||
|
UNUSED_ENTRY(.percentTameChance = 101.0f,)
|
||||||
|
UNUSED_ENTRY(.tameability = 100.0f,)
|
||||||
|
UNUSED_ENTRY(.elementType = 1,)
|
||||||
|
.walkSpeed = 2.5f,
|
||||||
|
.runSpeed = 5.0f,
|
||||||
|
.sprintSpeed = 10.0f,
|
||||||
|
UNUSED_ENTRY(.idleTimeMin = 60.0f,)
|
||||||
|
UNUSED_ENTRY(.idleTimeMax = 300.0f,)
|
||||||
|
UNUSED_ENTRY(.petForm = 0,)
|
||||||
|
.imaginationDrainRate = 60.0f,
|
||||||
|
UNUSED_ENTRY(.AudioMetaEventSet = "",)
|
||||||
|
UNUSED_ENTRY(.buffIDs = "",)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDPetComponentTable::LoadValuesFromDatabase() {
|
||||||
|
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PetComponent");
|
||||||
|
while (!tableData.eof()) {
|
||||||
|
const uint32_t componentID = tableData.getIntField("id", defaultEntry.id);
|
||||||
|
|
||||||
|
auto& entry = m_Entries[componentID];
|
||||||
|
entry.id = componentID;
|
||||||
|
UNUSED_COLUMN(entry.minTameUpdateTime = tableData.getFloatField("minTameUpdateTime", defaultEntry.minTameUpdateTime));
|
||||||
|
UNUSED_COLUMN(entry.maxTameUpdateTime = tableData.getFloatField("maxTameUpdateTime", defaultEntry.maxTameUpdateTime));
|
||||||
|
UNUSED_COLUMN(entry.percentTameChance = tableData.getFloatField("percentTameChance", defaultEntry.percentTameChance));
|
||||||
|
UNUSED_COLUMN(entry.tameability = tableData.getFloatField("tamability", defaultEntry.tameability)); // Mispelled as "tamability" in CDClient
|
||||||
|
UNUSED_COLUMN(entry.elementType = tableData.getIntField("elementType", defaultEntry.elementType));
|
||||||
|
entry.walkSpeed = static_cast<float>(tableData.getFloatField("walkSpeed", defaultEntry.walkSpeed));
|
||||||
|
entry.runSpeed = static_cast<float>(tableData.getFloatField("runSpeed", defaultEntry.runSpeed));
|
||||||
|
entry.sprintSpeed = static_cast<float>(tableData.getFloatField("sprintSpeed", defaultEntry.sprintSpeed));
|
||||||
|
UNUSED_COLUMN(entry.idleTimeMin = tableData.getFloatField("idleTimeMin", defaultEntry.idleTimeMin));
|
||||||
|
UNUSED_COLUMN(entry.idleTimeMax = tableData.getFloatField("idleTimeMax", defaultEntry.idleTimeMax));
|
||||||
|
UNUSED_COLUMN(entry.petForm = tableData.getIntField("petForm", defaultEntry.petForm));
|
||||||
|
entry.imaginationDrainRate = static_cast<float>(tableData.getFloatField("imaginationDrainRate", defaultEntry.imaginationDrainRate));
|
||||||
|
UNUSED_COLUMN(entry.AudioMetaEventSet = tableData.getStringField("AudioMetaEventSet", defaultEntry.AudioMetaEventSet));
|
||||||
|
UNUSED_COLUMN(entry.buffIDs = tableData.getStringField("buffIDs", defaultEntry.buffIDs));
|
||||||
|
|
||||||
|
tableData.nextRow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDPetComponentTable::LoadValuesFromDefaults() {
|
||||||
|
m_Entries.insert(std::make_pair(defaultEntry.id, defaultEntry));
|
||||||
|
}
|
||||||
|
|
||||||
|
CDPetComponent& CDPetComponentTable::GetByID(const uint32_t componentID) {
|
||||||
|
auto itr = m_Entries.find(componentID);
|
||||||
|
if (itr == m_Entries.end()) {
|
||||||
|
LOG("Unable to load pet component (ID %i) values from database! Using default values instead.", componentID);
|
||||||
|
return defaultEntry;
|
||||||
|
}
|
||||||
|
return itr->second;
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "CDTable.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct CDPetComponent {
|
||||||
|
uint32_t id;
|
||||||
|
UNUSED_COLUMN(float minTameUpdateTime;)
|
||||||
|
UNUSED_COLUMN(float maxTameUpdateTime;)
|
||||||
|
UNUSED_COLUMN(float percentTameChance;)
|
||||||
|
UNUSED_COLUMN(float tameability;) // Mispelled as "tamability" in CDClient
|
||||||
|
UNUSED_COLUMN(uint32_t elementType;)
|
||||||
|
float walkSpeed;
|
||||||
|
float runSpeed;
|
||||||
|
float sprintSpeed;
|
||||||
|
UNUSED_COLUMN(float idleTimeMin;)
|
||||||
|
UNUSED_COLUMN(float idleTimeMax;)
|
||||||
|
UNUSED_COLUMN(uint32_t petForm;)
|
||||||
|
float imaginationDrainRate;
|
||||||
|
UNUSED_COLUMN(std::string AudioMetaEventSet;)
|
||||||
|
UNUSED_COLUMN(std::string buffIDs;)
|
||||||
|
};
|
||||||
|
|
||||||
|
class CDPetComponentTable : public CDTable<CDPetComponentTable> {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load values from the CD client database
|
||||||
|
*/
|
||||||
|
void LoadValuesFromDatabase();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the default values into memory instead of attempting to connect to the CD client database
|
||||||
|
*/
|
||||||
|
void LoadValuesFromDefaults();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the pet component table corresponding to the pet component ID
|
||||||
|
* @returns A reference to the corresponding table, or the default if one could not be found
|
||||||
|
*/
|
||||||
|
CDPetComponent& GetByID(const uint32_t componentID);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<uint32_t, CDPetComponent> m_Entries;
|
||||||
|
};
|
@ -23,6 +23,9 @@
|
|||||||
// Enable this to skip some unused columns in some tables
|
// Enable this to skip some unused columns in some tables
|
||||||
#define UNUSED_COLUMN(v)
|
#define UNUSED_COLUMN(v)
|
||||||
|
|
||||||
|
// Use this to skip unused defaults for unused entries in some tables
|
||||||
|
#define UNUSED_ENTRY(v, x)
|
||||||
|
|
||||||
#pragma warning (disable : 4244) //Disable double to float conversion warnings
|
#pragma warning (disable : 4244) //Disable double to float conversion warnings
|
||||||
#pragma warning (disable : 4715) //Disable "not all control paths return a value"
|
#pragma warning (disable : 4715) //Disable "not all control paths return a value"
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ set(DDATABASE_CDCLIENTDATABASE_CDCLIENTTABLES_SOURCES "CDActivitiesTable.cpp"
|
|||||||
"CDMovementAIComponentTable.cpp"
|
"CDMovementAIComponentTable.cpp"
|
||||||
"CDObjectSkillsTable.cpp"
|
"CDObjectSkillsTable.cpp"
|
||||||
"CDObjectsTable.cpp"
|
"CDObjectsTable.cpp"
|
||||||
|
"CDPetComponentTable.cpp"
|
||||||
"CDPackageComponentTable.cpp"
|
"CDPackageComponentTable.cpp"
|
||||||
"CDPhysicsComponentTable.cpp"
|
"CDPhysicsComponentTable.cpp"
|
||||||
"CDPropertyEntranceComponentTable.cpp"
|
"CDPropertyEntranceComponentTable.cpp"
|
||||||
|
@ -34,7 +34,6 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id):
|
|||||||
m_MovementAI = nullptr;
|
m_MovementAI = nullptr;
|
||||||
m_Disabled = false;
|
m_Disabled = false;
|
||||||
m_SkillEntries = {};
|
m_SkillEntries = {};
|
||||||
m_MovementAI = nullptr;
|
|
||||||
m_SoftTimer = 5.0f;
|
m_SoftTimer = 5.0f;
|
||||||
|
|
||||||
//Grab the aggro information from BaseCombatAI:
|
//Grab the aggro information from BaseCombatAI:
|
||||||
|
@ -69,7 +69,8 @@ std::map<LOT, int32_t> PetComponent::petFlags = {
|
|||||||
{ 13067, 838 }, // Skeleton dragon
|
{ 13067, 838 }, // Skeleton dragon
|
||||||
};
|
};
|
||||||
|
|
||||||
PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(parent) {
|
PetComponent::PetComponent(Entity* parentEntity, uint32_t componentId) : Component{ parentEntity } {
|
||||||
|
m_PetInfo = CDClientManager::Instance().GetTable<CDPetComponentTable>()->GetByID(componentId); // TODO: Make reference when safe
|
||||||
m_ComponentId = componentId;
|
m_ComponentId = componentId;
|
||||||
|
|
||||||
m_Interaction = LWOOBJID_EMPTY;
|
m_Interaction = LWOOBJID_EMPTY;
|
||||||
@ -81,31 +82,17 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare
|
|||||||
m_TimerAway = 0;
|
m_TimerAway = 0;
|
||||||
m_DatabaseId = LWOOBJID_EMPTY;
|
m_DatabaseId = LWOOBJID_EMPTY;
|
||||||
m_Status = 67108866; // Tamable
|
m_Status = 67108866; // Tamable
|
||||||
m_Ability = PetAbilityType::Invalid;
|
m_Ability = ePetAbilityType::Invalid;
|
||||||
m_StartPosition = NiPoint3::ZERO;
|
m_StartPosition = NiPoint3::ZERO;
|
||||||
m_MovementAI = nullptr;
|
m_MovementAI = nullptr;
|
||||||
m_TresureTime = 0;
|
m_TresureTime = 0;
|
||||||
m_Preconditions = nullptr;
|
m_Preconditions = nullptr;
|
||||||
|
|
||||||
std::string checkPreconditions = GeneralUtils::UTF16ToWTF8(parent->GetVar<std::u16string>(u"CheckPrecondition"));
|
std::string checkPreconditions = GeneralUtils::UTF16ToWTF8(parentEntity->GetVar<std::u16string>(u"CheckPrecondition"));
|
||||||
|
|
||||||
if (!checkPreconditions.empty()) {
|
if (!checkPreconditions.empty()) {
|
||||||
SetPreconditions(checkPreconditions);
|
SetPreconditions(checkPreconditions);
|
||||||
}
|
}
|
||||||
// Get the imagination drain rate from the CDClient
|
|
||||||
auto query = CDClientDatabase::CreatePreppedStmt("SELECT imaginationDrainRate FROM PetComponent WHERE id = ?;");
|
|
||||||
|
|
||||||
query.bind(1, static_cast<int>(componentId));
|
|
||||||
|
|
||||||
auto result = query.execQuery();
|
|
||||||
|
|
||||||
// Should a result not exist for this pet default to 60 seconds.
|
|
||||||
if (!result.eof() && !result.fieldIsNull(0)) {
|
|
||||||
imaginationDrainRate = result.getFloatField(0, 60.0f);
|
|
||||||
} else {
|
|
||||||
imaginationDrainRate = 60.0f;
|
|
||||||
}
|
|
||||||
result.finalize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
void PetComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||||
@ -114,7 +101,7 @@ void PetComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpd
|
|||||||
outBitStream->Write1(); // Always serialize as dirty for now
|
outBitStream->Write1(); // Always serialize as dirty for now
|
||||||
|
|
||||||
outBitStream->Write<uint32_t>(m_Status);
|
outBitStream->Write<uint32_t>(m_Status);
|
||||||
outBitStream->Write(tamed ? m_Ability : PetAbilityType::Invalid); // Something with the overhead icon?
|
outBitStream->Write(tamed ? m_Ability : ePetAbilityType::Invalid); // Something with the overhead icon?
|
||||||
|
|
||||||
const bool interacting = m_Interaction != LWOOBJID_EMPTY;
|
const bool interacting = m_Interaction != LWOOBJID_EMPTY;
|
||||||
|
|
||||||
@ -835,11 +822,11 @@ void PetComponent::Wander() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_MovementAI->SetMaxSpeed(info.wanderSpeed);
|
m_MovementAI->SetMaxSpeed(m_PetInfo.sprintSpeed);
|
||||||
|
|
||||||
m_MovementAI->SetDestination(destination);
|
m_MovementAI->SetDestination(destination);
|
||||||
|
|
||||||
m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / info.wanderSpeed;
|
m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / m_PetInfo.sprintSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
|
void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
|
||||||
@ -905,8 +892,6 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
|
|||||||
|
|
||||||
GameMessages::SendRegisterPetDBID(m_Owner, m_DatabaseId, owner->GetSystemAddress());
|
GameMessages::SendRegisterPetDBID(m_Owner, m_DatabaseId, owner->GetSystemAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
GameMessages::SendShowPetActionButton(m_Owner, 3, true, owner->GetSystemAddress());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) {
|
void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) {
|
||||||
@ -928,7 +913,7 @@ void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) {
|
|||||||
if (!fromTaming) playerDestroyableComponent->Imagine(-1);
|
if (!fromTaming) playerDestroyableComponent->Imagine(-1);
|
||||||
|
|
||||||
// Set this to a variable so when this is called back from the player the timer doesn't fire off.
|
// Set this to a variable so when this is called back from the player the timer doesn't fire off.
|
||||||
m_Parent->AddCallbackTimer(imaginationDrainRate, [playerDestroyableComponent, this, item]() {
|
m_Parent->AddCallbackTimer(m_PetInfo.imaginationDrainRate, [playerDestroyableComponent, this, item]() {
|
||||||
if (!playerDestroyableComponent) {
|
if (!playerDestroyableComponent) {
|
||||||
LOG("No petComponent and/or no playerDestroyableComponent");
|
LOG("No petComponent and/or no playerDestroyableComponent");
|
||||||
return;
|
return;
|
||||||
@ -966,7 +951,7 @@ void PetComponent::Deactivate() {
|
|||||||
|
|
||||||
GameMessages::SendRegisterPetDBID(m_Owner, LWOOBJID_EMPTY, owner->GetSystemAddress());
|
GameMessages::SendRegisterPetDBID(m_Owner, LWOOBJID_EMPTY, owner->GetSystemAddress());
|
||||||
|
|
||||||
GameMessages::SendShowPetActionButton(m_Owner, 0, false, owner->GetSystemAddress());
|
GameMessages::SendShowPetActionButton(m_Owner, ePetAbilityType::Invalid, false, owner->GetSystemAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetComponent::Release() {
|
void PetComponent::Release() {
|
||||||
@ -985,12 +970,9 @@ void PetComponent::Release() {
|
|||||||
item->SetCount(0, false, false);
|
item->SetCount(0, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetComponent::Command(NiPoint3 position, LWOOBJID source, int32_t commandType, int32_t typeId, bool overrideObey) {
|
void PetComponent::Command(const NiPoint3& position, const LWOOBJID source, const int32_t commandType, const int32_t typeId, const bool overrideObey) {
|
||||||
auto* owner = GetOwner();
|
auto* owner = GetOwner();
|
||||||
|
if (!owner) return;
|
||||||
if (owner == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (commandType == 1) {
|
if (commandType == 1) {
|
||||||
// Emotes
|
// Emotes
|
||||||
@ -1030,7 +1012,7 @@ uint32_t PetComponent::GetStatus() const {
|
|||||||
return m_Status;
|
return m_Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
PetAbilityType PetComponent::GetAbility() const {
|
ePetAbilityType PetComponent::GetAbility() const {
|
||||||
return m_Ability;
|
return m_Ability;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1042,7 +1024,7 @@ void PetComponent::SetStatus(uint32_t value) {
|
|||||||
m_Status = value;
|
m_Status = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetComponent::SetAbility(PetAbilityType value) {
|
void PetComponent::SetAbility(ePetAbilityType value) {
|
||||||
m_Ability = value;
|
m_Ability = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,13 @@
|
|||||||
#pragma once
|
#ifndef PETCOMPONENT_H
|
||||||
|
#define PETCOMPONENT_H
|
||||||
|
|
||||||
#include "Entity.h"
|
#include "Entity.h"
|
||||||
#include "MovementAIComponent.h"
|
#include "MovementAIComponent.h"
|
||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
#include "Preconditions.h"
|
#include "Preconditions.h"
|
||||||
|
#include "ePetAbilityType.h"
|
||||||
#include "eReplicaComponentType.h"
|
#include "eReplicaComponentType.h"
|
||||||
|
#include "CDPetComponentTable.h"
|
||||||
enum class PetAbilityType : uint32_t
|
|
||||||
{
|
|
||||||
Invalid,
|
|
||||||
GoToObject,
|
|
||||||
JumpOnObject,
|
|
||||||
DigAtPosition
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an entity that is a pet. This pet can be tamed and consequently follows the tamer around, allowing it
|
* Represents an entity that is a pet. This pet can be tamed and consequently follows the tamer around, allowing it
|
||||||
@ -103,7 +98,7 @@ public:
|
|||||||
* @param typeId extra information about the command, e.g. the emote to play
|
* @param typeId extra information about the command, e.g. the emote to play
|
||||||
* @param overrideObey unused
|
* @param overrideObey unused
|
||||||
*/
|
*/
|
||||||
void Command(NiPoint3 position, LWOOBJID source, int32_t commandType, int32_t typeId, bool overrideObey);
|
void Command(const NiPoint3& position, const LWOOBJID source, const int32_t commandType, const int32_t typeId, const bool overrideObey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ID of the owner of this pet (if any)
|
* Returns the ID of the owner of this pet (if any)
|
||||||
@ -158,13 +153,13 @@ public:
|
|||||||
* Returns an ability the pet may perform, currently unused
|
* Returns an ability the pet may perform, currently unused
|
||||||
* @return an ability the pet may perform
|
* @return an ability the pet may perform
|
||||||
*/
|
*/
|
||||||
PetAbilityType GetAbility() const;
|
ePetAbilityType GetAbility() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the ability of the pet, currently unused
|
* Sets the ability of the pet, currently unused
|
||||||
* @param value the ability to set
|
* @param value the ability to set
|
||||||
*/
|
*/
|
||||||
void SetAbility(PetAbilityType value);
|
void SetAbility(ePetAbilityType value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets preconditions for the pet that need to be met before it can be tamed
|
* Sets preconditions for the pet that need to be met before it can be tamed
|
||||||
@ -323,7 +318,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* A currently active ability, mostly unused
|
* A currently active ability, mostly unused
|
||||||
*/
|
*/
|
||||||
PetAbilityType m_Ability;
|
ePetAbilityType m_Ability;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time an entity has left to complete the minigame
|
* The time an entity has left to complete the minigame
|
||||||
@ -357,7 +352,10 @@ private:
|
|||||||
PreconditionExpression* m_Preconditions;
|
PreconditionExpression* m_Preconditions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The rate at which imagination is drained from the user for having the pet out.
|
* Pet information loaded from the CDClientDatabase
|
||||||
|
* TODO: Switch to a reference when safe to do so
|
||||||
*/
|
*/
|
||||||
float imaginationDrainRate;
|
CDPetComponent m_PetInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // !PETCOMPONENT_H
|
||||||
|
@ -94,6 +94,7 @@
|
|||||||
#include "eReplicaComponentType.h"
|
#include "eReplicaComponentType.h"
|
||||||
#include "eClientMessageType.h"
|
#include "eClientMessageType.h"
|
||||||
#include "eGameMessageType.h"
|
#include "eGameMessageType.h"
|
||||||
|
#include "ePetAbilityType.h"
|
||||||
#include "ActivityManager.h"
|
#include "ActivityManager.h"
|
||||||
|
|
||||||
#include "CDComponentsRegistryTable.h"
|
#include "CDComponentsRegistryTable.h"
|
||||||
@ -3516,14 +3517,14 @@ void GameMessages::SendClientExitTamingMinigame(LWOOBJID objectId, bool bVolunta
|
|||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameMessages::SendShowPetActionButton(LWOOBJID objectId, int32_t buttonLabel, bool bShow, const SystemAddress& sysAddr) {
|
void GameMessages::SendShowPetActionButton(const LWOOBJID objectId, const ePetAbilityType petAbility, const bool bShow, const SystemAddress& sysAddr) {
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
CMSGHEADER;
|
CMSGHEADER;
|
||||||
|
|
||||||
bitStream.Write(objectId);
|
bitStream.Write(objectId);
|
||||||
bitStream.Write(eGameMessageType::SHOW_PET_ACTION_BUTTON);
|
bitStream.Write(eGameMessageType::SHOW_PET_ACTION_BUTTON);
|
||||||
|
|
||||||
bitStream.Write(buttonLabel);
|
bitStream.Write(petAbility);
|
||||||
bitStream.Write(bShow);
|
bitStream.Write(bShow);
|
||||||
|
|
||||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||||
|
@ -32,6 +32,7 @@ enum class eObjectWorldState : uint32_t;
|
|||||||
enum class eTerminateType : uint32_t;
|
enum class eTerminateType : uint32_t;
|
||||||
enum class eControlScheme : uint32_t;
|
enum class eControlScheme : uint32_t;
|
||||||
enum class eStateChangeType : uint32_t;
|
enum class eStateChangeType : uint32_t;
|
||||||
|
enum class ePetAbilityType : uint32_t;
|
||||||
enum class ePetTamingNotifyType : uint32_t;
|
enum class ePetTamingNotifyType : uint32_t;
|
||||||
enum class eUseItemResponse : uint32_t;
|
enum class eUseItemResponse : uint32_t;
|
||||||
enum class eQuickBuildFailReason : uint32_t;
|
enum class eQuickBuildFailReason : uint32_t;
|
||||||
@ -386,7 +387,7 @@ namespace GameMessages {
|
|||||||
|
|
||||||
void SendClientExitTamingMinigame(LWOOBJID objectId, bool bVoluntaryExit, const SystemAddress& sysAddr);
|
void SendClientExitTamingMinigame(LWOOBJID objectId, bool bVoluntaryExit, const SystemAddress& sysAddr);
|
||||||
|
|
||||||
void SendShowPetActionButton(LWOOBJID objectId, int32_t buttonLabel, bool bShow, const SystemAddress& sysAddr);
|
void SendShowPetActionButton(const LWOOBJID objectId, const ePetAbilityType petAbility, const bool bShow, const SystemAddress& sysAddr);
|
||||||
|
|
||||||
void SendPlayEmote(LWOOBJID objectId, int32_t emoteID, LWOOBJID target, const SystemAddress& sysAddr);
|
void SendPlayEmote(LWOOBJID objectId, int32_t emoteID, LWOOBJID target, const SystemAddress& sysAddr);
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ int main(int argc, char** argv) {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDClientManager::Instance();
|
CDClientManager::Instance().LoadValuesFromDatabase();
|
||||||
|
|
||||||
Diagnostics::SetProduceMemoryDump(Game::config->GetValue("generate_dump") == "1");
|
Diagnostics::SetProduceMemoryDump(Game::config->GetValue("generate_dump") == "1");
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "dServer.h"
|
#include "dServer.h"
|
||||||
|
#include "CDClientManager.h"
|
||||||
#include "EntityInfo.h"
|
#include "EntityInfo.h"
|
||||||
#include "EntityManager.h"
|
#include "EntityManager.h"
|
||||||
#include "dConfig.h"
|
#include "dConfig.h"
|
||||||
@ -33,6 +34,9 @@ protected:
|
|||||||
Game::server = new dServerMock();
|
Game::server = new dServerMock();
|
||||||
Game::config = new dConfig("worldconfig.ini");
|
Game::config = new dConfig("worldconfig.ini");
|
||||||
Game::entityManager = new EntityManager();
|
Game::entityManager = new EntityManager();
|
||||||
|
|
||||||
|
// Create a CDClientManager instance and load from defaults
|
||||||
|
CDClientManager::Instance().LoadValuesFromDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TearDownDependencies() {
|
void TearDownDependencies() {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
set(DCOMPONENTS_TESTS
|
set(DCOMPONENTS_TESTS
|
||||||
"DestroyableComponentTests.cpp"
|
"DestroyableComponentTests.cpp"
|
||||||
|
"PetComponentTests.cpp"
|
||||||
"SimplePhysicsComponentTests.cpp"
|
"SimplePhysicsComponentTests.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
43
tests/dGameTests/dComponentsTests/PetComponentTests.cpp
Normal file
43
tests/dGameTests/dComponentsTests/PetComponentTests.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include "GameDependencies.h"
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "BitStream.h"
|
||||||
|
#include "PetComponent.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "eReplicaComponentType.h"
|
||||||
|
#include "ePetAbilityType.h"
|
||||||
|
#include "eStateChangeType.h"
|
||||||
|
|
||||||
|
class PetTest : public GameDependenciesTest {
|
||||||
|
protected:
|
||||||
|
Entity* baseEntity;
|
||||||
|
PetComponent* petComponent;
|
||||||
|
CBITSTREAM
|
||||||
|
|
||||||
|
void SetUp() override {
|
||||||
|
SetUpDependencies();
|
||||||
|
|
||||||
|
// Set up entity and pet component
|
||||||
|
baseEntity = new Entity(15, GameDependenciesTest::info);
|
||||||
|
petComponent = baseEntity->AddComponent<PetComponent>(1);
|
||||||
|
|
||||||
|
// Initialize some values to be not default
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown() override {
|
||||||
|
delete baseEntity;
|
||||||
|
TearDownDependencies();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(PetTest, PlacementNewAddComponentTest) {
|
||||||
|
// Test adding component
|
||||||
|
ASSERT_NE(petComponent, nullptr);
|
||||||
|
baseEntity->AddComponent<PetComponent>(1);
|
||||||
|
ASSERT_NE(baseEntity->GetComponent<PetComponent>(), nullptr);
|
||||||
|
|
||||||
|
// Test getting initial status
|
||||||
|
ASSERT_EQ(petComponent->GetParent()->GetObjectID(), 15);
|
||||||
|
ASSERT_EQ(petComponent->GetAbility(), ePetAbilityType::Invalid);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user