Merge branch 'main' into cdclient-rework

This commit is contained in:
David Markowitz
2023-07-27 20:03:12 -07:00
1177 changed files with 21192 additions and 13777 deletions

View File

@@ -2,13 +2,18 @@
#include "BehaviorBranchContext.h"
#include "BehaviorContext.h"
#include "EntityManager.h"
#include "Game.h"
#include "dLogger.h"
void AirMovementBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
uint32_t handle;
uint32_t handle{};
bitStream->Read(handle);
if (!bitStream->Read(handle)) {
Game::logger->Log("AirMovementBehavior", "Unable to read handle from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
}
context->RegisterSyncBehavior(handle, this, branch);
context->RegisterSyncBehavior(handle, this, branch, this->m_Timeout);
}
void AirMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
@@ -17,23 +22,30 @@ void AirMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStream*
bitStream->Write(handle);
}
void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) {
uint32_t behaviorId;
void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
uint32_t behaviorId{};
bit_stream->Read(behaviorId);
if (!bitStream->Read(behaviorId)) {
Game::logger->Log("AirMovementBehavior", "Unable to read behaviorId from bitStream, aborting Sync! %i", bitStream->GetNumberOfUnreadBits());
return;
}
LWOOBJID target;
LWOOBJID target{};
bit_stream->Read(target);
if (!bitStream->Read(target)) {
Game::logger->Log("AirMovementBehavior", "Unable to read target from bitStream, aborting Sync! %i", bitStream->GetNumberOfUnreadBits());
return;
}
auto* behavior = CreateBehavior(behaviorId);
if (EntityManager::Instance()->GetEntity(target) != nullptr) {
if (Game::entityManager->GetEntity(target) != nullptr) {
branch.target = target;
}
behavior->Handle(context, bit_stream, branch);
behavior->Handle(context, bitStream, branch);
}
void AirMovementBehavior::Load() {
this->m_Timeout = (GetFloat("timeout_ms") / 1000.0f);
}

View File

@@ -4,19 +4,15 @@
class AirMovementBehavior final : public Behavior
{
public:
/*
* Inherited
*/
explicit AirMovementBehavior(const uint32_t behavior_id) : Behavior(behavior_id) {
}
explicit AirMovementBehavior(const uint32_t behavior_id) : Behavior(behavior_id) {}
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Sync(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) override;
void Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Load() override;
private:
float m_Timeout;
};

View File

@@ -6,7 +6,7 @@
void ApplyBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target == LWOOBJID_EMPTY ? context->originator : branch.target);
auto* entity = Game::entityManager->GetEntity(branch.target == LWOOBJID_EMPTY ? context->originator : branch.target);
if (entity == nullptr) return;
@@ -19,7 +19,7 @@ void ApplyBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS
}
void ApplyBuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
auto* entity = Game::entityManager->GetEntity(branch.target);
if (entity == nullptr) return;

View File

@@ -9,11 +9,16 @@
#include "BehaviorContext.h"
#include "RebuildComponent.h"
#include "DestroyableComponent.h"
#include "Game.h"
#include "dLogger.h"
void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
uint32_t targetCount;
uint32_t targetCount{};
bitStream->Read(targetCount);
if (!bitStream->Read(targetCount)) {
Game::logger->Log("AreaOfEffectBehavior", "Unable to read targetCount from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
}
if (targetCount > this->m_maxTargets) {
return;
@@ -24,9 +29,12 @@ void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* b
targets.reserve(targetCount);
for (auto i = 0u; i < targetCount; ++i) {
LWOOBJID target;
LWOOBJID target{};
bitStream->Read(target);
if (!bitStream->Read(target)) {
Game::logger->Log("AreaOfEffectBehavior", "failed to read in target %i from bitStream, aborting target Handle!", i);
return;
};
targets.push_back(target);
}
@@ -39,10 +47,9 @@ void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* b
}
void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* self = EntityManager::Instance()->GetEntity(context->caster);
auto* self = Game::entityManager->GetEntity(context->caster);
if (self == nullptr) {
Game::logger->Log("TacArcBehavior", "Invalid self for (%llu)!", context->originator);
Game::logger->Log("AreaOfEffectBehavior", "Invalid self for (%llu)!", context->originator);
return;
}
@@ -51,7 +58,7 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream
std::vector<Entity*> targets;
auto* presetTarget = EntityManager::Instance()->GetEntity(branch.target);
auto* presetTarget = Game::entityManager->GetEntity(branch.target);
if (presetTarget != nullptr) {
if (this->m_radius * this->m_radius >= Vector3::DistanceSquared(reference, presetTarget->GetPosition())) {
@@ -68,10 +75,10 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream
// Gets all of the valid targets, passing in if should target enemies and friends
for (auto validTarget : context->GetValidTargets(m_ignoreFaction, includeFaction, m_TargetSelf == 1, m_targetEnemy == 1, m_targetFriend == 1)) {
auto* entity = EntityManager::Instance()->GetEntity(validTarget);
auto* entity = Game::entityManager->GetEntity(validTarget);
if (entity == nullptr) {
Game::logger->Log("TacArcBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator);
Game::logger->Log("AreaOfEffectBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator);
continue;
}

View File

@@ -5,12 +5,15 @@
#include "dLogger.h"
void AttackDelayBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
uint32_t handle;
uint32_t handle{};
bitStream->Read(handle);
if (!bitStream->Read(handle)) {
Game::logger->Log("AttackDelayBehavior", "Unable to read handle from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
for (auto i = 0u; i < this->m_numIntervals; ++i) {
context->RegisterSyncBehavior(handle, this, branch);
context->RegisterSyncBehavior(handle, this, branch, this->m_delay * i, m_ignoreInterrupts);
}
}

View File

@@ -5,146 +5,251 @@
#include "EntityManager.h"
#include "DestroyableComponent.h"
#include "BehaviorContext.h"
#include "eBasicAttackSuccessTypes.h"
void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
if (context->unmanaged) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
auto* entity = Game::entityManager->GetEntity(branch.target);
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
if (destroyableComponent != nullptr) {
PlayFx(u"onhit", entity->GetObjectID());
destroyableComponent->Damage(this->m_maxDamage, context->originator, context->skillID);
destroyableComponent->Damage(this->m_MaxDamage, context->originator, context->skillID);
}
this->m_onSuccess->Handle(context, bitStream, branch);
this->m_OnSuccess->Handle(context, bitStream, branch);
return;
}
bitStream->AlignReadToByteBoundary();
uint16_t allocatedBits;
bitStream->Read(allocatedBits);
uint16_t allocatedBits{};
if (!bitStream->Read(allocatedBits) || allocatedBits == 0) {
Game::logger->LogDebug("BasicAttackBehavior", "No allocated bits");
return;
}
Game::logger->LogDebug("BasicAttackBehavior", "Number of allocated bits %i", allocatedBits);
const auto baseAddress = bitStream->GetReadOffset();
if (bitStream->ReadBit()) { // Blocked
return;
}
if (bitStream->ReadBit()) { // Immune
return;
}
if (bitStream->ReadBit()) { // Success
uint32_t unknown;
bitStream->Read(unknown);
uint32_t damageDealt;
bitStream->Read(damageDealt);
// A value that's too large may be a cheating attempt, so we set it to MIN too
if (damageDealt > this->m_maxDamage || damageDealt < this->m_minDamage) {
damageDealt = this->m_minDamage;
}
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
bool died;
bitStream->Read(died);
if (entity != nullptr) {
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
if (destroyableComponent != nullptr) {
PlayFx(u"onhit", entity->GetObjectID());
destroyableComponent->Damage(damageDealt, context->originator, context->skillID);
}
}
}
uint8_t successState;
bitStream->Read(successState);
switch (successState) {
case 1:
this->m_onSuccess->Handle(context, bitStream, branch);
break;
default:
Game::logger->Log("BasicAttackBehavior", "Unknown success state (%i)!", successState);
break;
}
DoHandleBehavior(context, bitStream, branch);
bitStream->SetReadOffset(baseAddress + allocatedBits);
}
void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* self = EntityManager::Instance()->GetEntity(context->originator);
if (self == nullptr) {
Game::logger->Log("BasicAttackBehavior", "Invalid self entity (%llu)!", context->originator);
void BasicAttackBehavior::DoHandleBehavior(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* targetEntity = Game::entityManager->GetEntity(branch.target);
if (!targetEntity) {
Game::logger->Log("BasicAttackBehavior", "Target targetEntity %llu not found.", branch.target);
return;
}
auto* destroyableComponent = targetEntity->GetComponent<DestroyableComponent>();
if (!destroyableComponent) {
Game::logger->Log("BasicAttackBehavior", "No destroyable found on the obj/lot %llu/%i", branch.target, targetEntity->GetLOT());
return;
}
bool isBlocked{};
bool isImmune{};
bool isSuccess{};
if (!bitStream->Read(isBlocked)) {
Game::logger->Log("BasicAttackBehavior", "Unable to read isBlocked");
return;
}
if (isBlocked) {
destroyableComponent->SetAttacksToBlock(std::min(destroyableComponent->GetAttacksToBlock() - 1, 0U));
Game::entityManager->SerializeEntity(targetEntity);
this->m_OnFailBlocked->Handle(context, bitStream, branch);
return;
}
if (!bitStream->Read(isImmune)) {
Game::logger->Log("BasicAttackBehavior", "Unable to read isImmune");
return;
}
if (isImmune) {
this->m_OnFailImmune->Handle(context, bitStream, branch);
return;
}
if (!bitStream->Read(isSuccess)) {
Game::logger->Log("BasicAttackBehavior", "failed to read success from bitstream");
return;
}
if (isSuccess) {
uint32_t armorDamageDealt{};
if (!bitStream->Read(armorDamageDealt)) {
Game::logger->Log("BasicAttackBehavior", "Unable to read armorDamageDealt");
return;
}
uint32_t healthDamageDealt{};
if (!bitStream->Read(healthDamageDealt)) {
Game::logger->Log("BasicAttackBehavior", "Unable to read healthDamageDealt");
return;
}
uint32_t totalDamageDealt = armorDamageDealt + healthDamageDealt;
// A value that's too large may be a cheating attempt, so we set it to MIN
if (totalDamageDealt > this->m_MaxDamage) {
totalDamageDealt = this->m_MinDamage;
}
bool died{};
if (!bitStream->Read(died)) {
Game::logger->Log("BasicAttackBehavior", "Unable to read died");
return;
}
auto previousArmor = destroyableComponent->GetArmor();
auto previousHealth = destroyableComponent->GetHealth();
PlayFx(u"onhit", targetEntity->GetObjectID());
destroyableComponent->Damage(totalDamageDealt, context->originator, context->skillID);
}
uint8_t successState{};
if (!bitStream->Read(successState)) {
Game::logger->Log("BasicAttackBehavior", "Unable to read success state");
return;
}
switch (static_cast<eBasicAttackSuccessTypes>(successState)) {
case eBasicAttackSuccessTypes::SUCCESS:
this->m_OnSuccess->Handle(context, bitStream, branch);
break;
case eBasicAttackSuccessTypes::FAILARMOR:
this->m_OnFailArmor->Handle(context, bitStream, branch);
break;
default:
if (static_cast<eBasicAttackSuccessTypes>(successState) != eBasicAttackSuccessTypes::FAILIMMUNE) {
Game::logger->Log("BasicAttackBehavior", "Unknown success state (%i)!", successState);
return;
}
this->m_OnFailImmune->Handle(context, bitStream, branch);
break;
}
}
void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
bitStream->AlignWriteToByteBoundary();
const auto allocatedAddress = bitStream->GetWriteOffset();
bitStream->Write(uint16_t(0));
bitStream->Write<uint16_t>(0);
const auto startAddress = bitStream->GetWriteOffset();
bitStream->Write0(); // Blocked
bitStream->Write0(); // Immune
bitStream->Write1(); // Success
if (true) {
uint32_t unknown3 = 0;
bitStream->Write(unknown3);
auto damage = this->m_minDamage;
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
if (entity == nullptr) {
damage = 0;
bitStream->Write(damage);
bitStream->Write(false);
} else {
bitStream->Write(damage);
bitStream->Write(true);
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
if (damage != 0 && destroyableComponent != nullptr) {
PlayFx(u"onhit", entity->GetObjectID(), 1);
destroyableComponent->Damage(damage, context->originator, context->skillID, false);
context->ScheduleUpdate(branch.target);
}
}
}
uint8_t successState = 1;
bitStream->Write(successState);
switch (successState) {
case 1:
this->m_onSuccess->Calculate(context, bitStream, branch);
break;
default:
Game::logger->Log("BasicAttackBehavior", "Unknown success state (%i)!", successState);
break;
}
DoBehaviorCalculation(context, bitStream, branch);
const auto endAddress = bitStream->GetWriteOffset();
const uint16_t allocate = endAddress - startAddress + 1;
const uint16_t allocate = endAddress - startAddress;
bitStream->SetWriteOffset(allocatedAddress);
bitStream->Write(allocate);
bitStream->SetWriteOffset(startAddress + allocate);
}
void BasicAttackBehavior::Load() {
this->m_minDamage = GetInt("min damage");
if (this->m_minDamage == 0) this->m_minDamage = 1;
void BasicAttackBehavior::DoBehaviorCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* targetEntity = Game::entityManager->GetEntity(branch.target);
if (!targetEntity) {
Game::logger->Log("BasicAttackBehavior", "Target entity %llu is null!", branch.target);
return;
}
this->m_maxDamage = GetInt("max damage");
if (this->m_maxDamage == 0) this->m_maxDamage = 1;
auto* destroyableComponent = targetEntity->GetComponent<DestroyableComponent>();
if (!destroyableComponent || !destroyableComponent->GetParent()) {
Game::logger->Log("BasicAttackBehavior", "No destroyable component on %llu", branch.target);
return;
}
this->m_onSuccess = GetAction("on_success");
const bool isBlocking = destroyableComponent->GetAttacksToBlock() > 0;
bitStream->Write(isBlocking);
if (isBlocking) {
destroyableComponent->SetAttacksToBlock(destroyableComponent->GetAttacksToBlock() - 1);
Game::entityManager->SerializeEntity(targetEntity);
this->m_OnFailBlocked->Calculate(context, bitStream, branch);
return;
}
const bool isImmune = destroyableComponent->IsImmune();
bitStream->Write(isImmune);
if (isImmune) {
this->m_OnFailImmune->Calculate(context, bitStream, branch);
return;
}
bool isSuccess = false;
const uint32_t previousHealth = destroyableComponent->GetHealth();
const uint32_t previousArmor = destroyableComponent->GetArmor();
const auto damage = this->m_MinDamage;
PlayFx(u"onhit", targetEntity->GetObjectID(), 1);
destroyableComponent->Damage(damage, context->originator, context->skillID, false);
context->ScheduleUpdate(branch.target);
const uint32_t armorDamageDealt = previousArmor - destroyableComponent->GetArmor();
const uint32_t healthDamageDealt = previousHealth - destroyableComponent->GetHealth();
isSuccess = armorDamageDealt > 0 || healthDamageDealt > 0 || (armorDamageDealt + healthDamageDealt) > 0;
bitStream->Write(isSuccess);
eBasicAttackSuccessTypes successState = eBasicAttackSuccessTypes::FAILIMMUNE;
if (isSuccess) {
if (healthDamageDealt >= 1) {
successState = eBasicAttackSuccessTypes::SUCCESS;
} else if (armorDamageDealt >= 1) {
successState = this->m_OnFailArmor->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY ? eBasicAttackSuccessTypes::FAILIMMUNE : eBasicAttackSuccessTypes::FAILARMOR;
}
bitStream->Write(armorDamageDealt);
bitStream->Write(healthDamageDealt);
bitStream->Write(targetEntity->GetIsDead());
}
bitStream->Write(successState);
switch (static_cast<eBasicAttackSuccessTypes>(successState)) {
case eBasicAttackSuccessTypes::SUCCESS:
this->m_OnSuccess->Calculate(context, bitStream, branch);
break;
case eBasicAttackSuccessTypes::FAILARMOR:
this->m_OnFailArmor->Calculate(context, bitStream, branch);
break;
default:
if (static_cast<eBasicAttackSuccessTypes>(successState) != eBasicAttackSuccessTypes::FAILIMMUNE) {
Game::logger->Log("BasicAttackBehavior", "Unknown success state (%i)!", successState);
break;
}
this->m_OnFailImmune->Calculate(context, bitStream, branch);
break;
}
}
void BasicAttackBehavior::Load() {
this->m_MinDamage = GetInt("min damage");
if (this->m_MinDamage == 0) this->m_MinDamage = 1;
this->m_MaxDamage = GetInt("max damage");
if (this->m_MaxDamage == 0) this->m_MaxDamage = 1;
// The client sets the minimum damage to maximum, so we'll do the same. These are usually the same value anyways.
if (this->m_MinDamage < this->m_MaxDamage) this->m_MinDamage = this->m_MaxDamage;
this->m_OnSuccess = GetAction("on_success");
this->m_OnFailArmor = GetAction("on_fail_armor");
this->m_OnFailImmune = GetAction("on_fail_immune");
this->m_OnFailBlocked = GetAction("on_fail_blocked");
}

View File

@@ -4,18 +4,59 @@
class BasicAttackBehavior final : public Behavior
{
public:
uint32_t m_minDamage;
uint32_t m_maxDamage;
Behavior* m_onSuccess;
explicit BasicAttackBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {
}
/**
* @brief Reads a 16bit short from the bitStream and when the actual behavior handling finishes with all of its branches, the bitStream
* is then offset to after the allocated bits for this stream.
*
*/
void DoHandleBehavior(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch);
/**
* @brief Handles a client initialized Basic Attack Behavior cast to be deserialized and verified on the server.
*
* @param context The Skill's Behavior context. All behaviors in the same tree share the same context
* @param bitStream The bitStream to deserialize. BitStreams will always check their bounds before reading in a behavior
* and will fail gracefully if an overread is detected.
* @param branch The context of this specific branch of the Skill Behavior. Changes based on which branch you are going down.
*/
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
/**
* @brief Writes a 16bit short to the bitStream and when the actual behavior calculation finishes with all of its branches, the number
* of bits used is then written to where the 16bit short initially was.
*
*/
void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
/**
* @brief Calculates a server initialized Basic Attack Behavior cast to be serialized to the client
*
* @param context The Skill's Behavior context. All behaviors in the same tree share the same context
* @param bitStream The bitStream to serialize to.
* @param branch The context of this specific branch of the Skill Behavior. Changes based on which branch you are going down.
*/
void DoBehaviorCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch);
/**
* @brief Loads this Behaviors parameters from the database. For this behavior specifically:
* max and min damage will always be the same. If min is less than max, they are both set to max.
* If an action is not in the database, then no action is taken for that result.
*
*/
void Load() override;
private:
uint32_t m_MinDamage;
uint32_t m_MaxDamage;
Behavior* m_OnSuccess;
Behavior* m_OnFailArmor;
Behavior* m_OnFailImmune;
Behavior* m_OnFailBlocked;
};

View File

@@ -42,11 +42,13 @@
#include "SkillCastFailedBehavior.h"
#include "SpawnBehavior.h"
#include "ForceMovementBehavior.h"
#include "RemoveBuffBehavior.h"
#include "ImmunityBehavior.h"
#include "InterruptBehavior.h"
#include "PlayEffectBehavior.h"
#include "DamageAbsorptionBehavior.h"
#include "VentureVisionBehavior.h"
#include "PropertyTeleportBehavior.h"
#include "BlockBehavior.h"
#include "ClearTargetBehavior.h"
#include "PullToPointBehavior.h"
@@ -59,6 +61,9 @@
#include "SpeedBehavior.h"
#include "DamageReductionBehavior.h"
#include "JetPackBehavior.h"
#include "FallSpeedBehavior.h"
#include "ChangeIdleFlagsBehavior.h"
#include "DarkInspirationBehavior.h"
//CDClient includes
#include "CDBehaviorParameterTable.h"
@@ -69,13 +74,14 @@
#include "EntityManager.h"
#include "RenderComponent.h"
#include "DestroyableComponent.h"
#include "CDBehaviorTemplateTable.h"
std::unordered_map<uint32_t, Behavior*> Behavior::Cache = {};
CDBehaviorParameterTable* Behavior::BehaviorParameterTable = nullptr;
Behavior* Behavior::GetBehavior(const uint32_t behaviorId) {
if (BehaviorParameterTable == nullptr) {
BehaviorParameterTable = CDClientManager::Instance()->GetTable<CDBehaviorParameterTable>("BehaviorParameter");
BehaviorParameterTable = CDClientManager::Instance().GetTable<CDBehaviorParameterTable>();
}
const auto pair = Cache.find(behaviorId);
@@ -159,7 +165,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) {
case BehaviorTemplates::BEHAVIOR_CAR_BOOST:
behavior = new CarBoostBehavior(behaviorId);
break;
case BehaviorTemplates::BEHAVIOR_FALL_SPEED: break;
case BehaviorTemplates::BEHAVIOR_FALL_SPEED:
behavior = new FallSpeedBehavior(behaviorId);
break;
case BehaviorTemplates::BEHAVIOR_SHIELD: break;
case BehaviorTemplates::BEHAVIOR_REPAIR_ARMOR:
behavior = new RepairBehavior(behaviorId);
@@ -167,7 +175,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) {
case BehaviorTemplates::BEHAVIOR_SPEED:
behavior = new SpeedBehavior(behaviorId);
break;
case BehaviorTemplates::BEHAVIOR_DARK_INSPIRATION: break;
case BehaviorTemplates::BEHAVIOR_DARK_INSPIRATION:
behavior = new DarkInspirationBehavior(behaviorId);
break;
case BehaviorTemplates::BEHAVIOR_LOOT_BUFF:
behavior = new LootBuffBehavior(behaviorId);
break;
@@ -195,7 +205,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) {
behavior = new SkillCastFailedBehavior(behaviorId);
break;
case BehaviorTemplates::BEHAVIOR_IMITATION_SKUNK_STINK: break;
case BehaviorTemplates::BEHAVIOR_CHANGE_IDLE_FLAGS: break;
case BehaviorTemplates::BEHAVIOR_CHANGE_IDLE_FLAGS:
behavior = new ChangeIdleFlagsBehavior(behaviorId);
break;
case BehaviorTemplates::BEHAVIOR_APPLY_BUFF:
behavior = new ApplyBuffBehavior(behaviorId);
break;
@@ -226,7 +238,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) {
break;
case BehaviorTemplates::BEHAVIOR_ALTER_CHAIN_DELAY: break;
case BehaviorTemplates::BEHAVIOR_CAMERA: break;
case BehaviorTemplates::BEHAVIOR_REMOVE_BUFF: break;
case BehaviorTemplates::BEHAVIOR_REMOVE_BUFF:
behavior = new RemoveBuffBehavior(behaviorId);
break;
case BehaviorTemplates::BEHAVIOR_GRAB: break;
case BehaviorTemplates::BEHAVIOR_MODULAR_BUILD: break;
case BehaviorTemplates::BEHAVIOR_NPC_COMBAT_SKILL:
@@ -254,7 +268,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) {
case BehaviorTemplates::BEHAVIOR_DAMAGE_REDUCTION:
behavior = new DamageReductionBehavior(behaviorId);
break;
case BehaviorTemplates::BEHAVIOR_PROPERTY_TELEPORT: break;
case BehaviorTemplates::BEHAVIOR_PROPERTY_TELEPORT:
behavior = new PropertyTeleportBehavior(behaviorId);
break;
case BehaviorTemplates::BEHAVIOR_PROPERTY_CLEAR_TARGET:
behavior = new ClearTargetBehavior(behaviorId);
break;
@@ -278,7 +294,7 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) {
}
BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) {
auto behaviorTemplateTable = CDClientManager::Instance()->GetTable<CDBehaviorTemplateTable>("BehaviorTemplate");
auto behaviorTemplateTable = CDClientManager::Instance().GetTable<CDBehaviorTemplateTable>();
BehaviorTemplates templateID = BehaviorTemplates::BEHAVIOR_EMPTY;
// Find behavior template by its behavior id. Default to 0.
@@ -298,7 +314,7 @@ BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) {
// For use with enemies, to display the correct damage animations on the players
void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID secondary) {
auto* targetEntity = EntityManager::Instance()->GetEntity(target);
auto* targetEntity = Game::entityManager->GetEntity(target);
if (targetEntity == nullptr) {
return;
@@ -386,7 +402,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID
}
Behavior::Behavior(const uint32_t behaviorId) {
auto behaviorTemplateTable = CDClientManager::Instance()->GetTable<CDBehaviorTemplateTable>("BehaviorTemplate");
auto behaviorTemplateTable = CDClientManager::Instance().GetTable<CDBehaviorTemplateTable>();
CDBehaviorTemplate templateInDatabase{};
@@ -429,8 +445,8 @@ Behavior::Behavior(const uint32_t behaviorId) {
float Behavior::GetFloat(const std::string& name, const float defaultValue) const {
// Get the behavior parameter entry and return its value.
if (!BehaviorParameterTable) BehaviorParameterTable = CDClientManager::Instance()->GetTable<CDBehaviorParameterTable>("BehaviorParameter");
return BehaviorParameterTable->GetEntry(this->m_behaviorId, name, defaultValue);
if (!BehaviorParameterTable) BehaviorParameterTable = CDClientManager::Instance().GetTable<CDBehaviorParameterTable>();
return BehaviorParameterTable->GetValue(this->m_behaviorId, name, defaultValue);
}
@@ -455,14 +471,8 @@ Behavior* Behavior::GetAction(float value) const {
}
std::map<std::string, float> Behavior::GetParameterNames() const {
std::map<std::string, float> templatesInDatabase;
// Find behavior template by its behavior id.
/*if (!BehaviorParameterTable) BehaviorParameterTable = CDClientManager::Instance()->GetTable<CDBehaviorParameterTable>("BehaviorParameter");
if (BehaviorParameterTable) {
templatesInDatabase = BehaviorParameterTable->GetParametersByBehaviorID(this->m_behaviorId);
}*/
return templatesInDatabase;
if (!BehaviorParameterTable) BehaviorParameterTable = CDClientManager::Instance().GetTable<CDBehaviorParameterTable>();
return BehaviorParameterTable->GetParametersByBehaviorID(this->m_behaviorId);
}
void Behavior::Load() {

View File

@@ -15,6 +15,8 @@ struct BehaviorBranchContext
uint32_t start = 0;
bool isSync = false;
BehaviorBranchContext();
BehaviorBranchContext(LWOOBJID target, float duration = 0, const NiPoint3& referencePosition = NiPoint3(0, 0, 0));

View File

@@ -10,10 +10,12 @@
#include <sstream>
#include "DestroyableComponent.h"
#include "EchoSyncSkill.h"
#include "PhantomPhysicsComponent.h"
#include "RebuildComponent.h"
#include "eReplicaComponentType.h"
#include "eConnectionType.h"
BehaviorSyncEntry::BehaviorSyncEntry() {
}
@@ -25,7 +27,7 @@ BehaviorEndEntry::BehaviorEndEntry() {
}
uint32_t BehaviorContext::GetUniqueSkillId() const {
auto* entity = EntityManager::Instance()->GetEntity(this->originator);
auto* entity = Game::entityManager->GetEntity(this->originator);
if (entity == nullptr) {
Game::logger->Log("BehaviorContext", "Invalid entity for (%llu)!", this->originator);
@@ -45,12 +47,17 @@ uint32_t BehaviorContext::GetUniqueSkillId() const {
}
void BehaviorContext::RegisterSyncBehavior(const uint32_t syncId, Behavior* behavior, const BehaviorBranchContext& branchContext) {
void BehaviorContext::RegisterSyncBehavior(const uint32_t syncId, Behavior* behavior, const BehaviorBranchContext& branchContext, const float duration, bool ignoreInterrupts) {
auto entry = BehaviorSyncEntry();
entry.handle = syncId;
entry.behavior = behavior;
entry.branchContext = branchContext;
entry.branchContext.isSync = true;
entry.ignoreInterrupts = ignoreInterrupts;
// Add 10 seconds + duration time to account for lag and give clients time to send their syncs to the server.
constexpr float lagTime = 10.0f;
entry.time = lagTime + duration;
this->syncEntries.push_back(entry);
}
@@ -87,11 +94,11 @@ void BehaviorContext::ScheduleUpdate(const LWOOBJID id) {
void BehaviorContext::ExecuteUpdates() {
for (const auto& id : this->scheduledUpdates) {
auto* entity = EntityManager::Instance()->GetEntity(id);
auto* entity = Game::entityManager->GetEntity(id);
if (entity == nullptr) continue;
EntityManager::Instance()->SerializeEntity(entity);
Game::entityManager->SerializeEntity(entity);
}
this->scheduledUpdates.clear();
@@ -179,6 +186,21 @@ void BehaviorContext::SyncCalculation(const uint32_t syncId, const float time, B
this->syncEntries.push_back(entry);
}
void BehaviorContext::UpdatePlayerSyncs(float deltaTime) {
uint32_t i = 0;
while (i < this->syncEntries.size()) {
auto& entry = this->syncEntries.at(i);
entry.time -= deltaTime;
if (entry.time >= 0.0f) {
i++;
continue;
}
this->syncEntries.erase(this->syncEntries.begin() + i);
}
}
void BehaviorContext::InvokeEnd(const uint32_t id) {
std::vector<BehaviorEndEntry> entries;
@@ -214,7 +236,7 @@ bool BehaviorContext::CalculateUpdate(const float deltaTime) {
}
// Echo sync
GameMessages::EchoSyncSkill echo;
EchoSyncSkill echo;
echo.bDone = true;
echo.uiBehaviorHandle = entry.handle;
@@ -231,7 +253,7 @@ bool BehaviorContext::CalculateUpdate(const float deltaTime) {
// Write message
RakNet::BitStream message;
PacketUtils::WriteHeader(message, CLIENT, MSG_CLIENT_GAME_MSG);
PacketUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG);
message.Write(this->originator);
echo.Serialize(&message);
@@ -286,7 +308,7 @@ void BehaviorContext::Reset() {
}
std::vector<LWOOBJID> BehaviorContext::GetValidTargets(int32_t ignoreFaction, int32_t includeFaction, bool targetSelf, bool targetEnemy, bool targetFriend) const {
auto* entity = EntityManager::Instance()->GetEntity(this->caster);
auto* entity = Game::entityManager->GetEntity(this->caster);
std::vector<LWOOBJID> targets;
@@ -298,7 +320,7 @@ std::vector<LWOOBJID> BehaviorContext::GetValidTargets(int32_t ignoreFaction, in
if (!ignoreFaction && !includeFaction) {
for (auto entry : entity->GetTargetsInPhantom()) {
auto* instance = EntityManager::Instance()->GetEntity(entry);
auto* instance = Game::entityManager->GetEntity(entry);
if (instance == nullptr) {
continue;
@@ -308,13 +330,13 @@ std::vector<LWOOBJID> BehaviorContext::GetValidTargets(int32_t ignoreFaction, in
}
}
if (ignoreFaction || includeFaction || (!entity->HasComponent(COMPONENT_TYPE_PHANTOM_PHYSICS) && targets.empty())) {
if (ignoreFaction || includeFaction || (!entity->HasComponent(eReplicaComponentType::PHANTOM_PHYSICS) && targets.empty())) {
DestroyableComponent* destroyableComponent;
if (!entity->TryGetComponent(COMPONENT_TYPE_DESTROYABLE, destroyableComponent)) {
if (!entity->TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent)) {
return targets;
}
auto entities = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS);
auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS);
for (auto* candidate : entities) {
const auto id = candidate->GetObjectID();

View File

@@ -80,7 +80,9 @@ struct BehaviorContext
uint32_t GetUniqueSkillId() const;
void RegisterSyncBehavior(uint32_t syncId, Behavior* behavior, const BehaviorBranchContext& branchContext);
void UpdatePlayerSyncs(float deltaTime);
void RegisterSyncBehavior(uint32_t syncId, Behavior* behavior, const BehaviorBranchContext& branchContext, const float duration, bool ignoreInterrupts = false);
void RegisterTimerBehavior(Behavior* behavior, const BehaviorBranchContext& branchContext, LWOOBJID second = LWOOBJID_EMPTY);

View File

@@ -10,7 +10,7 @@
void BlockBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
const auto target = context->originator;
auto* entity = EntityManager::Instance()->GetEntity(target);
auto* entity = Game::entityManager->GetEntity(target);
if (entity == nullptr) {
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target);
@@ -40,7 +40,7 @@ void BlockBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitSt
void BlockBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
const auto target = context->originator;
auto* entity = EntityManager::Instance()->GetEntity(target);
auto* entity = Game::entityManager->GetEntity(target);
if (entity == nullptr) {
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target);

View File

@@ -10,7 +10,7 @@
void BuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator;
auto* entity = EntityManager::Instance()->GetEntity(target);
auto* entity = Game::entityManager->GetEntity(target);
if (entity == nullptr) {
Game::logger->Log("BuffBehavior", "Invalid target (%llu)!", target);
@@ -30,7 +30,7 @@ void BuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream
component->SetMaxArmor(component->GetMaxArmor() + this->m_armor);
component->SetMaxImagination(component->GetMaxImagination() + this->m_imagination);
EntityManager::Instance()->SerializeEntity(entity);
Game::entityManager->SerializeEntity(entity);
if (!context->unmanaged) {
if (branch.duration > 0) {
@@ -44,7 +44,7 @@ void BuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream
void BuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator;
auto* entity = EntityManager::Instance()->GetEntity(target);
auto* entity = Game::entityManager->GetEntity(target);
if (entity == nullptr) {
Game::logger->Log("BuffBehavior", "Invalid target (%llu)!", target);
@@ -64,7 +64,7 @@ void BuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch
component->SetMaxArmor(component->GetMaxArmor() - this->m_armor);
component->SetMaxImagination(component->GetMaxImagination() - this->m_imagination);
EntityManager::Instance()->SerializeEntity(entity);
Game::entityManager->SerializeEntity(entity);
}
void BuffBehavior::Timer(BehaviorContext* context, const BehaviorBranchContext branch, LWOOBJID second) {

View File

@@ -12,14 +12,17 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp"
"BuffBehavior.cpp"
"CarBoostBehavior.cpp"
"ChainBehavior.cpp"
"ChangeIdleFlagsBehavior.cpp"
"ChangeOrientationBehavior.cpp"
"ChargeUpBehavior.cpp"
"ClearTargetBehavior.cpp"
"DamageAbsorptionBehavior.cpp"
"DamageReductionBehavior.cpp"
"DarkInspirationBehavior.cpp"
"DurationBehavior.cpp"
"EmptyBehavior.cpp"
"EndBehavior.cpp"
"FallSpeedBehavior.cpp"
"ForceMovementBehavior.cpp"
"HealBehavior.cpp"
"ImaginationBehavior.cpp"
@@ -33,7 +36,9 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp"
"OverTimeBehavior.cpp"
"PlayEffectBehavior.cpp"
"ProjectileAttackBehavior.cpp"
"PropertyTeleportBehavior.cpp"
"PullToPointBehavior.cpp"
"RemoveBuffBehavior.cpp"
"RepairBehavior.cpp"
"SkillCastFailedBehavior.cpp"
"SkillEventBehavior.cpp"

View File

@@ -11,7 +11,7 @@
void CarBoostBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
GameMessages::SendVehicleAddPassiveBoostAction(branch.target, UNASSIGNED_SYSTEM_ADDRESS);
auto* entity = EntityManager::Instance()->GetEntity(context->originator);
auto* entity = Game::entityManager->GetEntity(context->originator);
if (entity == nullptr) {
return;
@@ -22,7 +22,7 @@ void CarBoostBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitSt
auto* possessableComponent = entity->GetComponent<PossessableComponent>();
if (possessableComponent != nullptr) {
auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor());
auto* possessor = Game::entityManager->GetEntity(possessableComponent->GetPossessor());
if (possessor != nullptr) {
auto* characterComponent = possessor->GetComponent<CharacterComponent>();

View File

@@ -4,14 +4,19 @@
#include "dLogger.h"
void ChainBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
uint32_t chain_index;
uint32_t chainIndex{};
bitStream->Read(chain_index);
if (!bitStream->Read(chainIndex)) {
Game::logger->Log("ChainBehavior", "Unable to read chainIndex from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
}
chain_index--;
chainIndex--;
if (chain_index < this->m_behaviors.size()) {
this->m_behaviors.at(chain_index)->Handle(context, bitStream, branch);
if (chainIndex < this->m_behaviors.size()) {
this->m_behaviors.at(chainIndex)->Handle(context, bitStream, branch);
} else {
Game::logger->Log("ChainBehavior", "chainIndex out of bounds, aborting handle of chain %i bits unread %i", chainIndex, bitStream->GetNumberOfUnreadBits());
}
}

View File

@@ -0,0 +1,37 @@
#include "ChangeIdleFlagsBehavior.h"
#include "BehaviorContext.h"
#include "BehaviorBranchContext.h"
void ChangeIdleFlagsBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator;
if (!target) return;
GameMessages::SendChangeIdleFlags(target, m_FlagsOn, m_FlagsOff, UNASSIGNED_SYSTEM_ADDRESS);
if (branch.duration > 0.0f) {
context->RegisterTimerBehavior(this, branch);
} else if (branch.start > 0) {
context->RegisterEndBehavior(this, branch);
}
}
void ChangeIdleFlagsBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
Handle(context, bitStream, branch);
}
void ChangeIdleFlagsBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {
const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator;
if (!target) return;
// flip on and off to end behavior
GameMessages::SendChangeIdleFlags(target, m_FlagsOff, m_FlagsOn, UNASSIGNED_SYSTEM_ADDRESS);
}
void ChangeIdleFlagsBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {
End(context, branch, second);
}
void ChangeIdleFlagsBehavior::Load() {
m_FlagsOff = static_cast<eAnimationFlags>(GetInt("flags_off", 0));
m_FlagsOn = static_cast<eAnimationFlags>(GetInt("flags_on", 0));
}

View File

@@ -0,0 +1,23 @@
#pragma once
#include "Behavior.h"
#include "eAninmationFlags.h"
class ChangeIdleFlagsBehavior final : public Behavior {
public:
/*
* Inherited
*/
explicit ChangeIdleFlagsBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {}
void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override;
void End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override;
void Load() override;
private:
eAnimationFlags m_FlagsOff;
eAnimationFlags m_FlagsOn;
};

View File

@@ -2,43 +2,35 @@
#include "BehaviorBranchContext.h"
#include "BehaviorContext.h"
#include "EntityManager.h"
#include "BaseCombatAIComponent.h"
void ChangeOrientationBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
}
void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
if (!m_ToTarget) return; // TODO: Add the other arguments to this behavior
Entity* sourceEntity;
if (this->m_orientCaster) sourceEntity = Game::entityManager->GetEntity(context->originator);
else sourceEntity = Game::entityManager->GetEntity(branch.target);
if (!sourceEntity) return;
auto* self = EntityManager::Instance()->GetEntity(context->originator);
auto* other = EntityManager::Instance()->GetEntity(branch.target);
if (this->m_toTarget) {
Entity* destinationEntity;
if (this->m_orientCaster) destinationEntity = Game::entityManager->GetEntity(branch.target);
else destinationEntity = Game::entityManager->GetEntity(context->originator);
if (!destinationEntity) return;
if (self == nullptr || other == nullptr) return;
const auto source = self->GetPosition();
const auto destination = self->GetPosition();
if (m_OrientCaster) {
auto* baseCombatAIComponent = self->GetComponent<BaseCombatAIComponent>();
/*if (baseCombatAIComponent != nullptr)
{
baseCombatAIComponent->LookAt(destination);
}
else*/
{
self->SetRotation(NiQuaternion::LookAt(source, destination));
}
EntityManager::Instance()->SerializeEntity(self);
} else {
other->SetRotation(NiQuaternion::LookAt(destination, source));
EntityManager::Instance()->SerializeEntity(other);
}
sourceEntity->SetRotation(
NiQuaternion::LookAt(sourceEntity->GetPosition(), destinationEntity->GetPosition())
);
} else if (this->m_toAngle){
auto baseAngle = NiPoint3(0, 0, this->m_angle);
if (this->m_relative) baseAngle += sourceEntity->GetRotation().GetForwardVector();
sourceEntity->SetRotation(NiQuaternion::FromEulerAngles(baseAngle));
} else return;
Game::entityManager->SerializeEntity(sourceEntity);
return;
}
void ChangeOrientationBehavior::Load() {
m_OrientCaster = GetBoolean("orient_caster");
m_ToTarget = GetBoolean("to_target");
this->m_orientCaster = GetBoolean("orient_caster", true);
this->m_toTarget = GetBoolean("to_target", false);
this->m_toAngle = GetBoolean("to_angle", false);
this->m_angle = GetFloat("angle", 0.0f);
this->m_relative = GetBoolean("relative", false);
}

View File

@@ -2,24 +2,15 @@
#include "Behavior.h"
#include <vector>
class ChangeOrientationBehavior final : public Behavior
{
class ChangeOrientationBehavior final : public Behavior {
public:
bool m_OrientCaster;
bool m_ToTarget;
/*
* Inherited
*/
explicit ChangeOrientationBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {
}
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
explicit ChangeOrientationBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {}
void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Load() override;
private:
bool m_orientCaster;
bool m_toTarget;
bool m_toAngle;
float m_angle;
bool m_relative;
};

View File

@@ -1,14 +1,18 @@
#include "ChargeUpBehavior.h"
#include "BehaviorBranchContext.h"
#include "BehaviorContext.h"
#include "Game.h"
#include "dLogger.h"
void ChargeUpBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
uint32_t handle;
uint32_t handle{};
bitStream->Read(handle);
if (!bitStream->Read(handle)) {
Game::logger->Log("ChargeUpBehavior", "Unable to read handle from bitStream, aborting Handle! variable_type");
return;
};
context->RegisterSyncBehavior(handle, this, branch);
context->RegisterSyncBehavior(handle, this, branch, this->m_MaxDuration);
}
void ChargeUpBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
@@ -20,4 +24,5 @@ void ChargeUpBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitStre
void ChargeUpBehavior::Load() {
this->m_action = GetAction("action");
this->m_MaxDuration = GetFloat("max_duration");
}

View File

@@ -4,14 +4,7 @@
class ChargeUpBehavior final : public Behavior
{
public:
Behavior* m_action;
/*
* Inherited
*/
explicit ChargeUpBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {
}
explicit ChargeUpBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {}
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
@@ -20,4 +13,7 @@ public:
void Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Load() override;
private:
Behavior* m_action;
float m_MaxDuration;
};

View File

@@ -8,7 +8,7 @@
#include "DestroyableComponent.h"
void DamageAbsorptionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* target = Game::entityManager->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target);
@@ -34,7 +34,7 @@ void DamageAbsorptionBehavior::Calculate(BehaviorContext* context, RakNet::BitSt
}
void DamageAbsorptionBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) {
auto* target = EntityManager::Instance()->GetEntity(second);
auto* target = Game::entityManager->GetEntity(second);
if (target == nullptr) {
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", second);

View File

@@ -8,7 +8,7 @@
#include "DestroyableComponent.h"
void DamageReductionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* target = Game::entityManager->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->Log("DamageReductionBehavior", "Failed to find target (%llu)!", branch.target);
@@ -32,7 +32,7 @@ void DamageReductionBehavior::Calculate(BehaviorContext* context, RakNet::BitStr
}
void DamageReductionBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) {
auto* target = EntityManager::Instance()->GetEntity(second);
auto* target = Game::entityManager->GetEntity(second);
if (target == nullptr) {
Game::logger->Log("DamageReductionBehavior", "Failed to find target (%llu)!", second);

View File

@@ -0,0 +1,52 @@
#include "DarkInspirationBehavior.h"
#include "BehaviorBranchContext.h"
#include "Entity.h"
#include "DestroyableComponent.h"
#include "EntityManager.h"
#include "BehaviorContext.h"
void DarkInspirationBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
auto* target = Game::entityManager->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->LogDebug("DarkInspirationBehavior", "Failed to find target (%llu)!", branch.target);
return;
}
auto* destroyableComponent = target->GetComponent<DestroyableComponent>();
if (destroyableComponent == nullptr) {
return;
}
if (destroyableComponent->HasFaction(m_FactionList)) {
this->m_ActionIfFactionMatches->Handle(context, bitStream, branch);
}
}
void DarkInspirationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* target = Game::entityManager->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->LogDebug("DarkInspirationBehavior", "Failed to find target (%llu)!", branch.target);
return;
}
auto* destroyableComponent = target->GetComponent<DestroyableComponent>();
if (destroyableComponent == nullptr) {
return;
}
if (destroyableComponent->HasFaction(m_FactionList)) {
this->m_ActionIfFactionMatches->Calculate(context, bitStream, branch);
}
}
void DarkInspirationBehavior::Load() {
this->m_ActionIfFactionMatches = GetAction("action");
this->m_FactionList = GetInt("faction_list");
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include "Behavior.h"
class DarkInspirationBehavior final : public Behavior
{
public:
/*
* Inherited
*/
explicit DarkInspirationBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {
}
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Load() override;
private:
Behavior* m_ActionIfFactionMatches;
uint32_t m_FactionList;
};

View File

@@ -0,0 +1,50 @@
#include "FallSpeedBehavior.h"
#include "ControllablePhysicsComponent.h"
#include "BehaviorContext.h"
#include "BehaviorBranchContext.h"
void FallSpeedBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
// make sure required parameter has non-default value
if (m_PercentSlowed == 0.0f) return;
auto* target = Game::entityManager->GetEntity(branch.target);
if (!target) return;
auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return;
controllablePhysicsComponent->SetGravityScale(m_PercentSlowed);
Game::entityManager->SerializeEntity(target);
if (branch.duration > 0.0f) {
context->RegisterTimerBehavior(this, branch);
} else if (branch.start > 0) {
context->RegisterEndBehavior(this, branch);
}
}
void FallSpeedBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
Handle(context, bitStream, branch);
}
void FallSpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {
End(context, branch, second);
}
void FallSpeedBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
End(context, branch, LWOOBJID_EMPTY);
}
void FallSpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {
auto* target = Game::entityManager->GetEntity(branch.target);
if (!target) return;
auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return;
controllablePhysicsComponent->SetGravityScale(1);
Game::entityManager->SerializeEntity(target);
}
void FallSpeedBehavior::Load(){
m_PercentSlowed = GetFloat("percent_slowed");
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include "Behavior.h"
class FallSpeedBehavior final : public Behavior
{
public:
explicit FallSpeedBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {}
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override;
void End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override;
void UnCast(BehaviorContext* context, BehaviorBranchContext branch) override;
void Load() override;
private:
float m_PercentSlowed;
};

View File

@@ -3,23 +3,34 @@
#include "BehaviorContext.h"
#include "ControllablePhysicsComponent.h"
#include "EntityManager.h"
#include "Game.h"
#include "dLogger.h"
void ForceMovementBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
if (this->m_hitAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && this->m_hitEnemyAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && this->m_hitFactionAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) {
return;
}
uint32_t handle;
bitStream->Read(handle);
context->RegisterSyncBehavior(handle, this, branch);
uint32_t handle{};
if (!bitStream->Read(handle)) {
Game::logger->Log("ForceMovementBehavior", "Unable to read handle from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
}
context->RegisterSyncBehavior(handle, this, branch, this->m_Duration);
}
void ForceMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
uint32_t next;
bitStream->Read(next);
uint32_t next{};
if (!bitStream->Read(next)) {
Game::logger->Log("ForceMovementBehavior", "Unable to read target from bitStream, aborting Sync! %i", bitStream->GetNumberOfUnreadBits());
return;
}
LWOOBJID target;
bitStream->Read(target);
LWOOBJID target{};
if (!bitStream->Read(target)) {
Game::logger->Log("ForceMovementBehavior", "Unable to read target from bitStream, aborting Sync! %i", bitStream->GetNumberOfUnreadBits());
return;
}
branch.target = target;
auto* behavior = CreateBehavior(next);
@@ -31,7 +42,7 @@ void ForceMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStrea
return;
}
auto* casterEntity = EntityManager::Instance()->GetEntity(context->caster);
auto* casterEntity = Game::entityManager->GetEntity(context->caster);
if (casterEntity != nullptr) {
auto* controllablePhysicsComponent = casterEntity->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent != nullptr) {
@@ -40,7 +51,7 @@ void ForceMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStrea
controllablePhysicsComponent->SetVelocity(controllablePhysicsComponent->GetRotation().GetForwardVector() * 25);
}
EntityManager::Instance()->SerializeEntity(casterEntity);
Game::entityManager->SerializeEntity(casterEntity);
}
}
@@ -61,7 +72,7 @@ void ForceMovementBehavior::Load() {
}
void ForceMovementBehavior::SyncCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* casterEntity = EntityManager::Instance()->GetEntity(context->caster);
auto* casterEntity = Game::entityManager->GetEntity(context->caster);
if (casterEntity != nullptr) {
auto* controllablePhysicsComponent = casterEntity->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent != nullptr) {
@@ -69,11 +80,11 @@ void ForceMovementBehavior::SyncCalculation(BehaviorContext* context, RakNet::Bi
controllablePhysicsComponent->SetPosition(controllablePhysicsComponent->GetPosition() + controllablePhysicsComponent->GetVelocity() * m_Duration);
controllablePhysicsComponent->SetVelocity({});
EntityManager::Instance()->SerializeEntity(casterEntity);
Game::entityManager->SerializeEntity(casterEntity);
}
}
this->m_hitAction->Calculate(context, bitStream, branch);
this->m_hitEnemyAction->Calculate(context, bitStream, branch);
this->m_hitEnemyAction->Calculate(context, bitStream, branch);
this->m_hitFactionAction->Calculate(context, bitStream, branch);
}

View File

@@ -4,10 +4,11 @@
#include "dLogger.h"
#include "EntityManager.h"
#include "DestroyableComponent.h"
#include "eReplicaComponentType.h"
void HealBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
auto* entity = Game::entityManager->GetEntity(branch.target);
if (entity == nullptr) {
Game::logger->Log("HealBehavior", "Failed to find entity for (%llu)!", branch.target);
@@ -15,7 +16,7 @@ void HealBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_strea
return;
}
auto* destroyable = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE));
auto* destroyable = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE));
if (destroyable == nullptr) {
Game::logger->Log("HealBehavior", "Failed to find destroyable component for %(llu)!", branch.target);

View File

@@ -7,7 +7,7 @@
void ImaginationBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
auto* entity = Game::entityManager->GetEntity(branch.target);
if (entity == nullptr) {
return;

View File

@@ -6,28 +6,48 @@
#include "Game.h"
#include "dLogger.h"
#include "DestroyableComponent.h"
#include "ControllablePhysicsComponent.h"
#include "eStateChangeType.h"
void ImmunityBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* target = Game::entityManager->GetEntity(branch.target);
if (target == nullptr) {
if (!target) {
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target);
return;
}
auto* destroyable = static_cast<DestroyableComponent*>(target->GetComponent(COMPONENT_TYPE_DESTROYABLE));
if (destroyable == nullptr) {
return;
auto* destroyableComponent = target->GetComponent<DestroyableComponent>();
if (destroyableComponent) {
destroyableComponent->SetStatusImmunity(
eStateChangeType::PUSH,
this->m_ImmuneToBasicAttack,
this->m_ImmuneToDamageOverTime,
this->m_ImmuneToKnockback,
this->m_ImmuneToInterrupt,
this->m_ImmuneToSpeed,
this->m_ImmuneToImaginationGain,
this->m_ImmuneToImaginationLoss,
this->m_ImmuneToQuickbuildInterrupt,
this->m_ImmuneToPullToPoint
);
}
if (!this->m_immuneBasicAttack) {
return;
auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent) {
controllablePhysicsComponent->SetStunImmunity(
eStateChangeType::PUSH,
context->caster,
this->m_ImmuneToStunAttack,
this->m_ImmuneToStunEquip,
this->m_ImmuneToStunInteract,
this->m_ImmuneToStunJump,
this->m_ImmuneToStunMove,
this->m_ImmuneToStunTurn,
this->m_ImmuneToStunUseItem
);
}
destroyable->PushImmunity();
context->RegisterTimerBehavior(this, branch, target->GetObjectID());
}
@@ -36,23 +56,62 @@ void ImmunityBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bi
}
void ImmunityBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) {
auto* target = EntityManager::Instance()->GetEntity(second);
auto* target = Game::entityManager->GetEntity(second);
if (target == nullptr) {
if (!target) {
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", second);
return;
}
auto* destroyable = static_cast<DestroyableComponent*>(target->GetComponent(COMPONENT_TYPE_DESTROYABLE));
if (destroyable == nullptr) {
return;
auto* destroyableComponent = target->GetComponent<DestroyableComponent>();
if (destroyableComponent) {
destroyableComponent->SetStatusImmunity(
eStateChangeType::POP,
this->m_ImmuneToBasicAttack,
this->m_ImmuneToDamageOverTime,
this->m_ImmuneToKnockback,
this->m_ImmuneToInterrupt,
this->m_ImmuneToSpeed,
this->m_ImmuneToImaginationGain,
this->m_ImmuneToImaginationLoss,
this->m_ImmuneToQuickbuildInterrupt,
this->m_ImmuneToPullToPoint
);
}
auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent) {
controllablePhysicsComponent->SetStunImmunity(
eStateChangeType::POP,
context->caster,
this->m_ImmuneToStunAttack,
this->m_ImmuneToStunEquip,
this->m_ImmuneToStunInteract,
this->m_ImmuneToStunJump,
this->m_ImmuneToStunMove,
this->m_ImmuneToStunTurn,
this->m_ImmuneToStunUseItem
);
}
destroyable->PopImmunity();
}
void ImmunityBehavior::Load() {
this->m_immuneBasicAttack = GetBoolean("immune_basic_attack");
//Stun
this->m_ImmuneToStunAttack = GetBoolean("immune_stun_attack", false);
this->m_ImmuneToStunEquip = GetBoolean("immune_stun_equip", false);
this->m_ImmuneToStunInteract = GetBoolean("immune_stun_interact", false);
this->m_ImmuneToStunMove = GetBoolean("immune_stun_move", false);
this->m_ImmuneToStunTurn = GetBoolean("immune_stun_rotate", false);
// Status
this->m_ImmuneToBasicAttack = GetBoolean("immune_basic_attack", false);
this->m_ImmuneToDamageOverTime = GetBoolean("immune_damage_over_time", false);
this->m_ImmuneToKnockback = GetBoolean("immune_knockback", false);
this->m_ImmuneToInterrupt = GetBoolean("immune_interrupt", false);
this->m_ImmuneToSpeed = GetBoolean("immune_speed", false);
this->m_ImmuneToImaginationGain = GetBoolean("immune_imagination_gain", false);
this->m_ImmuneToImaginationLoss = GetBoolean("immune_imagination_loss", false);
this->m_ImmuneToQuickbuildInterrupt = GetBoolean("immune_quickbuild_interrupts", false);
this->m_ImmuneToPullToPoint = GetBoolean("immune_pulltopoint", false);
}

View File

@@ -4,8 +4,6 @@
class ImmunityBehavior final : public Behavior
{
public:
uint32_t m_immuneBasicAttack;
/*
* Inherited
*/
@@ -20,4 +18,25 @@ public:
void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override;
void Load() override;
private:
// stuns
bool m_ImmuneToStunAttack = false;
bool m_ImmuneToStunEquip = false;
bool m_ImmuneToStunInteract = false;
bool m_ImmuneToStunJump = false; // Unused
bool m_ImmuneToStunMove = false;
bool m_ImmuneToStunTurn = false;
bool m_ImmuneToStunUseItem = false; // Unused
//status
bool m_ImmuneToBasicAttack = false;
bool m_ImmuneToDamageOverTime = false;
bool m_ImmuneToKnockback = false;
bool m_ImmuneToInterrupt = false;
bool m_ImmuneToSpeed = false;
bool m_ImmuneToImaginationGain = false;
bool m_ImmuneToImaginationLoss = false;
bool m_ImmuneToQuickbuildInterrupt = false;
bool m_ImmuneToPullToPoint = false; // Unused in cdclient, but used in client
};

View File

@@ -11,7 +11,10 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS
if (branch.target != context->originator) {
bool unknown = false;
bitStream->Read(unknown);
if (!bitStream->Read(unknown)) {
Game::logger->Log("InterruptBehavior", "Unable to read unknown1 from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
if (unknown) return;
}
@@ -19,7 +22,10 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS
if (!this->m_interruptBlock) {
bool unknown = false;
bitStream->Read(unknown);
if (!bitStream->Read(unknown)) {
Game::logger->Log("InterruptBehavior", "Unable to read unknown2 from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
if (unknown) return;
}
@@ -28,12 +34,15 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS
{
bool unknown = false;
bitStream->Read(unknown);
if (!bitStream->Read(unknown)) {
Game::logger->Log("InterruptBehavior", "Unable to read unknown3 from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
}
if (branch.target == context->originator) return;
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* target = Game::entityManager->GetEntity(branch.target);
if (target == nullptr) return;
@@ -58,7 +67,7 @@ void InterruptBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* b
if (branch.target == context->originator) return;
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* target = Game::entityManager->GetEntity(branch.target);
if (target == nullptr) return;

View File

@@ -6,7 +6,7 @@
#include "Character.h"
void JetPackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
auto* entity = Game::entityManager->GetEntity(branch.target);
GameMessages::SendSetJetPackMode(entity, true, this->m_BypassChecks, this->m_EnableHover, this->m_effectId, this->m_Airspeed, this->m_MaxAirspeed, this->m_VerticalVelocity, this->m_WarningEffectID);
@@ -20,7 +20,7 @@ void JetPackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_st
}
void JetPackBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
auto* entity = Game::entityManager->GetEntity(branch.target);
GameMessages::SendSetJetPackMode(entity, false);

View File

@@ -6,17 +6,22 @@
#include "EntityManager.h"
#include "GameMessages.h"
#include "DestroyableComponent.h"
#include "Game.h"
#include "dLogger.h"
void KnockbackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
bool unknown;
bool unknown{};
bitStream->Read(unknown);
if (!bitStream->Read(unknown)) {
Game::logger->Log("KnockbackBehavior", "Unable to read unknown from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
}
void KnockbackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
bool blocked = false;
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* target = Game::entityManager->GetEntity(branch.target);
if (target != nullptr) {
auto* destroyableComponent = target->GetComponent<DestroyableComponent>();

View File

@@ -1,14 +1,14 @@
#include "LootBuffBehavior.h"
void LootBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto target = EntityManager::Instance()->GetEntity(context->caster);
auto target = Game::entityManager->GetEntity(context->caster);
if (!target) return;
auto controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return;
controllablePhysicsComponent->AddPickupRadiusScale(m_Scale);
EntityManager::Instance()->SerializeEntity(target);
Game::entityManager->SerializeEntity(target);
if (branch.duration > 0) context->RegisterTimerBehavior(this, branch);
@@ -19,14 +19,14 @@ void LootBuffBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bi
}
void LootBuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
auto target = EntityManager::Instance()->GetEntity(context->caster);
auto target = Game::entityManager->GetEntity(context->caster);
if (!target) return;
auto controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return;
controllablePhysicsComponent->RemovePickupRadiusScale(m_Scale);
EntityManager::Instance()->SerializeEntity(target);
Game::entityManager->SerializeEntity(target);
}
void LootBuffBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {

View File

@@ -4,18 +4,20 @@
#include "dLogger.h"
void MovementSwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
if (this->m_groundAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
this->m_jumpAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
this->m_fallingAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
this->m_doubleJumpAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
this->m_airAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
this->m_jetpackAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) {
uint32_t movementType{};
if (!bitStream->Read(movementType)) {
if (this->m_groundAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
this->m_jumpAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
this->m_fallingAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
this->m_doubleJumpAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
this->m_airAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
this->m_jetpackAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
this->m_movingAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) {
return;
}
Game::logger->Log("MovementSwitchBehavior", "Unable to read movementType from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
}
uint32_t movementType;
bitStream->Read(movementType);
};
switch (movementType) {
case 1:
@@ -25,34 +27,40 @@ void MovementSwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream*
this->m_jumpAction->Handle(context, bitStream, branch);
break;
case 3:
this->m_fallingAction->Handle(context, bitStream, branch);
this->m_airAction->Handle(context, bitStream, branch);
break;
case 4:
this->m_doubleJumpAction->Handle(context, bitStream, branch);
break;
case 5:
this->m_airAction->Handle(context, bitStream, branch);
this->m_fallingAction->Handle(context, bitStream, branch);
break;
case 6:
this->m_jetpackAction->Handle(context, bitStream, branch);
break;
default:
Game::logger->Log("MovementSwitchBehavior", "Invalid movement behavior type (%i)!", movementType);
this->m_groundAction->Handle(context, bitStream, branch);
break;
}
}
void MovementSwitchBehavior::Load() {
this->m_airAction = GetAction("air_action");
this->m_doubleJumpAction = GetAction("double_jump_action");
this->m_fallingAction = GetAction("falling_action");
this->m_groundAction = GetAction("ground_action");
this->m_jetpackAction = GetAction("jetpack_action");
this->m_jumpAction = GetAction("jump_action");
Behavior* MovementSwitchBehavior::LoadMovementType(std::string movementType) {
float actionValue = GetFloat(movementType, -1.0f);
auto loadedBehavior = GetAction(actionValue != -1.0f ? actionValue : 0.0f);
if (actionValue == -1.0f && loadedBehavior->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) {
loadedBehavior = this->m_groundAction;
}
return loadedBehavior;
}
void MovementSwitchBehavior::Load() {
float groundActionValue = GetFloat("ground_action", -1.0f);
this->m_groundAction = GetAction(groundActionValue != -1.0f ? groundActionValue : 0.0f);
this->m_airAction = LoadMovementType("air_action");
this->m_doubleJumpAction = LoadMovementType("double_jump_action");
this->m_fallingAction = LoadMovementType("falling_action");
this->m_jetpackAction = LoadMovementType("jetpack_action");
this->m_jumpAction = LoadMovementType("jump_action");
this->m_movingAction = LoadMovementType("moving_action");
}

View File

@@ -3,7 +3,7 @@
class MovementSwitchBehavior final : public Behavior
{
public:
private:
/*
* Members
*/
@@ -19,6 +19,17 @@ public:
Behavior* m_jumpAction;
Behavior* m_movingAction;
/**
* @brief Loads a movement type from the database into a behavior
*
* @param movementType The movement type to lookup in the database
* @param behaviorToLoad The Behavior where the result will be stored
*/
Behavior* LoadMovementType(std::string movementType);
public:
/*
* Inherited
*/

View File

@@ -6,17 +6,21 @@
#include "EntityManager.h"
#include "SkillComponent.h"
#include "DestroyableComponent.h"
#include "CDClientDatabase.h"
#include "CDClientManager.h"
#include "CDSkillBehaviorTable.h"
void OverTimeBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
const auto originator = context->originator;
auto* entity = EntityManager::Instance()->GetEntity(originator);
auto* entity = Game::entityManager->GetEntity(originator);
if (entity == nullptr) return;
for (size_t i = 0; i < m_NumIntervals; i++) {
entity->AddCallbackTimer((i + 1) * m_Delay, [originator, branch, this]() {
auto* entity = EntityManager::Instance()->GetEntity(originator);
auto* entity = Game::entityManager->GetEntity(originator);
if (entity == nullptr) return;
@@ -37,7 +41,7 @@ void OverTimeBehavior::Load() {
m_Action = GetInt("action");
// Since m_Action is a skillID and not a behavior, get is correlated behaviorID.
CDSkillBehaviorTable* skillTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior");
CDSkillBehaviorTable* skillTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>();
m_ActionBehaviorId = skillTable->GetSkillByID(m_Action).behaviorID;
m_Delay = GetFloat("delay");

View File

@@ -6,13 +6,17 @@
#include "dLogger.h"
#include "SkillComponent.h"
#include "../dWorldServer/ObjectIDManager.h"
#include "eObjectBits.h"
void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
LWOOBJID target;
LWOOBJID target{};
bitStream->Read(target);
if (!bitStream->Read(target)) {
Game::logger->Log("ProjectileAttackBehavior", "Unable to read target from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
auto* entity = EntityManager::Instance()->GetEntity(context->originator);
auto* entity = Game::entityManager->GetEntity(context->originator);
if (entity == nullptr) {
Game::logger->Log("ProjectileAttackBehavior", "Failed to find originator (%llu)!", context->originator);
@@ -28,17 +32,23 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea
return;
}
if (m_useMouseposit) {
if (m_useMouseposit && !branch.isSync) {
NiPoint3 targetPosition = NiPoint3::ZERO;
bitStream->Read(targetPosition);
if (!bitStream->Read(targetPosition)) {
Game::logger->Log("ProjectileAttackBehavior", "Unable to read targetPosition from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
}
auto* targetEntity = EntityManager::Instance()->GetEntity(target);
auto* targetEntity = Game::entityManager->GetEntity(target);
for (auto i = 0u; i < this->m_projectileCount; ++i) {
LWOOBJID projectileId;
LWOOBJID projectileId{};
bitStream->Read(projectileId);
if (!bitStream->Read(projectileId)) {
Game::logger->Log("ProjectileAttackBehavior", "Unable to read projectileId from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
branch.target = target;
branch.isProjectile = true;
@@ -51,7 +61,7 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea
void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
bitStream->Write(branch.target);
auto* entity = EntityManager::Instance()->GetEntity(context->originator);
auto* entity = Game::entityManager->GetEntity(context->originator);
if (entity == nullptr) {
Game::logger->Log("ProjectileAttackBehavior", "Failed to find originator (%llu)!", context->originator);
@@ -68,7 +78,7 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt
}
auto* other = EntityManager::Instance()->GetEntity(branch.target);
auto* other = Game::entityManager->GetEntity(branch.target);
if (other == nullptr) {
Game::logger->Log("ProjectileAttackBehavior", "Invalid projectile target (%llu)!", branch.target);
@@ -98,7 +108,7 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt
for (auto i = 0u; i < this->m_projectileCount; ++i) {
auto id = static_cast<LWOOBJID>(ObjectIDManager::Instance()->GenerateObjectID());
id = GeneralUtils::SetBit(id, OBJECT_BIT_CLIENT);
GeneralUtils::SetBit(id, eObjectBits::SPAWNED);
bitStream->Write(id);
@@ -148,4 +158,6 @@ void ProjectileAttackBehavior::Load() {
this->m_trackRadius = GetFloat("track_radius");
this->m_useMouseposit = GetBoolean("use_mouseposit");
this->m_ProjectileType = GetInt("projectile_type");
}

View File

@@ -23,6 +23,8 @@ public:
bool m_useMouseposit;
int32_t m_ProjectileType;
/*
* Inherited
*/

View File

@@ -0,0 +1,61 @@
#include "PropertyTeleportBehavior.h"
#include "BehaviorBranchContext.h"
#include "BehaviorContext.h"
#include "Character.h"
#include "CharacterComponent.h"
#include "ChatPackets.h"
#include "WorldPackets.h"
#include "EntityManager.h"
#include "Game.h"
#include "ZoneInstanceManager.h"
#include "dZoneManager.h"
void PropertyTeleportBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* caster = Game::entityManager->GetEntity(context->caster);
if (!caster) return;
auto* character = caster->GetCharacter();
if (!character) return;
LWOOBJID objId = caster->GetObjectID();
LWOMAPID targetMapId = m_MapId;
LWOCLONEID targetCloneId = character->GetPropertyCloneID();
if (Game::zoneManager->GetZoneID().GetCloneID() == character->GetPropertyCloneID()) {
targetMapId = character->GetLastNonInstanceZoneID();
targetCloneId = 0;
} else {
character->SetLastNonInstanceZoneID(Game::zoneManager->GetZoneID().GetMapID());
}
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, targetMapId, targetCloneId, false, [objId](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
auto* entity = Game::entityManager->GetEntity(objId);
if (!entity) return;
const auto sysAddr = entity->GetSystemAddress();
if (zoneClone != 0) ChatPackets::SendSystemMessage(sysAddr, u"Transfering to your property!");
else ChatPackets::SendSystemMessage(sysAddr, u"Transfering back to previous world!");
Game::logger->Log("PropertyTeleportBehavior", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i", sysAddr.ToString(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);
if (entity->GetCharacter()) {
entity->GetCharacter()->SetZoneID(zoneID);
entity->GetCharacter()->SetZoneInstance(zoneInstance);
entity->GetCharacter()->SetZoneClone(zoneClone);
entity->GetComponent<CharacterComponent>()->SetLastRocketConfig(u"");
}
entity->GetCharacter()->SaveXMLToDatabase();
WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift);
return;
});
}
void PropertyTeleportBehavior::Load() {
this->m_CancelIfInteracting = GetBoolean("cancel_if_interacting"); // TODO unused
this->m_MapId = LWOMAPID(GetInt("mapID"));
}

View File

@@ -0,0 +1,21 @@
#pragma once
#include "Behavior.h"
class PropertyTeleportBehavior final : public Behavior
{
public:
/*
* Inherited
*/
explicit PropertyTeleportBehavior(const uint32_t behavior_id) : Behavior(behavior_id) {
}
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Load() override;
private:
LWOMAPID m_MapId;
bool m_CancelIfInteracting;
};

View File

@@ -6,9 +6,9 @@
#include "MovementAIComponent.h"
void PullToPointBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* entity = EntityManager::Instance()->GetEntity(context->originator);
auto* entity = Game::entityManager->GetEntity(context->originator);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* target = Game::entityManager->GetEntity(branch.target);
if (entity == nullptr || target == nullptr) {
return;

View File

@@ -0,0 +1,21 @@
#include "RemoveBuffBehavior.h"
#include "BehaviorBranchContext.h"
#include "BehaviorContext.h"
#include "EntityManager.h"
#include "BuffComponent.h"
void RemoveBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* entity = Game::entityManager->GetEntity(context->caster);
if (!entity) return;
auto* buffComponent = entity->GetComponent<BuffComponent>();
if (!buffComponent) return;
buffComponent->RemoveBuff(m_BuffId, false, m_RemoveImmunity);
}
void RemoveBuffBehavior::Load() {
this->m_RemoveImmunity = GetBoolean("remove_immunity");
this->m_BuffId = GetInt("buff_id");
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include "Behavior.h"
class RemoveBuffBehavior final : public Behavior
{
public:
/*
* Inherited
*/
explicit RemoveBuffBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {
}
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Load() override;
private:
bool m_RemoveImmunity;
uint32_t m_BuffId;
};

View File

@@ -5,9 +5,10 @@
#include "EntityManager.h"
#include "dLogger.h"
#include "Game.h"
#include "eReplicaComponentType.h"
void RepairBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
auto* entity = Game::entityManager->GetEntity(branch.target);
if (entity == nullptr) {
Game::logger->Log("RepairBehavior", "Failed to find entity for (%llu)!", branch.target);
@@ -15,7 +16,7 @@ void RepairBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_str
return;
}
auto* destroyable = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE));
auto* destroyable = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE));
if (destroyable == nullptr) {
Game::logger->Log("RepairBehavior", "Failed to find destroyable component for %(llu)!", branch.target);

View File

@@ -5,8 +5,8 @@
#include "CppScripts.h"
void SkillEventBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* caster = EntityManager::Instance()->GetEntity(context->originator);
auto* target = Game::entityManager->GetEntity(branch.target);
auto* caster = Game::entityManager->GetEntity(context->originator);
if (caster != nullptr && target != nullptr && this->m_effectHandle != nullptr && !this->m_effectHandle->empty()) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(target)) {
@@ -17,8 +17,8 @@ void SkillEventBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit
void
SkillEventBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* caster = EntityManager::Instance()->GetEntity(context->originator);
auto* target = Game::entityManager->GetEntity(branch.target);
auto* caster = Game::entityManager->GetEntity(context->originator);
if (caster != nullptr && target != nullptr && this->m_effectHandle != nullptr && !this->m_effectHandle->empty()) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(target)) {

View File

@@ -7,9 +7,12 @@
#include "dLogger.h"
#include "DestroyableComponent.h"
#include "RebuildComponent.h"
#include "Entity.h"
#include "EntityInfo.h"
#include "eReplicaComponentType.h"
void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* origin = EntityManager::Instance()->GetEntity(context->originator);
auto* origin = Game::entityManager->GetEntity(context->originator);
if (origin == nullptr) {
Game::logger->Log("SpawnBehavior", "Failed to find self entity (%llu)!", context->originator);
@@ -18,7 +21,7 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea
}
if (branch.isProjectile) {
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* target = Game::entityManager->GetEntity(branch.target);
if (target != nullptr) {
origin = target;
@@ -35,10 +38,10 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea
info.spawnerNodeID = 0;
info.pos = info.pos + (info.rot.GetForwardVector() * m_Distance);
auto* entity = EntityManager::Instance()->CreateEntity(
auto* entity = Game::entityManager->CreateEntity(
info,
nullptr,
EntityManager::Instance()->GetEntity(context->originator)
Game::entityManager->GetEntity(context->originator)
);
if (entity == nullptr) {
@@ -56,7 +59,7 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea
rebuildComponent->SetRepositionPlayer(false);
}
EntityManager::Instance()->ConstructEntity(entity);
Game::entityManager->ConstructEntity(entity);
if (branch.duration > 0) {
context->RegisterTimerBehavior(this, branch, entity->GetObjectID());
@@ -76,7 +79,7 @@ void SpawnBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitSt
}
void SpawnBehavior::Timer(BehaviorContext* context, const BehaviorBranchContext branch, const LWOOBJID second) {
auto* entity = EntityManager::Instance()->GetEntity(second);
auto* entity = Game::entityManager->GetEntity(second);
if (entity == nullptr) {
Game::logger->Log("SpawnBehavior", "Failed to find spawned entity (%llu)!", second);
@@ -84,7 +87,7 @@ void SpawnBehavior::Timer(BehaviorContext* context, const BehaviorBranchContext
return;
}
auto* destroyable = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE));
auto* destroyable = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE));
if (destroyable == nullptr) {
entity->Smash(context->originator);

View File

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

View File

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

View File

@@ -7,6 +7,7 @@
#include "Game.h"
#include "dLogger.h"
#include "DestroyableComponent.h"
#include "eReplicaComponentType.h"
void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
@@ -14,10 +15,13 @@ void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream
return;
}
bool blocked;
bitStream->Read(blocked);
bool blocked{};
if (!bitStream->Read(blocked)) {
Game::logger->Log("StunBehavior", "Unable to read blocked from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* target = Game::entityManager->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->Log("StunBehavior", "Failed to find target (%llu)!", branch.target);
@@ -29,7 +33,7 @@ void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream
* If our target is an enemy we can go ahead and stun it.
*/
auto* combatAiComponent = static_cast<BaseCombatAIComponent*>(target->GetComponent(COMPONENT_TYPE_BASE_COMBAT_AI));
auto* combatAiComponent = static_cast<BaseCombatAIComponent*>(target->GetComponent(eReplicaComponentType::BASE_COMBAT_AI));
if (combatAiComponent == nullptr) {
return;
@@ -40,7 +44,7 @@ void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream
void StunBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
if (this->m_stunCaster || branch.target == context->originator) {
auto* self = EntityManager::Instance()->GetEntity(context->originator);
auto* self = Game::entityManager->GetEntity(context->originator);
if (self == nullptr) {
Game::logger->Log("StunBehavior", "Invalid self entity (%llu)!", context->originator);
@@ -52,7 +56,7 @@ void StunBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStr
* See if we can stun ourselves
*/
auto* combatAiComponent = static_cast<BaseCombatAIComponent*>(self->GetComponent(COMPONENT_TYPE_BASE_COMBAT_AI));
auto* combatAiComponent = static_cast<BaseCombatAIComponent*>(self->GetComponent(eReplicaComponentType::BASE_COMBAT_AI));
if (combatAiComponent == nullptr) {
return;
@@ -65,7 +69,7 @@ void StunBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStr
bool blocked = false;
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* target = Game::entityManager->GetEntity(branch.target);
if (target != nullptr) {
auto* destroyableComponent = target->GetComponent<DestroyableComponent>();
@@ -87,7 +91,7 @@ void StunBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStr
* If our target is an enemy we can go ahead and stun it.
*/
auto* combatAiComponent = static_cast<BaseCombatAIComponent*>(target->GetComponent(COMPONENT_TYPE_BASE_COMBAT_AI));
auto* combatAiComponent = static_cast<BaseCombatAIComponent*>(target->GetComponent(eReplicaComponentType::BASE_COMBAT_AI));
if (combatAiComponent == nullptr) {
return;

View File

@@ -10,10 +10,13 @@ void SwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre
auto state = true;
if (this->m_imagination > 0 || !this->m_isEnemyFaction) {
bitStream->Read(state);
if (!bitStream->Read(state)) {
Game::logger->Log("SwitchBehavior", "Unable to read state from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
}
auto* entity = EntityManager::Instance()->GetEntity(context->originator);
auto* entity = Game::entityManager->GetEntity(context->originator);
if (entity == nullptr) {
return;
@@ -25,9 +28,9 @@ void SwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre
return;
}
Game::logger->Log("SwitchBehavior", "[%i] State: (%d), imagination: (%i) / (%f)", entity->GetLOT(), state, destroyableComponent->GetImagination(), destroyableComponent->GetMaxImagination());
Game::logger->LogDebug("SwitchBehavior", "[%i] State: (%d), imagination: (%i) / (%f)", entity->GetLOT(), state, destroyableComponent->GetImagination(), destroyableComponent->GetMaxImagination());
if (state || (entity->GetLOT() == 8092 && destroyableComponent->GetImagination() >= m_imagination)) {
if (state) {
this->m_actionTrue->Handle(context, bitStream, branch);
} else {
this->m_actionFalse->Handle(context, bitStream, branch);
@@ -38,7 +41,7 @@ void SwitchBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS
auto state = true;
if (this->m_imagination > 0 || !this->m_isEnemyFaction) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
auto* entity = Game::entityManager->GetEntity(branch.target);
state = entity != nullptr;

View File

@@ -9,31 +9,30 @@
#include "EntityManager.h"
void SwitchMultipleBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) {
float value;
void SwitchMultipleBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
float value{};
bit_stream->Read(value);
if (!bitStream->Read(value)) {
Game::logger->Log("SwitchMultipleBehavior", "Unable to read value from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
uint32_t trigger = 0;
for (unsigned int i = 0; i < this->m_behaviors.size(); i++) {
const double data = this->m_behaviors.at(i).first;
trigger = i;
if (value <= data) {
trigger = i;
break;
}
if (value <= data) break;
}
auto* behavior = this->m_behaviors.at(trigger).second;
behavior->Handle(context, bit_stream, branch);
behavior->Handle(context, bitStream, branch);
}
void SwitchMultipleBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) {
void SwitchMultipleBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
// TODO
}

View File

@@ -20,12 +20,18 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre
bool hit = false;
bitStream->Read(hit);
if (!bitStream->Read(hit)) {
Game::logger->Log("TacArcBehavior", "Unable to read hit from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
if (this->m_checkEnv) {
bool blocked = false;
bitStream->Read(blocked);
if (!bitStream->Read(blocked)) {
Game::logger->Log("TacArcBehavior", "Unable to read blocked from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
if (blocked) {
this->m_blockedAction->Handle(context, bitStream, branch);
@@ -37,7 +43,10 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre
if (hit) {
uint32_t count = 0;
bitStream->Read(count);
if (!bitStream->Read(count)) {
Game::logger->Log("TacArcBehavior", "Unable to read count from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
if (count > m_maxTargets && m_maxTargets > 0) {
count = m_maxTargets;
@@ -46,9 +55,12 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre
std::vector<LWOOBJID> targets;
for (auto i = 0u; i < count; ++i) {
LWOOBJID id;
LWOOBJID id{};
bitStream->Read(id);
if (!bitStream->Read(id)) {
Game::logger->Log("TacArcBehavior", "Unable to read id from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};
targets.push_back(id);
}
@@ -64,7 +76,7 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre
}
void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* self = EntityManager::Instance()->GetEntity(context->originator);
auto* self = Game::entityManager->GetEntity(context->originator);
if (self == nullptr) {
Game::logger->Log("TacArcBehavior", "Invalid self for (%llu)!", context->originator);
return;
@@ -73,7 +85,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS
const auto* destroyableComponent = self->GetComponent<DestroyableComponent>();
if ((this->m_usePickedTarget || context->clientInitalized) && branch.target > 0) {
const auto* target = EntityManager::Instance()->GetEntity(branch.target);
const auto* target = Game::entityManager->GetEntity(branch.target);
if (target == nullptr) {
return;
@@ -108,7 +120,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS
// Find all valid targets, based on whether we target enemies or friends
for (const auto& contextTarget : context->GetValidTargets()) {
if (destroyableComponent != nullptr) {
const auto* targetEntity = EntityManager::Instance()->GetEntity(contextTarget);
const auto* targetEntity = Game::entityManager->GetEntity(contextTarget);
if (m_targetEnemy && destroyableComponent->IsEnemy(targetEntity)
|| m_targetFriend && destroyableComponent->IsFriend(targetEntity)) {
@@ -124,7 +136,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS
break;
}
auto* entity = EntityManager::Instance()->GetEntity(validTarget);
auto* entity = Game::entityManager->GetEntity(validTarget);
if (entity == nullptr) {
Game::logger->Log("TacArcBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator);

View File

@@ -7,7 +7,7 @@
void TauntBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* target = Game::entityManager->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->Log("TauntBehavior", "Failed to find target (%llu)!", branch.target);
@@ -23,7 +23,7 @@ void TauntBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea
}
void TauntBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* target = Game::entityManager->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->Log("TauntBehavior", "Failed to find target (%llu)!", branch.target);

View File

@@ -5,7 +5,7 @@
void VentureVisionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
const auto targetEntity = EntityManager::Instance()->GetEntity(branch.target);
const auto targetEntity = Game::entityManager->GetEntity(branch.target);
if (targetEntity) {
auto characterComponent = targetEntity->GetComponent<CharacterComponent>();
@@ -21,7 +21,7 @@ void VentureVisionBehavior::Handle(BehaviorContext* context, RakNet::BitStream*
}
void VentureVisionBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
const auto targetEntity = EntityManager::Instance()->GetEntity(branch.target);
const auto targetEntity = Game::entityManager->GetEntity(branch.target);
if (targetEntity) {
auto characterComponent = targetEntity->GetComponent<CharacterComponent>();

View File

@@ -8,14 +8,14 @@
void VerifyBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
auto* entity = Game::entityManager->GetEntity(branch.target);
auto success = true;
if (entity == nullptr) {
success = false;
} else if (this->m_rangeCheck) {
auto* self = EntityManager::Instance()->GetEntity(context->originator);
auto* self = Game::entityManager->GetEntity(context->originator);
if (self == nullptr) {
Game::logger->Log("VerifyBehavior", "Invalid self for (%llu)", context->originator);