mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-10-11 18:08:05 +00:00
Merge branch 'DarkflameUniverse:main' into PetFixes
This commit is contained in:
@@ -33,7 +33,7 @@ ActivityComponent::ActivityComponent(Entity* parent, int32_t activityID) : Compo
|
||||
if (activityID > 0) m_ActivityID = activityID;
|
||||
else m_ActivityID = parent->GetVar<int32_t>(u"activityID");
|
||||
CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable<CDActivitiesTable>();
|
||||
std::vector<CDActivities> activities = activitiesTable->Query([=](CDActivities entry) {return (entry.ActivityID == m_ActivityID); });
|
||||
std::vector<CDActivities> activities = activitiesTable->Query([this](CDActivities entry) {return (entry.ActivityID == m_ActivityID); });
|
||||
|
||||
for (CDActivities activity : activities) {
|
||||
m_ActivityInfo = activity;
|
||||
@@ -93,7 +93,7 @@ void ActivityComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIniti
|
||||
|
||||
void ActivityComponent::ReloadConfig() {
|
||||
CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable<CDActivitiesTable>();
|
||||
std::vector<CDActivities> activities = activitiesTable->Query([=](CDActivities entry) {return (entry.ActivityID == m_ActivityID); });
|
||||
std::vector<CDActivities> activities = activitiesTable->Query([this](CDActivities entry) {return (entry.ActivityID == m_ActivityID); });
|
||||
for (auto activity : activities) {
|
||||
auto mapID = m_ActivityInfo.instanceMapID;
|
||||
if (static_cast<Leaderboard::Type>(activity.leaderboardType) == Leaderboard::Type::Racing && Game::config->GetValue("solo_racing") == "1") {
|
||||
@@ -532,7 +532,7 @@ void ActivityInstance::RewardParticipant(Entity* participant) {
|
||||
|
||||
// First, get the activity data
|
||||
auto* activityRewardsTable = CDClientManager::Instance().GetTable<CDActivityRewardsTable>();
|
||||
std::vector<CDActivityRewards> activityRewards = activityRewardsTable->Query([=](CDActivityRewards entry) { return (entry.objectTemplate == m_ActivityInfo.ActivityID); });
|
||||
std::vector<CDActivityRewards> activityRewards = activityRewardsTable->Query([this](CDActivityRewards entry) { return (entry.objectTemplate == m_ActivityInfo.ActivityID); });
|
||||
|
||||
if (!activityRewards.empty()) {
|
||||
uint32_t minCoins = 0;
|
||||
|
@@ -95,10 +95,16 @@ void BuffComponent::Update(float deltaTime) {
|
||||
|
||||
if (buff.second.time <= 0.0f) {
|
||||
RemoveBuff(buff.first);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_BuffsToRemove.empty()) return;
|
||||
|
||||
for (const auto& buff : m_BuffsToRemove) {
|
||||
m_Buffs.erase(buff);
|
||||
}
|
||||
|
||||
m_BuffsToRemove.clear();
|
||||
}
|
||||
|
||||
const std::string& GetFxName(const std::string& buffname) {
|
||||
@@ -216,7 +222,7 @@ void BuffComponent::RemoveBuff(int32_t id, bool fromUnEquip, bool removeImmunity
|
||||
|
||||
GameMessages::SendRemoveBuff(m_Parent, fromUnEquip, removeImmunity, id);
|
||||
|
||||
m_Buffs.erase(iter);
|
||||
m_BuffsToRemove.push_back(id);
|
||||
|
||||
RemoveBuffEffect(id);
|
||||
}
|
||||
|
@@ -140,6 +140,9 @@ private:
|
||||
*/
|
||||
std::map<int32_t, Buff> m_Buffs;
|
||||
|
||||
// Buffs to remove at the end of the update frame.
|
||||
std::vector<int32_t> m_BuffsToRemove;
|
||||
|
||||
/**
|
||||
* Parameters (=effects) for each buff
|
||||
*/
|
||||
|
@@ -1,4 +1,5 @@
|
||||
set(DGAME_DCOMPONENTS_SOURCES "ActivityComponent.cpp"
|
||||
set(DGAME_DCOMPONENTS_SOURCES
|
||||
"ActivityComponent.cpp"
|
||||
"BaseCombatAIComponent.cpp"
|
||||
"BouncerComponent.cpp"
|
||||
"BuffComponent.cpp"
|
||||
@@ -46,5 +47,11 @@ set(DGAME_DCOMPONENTS_SOURCES "ActivityComponent.cpp"
|
||||
"HavokVehiclePhysicsComponent.cpp"
|
||||
"VendorComponent.cpp"
|
||||
"MiniGameControlComponent.cpp"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
add_library(dComponents STATIC ${DGAME_DCOMPONENTS_SOURCES})
|
||||
target_include_directories(dComponents PRIVATE ${PROJECT_SOURCE_DIR}/dScripts/02_server/Map/General) # PetDigServer.h
|
||||
target_precompile_headers(dComponents REUSE_FROM dGameBase)
|
||||
target_link_libraries(dComponents
|
||||
PUBLIC dPhysics dDatabase
|
||||
INTERFACE dUtilities dCommon dBehaviors dChatFilter dMission dInventory)
|
||||
|
@@ -1,6 +1,12 @@
|
||||
#include "ModelComponent.h"
|
||||
#include "Entity.h"
|
||||
|
||||
#include "Game.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#include "BehaviorStates.h"
|
||||
#include "ControlBehaviorMsgs.h"
|
||||
|
||||
ModelComponent::ModelComponent(Entity* parent) : Component(parent) {
|
||||
m_OriginalPosition = m_Parent->GetDefaultPosition();
|
||||
m_OriginalRotation = m_Parent->GetDefaultRotation();
|
||||
@@ -29,3 +35,40 @@ void ModelComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialU
|
||||
outBitStream->Write1(); // Is this model paused
|
||||
if (bIsInitialUpdate) outBitStream->Write0(); // We are not writing model editing info
|
||||
}
|
||||
|
||||
void ModelComponent::UpdatePendingBehaviorId(const int32_t newId) {
|
||||
for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == -1) behavior.SetBehaviorId(newId);
|
||||
}
|
||||
|
||||
void ModelComponent::SendBehaviorListToClient(AMFArrayValue& args) const {
|
||||
args.Insert("objectID", std::to_string(m_Parent->GetObjectID()));
|
||||
|
||||
auto* behaviorArray = args.InsertArray("behaviors");
|
||||
for (auto& behavior : m_Behaviors) {
|
||||
auto* behaviorArgs = behaviorArray->PushArray();
|
||||
behavior.SendBehaviorListToClient(*behaviorArgs);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelComponent::VerifyBehaviors() {
|
||||
for (auto& behavior : m_Behaviors) behavior.VerifyLastEditedState();
|
||||
}
|
||||
|
||||
void ModelComponent::SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args) const {
|
||||
args.Insert("BehaviorID", std::to_string(behaviorToSend));
|
||||
args.Insert("objectID", std::to_string(m_Parent->GetObjectID()));
|
||||
for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == behaviorToSend) behavior.SendBehaviorBlocksToClient(args);
|
||||
}
|
||||
|
||||
void ModelComponent::AddBehavior(AddMessage& msg) {
|
||||
// Can only have 1 of the loot behaviors
|
||||
for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == msg.GetBehaviorId()) return;
|
||||
m_Behaviors.insert(m_Behaviors.begin() + msg.GetBehaviorIndex(), PropertyBehavior());
|
||||
m_Behaviors.at(msg.GetBehaviorIndex()).HandleMsg(msg);
|
||||
}
|
||||
|
||||
void ModelComponent::MoveToInventory(MoveToInventoryMessage& msg) {
|
||||
if (msg.GetBehaviorIndex() >= m_Behaviors.size() || m_Behaviors.at(msg.GetBehaviorIndex()).GetBehaviorId() != msg.GetBehaviorId()) return;
|
||||
m_Behaviors.erase(m_Behaviors.begin() + msg.GetBehaviorIndex());
|
||||
// TODO move to the inventory
|
||||
}
|
||||
|
@@ -1,4 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "dCommonVars.h"
|
||||
#include "RakNetTypes.h"
|
||||
#include "NiPoint3.h"
|
||||
@@ -6,7 +9,15 @@
|
||||
#include "Component.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
|
||||
#include "Action.h"
|
||||
#include "PropertyBehavior.h"
|
||||
#include "StripUiPosition.h"
|
||||
|
||||
class AddMessage;
|
||||
class AMFArrayValue;
|
||||
class BehaviorMessageBase;
|
||||
class Entity;
|
||||
class MoveToInventoryMessage;
|
||||
|
||||
/**
|
||||
* Component that represents entities that are a model, e.g. collectible models and BBB models.
|
||||
@@ -43,7 +54,68 @@ public:
|
||||
*/
|
||||
void SetRotation(const NiQuaternion& rot) { m_OriginalRotation = rot; }
|
||||
|
||||
/**
|
||||
* Main gateway for all behavior messages to be passed to their respective behaviors.
|
||||
*
|
||||
* @tparam Msg The message type to pass
|
||||
* @param args the arguments of the message to be deserialized
|
||||
*/
|
||||
template<typename Msg>
|
||||
void HandleControlBehaviorsMsg(AMFArrayValue* args) {
|
||||
static_assert(std::is_base_of_v<BehaviorMessageBase, Msg>, "Msg must be a BehaviorMessageBase");
|
||||
Msg msg(args);
|
||||
for (auto& behavior : m_Behaviors) {
|
||||
if (behavior.GetBehaviorId() == msg.GetBehaviorId()) {
|
||||
behavior.HandleMsg(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If we somehow added more than 5 behaviors, resize to 5.
|
||||
if (m_Behaviors.size() > 5) m_Behaviors.resize(5);
|
||||
|
||||
// Do not allow more than 5 to be added. The client UI will break if you do!
|
||||
if (m_Behaviors.size() == 5) return;
|
||||
|
||||
auto newBehavior = m_Behaviors.insert(m_Behaviors.begin(), PropertyBehavior());
|
||||
// Generally if we are inserting a new behavior, it is because the client is creating a new behavior.
|
||||
// However if we are testing behaviors the behavior will not exist on the initial pass, so we set the ID here to that of the msg.
|
||||
// This will either set the ID to -1 (no change in the current default) or set the ID to the ID of the behavior we are testing.
|
||||
newBehavior->SetBehaviorId(msg.GetBehaviorId());
|
||||
newBehavior->HandleMsg(msg);
|
||||
};
|
||||
|
||||
void AddBehavior(AddMessage& msg);
|
||||
|
||||
void MoveToInventory(MoveToInventoryMessage& msg);
|
||||
|
||||
// Updates the pending behavior ID to the new ID.
|
||||
void UpdatePendingBehaviorId(const int32_t newId);
|
||||
|
||||
// Sends the behavior list to the client.
|
||||
|
||||
/**
|
||||
* The behaviors AMFArray will have up to 5 elements in the dense portion.
|
||||
* Each element in the dense portion will be made up of another AMFArray
|
||||
* with the following information mapped in the associative portion
|
||||
* "id": Behavior ID cast to an AMFString
|
||||
* "isLocked": AMFTrue or AMFFalse of whether or not the behavior is locked
|
||||
* "isLoot": AMFTrue or AMFFalse of whether or not the behavior is a custom behavior (true if custom)
|
||||
* "name": The name of the behavior formatted as an AMFString
|
||||
*/
|
||||
void SendBehaviorListToClient(AMFArrayValue& args) const;
|
||||
|
||||
void SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args) const;
|
||||
|
||||
void VerifyBehaviors();
|
||||
|
||||
private:
|
||||
/**
|
||||
* The behaviors of the model
|
||||
* Note: This is a vector because the order of the behaviors matters when serializing to the client.
|
||||
* Note: No two PropertyBehaviors should have the same behavior ID.
|
||||
*/
|
||||
std::vector<PropertyBehavior> m_Behaviors;
|
||||
|
||||
/**
|
||||
* The original position of the model
|
||||
|
@@ -312,7 +312,7 @@ void RacingControlComponent::OnRequestDie(Entity* player) {
|
||||
}
|
||||
|
||||
// Respawn the player in 2 seconds, as was done in live. Not sure if this value is in a setting somewhere else...
|
||||
vehicle->AddCallbackTimer(2.0f, [=]() {
|
||||
vehicle->AddCallbackTimer(2.0f, [=, this]() {
|
||||
if (!vehicle || !this->m_Parent) return;
|
||||
GameMessages::SendRacingResetPlayerToLastReset(
|
||||
m_Parent->GetObjectID(), racingPlayer.playerID,
|
||||
|
Reference in New Issue
Block a user