mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
The client's TacArcBehavior::DoHit (0x00fb10c0) writes the closest max-targets ids from a set, so ascending and each once, then the action data per id in that same order; DoUnserializeBS (0x00fb26a0) reads them the same way and skips empty ids. The server handled the targets in list order and skipped ids whose object it could not find without reading their action data, so every later target read the wrong bits (several pirates under a Doom Slicer). Handle now reads the action for every listed id in ascending order, and the server's own casts write ids and actions in ascending order after picking the closest targets. TacArcBehavior::Cast (0x00fb2d10): a picked target that passes the filter gets the action with no TacArc data (the server's own cast now calculates that action instead of handling it); otherwise the target is dropped, and an arc measured from the target's position writes nothing. Check in game: Doom Slicer and multi-target katanas on groups of pirates/admirals damage each of them; apes still take damage during their stun; enemies with arc attacks (apes, Maelstrom horsemen) still hit players. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
54 lines
1.7 KiB
C++
54 lines
1.7 KiB
C++
#pragma once
|
|
#include "Behavior.h"
|
|
#include "dCommonVars.h"
|
|
#include "NiPoint3.h"
|
|
#include <forward_list>
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
class TacArcBehavior final : public Behavior {
|
|
public:
|
|
explicit TacArcBehavior(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 Load() override;
|
|
|
|
// Reads the target count and ids the way the client writes them: at most maxTargets, returned ascending and
|
|
// without empty ids. False when the data is cut short or lists too many targets.
|
|
static bool ReadTargets(RakNet::BitStream& bitStream, uint32_t maxTargets, std::set<LWOOBJID>& targets);
|
|
|
|
// Writes the closest maxTargets of closestFirst as the client does and returns them in the order their action
|
|
// data follows (ascending id)
|
|
static std::set<LWOOBJID> WriteTargets(RakNet::BitStream& bitStream, const std::vector<LWOOBJID>& closestFirst, uint32_t maxTargets);
|
|
private:
|
|
float m_maxRange;
|
|
float m_height;
|
|
float m_distanceWeight;
|
|
float m_angleWeight;
|
|
float m_angle;
|
|
float m_minRange;
|
|
NiPoint3 m_offset;
|
|
uint32_t m_method;
|
|
float m_upperBound;
|
|
float m_lowerBound;
|
|
bool m_usePickedTarget;
|
|
bool m_useTargetPostion;
|
|
bool m_checkEnv;
|
|
bool m_useAttackPriority;
|
|
Behavior* m_action;
|
|
Behavior* m_missAction;
|
|
Behavior* m_blockedAction;
|
|
uint32_t m_maxTargets;
|
|
float m_farHeight;
|
|
float m_farWidth;
|
|
float m_nearHeight;
|
|
float m_nearWidth;
|
|
|
|
std::forward_list<int32_t> m_ignoreFactionList {};
|
|
std::forward_list<int32_t> m_includeFactionList {};
|
|
bool m_targetSelf;
|
|
bool m_targetEnemy;
|
|
bool m_targetFriend;
|
|
bool m_targetTeam;
|
|
};
|