mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-01 13:48:20 +00:00
Merge branch 'main' into moreMovementAi
This commit is contained in:
@@ -9,11 +9,15 @@
|
||||
#include "UserManager.h"
|
||||
#include "CDMissionsTable.h"
|
||||
|
||||
AchievementVendorComponent::AchievementVendorComponent(Entity* parent) : VendorComponent(parent) {
|
||||
RefreshInventory(true);
|
||||
};
|
||||
|
||||
bool AchievementVendorComponent::SellsItem(Entity* buyer, const LOT lot) {
|
||||
auto* missionComponent = buyer->GetComponent<MissionComponent>();
|
||||
if (!missionComponent) return false;
|
||||
|
||||
if (m_PlayerPurchasableItems[buyer->GetObjectID()].contains(lot)){
|
||||
if (m_PlayerPurchasableItems[buyer->GetObjectID()].contains(lot)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -35,7 +39,7 @@ void AchievementVendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
|
||||
int itemCompID = compRegistryTable->GetByIDAndType(lot, eReplicaComponentType::ITEM);
|
||||
CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID);
|
||||
uint32_t costLOT = itemComp.commendationLOT;
|
||||
|
||||
|
||||
if (costLOT == -1 || !SellsItem(buyer, lot)) {
|
||||
auto* user = UserManager::Instance()->GetUser(buyer->GetSystemAddress());
|
||||
CheatDetection::ReportCheat(user, buyer->GetSystemAddress(), "Attempted to buy item %i from achievement vendor %i that is not purchasable", lot, m_Parent->GetLOT());
|
||||
@@ -44,7 +48,7 @@ void AchievementVendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
|
||||
}
|
||||
|
||||
auto* inventoryComponent = buyer->GetComponent<InventoryComponent>();
|
||||
if (!inventoryComponent) {
|
||||
if (!inventoryComponent) {
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
@@ -69,4 +73,9 @@ void AchievementVendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
|
||||
inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR);
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void AchievementVendorComponent::RefreshInventory(bool isCreation) {
|
||||
SetHasStandardCostItems(true);
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,9 @@ class Entity;
|
||||
class AchievementVendorComponent final : public VendorComponent {
|
||||
public:
|
||||
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::ACHIEVEMENT_VENDOR;
|
||||
AchievementVendorComponent(Entity* parent) : VendorComponent(parent) {};
|
||||
AchievementVendorComponent(Entity* parent);
|
||||
|
||||
void RefreshInventory(bool isCreation = false) override;
|
||||
bool SellsItem(Entity* buyer, const LOT lot);
|
||||
void Buy(Entity* buyer, LOT lot, uint32_t count);
|
||||
|
||||
|
||||
@@ -48,11 +48,35 @@ set(DGAME_DCOMPONENTS_SOURCES
|
||||
"HavokVehiclePhysicsComponent.cpp"
|
||||
"VendorComponent.cpp"
|
||||
"MiniGameControlComponent.cpp"
|
||||
"ScriptComponent.cpp"
|
||||
)
|
||||
|
||||
add_library(dComponents STATIC ${DGAME_DCOMPONENTS_SOURCES})
|
||||
target_include_directories(dComponents PRIVATE ${PROJECT_SOURCE_DIR}/dScripts/02_server/Map/General) # PetDigServer.h
|
||||
add_library(dComponents OBJECT ${DGAME_DCOMPONENTS_SOURCES})
|
||||
target_include_directories(dComponents PUBLIC "."
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dPropertyBehaviors" # via ModelComponent.h
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dPropertyBehaviors/ControlBehaviorMessages"
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dMission" # via MissionComponent.h
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dBehaviors" # via InventoryComponent.h
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dInventory" # via InventoryComponent.h
|
||||
PRIVATE
|
||||
"${PROJECT_SOURCE_DIR}/dCommon"
|
||||
"${PROJECT_SOURCE_DIR}/dCommon/dEnums"
|
||||
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase"
|
||||
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase/CDClientTables"
|
||||
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase"
|
||||
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase/ITables"
|
||||
"${PROJECT_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/include"
|
||||
# dPhysics (via dpWorld.h)
|
||||
"${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Recast/Include"
|
||||
"${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Detour/Include"
|
||||
|
||||
"${PROJECT_SOURCE_DIR}/dScripts/02_server/Map/General" # PetDigServer.h
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dGameMessages" # direct
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dUtilities" # direct Loot.h
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dEntity" # via dZoneManager/Spawner.h
|
||||
"${PROJECT_SOURCE_DIR}/dZoneManager" # via BouncerComponent.cpp, ActivityComponent.cpp
|
||||
"${PROJECT_SOURCE_DIR}/dChatFilter" # via PetComponent.cpp
|
||||
)
|
||||
target_precompile_headers(dComponents REUSE_FROM dGameBase)
|
||||
target_link_libraries(dComponents
|
||||
PUBLIC dPhysics dDatabase
|
||||
INTERFACE dUtilities dCommon dBehaviors dChatFilter dMission dInventory)
|
||||
|
||||
target_link_libraries(dComponents INTERFACE dBehaviors)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "RakNetTypes.h"
|
||||
#include "Character.h"
|
||||
#include "Component.h"
|
||||
#include "Item.h"
|
||||
#include <string>
|
||||
#include "CDMissionsTable.h"
|
||||
#include "tinyxml2.h"
|
||||
@@ -15,6 +14,8 @@
|
||||
|
||||
enum class eGameActivity : uint32_t;
|
||||
|
||||
class Item;
|
||||
|
||||
/**
|
||||
* The statistics that can be achieved per zone
|
||||
*/
|
||||
|
||||
@@ -21,7 +21,6 @@ ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Phy
|
||||
m_InJetpackMode = false;
|
||||
m_IsOnGround = true;
|
||||
m_IsOnRail = false;
|
||||
m_DirtyVelocity = true;
|
||||
m_dpEntity = nullptr;
|
||||
m_Static = false;
|
||||
m_SpeedMultiplier = 1;
|
||||
@@ -137,21 +136,23 @@ void ControllablePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo
|
||||
outBitStream.Write(m_IsOnGround);
|
||||
outBitStream.Write(m_IsOnRail);
|
||||
|
||||
outBitStream.Write(isVelocityZero);
|
||||
if (isVelocityZero) {
|
||||
bool isNotZero = m_Velocity != NiPoint3Constant::ZERO;
|
||||
outBitStream.Write(isNotZero);
|
||||
if (isNotZero) {
|
||||
outBitStream.Write(m_Velocity.x);
|
||||
outBitStream.Write(m_Velocity.y);
|
||||
outBitStream.Write(m_Velocity.z);
|
||||
}
|
||||
|
||||
outBitStream.Write(isAngularVelocityZero);
|
||||
if (isAngularVelocityZero) {
|
||||
isNotZero = m_AngularVelocity != NiPoint3Constant::ZERO;
|
||||
outBitStream.Write(isNotZero);
|
||||
if (isNotZero) {
|
||||
outBitStream.Write(m_AngularVelocity.x);
|
||||
outBitStream.Write(m_AngularVelocity.y);
|
||||
outBitStream.Write(m_AngularVelocity.z);
|
||||
}
|
||||
|
||||
outBitStream.Write0(); // LocalSpaceInfo
|
||||
outBitStream.Write0();
|
||||
if (!bIsInitialUpdate) {
|
||||
m_DirtyPosition = false;
|
||||
outBitStream.Write(m_IsTeleporting);
|
||||
@@ -213,9 +214,7 @@ void ControllablePhysicsComponent::SetRotation(const NiQuaternion& rot) {
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::SetVelocity(const NiPoint3& vel) {
|
||||
if (m_Static || m_Velocity == vel) {
|
||||
return;
|
||||
}
|
||||
if (m_Static || m_Velocity == vel) return;
|
||||
|
||||
m_Velocity = vel;
|
||||
m_DirtyPosition = true;
|
||||
@@ -224,22 +223,20 @@ void ControllablePhysicsComponent::SetVelocity(const NiPoint3& vel) {
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::SetAngularVelocity(const NiPoint3& vel) {
|
||||
if (m_Static || m_AngularVelocity == vel) {
|
||||
return;
|
||||
}
|
||||
if (m_Static || m_AngularVelocity == vel) return;
|
||||
|
||||
m_AngularVelocity = vel;
|
||||
m_DirtyPosition = true;
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::SetIsOnGround(bool val) {
|
||||
if (val == m_IsOnGround) return;
|
||||
if (m_IsOnGround == val) return;
|
||||
m_DirtyPosition = true;
|
||||
m_IsOnGround = val;
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::SetIsOnRail(bool val) {
|
||||
if (val == m_IsOnRail) return;
|
||||
if (m_IsOnRail == val) return;
|
||||
m_DirtyPosition = true;
|
||||
m_IsOnRail = val;
|
||||
}
|
||||
|
||||
@@ -298,11 +298,6 @@ private:
|
||||
*/
|
||||
dpEntity* m_dpEntity;
|
||||
|
||||
/**
|
||||
* Whether or not the velocity is dirty, forcing a serialization of the velocity
|
||||
*/
|
||||
bool m_DirtyVelocity;
|
||||
|
||||
/**
|
||||
* The current velocity of the entity
|
||||
*/
|
||||
|
||||
@@ -785,16 +785,12 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
|
||||
}
|
||||
|
||||
Entity* zoneControl = Game::entityManager->GetZoneControlEntity();
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) {
|
||||
script->OnPlayerDied(zoneControl, m_Parent);
|
||||
}
|
||||
if (zoneControl) zoneControl->GetScript()->OnPlayerDied(zoneControl, m_Parent);
|
||||
|
||||
std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY);
|
||||
for (Entity* scriptEntity : scriptedActs) {
|
||||
if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) {
|
||||
script->OnPlayerDied(scriptEntity, m_Parent);
|
||||
}
|
||||
scriptEntity->GetScript()->OnPlayerDied(scriptEntity, m_Parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@ HavokVehiclePhysicsComponent::HavokVehiclePhysicsComponent(Entity* parent) : Phy
|
||||
m_IsOnGround = true;
|
||||
m_IsOnRail = false;
|
||||
m_DirtyPosition = true;
|
||||
m_DirtyVelocity = true;
|
||||
m_DirtyAngularVelocity = true;
|
||||
m_EndBehavior = GeneralUtils::GenerateRandomNumber<uint32_t>(0, 7);
|
||||
}
|
||||
|
||||
@@ -37,17 +35,9 @@ void HavokVehiclePhysicsComponent::SetIsOnRail(bool val) {
|
||||
}
|
||||
|
||||
void HavokVehiclePhysicsComponent::SetRemoteInputInfo(const RemoteInputInfo& remoteInputInfo) {
|
||||
if (m_RemoteInputInfo == remoteInputInfo) return;
|
||||
if (remoteInputInfo == m_RemoteInputInfo) return;
|
||||
this->m_RemoteInputInfo = remoteInputInfo;
|
||||
m_DirtyRemoteInput = true;
|
||||
}
|
||||
|
||||
void HavokVehiclePhysicsComponent::SetDirtyVelocity(bool val) {
|
||||
m_DirtyVelocity = val;
|
||||
}
|
||||
|
||||
void HavokVehiclePhysicsComponent::SetDirtyAngularVelocity(bool val) {
|
||||
m_DirtyAngularVelocity = val;
|
||||
m_DirtyPosition = true;
|
||||
}
|
||||
|
||||
void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
@@ -67,18 +57,17 @@ void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo
|
||||
outBitStream.Write(m_IsOnGround);
|
||||
outBitStream.Write(m_IsOnRail);
|
||||
|
||||
bool isVelocityZero = m_Velocity == NiPoint3Constant::ZERO;
|
||||
|
||||
outBitStream.Write(isVelocityZero);
|
||||
if (isVelocityZero) {
|
||||
bool isNotZero = m_Velocity != NiPoint3Constant::ZERO;
|
||||
outBitStream.Write(isNotZero);
|
||||
if (isNotZero) {
|
||||
outBitStream.Write(m_Velocity.x);
|
||||
outBitStream.Write(m_Velocity.y);
|
||||
outBitStream.Write(m_Velocity.z);
|
||||
}
|
||||
|
||||
bool isAngularVelocityZero = m_AngularVelocity == NiPoint3Constant::ZERO;
|
||||
outBitStream.Write(isAngularVelocityZero);
|
||||
if (isAngularVelocityZero) {
|
||||
isNotZero = m_AngularVelocity != NiPoint3Constant::ZERO;
|
||||
outBitStream.Write(isNotZero);
|
||||
if (isNotZero) {
|
||||
outBitStream.Write(m_AngularVelocity.x);
|
||||
outBitStream.Write(m_AngularVelocity.y);
|
||||
outBitStream.Write(m_AngularVelocity.z);
|
||||
@@ -86,14 +75,14 @@ void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo
|
||||
|
||||
outBitStream.Write0(); // local_space_info. TODO: Implement this
|
||||
|
||||
outBitStream.Write(m_DirtyRemoteInput || bIsInitialUpdate); // remote_input_info
|
||||
if (m_DirtyRemoteInput || bIsInitialUpdate) {
|
||||
outBitStream.Write(m_RemoteInputInfo.m_RemoteInputX);
|
||||
outBitStream.Write(m_RemoteInputInfo.m_RemoteInputY);
|
||||
outBitStream.Write(m_RemoteInputInfo.m_IsPowersliding);
|
||||
outBitStream.Write(m_RemoteInputInfo.m_IsModified);
|
||||
m_DirtyRemoteInput = false;
|
||||
}
|
||||
// This structure only has this bool flag set to false if a ptr to the peVehicle is null, which we don't have
|
||||
// therefore, this will always be 1, even if all the values in the structure are 0.
|
||||
outBitStream.Write1(); // has remote_input_info
|
||||
outBitStream.Write(m_RemoteInputInfo.m_RemoteInputX);
|
||||
outBitStream.Write(m_RemoteInputInfo.m_RemoteInputY);
|
||||
outBitStream.Write(m_RemoteInputInfo.m_IsPowersliding);
|
||||
outBitStream.Write(m_RemoteInputInfo.m_IsModified);
|
||||
|
||||
|
||||
outBitStream.Write(125.0f); // remote_input_ping TODO: Figure out how this should be calculated as it seems to be constant through the whole race.
|
||||
|
||||
@@ -109,12 +98,3 @@ void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo
|
||||
|
||||
outBitStream.Write0();
|
||||
}
|
||||
|
||||
void HavokVehiclePhysicsComponent::Update(float deltaTime) {
|
||||
if (m_SoftUpdate > 5) {
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
m_SoftUpdate = 0;
|
||||
} else {
|
||||
m_SoftUpdate += deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@ public:
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
|
||||
/**
|
||||
* Sets the velocity
|
||||
* @param vel the new velocity
|
||||
@@ -67,22 +65,16 @@ public:
|
||||
*/
|
||||
const bool GetIsOnRail() const { return m_IsOnRail; }
|
||||
|
||||
void SetDirtyPosition(bool val);
|
||||
void SetDirtyVelocity(bool val);
|
||||
void SetDirtyAngularVelocity(bool val);
|
||||
void SetRemoteInputInfo(const RemoteInputInfo&);
|
||||
|
||||
private:
|
||||
bool m_DirtyVelocity;
|
||||
NiPoint3 m_Velocity;
|
||||
|
||||
bool m_DirtyAngularVelocity;
|
||||
NiPoint3 m_AngularVelocity;
|
||||
|
||||
bool m_IsOnGround;
|
||||
bool m_IsOnRail;
|
||||
|
||||
float m_SoftUpdate = 0;
|
||||
uint32_t m_EndBehavior;
|
||||
RemoteInputInfo m_RemoteInputInfo;
|
||||
bool m_DirtyRemoteInput;
|
||||
};
|
||||
|
||||
@@ -162,7 +162,7 @@ void MovingPlatformComponent::StartPathing() {
|
||||
const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex];
|
||||
|
||||
subComponent->mPosition = currentWaypoint.position;
|
||||
subComponent->mSpeed = currentWaypoint.movingPlatform.speed;
|
||||
subComponent->mSpeed = currentWaypoint.speed;
|
||||
subComponent->mWaitTime = currentWaypoint.movingPlatform.wait;
|
||||
|
||||
targetPosition = nextWaypoint.position;
|
||||
@@ -183,9 +183,7 @@ void MovingPlatformComponent::StartPathing() {
|
||||
const auto travelNext = subComponent->mWaitTime + travelTime;
|
||||
|
||||
m_Parent->AddCallbackTimer(travelTime, [subComponent, this] {
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
|
||||
}
|
||||
this->m_Parent->GetScript()->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
|
||||
});
|
||||
|
||||
m_Parent->AddCallbackTimer(travelNext, [this] {
|
||||
@@ -213,7 +211,7 @@ void MovingPlatformComponent::ContinuePathing() {
|
||||
const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex];
|
||||
|
||||
subComponent->mPosition = currentWaypoint.position;
|
||||
subComponent->mSpeed = currentWaypoint.movingPlatform.speed;
|
||||
subComponent->mSpeed = currentWaypoint.speed;
|
||||
subComponent->mWaitTime = currentWaypoint.movingPlatform.wait; // + 2;
|
||||
|
||||
pathSize = m_Path->pathWaypoints.size() - 1;
|
||||
@@ -295,9 +293,7 @@ void MovingPlatformComponent::ContinuePathing() {
|
||||
const auto travelNext = subComponent->mWaitTime + travelTime;
|
||||
|
||||
m_Parent->AddCallbackTimer(travelTime, [subComponent, this] {
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
|
||||
}
|
||||
this->m_Parent->GetScript()->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
|
||||
});
|
||||
|
||||
m_Parent->AddCallbackTimer(travelNext, [this] {
|
||||
|
||||
@@ -306,9 +306,7 @@ void PetComponent::OnUse(Entity* originator) {
|
||||
currentActivities.insert_or_assign(m_Tamer, m_Parent->GetObjectID());
|
||||
|
||||
// Notify the start of a pet taming minigame
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnNotifyPetTamingMinigame(m_Parent, originator, ePetTamingNotifyType::BEGIN);
|
||||
}
|
||||
m_Parent->GetScript()->OnNotifyPetTamingMinigame(m_Parent, originator, ePetTamingNotifyType::BEGIN);
|
||||
}
|
||||
|
||||
void PetComponent::Update(float deltaTime) {
|
||||
@@ -690,9 +688,7 @@ void PetComponent::RequestSetPetName(std::u16string name) {
|
||||
m_Tamer = LWOOBJID_EMPTY;
|
||||
|
||||
// Notify the end of a pet taming minigame
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::SUCCESS);
|
||||
}
|
||||
m_Parent->GetScript()->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::SUCCESS);
|
||||
}
|
||||
|
||||
void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) {
|
||||
@@ -731,9 +727,7 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) {
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
|
||||
// Notify the end of a pet taming minigame
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::QUIT);
|
||||
}
|
||||
m_Parent->GetScript()->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::QUIT);
|
||||
}
|
||||
|
||||
void PetComponent::StartTimer() {
|
||||
@@ -782,9 +776,7 @@ void PetComponent::ClientFailTamingMinigame() {
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
|
||||
// Notify the end of a pet taming minigame
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::FAILED);
|
||||
}
|
||||
m_Parent->GetScript()->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::FAILED);
|
||||
}
|
||||
|
||||
void PetComponent::Wander() {
|
||||
|
||||
@@ -353,7 +353,6 @@ private:
|
||||
|
||||
/**
|
||||
* Pet information loaded from the CDClientDatabase
|
||||
* TODO: Switch to a reference when safe to do so
|
||||
*/
|
||||
CDPetComponent m_PetInfo;
|
||||
};
|
||||
|
||||
@@ -214,9 +214,7 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) {
|
||||
Database::Get()->InsertNewProperty(info, templateId, worldId);
|
||||
|
||||
auto* zoneControlObject = Game::zoneManager->GetZoneControlObject();
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControlObject)) {
|
||||
script->OnZonePropertyRented(zoneControlObject, entity);
|
||||
}
|
||||
if (zoneControlObject) zoneControlObject->GetScript()->OnZonePropertyRented(zoneControlObject, entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -414,13 +414,11 @@ void QuickBuildComponent::StartQuickBuild(Entity* const user) {
|
||||
movingPlatform->OnQuickBuildInitilized();
|
||||
}
|
||||
|
||||
for (auto* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnQuickBuildStart(m_Parent, user);
|
||||
}
|
||||
auto* script = m_Parent->GetScript();
|
||||
script->OnQuickBuildStart(m_Parent, user);
|
||||
|
||||
// Notify scripts and possible subscribers
|
||||
for (auto* script : CppScripts::GetEntityScripts(m_Parent))
|
||||
script->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
script->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
for (const auto& cb : m_QuickBuildStateCallbacks)
|
||||
cb(m_State);
|
||||
}
|
||||
@@ -485,10 +483,9 @@ void QuickBuildComponent::CompleteQuickBuild(Entity* const user) {
|
||||
}
|
||||
|
||||
// Notify scripts
|
||||
for (auto* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnQuickBuildComplete(m_Parent, user);
|
||||
script->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
}
|
||||
auto* script = m_Parent->GetScript();
|
||||
script->OnQuickBuildComplete(m_Parent, user);
|
||||
script->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
|
||||
// Notify subscribers
|
||||
for (const auto& callback : m_QuickBuildStateCallbacks)
|
||||
@@ -539,8 +536,7 @@ void QuickBuildComponent::ResetQuickBuild(const bool failed) {
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
|
||||
// Notify scripts and possible subscribers
|
||||
for (auto* script : CppScripts::GetEntityScripts(m_Parent))
|
||||
script->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
m_Parent->GetScript()->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
for (const auto& cb : m_QuickBuildStateCallbacks)
|
||||
cb(m_State);
|
||||
|
||||
@@ -571,8 +567,7 @@ void QuickBuildComponent::CancelQuickBuild(Entity* const entity, const eQuickBui
|
||||
m_StateDirty = true;
|
||||
|
||||
// Notify scripts and possible subscribers
|
||||
for (auto* script : CppScripts::GetEntityScripts(m_Parent))
|
||||
script->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
m_Parent->GetScript()->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
for (const auto& cb : m_QuickBuildStateCallbacks)
|
||||
cb(m_State);
|
||||
|
||||
|
||||
52
dGame/dComponents/ScriptComponent.cpp
Normal file
52
dGame/dComponents/ScriptComponent.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Darkflame Universe
|
||||
* Copyright 2018
|
||||
*/
|
||||
|
||||
#include "Entity.h"
|
||||
#include "ScriptComponent.h"
|
||||
|
||||
ScriptComponent::ScriptComponent(Entity* parent, std::string scriptName, bool serialized, bool client) : Component(parent) {
|
||||
m_Serialized = serialized;
|
||||
m_Client = client;
|
||||
|
||||
SetScript(scriptName);
|
||||
}
|
||||
|
||||
ScriptComponent::~ScriptComponent() {
|
||||
|
||||
}
|
||||
|
||||
void ScriptComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
if (bIsInitialUpdate) {
|
||||
const auto& networkSettings = m_Parent->GetNetworkSettings();
|
||||
auto hasNetworkSettings = !networkSettings.empty();
|
||||
outBitStream.Write(hasNetworkSettings);
|
||||
|
||||
if (hasNetworkSettings) {
|
||||
|
||||
// First write the most inner LDF data
|
||||
RakNet::BitStream ldfData;
|
||||
ldfData.Write<uint8_t>(0);
|
||||
ldfData.Write<uint32_t>(networkSettings.size());
|
||||
|
||||
for (auto* networkSetting : networkSettings) {
|
||||
networkSetting->WriteToPacket(ldfData);
|
||||
}
|
||||
|
||||
// Finally write everything to the stream
|
||||
outBitStream.Write<uint32_t>(ldfData.GetNumberOfBytesUsed());
|
||||
outBitStream.Write(ldfData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CppScripts::Script* const ScriptComponent::GetScript() {
|
||||
return m_Script;
|
||||
}
|
||||
|
||||
void ScriptComponent::SetScript(const std::string& scriptName) {
|
||||
// Scripts are managed by the CppScripts class and are effecitvely singletons
|
||||
// and they may also be used by other script components so DON'T delete them.
|
||||
m_Script = CppScripts::GetScript(m_Parent, scriptName);
|
||||
}
|
||||
65
dGame/dComponents/ScriptComponent.h
Normal file
65
dGame/dComponents/ScriptComponent.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Darkflame Universe
|
||||
* Copyright 2018
|
||||
*/
|
||||
|
||||
#ifndef SCRIPTCOMPONENT_H
|
||||
#define SCRIPTCOMPONENT_H
|
||||
|
||||
#include "CppScripts.h"
|
||||
#include "Component.h"
|
||||
#include <string>
|
||||
#include "eReplicaComponentType.h"
|
||||
|
||||
class Entity;
|
||||
|
||||
/**
|
||||
* Handles the loading and execution of server side scripts on entities, scripts were originally written in Lua,
|
||||
* here they're written in C++
|
||||
*/
|
||||
class ScriptComponent final : public Component {
|
||||
public:
|
||||
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPT;
|
||||
|
||||
ScriptComponent(Entity* parent, std::string scriptName, bool serialized, bool client = false);
|
||||
~ScriptComponent() override;
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Returns the script that's attached to this entity
|
||||
* @return the script that's attached to this entity
|
||||
*/
|
||||
CppScripts::Script* const GetScript();
|
||||
|
||||
/**
|
||||
* Sets whether the entity should be serialized, unused
|
||||
* @param var whether the entity should be serialized
|
||||
*/
|
||||
void SetSerialized(const bool var) { m_Serialized = var; }
|
||||
|
||||
/**
|
||||
* Sets the script using a path by looking through dScripts for a script that matches
|
||||
* @param scriptName the name of the script to find
|
||||
*/
|
||||
void SetScript(const std::string& scriptName);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* The script attached to this entity
|
||||
*/
|
||||
CppScripts::Script* m_Script;
|
||||
|
||||
/**
|
||||
* Whether or not the comp should be serialized, unused
|
||||
*/
|
||||
bool m_Serialized;
|
||||
|
||||
/**
|
||||
* Whether or not this script is a client script
|
||||
*/
|
||||
bool m_Client;
|
||||
};
|
||||
|
||||
#endif // SCRIPTCOMPONENT_H
|
||||
@@ -268,9 +268,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c
|
||||
|
||||
behavior->Calculate(context, bitStream, { target, 0 });
|
||||
|
||||
for (auto* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnSkillCast(m_Parent, skillId);
|
||||
}
|
||||
m_Parent->GetScript()->OnSkillCast(m_Parent, skillId);
|
||||
|
||||
if (!context->foundTarget) {
|
||||
delete context;
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "MovementAIComponent.h"
|
||||
#include "eEndBehavior.h"
|
||||
#include "PlayerManager.h"
|
||||
#include "Game.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo): Component(parent) {
|
||||
m_Parent = parent;
|
||||
@@ -194,9 +196,7 @@ std::vector<Entity*> TriggerComponent::GatherTargets(LUTriggers::Command* comman
|
||||
}
|
||||
|
||||
void TriggerComponent::HandleFireEvent(Entity* targetEntity, std::string args) {
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(targetEntity)) {
|
||||
script->OnFireEventServerSide(targetEntity, m_Parent, args, 0, 0, 0);
|
||||
}
|
||||
targetEntity->GetScript()->OnFireEventServerSide(targetEntity, m_Parent, args, 0, 0, 0);
|
||||
}
|
||||
|
||||
void TriggerComponent::HandleDestroyObject(Entity* targetEntity, std::string args){
|
||||
|
||||
@@ -40,9 +40,19 @@ void VendorComponent::RefreshInventory(bool isCreation) {
|
||||
SetHasMultiCostItems(false);
|
||||
m_Inventory.clear();
|
||||
|
||||
// Custom code for Max vanity NPC and Mr.Ree cameras
|
||||
if(isCreation && m_Parent->GetLOT() == 9749 && Game::server->GetZoneID() == 1201) {
|
||||
SetupMaxCustomVendor();
|
||||
// Custom code for Vanity Vendor Invetory Override
|
||||
if(m_Parent->HasVar(u"vendorInvOverride")) {
|
||||
std::vector<std::string> items = GeneralUtils::SplitString(m_Parent->GetVarAsString(u"vendorInvOverride"), ',');
|
||||
uint32_t sortPriority = -1;
|
||||
for (auto& itemString : items) {
|
||||
itemString.erase(remove_if(itemString.begin(), itemString.end(), isspace), itemString.end());
|
||||
auto item = GeneralUtils::TryParse<uint32_t>(itemString);
|
||||
if (!item) continue;
|
||||
if (SetupItem(item.value())) {
|
||||
sortPriority++;
|
||||
m_Inventory.push_back(SoldItem(item.value(), sortPriority));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -52,24 +62,12 @@ void VendorComponent::RefreshInventory(bool isCreation) {
|
||||
if (lootMatrices.empty()) return;
|
||||
|
||||
auto* lootTableTable = CDClientManager::GetTable<CDLootTableTable>();
|
||||
auto* itemComponentTable = CDClientManager::GetTable<CDItemComponentTable>();
|
||||
auto* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
|
||||
for (const auto& lootMatrix : lootMatrices) {
|
||||
auto vendorItems = lootTableTable->GetTable(lootMatrix.LootTableIndex);
|
||||
if (lootMatrix.maxToDrop == 0 || lootMatrix.minToDrop == 0) {
|
||||
for (const auto& item : vendorItems) {
|
||||
if (!m_HasStandardCostItems || !m_HasMultiCostItems) {
|
||||
auto itemComponentID = compRegistryTable->GetByIDAndType(item.itemid, eReplicaComponentType::ITEM, -1);
|
||||
if (itemComponentID == -1) {
|
||||
LOG("Attempted to add item %i with ItemComponent ID -1 to vendor %i inventory. Not adding item!", itemComponentID, m_Parent->GetLOT());
|
||||
continue;
|
||||
}
|
||||
auto itemComponent = itemComponentTable->GetItemComponentByID(itemComponentID);
|
||||
if (!m_HasStandardCostItems && itemComponent.baseValue != -1) SetHasStandardCostItems(true);
|
||||
if (!m_HasMultiCostItems && !itemComponent.currencyCosts.empty()) SetHasMultiCostItems(true);
|
||||
}
|
||||
m_Inventory.push_back(SoldItem(item.itemid, item.sortPriority));
|
||||
if (SetupItem(item.itemid)) m_Inventory.push_back(SoldItem(item.itemid, item.sortPriority));
|
||||
}
|
||||
} else {
|
||||
auto randomCount = GeneralUtils::GenerateRandomNumber<int32_t>(lootMatrix.minToDrop, lootMatrix.maxToDrop);
|
||||
@@ -79,17 +77,7 @@ void VendorComponent::RefreshInventory(bool isCreation) {
|
||||
auto randomItemIndex = GeneralUtils::GenerateRandomNumber<int32_t>(0, vendorItems.size() - 1);
|
||||
const auto& randomItem = vendorItems.at(randomItemIndex);
|
||||
vendorItems.erase(vendorItems.begin() + randomItemIndex);
|
||||
if (!m_HasStandardCostItems || !m_HasMultiCostItems) {
|
||||
auto itemComponentID = compRegistryTable->GetByIDAndType(randomItem.itemid, eReplicaComponentType::ITEM, -1);
|
||||
if (itemComponentID == -1) {
|
||||
LOG("Attempted to add item %i with ItemComponent ID -1 to vendor %i inventory. Not adding item!", itemComponentID, m_Parent->GetLOT());
|
||||
continue;
|
||||
}
|
||||
auto itemComponent = itemComponentTable->GetItemComponentByID(itemComponentID);
|
||||
if (!m_HasStandardCostItems && itemComponent.baseValue != -1) SetHasStandardCostItems(true);
|
||||
if (!m_HasMultiCostItems && !itemComponent.currencyCosts.empty()) SetHasMultiCostItems(true);
|
||||
}
|
||||
m_Inventory.push_back(SoldItem(randomItem.itemid, randomItem.sortPriority));
|
||||
if (SetupItem(randomItem.itemid)) m_Inventory.push_back(SoldItem(randomItem.itemid, randomItem.sortPriority));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,15 +114,6 @@ bool VendorComponent::SellsItem(const LOT item) const {
|
||||
}) > 0;
|
||||
}
|
||||
|
||||
|
||||
void VendorComponent::SetupMaxCustomVendor(){
|
||||
SetHasStandardCostItems(true);
|
||||
m_Inventory.push_back(SoldItem(11909, 0)); // Top hat w frog
|
||||
m_Inventory.push_back(SoldItem(7785, 0)); // Flash bulb
|
||||
m_Inventory.push_back(SoldItem(12764, 0)); // Big fountain soda
|
||||
m_Inventory.push_back(SoldItem(12241, 0)); // Hot cocoa (from fb)
|
||||
}
|
||||
|
||||
void VendorComponent::HandleMrReeCameras(){
|
||||
if (m_Parent->GetLOT() == 13569) {
|
||||
SetHasStandardCostItems(true);
|
||||
@@ -211,5 +190,25 @@ void VendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
|
||||
character->SetCoins(character->GetCoins() - (coinCost), eLootSourceType::VENDOR);
|
||||
inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR);
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS);
|
||||
}
|
||||
|
||||
bool VendorComponent::SetupItem(LOT item) {
|
||||
|
||||
auto* itemComponentTable = CDClientManager::GetTable<CDItemComponentTable>();
|
||||
auto* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
|
||||
auto itemComponentID = compRegistryTable->GetByIDAndType(item, eReplicaComponentType::ITEM, -1);
|
||||
if (itemComponentID == -1) {
|
||||
LOG("Attempted to add item %i with ItemComponent ID -1 to vendor %i inventory. Not adding item!", itemComponentID, m_Parent->GetLOT());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_HasStandardCostItems || !m_HasMultiCostItems) {
|
||||
auto itemComponent = itemComponentTable->GetItemComponentByID(itemComponentID);
|
||||
if (!m_HasStandardCostItems && itemComponent.baseValue != -1) SetHasStandardCostItems(true);
|
||||
if (!m_HasMultiCostItems && !itemComponent.currencyCosts.empty()) SetHasMultiCostItems(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
void OnUse(Entity* originator) override;
|
||||
void RefreshInventory(bool isCreation = false);
|
||||
virtual void RefreshInventory(bool isCreation = false);
|
||||
void SetupConstants();
|
||||
bool SellsItem(const LOT item) const;
|
||||
float GetBuyScalar() const { return m_BuyScalar; }
|
||||
@@ -50,8 +50,8 @@ public:
|
||||
void Buy(Entity* buyer, LOT lot, uint32_t count);
|
||||
|
||||
private:
|
||||
void SetupMaxCustomVendor();
|
||||
void HandleMrReeCameras();
|
||||
bool SetupItem(LOT item);
|
||||
float m_BuyScalar = 0.0f;
|
||||
float m_SellScalar = 0.0f;
|
||||
float m_RefreshTimeSeconds = 0.0f;
|
||||
|
||||
Reference in New Issue
Block a user