[Feature] Allow any spawn2 spawned mob to path while zone is idle if new flag is set. (#1339)

* Changes to allow any spawn2 to be marked to path even when zone is idle

* Fixed for Kingly review of PR

Co-authored-by: Noudess <noudess@gmail.com>
This commit is contained in:
Paul Coene 2021-05-10 02:21:43 -04:00 committed by GitHub
parent b335568bf9
commit 2edda6e743
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 87 additions and 50 deletions

View File

@ -34,7 +34,7 @@
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9164
#define CURRENT_BINARY_DATABASE_VERSION 9165
#ifdef BOTS
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9027

View File

@ -418,6 +418,7 @@
9162|2021_02_17_server_scheduled_events.sql|SELECT * FROM db_version WHERE version >= 9162|empty|
9163|2021_04_17_zone_safe_heading_changes.sql|SHOW COLUMNS FROM `zone` LIKE 'safe_heading'|empty|
9164|2021_04_23_character_exp_modifiers.sql|SHOW TABLES LIKE 'character_exp_modifiers'|empty|
9165|2021_04_28_idle_pathing.sql|SHOW COLUMNS FROM `spawn2` LIKE 'path_when_zone_idle'|empty|
# Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not

View File

@ -0,0 +1,13 @@
-- Add new path_when_zone_idle flag to allow some spawns to path in empty zones
ALTER TABLE spawn2 ADD COLUMN path_when_zone_idle tinyint(1) NOT NULL DEFAULT 0 AFTER pathgrid;
-- Update spawns that used to path in empty zones because of their grid type
-- to behave the same using the new mechanism. The code that checked path grid
-- types has been removed as it was coincidentally coupled to idle movement.
-- The new flag path_when_zone_idle is the new mechanism, and allows any moving
-- mob, not just those on grids, to path while the zone is idle.
UPDATE spawn2 s
LEFT JOIN zone z on z.short_name = s.zone
LEFT JOIN grid g on g.id = s.pathgrid AND g.zoneid = z.zoneidnumber
SET path_when_zone_idle = 1
WHERE pathgrid != 0 AND g.type in (4, 6)

View File

@ -517,13 +517,15 @@ void EntityList::MobProcess()
mob_settle_timer->Disable();
}
Spawn2* s2 = mob->CastToNPC()->respawn2;
// Perform normal mob processing if any of these are true:
// -- zone is not empty
// -- a quest has turned it on for this zone while zone is idle
// -- the entity's spawn2 point is marked as path_while_zone_idle
// -- the zone is newly empty and we're allowing mobs to settle
if (zone->process_mobs_while_empty || numclients > 0 ||
mob->GetWanderType() == 4 || mob->GetWanderType() == 6 ||
mob_settle_timer->Enabled()) {
// Normal processing, or assuring that spawns that should
// path and depop do that. Otherwise all of these type mobs
// will be up and at starting positions, or waiting at the zoneline
// if they chased the PCs when idle zone wakes up.
(s2 && s2->PathWhenZoneIdle()) || mob_settle_timer->Enabled()) {
mob_dead = !mob->Process();
}
else {

View File

@ -1732,6 +1732,7 @@ void lua_add_spawn_point(luabind::adl::object table) {
uint32 variance;
uint32 timeleft = 0;
uint32 grid = 0;
bool path_when_zone_idle = false;
int condition_id = 0;
int condition_min_value = 0;
bool enabled = true;
@ -1841,6 +1842,14 @@ void lua_add_spawn_point(luabind::adl::object table) {
}
}
cur = table["path_when_zone_idle"];
if(luabind::type(cur) != LUA_TNIL) {
try {
path_when_zone_idle = luabind::object_cast<bool>(cur);
} catch(luabind::cast_failed &) {
}
}
cur = table["condition_id"];
if(luabind::type(cur) != LUA_TNIL) {
try {
@ -1875,8 +1884,10 @@ void lua_add_spawn_point(luabind::adl::object table) {
lua_remove_spawn_point(spawn2_id);
auto t = new Spawn2(spawn2_id, spawngroup_id, x, y, z, heading, respawn, variance, timeleft, grid,
condition_id, condition_min_value, enabled, static_cast<EmuAppearance>(animation));
auto t = new Spawn2(spawn2_id, spawngroup_id, x, y, z, heading, respawn,
variance, timeleft, grid, path_when_zone_idle, condition_id,
condition_min_value, enabled, static_cast<EmuAppearance>(animation));
zone->spawn2_list.Insert(t);
}
}

View File

@ -70,7 +70,8 @@ CREATE TABLE spawn_events (
Spawn2::Spawn2(uint32 in_spawn2_id, uint32 spawngroup_id,
float in_x, float in_y, float in_z, float in_heading,
uint32 respawn, uint32 variance, uint32 timeleft, uint32 grid,
uint16 in_cond_id, int16 in_min_value, bool in_enabled, EmuAppearance anim)
bool in_path_when_zone_idle, uint16 in_cond_id, int16 in_min_value,
bool in_enabled, EmuAppearance anim)
: timer(100000), killcount(0)
{
spawn2_id = in_spawn2_id;
@ -82,6 +83,7 @@ Spawn2::Spawn2(uint32 in_spawn2_id, uint32 spawngroup_id,
respawn_ = respawn;
variance_ = variance;
grid_ = grid;
path_when_zone_idle = in_path_when_zone_idle;
condition_id = in_cond_id;
condition_min_value = in_min_value;
npcthis = nullptr;
@ -474,6 +476,7 @@ bool ZoneDatabase::PopulateZoneSpawnListClose(uint32 zoneid, LinkedList<Spawn2*>
"respawntime, "
"variance, "
"pathgrid, "
"path_when_zone_idle, "
"_condition, "
"cond_value, "
"enabled, "
@ -494,7 +497,7 @@ bool ZoneDatabase::PopulateZoneSpawnListClose(uint32 zoneid, LinkedList<Spawn2*>
uint32 spawn_time_left = 0;
Spawn2* new_spawn = 0;
bool perl_enabled = atoi(row[11]) == 1 ? true : false;
bool perl_enabled = atoi(row[12]) == 1 ? true : false;
if (spawn_times.count(atoi(row[0])) != 0)
spawn_time_left = spawn_times[atoi(row[0])];
@ -508,21 +511,22 @@ bool ZoneDatabase::PopulateZoneSpawnListClose(uint32 zoneid, LinkedList<Spawn2*>
if (mob_distance > repop_distance)
continue;
new_spawn = new Spawn2( //
atoi(row[0]), // uint32 in_spawn2_id
atoi(row[1]), // uint32 spawngroup_id
atof(row[2]), // float in_x
atof(row[3]), // float in_y
atof(row[4]), // float in_z
atof(row[5]), // float in_heading
atoi(row[6]), // uint32 respawn
atoi(row[7]), // uint32 variance
spawn_time_left, // uint32 timeleft
atoi(row[8]), // uint32 grid
atoi(row[9]), // uint16 in_cond_id
atoi(row[10]), // int16 in_min_value
perl_enabled, // bool in_enabled
(EmuAppearance)atoi(row[12]) // EmuAppearance anim
new_spawn = new Spawn2(
atoi(row[0]), // uint32 in_spawn2_id
atoi(row[1]), // uint32 spawngroup_id
atof(row[2]), // float in_x
atof(row[3]), // float in_y
atof(row[4]), // float in_z
atof(row[5]), // float in_heading
atoi(row[6]), // uint32 respawn
atoi(row[7]), // uint32 variance
spawn_time_left, // uint32 timeleft
atoi(row[8]), // uint32 grid
(bool)atoi(row[9]), // bool path_when_zone_idle
atoi(row[10]), // uint16 in_cond_id
atoi(row[11]), // int16 in_min_value
perl_enabled, // bool in_enabled
(EmuAppearance)atoi(row[13]) // EmuAppearance anim
);
spawn2_list.Insert(new_spawn);
@ -578,6 +582,7 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spa
"respawntime, "
"variance, "
"pathgrid, "
"path_when_zone_idle, "
"_condition, "
"cond_value, "
"enabled, "
@ -598,26 +603,27 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spa
uint32 spawn_time_left = 0;
Spawn2* new_spawn = 0;
bool perl_enabled = atoi(row[11]) == 1 ? true : false;
bool perl_enabled = atoi(row[12]) == 1 ? true : false;
if (spawn_times.count(atoi(row[0])) != 0)
spawn_time_left = spawn_times[atoi(row[0])];
new_spawn = new Spawn2( //
atoi(row[0]), // uint32 in_spawn2_id
atoi(row[1]), // uint32 spawngroup_id
atof(row[2]), // float in_x
atof(row[3]), // float in_y
atof(row[4]), // float in_z
atof(row[5]), // float in_heading
atoi(row[6]), // uint32 respawn
atoi(row[7]), // uint32 variance
spawn_time_left, // uint32 timeleft
atoi(row[8]), // uint32 grid
atoi(row[9]), // uint16 in_cond_id
atoi(row[10]), // int16 in_min_value
perl_enabled, // bool in_enabled
(EmuAppearance)atoi(row[12]) // EmuAppearance anim
new_spawn = new Spawn2(
atoi(row[0]), // uint32 in_spawn2_id
atoi(row[1]), // uint32 spawngroup_id
atof(row[2]), // float in_x
atof(row[3]), // float in_y
atof(row[4]), // float in_z
atof(row[5]), // float in_heading
atoi(row[6]), // uint32 respawn
atoi(row[7]), // uint32 variance
spawn_time_left, // uint32 timeleft
atoi(row[8]), // uint32 grid
(bool)atoi(row[9]), // bool path_when_zone_idle
atoi(row[10]), // uint16 in_cond_id
atoi(row[11]), // int16 in_min_value
perl_enabled, // bool in_enabled
(EmuAppearance)atoi(row[13]) // EmuAppearance anim
);
spawn2_list.Insert(new_spawn);
@ -632,9 +638,10 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spa
Spawn2* ZoneDatabase::LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2id, uint32 timeleft) {
std::string query = StringFormat("SELECT id, spawngroupID, x, y, z, heading, "
"respawntime, variance, pathgrid, _condition, "
"cond_value, enabled, animation FROM spawn2 "
"WHERE id = %i", spawn2id);
"respawntime, variance, pathgrid, "
"path_when_zone_idle, _condition, "
"cond_value, enabled, animation FROM spawn2 "
"WHERE id = %i", spawn2id);
auto results = QueryDatabase(query);
if (!results.Success()) {
return nullptr;
@ -646,11 +653,12 @@ Spawn2* ZoneDatabase::LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2
auto row = results.begin();
bool perl_enabled = atoi(row[11]) == 1 ? true : false;
bool perl_enabled = atoi(row[12]) == 1 ? true : false;
auto newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]), atof(row[5]),
atoi(row[6]), atoi(row[7]), timeleft, atoi(row[8]), atoi(row[9]), atoi(row[10]),
perl_enabled, (EmuAppearance)atoi(row[12]));
auto newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]),
atof(row[3]), atof(row[4]), atof(row[5]), atoi(row[6]), atoi(row[7]),
timeleft, atoi(row[8]), (bool) atoi(row[9]), atoi(row[10]),
atoi(row[11]), perl_enabled, (EmuAppearance)atoi(row[13]));
spawn2_list.Insert(newSpawn);

View File

@ -32,7 +32,7 @@ public:
Spawn2(uint32 spawn2_id, uint32 spawngroup_id,
float x, float y, float z, float heading,
uint32 respawn, uint32 variance,
uint32 timeleft = 0, uint32 grid = 0,
uint32 timeleft = 0, uint32 grid = 0, bool in_path_when_zone_idle=false,
uint16 cond_id = SC_AlwaysEnabled, int16 min_value = 0, bool in_enabled = true, EmuAppearance anim = eaStanding);
~Spawn2();
@ -54,6 +54,7 @@ public:
float GetY() { return y; }
float GetZ() { return z; }
float GetHeading() { return heading; }
bool PathWhenZoneIdle() { return path_when_zone_idle; }
void SetRespawnTimer(uint32 newrespawntime) { respawn_ = newrespawntime; };
void SetVariance(uint32 newvariance) { variance_ = newvariance; }
const uint32 GetVariance() const { return variance_; }
@ -86,6 +87,7 @@ private:
float heading;
uint32 variance_;
uint32 grid_;
bool path_when_zone_idle;
uint16 condition_id;
int16 condition_min_value;
bool enabled;