mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-24 09:01:29 +00:00
Simplified the use of roamboxes and improved the AI for roambox pathing
This commit is contained in:
parent
c149e6ca5f
commit
05e7c473df
@ -1,5 +1,13 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 8/16/2019 ==
|
||||||
|
Akkadius: Simplified the use of roamboxes and improved the AI for roambox pathing https://i.imgur.com/z33u7y9.gif
|
||||||
|
Akkadius: Implemented command #roambox set <box_size> [move_delay]
|
||||||
|
Akkadius: Implemented command #roambox remove
|
||||||
|
Akkadius: Implemented LUA NPC:SetSimpleRoamBox(box_size, [move_distance], [move_delay]);
|
||||||
|
Akkadius: Implemented Perl $npc->SetSimpleRoamBox(box_size, [move_distance], [move_delay]);
|
||||||
|
Akkadius: Spawngroup data now hot reloads on #repop
|
||||||
|
|
||||||
== 8/11/2019 ==
|
== 8/11/2019 ==
|
||||||
Akkadius: Added bulk edit command #npceditmass <column-to-search> <column-search-value> <change-column> <change-value>
|
Akkadius: Added bulk edit command #npceditmass <column-to-search> <column-search-value> <change-column> <change-value>
|
||||||
Akkadius: Modified #findzone to include clickable saylinks to both regular zone (if able) and private gmzone instances
|
Akkadius: Modified #findzone to include clickable saylinks to both regular zone (if able) and private gmzone instances
|
||||||
|
|||||||
@ -973,11 +973,13 @@ bool Mob::CombatRange(Mob* other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Father Nitwit's LOS code
|
//Father Nitwit's LOS code
|
||||||
bool Mob::CheckLosFN(Mob* other) {
|
bool Mob::CheckLosFN(Mob *other)
|
||||||
|
{
|
||||||
bool Result = false;
|
bool Result = false;
|
||||||
|
|
||||||
if(other)
|
if (other) {
|
||||||
Result = CheckLosFN(other->GetX(), other->GetY(), other->GetZ(), other->GetSize());
|
Result = CheckLosFN(other->GetX(), other->GetY(), other->GetZ(), other->GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
SetLastLosState(Result);
|
SetLastLosState(Result);
|
||||||
|
|
||||||
|
|||||||
@ -225,7 +225,7 @@ Json::Value ApiGetNpcListDetail(EQ::Net::WebsocketServerConnection *connection,
|
|||||||
row["sec_skill"] = npc->GetSecSkill();
|
row["sec_skill"] = npc->GetSecSkill();
|
||||||
row["silver"] = npc->GetSilver();
|
row["silver"] = npc->GetSilver();
|
||||||
row["slow_mitigation"] = npc->GetSlowMitigation();
|
row["slow_mitigation"] = npc->GetSlowMitigation();
|
||||||
row["sp2"] = npc->GetSp2();
|
row["spawn_group_id"] = npc->GetSpawnGroupId();
|
||||||
row["swarm_owner"] = npc->GetSwarmOwner();
|
row["swarm_owner"] = npc->GetSwarmOwner();
|
||||||
row["swarm_target"] = npc->GetSwarmTarget();
|
row["swarm_target"] = npc->GetSwarmTarget();
|
||||||
row["waypoint_max"] = npc->GetWaypointMax();
|
row["waypoint_max"] = npc->GetWaypointMax();
|
||||||
|
|||||||
@ -34,6 +34,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "lua_parser.h"
|
#include "lua_parser.h"
|
||||||
#include "fastmath.h"
|
#include "fastmath.h"
|
||||||
#include "mob.h"
|
#include "mob.h"
|
||||||
|
#include "npc.h"
|
||||||
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|||||||
117
zone/command.cpp
117
zone/command.cpp
@ -346,6 +346,7 @@ int command_init(void)
|
|||||||
command_add("resetaa", "- Resets a Player's AA in their profile and refunds spent AA's to unspent, may disconnect player.", 200, command_resetaa) ||
|
command_add("resetaa", "- Resets a Player's AA in their profile and refunds spent AA's to unspent, may disconnect player.", 200, command_resetaa) ||
|
||||||
command_add("resetaa_timer", "Command to reset AA cooldown timers.", 200, command_resetaa_timer) ||
|
command_add("resetaa_timer", "Command to reset AA cooldown timers.", 200, command_resetaa_timer) ||
|
||||||
command_add("revoke", "[charname] [1/0] - Makes charname unable to talk on OOC", 200, command_revoke) ||
|
command_add("revoke", "[charname] [1/0] - Makes charname unable to talk on OOC", 200, command_revoke) ||
|
||||||
|
command_add("roambox", "Manages roambox settings for an NPC", 200, command_roambox) ||
|
||||||
command_add("rules", "(subcommand) - Manage server rules", 250, command_rules) ||
|
command_add("rules", "(subcommand) - Manage server rules", 250, command_rules) ||
|
||||||
command_add("save", "- Force your player or player corpse target to be saved to the database", 50, command_save) ||
|
command_add("save", "- Force your player or player corpse target to be saved to the database", 50, command_save) ||
|
||||||
command_add("scale", "- Handles npc scaling", 150, command_scale) ||
|
command_add("scale", "- Handles npc scaling", 150, command_scale) ||
|
||||||
@ -1820,7 +1821,7 @@ void command_npcstats(Client *c, const Seperator *sep)
|
|||||||
//c->Message(Chat::White, "Weapon Item Number: %s", target_npc->GetWeapNo());
|
//c->Message(Chat::White, "Weapon Item Number: %s", target_npc->GetWeapNo());
|
||||||
c->Message(Chat::White, "- Gender: %i Size: %f Bodytype: %d", target_npc->GetGender(), target_npc->GetSize(), target_npc->GetBodyType());
|
c->Message(Chat::White, "- Gender: %i Size: %f Bodytype: %d", target_npc->GetGender(), target_npc->GetSize(), target_npc->GetBodyType());
|
||||||
c->Message(Chat::White, "- Runspeed: %.3f Walkspeed: %.3f", static_cast<float>(0.025f * target_npc->GetRunspeed()), static_cast<float>(0.025f * target_npc->GetWalkspeed()));
|
c->Message(Chat::White, "- Runspeed: %.3f Walkspeed: %.3f", static_cast<float>(0.025f * target_npc->GetRunspeed()), static_cast<float>(0.025f * target_npc->GetWalkspeed()));
|
||||||
c->Message(Chat::White, "- Spawn Group: %i Grid: %i", target_npc->GetSp2(), target_npc->GetGrid());
|
c->Message(Chat::White, "- Spawn Group: %i Grid: %i", target_npc->GetSpawnGroupId(), target_npc->GetGrid());
|
||||||
if (target_npc->proximity) {
|
if (target_npc->proximity) {
|
||||||
c->Message(Chat::White, "- Proximity: Enabled");
|
c->Message(Chat::White, "- Proximity: Enabled");
|
||||||
c->Message(Chat::White, "-- Cur_X: %1.3f, Cur_Y: %1.3f, Cur_Z: %1.3f", target_npc->GetX(), target_npc->GetY(), target_npc->GetZ());
|
c->Message(Chat::White, "-- Cur_X: %1.3f, Cur_Y: %1.3f, Cur_Z: %1.3f", target_npc->GetX(), target_npc->GetY(), target_npc->GetZ());
|
||||||
@ -7199,6 +7200,96 @@ void command_revoke(Client *c, const Seperator *sep)
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void command_roambox(Client *c, const Seperator *sep)
|
||||||
|
{
|
||||||
|
std::string arg1 = sep->arg[1];
|
||||||
|
|
||||||
|
Mob *target = c->GetTarget();
|
||||||
|
if (!target || !target->IsNPC()) {
|
||||||
|
c->Message(Chat::Red, "You need a valid NPC target for this command");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NPC *npc = dynamic_cast<NPC *>(target);
|
||||||
|
int spawn_group_id = npc->GetSpawnGroupId();
|
||||||
|
if (spawn_group_id <= 0) {
|
||||||
|
c->Message(Chat::Red, "NPC needs a valid SpawnGroup!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg1 == "set") {
|
||||||
|
int box_size = (sep->arg[2] ? atoi(sep->arg[2]) : 0);
|
||||||
|
int delay = (sep->arg[3] ? atoi(sep->arg[3]) : 15000);
|
||||||
|
if (box_size > 0) {
|
||||||
|
std::string query = fmt::format(
|
||||||
|
SQL(
|
||||||
|
UPDATE spawngroup SET
|
||||||
|
dist = {},
|
||||||
|
min_x = {},
|
||||||
|
max_x = {},
|
||||||
|
min_y = {},
|
||||||
|
max_y = {},
|
||||||
|
delay = {}
|
||||||
|
WHERE id = {}
|
||||||
|
),
|
||||||
|
box_size,
|
||||||
|
npc->GetX() - 100,
|
||||||
|
npc->GetX() + 100,
|
||||||
|
npc->GetY() - 100,
|
||||||
|
npc->GetY() + 100,
|
||||||
|
delay,
|
||||||
|
spawn_group_id
|
||||||
|
);
|
||||||
|
|
||||||
|
database.QueryDatabase(query);
|
||||||
|
|
||||||
|
c->Message(
|
||||||
|
Chat::Yellow,
|
||||||
|
"NPC (%s) Roam Box set to box size of [%i] SpawnGroupId [%i] delay [%i]",
|
||||||
|
npc->GetCleanName(),
|
||||||
|
box_size,
|
||||||
|
spawn_group_id,
|
||||||
|
delay
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->Message(Chat::Red, "Box size must be set!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg1 == "remove") {
|
||||||
|
std::string query = fmt::format(
|
||||||
|
SQL(
|
||||||
|
UPDATE spawngroup SET
|
||||||
|
dist = 0,
|
||||||
|
min_x = 0,
|
||||||
|
max_x = 0,
|
||||||
|
min_y = 0,
|
||||||
|
max_y = 0,
|
||||||
|
delay = 0
|
||||||
|
WHERE id = {}
|
||||||
|
),
|
||||||
|
spawn_group_id
|
||||||
|
);
|
||||||
|
|
||||||
|
database.QueryDatabase(query);
|
||||||
|
|
||||||
|
c->Message(
|
||||||
|
Chat::Yellow,
|
||||||
|
"NPC (%s) Roam Box has been removed from SpawnGroupID [%i]",
|
||||||
|
npc->GetCleanName(),
|
||||||
|
spawn_group_id
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->Message(Chat::Yellow, "> Command Usage");
|
||||||
|
c->Message(Chat::Yellow, "#roambox set box_size [delay = 0]");
|
||||||
|
c->Message(Chat::Yellow, "#roambox remove");
|
||||||
|
}
|
||||||
|
|
||||||
void command_oocmute(Client *c, const Seperator *sep)
|
void command_oocmute(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
if(sep->arg[1][0] == 0 || !(sep->arg[1][0] == '1' || sep->arg[1][0] == '0'))
|
if(sep->arg[1][0] == 0 || !(sep->arg[1][0] == '1' || sep->arg[1][0] == '0'))
|
||||||
@ -7213,16 +7304,15 @@ void command_oocmute(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
void command_checklos(Client *c, const Seperator *sep)
|
void command_checklos(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
if(c->GetTarget())
|
if (c->GetTarget()) {
|
||||||
{
|
if (c->CheckLosFN(c->GetTarget())) {
|
||||||
// if(c->CheckLos(c->GetTarget()))
|
|
||||||
if(c->CheckLosFN(c->GetTarget()))
|
|
||||||
c->Message(Chat::White, "You have LOS to %s", c->GetTarget()->GetName());
|
c->Message(Chat::White, "You have LOS to %s", c->GetTarget()->GetName());
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
c->Message(Chat::White, "You do not have LOS to %s", c->GetTarget()->GetName());
|
c->Message(Chat::White, "You do not have LOS to %s", c->GetTarget()->GetName());
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
else {
|
||||||
c->Message(Chat::White, "ERROR: Target required");
|
c->Message(Chat::White, "ERROR: Target required");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8102,8 +8192,10 @@ void command_npcedit(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->Message(Chat::Yellow,"NPCID %u now has the animation set to %i on spawn with spawngroup %i", npcTypeID, animation, c->GetTarget()->CastToNPC()->GetSp2() );
|
c->Message(Chat::Yellow,"NPCID %u now has the animation set to %i on spawn with spawngroup %i", npcTypeID, animation,
|
||||||
std::string query = StringFormat("UPDATE spawn2 SET animation = %i " "WHERE spawngroupID = %i", animation, c->GetTarget()->CastToNPC()->GetSp2());
|
c->GetTarget()->CastToNPC()->GetSpawnGroupId() );
|
||||||
|
std::string query = StringFormat("UPDATE spawn2 SET animation = %i " "WHERE spawngroupID = %i", animation,
|
||||||
|
c->GetTarget()->CastToNPC()->GetSpawnGroupId());
|
||||||
database.QueryDatabase(query);
|
database.QueryDatabase(query);
|
||||||
|
|
||||||
c->GetTarget()->SetAppearance(EmuAppearance(animation));
|
c->GetTarget()->SetAppearance(EmuAppearance(animation));
|
||||||
@ -9437,7 +9529,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep)
|
|||||||
int16 version = atoi(sep->arg[2]);
|
int16 version = atoi(sep->arg[2]);
|
||||||
std::string query = StringFormat("UPDATE spawn2 SET version = %i "
|
std::string query = StringFormat("UPDATE spawn2 SET version = %i "
|
||||||
"WHERE spawngroupID = '%i'",
|
"WHERE spawngroupID = '%i'",
|
||||||
version, c->GetTarget()->CastToNPC()->GetSp2());
|
version, c->GetTarget()->CastToNPC()->GetSpawnGroupId());
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
c->Message(Chat::Red, "Update failed! MySQL gave the following error:");
|
c->Message(Chat::Red, "Update failed! MySQL gave the following error:");
|
||||||
@ -9445,7 +9537,8 @@ void command_advnpcspawn(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->Message(Chat::White, "Version change to %i was successful from SpawnGroupID %i", version, c->GetTarget()->CastToNPC()->GetSp2());
|
c->Message(Chat::White, "Version change to %i was successful from SpawnGroupID %i", version,
|
||||||
|
c->GetTarget()->CastToNPC()->GetSpawnGroupId());
|
||||||
c->GetTarget()->Depop(false);
|
c->GetTarget()->Depop(false);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -248,6 +248,7 @@ void command_repopclose(Client *c, const Seperator *sep);
|
|||||||
void command_resetaa(Client* c,const Seperator *sep);
|
void command_resetaa(Client* c,const Seperator *sep);
|
||||||
void command_resetaa_timer(Client *c, const Seperator *sep);
|
void command_resetaa_timer(Client *c, const Seperator *sep);
|
||||||
void command_revoke(Client *c, const Seperator *sep);
|
void command_revoke(Client *c, const Seperator *sep);
|
||||||
|
void command_roambox(Client *c, const Seperator *sep);
|
||||||
void command_rules(Client *c, const Seperator *sep);
|
void command_rules(Client *c, const Seperator *sep);
|
||||||
void command_save(Client *c, const Seperator *sep);
|
void command_save(Client *c, const Seperator *sep);
|
||||||
void command_scale(Client *c, const Seperator *sep);
|
void command_scale(Client *c, const Seperator *sep);
|
||||||
|
|||||||
@ -3728,7 +3728,7 @@ void EntityList::LimitAddNPC(NPC *npc)
|
|||||||
SpawnLimitRecord r;
|
SpawnLimitRecord r;
|
||||||
|
|
||||||
uint16 eid = npc->GetID();
|
uint16 eid = npc->GetID();
|
||||||
r.spawngroup_id = npc->GetSp2();
|
r.spawngroup_id = npc->GetSpawnGroupId();
|
||||||
r.npc_type = npc->GetNPCTypeID();
|
r.npc_type = npc->GetNPCTypeID();
|
||||||
|
|
||||||
npc_limit_list[eid] = r;
|
npc_limit_list[eid] = r;
|
||||||
|
|||||||
@ -159,7 +159,7 @@ void Lua_NPC::SetSaveWaypoint(int wp) {
|
|||||||
|
|
||||||
void Lua_NPC::SetSp2(int sg2) {
|
void Lua_NPC::SetSp2(int sg2) {
|
||||||
Lua_Safe_Call_Void();
|
Lua_Safe_Call_Void();
|
||||||
self->SetSp2(sg2);
|
self->SetSpawnGroupId(sg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Lua_NPC::GetWaypointMax() {
|
int Lua_NPC::GetWaypointMax() {
|
||||||
@ -174,7 +174,7 @@ int Lua_NPC::GetGrid() {
|
|||||||
|
|
||||||
uint32 Lua_NPC::GetSp2() {
|
uint32 Lua_NPC::GetSp2() {
|
||||||
Lua_Safe_Call_Int();
|
Lua_Safe_Call_Int();
|
||||||
return self->GetSp2();
|
return self->GetSpawnGroupId();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Lua_NPC::GetNPCFactionID() {
|
int Lua_NPC::GetNPCFactionID() {
|
||||||
@ -529,6 +529,24 @@ int Lua_NPC::GetAvoidanceRating()
|
|||||||
return self->GetAvoidanceRating();
|
return self->GetAvoidanceRating();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetSimpleRoamBox(float box_size)
|
||||||
|
{
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetSimpleRoamBox(box_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetSimpleRoamBox(float box_size, float move_distance)
|
||||||
|
{
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetSimpleRoamBox(box_size, move_distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetSimpleRoamBox(float box_size, float move_distance, int move_delay)
|
||||||
|
{
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetSimpleRoamBox(box_size, move_distance, move_delay);
|
||||||
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_npc() {
|
luabind::scope lua_register_npc() {
|
||||||
return luabind::class_<Lua_NPC, Lua_Mob>("NPC")
|
return luabind::class_<Lua_NPC, Lua_Mob>("NPC")
|
||||||
.def(luabind::constructor<>())
|
.def(luabind::constructor<>())
|
||||||
@ -614,6 +632,9 @@ luabind::scope lua_register_npc() {
|
|||||||
.def("GetGuardPointZ", (float(Lua_NPC::*)(void))&Lua_NPC::GetGuardPointZ)
|
.def("GetGuardPointZ", (float(Lua_NPC::*)(void))&Lua_NPC::GetGuardPointZ)
|
||||||
.def("SetPrimSkill", (void(Lua_NPC::*)(int))&Lua_NPC::SetPrimSkill)
|
.def("SetPrimSkill", (void(Lua_NPC::*)(int))&Lua_NPC::SetPrimSkill)
|
||||||
.def("SetSecSkill", (void(Lua_NPC::*)(int))&Lua_NPC::SetSecSkill)
|
.def("SetSecSkill", (void(Lua_NPC::*)(int))&Lua_NPC::SetSecSkill)
|
||||||
|
.def("SetSimpleRoamBox", (void(Lua_NPC::*)(float))&Lua_NPC::SetSimpleRoamBox)
|
||||||
|
.def("SetSimpleRoamBox", (void(Lua_NPC::*)(float, float))&Lua_NPC::SetSimpleRoamBox)
|
||||||
|
.def("SetSimpleRoamBox", (void(Lua_NPC::*)(float, float, int))&Lua_NPC::SetSimpleRoamBox)
|
||||||
.def("GetPrimSkill", (int(Lua_NPC::*)(void))&Lua_NPC::GetPrimSkill)
|
.def("GetPrimSkill", (int(Lua_NPC::*)(void))&Lua_NPC::GetPrimSkill)
|
||||||
.def("GetSecSkill", (int(Lua_NPC::*)(void))&Lua_NPC::GetSecSkill)
|
.def("GetSecSkill", (int(Lua_NPC::*)(void))&Lua_NPC::GetSecSkill)
|
||||||
.def("GetSwarmOwner", (int(Lua_NPC::*)(void))&Lua_NPC::GetSwarmOwner)
|
.def("GetSwarmOwner", (int(Lua_NPC::*)(void))&Lua_NPC::GetSwarmOwner)
|
||||||
|
|||||||
@ -131,6 +131,9 @@ public:
|
|||||||
void MerchantCloseShop();
|
void MerchantCloseShop();
|
||||||
int GetRawAC();
|
int GetRawAC();
|
||||||
int GetAvoidanceRating();
|
int GetAvoidanceRating();
|
||||||
|
void SetSimpleRoamBox(float box_size);
|
||||||
|
void SetSimpleRoamBox(float box_size, float move_distance);
|
||||||
|
void SetSimpleRoamBox(float box_size, float move_distance, int move_delay);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -2789,10 +2789,10 @@ void Mob::WipeHateList()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Mob::RandomTimer(int min,int max) {
|
uint32 Mob::RandomTimer(int min, int max)
|
||||||
|
{
|
||||||
int r = 14000;
|
int r = 14000;
|
||||||
if(min != 0 && max != 0 && min < max)
|
if (min != 0 && max != 0 && min < max) {
|
||||||
{
|
|
||||||
r = zone->random.Int(min, max);
|
r = zone->random.Int(min, max);
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
@ -1579,7 +1579,25 @@ void NPC::AI_DoMovement() {
|
|||||||
|
|
||||||
if (GetCWP() == EQEmu::WaypointStatus::RoamBoxPauseInProgress && !IsMoving()) {
|
if (GetCWP() == EQEmu::WaypointStatus::RoamBoxPauseInProgress && !IsMoving()) {
|
||||||
// We have arrived
|
// We have arrived
|
||||||
time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay);
|
|
||||||
|
int roambox_move_delay = EQEmu::ClampLower(GetRoamboxDelay(), GetRoamboxMinDelay());
|
||||||
|
int move_delay_max = (roambox_move_delay > 0 ? roambox_move_delay : (int) GetRoamboxMinDelay() * 4);
|
||||||
|
int random_timer = RandomTimer(
|
||||||
|
GetRoamboxMinDelay(),
|
||||||
|
move_delay_max
|
||||||
|
);
|
||||||
|
|
||||||
|
Log(
|
||||||
|
Logs::Detail,
|
||||||
|
Logs::NPCRoamBox, "(%s) Timer calc | random_timer [%i] roambox_move_delay [%i] move_min [%i] move_max [%i]",
|
||||||
|
this->GetCleanName(),
|
||||||
|
random_timer,
|
||||||
|
roambox_move_delay,
|
||||||
|
(int) GetRoamboxMinDelay(),
|
||||||
|
move_delay_max
|
||||||
|
);
|
||||||
|
|
||||||
|
time_until_can_move = Timer::GetCurrentTime() + random_timer;
|
||||||
SetCurrentWP(0);
|
SetCurrentWP(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1636,25 +1654,51 @@ void NPC::AI_DoMovement() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
roambox_destination_z = 0;
|
PathfinderOptions opts;
|
||||||
/*
|
opts.smooth_path = true;
|
||||||
if (zone->zonemap) {
|
opts.step_size = RuleR(Pathing, NavmeshStepSize);
|
||||||
roambox_destination_z = FindGroundZ(roambox_destination_x, roambox_destination_y, this->GetZOffset());
|
opts.offset = GetZOffset();
|
||||||
}
|
opts.flags = PathingNotDisabled ^ PathingZoneLine;
|
||||||
*/
|
|
||||||
|
|
||||||
Log(Logs::Detail,
|
auto partial = false;
|
||||||
|
auto stuck = false;
|
||||||
|
auto route = zone->pathing->FindPath(
|
||||||
|
glm::vec3(GetX(), GetY(), GetZ()),
|
||||||
|
glm::vec3(
|
||||||
|
roambox_destination_x,
|
||||||
|
roambox_destination_y,
|
||||||
|
GetGroundZ(roambox_destination_x, roambox_destination_y)
|
||||||
|
),
|
||||||
|
partial,
|
||||||
|
stuck,
|
||||||
|
opts
|
||||||
|
);
|
||||||
|
|
||||||
|
if (route.empty()) {
|
||||||
|
Log(
|
||||||
|
Logs::Detail,
|
||||||
|
Logs::NPCRoamBox, "(%s) We don't have a path route... exiting...",
|
||||||
|
this->GetCleanName()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
roambox_destination_z = 0;
|
||||||
|
|
||||||
|
Log(
|
||||||
|
Logs::General,
|
||||||
Logs::NPCRoamBox,
|
Logs::NPCRoamBox,
|
||||||
"Calculate | NPC: %s distance %.3f | min_x %.3f | max_x %.3f | final_x %.3f | min_y %.3f | max_y %.3f | final_y %.3f",
|
"NPC (%s) distance [%.0f] X (min/max) [%.0f / %.0f] Y (min/max) [%.0f / %.0f] | Dest x/y/z [%.0f / %.0f / %.0f]",
|
||||||
this->GetCleanName(),
|
this->GetCleanName(),
|
||||||
roambox_distance,
|
roambox_distance,
|
||||||
roambox_min_x,
|
roambox_min_x,
|
||||||
roambox_max_x,
|
roambox_max_x,
|
||||||
roambox_destination_x,
|
|
||||||
roambox_min_y,
|
roambox_min_y,
|
||||||
roambox_max_y,
|
roambox_max_y,
|
||||||
roambox_destination_y);
|
roambox_destination_x,
|
||||||
Log(Logs::Detail, Logs::NPCRoamBox, "Dest Z is (%f)", roambox_destination_z);
|
roambox_destination_y,
|
||||||
|
roambox_destination_z
|
||||||
|
);
|
||||||
|
|
||||||
SetCurrentWP(EQEmu::WaypointStatus::RoamBoxPauseInProgress);
|
SetCurrentWP(EQEmu::WaypointStatus::RoamBoxPauseInProgress);
|
||||||
NavigateTo(roambox_destination_x, roambox_destination_y, roambox_destination_z);
|
NavigateTo(roambox_destination_x, roambox_destination_y, roambox_destination_z);
|
||||||
|
|||||||
@ -278,7 +278,7 @@ inline std::string GetMobAttributeByString(Mob *mob, const std::string &attribut
|
|||||||
return std::to_string((int)npc->GetWalkspeed());
|
return std::to_string((int)npc->GetWalkspeed());
|
||||||
}
|
}
|
||||||
if (attribute == "spawngroup") {
|
if (attribute == "spawngroup") {
|
||||||
return std::to_string(npc->GetSp2());
|
return std::to_string(npc->GetSpawnGroupId());
|
||||||
}
|
}
|
||||||
if (attribute == "grid") {
|
if (attribute == "grid") {
|
||||||
return std::to_string(npc->GetGrid());
|
return std::to_string(npc->GetGrid());
|
||||||
|
|||||||
20
zone/npc.cpp
20
zone/npc.cpp
@ -159,7 +159,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
|||||||
wp_m = 0;
|
wp_m = 0;
|
||||||
max_wp = 0;
|
max_wp = 0;
|
||||||
save_wp = 0;
|
save_wp = 0;
|
||||||
spawn_group = 0;
|
spawn_group_id = 0;
|
||||||
swarmInfoPtr = nullptr;
|
swarmInfoPtr = nullptr;
|
||||||
spellscale = npc_type_data->spellscale;
|
spellscale = npc_type_data->spellscale;
|
||||||
healscale = npc_type_data->healscale;
|
healscale = npc_type_data->healscale;
|
||||||
@ -1270,7 +1270,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char *zone, uint32 zone_version,
|
|||||||
}
|
}
|
||||||
uint32 spawngroupid = results.LastInsertedID();
|
uint32 spawngroupid = results.LastInsertedID();
|
||||||
|
|
||||||
spawn->SetSp2(spawngroupid);
|
spawn->SetSpawnGroupId(spawngroupid);
|
||||||
spawn->SetNPCTypeID(npc_type_id);
|
spawn->SetNPCTypeID(npc_type_id);
|
||||||
|
|
||||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||||
@ -1355,7 +1355,7 @@ uint32 ZoneDatabase::DeleteSpawnLeaveInNPCTypeTable(const char *zone, Client *cl
|
|||||||
|
|
||||||
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE "
|
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE "
|
||||||
"zone='%s' AND spawngroupID=%i",
|
"zone='%s' AND spawngroupID=%i",
|
||||||
zone, spawn->GetSp2());
|
zone, spawn->GetSpawnGroupId());
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
return 0;
|
return 0;
|
||||||
@ -1396,7 +1396,7 @@ uint32 ZoneDatabase::DeleteSpawnRemoveFromNPCTypeTable(const char *zone, uint32
|
|||||||
|
|
||||||
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE zone = '%s' "
|
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE zone = '%s' "
|
||||||
"AND (version = %u OR version = -1) AND spawngroupID = %i",
|
"AND (version = %u OR version = -1) AND spawngroupID = %i",
|
||||||
zone, zone_version, spawn->GetSp2());
|
zone, zone_version, spawn->GetSpawnGroupId());
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
return 0;
|
return 0;
|
||||||
@ -2924,3 +2924,15 @@ bool NPC::IsProximitySet()
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NPC::SetSimpleRoamBox(float box_size, float move_distance, int move_delay)
|
||||||
|
{
|
||||||
|
AI_SetRoambox(
|
||||||
|
(move_distance != 0 ? move_distance : box_size / 2),
|
||||||
|
GetX() + box_size,
|
||||||
|
GetX() - box_size,
|
||||||
|
GetY() + box_size,
|
||||||
|
GetY() - box_size,
|
||||||
|
move_delay
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -214,13 +214,13 @@ public:
|
|||||||
|
|
||||||
virtual int32 CalcMaxMana();
|
virtual int32 CalcMaxMana();
|
||||||
void SetGrid(int32 grid_){ grid=grid_; }
|
void SetGrid(int32 grid_){ grid=grid_; }
|
||||||
void SetSp2(uint32 sg2){ spawn_group=sg2; }
|
void SetSpawnGroupId(uint32 sg2){ spawn_group_id =sg2; }
|
||||||
void SetWaypointMax(uint16 wp_){ wp_m=wp_; }
|
void SetWaypointMax(uint16 wp_){ wp_m=wp_; }
|
||||||
void SetSaveWaypoint(uint16 wp_){ save_wp=wp_; }
|
void SetSaveWaypoint(uint16 wp_){ save_wp=wp_; }
|
||||||
|
|
||||||
uint16 GetWaypointMax() const { return wp_m; }
|
uint16 GetWaypointMax() const { return wp_m; }
|
||||||
int32 GetGrid() const { return grid; }
|
int32 GetGrid() const { return grid; }
|
||||||
uint32 GetSp2() const { return spawn_group; }
|
uint32 GetSpawnGroupId() const { return spawn_group_id; }
|
||||||
uint32 GetSpawnPointID() const;
|
uint32 GetSpawnPointID() const;
|
||||||
|
|
||||||
glm::vec4 const GetSpawnPoint() const { return m_SpawnPoint; }
|
glm::vec4 const GetSpawnPoint() const { return m_SpawnPoint; }
|
||||||
@ -453,6 +453,8 @@ public:
|
|||||||
|
|
||||||
bool IgnoreDespawn() { return ignore_despawn; }
|
bool IgnoreDespawn() { return ignore_despawn; }
|
||||||
|
|
||||||
|
void SetSimpleRoamBox(float box_size, float move_distance = 0, int move_delay = 0);
|
||||||
|
|
||||||
float GetRoamboxMaxX() const;
|
float GetRoamboxMaxX() const;
|
||||||
float GetRoamboxMaxY() const;
|
float GetRoamboxMaxY() const;
|
||||||
float GetRoamboxMinX() const;
|
float GetRoamboxMinX() const;
|
||||||
@ -483,7 +485,7 @@ protected:
|
|||||||
uint32 gold;
|
uint32 gold;
|
||||||
uint32 platinum;
|
uint32 platinum;
|
||||||
int32 grid;
|
int32 grid;
|
||||||
uint32 spawn_group;
|
uint32 spawn_group_id;
|
||||||
uint16 wp_m;
|
uint16 wp_m;
|
||||||
|
|
||||||
int32 npc_faction_id;
|
int32 npc_faction_id;
|
||||||
|
|||||||
@ -571,7 +571,7 @@ XS(XS_NPC_SetSp2) {
|
|||||||
if (THIS == nullptr)
|
if (THIS == nullptr)
|
||||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
THIS->SetSp2(sg2);
|
THIS->SetSpawnGroupId(sg2);
|
||||||
}
|
}
|
||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
@ -644,7 +644,7 @@ XS(XS_NPC_GetSp2) {
|
|||||||
if (THIS == nullptr)
|
if (THIS == nullptr)
|
||||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
RETVAL = THIS->GetSp2();
|
RETVAL = THIS->GetSpawnGroupId();
|
||||||
XSprePUSH;
|
XSprePUSH;
|
||||||
PUSHu((UV) RETVAL);
|
PUSHu((UV) RETVAL);
|
||||||
}
|
}
|
||||||
@ -2377,6 +2377,42 @@ XS(XS_NPC_GetCombatState) {
|
|||||||
XSRETURN(1);
|
XSRETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_NPC_SetSimpleRoamBox); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_NPC_SetSimpleRoamBox) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items < 2)
|
||||||
|
Perl_croak(aTHX_ "Usage: NPC::SetSimpleRoamBox(THIS, box_size, move_distance, move_delay)");
|
||||||
|
{
|
||||||
|
NPC *THIS;
|
||||||
|
|
||||||
|
auto box_size = (float) SvNV(ST(1));
|
||||||
|
float move_distance = 0;
|
||||||
|
int move_delay = 0;
|
||||||
|
|
||||||
|
if (items >= 3) {
|
||||||
|
move_distance = (float) SvNV(ST(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items >= 4) {
|
||||||
|
move_delay = (int) SvIV(ST(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "NPC")) {
|
||||||
|
IV tmp = SvIV((SV *) SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(NPC *, tmp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type NPC");
|
||||||
|
}
|
||||||
|
if (THIS == nullptr) {
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
}
|
||||||
|
|
||||||
|
THIS->SetSimpleRoamBox(box_size, move_distance, move_delay);
|
||||||
|
}
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
#endif
|
#endif
|
||||||
@ -2488,6 +2524,7 @@ XS(boot_NPC) {
|
|||||||
newXSproto(strcpy(buf, "ChangeLastName"), XS_NPC_ChangeLastName, file, "$:$");
|
newXSproto(strcpy(buf, "ChangeLastName"), XS_NPC_ChangeLastName, file, "$:$");
|
||||||
newXSproto(strcpy(buf, "ClearLastName"), XS_NPC_ClearLastName, file, "$");
|
newXSproto(strcpy(buf, "ClearLastName"), XS_NPC_ClearLastName, file, "$");
|
||||||
newXSproto(strcpy(buf, "GetCombatState"), XS_NPC_GetCombatState, file, "$");
|
newXSproto(strcpy(buf, "GetCombatState"), XS_NPC_GetCombatState, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "SetSimpleRoamBox"), XS_NPC_SetSimpleRoamBox, file, "$$;$$");
|
||||||
XSRETURN_YES;
|
XSRETURN_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -234,59 +234,48 @@ Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, const glm::v
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mob* QuestManager::spawn_from_spawn2(uint32 spawn2_id)
|
Mob *QuestManager::spawn_from_spawn2(uint32 spawn2_id)
|
||||||
{
|
{
|
||||||
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
|
LinkedListIterator<Spawn2 *> iterator(zone->spawn2_list);
|
||||||
iterator.Reset();
|
iterator.Reset();
|
||||||
Spawn2 *found_spawn = nullptr;
|
Spawn2 *found_spawn = nullptr;
|
||||||
|
|
||||||
while(iterator.MoreElements())
|
while (iterator.MoreElements()) {
|
||||||
{
|
Spawn2 *cur = iterator.GetData();
|
||||||
Spawn2* cur = iterator.GetData();
|
|
||||||
iterator.Advance();
|
iterator.Advance();
|
||||||
if(cur->GetID() == spawn2_id)
|
if (cur->GetID() == spawn2_id) {
|
||||||
{
|
|
||||||
found_spawn = cur;
|
found_spawn = cur;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(found_spawn)
|
if (found_spawn) {
|
||||||
{
|
SpawnGroup *spawn_group = zone->spawn_group_list.GetSpawnGroup(found_spawn->SpawnGroupID());
|
||||||
SpawnGroup* sg = zone->spawn_group_list.GetSpawnGroup(found_spawn->SpawnGroupID());
|
if (!spawn_group) {
|
||||||
if(!sg)
|
database.LoadSpawnGroupsByID(found_spawn->SpawnGroupID(), &zone->spawn_group_list);
|
||||||
{
|
spawn_group = zone->spawn_group_list.GetSpawnGroup(found_spawn->SpawnGroupID());
|
||||||
database.LoadSpawnGroupsByID(found_spawn->SpawnGroupID(),&zone->spawn_group_list);
|
if (!spawn_group) {
|
||||||
sg = zone->spawn_group_list.GetSpawnGroup(found_spawn->SpawnGroupID());
|
|
||||||
if(!sg)
|
|
||||||
{
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint32 npcid = sg->GetNPCType();
|
uint32 npcid = spawn_group->GetNPCType();
|
||||||
if(npcid == 0)
|
if (npcid == 0) {
|
||||||
{
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NPCType* tmp = database.LoadNPCTypesData(npcid);
|
const NPCType *tmp = database.LoadNPCTypesData(npcid);
|
||||||
if(!tmp)
|
if (!tmp) {
|
||||||
{
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tmp->unique_spawn_by_name)
|
if (tmp->unique_spawn_by_name) {
|
||||||
{
|
if (!entity_list.LimitCheckName(tmp->name)) {
|
||||||
if(!entity_list.LimitCheckName(tmp->name))
|
|
||||||
{
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tmp->spawn_limit > 0)
|
if (tmp->spawn_limit > 0) {
|
||||||
{
|
if (!entity_list.LimitCheckType(npcid, tmp->spawn_limit)) {
|
||||||
if(!entity_list.LimitCheckType(npcid, tmp->spawn_limit))
|
|
||||||
{
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,21 +283,35 @@ Mob* QuestManager::spawn_from_spawn2(uint32 spawn2_id)
|
|||||||
database.UpdateRespawnTime(spawn2_id, zone->GetInstanceID(), 0);
|
database.UpdateRespawnTime(spawn2_id, zone->GetInstanceID(), 0);
|
||||||
found_spawn->SetCurrentNPCID(npcid);
|
found_spawn->SetCurrentNPCID(npcid);
|
||||||
|
|
||||||
auto position = glm::vec4(found_spawn->GetX(), found_spawn->GetY(), found_spawn->GetZ(), found_spawn->GetHeading());
|
auto position = glm::vec4(
|
||||||
|
found_spawn->GetX(),
|
||||||
|
found_spawn->GetY(),
|
||||||
|
found_spawn->GetZ(),
|
||||||
|
found_spawn->GetHeading()
|
||||||
|
);
|
||||||
|
|
||||||
auto npc = new NPC(tmp, found_spawn, position, GravityBehavior::Water);
|
auto npc = new NPC(tmp, found_spawn, position, GravityBehavior::Water);
|
||||||
|
|
||||||
found_spawn->SetNPCPointer(npc);
|
found_spawn->SetNPCPointer(npc);
|
||||||
npc->AddLootTable();
|
npc->AddLootTable();
|
||||||
if (npc->DropsGlobalLoot())
|
if (npc->DropsGlobalLoot()) {
|
||||||
npc->CheckGlobalLootTables();
|
npc->CheckGlobalLootTables();
|
||||||
npc->SetSp2(found_spawn->SpawnGroupID());
|
}
|
||||||
|
npc->SetSpawnGroupId(found_spawn->SpawnGroupID());
|
||||||
entity_list.AddNPC(npc);
|
entity_list.AddNPC(npc);
|
||||||
entity_list.LimitAddNPC(npc);
|
entity_list.LimitAddNPC(npc);
|
||||||
|
|
||||||
if (sg->roamdist && sg->roambox[0] && sg->roambox[1] && sg->roambox[2] && sg->roambox[3] && sg->delay &&
|
if (spawn_group->roamdist > 0) {
|
||||||
sg->min_delay)
|
npc->AI_SetRoambox(
|
||||||
npc->AI_SetRoambox(sg->roamdist, sg->roambox[0], sg->roambox[1], sg->roambox[2], sg->roambox[3],
|
spawn_group->roamdist,
|
||||||
sg->delay, sg->min_delay);
|
spawn_group->roambox[0],
|
||||||
|
spawn_group->roambox[1],
|
||||||
|
spawn_group->roambox[2],
|
||||||
|
spawn_group->roambox[3],
|
||||||
|
spawn_group->delay,
|
||||||
|
spawn_group->min_delay
|
||||||
|
);
|
||||||
|
}
|
||||||
if (zone->InstantGrids()) {
|
if (zone->InstantGrids()) {
|
||||||
found_spawn->LoadGrid();
|
found_spawn->LoadGrid();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -264,7 +264,7 @@ bool Spawn2::Process() {
|
|||||||
if (npc->DropsGlobalLoot()) {
|
if (npc->DropsGlobalLoot()) {
|
||||||
npc->CheckGlobalLootTables();
|
npc->CheckGlobalLootTables();
|
||||||
}
|
}
|
||||||
npc->SetSp2(spawngroup_id_);
|
npc->SetSpawnGroupId(spawngroup_id_);
|
||||||
npc->SaveGuardPointAnim(anim);
|
npc->SaveGuardPointAnim(anim);
|
||||||
npc->SetAppearance((EmuAppearance) anim);
|
npc->SetAppearance((EmuAppearance) anim);
|
||||||
entity_list.AddNPC(npc);
|
entity_list.AddNPC(npc);
|
||||||
@ -274,9 +274,7 @@ bool Spawn2::Process() {
|
|||||||
/**
|
/**
|
||||||
* Roambox init
|
* Roambox init
|
||||||
*/
|
*/
|
||||||
if (spawn_group->roamdist && spawn_group->roambox[0] && spawn_group->roambox[1] && spawn_group->roambox[2] &&
|
if (spawn_group->roamdist > 0) {
|
||||||
spawn_group->roambox[3] && spawn_group->delay && spawn_group->min_delay) {
|
|
||||||
|
|
||||||
npc->AI_SetRoambox(
|
npc->AI_SetRoambox(
|
||||||
spawn_group->roamdist,
|
spawn_group->roamdist,
|
||||||
spawn_group->roambox[0],
|
spawn_group->roambox[0],
|
||||||
@ -298,7 +296,8 @@ bool Spawn2::Process() {
|
|||||||
npcid,
|
npcid,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
z);
|
z
|
||||||
|
);
|
||||||
|
|
||||||
LoadGrid();
|
LoadGrid();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,8 +16,8 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
#include "../common/global_define.h"
|
#include "../common/global_define.h"
|
||||||
#include "../common/string_util.h"
|
|
||||||
#include "../common/types.h"
|
#include "../common/types.h"
|
||||||
|
|
||||||
#include "entity.h"
|
#include "entity.h"
|
||||||
@ -26,209 +26,352 @@
|
|||||||
#include "zonedb.h"
|
#include "zonedb.h"
|
||||||
|
|
||||||
extern EntityList entity_list;
|
extern EntityList entity_list;
|
||||||
extern Zone* zone;
|
extern Zone *zone;
|
||||||
|
|
||||||
SpawnEntry::SpawnEntry( uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit ) {
|
SpawnEntry::SpawnEntry(uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit)
|
||||||
|
{
|
||||||
NPCType = in_NPCType;
|
NPCType = in_NPCType;
|
||||||
chance = in_chance;
|
chance = in_chance;
|
||||||
npc_spawn_limit = in_npc_spawn_limit;
|
npc_spawn_limit = in_npc_spawn_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpawnGroup::SpawnGroup( uint32 in_id, char* name, int in_group_spawn_limit, float dist, float maxx, float minx, float maxy, float miny, int delay_in, int despawn_in, uint32 despawn_timer_in, int min_delay_in ) {
|
SpawnGroup::SpawnGroup(
|
||||||
|
uint32 in_id,
|
||||||
|
char *name,
|
||||||
|
int in_group_spawn_limit,
|
||||||
|
float dist,
|
||||||
|
float maxx,
|
||||||
|
float minx,
|
||||||
|
float maxy,
|
||||||
|
float miny,
|
||||||
|
int delay_in,
|
||||||
|
int despawn_in,
|
||||||
|
uint32 despawn_timer_in,
|
||||||
|
int min_delay_in
|
||||||
|
)
|
||||||
|
{
|
||||||
id = in_id;
|
id = in_id;
|
||||||
strn0cpy( name_, name, 120);
|
strn0cpy(name_, name, 120);
|
||||||
group_spawn_limit = in_group_spawn_limit;
|
group_spawn_limit = in_group_spawn_limit;
|
||||||
roambox[0]=maxx;
|
roambox[0] = maxx;
|
||||||
roambox[1]=minx;
|
roambox[1] = minx;
|
||||||
roambox[2]=maxy;
|
roambox[2] = maxy;
|
||||||
roambox[3]=miny;
|
roambox[3] = miny;
|
||||||
roamdist=dist;
|
roamdist = dist;
|
||||||
min_delay=min_delay_in;
|
min_delay = min_delay_in;
|
||||||
delay=delay_in;
|
delay = delay_in;
|
||||||
despawn=despawn_in;
|
despawn = despawn_in;
|
||||||
despawn_timer=despawn_timer_in;
|
despawn_timer = despawn_timer_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 SpawnGroup::GetNPCType() {
|
uint32 SpawnGroup::GetNPCType()
|
||||||
|
{
|
||||||
#if EQDEBUG >= 10
|
#if EQDEBUG >= 10
|
||||||
Log(Logs::General, Logs::None, "SpawnGroup[%08x]::GetNPCType()", (uint32) this);
|
Log(Logs::General, Logs::None, "SpawnGroup[%08x]::GetNPCType()", (uint32) this);
|
||||||
#endif
|
#endif
|
||||||
int npcType = 0;
|
int npcType = 0;
|
||||||
int totalchance = 0;
|
int totalchance = 0;
|
||||||
|
|
||||||
if(!entity_list.LimitCheckGroup(id, group_spawn_limit))
|
if (!entity_list.LimitCheckGroup(id, group_spawn_limit)) {
|
||||||
return(0);
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
std::list<SpawnEntry*>::iterator cur,end;
|
std::list<SpawnEntry *>::iterator cur, end;
|
||||||
std::list<SpawnEntry*> possible;
|
std::list<SpawnEntry *> possible;
|
||||||
cur = list_.begin();
|
cur = list_.begin();
|
||||||
end = list_.end();
|
end = list_.end();
|
||||||
for(; cur != end; ++cur) {
|
for (; cur != end; ++cur) {
|
||||||
SpawnEntry *se = *cur;
|
SpawnEntry *se = *cur;
|
||||||
|
|
||||||
if(!entity_list.LimitCheckType(se->NPCType, se->npc_spawn_limit))
|
if (!entity_list.LimitCheckType(se->NPCType, se->npc_spawn_limit)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
totalchance += se->chance;
|
totalchance += se->chance;
|
||||||
possible.push_back(se);
|
possible.push_back(se);
|
||||||
}
|
}
|
||||||
if(totalchance == 0)
|
if (totalchance == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32 roll = 0;
|
int32 roll = 0;
|
||||||
roll = zone->random.Int(0, totalchance-1);
|
roll = zone->random.Int(0, totalchance - 1);
|
||||||
|
|
||||||
cur = possible.begin();
|
cur = possible.begin();
|
||||||
end = possible.end();
|
end = possible.end();
|
||||||
for(; cur != end; ++cur) {
|
for (; cur != end; ++cur) {
|
||||||
SpawnEntry *se = *cur;
|
SpawnEntry *se = *cur;
|
||||||
if (roll < se->chance) {
|
if (roll < se->chance) {
|
||||||
npcType = se->NPCType;
|
npcType = se->NPCType;
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
roll -= se->chance;
|
roll -= se->chance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return npcType;
|
return npcType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpawnGroup::AddSpawnEntry( SpawnEntry* newEntry ) {
|
void SpawnGroup::AddSpawnEntry(SpawnEntry *newEntry)
|
||||||
list_.push_back( newEntry );
|
{
|
||||||
|
list_.push_back(newEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpawnGroup::~SpawnGroup() {
|
SpawnGroup::~SpawnGroup()
|
||||||
std::list<SpawnEntry*>::iterator cur,end;
|
{
|
||||||
|
std::list<SpawnEntry *>::iterator cur, end;
|
||||||
cur = list_.begin();
|
cur = list_.begin();
|
||||||
end = list_.end();
|
end = list_.end();
|
||||||
for(; cur != end; ++cur) {
|
for (; cur != end; ++cur) {
|
||||||
SpawnEntry* tmp = *cur;
|
SpawnEntry *tmp = *cur;
|
||||||
safe_delete(tmp);
|
safe_delete(tmp);
|
||||||
}
|
}
|
||||||
list_.clear();
|
list_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
SpawnGroupList::~SpawnGroupList() {
|
SpawnGroupList::~SpawnGroupList()
|
||||||
std::map<uint32, SpawnGroup*>::iterator cur,end;
|
{
|
||||||
cur = groups.begin();
|
std::map<uint32, SpawnGroup *>::iterator cur, end;
|
||||||
end = groups.end();
|
cur = m_spawn_groups.begin();
|
||||||
for(; cur != end; ++cur) {
|
end = m_spawn_groups.end();
|
||||||
SpawnGroup* tmp = cur->second;
|
for (; cur != end; ++cur) {
|
||||||
|
SpawnGroup *tmp = cur->second;
|
||||||
safe_delete(tmp);
|
safe_delete(tmp);
|
||||||
}
|
}
|
||||||
groups.clear();
|
m_spawn_groups.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpawnGroupList::AddSpawnGroup(SpawnGroup* newGroup) {
|
void SpawnGroupList::AddSpawnGroup(SpawnGroup *new_group)
|
||||||
if(newGroup == nullptr)
|
{
|
||||||
|
if (new_group == nullptr) {
|
||||||
return;
|
return;
|
||||||
groups[newGroup->id] = newGroup;
|
}
|
||||||
|
|
||||||
|
m_spawn_groups[new_group->id] = new_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpawnGroup* SpawnGroupList::GetSpawnGroup(uint32 in_id) {
|
SpawnGroup *SpawnGroupList::GetSpawnGroup(uint32 in_id)
|
||||||
if(groups.count(in_id) != 1)
|
{
|
||||||
|
if (m_spawn_groups.count(in_id) != 1) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return(groups[in_id]);
|
}
|
||||||
|
|
||||||
|
return (m_spawn_groups[in_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpawnGroupList::RemoveSpawnGroup(uint32 in_id) {
|
bool SpawnGroupList::RemoveSpawnGroup(uint32 in_id)
|
||||||
if(groups.count(in_id) != 1)
|
{
|
||||||
return(false);
|
if (m_spawn_groups.count(in_id) != 1) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
groups.erase(in_id);
|
m_spawn_groups.erase(in_id);
|
||||||
return(true);
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpawnGroupList::ReloadSpawnGroups()
|
||||||
|
{
|
||||||
|
ClearSpawnGroups();
|
||||||
|
database.LoadSpawnGroups(zone->GetShortName(), zone->GetInstanceVersion(), &zone->spawn_group_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpawnGroupList::ClearSpawnGroups()
|
||||||
|
{
|
||||||
|
m_spawn_groups.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::LoadSpawnGroups(const char *zone_name, uint16 version, SpawnGroupList *spawn_group_list)
|
bool ZoneDatabase::LoadSpawnGroups(const char *zone_name, uint16 version, SpawnGroupList *spawn_group_list)
|
||||||
{
|
{
|
||||||
std::string query = StringFormat("SELECT DISTINCT(spawngroupID), spawngroup.name, spawngroup.spawn_limit, "
|
std::string query = fmt::format(
|
||||||
"spawngroup.dist, spawngroup.max_x, spawngroup.min_x, "
|
SQL(
|
||||||
"spawngroup.max_y, spawngroup.min_y, spawngroup.delay, "
|
SELECT
|
||||||
"spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay "
|
DISTINCT(spawngroupID),
|
||||||
"FROM spawn2, spawngroup WHERE spawn2.spawngroupID = spawngroup.ID "
|
spawngroup.name,
|
||||||
"AND spawn2.version = %u and zone = '%s'",
|
spawngroup.spawn_limit,
|
||||||
version, zone_name);
|
spawngroup.dist,
|
||||||
|
spawngroup.max_x,
|
||||||
|
spawngroup.min_x,
|
||||||
|
spawngroup.max_y,
|
||||||
|
spawngroup.min_y,
|
||||||
|
spawngroup.delay,
|
||||||
|
spawngroup.despawn,
|
||||||
|
spawngroup.despawn_timer,
|
||||||
|
spawngroup.mindelay
|
||||||
|
FROM
|
||||||
|
spawn2,
|
||||||
|
spawngroup
|
||||||
|
WHERE
|
||||||
|
spawn2.spawngroupID = spawngroup.ID
|
||||||
|
AND
|
||||||
|
spawn2.version = {} and zone = '{}'
|
||||||
|
),
|
||||||
|
version,
|
||||||
|
zone_name
|
||||||
|
);
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
auto newSpawnGroup = new SpawnGroup(atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]),
|
auto new_spawn_group = new SpawnGroup(
|
||||||
atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]),
|
atoi(row[0]),
|
||||||
atoi(row[9]), atoi(row[10]), atoi(row[11]));
|
row[1],
|
||||||
spawn_group_list->AddSpawnGroup(newSpawnGroup);
|
atoi(row[2]),
|
||||||
|
atof(row[3]),
|
||||||
|
atof(row[4]),
|
||||||
|
atof(row[5]),
|
||||||
|
atof(row[6]),
|
||||||
|
atof(row[7]),
|
||||||
|
atoi(row[8]),
|
||||||
|
atoi(row[9]),
|
||||||
|
atoi(row[10]),
|
||||||
|
atoi(row[11])
|
||||||
|
);
|
||||||
|
|
||||||
|
spawn_group_list->AddSpawnGroup(new_spawn_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
query = StringFormat("SELECT DISTINCT spawnentry.spawngroupID, npcid, chance, "
|
query = fmt::format(
|
||||||
"npc_types.spawn_limit AS sl "
|
SQL(
|
||||||
"FROM spawnentry, spawn2, npc_types "
|
SELECT
|
||||||
"WHERE spawnentry.npcID=npc_types.id "
|
DISTINCT
|
||||||
"AND spawnentry.spawngroupID = spawn2.spawngroupID "
|
spawnentry.spawngroupID,
|
||||||
"AND zone = '%s'",
|
npcid,
|
||||||
zone_name);
|
chance,
|
||||||
|
npc_types.spawn_limit
|
||||||
|
AS sl
|
||||||
|
FROM
|
||||||
|
spawnentry,
|
||||||
|
spawn2,
|
||||||
|
npc_types
|
||||||
|
WHERE
|
||||||
|
spawnentry.npcID = npc_types.id
|
||||||
|
AND
|
||||||
|
spawnentry.spawngroupID = spawn2.spawngroupID
|
||||||
|
AND
|
||||||
|
zone = '{}'),
|
||||||
|
zone_name
|
||||||
|
);
|
||||||
|
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
Log(Logs::General, Logs::Error, "Error2 in PopulateZoneLists query '%'", query.c_str());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
auto newSpawnEntry = new SpawnEntry(atoi(row[1]), atoi(row[2]), row[3] ? atoi(row[3]) : 0);
|
auto new_spawn_entry = new SpawnEntry(
|
||||||
SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
atoi(row[1]),
|
||||||
|
atoi(row[2]),
|
||||||
|
(row[3] ? atoi(row[3]) : 0)
|
||||||
|
);
|
||||||
|
|
||||||
if (!sg) {
|
SpawnGroup *spawn_group = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
||||||
safe_delete(newSpawnEntry);
|
|
||||||
|
if (!spawn_group) {
|
||||||
|
safe_delete(new_spawn_entry);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sg->AddSpawnEntry(newSpawnEntry);
|
spawn_group->AddSpawnEntry(new_spawn_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList *spawn_group_list)
|
/**
|
||||||
|
* @param spawn_group_id
|
||||||
|
* @param spawn_group_list
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool ZoneDatabase::LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList *spawn_group_list)
|
||||||
{
|
{
|
||||||
std::string query = StringFormat("SELECT DISTINCT(spawngroup.id), spawngroup.name, spawngroup.spawn_limit, "
|
std::string query = fmt::format(
|
||||||
"spawngroup.dist, spawngroup.max_x, spawngroup.min_x, "
|
SQL(
|
||||||
"spawngroup.max_y, spawngroup.min_y, spawngroup.delay, "
|
SELECT DISTINCT
|
||||||
"spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay "
|
(spawngroup.id),
|
||||||
"FROM spawngroup WHERE spawngroup.ID = '%i'",
|
spawngroup.name,
|
||||||
spawngroupid);
|
spawngroup.spawn_limit,
|
||||||
|
spawngroup.dist,
|
||||||
|
spawngroup.max_x,
|
||||||
|
spawngroup.min_x,
|
||||||
|
spawngroup.max_y,
|
||||||
|
spawngroup.min_y,
|
||||||
|
spawngroup.delay,
|
||||||
|
spawngroup.despawn,
|
||||||
|
spawngroup.despawn_timer,
|
||||||
|
spawngroup.mindelay
|
||||||
|
FROM
|
||||||
|
spawngroup
|
||||||
|
WHERE
|
||||||
|
spawngroup.ID = '{}'
|
||||||
|
),
|
||||||
|
spawn_group_id
|
||||||
|
);
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
Log(Logs::General, Logs::Error, "Error2 in PopulateZoneLists query %s", query.c_str());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
auto newSpawnGroup = new SpawnGroup(atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]),
|
auto new_spawn_group = new SpawnGroup(
|
||||||
atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]),
|
atoi(row[0]),
|
||||||
atoi(row[9]), atoi(row[10]), atoi(row[11]));
|
row[1],
|
||||||
spawn_group_list->AddSpawnGroup(newSpawnGroup);
|
atoi(row[2]),
|
||||||
|
atof(row[3]),
|
||||||
|
atof(row[4]),
|
||||||
|
atof(row[5]),
|
||||||
|
atof(row[6]),
|
||||||
|
atof(row[7]),
|
||||||
|
atoi(row[8]),
|
||||||
|
atoi(row[9]),
|
||||||
|
atoi(row[10]),
|
||||||
|
atoi(row[11])
|
||||||
|
);
|
||||||
|
|
||||||
|
spawn_group_list->AddSpawnGroup(new_spawn_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
query = StringFormat("SELECT DISTINCT(spawnentry.spawngroupID), spawnentry.npcid, "
|
query = fmt::format(
|
||||||
"spawnentry.chance, spawngroup.spawn_limit FROM spawnentry, spawngroup "
|
SQL(
|
||||||
"WHERE spawnentry.spawngroupID = '%i' AND spawngroup.spawn_limit = '0' "
|
SELECT DISTINCT
|
||||||
"ORDER BY chance",
|
(spawnentry.spawngroupID),
|
||||||
spawngroupid);
|
spawnentry.npcid,
|
||||||
|
spawnentry.chance,
|
||||||
|
spawngroup.spawn_limit
|
||||||
|
FROM
|
||||||
|
spawnentry,
|
||||||
|
spawngroup
|
||||||
|
WHERE
|
||||||
|
spawnentry.spawngroupID = '{}'
|
||||||
|
AND spawngroup.spawn_limit = '0'
|
||||||
|
ORDER BY chance),
|
||||||
|
spawn_group_id
|
||||||
|
);
|
||||||
|
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
Log(Logs::General, Logs::Error, "Error3 in PopulateZoneLists query '%s'", query.c_str());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
auto newSpawnEntry = new SpawnEntry(atoi(row[1]), atoi(row[2]), row[3] ? atoi(row[3]) : 0);
|
auto new_spawn_entry = new SpawnEntry(
|
||||||
SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
atoi(row[1]),
|
||||||
if (!sg) {
|
atoi(row[2]),
|
||||||
safe_delete(newSpawnEntry);
|
(row[3] ? atoi(row[3]) : 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
SpawnGroup *spawn_group = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
||||||
|
if (!spawn_group) {
|
||||||
|
safe_delete(new_spawn_entry);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sg->AddSpawnEntry(newSpawnEntry);
|
spawn_group->AddSpawnEntry(new_spawn_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -23,11 +23,10 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
class SpawnEntry
|
class SpawnEntry {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
SpawnEntry(uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit );
|
SpawnEntry(uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit);
|
||||||
~SpawnEntry() { }
|
~SpawnEntry() {}
|
||||||
uint32 NPCType;
|
uint32 NPCType;
|
||||||
int chance;
|
int chance;
|
||||||
|
|
||||||
@ -35,13 +34,26 @@ public:
|
|||||||
uint8 npc_spawn_limit; //max # of this entry which can be spawned in this zone
|
uint8 npc_spawn_limit; //max # of this entry which can be spawned in this zone
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpawnGroup
|
class SpawnGroup {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
SpawnGroup(uint32 in_id, char* name, int in_group_spawn_limit, float dist, float maxx, float minx, float maxy, float miny, int delay_in, int despawn_in, uint32 despawn_timer_in, int min_delay_in );
|
SpawnGroup(
|
||||||
|
uint32 in_id,
|
||||||
|
char *name,
|
||||||
|
int in_group_spawn_limit,
|
||||||
|
float dist,
|
||||||
|
float maxx,
|
||||||
|
float minx,
|
||||||
|
float maxy,
|
||||||
|
float miny,
|
||||||
|
int delay_in,
|
||||||
|
int despawn_in,
|
||||||
|
uint32 despawn_timer_in,
|
||||||
|
int min_delay_in
|
||||||
|
);
|
||||||
|
|
||||||
~SpawnGroup();
|
~SpawnGroup();
|
||||||
uint32 GetNPCType();
|
uint32 GetNPCType();
|
||||||
void AddSpawnEntry( SpawnEntry* newEntry );
|
void AddSpawnEntry(SpawnEntry *newEntry);
|
||||||
uint32 id;
|
uint32 id;
|
||||||
float roamdist;
|
float roamdist;
|
||||||
float roambox[4];
|
float roambox[4];
|
||||||
@ -51,22 +63,23 @@ public:
|
|||||||
uint32 despawn_timer;
|
uint32 despawn_timer;
|
||||||
private:
|
private:
|
||||||
char name_[120];
|
char name_[120];
|
||||||
std::list<SpawnEntry*> list_;
|
std::list<SpawnEntry *> list_;
|
||||||
uint8 group_spawn_limit; //max # of this entry which can be spawned by this group
|
uint8 group_spawn_limit; //max # of this entry which can be spawned by this group
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpawnGroupList
|
class SpawnGroupList {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
SpawnGroupList() { }
|
SpawnGroupList() {}
|
||||||
~SpawnGroupList();
|
~SpawnGroupList();
|
||||||
|
|
||||||
void AddSpawnGroup(SpawnGroup* newGroup);
|
void AddSpawnGroup(SpawnGroup *new_group);
|
||||||
SpawnGroup* GetSpawnGroup(uint32 id);
|
SpawnGroup *GetSpawnGroup(uint32 id);
|
||||||
bool RemoveSpawnGroup(uint32 in_id);
|
bool RemoveSpawnGroup(uint32 in_id);
|
||||||
|
void ClearSpawnGroups();
|
||||||
|
void ReloadSpawnGroups();
|
||||||
private:
|
private:
|
||||||
//LinkedList<SpawnGroup*> list_;
|
//LinkedList<SpawnGroup*> list_;
|
||||||
std::map<uint32, SpawnGroup*> groups;
|
std::map<uint32, SpawnGroup *> m_spawn_groups;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -57,7 +57,16 @@ void NPC::AI_SetRoambox(float max_distance, float roam_distance_variance, uint32
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPC::AI_SetRoambox(float distance, float max_x, float min_x, float max_y, float min_y, uint32 delay, uint32 min_delay) {
|
void NPC::AI_SetRoambox(
|
||||||
|
float distance,
|
||||||
|
float max_x,
|
||||||
|
float min_x,
|
||||||
|
float max_y,
|
||||||
|
float min_y,
|
||||||
|
uint32 delay,
|
||||||
|
uint32 min_delay
|
||||||
|
)
|
||||||
|
{
|
||||||
roambox_distance = distance;
|
roambox_distance = distance;
|
||||||
roambox_max_x = max_x;
|
roambox_max_x = max_x;
|
||||||
roambox_min_x = min_x;
|
roambox_min_x = min_x;
|
||||||
@ -72,7 +81,7 @@ void NPC::DisplayWaypointInfo(Client *c) {
|
|||||||
|
|
||||||
c->Message(Chat::White, "Mob is on grid %d, in spawn group %d, on waypoint %d/%d",
|
c->Message(Chat::White, "Mob is on grid %d, in spawn group %d, on waypoint %d/%d",
|
||||||
GetGrid(),
|
GetGrid(),
|
||||||
GetSp2(),
|
GetSpawnGroupId(),
|
||||||
GetCurWp(),
|
GetCurWp(),
|
||||||
GetMaxWp());
|
GetMaxWp());
|
||||||
|
|
||||||
|
|||||||
@ -1485,6 +1485,8 @@ bool Zone::Depop(bool StartSpawnTimer) {
|
|||||||
// clear spell cache
|
// clear spell cache
|
||||||
database.ClearNPCSpells();
|
database.ClearNPCSpells();
|
||||||
|
|
||||||
|
zone->spawn_group_list.ReloadSpawnGroups();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -409,7 +409,7 @@ public:
|
|||||||
|
|
||||||
/* Spawns and Spawn Points */
|
/* Spawns and Spawn Points */
|
||||||
bool LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list);
|
bool LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list);
|
||||||
bool LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list);
|
bool LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList* spawn_group_list);
|
||||||
bool PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay = 0);
|
bool PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay = 0);
|
||||||
bool PopulateZoneSpawnListClose(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, const glm::vec4& client_position, uint32 repop_distance);
|
bool PopulateZoneSpawnListClose(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, const glm::vec4& client_position, uint32 repop_distance);
|
||||||
Spawn2* LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2id, uint32 timeleft);
|
Spawn2* LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2id, uint32 timeleft);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user