Skip to content

Commit

Permalink
Merge branch 'main' into somethingElse
Browse files Browse the repository at this point in the history
  • Loading branch information
aronwk-aaron authored Oct 9, 2023
2 parents 47f62dd + 3dd2791 commit ef27ead
Show file tree
Hide file tree
Showing 44 changed files with 785 additions and 697 deletions.
5 changes: 5 additions & 0 deletions dCommon/GeneralUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ namespace GeneralUtils {
template <typename T>
T Parse(const char* value);

template <>
inline bool Parse(const char* value) {
return std::stoi(value);
}

template <>
inline int32_t Parse(const char* value) {
return std::stoi(value);
Expand Down
44 changes: 18 additions & 26 deletions dCommon/LDFFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,35 +61,33 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
}

case LDF_TYPE_S32: {
try {
int32_t data = static_cast<int32_t>(strtoul(ldfTypeAndValue.second.data(), &storage, 10));
returnValue = new LDFData<int32_t>(key, data);
} catch (std::exception) {
int32_t data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid int32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<int32_t>(key, data);

break;
}

case LDF_TYPE_FLOAT: {
try {
float data = strtof(ldfTypeAndValue.second.data(), &storage);
returnValue = new LDFData<float>(key, data);
} catch (std::exception) {
float data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid float value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<float>(key, data);
break;
}

case LDF_TYPE_DOUBLE: {
try {
double data = strtod(ldfTypeAndValue.second.data(), &storage);
returnValue = new LDFData<double>(key, data);
} catch (std::exception) {
double data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid double value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<double>(key, data);
break;
}

Expand All @@ -102,9 +100,7 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
} else if (ldfTypeAndValue.second == "false") {
data = 0;
} else {
try {
data = static_cast<uint32_t>(strtoul(ldfTypeAndValue.second.data(), &storage, 10));
} catch (std::exception) {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid uint32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
Expand All @@ -122,9 +118,7 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
} else if (ldfTypeAndValue.second == "false") {
data = false;
} else {
try {
data = static_cast<bool>(strtol(ldfTypeAndValue.second.data(), &storage, 10));
} catch (std::exception) {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid bool value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
Expand All @@ -135,24 +129,22 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
}

case LDF_TYPE_U64: {
try {
uint64_t data = static_cast<uint64_t>(strtoull(ldfTypeAndValue.second.data(), &storage, 10));
returnValue = new LDFData<uint64_t>(key, data);
} catch (std::exception) {
uint64_t data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid uint64 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<uint64_t>(key, data);
break;
}

case LDF_TYPE_OBJID: {
try {
LWOOBJID data = static_cast<LWOOBJID>(strtoll(ldfTypeAndValue.second.data(), &storage, 10));
returnValue = new LDFData<LWOOBJID>(key, data);
} catch (std::exception) {
LWOOBJID data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
Game::logger->Log("LDFFormat", "Warning: Attempted to process invalid LWOOBJID value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<LWOOBJID>(key, data);
break;
}

Expand Down
2 changes: 1 addition & 1 deletion dCommon/dClient/AssetManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct AssetMemoryBuffer : std::streambuf {
}

void close() {
delete m_Base;
free(m_Base);
}
};

Expand Down
2 changes: 1 addition & 1 deletion dCommon/dEnums/eGameMessageType.h
Original file line number Diff line number Diff line change
Expand Up @@ -1152,7 +1152,7 @@ enum class eGameMessageType : uint16_t {
COLLISION_POINT_REMOVED = 1269,
SET_ATTACHED = 1270,
SET_DESTROYABLE_MODEL_BRICKS = 1271,
VEHICLE_SET_POWERSLIDE_LOCK_WHEELS = 1273,
VEHICLE_SET_POWERSLIDE_LOCK_WHEELS = 1272,
VEHICLE_SET_WHEEL_LOCK_STATE = 1273,
SHOW_HEALTH_BAR = 1274,
GET_SHOWS_HEALTH_BAR = 1275,
Expand Down
10 changes: 10 additions & 0 deletions dGame/EntityManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,16 @@ std::vector<Entity*> EntityManager::GetEntitiesByLOT(const LOT& lot) const {
return entities;
}

std::vector<Entity*> EntityManager::GetEntitiesByProximity(NiPoint3 reference, float radius) const{
std::vector<Entity*> entities = {};
if (radius > 1000.0f) return entities;
for (const auto& entity : m_Entities) {
if (NiPoint3::Distance(reference, entity.second->GetPosition()) <= radius) entities.push_back(entity.second);
}
return entities;
}


Entity* EntityManager::GetZoneControlEntity() const {
return m_ZoneControlEntity;
}
Expand Down
1 change: 1 addition & 0 deletions dGame/EntityManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class EntityManager {
std::vector<Entity*> GetEntitiesInGroup(const std::string& group);
std::vector<Entity*> GetEntitiesByComponent(eReplicaComponentType componentType) const;
std::vector<Entity*> GetEntitiesByLOT(const LOT& lot) const;
std::vector<Entity*> GetEntitiesByProximity(NiPoint3 reference, float radius) const;
Entity* GetZoneControlEntity() const;

// Get spawn point entity by spawn name
Expand Down
166 changes: 73 additions & 93 deletions dGame/dBehaviors/AreaOfEffectBehavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,134 +20,114 @@ void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* b
return;
}

if (this->m_useTargetPosition && branch.target == LWOOBJID_EMPTY) return;

if (targetCount == 0){
PlayFx(u"miss", context->originator);
return;
}

if (targetCount > this->m_maxTargets) {
Game::logger->Log("AreaOfEffectBehavior", "Serialized size is greater than max targets! Size: %i, Max: %i", targetCount, this->m_maxTargets);
return;
}

std::vector<LWOOBJID> targets;
auto caster = context->caster;
if (this->m_useTargetAsCaster) context->caster = branch.target;

std::vector<LWOOBJID> targets;
targets.reserve(targetCount);

for (auto i = 0u; i < targetCount; ++i) {
LWOOBJID 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);
}

for (auto target : targets) {
branch.target = target;

this->m_action->Handle(context, bitStream, branch);
}
context->caster = caster;
PlayFx(u"cast", context->originator);
}

void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* self = Game::entityManager->GetEntity(context->caster);
if (self == nullptr) {
Game::logger->Log("AreaOfEffectBehavior", "Invalid self for (%llu)!", context->originator);

return;
auto* caster = Game::entityManager->GetEntity(context->caster);
if (!caster) return;

// determine the position we are casting the AOE from
auto reference = branch.isProjectile ? branch.referencePosition : caster->GetPosition();
if (this->m_useTargetPosition) {
if (branch.target == LWOOBJID_EMPTY) return;
auto branchTarget = Game::entityManager->GetEntity(branch.target);
if (branchTarget) reference = branchTarget->GetPosition();
}

auto reference = branch.isProjectile ? branch.referencePosition : self->GetPosition();

std::vector<Entity*> targets;
reference += this->m_offset;

auto* presetTarget = Game::entityManager->GetEntity(branch.target);
std::vector<Entity*> targets {};
targets = Game::entityManager->GetEntitiesByProximity(reference, this->m_radius);
context->FilterTargets(targets, this->m_ignoreFactionList, this->m_includeFactionList, this->m_targetSelf, this->m_targetEnemy, this->m_targetFriend, this->m_targetTeam);

if (presetTarget != nullptr) {
if (this->m_radius * this->m_radius >= Vector3::DistanceSquared(reference, presetTarget->GetPosition())) {
targets.push_back(presetTarget);
}
}

int32_t includeFaction = m_includeFaction;

if (self->GetLOT() == 14466) // TODO: Fix edge case
{
includeFaction = 1;
}

// 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 = Game::entityManager->GetEntity(validTarget);

if (entity == nullptr) {
Game::logger->Log("AreaOfEffectBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator);

continue;
}

if (std::find(targets.begin(), targets.end(), entity) != targets.end()) {
continue;
// sort by distance
std::sort(targets.begin(), targets.end(), [reference](Entity* a, Entity* b) {
const auto aDistance = NiPoint3::Distance(a->GetPosition(), reference);
const auto bDistance = NiPoint3::Distance(b->GetPosition(), reference);
return aDistance < bDistance;
}
);

auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
// resize if we have more than max targets allows
if (targets.size() > this->m_maxTargets) targets.resize(this->m_maxTargets);

if (destroyableComponent == nullptr) {
continue;
}
bitStream->Write<uint32_t>(targets.size());

if (destroyableComponent->HasFaction(m_ignoreFaction)) {
continue;
if (targets.size() == 0) {
PlayFx(u"miss", context->originator);
return;
} else {
context->foundTarget = true;
// write all the targets to the bitstream
for (auto* target : targets) {
bitStream->Write(target->GetObjectID());
}

const auto distance = Vector3::DistanceSquared(reference, entity->GetPosition());

if (this->m_radius * this->m_radius >= distance && (this->m_maxTargets == 0 || targets.size() < this->m_maxTargets)) {
targets.push_back(entity);
// then cast all the actions
for (auto* target : targets) {
branch.target = target->GetObjectID();
this->m_action->Calculate(context, bitStream, branch);
}
}

std::sort(targets.begin(), targets.end(), [reference](Entity* a, Entity* b) {
const auto aDistance = Vector3::DistanceSquared(a->GetPosition(), reference);
const auto bDistance = Vector3::DistanceSquared(b->GetPosition(), reference);

return aDistance > bDistance;
});

const uint32_t size = targets.size();

bitStream->Write(size);

if (size == 0) {
return;
}

context->foundTarget = true;

for (auto* target : targets) {
bitStream->Write(target->GetObjectID());

PlayFx(u"cast", context->originator, target->GetObjectID());
}

for (auto* target : targets) {
branch.target = target->GetObjectID();

this->m_action->Calculate(context, bitStream, branch);
PlayFx(u"cast", context->originator);
}
}

void AreaOfEffectBehavior::Load() {
this->m_action = GetAction("action");

this->m_radius = GetFloat("radius");

this->m_maxTargets = GetInt("max targets");

this->m_ignoreFaction = GetInt("ignore_faction");

this->m_includeFaction = GetInt("include_faction");

this->m_TargetSelf = GetInt("target_self");

this->m_targetEnemy = GetInt("target_enemy");

this->m_targetFriend = GetInt("target_friend");
this->m_action = GetAction("action"); // required
this->m_radius = GetFloat("radius", 0.0f); // required
this->m_maxTargets = GetInt("max targets", 100);
if (this->m_maxTargets == 0) this->m_maxTargets = 100;
this->m_useTargetPosition = GetBoolean("use_target_position", false);
this->m_useTargetAsCaster = GetBoolean("use_target_as_caster", false);
this->m_offset = NiPoint3(
GetFloat("offset_x", 0.0f),
GetFloat("offset_y", 0.0f),
GetFloat("offset_z", 0.0f)
);

// params after this are needed for filter targets
const auto parameters = GetParameterNames();
for (const auto& parameter : parameters) {
if (parameter.first.rfind("include_faction", 0) == 0) {
this->m_includeFactionList.push_front(parameter.second);
} else if (parameter.first.rfind("ignore_faction", 0) == 0) {
this->m_ignoreFactionList.push_front(parameter.second);
}
}
this->m_targetSelf = GetBoolean("target_self", false);
this->m_targetEnemy = GetBoolean("target_enemy", false);
this->m_targetFriend = GetBoolean("target_friend", false);
this->m_targetTeam = GetBoolean("target_team", false);
}
Loading

0 comments on commit ef27ead

Please sign in to comment.