mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 09:31:30 +00:00
XTargets will move auto entries up on removal like live
This also makes use of the bulk packet so not a crap ton of packets generated.
This commit is contained in:
parent
b7ee4634be
commit
4ae02e5efe
@ -7041,7 +7041,7 @@ void Client::UpdateClientXTarget(Client *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::AddAutoXTarget(Mob *m)
|
void Client::AddAutoXTarget(Mob *m, bool send)
|
||||||
{
|
{
|
||||||
if(!XTargettingAvailable() || !XTargetAutoAddHaters)
|
if(!XTargettingAvailable() || !XTargetAutoAddHaters)
|
||||||
return;
|
return;
|
||||||
@ -7054,7 +7054,10 @@ void Client::AddAutoXTarget(Mob *m)
|
|||||||
if((XTargets[i].Type == Auto) && (XTargets[i].ID == 0))
|
if((XTargets[i].Type == Auto) && (XTargets[i].ID == 0))
|
||||||
{
|
{
|
||||||
XTargets[i].ID = m->GetID();
|
XTargets[i].ID = m->GetID();
|
||||||
SendXTargetPacket(i, m);
|
if (send) // if we don't send we're bulk sending updates later on
|
||||||
|
SendXTargetPacket(i, m);
|
||||||
|
else
|
||||||
|
XTargets[i].dirty = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7062,42 +7065,59 @@ void Client::AddAutoXTarget(Mob *m)
|
|||||||
|
|
||||||
void Client::RemoveXTarget(Mob *m, bool OnlyAutoSlots)
|
void Client::RemoveXTarget(Mob *m, bool OnlyAutoSlots)
|
||||||
{
|
{
|
||||||
if(!XTargettingAvailable())
|
if (!XTargettingAvailable())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool HadFreeAutoSlotsBefore = false;
|
bool HadFreeAutoSlotsBefore = false;
|
||||||
|
|
||||||
int FreedAutoSlots = 0;
|
int FreedAutoSlots = 0;
|
||||||
|
|
||||||
if(m->GetID() == 0)
|
if (m->GetID() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(int i = 0; i < GetMaxXTargets(); ++i)
|
for (int i = 0; i < GetMaxXTargets(); ++i) {
|
||||||
{
|
if (OnlyAutoSlots && XTargets[i].Type != Auto)
|
||||||
if(OnlyAutoSlots && (XTargets[i].Type !=Auto))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(XTargets[i].ID == m->GetID())
|
if (XTargets[i].ID == m->GetID()) {
|
||||||
{
|
if (XTargets[i].Type == CurrentTargetNPC)
|
||||||
if(XTargets[i].Type == CurrentTargetNPC)
|
|
||||||
XTargets[i].Type = Auto;
|
XTargets[i].Type = Auto;
|
||||||
|
|
||||||
if(XTargets[i].Type == Auto)
|
if (XTargets[i].Type == Auto)
|
||||||
++FreedAutoSlots;
|
++FreedAutoSlots;
|
||||||
|
|
||||||
XTargets[i].ID = 0;
|
XTargets[i].ID = 0;
|
||||||
|
XTargets[i].dirty = true;
|
||||||
SendXTargetPacket(i, nullptr);
|
} else {
|
||||||
}
|
if (XTargets[i].Type == Auto && XTargets[i].ID == 0)
|
||||||
else
|
|
||||||
{
|
|
||||||
if((XTargets[i].Type == Auto) && (XTargets[i].ID == 0))
|
|
||||||
HadFreeAutoSlotsBefore = true;
|
HadFreeAutoSlotsBefore = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If there are more mobs aggro on us than we had auto-hate slots, add one of those haters into the slot(s) we just freed up.
|
|
||||||
if(!HadFreeAutoSlotsBefore && FreedAutoSlots)
|
// move shit up!
|
||||||
|
std::queue<int> empty_slots;
|
||||||
|
for (int i = 0; i < GetMaxXTargets(); ++i) {
|
||||||
|
if (XTargets[i].Type != Auto)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (XTargets[i].ID == 0) {
|
||||||
|
empty_slots.push(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (XTargets[i].ID != 0 && !empty_slots.empty()) {
|
||||||
|
int temp = empty_slots.front();
|
||||||
|
std::swap(XTargets[i], XTargets[temp]);
|
||||||
|
XTargets[i].dirty = XTargets[temp].dirty = true;
|
||||||
|
empty_slots.pop();
|
||||||
|
empty_slots.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If there are more mobs aggro on us than we had auto-hate slots, add one of those haters into the slot(s) we
|
||||||
|
// just freed up.
|
||||||
|
if (!HadFreeAutoSlotsBefore && FreedAutoSlots)
|
||||||
entity_list.RefreshAutoXTargets(this);
|
entity_list.RefreshAutoXTargets(this);
|
||||||
|
SendXTargetUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::UpdateXTargetType(XTargetType Type, Mob *m, const char *Name)
|
void Client::UpdateXTargetType(XTargetType Type, Mob *m, const char *Name)
|
||||||
@ -7166,6 +7186,42 @@ void Client::SendXTargetPacket(uint32 Slot, Mob *m)
|
|||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a bulk packet, we use it when we remove something since we need to reorder the xtargets and maybe
|
||||||
|
// add new mobs! Currently doesn't check if there is a dirty flag set, so it should only be called when there is
|
||||||
|
void Client::SendXTargetUpdates()
|
||||||
|
{
|
||||||
|
if (!XTargettingAvailable())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
// header is 4 bytes max xtargets, 4 bytes count
|
||||||
|
// entry is 4 bytes slot, 1 byte unknown, 4 bytes ID, 65 char name
|
||||||
|
auto outapp = new EQApplicationPacket(OP_XTargetResponse, 8 + 74 * GetMaxXTargets()); // fuck it max size
|
||||||
|
outapp->WriteUInt32(GetMaxXTargets());
|
||||||
|
outapp->WriteUInt32(1); // we will correct this later
|
||||||
|
for (int i = 0; i < GetMaxXTargets(); ++i) {
|
||||||
|
if (XTargets[i].dirty) {
|
||||||
|
outapp->WriteUInt32(i);
|
||||||
|
outapp->WriteUInt8(0); // no idea what this is
|
||||||
|
outapp->WriteUInt32(XTargets[i].ID);
|
||||||
|
outapp->WriteString(XTargets[i].Name);
|
||||||
|
count++;
|
||||||
|
XTargets[i].dirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(count > 0); // we don't have any logic to prevent this, assert for now
|
||||||
|
|
||||||
|
auto newbuff = new uchar[outapp->GetWritePosition()];
|
||||||
|
memcpy(newbuff, outapp->pBuffer, outapp->GetWritePosition());
|
||||||
|
safe_delete_array(outapp->pBuffer);
|
||||||
|
outapp->pBuffer = newbuff;
|
||||||
|
outapp->size = outapp->GetWritePosition();
|
||||||
|
outapp->SetWritePosition(4);
|
||||||
|
outapp->WriteUInt32(count);
|
||||||
|
FastQueuePacket(&outapp);
|
||||||
|
}
|
||||||
|
|
||||||
void Client::RemoveGroupXTargets()
|
void Client::RemoveGroupXTargets()
|
||||||
{
|
{
|
||||||
if(!XTargettingAvailable())
|
if(!XTargettingAvailable())
|
||||||
@ -8670,4 +8726,4 @@ uint32 Client::GetMoney(uint8 type, uint8 subtype) {
|
|||||||
|
|
||||||
int Client::GetAccountAge() {
|
int Client::GetAccountAge() {
|
||||||
return (time(nullptr) - GetAccountCreation());
|
return (time(nullptr) - GetAccountCreation());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -175,6 +175,7 @@ typedef enum
|
|||||||
struct XTarget_Struct
|
struct XTarget_Struct
|
||||||
{
|
{
|
||||||
XTargetType Type;
|
XTargetType Type;
|
||||||
|
bool dirty;
|
||||||
uint16 ID;
|
uint16 ID;
|
||||||
char Name[65];
|
char Name[65];
|
||||||
};
|
};
|
||||||
@ -1144,9 +1145,10 @@ public:
|
|||||||
bool IsClientXTarget(const Client *c) const;
|
bool IsClientXTarget(const Client *c) const;
|
||||||
void UpdateClientXTarget(Client *c);
|
void UpdateClientXTarget(Client *c);
|
||||||
void UpdateXTargetType(XTargetType Type, Mob *m, const char *Name = nullptr);
|
void UpdateXTargetType(XTargetType Type, Mob *m, const char *Name = nullptr);
|
||||||
void AddAutoXTarget(Mob *m);
|
void AddAutoXTarget(Mob *m, bool send = true);
|
||||||
void RemoveXTarget(Mob *m, bool OnlyAutoSlots);
|
void RemoveXTarget(Mob *m, bool OnlyAutoSlots);
|
||||||
void SendXTargetPacket(uint32 Slot, Mob *m);
|
void SendXTargetPacket(uint32 Slot, Mob *m);
|
||||||
|
void SendXTargetUpdates();
|
||||||
void RemoveGroupXTargets();
|
void RemoveGroupXTargets();
|
||||||
void RemoveAutoXTargets();
|
void RemoveAutoXTargets();
|
||||||
void ShowXTargets(Client *c);
|
void ShowXTargets(Client *c);
|
||||||
|
|||||||
@ -1373,7 +1373,7 @@ void EntityList::RefreshAutoXTargets(Client *c)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (m->CheckAggro(c) && !c->IsXTarget(m)) {
|
if (m->CheckAggro(c) && !c->IsXTarget(m)) {
|
||||||
c->AddAutoXTarget(m);
|
c->AddAutoXTarget(m, false); // we only call this before a bulk, so lets not send right away
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user