Here is the function that handles the targeting stuff:
client_packet.cpp
Code:
void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app)
{
if (app->size != sizeof(ClientTarget_Struct)) {
LogFile->write(EQEMuLog::Error, "OP size error: OP_TargetMouse expected:%i got:%i", sizeof(ClientTarget_Struct), app->size);
return;
}
if(GetTarget())
{
GetTarget()->IsTargeted(-1);
}
// Locate and cache new target
ClientTarget_Struct* ct=(ClientTarget_Struct*)app->pBuffer;
pClientSideTarget = ct->new_target;
if(!IsAIControlled())
{
Mob *new_target = entity_list.GetMob(ct->new_target);
if(new_target)
{
SetTarget(new_target);
}
else
{
SetTarget(NULL);
SetHoTT(0);
return;
}
}
else
{
SetTarget(NULL);
SetHoTT(0);
return;
}
// <Rogean> HoTT
if (GetTarget() && GetTarget()->GetTarget())
SetHoTT(GetTarget()->GetTarget()->GetID());
else
SetHoTT(0);
Group *g = GetGroup();
if(g && g->IsMainAssist(this))
g->SetGroupTarget(ct->new_target);
// For /target, send reject or success packet
if (app->GetOpcode() == OP_TargetCommand) {
if (GetTarget() && !GetTarget()->CastToMob()->IsInvisible(this) && DistNoRoot(*GetTarget()) <= TARGETING_RANGE*TARGETING_RANGE) {
if(GetTarget()->GetBodyType() == BT_NoTarget2 || GetTarget()->GetBodyType() == BT_Special
|| GetTarget()->GetBodyType() == BT_NoTarget)
{
//Targeting something we shouldn't with /target
//but the client allows this without MQ so you don't flag it
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TargetReject, sizeof(TargetReject_Struct));
outapp->pBuffer[0] = 0x2f;
outapp->pBuffer[1] = 0x01;
outapp->pBuffer[4] = 0x0d;
if(GetTarget())
{
SetTarget(NULL);
}
QueuePacket(outapp);
safe_delete(outapp);
return;
}
QueuePacket(app);
EQApplicationPacket hp_app;
GetTarget()->IsTargeted(1);
GetTarget()->CreateHPPacket(&hp_app);
QueuePacket(&hp_app, false);
}
else
{
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TargetReject, sizeof(TargetReject_Struct));
outapp->pBuffer[0] = 0x2f;
outapp->pBuffer[1] = 0x01;
outapp->pBuffer[4] = 0x0d;
if(GetTarget())
{
SetTarget(NULL);
}
QueuePacket(outapp);
safe_delete(outapp);
}
}
else
{
if(GetTarget())
{
if(GetGM())
{
GetTarget()->IsTargeted(1);
return;
}
else if(GetTarget()->IsClient())
{
//make sure this client is in our raid/group
GetTarget()->IsTargeted(1);
return;
}
else if(GetTarget()->GetBodyType() == BT_NoTarget2 || GetTarget()->GetBodyType() == BT_Special
|| GetTarget()->GetBodyType() == BT_NoTarget)
{
char *hacker_str = NULL;
MakeAnyLenString(&hacker_str, "%s attempting to target something untargetable, %s bodytype: %i\n",
GetName(), GetTarget()->GetName(), (int)GetTarget()->GetBodyType());
database.SetMQDetectionFlag(AccountName(), GetName(), hacker_str, zone->GetShortName());
safe_delete_array(hacker_str);
SetTarget((Mob*)NULL);
return;
}
else if(IsPortExempted())
{
GetTarget()->IsTargeted(1);
return;
}
else if(IsSenseExempted())
{
GetTarget()->IsTargeted(1);
SetSenseExemption(false);
return;
}
else if(GetBindSightTarget())
{
if(GetBindSightTarget()->DistNoRoot(*GetTarget()) > (zone->newzone_data.maxclip*zone->newzone_data.maxclip))
{
if(DistNoRoot(*GetTarget()) > (zone->newzone_data.maxclip*zone->newzone_data.maxclip))
{
char *hacker_str = NULL;
MakeAnyLenString(&hacker_str, "%s attempting to target something beyond the clip plane of %.2f units,"
" from (%.2f, %.2f, %.2f) to %s (%.2f, %.2f, %.2f)", GetName(),
(zone->newzone_data.maxclip*zone->newzone_data.maxclip),
GetX(), GetY(), GetZ(), GetTarget()->GetName(), GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ());
database.SetMQDetectionFlag(AccountName(), GetName(), hacker_str, zone->GetShortName());
safe_delete_array(hacker_str);
SetTarget(NULL);
return;
}
}
}
else if(DistNoRoot(*GetTarget()) > (zone->newzone_data.maxclip*zone->newzone_data.maxclip))
{
char *hacker_str = NULL;
MakeAnyLenString(&hacker_str, "%s attempting to target something beyond the clip plane of %.2f units,"
" from (%.2f, %.2f, %.2f) to %s (%.2f, %.2f, %.2f)", GetName(),
(zone->newzone_data.maxclip*zone->newzone_data.maxclip),
GetX(), GetY(), GetZ(), GetTarget()->GetName(), GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ());
database.SetMQDetectionFlag(AccountName(), GetName(), hacker_str, zone->GetShortName());
safe_delete_array(hacker_str);
SetTarget(NULL);
return;
}
GetTarget()->IsTargeted(1);
}
}
return;
}
I will try to look through this later and maybe add in a "if(Admin() < 80)" type of check to allow GMs to use /target from any range. Just need to figure out the best place to put that, but it shouldn't be too hard.