diff --git a/zone/command.cpp b/zone/command.cpp index 2bca4cfcf..1dc001a5c 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -312,6 +312,7 @@ int command_init(void) #endif command_add("push", "Lets you do spell push", 150, command_push) || + command_add("proximity", "Shows NPC proximity", 150, command_proximity) || command_add("pvp", "[on/off] - Set your or your player target's PVP status", 100, command_pvp) || command_add("qglobal", "[on/off/view] - Toggles qglobal functionality on an NPC", 100, command_qglobal) || command_add("questerrors", "Shows quest errors.", 100, command_questerrors) || @@ -4930,6 +4931,49 @@ void command_push(Client *c, const Seperator *sep) } } +void command_proximity(Client *c, const Seperator *sep) +{ + if (!c->GetTarget() && !c->GetTarget()->IsNPC()) { + c->Message(0, "You must target an NPC"); + return; + } + + for (auto &iter : entity_list.GetNPCList()) { + auto npc = iter.second; + std::string name = npc->GetName(); + + if (name.find("Proximity") != std::string::npos) { + npc->Depop(); + } + } + + NPC *npc = c->GetTarget()->CastToNPC(); + + if (npc->IsProximitySet()) { + glm::vec4 position; + position.w = npc->GetHeading(); + position.x = npc->GetProximityMinX(); + position.y = npc->GetProximityMinY(); + position.z = npc->GetZ(); + + position.x = npc->GetProximityMinX(); + position.y = npc->GetProximityMinY(); + NPC::SpawnNodeNPC("Proximity", "", position); + + position.x = npc->GetProximityMinX(); + position.y = npc->GetProximityMaxY(); + NPC::SpawnNodeNPC("Proximity", "", position); + + position.x = npc->GetProximityMaxX(); + position.y = npc->GetProximityMinY(); + NPC::SpawnNodeNPC("Proximity", "", position); + + position.x = npc->GetProximityMaxX(); + position.y = npc->GetProximityMaxY(); + NPC::SpawnNodeNPC("Proximity", "", position); + } +} + void command_pvp(Client *c, const Seperator *sep) { bool state=atobool(sep->arg[1]); diff --git a/zone/command.h b/zone/command.h index abac73def..1c4b21529 100644 --- a/zone/command.h +++ b/zone/command.h @@ -214,6 +214,7 @@ void command_profiledump(Client *c, const Seperator *sep); void command_profilereset(Client *c, const Seperator *sep); #endif +void command_proximity(Client *c, const Seperator *sep); void command_push(Client *c, const Seperator *sep); void command_pvp(Client *c, const Seperator *sep); void command_qglobal(Client *c, const Seperator *sep); diff --git a/zone/mob_info.cpp b/zone/mob_info.cpp index 21e7ed5bb..2de8e68ec 100644 --- a/zone/mob_info.cpp +++ b/zone/mob_info.cpp @@ -618,6 +618,10 @@ inline void NPCCommandsMenu(Client* client, NPC* npc) menu_commands += "[" + EQEmu::SayLinkEngine::GenerateQuestSaylink("#npcloot show", false, "Loot") + "] "; } + if (npc->IsProximitySet()) { + menu_commands += "[" + EQEmu::SayLinkEngine::GenerateQuestSaylink("#proximity show", false, "Proximity") + "] "; + } + if (menu_commands.length() > 0) { std::string dev_menu = "[" + EQEmu::SayLinkEngine::GenerateQuestSaylink("#devtools", false, "DevTools") + "] ";; client->Message(0, "| %s [Show Commands] %s", dev_menu.c_str(), menu_commands.c_str()); diff --git a/zone/npc.cpp b/zone/npc.cpp index 365fc7ff9..ae90edde8 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -1037,22 +1037,50 @@ NPC * NPC::SpawnGridNodeNPC(std::string name, const glm::vec4 &position, uint32 npc_type->light = 1; npc_type->size = 1; npc_type->runspeed = 0; + npc_type->merchanttype = 1; + npc_type->bodytype = 1; + npc_type->show_name = true; + npc_type->findable = true; + + auto node_position = glm::vec4(position.x, position.y, position.z, position.w); + auto npc = new NPC(npc_type, nullptr, node_position, GravityBehavior::Flying); + npc->GiveNPCTypeData(npc_type); + + entity_list.AddNPC(npc, true, true); + + return npc; +} + +NPC * NPC::SpawnNodeNPC(std::string name, std::string last_name, const glm::vec4 &position) { + auto npc_type = new NPCType; + memset(npc_type, 0, sizeof(NPCType)); + + sprintf(npc_type->name, "%s", name.c_str()); + sprintf(npc_type->lastname, "%s", last_name.c_str()); + + npc_type->cur_hp = 4000000; + npc_type->max_hp = 4000000; + npc_type->race = 2254; + npc_type->gender = 2; + npc_type->class_ = 9; + npc_type->deity = 1; + npc_type->level = 200; + npc_type->npc_id = 0; + npc_type->loottable_id = 0; + npc_type->texture = 1; + npc_type->light = 1; + npc_type->size = 3; npc_type->d_melee_texture1 = 1; npc_type->d_melee_texture2 = 1; npc_type->merchanttype = 1; npc_type->bodytype = 1; npc_type->show_name = true; - npc_type->STR = 150; - npc_type->STA = 150; - npc_type->DEX = 150; - npc_type->AGI = 150; - npc_type->INT = 150; - npc_type->WIS = 150; - npc_type->CHA = 150; npc_type->findable = true; + npc_type->runspeed = 1.25; auto node_position = glm::vec4(position.x, position.y, position.z, position.w); auto npc = new NPC(npc_type, nullptr, node_position, GravityBehavior::Flying); + npc->GiveNPCTypeData(npc_type); entity_list.AddNPC(npc, true, true); @@ -2849,3 +2877,8 @@ float NPC::GetProximityMaxZ() { return proximity->max_z; } + +bool NPC::IsProximitySet() +{ + return proximity->proximity_set; +} diff --git a/zone/npc.h b/zone/npc.h index 0ad772754..7ad1fccd0 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -51,6 +51,7 @@ typedef struct { float min_z; float max_z; bool say; + bool proximity_set; } NPCProximity; struct AISpells_Struct { @@ -110,6 +111,7 @@ public: virtual ~NPC(); + static NPC *SpawnNodeNPC(std::string name, std::string last_name, const glm::vec4 &position); static NPC *SpawnGridNodeNPC(std::string name, const glm::vec4 &position, uint32 grid_id, uint32 grid_number, uint32 pause); //abstract virtual function implementations requird by base abstract class @@ -355,6 +357,7 @@ public: float GetProximityMaxY(); float GetProximityMinZ(); float GetProximityMaxZ(); + bool IsProximitySet(); ItemList itemlist; //kathgar - why is this public? Doing other things or I would check the code diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 3905c6abc..dad4ebd26 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -1716,20 +1716,23 @@ void QuestManager::respawn(int npcTypeID, int grid) { } } -void QuestManager::set_proximity(float minx, float maxx, float miny, float maxy, float minz, float maxz, bool bSay) { +void QuestManager::set_proximity(float minx, float maxx, float miny, float maxy, float minz, float maxz, bool bSay) +{ QuestManagerCurrentQuestVars(); - if (!owner || !owner->IsNPC()) + if (!owner || !owner->IsNPC()) { return; + } entity_list.AddProximity(owner->CastToNPC()); - owner->CastToNPC()->proximity->min_x = minx; - owner->CastToNPC()->proximity->max_x = maxx; - owner->CastToNPC()->proximity->min_y = miny; - owner->CastToNPC()->proximity->max_y = maxy; - owner->CastToNPC()->proximity->min_z = minz; - owner->CastToNPC()->proximity->max_z = maxz; - owner->CastToNPC()->proximity->say = bSay; + owner->CastToNPC()->proximity->min_x = minx; + owner->CastToNPC()->proximity->max_x = maxx; + owner->CastToNPC()->proximity->min_y = miny; + owner->CastToNPC()->proximity->max_y = maxy; + owner->CastToNPC()->proximity->min_z = minz; + owner->CastToNPC()->proximity->max_z = maxz; + owner->CastToNPC()->proximity->say = bSay; + owner->CastToNPC()->proximity->proximity_set = true; } void QuestManager::clear_proximity() {