mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 18:52:22 +00:00
[Zones] Convert IDLE_WHEN_EMPTY to a Zone Column (#3891)
* [Rules] Convert IDLE_WHEN_EMPTY to a rule # Notes - Converts `IDLE_WHEN_EMPTY` to `Zone:ZonesIdleWhenEmpty` so that we can change this on the fly or on a zone-by-zone basis instead of having to recompile to do this. - Especially helpful for those using release binaries that do not compile their own source. * Convert to zone column. * Update ruletypes.h * Update ruletypes.h * Update entity.cpp * Update entity.cpp * Rename. * Update database_update_manifest.cpp * Update base_zone_repository.h * Update zone.cpp * seconds_before_idle * Update database_update_manifest.cpp * Getter/Setters/Private * Update base_zone_repository.h * IsIdle()/SetIsIdle() * Update entity.cpp
This commit is contained in:
@@ -5703,6 +5703,26 @@ int Perl__GetZoneMinimumLavaDamage(uint32 zone_id, int version)
|
||||
return zone_store.GetZoneMinimumLavaDamage(zone_id, version);
|
||||
}
|
||||
|
||||
uint8 Perl__GetZoneIdleWhenEmpty(uint32 zone_id)
|
||||
{
|
||||
return zone_store.GetZoneIdleWhenEmpty(zone_id);
|
||||
}
|
||||
|
||||
uint8 Perl__GetZoneIdleWhenEmpty(uint32 zone_id, int version)
|
||||
{
|
||||
return zone_store.GetZoneIdleWhenEmpty(zone_id, version);
|
||||
}
|
||||
|
||||
uint32 Perl__GetZoneSecondsBeforeIdle(uint32 zone_id)
|
||||
{
|
||||
return zone_store.GetZoneSecondsBeforeIdle(zone_id);
|
||||
}
|
||||
|
||||
uint32 Perl__GetZoneSecondsBeforeIdle(uint32 zone_id, int version)
|
||||
{
|
||||
return zone_store.GetZoneSecondsBeforeIdle(zone_id, version);
|
||||
}
|
||||
|
||||
void Perl__send_channel_message(uint8 channel_number, uint32 guild_id, uint8 language_id, uint8 language_skill, const char* message)
|
||||
{
|
||||
quest_manager.SendChannelMessage(channel_number, guild_id, language_id, language_skill, message);
|
||||
@@ -5810,6 +5830,8 @@ void perl_register_quest()
|
||||
package.add("GetZoneGraveyardID", (float(*)(uint32, int))&Perl__GetZoneGraveyardID);
|
||||
package.add("GetZoneHotzone", (uint8(*)(uint32))&Perl__GetZoneHotzone);
|
||||
package.add("GetZoneHotzone", (uint8(*)(uint32, int))&Perl__GetZoneHotzone);
|
||||
package.add("GetZoneIdleWhenEmpty", (uint8(*)(uint32))&Perl__GetZoneIdleWhenEmpty);
|
||||
package.add("GetZoneIdleWhenEmpty", (uint8(*)(uint32, int))&Perl__GetZoneIdleWhenEmpty);
|
||||
package.add("GetZoneInstanceType", (uint8(*)(uint32))&Perl__GetZoneInstanceType);
|
||||
package.add("GetZoneInstanceType", (uint8(*)(uint32, int))&Perl__GetZoneInstanceType);
|
||||
package.add("GetZoneID", &Perl__GetZoneID);
|
||||
@@ -5890,6 +5912,8 @@ void perl_register_quest()
|
||||
package.add("GetZoneSafeY", (float(*)(uint32, int))&Perl__GetZoneSafeY);
|
||||
package.add("GetZoneSafeZ", (float(*)(uint32))&Perl__GetZoneSafeZ);
|
||||
package.add("GetZoneSafeZ", (float(*)(uint32, int))&Perl__GetZoneSafeZ);
|
||||
package.add("GetZoneSecondsBeforeIdle", (uint32(*)(uint32))&Perl__GetZoneSecondsBeforeIdle);
|
||||
package.add("GetZoneSecondsBeforeIdle", (uint32(*)(uint32, int))&Perl__GetZoneSecondsBeforeIdle);
|
||||
package.add("GetZoneShutdownDelay", (uint64(*)(uint32))&Perl__GetZoneShutdownDelay);
|
||||
package.add("GetZoneShutdownDelay", (uint64(*)(uint32, int))&Perl__GetZoneShutdownDelay);
|
||||
package.add("GetZoneSky", (uint8(*)(uint32))&Perl__GetZoneSky);
|
||||
|
||||
+78
-46
@@ -411,10 +411,12 @@ void EntityList::RaidProcess()
|
||||
|
||||
void EntityList::DoorProcess()
|
||||
{
|
||||
#ifdef IDLE_WHEN_EMPTY
|
||||
if (numclients < 1)
|
||||
return;
|
||||
#endif
|
||||
if (zone && zone->IsIdleWhenEmpty()) {
|
||||
if (numclients < 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (door_list.empty()) {
|
||||
door_timer.Disable();
|
||||
return;
|
||||
@@ -480,46 +482,76 @@ void EntityList::MobProcess()
|
||||
|
||||
size_t sz = mob_list.size();
|
||||
|
||||
#ifdef IDLE_WHEN_EMPTY
|
||||
static int old_client_count=0;
|
||||
static int old_client_count = 0;
|
||||
static Timer *mob_settle_timer = new Timer();
|
||||
|
||||
if (numclients == 0 && old_client_count > 0 &&
|
||||
RuleI(Zone, SecondsBeforeIdle) > 0) {
|
||||
// Start Timer to allow any mobs that chased chars from zone
|
||||
// to return home.
|
||||
mob_settle_timer->Start(RuleI(Zone, SecondsBeforeIdle) * 1000);
|
||||
}
|
||||
if (zone->IsIdleWhenEmpty()) {
|
||||
if (
|
||||
numclients == 0 &&
|
||||
old_client_count > 0 &&
|
||||
zone->GetSecondsBeforeIdle() > 0
|
||||
) {
|
||||
if (!zone->IsIdle()) {
|
||||
LogInfo(
|
||||
"Zone will go into an idle state after [{}] second{}.",
|
||||
zone->GetSecondsBeforeIdle(),
|
||||
zone->GetSecondsBeforeIdle() != 1 ? "s" : ""
|
||||
);
|
||||
}
|
||||
|
||||
old_client_count = numclients;
|
||||
mob_settle_timer->Start(zone->GetSecondsBeforeIdle() * 1000);
|
||||
}
|
||||
|
||||
// Disable settle timer if someone zones into empty zone
|
||||
if (numclients > 0 || mob_settle_timer->Check()) {
|
||||
mob_settle_timer->Disable();
|
||||
}
|
||||
old_client_count = numclients;
|
||||
|
||||
Spawn2* s2 = mob->CastToNPC()->respawn2;
|
||||
if (numclients == 0 && mob_settle_timer->Check()) {
|
||||
if (!zone->IsIdle()) {
|
||||
LogInfo(
|
||||
"Zone has gone idle after [{}] second{}.",
|
||||
zone->GetSecondsBeforeIdle(),
|
||||
zone->GetSecondsBeforeIdle() != 1 ? "s" : ""
|
||||
);
|
||||
|
||||
// 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 ||
|
||||
(s2 && s2->PathWhenZoneIdle()) || mob_settle_timer->Enabled()) {
|
||||
zone->SetIsIdle(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Disable settle timer if someone zones into empty zone
|
||||
if (numclients > 0 || mob_settle_timer->Check()) {
|
||||
if (zone->IsIdle()) {
|
||||
LogInfo("Zone is no longer idle.");
|
||||
|
||||
zone->SetIsIdle(false);
|
||||
}
|
||||
|
||||
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 (
|
||||
numclients > 0 ||
|
||||
(s2 && s2->PathWhenZoneIdle()) ||
|
||||
mob_settle_timer->Enabled()
|
||||
) {
|
||||
mob_dead = !mob->Process();
|
||||
} else {
|
||||
// spawn_events can cause spawns and deaths while zone empty.
|
||||
// At the very least, process that.
|
||||
mob_dead = mob->CastToNPC()->GetDepop();
|
||||
}
|
||||
} else {
|
||||
mob_dead = !mob->Process();
|
||||
}
|
||||
else {
|
||||
// spawn_events can cause spawns and deaths while zone empty.
|
||||
// At the very least, process that.
|
||||
mob_dead = mob->CastToNPC()->GetDepop();
|
||||
}
|
||||
#else
|
||||
mob_dead = !mob->Process();
|
||||
#endif
|
||||
|
||||
size_t a_sz = mob_list.size();
|
||||
|
||||
if(a_sz > sz) {
|
||||
if (a_sz > sz) {
|
||||
//increased size can potentially screw with iterators so reset it to current value
|
||||
//if buckets are re-orderered we may skip a process here and there but since
|
||||
//process happens so often it shouldn't matter much
|
||||
@@ -529,30 +561,30 @@ void EntityList::MobProcess()
|
||||
++it;
|
||||
}
|
||||
|
||||
if(mob_dead) {
|
||||
if(mob->IsMerc()) {
|
||||
if (mob_dead) {
|
||||
if (mob->IsMerc()) {
|
||||
entity_list.RemoveMerc(id);
|
||||
}
|
||||
else if(mob->IsBot()) {
|
||||
} else if (mob->IsBot()) {
|
||||
entity_list.RemoveBot(id);
|
||||
}
|
||||
else if(mob->IsNPC()) {
|
||||
} else if (mob->IsNPC()) {
|
||||
entity_list.RemoveNPC(id);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
#ifdef _WINDOWS
|
||||
struct in_addr in;
|
||||
in.s_addr = mob->CastToClient()->GetIP();
|
||||
LogInfo("Dropping client: Process=false, ip=[{}] port=[{}]", inet_ntoa(in), mob->CastToClient()->GetPort());
|
||||
#endif
|
||||
Group *g = GetGroupByMob(mob);
|
||||
if(g) {
|
||||
|
||||
Group* g = GetGroupByMob(mob);
|
||||
if (g) {
|
||||
g->DelMember(mob);
|
||||
}
|
||||
Raid *r = entity_list.GetRaidByClient(mob->CastToClient());
|
||||
if(r) {
|
||||
|
||||
Raid* r = entity_list.GetRaidByClient(mob->CastToClient());
|
||||
if (r) {
|
||||
r->MemberZoned(mob->CastToClient());
|
||||
}
|
||||
|
||||
entity_list.RemoveClient(id);
|
||||
}
|
||||
|
||||
|
||||
@@ -4743,6 +4743,26 @@ int lua_get_zone_minimum_lava_damage(uint32 zone_id, int version)
|
||||
return zone_store.GetZoneMinimumLavaDamage(zone_id, version);
|
||||
}
|
||||
|
||||
uint8 lua_get_zone_idle_when_empty(uint32 zone_id)
|
||||
{
|
||||
return zone_store.GetZoneIdleWhenEmpty(zone_id);
|
||||
}
|
||||
|
||||
uint8 lua_get_zone_idle_when_empty(uint32 zone_id, int version)
|
||||
{
|
||||
return zone_store.GetZoneIdleWhenEmpty(zone_id, version);
|
||||
}
|
||||
|
||||
uint32 lua_get_zone_seconds_before_idle(uint32 zone_id)
|
||||
{
|
||||
return zone_store.GetZoneSecondsBeforeIdle(zone_id);
|
||||
}
|
||||
|
||||
uint32 lua_get_zone_seconds_before_idle(uint32 zone_id, int version)
|
||||
{
|
||||
return zone_store.GetZoneSecondsBeforeIdle(zone_id, version);
|
||||
}
|
||||
|
||||
void lua_send_channel_message(uint8 channel_number, uint32 guild_id, uint8 language_id, uint8 language_skill, const char* message)
|
||||
{
|
||||
quest_manager.SendChannelMessage(channel_number, guild_id, language_id, language_skill, message);
|
||||
@@ -6034,6 +6054,10 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("get_zone_lava_damage", (int(*)(uint32,int))&lua_get_zone_lava_damage),
|
||||
luabind::def("get_zone_minimum_lava_damage", (int(*)(uint32))&lua_get_zone_minimum_lava_damage),
|
||||
luabind::def("get_zone_minimum_lava_damage", (int(*)(uint32,int))&lua_get_zone_minimum_lava_damage),
|
||||
luabind::def("get_zone_idle_when_empty", (uint8(*)(uint32))&lua_get_zone_idle_when_empty),
|
||||
luabind::def("get_zone_idle_when_empty", (uint8(*)(uint32,int))&lua_get_zone_idle_when_empty),
|
||||
luabind::def("get_zone_seconds_before_idle", (uint32(*)(uint32))&lua_get_zone_seconds_before_idle),
|
||||
luabind::def("get_zone_seconds_before_idle", (uint32(*)(uint32,int))&lua_get_zone_seconds_before_idle),
|
||||
luabind::def("send_channel_message", (void(*)(uint8,uint32,uint8,uint8,const char*))&lua_send_channel_message),
|
||||
luabind::def("send_channel_message", (void(*)(Lua_Client,uint8,uint32,uint8,uint8,const char*))&lua_send_channel_message),
|
||||
luabind::def("send_channel_message", (void(*)(Lua_Client,const char*,uint8,uint32,uint8,uint8,const char*))&lua_send_channel_message),
|
||||
|
||||
+7
-6
@@ -933,12 +933,13 @@ void QuestManager::repopzone() {
|
||||
}
|
||||
}
|
||||
|
||||
void QuestManager::processmobswhilezoneempty(bool on) {
|
||||
if(zone) {
|
||||
zone->process_mobs_while_empty = on;
|
||||
}
|
||||
else {
|
||||
LogQuests("QuestManager::processmobswhilezoneempty called with nullptr zone. Probably syntax error in quest file");
|
||||
void QuestManager::processmobswhilezoneempty(bool idle_when_empty) {
|
||||
if (zone) {
|
||||
zone->SetIdleWhenEmpty(idle_when_empty);
|
||||
} else {
|
||||
LogQuests(
|
||||
"QuestManager::processmobswhilezoneempty called with nullptr zone. Probably syntax error in quest file"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -106,7 +106,7 @@ public:
|
||||
void depopall(int npc_type = 0);
|
||||
void depopzone(bool StartSpawnTimer = true);
|
||||
void repopzone();
|
||||
void processmobswhilezoneempty(bool on);
|
||||
void processmobswhilezoneempty(bool idle_when_empty);
|
||||
void settarget(const char *type, int target_id);
|
||||
void follow(int entity_id, int distance);
|
||||
void sfollow();
|
||||
|
||||
+42
-3
@@ -974,7 +974,6 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
|
||||
default_ruleset = 0;
|
||||
|
||||
is_zone_time_localized = false;
|
||||
process_mobs_while_empty = false;
|
||||
|
||||
loglevelvar = 0;
|
||||
merchantvar = 0;
|
||||
@@ -984,13 +983,17 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
|
||||
short_name = strcpy(new char[strlen(in_short_name)+1], in_short_name);
|
||||
strlwr(short_name);
|
||||
memset(file_name, 0, sizeof(file_name));
|
||||
long_name = 0;
|
||||
aggroedmobs =0;
|
||||
|
||||
long_name = 0;
|
||||
aggroedmobs = 0;
|
||||
m_graveyard_id = 0;
|
||||
pgraveyard_zoneid = 0;
|
||||
m_max_clients = 0;
|
||||
pvpzone = false;
|
||||
|
||||
SetIdleWhenEmpty(true);
|
||||
SetSecondsBeforeIdle(60);
|
||||
|
||||
if (database.GetServerType() == 1) {
|
||||
pvpzone = true;
|
||||
}
|
||||
@@ -1006,6 +1009,9 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
|
||||
m_graveyard_id = z->graveyard_id;
|
||||
m_max_clients = z->maxclients;
|
||||
|
||||
SetIdleWhenEmpty(z->idle_when_empty);
|
||||
SetSecondsBeforeIdle(z->seconds_before_idle);
|
||||
|
||||
if (z->file_name.empty()) {
|
||||
strcpy(file_name, short_name);
|
||||
}
|
||||
@@ -1391,6 +1397,9 @@ bool Zone::LoadZoneCFG(const char* filename, uint16 instance_version)
|
||||
m_graveyard_id = z->graveyard_id;
|
||||
m_max_clients = z->maxclients;
|
||||
|
||||
SetIdleWhenEmpty(z->idle_when_empty);
|
||||
SetSecondsBeforeIdle(z->seconds_before_idle);
|
||||
|
||||
// safe coordinates
|
||||
m_safe_points.x = z->safe_x;
|
||||
m_safe_points.y = z->safe_y;
|
||||
@@ -3230,3 +3239,33 @@ void Zone::SetEXPModifier(Client* c, float exp_modifier)
|
||||
m
|
||||
);
|
||||
}
|
||||
|
||||
bool Zone::IsIdleWhenEmpty() const
|
||||
{
|
||||
return m_idle_when_empty;
|
||||
}
|
||||
|
||||
void Zone::SetIdleWhenEmpty(bool idle_when_empty)
|
||||
{
|
||||
Zone::m_idle_when_empty = idle_when_empty;
|
||||
}
|
||||
|
||||
uint32 Zone::GetSecondsBeforeIdle() const
|
||||
{
|
||||
return m_seconds_before_idle;
|
||||
}
|
||||
|
||||
void Zone::SetSecondsBeforeIdle(uint32 seconds_before_idle)
|
||||
{
|
||||
Zone::m_seconds_before_idle = seconds_before_idle;
|
||||
}
|
||||
|
||||
bool Zone::IsIdle() const
|
||||
{
|
||||
return m_is_idle;
|
||||
}
|
||||
|
||||
void Zone::SetIsIdle(bool m_is_idle)
|
||||
{
|
||||
Zone::m_is_idle = m_is_idle;
|
||||
}
|
||||
|
||||
+9
-1
@@ -105,7 +105,12 @@ public:
|
||||
AA::Ability *GetAlternateAdvancementAbilityByRank(int rank_id);
|
||||
AA::Rank *GetAlternateAdvancementRank(int rank_id);
|
||||
bool is_zone_time_localized;
|
||||
bool process_mobs_while_empty;
|
||||
bool IsIdle() const;
|
||||
void SetIsIdle(bool m_is_idle);
|
||||
bool IsIdleWhenEmpty() const;
|
||||
void SetIdleWhenEmpty(bool idle_when_empty);
|
||||
uint32 GetSecondsBeforeIdle() const;
|
||||
void SetSecondsBeforeIdle(uint32 seconds_before_idle);
|
||||
bool AggroLimitReached() { return (aggroedmobs > 10) ? true : false; }
|
||||
bool AllowMercs() const { return (allow_mercs); }
|
||||
bool CanBind() const { return (can_bind); }
|
||||
@@ -436,6 +441,9 @@ private:
|
||||
uint32 m_max_clients;
|
||||
uint32 zoneid;
|
||||
uint32 m_last_ucss_update;
|
||||
bool m_idle_when_empty;
|
||||
uint32 m_seconds_before_idle;
|
||||
bool m_is_idle;
|
||||
|
||||
GlobalLootManager m_global_loot;
|
||||
LinkedList<ZoneClientAuth_Struct *> client_auth_list;
|
||||
|
||||
Reference in New Issue
Block a user