mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[Quest API] Add TrackNPC to Perl/Lua. (#2272)
* [Quest API] Add TrackNPC to Perl/Lua. - Add quest::tracknpc(entity_id) to Perl. - Add eq.track_npc(entity_id) to Lua. - This will allow server operators to arbitrarily Track NPCs for clients with scripts. - Modified tracking to auto turn off and tell you that you discovered your target if within 10 units, this is to allow scripted Tracking to turn off without the need for the Tracking skill. * Remove unnecessary DoTracking() call. * Update client.cpp
This commit is contained in:
parent
16b31c5a3a
commit
15113f4056
@ -11753,3 +11753,21 @@ void Client::Undye()
|
||||
|
||||
database.DeleteCharacterDye(CharacterID());
|
||||
}
|
||||
|
||||
void Client::SetTrackingID(uint32 entity_id)
|
||||
{
|
||||
if (!entity_id) {
|
||||
TrackingID = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
auto *m = entity_list.GetMob(entity_id);
|
||||
if (!m) {
|
||||
TrackingID = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
TrackingID = entity_id;
|
||||
|
||||
MessageString(Chat::Skills, TRACKING_BEGIN, m->GetCleanName());
|
||||
}
|
||||
|
||||
@ -409,6 +409,8 @@ public:
|
||||
inline void SetBaseRace(uint32 i) { m_pp.race=i; }
|
||||
inline void SetBaseGender(uint32 i) { m_pp.gender=i; }
|
||||
inline void SetDeity(uint32 i) {m_pp.deity=i;deity=i;}
|
||||
|
||||
void SetTrackingID(uint32 entity_id);
|
||||
|
||||
inline uint8 GetLevel2() const { return m_pp.level2; }
|
||||
inline uint16 GetBaseRace() const { return m_pp.race; }
|
||||
|
||||
@ -14165,16 +14165,14 @@ void Client::Handle_OP_TrackTarget(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
if (app->size != sizeof(TrackTarget_Struct))
|
||||
{
|
||||
LogError("Invalid size for OP_TrackTarget: Expected: [{}], Got: [{}]",
|
||||
sizeof(TrackTarget_Struct), app->size);
|
||||
if (app->size != sizeof(TrackTarget_Struct)) {
|
||||
LogError("Invalid size for OP_TrackTarget: Expected: [{}], Got: [{}]", sizeof(TrackTarget_Struct), app->size);
|
||||
return;
|
||||
}
|
||||
|
||||
TrackTarget_Struct *tts = (TrackTarget_Struct*)app->pBuffer;
|
||||
auto *t = (TrackTarget_Struct*) app->pBuffer;
|
||||
|
||||
TrackingID = tts->EntityID;
|
||||
SetTrackingID(t->EntityID);
|
||||
}
|
||||
|
||||
void Client::Handle_OP_TrackUnknown(const EQApplicationPacket *app)
|
||||
|
||||
@ -1946,10 +1946,11 @@ void Client::CalcRestState()
|
||||
|
||||
void Client::DoTracking()
|
||||
{
|
||||
if (TrackingID == 0)
|
||||
if (!TrackingID) {
|
||||
return;
|
||||
}
|
||||
|
||||
Mob *m = entity_list.GetMob(TrackingID);
|
||||
auto *m = entity_list.GetMob(TrackingID);
|
||||
|
||||
if (!m || m->IsCorpse()) {
|
||||
MessageString(Chat::Skills, TRACK_LOST_TARGET);
|
||||
@ -1957,29 +1958,43 @@ void Client::DoTracking()
|
||||
return;
|
||||
}
|
||||
|
||||
float RelativeHeading = GetHeading() - CalculateHeadingToTarget(m->GetX(), m->GetY());
|
||||
if (DistanceNoZ(m->GetPosition(), GetPosition()) < 10) {
|
||||
Message(
|
||||
Chat::Skills,
|
||||
fmt::format(
|
||||
"You have found {}.",
|
||||
m->GetCleanName()
|
||||
).c_str()
|
||||
);
|
||||
TrackingID = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (RelativeHeading < 0)
|
||||
RelativeHeading += 512;
|
||||
float relative_heading = GetHeading() - CalculateHeadingToTarget(m->GetX(), m->GetY());
|
||||
|
||||
if (RelativeHeading > 480)
|
||||
if (relative_heading < 0) {
|
||||
relative_heading += 512;
|
||||
}
|
||||
|
||||
if (relative_heading > 480) {
|
||||
MessageString(Chat::Skills, TRACK_STRAIGHT_AHEAD, m->GetCleanName());
|
||||
else if (RelativeHeading > 416)
|
||||
} else if (relative_heading > 416) {
|
||||
MessageString(Chat::Skills, TRACK_AHEAD_AND_TO, m->GetCleanName(), "left");
|
||||
else if (RelativeHeading > 352)
|
||||
} else if (relative_heading > 352) {
|
||||
MessageString(Chat::Skills, TRACK_TO_THE, m->GetCleanName(), "left");
|
||||
else if (RelativeHeading > 288)
|
||||
} else if (relative_heading > 288) {
|
||||
MessageString(Chat::Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "left");
|
||||
else if (RelativeHeading > 224)
|
||||
} else if (relative_heading > 224) {
|
||||
MessageString(Chat::Skills, TRACK_BEHIND_YOU, m->GetCleanName());
|
||||
else if (RelativeHeading > 160)
|
||||
} else if (relative_heading > 160) {
|
||||
MessageString(Chat::Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "right");
|
||||
else if (RelativeHeading > 96)
|
||||
} else if (relative_heading > 96) {
|
||||
MessageString(Chat::Skills, TRACK_TO_THE, m->GetCleanName(), "right");
|
||||
else if (RelativeHeading > 32)
|
||||
} else if (relative_heading > 32) {
|
||||
MessageString(Chat::Skills, TRACK_AHEAD_AND_TO, m->GetCleanName(), "right");
|
||||
else if (RelativeHeading >= 0)
|
||||
} else if (relative_heading >= 0) {
|
||||
MessageString(Chat::Skills, TRACK_STRAIGHT_AHEAD, m->GetCleanName());
|
||||
}
|
||||
}
|
||||
|
||||
void Client::HandleRespawnFromHover(uint32 Option)
|
||||
|
||||
@ -8454,6 +8454,18 @@ XS(XS__discordsend) {
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__tracknpc);
|
||||
XS(XS__tracknpc) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: quest::tracknpc(uint32 entity_id)");
|
||||
{
|
||||
uint32 entity_id = (uint32) SvUV(ST(0));
|
||||
quest_manager.TrackNPC(entity_id);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
/*
|
||||
This is the callback perl will look for to setup the
|
||||
quest package's XSUBs
|
||||
@ -8893,6 +8905,7 @@ EXTERN_C XS(boot_quest) {
|
||||
newXS(strcpy(buf, "tasktimeleft"), XS__tasktimeleft, file);
|
||||
newXS(strcpy(buf, "toggle_spawn_event"), XS__toggle_spawn_event, file);
|
||||
newXS(strcpy(buf, "toggledoorstate"), XS__toggledoorstate, file);
|
||||
newXS(strcpy(buf, "tracknpc"), XS__tracknpc, file);
|
||||
newXS(strcpy(buf, "traindisc"), XS__traindisc, file);
|
||||
newXS(strcpy(buf, "traindiscs"), XS__traindiscs, file);
|
||||
newXS(strcpy(buf, "unique_spawn"), XS__unique_spawn, file);
|
||||
|
||||
@ -3668,46 +3668,53 @@ void EntityList::SignalMobsByNPCID(uint32 snpc, int signal_id)
|
||||
bool EntityList::MakeTrackPacket(Client *client)
|
||||
{
|
||||
std::list<std::pair<Mob *, float> > tracking_list;
|
||||
uint32 distance = 0;
|
||||
float MobDistance;
|
||||
auto distance = static_cast<float>(client->GetSkill(EQ::skills::SkillTracking) * client->GetClassTrackingDistanceMultiplier(client->GetClass()));
|
||||
|
||||
distance = (client->GetSkill(EQ::skills::SkillTracking) * client->GetClassTrackingDistanceMultiplier(client->GetClass()));
|
||||
|
||||
if (distance <= 0)
|
||||
if (distance <= 0.0f) {
|
||||
return false;
|
||||
if (distance < 300)
|
||||
distance = 300;
|
||||
}
|
||||
|
||||
if (distance < 300.0f) {
|
||||
distance = 300.0f;
|
||||
}
|
||||
|
||||
for (auto it = mob_list.cbegin(); it != mob_list.cend(); ++it) {
|
||||
if (!it->second || it->second == client || !it->second->IsTrackable() ||
|
||||
it->second->IsInvisible(client))
|
||||
if (
|
||||
!it->second ||
|
||||
it->second == client ||
|
||||
!it->second->IsTrackable() ||
|
||||
it->second->IsInvisible(client)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MobDistance = DistanceNoZ(it->second->GetPosition(), client->GetPosition());
|
||||
if (MobDistance > distance)
|
||||
const auto mob_distance = DistanceNoZ(it->second->GetPosition(), client->GetPosition());
|
||||
if (mob_distance > distance) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tracking_list.push_back(std::make_pair(it->second, MobDistance));
|
||||
tracking_list.push_back(std::make_pair(it->second, mob_distance));
|
||||
}
|
||||
|
||||
tracking_list.sort(
|
||||
[](const std::pair<Mob *, float> &a, const std::pair<Mob *, float> &b) {
|
||||
return a.first->GetSpawnTimeStamp() > b.first->GetSpawnTimeStamp();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_Track, sizeof(Track_Struct) * tracking_list.size());
|
||||
Tracking_Struct *outtrack = (Tracking_Struct *)outapp->pBuffer;
|
||||
auto pack = (Tracking_Struct *) outapp->pBuffer;
|
||||
outapp->priority = 6;
|
||||
|
||||
int index = 0;
|
||||
for (auto it = tracking_list.cbegin(); it != tracking_list.cend(); ++it, ++index) {
|
||||
Mob *cur_entity = it->first;
|
||||
outtrack->Entrys[index].entityid = (uint32)cur_entity->GetID();
|
||||
outtrack->Entrys[index].distance = it->second;
|
||||
outtrack->Entrys[index].level = cur_entity->GetLevel();
|
||||
outtrack->Entrys[index].is_npc = !cur_entity->IsClient();
|
||||
strn0cpy(outtrack->Entrys[index].name, cur_entity->GetName(), sizeof(outtrack->Entrys[index].name));
|
||||
outtrack->Entrys[index].is_pet = cur_entity->IsPet();
|
||||
outtrack->Entrys[index].is_merc = cur_entity->IsMerc();
|
||||
pack->Entrys[index].entityid = static_cast<uint32>(it->first->GetID());
|
||||
pack->Entrys[index].distance = it->second;
|
||||
pack->Entrys[index].level = it->first->GetLevel();
|
||||
pack->Entrys[index].is_npc = !it->first->IsClient();
|
||||
strn0cpy(pack->Entrys[index].name, it->first->GetName(), sizeof(pack->Entrys[index].name));
|
||||
pack->Entrys[index].is_pet = it->first->IsPet();
|
||||
pack->Entrys[index].is_merc = it->first->IsMerc();
|
||||
}
|
||||
|
||||
client->QueuePacket(outapp);
|
||||
|
||||
@ -3392,16 +3392,18 @@ std::string lua_commify(std::string number) {
|
||||
return commify(number);
|
||||
}
|
||||
|
||||
bool lua_check_name_filter(std::string name)
|
||||
{
|
||||
bool lua_check_name_filter(std::string name) {
|
||||
return database.CheckNameFilter(name);
|
||||
}
|
||||
|
||||
void lua_discord_send(std::string webhook_name, std::string message)
|
||||
{
|
||||
void lua_discord_send(std::string webhook_name, std::string message) {
|
||||
zone->SendDiscordMessage(webhook_name, message);
|
||||
}
|
||||
|
||||
void lua_track_npc(uint32 entity_id) {
|
||||
quest_manager.TrackNPC(entity_id);
|
||||
}
|
||||
|
||||
#define LuaCreateNPCParse(name, c_type, default_value) do { \
|
||||
cur = table[#name]; \
|
||||
if(luabind::type(cur) != LUA_TNIL) { \
|
||||
@ -3857,6 +3859,7 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("commify", &lua_commify),
|
||||
luabind::def("check_name_filter", &lua_check_name_filter),
|
||||
luabind::def("discord_send", &lua_discord_send),
|
||||
luabind::def("track_npc", &lua_track_npc),
|
||||
|
||||
/*
|
||||
Cross Zone
|
||||
|
||||
@ -3688,3 +3688,12 @@ std::string QuestManager::getenvironmentaldamagename(uint8 damage_type) {
|
||||
std::string environmental_damage_name = EQ::constants::GetEnvironmentalDamageName(damage_type);
|
||||
return environmental_damage_name;
|
||||
}
|
||||
|
||||
void QuestManager::TrackNPC(uint32 entity_id) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (!initiator) {
|
||||
return;
|
||||
}
|
||||
|
||||
initiator->SetTrackingID(entity_id);
|
||||
}
|
||||
|
||||
@ -336,6 +336,7 @@ public:
|
||||
int getspellstat(uint32 spell_id, std::string stat_identifier, uint8 slot = 0);
|
||||
const SPDat_Spell_Struct *getspell(uint32 spell_id);
|
||||
std::string getenvironmentaldamagename(uint8 damage_type);
|
||||
void TrackNPC(uint32 entity_id);
|
||||
|
||||
Client *GetInitiator() const;
|
||||
NPC *GetNPC() const;
|
||||
|
||||
@ -454,6 +454,7 @@
|
||||
#define NO_ABILITY_OUT_OF_COMBAT 9194 //You can not use this ability while out of combat.
|
||||
#define AE_RAMPAGE 11015 //%1 goes on a WILD RAMPAGE!
|
||||
#define FACE_ACCEPTED 12028 //Facial features accepted.
|
||||
#define TRACKING_BEGIN 12040 //You begin tracking %1.
|
||||
#define SPELL_LEVEL_TO_LOW 12048 //You will have to achieve level %1 before you can scribe the %2.
|
||||
#define YOU_RECEIVE_AS_SPLIT 12071 //You receive %1 as your split.
|
||||
#define ATTACKFAILED 12158 //%1 try to %2 %3, but %4!
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user