Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Make pets behave more accurately to Live #1305

Draft
wants to merge 100 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
8270e0e
Working on pet bouncers
jadebenn Nov 18, 2023
a58ffcc
Merge branch 'DarkflameUniverse:main' into PetDigAnimFix
jadebenn Nov 18, 2023
5734ef8
initial dig functionality; need to clean up kruft
jadebenn Nov 19, 2023
a76ddd9
cleaned up kruft
jadebenn Nov 19, 2023
fc1ff50
Merge branch 'DarkflameUniverse:main' into PetFixes
jadebenn Nov 19, 2023
bd6f9a7
added imagination cost to digs
jadebenn Nov 19, 2023
76d3187
actually check if the player can afford to dig
jadebenn Nov 19, 2023
c8b624c
minor changes
jadebenn Nov 19, 2023
9b9b5bc
Merge branch 'DarkflameUniverse:main' into PetFixes
jadebenn Nov 19, 2023
e835eb3
Fixed pet emotes not playing
jadebenn Nov 19, 2023
81a54e7
Merge branch 'PetFixes' of https://github.com/jadebenn/DarkflameServe…
jadebenn Nov 19, 2023
23664c0
updated pet command functionality
jadebenn Nov 19, 2023
81d8c18
mission fix redo
jadebenn Nov 22, 2023
57a1c05
update loop cleanup
jadebenn Nov 22, 2023
1a6fb89
Merge branch 'DarkflameUniverse:main' into PetFixes
jadebenn Nov 22, 2023
74047bc
Working on pet bouncers
jadebenn Nov 18, 2023
119968a
initial dig functionality; need to clean up kruft
jadebenn Nov 19, 2023
86abbc1
cleaned up kruft
jadebenn Nov 19, 2023
b3762da
added imagination cost to digs
jadebenn Nov 19, 2023
e73b2bf
actually check if the player can afford to dig
jadebenn Nov 19, 2023
3f1f51f
minor changes
jadebenn Nov 19, 2023
1a74ed6
Fixed pet emotes not playing
jadebenn Nov 19, 2023
cb65de6
updated pet command functionality
jadebenn Nov 19, 2023
3f1468e
mission fix redo
jadebenn Nov 22, 2023
e4b3e22
update loop cleanup
jadebenn Nov 22, 2023
c598b57
Merge branch 'PetFixes' of https://github.com/jadebenn/DarkflameServe…
jadebenn Nov 25, 2023
55f857b
Merge branch 'DarkflameUniverse:main' into PetFixes
jadebenn Nov 25, 2023
93592c7
Merge branch 'DarkflameUniverse:main' into PetFixes
jadebenn Dec 10, 2023
1c01219
added some pet debug commands
jadebenn Dec 10, 2023
200d679
redone pet update loop
jadebenn Dec 11, 2023
5b738df
Further redid pet update loop
jadebenn Dec 12, 2023
a99f7a7
Re-implemented treasure dig handling
jadebenn Dec 13, 2023
68df8af
capitalization
jadebenn Dec 13, 2023
fd5ea75
added bone dragon treasure dig handling
jadebenn Dec 13, 2023
291fc83
added bone dragon treasure dig handling
jadebenn Dec 13, 2023
775e4fe
change AND priority
jadebenn Dec 13, 2023
2a4cfe3
function rename
jadebenn Dec 13, 2023
1b8f10f
added treasure dig menu prompts and help messages
jadebenn Dec 14, 2023
9953255
Update GameMessages.h
jadebenn Dec 14, 2023
2db76ae
Update GameMessages.cpp
jadebenn Dec 14, 2023
8f19aa9
minor gm formatting fix
jadebenn Dec 14, 2023
f5ca142
Update PetStatus enum to prep for bitset use
jadebenn Dec 14, 2023
668bebf
adding new pet flags
jadebenn Dec 15, 2023
054371d
added new pet bitflag system
jadebenn Dec 15, 2023
e01fbfc
restored header guards
jadebenn Dec 15, 2023
9add2c9
PetFlag system now functioning correctly
jadebenn Dec 15, 2023
1c7ce6e
updated CDClient pet data handling
jadebenn Dec 16, 2023
cecf065
Changed how pet data is loaded
jadebenn Dec 16, 2023
60e4813
Merge branch 'DarkflameUniverse:main' into PetFixes
jadebenn Dec 17, 2023
8c97271
Update treasure behavior
jadebenn Dec 17, 2023
b8449a1
Merge branch 'PetFixes' of https://github.com/jadebenn/DarkflameServe…
jadebenn Dec 17, 2023
2d3e03a
pet following and flag behavior improvements
jadebenn Dec 17, 2023
c6df078
comment cleanup
jadebenn Dec 17, 2023
60b3f3c
Merge branch 'main' into PetFixes
Dec 27, 2023
d7d5202
Merge branch 'DarkflameUniverse:main' into PetFixes
jadebenn Dec 27, 2023
6edd42d
pet bouncer minimum functionality
Dec 28, 2023
a4f0602
Merge branch 'main' into PetFixes
Dec 28, 2023
5f8f200
pet bouncers now bounce player upon pressing shift
Dec 28, 2023
b83e1bf
some further bouncer refinements
Dec 29, 2023
1ee5b64
Update PetComponent.h
jadebenn Jan 1, 2024
17753c5
Update PetComponent.h
jadebenn Jan 1, 2024
d5a0b71
Update PetComponent.cpp
jadebenn Jan 1, 2024
9a35aad
Merge branch 'DarkflameUniverse:main' into PetFixes
jadebenn Jan 1, 2024
c575fd9
Merge branch 'DarkflameUniverse:main' into PetFixes
jadebenn Jan 5, 2024
384083e
use reference instead of pointer for cdclient data
jadebenn Jan 5, 2024
0f365e0
Merge branch 'DarkflameUniverse:main' into PetFixes
jadebenn Jan 5, 2024
6c3c08c
Added fallback to default values if CDClient data cannot be loaded
jadebenn Jan 5, 2024
20d6820
Merge branch 'main' into PetFixes
jadebenn Jan 6, 2024
06d5a27
Merge branch 'DarkflameUniverse:main' into PetFixes
jadebenn Jan 6, 2024
d6321a6
Merge remote-tracking branch 'upstream/main' into PetFixes
jadebenn Feb 14, 2024
70e0cd6
more merge
jadebenn Feb 14, 2024
a449e53
delete unused functions and update documentation
jadebenn Mar 4, 2024
1c1b733
Merge remote-tracking branch 'upstream/main' into PetFixes
jadebenn Mar 4, 2024
c36bc83
fix pet taming minigame countdown
jadebenn Mar 4, 2024
9ec028b
Merge remote-tracking branch 'upstream/main' into PetFixes
jadebenn Mar 6, 2024
4791b31
use class enums
jadebenn Mar 6, 2024
9a9254b
Merge remote-tracking branch 'upstream/main' into PetFixes
jadebenn Mar 8, 2024
e832dfb
add most pet messages
jadebenn Mar 9, 2024
50b2074
Merge remote-tracking branch 'upstream/main' into PetFixes
jadebenn Mar 24, 2024
657fb35
semi update the unit tests
jadebenn Apr 1, 2024
0b4d7b6
Merge remote-tracking branch 'upstream/main' into PetFixes
jadebenn Apr 1, 2024
36e0dbd
load imagination costs for pet abilities from CDClient
jadebenn Apr 19, 2024
d88b982
Merge remote-tracking branch 'upstream/main' into PetFixes
jadebenn Apr 19, 2024
0b24532
clean up PetComponent
jadebenn Apr 20, 2024
6ddf5b3
remove unneeded tests
jadebenn Apr 20, 2024
5ddf4ce
fix unused expression
jadebenn Apr 20, 2024
f41321e
Use compile-time flag setting
jadebenn Apr 20, 2024
071c022
this commit may be kinda broke but I'm gonna push it to check something
jadebenn Apr 20, 2024
7b223d1
Revert "this commit may be kinda broke but I'm gonna push it to check…
jadebenn Apr 20, 2024
68bb51f
move the pet taming minigame start logic into a separate function
jadebenn Apr 20, 2024
fdd981c
Merge remote-tracking branch 'upstream/main' into PetFixes
jadebenn Apr 25, 2024
efc2cb6
Merge branch 'main' into PetFixes
jadebenn Dec 14, 2024
514732d
formatting & const
jadebenn Dec 15, 2024
43681b4
more formatting & const
jadebenn Dec 15, 2024
96f224c
move semantics
jadebenn Dec 15, 2024
0786986
partially address comments
jadebenn Dec 15, 2024
472f873
further address feedback
jadebenn Dec 15, 2024
f7bcbb0
no longer bad (you know it)
jadebenn Dec 15, 2024
d42351d
formatting nits
jadebenn Dec 15, 2024
79c26d9
misc
jadebenn Dec 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 160 additions & 0 deletions dCommon/Flag.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#pragma once
#include "GeneralUtils.h"

/**
* A bitset flag class capable of compile-time bounds-checking.
* It should be possible to unify its methods with C++23, but until then
* use the compile-time overloads preferentially.
*/
template <typename T>
requires std::is_enum_v<T>
class Flag {
public:
// Type aliases
using type = T;
using underlying_type = std::underlying_type_t<T>;

// Static constants
static constexpr auto MAX_FLAG_VAL = sizeof(underlying_type) * CHAR_BIT;

// Constructors
Flag() = default;

// Run-time constructor
constexpr Flag(const T value) : m_Flags{ ConvertFlag(value) } {}

/**
* RUNTIME: Sets one or more flags
* @param flag Flag(s) to set
*/
template <std::same_as<T>... varArg>
constexpr void Set(const varArg... flag) noexcept {
m_Flags |= (ConvertFlag(flag) | ...);
}

/**
* COMPILETIME: Sets one or more flags
* @param flag Flag(s) to set
*/
template <T... flag>
constexpr void Set() noexcept {
m_Flags |= (ConvertFlag<flag>() | ...);
}

/**
* RUNTIME: Sets ONLY have the specified flag(s), clearing all others
* @param flag Flag(s) to set exclusively
*/
template <std::same_as<T>... varArg>
constexpr void Reset(const varArg... flag) {
m_Flags = (ConvertFlag(flag) | ...);
}

/**
* COMPILETIME: Sets ONLY have the specified flag(s), clearing all others
* @param flag Flag(s) to set exclusively
*/
template <T... flag>
constexpr void Reset() noexcept {
m_Flags = (ConvertFlag<flag>() | ...);
}

/**
* RUNTIME: Unsets one or more flags
* @param flag Flag(s) to unset
*/
template <std::same_as<T>... varArg>
constexpr void Unset(const varArg... flag) {
m_Flags &= ~(ConvertFlag(flag) | ...);
}

/**
* COMPILETIME: Unsets one or more flags
* @param flag Flag(s) to unset
*/
template <T... flag>
constexpr void Unset() noexcept {
m_Flags &= ~(ConvertFlag<flag>() | ...);
}

/**
* RUNTIME: Returns true all the specified flag(s) are set
* @param flag Flag(s) to check
*/
template <std::same_as<T>... varArg>
[[nodiscard]]
constexpr bool Has(const varArg... flag) const {
return (m_Flags & (ConvertFlag(flag) | ...)) == (ConvertFlag(flag) | ...);
}

/**
* COMPILETIME: Returns true if all the specified flag(s) are set
* @param flag Flag(s) to check
*/
template <T... flag>
[[nodiscard]]
constexpr bool Has() const noexcept {
return (m_Flags & (ConvertFlag<flag>() | ...)) == (ConvertFlag<flag>() | ...);
}

/**
* RUNTIME: Returns true if ONLY the specified flag(s) are set
* @param flag Flag(s) to check
*/
template <std::same_as<T>... varArg>
[[nodiscard]]
constexpr bool HasOnly(const varArg... flag) const {
return m_Flags == (ConvertFlag(flag) | ...);
}

/**
* COMPILETIME: Returns true if ONLY the specified flag(s) are set
* @param flag Flag(s) to check
*/
template <T... flag>
[[nodiscard]]
constexpr bool HasOnly() const noexcept {
return m_Flags == (ConvertFlag<flag>() | ...);
}

/**
* @return the raw value of the flags set
*/
[[nodiscard]]
constexpr T Value() const noexcept {
return static_cast<T>(m_Flags);
}

/**
* Operator overload to allow for '=' assignment
*/
constexpr Flag& operator=(const T value) {
m_Flags = ConvertFlag(value);
return *this;
}

private:
template <T flag>
[[nodiscard]]
static consteval underlying_type ConvertFlag() noexcept {
constexpr auto flag_val = GeneralUtils::ToUnderlying(flag);
static_assert(flag_val <= MAX_FLAG_VAL, "Flag value is too large to set!");

return flag_val != 0 ? 1 << flag_val : flag_val;
}

[[nodiscard]]
static constexpr underlying_type ConvertFlag(const T flag) {
auto flag_val = GeneralUtils::ToUnderlying(flag);

// This is less-efficient than the compile-time check, but still works
// We can probably unify this and the above functions with C++23 and 'if consteval'
if (flag_val > MAX_FLAG_VAL) {
throw std::runtime_error{ "Flag value is too large to set!" };
}

return flag_val != 0 ? 1 << flag_val : flag_val;
}

underlying_type m_Flags;
};
9 changes: 8 additions & 1 deletion dCommon/dEnums/eHelpType.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@

#ifndef __EHELPTYPE__H__
#define __EHELPTYPE__H__

#include <cstdint>

#include "magic_enum.hpp"

enum class eHelpType : int32_t {
NONE = 0,
UNLOCK_MINIMAP = 2,
Expand Down Expand Up @@ -38,4 +39,10 @@ enum class eHelpType : int32_t {
UI_INVENTORY_FULL_CANNOT_PICKUP_ITEM = 86
};

template <>
struct magic_enum::customize::enum_range<eHelpType> {
static constexpr int min = 0;
static constexpr int max = 86;
};

#endif //!__EHELPTYPE__H__
6 changes: 3 additions & 3 deletions dCommon/dEnums/ePetAbilityType.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __EPETABILITYTYPE__H__
#define __EPETABILITYTYPE__H__
#ifndef EPETABILITYTYPE_H
#define EPETABILITYTYPE_H

#include <cstdint>

Expand All @@ -10,4 +10,4 @@ enum class ePetAbilityType : uint32_t {
DigAtPosition
};

#endif //!__EPETABILITYTYPE__H__
#endif //!EPETABILITYTYPE_H
4 changes: 4 additions & 0 deletions dDatabase/CDClientDatabase/CDClientManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "CDMissionsTable.h"
#include "CDObjectSkillsTable.h"
#include "CDObjectsTable.h"
#include "CDPetAbilitiesTable.h"
#include "CDPhysicsComponentTable.h"
#include "CDRebuildComponentTable.h"
#include "CDScriptComponentTable.h"
Expand Down Expand Up @@ -89,6 +90,7 @@ DEFINE_TABLE_STORAGE(CDObjectSkillsTable);
DEFINE_TABLE_STORAGE(CDObjectsTable);
DEFINE_TABLE_STORAGE(CDPhysicsComponentTable);
DEFINE_TABLE_STORAGE(CDPackageComponentTable);
DEFINE_TABLE_STORAGE(CDPetAbilitiesTable);
DEFINE_TABLE_STORAGE(CDPetComponentTable);
DEFINE_TABLE_STORAGE(CDProximityMonitorComponentTable);
DEFINE_TABLE_STORAGE(CDPropertyEntranceComponentTable);
Expand Down Expand Up @@ -136,6 +138,7 @@ void CDClientManager::LoadValuesFromDatabase() {
CDCLIENT_DONT_CACHE_TABLE(CDObjectsTable::Instance().LoadValuesFromDatabase());
CDPhysicsComponentTable::Instance().LoadValuesFromDatabase();
CDPackageComponentTable::Instance().LoadValuesFromDatabase();
CDPetAbilitiesTable::Instance().LoadValuesFromDatabase();
CDPetComponentTable::Instance().LoadValuesFromDatabase();
CDProximityMonitorComponentTable::Instance().LoadValuesFromDatabase();
CDPropertyEntranceComponentTable::Instance().LoadValuesFromDatabase();
Expand All @@ -155,5 +158,6 @@ void CDClientManager::LoadValuesFromDatabase() {
void CDClientManager::LoadValuesFromDefaults() {
LOG("Loading default CDClient tables!");

CDPetAbilitiesTable::Instance().LoadValuesFromDefaults();
CDPetComponentTable::Instance().LoadValuesFromDefaults();
}
43 changes: 43 additions & 0 deletions dDatabase/CDClientDatabase/CDClientTables/CDPetAbilitiesTable.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "CDPetAbilitiesTable.h"
#include "ePetAbilityType.h"

namespace {
// Default entries for fallback
CDPetAbilities defaultEntry{
.id = ePetAbilityType::Invalid,
UNUSED_ENTRY(.AbilityName = "invalid",)
.imaginationCost = 0,
UNUSED_ENTRY(.locStatus = 2,)
};
}

void CDPetAbilitiesTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PetAbilities");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
const auto abilityId =
static_cast<ePetAbilityType>(tableData.getIntField("id", static_cast<int>(defaultEntry.id)));
auto& entry = entries[abilityId];

entry.id = abilityId;
UNUSED_COLUMN(entry.abilityName = tableData.getStringField("AbilityName", defaultEntry.abilityName));
entry.imaginationCost = tableData.getIntField("ImaginationCost", defaultEntry.imaginationCost);
UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", defaultEntry.locStatus));

tableData.nextRow();
}
}

void CDPetAbilitiesTable::LoadValuesFromDefaults() {
GetEntriesMutable().emplace(defaultEntry.id, defaultEntry);
}

const CDPetAbilities& CDPetAbilitiesTable::GetByID(const ePetAbilityType id) {
const auto& entries = GetEntries();
const auto itr = entries.find(id);
if (itr == entries.cend()) {
LOG("Unable to load pet ability (ID %i) values from database! Using default values instead.", id);
return defaultEntry;
}
return itr->second;
}
34 changes: 34 additions & 0 deletions dDatabase/CDClientDatabase/CDClientTables/CDPetAbilitiesTable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once
#include "CDTable.h"
#include <cstdint>
#include <string>

// Forward declarations
enum class ePetAbilityType : uint32_t;

struct CDPetAbilities {
ePetAbilityType id;
UNUSED_COLUMN(std::string abilityName;)
int32_t imaginationCost;
UNUSED_COLUMN(uint32_t locStatus;)
};

class CDPetAbilitiesTable : public CDTable<CDPetAbilitiesTable, std::map<ePetAbilityType, CDPetAbilities>> {
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 ability table corresponding to the pet ability ID
* @returns A pointer to the corresponding table, or nullptr if one could not be found
*/
const CDPetAbilities& GetByID(const ePetAbilityType id);
};
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ void CDPetComponentTable::LoadValuesFromDefaults() {
GetEntriesMutable().emplace(defaultEntry.id, defaultEntry);
}

CDPetComponent& CDPetComponentTable::GetByID(const uint32_t componentID) {
auto& entries = GetEntriesMutable();
auto itr = entries.find(componentID);
if (itr == entries.end()) {
const CDPetComponent& CDPetComponentTable::GetByID(const uint32_t componentID) {
const auto& entries = GetEntries();
const auto itr = entries.find(componentID);
if (itr == entries.cend()) {
LOG("Unable to load pet component (ID %i) values from database! Using default values instead.", componentID);
return defaultEntry;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class CDPetComponentTable : public CDTable<CDPetComponentTable, std::map<uint32_
* 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
*/
Expand All @@ -38,5 +38,5 @@ class CDPetComponentTable : public CDTable<CDPetComponentTable, std::map<uint32_
* 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);
const CDPetComponent& GetByID(const uint32_t componentID);
};
1 change: 1 addition & 0 deletions dDatabase/CDClientDatabase/CDClientTables/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ set(DDATABASE_CDCLIENTDATABASE_CDCLIENTTABLES_SOURCES "CDActivitiesTable.cpp"
"CDMovementAIComponentTable.cpp"
"CDObjectSkillsTable.cpp"
"CDObjectsTable.cpp"
"CDPetAbilitiesTable.cpp"
"CDPetComponentTable.cpp"
"CDPackageComponentTable.cpp"
"CDPhysicsComponentTable.cpp"
Expand Down
17 changes: 9 additions & 8 deletions dGame/dComponents/InventoryComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1221,7 +1221,7 @@ void InventoryComponent::SpawnPet(Item* item) {
auto* current = PetComponent::GetActivePet(m_Parent->GetObjectID());

if (current != nullptr) {
current->Deactivate();
current->Deactivate(eHelpType::PET_DESPAWN_BY_OWNER_HIBERNATE);

if (current->GetDatabaseId() == item->GetSubKey()) {
return;
Expand Down Expand Up @@ -1253,8 +1253,8 @@ void InventoryComponent::SpawnPet(Item* item) {
Game::entityManager->ConstructEntity(pet);
}

void InventoryComponent::SetDatabasePet(LWOOBJID id, const DatabasePet& data) {
m_Pets.insert_or_assign(id, data);
void InventoryComponent::SetDatabasePet(LWOOBJID id, DatabasePet&& data) {
m_Pets.insert_or_assign(id, std::move(data));
}

const DatabasePet& InventoryComponent::GetDatabasePet(LWOOBJID id) const {
Expand Down Expand Up @@ -1580,12 +1580,13 @@ void InventoryComponent::LoadPetXml(const tinyxml2::XMLDocument& document) {
petElement->QueryAttribute("m", &moderationStatus);
const char* name = petElement->Attribute("n");

DatabasePet databasePet;
databasePet.lot = lot;
databasePet.moderationState = moderationStatus;
databasePet.name = std::string(name);
auto databasePet = DatabasePet{
.lot = lot,
.name = std::string(name),
.moderationState = moderationStatus,
};

SetDatabasePet(id, databasePet);
SetDatabasePet(id, std::move(databasePet));

petElement = petElement->NextSiblingElement();
}
Expand Down
2 changes: 1 addition & 1 deletion dGame/dComponents/InventoryComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ class InventoryComponent final : public Component {
* @param id the id of the pet to find
* @param data the data to store on the pet
*/
void SetDatabasePet(LWOOBJID id, const DatabasePet& data);
void SetDatabasePet(LWOOBJID id, DatabasePet&& data);

/**
* Returns the database pet information for an object
Expand Down
Loading