[Zones] Add Max Level Check to Zones. (#2714)

* [Zones] Add Max Level Check to Zones.

# Perl
- Add `$client->CanEnterZone(zone_short_name)`.
- Add `$client->CanEnterZone(zone_short_name, instance_version)`.

# Lua
- Add `client:CanEnterZone(zone_short_name)`.
- Add `client:CanEnterZone(zone_short_name, instance_version)`.

# Notes
- Allows operators to limit zones to a maximum level.
- Allows operators to see if a player can enter a zone before sending them.
- Keeps players from entering via `#peqzone` and `#zone` as well if they do not meet the requirements or are not high enough status to bypass the requirements.

* Cleanup.
This commit is contained in:
Alex King 2023-01-10 20:47:37 -05:00 committed by GitHub
parent 4c8b65ecc6
commit 0d23ffe5e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 458 additions and 420 deletions

View File

@ -684,14 +684,6 @@ namespace Zones {
constexpr uint16 APPRENTICE = 999; // Designer Apprentice constexpr uint16 APPRENTICE = 999; // Designer Apprentice
} }
//ZoneChange_Struct->success values
#define ZONE_ERROR_NOMSG 0
#define ZONE_ERROR_NOTREADY -1
#define ZONE_ERROR_VALIDPC -2
#define ZONE_ERROR_STORYZONE -3
#define ZONE_ERROR_NOEXPANSION -6
#define ZONE_ERROR_NOEXPERIENCE -7
typedef enum { typedef enum {
FilterNone = 0, FilterNone = 0,
@ -1023,4 +1015,15 @@ enum Anonymity : uint8
Roleplaying Roleplaying
}; };
enum ZoningMessage : int8
{
ZoneNoMessage = 0,
ZoneSuccess = 1,
ZoneNotReady = -1,
ZoneValidPC = -2,
ZoneStoryZone = -3,
ZoneNoExpansion = -6,
ZoneNoExperience = -7
};
#endif /*COMMON_EQ_CONSTANTS_H*/ #endif /*COMMON_EQ_CONSTANTS_H*/

View File

@ -16,6 +16,7 @@
#include "../../strings.h" #include "../../strings.h"
#include <ctime> #include <ctime>
class BaseZoneRepository { class BaseZoneRepository {
public: public:
struct Zone { struct Zone {
@ -30,6 +31,7 @@ public:
float safe_heading; float safe_heading;
float graveyard_id; float graveyard_id;
uint8_t min_level; uint8_t min_level;
uint8_t max_level;
uint8_t min_status; uint8_t min_status;
int32_t zoneidnumber; int32_t zoneidnumber;
uint8_t version; uint8_t version;
@ -80,6 +82,8 @@ public:
uint8_t insttype; uint8_t insttype;
uint64_t shutdowndelay; uint64_t shutdowndelay;
int8_t peqzone; int8_t peqzone;
int8_t expansion;
int8_t bypass_expansion_check;
uint8_t suspendbuffs; uint8_t suspendbuffs;
int32_t rain_chance1; int32_t rain_chance1;
int32_t rain_chance2; int32_t rain_chance2;
@ -112,8 +116,6 @@ public:
int32_t underworld_teleport_index; int32_t underworld_teleport_index;
int32_t lava_damage; int32_t lava_damage;
int32_t min_lava_damage; int32_t min_lava_damage;
int8_t expansion;
int8_t bypass_expansion_check;
}; };
static std::string PrimaryKey() static std::string PrimaryKey()
@ -135,6 +137,7 @@ public:
"safe_heading", "safe_heading",
"graveyard_id", "graveyard_id",
"min_level", "min_level",
"max_level",
"min_status", "min_status",
"zoneidnumber", "zoneidnumber",
"version", "version",
@ -185,6 +188,8 @@ public:
"insttype", "insttype",
"shutdowndelay", "shutdowndelay",
"peqzone", "peqzone",
"expansion",
"bypass_expansion_check",
"suspendbuffs", "suspendbuffs",
"rain_chance1", "rain_chance1",
"rain_chance2", "rain_chance2",
@ -217,8 +222,6 @@ public:
"underworld_teleport_index", "underworld_teleport_index",
"lava_damage", "lava_damage",
"min_lava_damage", "min_lava_damage",
"expansion",
"bypass_expansion_check",
}; };
} }
@ -236,6 +239,7 @@ public:
"safe_heading", "safe_heading",
"graveyard_id", "graveyard_id",
"min_level", "min_level",
"max_level",
"min_status", "min_status",
"zoneidnumber", "zoneidnumber",
"version", "version",
@ -286,6 +290,8 @@ public:
"insttype", "insttype",
"shutdowndelay", "shutdowndelay",
"peqzone", "peqzone",
"expansion",
"bypass_expansion_check",
"suspendbuffs", "suspendbuffs",
"rain_chance1", "rain_chance1",
"rain_chance2", "rain_chance2",
@ -318,8 +324,6 @@ public:
"underworld_teleport_index", "underworld_teleport_index",
"lava_damage", "lava_damage",
"min_lava_damage", "min_lava_damage",
"expansion",
"bypass_expansion_check",
}; };
} }
@ -371,6 +375,7 @@ public:
e.safe_heading = 0; e.safe_heading = 0;
e.graveyard_id = 0; e.graveyard_id = 0;
e.min_level = 0; e.min_level = 0;
e.max_level = 255;
e.min_status = 0; e.min_status = 0;
e.zoneidnumber = 0; e.zoneidnumber = 0;
e.version = 0; e.version = 0;
@ -421,6 +426,8 @@ public:
e.insttype = 0; e.insttype = 0;
e.shutdowndelay = 5000; e.shutdowndelay = 5000;
e.peqzone = 1; e.peqzone = 1;
e.expansion = 0;
e.bypass_expansion_check = 0;
e.suspendbuffs = 0; e.suspendbuffs = 0;
e.rain_chance1 = 0; e.rain_chance1 = 0;
e.rain_chance2 = 0; e.rain_chance2 = 0;
@ -453,8 +460,6 @@ public:
e.underworld_teleport_index = 0; e.underworld_teleport_index = 0;
e.lava_damage = 50; e.lava_damage = 50;
e.min_lava_damage = 10; e.min_lava_damage = 10;
e.expansion = 0;
e.bypass_expansion_check = 0;
return e; return e;
} }
@ -480,8 +485,9 @@ public:
{ {
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
"{} WHERE id = {} LIMIT 1", "{} WHERE {} = {} LIMIT 1",
BaseSelect(), BaseSelect(),
PrimaryKey(),
zone_id zone_id
) )
); );
@ -501,90 +507,91 @@ public:
e.safe_heading = strtof(row[8], nullptr); e.safe_heading = strtof(row[8], nullptr);
e.graveyard_id = strtof(row[9], nullptr); e.graveyard_id = strtof(row[9], nullptr);
e.min_level = static_cast<uint8_t>(strtoul(row[10], nullptr, 10)); e.min_level = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
e.min_status = static_cast<uint8_t>(strtoul(row[11], nullptr, 10)); e.max_level = static_cast<uint8_t>(strtoul(row[11], nullptr, 10));
e.zoneidnumber = static_cast<int32_t>(atoi(row[12])); e.min_status = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
e.version = static_cast<uint8_t>(strtoul(row[13], nullptr, 10)); e.zoneidnumber = static_cast<int32_t>(atoi(row[13]));
e.timezone = static_cast<int32_t>(atoi(row[14])); e.version = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
e.maxclients = static_cast<int32_t>(atoi(row[15])); e.timezone = static_cast<int32_t>(atoi(row[15]));
e.ruleset = static_cast<uint32_t>(strtoul(row[16], nullptr, 10)); e.maxclients = static_cast<int32_t>(atoi(row[16]));
e.note = row[17] ? row[17] : ""; e.ruleset = static_cast<uint32_t>(strtoul(row[17], nullptr, 10));
e.underworld = strtof(row[18], nullptr); e.note = row[18] ? row[18] : "";
e.minclip = strtof(row[19], nullptr); e.underworld = strtof(row[19], nullptr);
e.maxclip = strtof(row[20], nullptr); e.minclip = strtof(row[20], nullptr);
e.fog_minclip = strtof(row[21], nullptr); e.maxclip = strtof(row[21], nullptr);
e.fog_maxclip = strtof(row[22], nullptr); e.fog_minclip = strtof(row[22], nullptr);
e.fog_blue = static_cast<uint8_t>(strtoul(row[23], nullptr, 10)); e.fog_maxclip = strtof(row[23], nullptr);
e.fog_red = static_cast<uint8_t>(strtoul(row[24], nullptr, 10)); e.fog_blue = static_cast<uint8_t>(strtoul(row[24], nullptr, 10));
e.fog_green = static_cast<uint8_t>(strtoul(row[25], nullptr, 10)); e.fog_red = static_cast<uint8_t>(strtoul(row[25], nullptr, 10));
e.sky = static_cast<uint8_t>(strtoul(row[26], nullptr, 10)); e.fog_green = static_cast<uint8_t>(strtoul(row[26], nullptr, 10));
e.ztype = static_cast<uint8_t>(strtoul(row[27], nullptr, 10)); e.sky = static_cast<uint8_t>(strtoul(row[27], nullptr, 10));
e.zone_exp_multiplier = strtof(row[28], nullptr); e.ztype = static_cast<uint8_t>(strtoul(row[28], nullptr, 10));
e.walkspeed = strtof(row[29], nullptr); e.zone_exp_multiplier = strtof(row[29], nullptr);
e.time_type = static_cast<uint8_t>(strtoul(row[30], nullptr, 10)); e.walkspeed = strtof(row[30], nullptr);
e.fog_red1 = static_cast<uint8_t>(strtoul(row[31], nullptr, 10)); e.time_type = static_cast<uint8_t>(strtoul(row[31], nullptr, 10));
e.fog_green1 = static_cast<uint8_t>(strtoul(row[32], nullptr, 10)); e.fog_red1 = static_cast<uint8_t>(strtoul(row[32], nullptr, 10));
e.fog_blue1 = static_cast<uint8_t>(strtoul(row[33], nullptr, 10)); e.fog_green1 = static_cast<uint8_t>(strtoul(row[33], nullptr, 10));
e.fog_minclip1 = strtof(row[34], nullptr); e.fog_blue1 = static_cast<uint8_t>(strtoul(row[34], nullptr, 10));
e.fog_maxclip1 = strtof(row[35], nullptr); e.fog_minclip1 = strtof(row[35], nullptr);
e.fog_red2 = static_cast<uint8_t>(strtoul(row[36], nullptr, 10)); e.fog_maxclip1 = strtof(row[36], nullptr);
e.fog_green2 = static_cast<uint8_t>(strtoul(row[37], nullptr, 10)); e.fog_red2 = static_cast<uint8_t>(strtoul(row[37], nullptr, 10));
e.fog_blue2 = static_cast<uint8_t>(strtoul(row[38], nullptr, 10)); e.fog_green2 = static_cast<uint8_t>(strtoul(row[38], nullptr, 10));
e.fog_minclip2 = strtof(row[39], nullptr); e.fog_blue2 = static_cast<uint8_t>(strtoul(row[39], nullptr, 10));
e.fog_maxclip2 = strtof(row[40], nullptr); e.fog_minclip2 = strtof(row[40], nullptr);
e.fog_red3 = static_cast<uint8_t>(strtoul(row[41], nullptr, 10)); e.fog_maxclip2 = strtof(row[41], nullptr);
e.fog_green3 = static_cast<uint8_t>(strtoul(row[42], nullptr, 10)); e.fog_red3 = static_cast<uint8_t>(strtoul(row[42], nullptr, 10));
e.fog_blue3 = static_cast<uint8_t>(strtoul(row[43], nullptr, 10)); e.fog_green3 = static_cast<uint8_t>(strtoul(row[43], nullptr, 10));
e.fog_minclip3 = strtof(row[44], nullptr); e.fog_blue3 = static_cast<uint8_t>(strtoul(row[44], nullptr, 10));
e.fog_maxclip3 = strtof(row[45], nullptr); e.fog_minclip3 = strtof(row[45], nullptr);
e.fog_red4 = static_cast<uint8_t>(strtoul(row[46], nullptr, 10)); e.fog_maxclip3 = strtof(row[46], nullptr);
e.fog_green4 = static_cast<uint8_t>(strtoul(row[47], nullptr, 10)); e.fog_red4 = static_cast<uint8_t>(strtoul(row[47], nullptr, 10));
e.fog_blue4 = static_cast<uint8_t>(strtoul(row[48], nullptr, 10)); e.fog_green4 = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
e.fog_minclip4 = strtof(row[49], nullptr); e.fog_blue4 = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
e.fog_maxclip4 = strtof(row[50], nullptr); e.fog_minclip4 = strtof(row[50], nullptr);
e.fog_density = strtof(row[51], nullptr); e.fog_maxclip4 = strtof(row[51], nullptr);
e.flag_needed = row[52] ? row[52] : ""; e.fog_density = strtof(row[52], nullptr);
e.canbind = static_cast<int8_t>(atoi(row[53])); e.flag_needed = row[53] ? row[53] : "";
e.cancombat = static_cast<int8_t>(atoi(row[54])); e.canbind = static_cast<int8_t>(atoi(row[54]));
e.canlevitate = static_cast<int8_t>(atoi(row[55])); e.cancombat = static_cast<int8_t>(atoi(row[55]));
e.castoutdoor = static_cast<int8_t>(atoi(row[56])); e.canlevitate = static_cast<int8_t>(atoi(row[56]));
e.hotzone = static_cast<uint8_t>(strtoul(row[57], nullptr, 10)); e.castoutdoor = static_cast<int8_t>(atoi(row[57]));
e.insttype = static_cast<uint8_t>(strtoul(row[58], nullptr, 10)); e.hotzone = static_cast<uint8_t>(strtoul(row[58], nullptr, 10));
e.shutdowndelay = strtoull(row[59], nullptr, 10); e.insttype = static_cast<uint8_t>(strtoul(row[59], nullptr, 10));
e.peqzone = static_cast<int8_t>(atoi(row[60])); e.shutdowndelay = strtoull(row[60], nullptr, 10);
e.suspendbuffs = static_cast<uint8_t>(strtoul(row[61], nullptr, 10)); e.peqzone = static_cast<int8_t>(atoi(row[61]));
e.rain_chance1 = static_cast<int32_t>(atoi(row[62])); e.expansion = static_cast<int8_t>(atoi(row[62]));
e.rain_chance2 = static_cast<int32_t>(atoi(row[63])); e.bypass_expansion_check = static_cast<int8_t>(atoi(row[63]));
e.rain_chance3 = static_cast<int32_t>(atoi(row[64])); e.suspendbuffs = static_cast<uint8_t>(strtoul(row[64], nullptr, 10));
e.rain_chance4 = static_cast<int32_t>(atoi(row[65])); e.rain_chance1 = static_cast<int32_t>(atoi(row[65]));
e.rain_duration1 = static_cast<int32_t>(atoi(row[66])); e.rain_chance2 = static_cast<int32_t>(atoi(row[66]));
e.rain_duration2 = static_cast<int32_t>(atoi(row[67])); e.rain_chance3 = static_cast<int32_t>(atoi(row[67]));
e.rain_duration3 = static_cast<int32_t>(atoi(row[68])); e.rain_chance4 = static_cast<int32_t>(atoi(row[68]));
e.rain_duration4 = static_cast<int32_t>(atoi(row[69])); e.rain_duration1 = static_cast<int32_t>(atoi(row[69]));
e.snow_chance1 = static_cast<int32_t>(atoi(row[70])); e.rain_duration2 = static_cast<int32_t>(atoi(row[70]));
e.snow_chance2 = static_cast<int32_t>(atoi(row[71])); e.rain_duration3 = static_cast<int32_t>(atoi(row[71]));
e.snow_chance3 = static_cast<int32_t>(atoi(row[72])); e.rain_duration4 = static_cast<int32_t>(atoi(row[72]));
e.snow_chance4 = static_cast<int32_t>(atoi(row[73])); e.snow_chance1 = static_cast<int32_t>(atoi(row[73]));
e.snow_duration1 = static_cast<int32_t>(atoi(row[74])); e.snow_chance2 = static_cast<int32_t>(atoi(row[74]));
e.snow_duration2 = static_cast<int32_t>(atoi(row[75])); e.snow_chance3 = static_cast<int32_t>(atoi(row[75]));
e.snow_duration3 = static_cast<int32_t>(atoi(row[76])); e.snow_chance4 = static_cast<int32_t>(atoi(row[76]));
e.snow_duration4 = static_cast<int32_t>(atoi(row[77])); e.snow_duration1 = static_cast<int32_t>(atoi(row[77]));
e.gravity = strtof(row[78], nullptr); e.snow_duration2 = static_cast<int32_t>(atoi(row[78]));
e.type = static_cast<int32_t>(atoi(row[79])); e.snow_duration3 = static_cast<int32_t>(atoi(row[79]));
e.skylock = static_cast<int8_t>(atoi(row[80])); e.snow_duration4 = static_cast<int32_t>(atoi(row[80]));
e.fast_regen_hp = static_cast<int32_t>(atoi(row[81])); e.gravity = strtof(row[81], nullptr);
e.fast_regen_mana = static_cast<int32_t>(atoi(row[82])); e.type = static_cast<int32_t>(atoi(row[82]));
e.fast_regen_endurance = static_cast<int32_t>(atoi(row[83])); e.skylock = static_cast<int8_t>(atoi(row[83]));
e.npc_max_aggro_dist = static_cast<int32_t>(atoi(row[84])); e.fast_regen_hp = static_cast<int32_t>(atoi(row[84]));
e.max_movement_update_range = static_cast<uint32_t>(strtoul(row[85], nullptr, 10)); e.fast_regen_mana = static_cast<int32_t>(atoi(row[85]));
e.min_expansion = static_cast<int8_t>(atoi(row[86])); e.fast_regen_endurance = static_cast<int32_t>(atoi(row[86]));
e.max_expansion = static_cast<int8_t>(atoi(row[87])); e.npc_max_aggro_dist = static_cast<int32_t>(atoi(row[87]));
e.content_flags = row[88] ? row[88] : ""; e.max_movement_update_range = static_cast<uint32_t>(strtoul(row[88], nullptr, 10));
e.content_flags_disabled = row[89] ? row[89] : ""; e.min_expansion = static_cast<int8_t>(atoi(row[89]));
e.underworld_teleport_index = static_cast<int32_t>(atoi(row[90])); e.max_expansion = static_cast<int8_t>(atoi(row[90]));
e.lava_damage = static_cast<int32_t>(atoi(row[91])); e.content_flags = row[91] ? row[91] : "";
e.min_lava_damage = static_cast<int32_t>(atoi(row[92])); e.content_flags_disabled = row[92] ? row[92] : "";
e.expansion = static_cast<int8_t>(atoi(row[93])); e.underworld_teleport_index = static_cast<int32_t>(atoi(row[93]));
e.bypass_expansion_check = static_cast<int8_t>(atoi(row[94])); e.lava_damage = static_cast<int32_t>(atoi(row[94]));
e.min_lava_damage = static_cast<int32_t>(atoi(row[95]));
return e; return e;
} }
@ -628,90 +635,91 @@ public:
v.push_back(columns[8] + " = " + std::to_string(e.safe_heading)); v.push_back(columns[8] + " = " + std::to_string(e.safe_heading));
v.push_back(columns[9] + " = " + std::to_string(e.graveyard_id)); v.push_back(columns[9] + " = " + std::to_string(e.graveyard_id));
v.push_back(columns[10] + " = " + std::to_string(e.min_level)); v.push_back(columns[10] + " = " + std::to_string(e.min_level));
v.push_back(columns[11] + " = " + std::to_string(e.min_status)); v.push_back(columns[11] + " = " + std::to_string(e.max_level));
v.push_back(columns[12] + " = " + std::to_string(e.zoneidnumber)); v.push_back(columns[12] + " = " + std::to_string(e.min_status));
v.push_back(columns[13] + " = " + std::to_string(e.version)); v.push_back(columns[13] + " = " + std::to_string(e.zoneidnumber));
v.push_back(columns[14] + " = " + std::to_string(e.timezone)); v.push_back(columns[14] + " = " + std::to_string(e.version));
v.push_back(columns[15] + " = " + std::to_string(e.maxclients)); v.push_back(columns[15] + " = " + std::to_string(e.timezone));
v.push_back(columns[16] + " = " + std::to_string(e.ruleset)); v.push_back(columns[16] + " = " + std::to_string(e.maxclients));
v.push_back(columns[17] + " = '" + Strings::Escape(e.note) + "'"); v.push_back(columns[17] + " = " + std::to_string(e.ruleset));
v.push_back(columns[18] + " = " + std::to_string(e.underworld)); v.push_back(columns[18] + " = '" + Strings::Escape(e.note) + "'");
v.push_back(columns[19] + " = " + std::to_string(e.minclip)); v.push_back(columns[19] + " = " + std::to_string(e.underworld));
v.push_back(columns[20] + " = " + std::to_string(e.maxclip)); v.push_back(columns[20] + " = " + std::to_string(e.minclip));
v.push_back(columns[21] + " = " + std::to_string(e.fog_minclip)); v.push_back(columns[21] + " = " + std::to_string(e.maxclip));
v.push_back(columns[22] + " = " + std::to_string(e.fog_maxclip)); v.push_back(columns[22] + " = " + std::to_string(e.fog_minclip));
v.push_back(columns[23] + " = " + std::to_string(e.fog_blue)); v.push_back(columns[23] + " = " + std::to_string(e.fog_maxclip));
v.push_back(columns[24] + " = " + std::to_string(e.fog_red)); v.push_back(columns[24] + " = " + std::to_string(e.fog_blue));
v.push_back(columns[25] + " = " + std::to_string(e.fog_green)); v.push_back(columns[25] + " = " + std::to_string(e.fog_red));
v.push_back(columns[26] + " = " + std::to_string(e.sky)); v.push_back(columns[26] + " = " + std::to_string(e.fog_green));
v.push_back(columns[27] + " = " + std::to_string(e.ztype)); v.push_back(columns[27] + " = " + std::to_string(e.sky));
v.push_back(columns[28] + " = " + std::to_string(e.zone_exp_multiplier)); v.push_back(columns[28] + " = " + std::to_string(e.ztype));
v.push_back(columns[29] + " = " + std::to_string(e.walkspeed)); v.push_back(columns[29] + " = " + std::to_string(e.zone_exp_multiplier));
v.push_back(columns[30] + " = " + std::to_string(e.time_type)); v.push_back(columns[30] + " = " + std::to_string(e.walkspeed));
v.push_back(columns[31] + " = " + std::to_string(e.fog_red1)); v.push_back(columns[31] + " = " + std::to_string(e.time_type));
v.push_back(columns[32] + " = " + std::to_string(e.fog_green1)); v.push_back(columns[32] + " = " + std::to_string(e.fog_red1));
v.push_back(columns[33] + " = " + std::to_string(e.fog_blue1)); v.push_back(columns[33] + " = " + std::to_string(e.fog_green1));
v.push_back(columns[34] + " = " + std::to_string(e.fog_minclip1)); v.push_back(columns[34] + " = " + std::to_string(e.fog_blue1));
v.push_back(columns[35] + " = " + std::to_string(e.fog_maxclip1)); v.push_back(columns[35] + " = " + std::to_string(e.fog_minclip1));
v.push_back(columns[36] + " = " + std::to_string(e.fog_red2)); v.push_back(columns[36] + " = " + std::to_string(e.fog_maxclip1));
v.push_back(columns[37] + " = " + std::to_string(e.fog_green2)); v.push_back(columns[37] + " = " + std::to_string(e.fog_red2));
v.push_back(columns[38] + " = " + std::to_string(e.fog_blue2)); v.push_back(columns[38] + " = " + std::to_string(e.fog_green2));
v.push_back(columns[39] + " = " + std::to_string(e.fog_minclip2)); v.push_back(columns[39] + " = " + std::to_string(e.fog_blue2));
v.push_back(columns[40] + " = " + std::to_string(e.fog_maxclip2)); v.push_back(columns[40] + " = " + std::to_string(e.fog_minclip2));
v.push_back(columns[41] + " = " + std::to_string(e.fog_red3)); v.push_back(columns[41] + " = " + std::to_string(e.fog_maxclip2));
v.push_back(columns[42] + " = " + std::to_string(e.fog_green3)); v.push_back(columns[42] + " = " + std::to_string(e.fog_red3));
v.push_back(columns[43] + " = " + std::to_string(e.fog_blue3)); v.push_back(columns[43] + " = " + std::to_string(e.fog_green3));
v.push_back(columns[44] + " = " + std::to_string(e.fog_minclip3)); v.push_back(columns[44] + " = " + std::to_string(e.fog_blue3));
v.push_back(columns[45] + " = " + std::to_string(e.fog_maxclip3)); v.push_back(columns[45] + " = " + std::to_string(e.fog_minclip3));
v.push_back(columns[46] + " = " + std::to_string(e.fog_red4)); v.push_back(columns[46] + " = " + std::to_string(e.fog_maxclip3));
v.push_back(columns[47] + " = " + std::to_string(e.fog_green4)); v.push_back(columns[47] + " = " + std::to_string(e.fog_red4));
v.push_back(columns[48] + " = " + std::to_string(e.fog_blue4)); v.push_back(columns[48] + " = " + std::to_string(e.fog_green4));
v.push_back(columns[49] + " = " + std::to_string(e.fog_minclip4)); v.push_back(columns[49] + " = " + std::to_string(e.fog_blue4));
v.push_back(columns[50] + " = " + std::to_string(e.fog_maxclip4)); v.push_back(columns[50] + " = " + std::to_string(e.fog_minclip4));
v.push_back(columns[51] + " = " + std::to_string(e.fog_density)); v.push_back(columns[51] + " = " + std::to_string(e.fog_maxclip4));
v.push_back(columns[52] + " = '" + Strings::Escape(e.flag_needed) + "'"); v.push_back(columns[52] + " = " + std::to_string(e.fog_density));
v.push_back(columns[53] + " = " + std::to_string(e.canbind)); v.push_back(columns[53] + " = '" + Strings::Escape(e.flag_needed) + "'");
v.push_back(columns[54] + " = " + std::to_string(e.cancombat)); v.push_back(columns[54] + " = " + std::to_string(e.canbind));
v.push_back(columns[55] + " = " + std::to_string(e.canlevitate)); v.push_back(columns[55] + " = " + std::to_string(e.cancombat));
v.push_back(columns[56] + " = " + std::to_string(e.castoutdoor)); v.push_back(columns[56] + " = " + std::to_string(e.canlevitate));
v.push_back(columns[57] + " = " + std::to_string(e.hotzone)); v.push_back(columns[57] + " = " + std::to_string(e.castoutdoor));
v.push_back(columns[58] + " = " + std::to_string(e.insttype)); v.push_back(columns[58] + " = " + std::to_string(e.hotzone));
v.push_back(columns[59] + " = " + std::to_string(e.shutdowndelay)); v.push_back(columns[59] + " = " + std::to_string(e.insttype));
v.push_back(columns[60] + " = " + std::to_string(e.peqzone)); v.push_back(columns[60] + " = " + std::to_string(e.shutdowndelay));
v.push_back(columns[61] + " = " + std::to_string(e.suspendbuffs)); v.push_back(columns[61] + " = " + std::to_string(e.peqzone));
v.push_back(columns[62] + " = " + std::to_string(e.rain_chance1)); v.push_back(columns[62] + " = " + std::to_string(e.expansion));
v.push_back(columns[63] + " = " + std::to_string(e.rain_chance2)); v.push_back(columns[63] + " = " + std::to_string(e.bypass_expansion_check));
v.push_back(columns[64] + " = " + std::to_string(e.rain_chance3)); v.push_back(columns[64] + " = " + std::to_string(e.suspendbuffs));
v.push_back(columns[65] + " = " + std::to_string(e.rain_chance4)); v.push_back(columns[65] + " = " + std::to_string(e.rain_chance1));
v.push_back(columns[66] + " = " + std::to_string(e.rain_duration1)); v.push_back(columns[66] + " = " + std::to_string(e.rain_chance2));
v.push_back(columns[67] + " = " + std::to_string(e.rain_duration2)); v.push_back(columns[67] + " = " + std::to_string(e.rain_chance3));
v.push_back(columns[68] + " = " + std::to_string(e.rain_duration3)); v.push_back(columns[68] + " = " + std::to_string(e.rain_chance4));
v.push_back(columns[69] + " = " + std::to_string(e.rain_duration4)); v.push_back(columns[69] + " = " + std::to_string(e.rain_duration1));
v.push_back(columns[70] + " = " + std::to_string(e.snow_chance1)); v.push_back(columns[70] + " = " + std::to_string(e.rain_duration2));
v.push_back(columns[71] + " = " + std::to_string(e.snow_chance2)); v.push_back(columns[71] + " = " + std::to_string(e.rain_duration3));
v.push_back(columns[72] + " = " + std::to_string(e.snow_chance3)); v.push_back(columns[72] + " = " + std::to_string(e.rain_duration4));
v.push_back(columns[73] + " = " + std::to_string(e.snow_chance4)); v.push_back(columns[73] + " = " + std::to_string(e.snow_chance1));
v.push_back(columns[74] + " = " + std::to_string(e.snow_duration1)); v.push_back(columns[74] + " = " + std::to_string(e.snow_chance2));
v.push_back(columns[75] + " = " + std::to_string(e.snow_duration2)); v.push_back(columns[75] + " = " + std::to_string(e.snow_chance3));
v.push_back(columns[76] + " = " + std::to_string(e.snow_duration3)); v.push_back(columns[76] + " = " + std::to_string(e.snow_chance4));
v.push_back(columns[77] + " = " + std::to_string(e.snow_duration4)); v.push_back(columns[77] + " = " + std::to_string(e.snow_duration1));
v.push_back(columns[78] + " = " + std::to_string(e.gravity)); v.push_back(columns[78] + " = " + std::to_string(e.snow_duration2));
v.push_back(columns[79] + " = " + std::to_string(e.type)); v.push_back(columns[79] + " = " + std::to_string(e.snow_duration3));
v.push_back(columns[80] + " = " + std::to_string(e.skylock)); v.push_back(columns[80] + " = " + std::to_string(e.snow_duration4));
v.push_back(columns[81] + " = " + std::to_string(e.fast_regen_hp)); v.push_back(columns[81] + " = " + std::to_string(e.gravity));
v.push_back(columns[82] + " = " + std::to_string(e.fast_regen_mana)); v.push_back(columns[82] + " = " + std::to_string(e.type));
v.push_back(columns[83] + " = " + std::to_string(e.fast_regen_endurance)); v.push_back(columns[83] + " = " + std::to_string(e.skylock));
v.push_back(columns[84] + " = " + std::to_string(e.npc_max_aggro_dist)); v.push_back(columns[84] + " = " + std::to_string(e.fast_regen_hp));
v.push_back(columns[85] + " = " + std::to_string(e.max_movement_update_range)); v.push_back(columns[85] + " = " + std::to_string(e.fast_regen_mana));
v.push_back(columns[86] + " = " + std::to_string(e.min_expansion)); v.push_back(columns[86] + " = " + std::to_string(e.fast_regen_endurance));
v.push_back(columns[87] + " = " + std::to_string(e.max_expansion)); v.push_back(columns[87] + " = " + std::to_string(e.npc_max_aggro_dist));
v.push_back(columns[88] + " = '" + Strings::Escape(e.content_flags) + "'"); v.push_back(columns[88] + " = " + std::to_string(e.max_movement_update_range));
v.push_back(columns[89] + " = '" + Strings::Escape(e.content_flags_disabled) + "'"); v.push_back(columns[89] + " = " + std::to_string(e.min_expansion));
v.push_back(columns[90] + " = " + std::to_string(e.underworld_teleport_index)); v.push_back(columns[90] + " = " + std::to_string(e.max_expansion));
v.push_back(columns[91] + " = " + std::to_string(e.lava_damage)); v.push_back(columns[91] + " = '" + Strings::Escape(e.content_flags) + "'");
v.push_back(columns[92] + " = " + std::to_string(e.min_lava_damage)); v.push_back(columns[92] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
v.push_back(columns[93] + " = " + std::to_string(e.expansion)); v.push_back(columns[93] + " = " + std::to_string(e.underworld_teleport_index));
v.push_back(columns[94] + " = " + std::to_string(e.bypass_expansion_check)); v.push_back(columns[94] + " = " + std::to_string(e.lava_damage));
v.push_back(columns[95] + " = " + std::to_string(e.min_lava_damage));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -744,6 +752,7 @@ public:
v.push_back(std::to_string(e.safe_heading)); v.push_back(std::to_string(e.safe_heading));
v.push_back(std::to_string(e.graveyard_id)); v.push_back(std::to_string(e.graveyard_id));
v.push_back(std::to_string(e.min_level)); v.push_back(std::to_string(e.min_level));
v.push_back(std::to_string(e.max_level));
v.push_back(std::to_string(e.min_status)); v.push_back(std::to_string(e.min_status));
v.push_back(std::to_string(e.zoneidnumber)); v.push_back(std::to_string(e.zoneidnumber));
v.push_back(std::to_string(e.version)); v.push_back(std::to_string(e.version));
@ -794,6 +803,8 @@ public:
v.push_back(std::to_string(e.insttype)); v.push_back(std::to_string(e.insttype));
v.push_back(std::to_string(e.shutdowndelay)); v.push_back(std::to_string(e.shutdowndelay));
v.push_back(std::to_string(e.peqzone)); v.push_back(std::to_string(e.peqzone));
v.push_back(std::to_string(e.expansion));
v.push_back(std::to_string(e.bypass_expansion_check));
v.push_back(std::to_string(e.suspendbuffs)); v.push_back(std::to_string(e.suspendbuffs));
v.push_back(std::to_string(e.rain_chance1)); v.push_back(std::to_string(e.rain_chance1));
v.push_back(std::to_string(e.rain_chance2)); v.push_back(std::to_string(e.rain_chance2));
@ -826,8 +837,6 @@ public:
v.push_back(std::to_string(e.underworld_teleport_index)); v.push_back(std::to_string(e.underworld_teleport_index));
v.push_back(std::to_string(e.lava_damage)); v.push_back(std::to_string(e.lava_damage));
v.push_back(std::to_string(e.min_lava_damage)); v.push_back(std::to_string(e.min_lava_damage));
v.push_back(std::to_string(e.expansion));
v.push_back(std::to_string(e.bypass_expansion_check));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -868,6 +877,7 @@ public:
v.push_back(std::to_string(e.safe_heading)); v.push_back(std::to_string(e.safe_heading));
v.push_back(std::to_string(e.graveyard_id)); v.push_back(std::to_string(e.graveyard_id));
v.push_back(std::to_string(e.min_level)); v.push_back(std::to_string(e.min_level));
v.push_back(std::to_string(e.max_level));
v.push_back(std::to_string(e.min_status)); v.push_back(std::to_string(e.min_status));
v.push_back(std::to_string(e.zoneidnumber)); v.push_back(std::to_string(e.zoneidnumber));
v.push_back(std::to_string(e.version)); v.push_back(std::to_string(e.version));
@ -918,6 +928,8 @@ public:
v.push_back(std::to_string(e.insttype)); v.push_back(std::to_string(e.insttype));
v.push_back(std::to_string(e.shutdowndelay)); v.push_back(std::to_string(e.shutdowndelay));
v.push_back(std::to_string(e.peqzone)); v.push_back(std::to_string(e.peqzone));
v.push_back(std::to_string(e.expansion));
v.push_back(std::to_string(e.bypass_expansion_check));
v.push_back(std::to_string(e.suspendbuffs)); v.push_back(std::to_string(e.suspendbuffs));
v.push_back(std::to_string(e.rain_chance1)); v.push_back(std::to_string(e.rain_chance1));
v.push_back(std::to_string(e.rain_chance2)); v.push_back(std::to_string(e.rain_chance2));
@ -950,8 +962,6 @@ public:
v.push_back(std::to_string(e.underworld_teleport_index)); v.push_back(std::to_string(e.underworld_teleport_index));
v.push_back(std::to_string(e.lava_damage)); v.push_back(std::to_string(e.lava_damage));
v.push_back(std::to_string(e.min_lava_damage)); v.push_back(std::to_string(e.min_lava_damage));
v.push_back(std::to_string(e.expansion));
v.push_back(std::to_string(e.bypass_expansion_check));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
} }
@ -996,90 +1006,91 @@ public:
e.safe_heading = strtof(row[8], nullptr); e.safe_heading = strtof(row[8], nullptr);
e.graveyard_id = strtof(row[9], nullptr); e.graveyard_id = strtof(row[9], nullptr);
e.min_level = static_cast<uint8_t>(strtoul(row[10], nullptr, 10)); e.min_level = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
e.min_status = static_cast<uint8_t>(strtoul(row[11], nullptr, 10)); e.max_level = static_cast<uint8_t>(strtoul(row[11], nullptr, 10));
e.zoneidnumber = static_cast<int32_t>(atoi(row[12])); e.min_status = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
e.version = static_cast<uint8_t>(strtoul(row[13], nullptr, 10)); e.zoneidnumber = static_cast<int32_t>(atoi(row[13]));
e.timezone = static_cast<int32_t>(atoi(row[14])); e.version = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
e.maxclients = static_cast<int32_t>(atoi(row[15])); e.timezone = static_cast<int32_t>(atoi(row[15]));
e.ruleset = static_cast<uint32_t>(strtoul(row[16], nullptr, 10)); e.maxclients = static_cast<int32_t>(atoi(row[16]));
e.note = row[17] ? row[17] : ""; e.ruleset = static_cast<uint32_t>(strtoul(row[17], nullptr, 10));
e.underworld = strtof(row[18], nullptr); e.note = row[18] ? row[18] : "";
e.minclip = strtof(row[19], nullptr); e.underworld = strtof(row[19], nullptr);
e.maxclip = strtof(row[20], nullptr); e.minclip = strtof(row[20], nullptr);
e.fog_minclip = strtof(row[21], nullptr); e.maxclip = strtof(row[21], nullptr);
e.fog_maxclip = strtof(row[22], nullptr); e.fog_minclip = strtof(row[22], nullptr);
e.fog_blue = static_cast<uint8_t>(strtoul(row[23], nullptr, 10)); e.fog_maxclip = strtof(row[23], nullptr);
e.fog_red = static_cast<uint8_t>(strtoul(row[24], nullptr, 10)); e.fog_blue = static_cast<uint8_t>(strtoul(row[24], nullptr, 10));
e.fog_green = static_cast<uint8_t>(strtoul(row[25], nullptr, 10)); e.fog_red = static_cast<uint8_t>(strtoul(row[25], nullptr, 10));
e.sky = static_cast<uint8_t>(strtoul(row[26], nullptr, 10)); e.fog_green = static_cast<uint8_t>(strtoul(row[26], nullptr, 10));
e.ztype = static_cast<uint8_t>(strtoul(row[27], nullptr, 10)); e.sky = static_cast<uint8_t>(strtoul(row[27], nullptr, 10));
e.zone_exp_multiplier = strtof(row[28], nullptr); e.ztype = static_cast<uint8_t>(strtoul(row[28], nullptr, 10));
e.walkspeed = strtof(row[29], nullptr); e.zone_exp_multiplier = strtof(row[29], nullptr);
e.time_type = static_cast<uint8_t>(strtoul(row[30], nullptr, 10)); e.walkspeed = strtof(row[30], nullptr);
e.fog_red1 = static_cast<uint8_t>(strtoul(row[31], nullptr, 10)); e.time_type = static_cast<uint8_t>(strtoul(row[31], nullptr, 10));
e.fog_green1 = static_cast<uint8_t>(strtoul(row[32], nullptr, 10)); e.fog_red1 = static_cast<uint8_t>(strtoul(row[32], nullptr, 10));
e.fog_blue1 = static_cast<uint8_t>(strtoul(row[33], nullptr, 10)); e.fog_green1 = static_cast<uint8_t>(strtoul(row[33], nullptr, 10));
e.fog_minclip1 = strtof(row[34], nullptr); e.fog_blue1 = static_cast<uint8_t>(strtoul(row[34], nullptr, 10));
e.fog_maxclip1 = strtof(row[35], nullptr); e.fog_minclip1 = strtof(row[35], nullptr);
e.fog_red2 = static_cast<uint8_t>(strtoul(row[36], nullptr, 10)); e.fog_maxclip1 = strtof(row[36], nullptr);
e.fog_green2 = static_cast<uint8_t>(strtoul(row[37], nullptr, 10)); e.fog_red2 = static_cast<uint8_t>(strtoul(row[37], nullptr, 10));
e.fog_blue2 = static_cast<uint8_t>(strtoul(row[38], nullptr, 10)); e.fog_green2 = static_cast<uint8_t>(strtoul(row[38], nullptr, 10));
e.fog_minclip2 = strtof(row[39], nullptr); e.fog_blue2 = static_cast<uint8_t>(strtoul(row[39], nullptr, 10));
e.fog_maxclip2 = strtof(row[40], nullptr); e.fog_minclip2 = strtof(row[40], nullptr);
e.fog_red3 = static_cast<uint8_t>(strtoul(row[41], nullptr, 10)); e.fog_maxclip2 = strtof(row[41], nullptr);
e.fog_green3 = static_cast<uint8_t>(strtoul(row[42], nullptr, 10)); e.fog_red3 = static_cast<uint8_t>(strtoul(row[42], nullptr, 10));
e.fog_blue3 = static_cast<uint8_t>(strtoul(row[43], nullptr, 10)); e.fog_green3 = static_cast<uint8_t>(strtoul(row[43], nullptr, 10));
e.fog_minclip3 = strtof(row[44], nullptr); e.fog_blue3 = static_cast<uint8_t>(strtoul(row[44], nullptr, 10));
e.fog_maxclip3 = strtof(row[45], nullptr); e.fog_minclip3 = strtof(row[45], nullptr);
e.fog_red4 = static_cast<uint8_t>(strtoul(row[46], nullptr, 10)); e.fog_maxclip3 = strtof(row[46], nullptr);
e.fog_green4 = static_cast<uint8_t>(strtoul(row[47], nullptr, 10)); e.fog_red4 = static_cast<uint8_t>(strtoul(row[47], nullptr, 10));
e.fog_blue4 = static_cast<uint8_t>(strtoul(row[48], nullptr, 10)); e.fog_green4 = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
e.fog_minclip4 = strtof(row[49], nullptr); e.fog_blue4 = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
e.fog_maxclip4 = strtof(row[50], nullptr); e.fog_minclip4 = strtof(row[50], nullptr);
e.fog_density = strtof(row[51], nullptr); e.fog_maxclip4 = strtof(row[51], nullptr);
e.flag_needed = row[52] ? row[52] : ""; e.fog_density = strtof(row[52], nullptr);
e.canbind = static_cast<int8_t>(atoi(row[53])); e.flag_needed = row[53] ? row[53] : "";
e.cancombat = static_cast<int8_t>(atoi(row[54])); e.canbind = static_cast<int8_t>(atoi(row[54]));
e.canlevitate = static_cast<int8_t>(atoi(row[55])); e.cancombat = static_cast<int8_t>(atoi(row[55]));
e.castoutdoor = static_cast<int8_t>(atoi(row[56])); e.canlevitate = static_cast<int8_t>(atoi(row[56]));
e.hotzone = static_cast<uint8_t>(strtoul(row[57], nullptr, 10)); e.castoutdoor = static_cast<int8_t>(atoi(row[57]));
e.insttype = static_cast<uint8_t>(strtoul(row[58], nullptr, 10)); e.hotzone = static_cast<uint8_t>(strtoul(row[58], nullptr, 10));
e.shutdowndelay = strtoull(row[59], nullptr, 10); e.insttype = static_cast<uint8_t>(strtoul(row[59], nullptr, 10));
e.peqzone = static_cast<int8_t>(atoi(row[60])); e.shutdowndelay = strtoull(row[60], nullptr, 10);
e.suspendbuffs = static_cast<uint8_t>(strtoul(row[61], nullptr, 10)); e.peqzone = static_cast<int8_t>(atoi(row[61]));
e.rain_chance1 = static_cast<int32_t>(atoi(row[62])); e.expansion = static_cast<int8_t>(atoi(row[62]));
e.rain_chance2 = static_cast<int32_t>(atoi(row[63])); e.bypass_expansion_check = static_cast<int8_t>(atoi(row[63]));
e.rain_chance3 = static_cast<int32_t>(atoi(row[64])); e.suspendbuffs = static_cast<uint8_t>(strtoul(row[64], nullptr, 10));
e.rain_chance4 = static_cast<int32_t>(atoi(row[65])); e.rain_chance1 = static_cast<int32_t>(atoi(row[65]));
e.rain_duration1 = static_cast<int32_t>(atoi(row[66])); e.rain_chance2 = static_cast<int32_t>(atoi(row[66]));
e.rain_duration2 = static_cast<int32_t>(atoi(row[67])); e.rain_chance3 = static_cast<int32_t>(atoi(row[67]));
e.rain_duration3 = static_cast<int32_t>(atoi(row[68])); e.rain_chance4 = static_cast<int32_t>(atoi(row[68]));
e.rain_duration4 = static_cast<int32_t>(atoi(row[69])); e.rain_duration1 = static_cast<int32_t>(atoi(row[69]));
e.snow_chance1 = static_cast<int32_t>(atoi(row[70])); e.rain_duration2 = static_cast<int32_t>(atoi(row[70]));
e.snow_chance2 = static_cast<int32_t>(atoi(row[71])); e.rain_duration3 = static_cast<int32_t>(atoi(row[71]));
e.snow_chance3 = static_cast<int32_t>(atoi(row[72])); e.rain_duration4 = static_cast<int32_t>(atoi(row[72]));
e.snow_chance4 = static_cast<int32_t>(atoi(row[73])); e.snow_chance1 = static_cast<int32_t>(atoi(row[73]));
e.snow_duration1 = static_cast<int32_t>(atoi(row[74])); e.snow_chance2 = static_cast<int32_t>(atoi(row[74]));
e.snow_duration2 = static_cast<int32_t>(atoi(row[75])); e.snow_chance3 = static_cast<int32_t>(atoi(row[75]));
e.snow_duration3 = static_cast<int32_t>(atoi(row[76])); e.snow_chance4 = static_cast<int32_t>(atoi(row[76]));
e.snow_duration4 = static_cast<int32_t>(atoi(row[77])); e.snow_duration1 = static_cast<int32_t>(atoi(row[77]));
e.gravity = strtof(row[78], nullptr); e.snow_duration2 = static_cast<int32_t>(atoi(row[78]));
e.type = static_cast<int32_t>(atoi(row[79])); e.snow_duration3 = static_cast<int32_t>(atoi(row[79]));
e.skylock = static_cast<int8_t>(atoi(row[80])); e.snow_duration4 = static_cast<int32_t>(atoi(row[80]));
e.fast_regen_hp = static_cast<int32_t>(atoi(row[81])); e.gravity = strtof(row[81], nullptr);
e.fast_regen_mana = static_cast<int32_t>(atoi(row[82])); e.type = static_cast<int32_t>(atoi(row[82]));
e.fast_regen_endurance = static_cast<int32_t>(atoi(row[83])); e.skylock = static_cast<int8_t>(atoi(row[83]));
e.npc_max_aggro_dist = static_cast<int32_t>(atoi(row[84])); e.fast_regen_hp = static_cast<int32_t>(atoi(row[84]));
e.max_movement_update_range = static_cast<uint32_t>(strtoul(row[85], nullptr, 10)); e.fast_regen_mana = static_cast<int32_t>(atoi(row[85]));
e.min_expansion = static_cast<int8_t>(atoi(row[86])); e.fast_regen_endurance = static_cast<int32_t>(atoi(row[86]));
e.max_expansion = static_cast<int8_t>(atoi(row[87])); e.npc_max_aggro_dist = static_cast<int32_t>(atoi(row[87]));
e.content_flags = row[88] ? row[88] : ""; e.max_movement_update_range = static_cast<uint32_t>(strtoul(row[88], nullptr, 10));
e.content_flags_disabled = row[89] ? row[89] : ""; e.min_expansion = static_cast<int8_t>(atoi(row[89]));
e.underworld_teleport_index = static_cast<int32_t>(atoi(row[90])); e.max_expansion = static_cast<int8_t>(atoi(row[90]));
e.lava_damage = static_cast<int32_t>(atoi(row[91])); e.content_flags = row[91] ? row[91] : "";
e.min_lava_damage = static_cast<int32_t>(atoi(row[92])); e.content_flags_disabled = row[92] ? row[92] : "";
e.expansion = static_cast<int8_t>(atoi(row[93])); e.underworld_teleport_index = static_cast<int32_t>(atoi(row[93]));
e.bypass_expansion_check = static_cast<int8_t>(atoi(row[94])); e.lava_damage = static_cast<int32_t>(atoi(row[94]));
e.min_lava_damage = static_cast<int32_t>(atoi(row[95]));
all_entries.push_back(e); all_entries.push_back(e);
} }
@ -1115,90 +1126,91 @@ public:
e.safe_heading = strtof(row[8], nullptr); e.safe_heading = strtof(row[8], nullptr);
e.graveyard_id = strtof(row[9], nullptr); e.graveyard_id = strtof(row[9], nullptr);
e.min_level = static_cast<uint8_t>(strtoul(row[10], nullptr, 10)); e.min_level = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
e.min_status = static_cast<uint8_t>(strtoul(row[11], nullptr, 10)); e.max_level = static_cast<uint8_t>(strtoul(row[11], nullptr, 10));
e.zoneidnumber = static_cast<int32_t>(atoi(row[12])); e.min_status = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
e.version = static_cast<uint8_t>(strtoul(row[13], nullptr, 10)); e.zoneidnumber = static_cast<int32_t>(atoi(row[13]));
e.timezone = static_cast<int32_t>(atoi(row[14])); e.version = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
e.maxclients = static_cast<int32_t>(atoi(row[15])); e.timezone = static_cast<int32_t>(atoi(row[15]));
e.ruleset = static_cast<uint32_t>(strtoul(row[16], nullptr, 10)); e.maxclients = static_cast<int32_t>(atoi(row[16]));
e.note = row[17] ? row[17] : ""; e.ruleset = static_cast<uint32_t>(strtoul(row[17], nullptr, 10));
e.underworld = strtof(row[18], nullptr); e.note = row[18] ? row[18] : "";
e.minclip = strtof(row[19], nullptr); e.underworld = strtof(row[19], nullptr);
e.maxclip = strtof(row[20], nullptr); e.minclip = strtof(row[20], nullptr);
e.fog_minclip = strtof(row[21], nullptr); e.maxclip = strtof(row[21], nullptr);
e.fog_maxclip = strtof(row[22], nullptr); e.fog_minclip = strtof(row[22], nullptr);
e.fog_blue = static_cast<uint8_t>(strtoul(row[23], nullptr, 10)); e.fog_maxclip = strtof(row[23], nullptr);
e.fog_red = static_cast<uint8_t>(strtoul(row[24], nullptr, 10)); e.fog_blue = static_cast<uint8_t>(strtoul(row[24], nullptr, 10));
e.fog_green = static_cast<uint8_t>(strtoul(row[25], nullptr, 10)); e.fog_red = static_cast<uint8_t>(strtoul(row[25], nullptr, 10));
e.sky = static_cast<uint8_t>(strtoul(row[26], nullptr, 10)); e.fog_green = static_cast<uint8_t>(strtoul(row[26], nullptr, 10));
e.ztype = static_cast<uint8_t>(strtoul(row[27], nullptr, 10)); e.sky = static_cast<uint8_t>(strtoul(row[27], nullptr, 10));
e.zone_exp_multiplier = strtof(row[28], nullptr); e.ztype = static_cast<uint8_t>(strtoul(row[28], nullptr, 10));
e.walkspeed = strtof(row[29], nullptr); e.zone_exp_multiplier = strtof(row[29], nullptr);
e.time_type = static_cast<uint8_t>(strtoul(row[30], nullptr, 10)); e.walkspeed = strtof(row[30], nullptr);
e.fog_red1 = static_cast<uint8_t>(strtoul(row[31], nullptr, 10)); e.time_type = static_cast<uint8_t>(strtoul(row[31], nullptr, 10));
e.fog_green1 = static_cast<uint8_t>(strtoul(row[32], nullptr, 10)); e.fog_red1 = static_cast<uint8_t>(strtoul(row[32], nullptr, 10));
e.fog_blue1 = static_cast<uint8_t>(strtoul(row[33], nullptr, 10)); e.fog_green1 = static_cast<uint8_t>(strtoul(row[33], nullptr, 10));
e.fog_minclip1 = strtof(row[34], nullptr); e.fog_blue1 = static_cast<uint8_t>(strtoul(row[34], nullptr, 10));
e.fog_maxclip1 = strtof(row[35], nullptr); e.fog_minclip1 = strtof(row[35], nullptr);
e.fog_red2 = static_cast<uint8_t>(strtoul(row[36], nullptr, 10)); e.fog_maxclip1 = strtof(row[36], nullptr);
e.fog_green2 = static_cast<uint8_t>(strtoul(row[37], nullptr, 10)); e.fog_red2 = static_cast<uint8_t>(strtoul(row[37], nullptr, 10));
e.fog_blue2 = static_cast<uint8_t>(strtoul(row[38], nullptr, 10)); e.fog_green2 = static_cast<uint8_t>(strtoul(row[38], nullptr, 10));
e.fog_minclip2 = strtof(row[39], nullptr); e.fog_blue2 = static_cast<uint8_t>(strtoul(row[39], nullptr, 10));
e.fog_maxclip2 = strtof(row[40], nullptr); e.fog_minclip2 = strtof(row[40], nullptr);
e.fog_red3 = static_cast<uint8_t>(strtoul(row[41], nullptr, 10)); e.fog_maxclip2 = strtof(row[41], nullptr);
e.fog_green3 = static_cast<uint8_t>(strtoul(row[42], nullptr, 10)); e.fog_red3 = static_cast<uint8_t>(strtoul(row[42], nullptr, 10));
e.fog_blue3 = static_cast<uint8_t>(strtoul(row[43], nullptr, 10)); e.fog_green3 = static_cast<uint8_t>(strtoul(row[43], nullptr, 10));
e.fog_minclip3 = strtof(row[44], nullptr); e.fog_blue3 = static_cast<uint8_t>(strtoul(row[44], nullptr, 10));
e.fog_maxclip3 = strtof(row[45], nullptr); e.fog_minclip3 = strtof(row[45], nullptr);
e.fog_red4 = static_cast<uint8_t>(strtoul(row[46], nullptr, 10)); e.fog_maxclip3 = strtof(row[46], nullptr);
e.fog_green4 = static_cast<uint8_t>(strtoul(row[47], nullptr, 10)); e.fog_red4 = static_cast<uint8_t>(strtoul(row[47], nullptr, 10));
e.fog_blue4 = static_cast<uint8_t>(strtoul(row[48], nullptr, 10)); e.fog_green4 = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
e.fog_minclip4 = strtof(row[49], nullptr); e.fog_blue4 = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
e.fog_maxclip4 = strtof(row[50], nullptr); e.fog_minclip4 = strtof(row[50], nullptr);
e.fog_density = strtof(row[51], nullptr); e.fog_maxclip4 = strtof(row[51], nullptr);
e.flag_needed = row[52] ? row[52] : ""; e.fog_density = strtof(row[52], nullptr);
e.canbind = static_cast<int8_t>(atoi(row[53])); e.flag_needed = row[53] ? row[53] : "";
e.cancombat = static_cast<int8_t>(atoi(row[54])); e.canbind = static_cast<int8_t>(atoi(row[54]));
e.canlevitate = static_cast<int8_t>(atoi(row[55])); e.cancombat = static_cast<int8_t>(atoi(row[55]));
e.castoutdoor = static_cast<int8_t>(atoi(row[56])); e.canlevitate = static_cast<int8_t>(atoi(row[56]));
e.hotzone = static_cast<uint8_t>(strtoul(row[57], nullptr, 10)); e.castoutdoor = static_cast<int8_t>(atoi(row[57]));
e.insttype = static_cast<uint8_t>(strtoul(row[58], nullptr, 10)); e.hotzone = static_cast<uint8_t>(strtoul(row[58], nullptr, 10));
e.shutdowndelay = strtoull(row[59], nullptr, 10); e.insttype = static_cast<uint8_t>(strtoul(row[59], nullptr, 10));
e.peqzone = static_cast<int8_t>(atoi(row[60])); e.shutdowndelay = strtoull(row[60], nullptr, 10);
e.suspendbuffs = static_cast<uint8_t>(strtoul(row[61], nullptr, 10)); e.peqzone = static_cast<int8_t>(atoi(row[61]));
e.rain_chance1 = static_cast<int32_t>(atoi(row[62])); e.expansion = static_cast<int8_t>(atoi(row[62]));
e.rain_chance2 = static_cast<int32_t>(atoi(row[63])); e.bypass_expansion_check = static_cast<int8_t>(atoi(row[63]));
e.rain_chance3 = static_cast<int32_t>(atoi(row[64])); e.suspendbuffs = static_cast<uint8_t>(strtoul(row[64], nullptr, 10));
e.rain_chance4 = static_cast<int32_t>(atoi(row[65])); e.rain_chance1 = static_cast<int32_t>(atoi(row[65]));
e.rain_duration1 = static_cast<int32_t>(atoi(row[66])); e.rain_chance2 = static_cast<int32_t>(atoi(row[66]));
e.rain_duration2 = static_cast<int32_t>(atoi(row[67])); e.rain_chance3 = static_cast<int32_t>(atoi(row[67]));
e.rain_duration3 = static_cast<int32_t>(atoi(row[68])); e.rain_chance4 = static_cast<int32_t>(atoi(row[68]));
e.rain_duration4 = static_cast<int32_t>(atoi(row[69])); e.rain_duration1 = static_cast<int32_t>(atoi(row[69]));
e.snow_chance1 = static_cast<int32_t>(atoi(row[70])); e.rain_duration2 = static_cast<int32_t>(atoi(row[70]));
e.snow_chance2 = static_cast<int32_t>(atoi(row[71])); e.rain_duration3 = static_cast<int32_t>(atoi(row[71]));
e.snow_chance3 = static_cast<int32_t>(atoi(row[72])); e.rain_duration4 = static_cast<int32_t>(atoi(row[72]));
e.snow_chance4 = static_cast<int32_t>(atoi(row[73])); e.snow_chance1 = static_cast<int32_t>(atoi(row[73]));
e.snow_duration1 = static_cast<int32_t>(atoi(row[74])); e.snow_chance2 = static_cast<int32_t>(atoi(row[74]));
e.snow_duration2 = static_cast<int32_t>(atoi(row[75])); e.snow_chance3 = static_cast<int32_t>(atoi(row[75]));
e.snow_duration3 = static_cast<int32_t>(atoi(row[76])); e.snow_chance4 = static_cast<int32_t>(atoi(row[76]));
e.snow_duration4 = static_cast<int32_t>(atoi(row[77])); e.snow_duration1 = static_cast<int32_t>(atoi(row[77]));
e.gravity = strtof(row[78], nullptr); e.snow_duration2 = static_cast<int32_t>(atoi(row[78]));
e.type = static_cast<int32_t>(atoi(row[79])); e.snow_duration3 = static_cast<int32_t>(atoi(row[79]));
e.skylock = static_cast<int8_t>(atoi(row[80])); e.snow_duration4 = static_cast<int32_t>(atoi(row[80]));
e.fast_regen_hp = static_cast<int32_t>(atoi(row[81])); e.gravity = strtof(row[81], nullptr);
e.fast_regen_mana = static_cast<int32_t>(atoi(row[82])); e.type = static_cast<int32_t>(atoi(row[82]));
e.fast_regen_endurance = static_cast<int32_t>(atoi(row[83])); e.skylock = static_cast<int8_t>(atoi(row[83]));
e.npc_max_aggro_dist = static_cast<int32_t>(atoi(row[84])); e.fast_regen_hp = static_cast<int32_t>(atoi(row[84]));
e.max_movement_update_range = static_cast<uint32_t>(strtoul(row[85], nullptr, 10)); e.fast_regen_mana = static_cast<int32_t>(atoi(row[85]));
e.min_expansion = static_cast<int8_t>(atoi(row[86])); e.fast_regen_endurance = static_cast<int32_t>(atoi(row[86]));
e.max_expansion = static_cast<int8_t>(atoi(row[87])); e.npc_max_aggro_dist = static_cast<int32_t>(atoi(row[87]));
e.content_flags = row[88] ? row[88] : ""; e.max_movement_update_range = static_cast<uint32_t>(strtoul(row[88], nullptr, 10));
e.content_flags_disabled = row[89] ? row[89] : ""; e.min_expansion = static_cast<int8_t>(atoi(row[89]));
e.underworld_teleport_index = static_cast<int32_t>(atoi(row[90])); e.max_expansion = static_cast<int8_t>(atoi(row[90]));
e.lava_damage = static_cast<int32_t>(atoi(row[91])); e.content_flags = row[91] ? row[91] : "";
e.min_lava_damage = static_cast<int32_t>(atoi(row[92])); e.content_flags_disabled = row[92] ? row[92] : "";
e.expansion = static_cast<int8_t>(atoi(row[93])); e.underworld_teleport_index = static_cast<int32_t>(atoi(row[93]));
e.bypass_expansion_check = static_cast<int8_t>(atoi(row[94])); e.lava_damage = static_cast<int32_t>(atoi(row[94]));
e.min_lava_damage = static_cast<int32_t>(atoi(row[95]));
all_entries.push_back(e); all_entries.push_back(e);
} }

View File

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

View File

@ -468,6 +468,7 @@
9212|2022_10_14_fix_misty_pok_stone.sql|select * from doors where id = 2040 and `name` = 'POKRVPORT500' and dest_zone = 'misty'|empty| 9212|2022_10_14_fix_misty_pok_stone.sql|select * from doors where id = 2040 and `name` = 'POKRVPORT500' and dest_zone = 'misty'|empty|
9213|2022_12_24_npc_keeps_sold_items.sql|SHOW COLUMNS FROM `npc_types` LIKE 'keeps_sold_items'|empty| 9213|2022_12_24_npc_keeps_sold_items.sql|SHOW COLUMNS FROM `npc_types` LIKE 'keeps_sold_items'|empty|
9214|2022_12_24_character_exp_toggle.sql|SHOW COLUMNS FROM `character_data` LIKE 'exp_enabled'|empty| 9214|2022_12_24_character_exp_toggle.sql|SHOW COLUMNS FROM `character_data` LIKE 'exp_enabled'|empty|
9215|2023_01_08_zone_max_level.sql|SHOW COLUMNS FROM `zone` LIKE 'max_level'|empty|
# Upgrade conditions: # Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not # This won't be needed after this system is implemented, but it is used database that are not

View File

@ -0,0 +1,2 @@
ALTER TABLE `zone`
ADD COLUMN `max_level` tinyint(3) UNSIGNED NOT NULL DEFAULT 255 AFTER `min_level`;

View File

@ -1352,6 +1352,8 @@ public:
void ClearPendingAdventureDoorClick() { safe_delete(adventure_door_timer); } void ClearPendingAdventureDoorClick() { safe_delete(adventure_door_timer); }
void ClearPendingAdventureData(); void ClearPendingAdventureData();
bool CanEnterZone(std::string zone_short_name = "", int16 instance_version = -1);
int GetAggroCount(); int GetAggroCount();
void IncrementAggroCount(bool raid_target = false); void IncrementAggroCount(bool raid_target = false);
void DecrementAggroCount(); void DecrementAggroCount();
@ -1861,7 +1863,6 @@ private:
void NPCSpawn(const Seperator* sep); void NPCSpawn(const Seperator* sep);
uint32 GetEXPForLevel(uint16 level); uint32 GetEXPForLevel(uint16 level);
bool CanBeInZone();
void SendLogoutPackets(); void SendLogoutPackets();
void SendZoneInPackets(); void SendZoneInPackets();
bool AddPacket(const EQApplicationPacket *, bool); bool AddPacket(const EQApplicationPacket *, bool);

View File

@ -904,9 +904,9 @@ void Client::CompleteConnect()
heroforge_wearchange_timer.Start(250); heroforge_wearchange_timer.Start(250);
// enforce some rules.. // enforce some rules..
if (!CanBeInZone()) { if (!CanEnterZone()) {
LogInfo("Kicking character [{}] from zone, not allowed here (missing requirements)", GetCleanName()); LogInfo("Kicking character [{}] from zone, not allowed here (missing requirements)", GetCleanName());
GoToSafeCoords(ZoneID("arena"), 0); GoToBind();
return; return;
} }
} }

View File

@ -53,13 +53,6 @@ void command_zone(Client *c, const Seperator *sep)
return; return;
} }
// status checking
auto min_status = content_db.GetMinStatus(zone_id, 0);
if (c->Admin() < min_status) {
c->Message(Chat::White, "Your status is not high enough to go to this zone.");
return;
}
#ifdef BOTS #ifdef BOTS
// This block is necessary to clean up any bot objects owned by a Client // This block is necessary to clean up any bot objects owned by a Client
if (zone_id != c->GetZoneID()) { if (zone_id != c->GetZoneID()) {

View File

@ -2926,6 +2926,16 @@ uint64 Lua_Client::CalcEXP(uint8 consider_level, bool ignore_modifiers) {
return self->CalcEXP(consider_level, ignore_modifiers); return self->CalcEXP(consider_level, ignore_modifiers);
} }
bool Lua_Client::CanEnterZone(std::string zone_short_name) {
Lua_Safe_Call_Bool();
return self->CanEnterZone(zone_short_name);
}
bool Lua_Client::CanEnterZone(std::string zone_short_name, int16 instance_version) {
Lua_Safe_Call_Bool();
return self->CanEnterZone(zone_short_name, instance_version);
}
#ifdef BOTS #ifdef BOTS
int Lua_Client::GetBotRequiredLevel() int Lua_Client::GetBotRequiredLevel()
@ -3060,6 +3070,8 @@ luabind::scope lua_register_client() {
.def("CalcEXP", (uint64(Lua_Client::*)(uint8))&Lua_Client::CalcEXP) .def("CalcEXP", (uint64(Lua_Client::*)(uint8))&Lua_Client::CalcEXP)
.def("CalcEXP", (uint64(Lua_Client::*)(uint8,bool))&Lua_Client::CalcEXP) .def("CalcEXP", (uint64(Lua_Client::*)(uint8,bool))&Lua_Client::CalcEXP)
.def("CalcPriceMod", (float(Lua_Client::*)(Lua_Mob,bool))&Lua_Client::CalcPriceMod) .def("CalcPriceMod", (float(Lua_Client::*)(Lua_Mob,bool))&Lua_Client::CalcPriceMod)
.def("CanEnterZone", (bool(Lua_Client::*)(std::string))&Lua_Client::CanEnterZone)
.def("CanEnterZone", (bool(Lua_Client::*)(std::string,int16))&Lua_Client::CanEnterZone)
.def("CanHaveSkill", (bool(Lua_Client::*)(int))&Lua_Client::CanHaveSkill) .def("CanHaveSkill", (bool(Lua_Client::*)(int))&Lua_Client::CanHaveSkill)
.def("CashReward", &Lua_Client::CashReward) .def("CashReward", &Lua_Client::CashReward)
.def("ChangeLastName", (void(Lua_Client::*)(std::string))&Lua_Client::ChangeLastName) .def("ChangeLastName", (void(Lua_Client::*)(std::string))&Lua_Client::ChangeLastName)

View File

@ -459,6 +459,8 @@ public:
void SetEXPEnabled(bool is_exp_enabled); void SetEXPEnabled(bool is_exp_enabled);
uint64 CalcEXP(uint8 consider_level); uint64 CalcEXP(uint8 consider_level);
uint64 CalcEXP(uint8 consider_level, bool ignore_modifiers); uint64 CalcEXP(uint8 consider_level, bool ignore_modifiers);
bool CanEnterZone(std::string zone_short_name);
bool CanEnterZone(std::string zone_short_name, int16 instance_version);
void ApplySpell(int spell_id); void ApplySpell(int spell_id);
void ApplySpell(int spell_id, int duration); void ApplySpell(int spell_id, int duration);

View File

@ -2799,6 +2799,16 @@ void Perl_Client_SetEXPEnabled(Client* self, bool is_exp_enabled)
self->SetEXPEnabled(is_exp_enabled); self->SetEXPEnabled(is_exp_enabled);
} }
bool Perl_Client_CanEnterZone(Client* self, std::string zone_short_name)
{
return self->CanEnterZone(zone_short_name);
}
bool Perl_Client_CanEnterZone(Client* self, std::string zone_short_name, int16 instance_version)
{
return self->CanEnterZone(zone_short_name, instance_version);
}
#ifdef BOTS #ifdef BOTS
int Perl_Client_GetBotRequiredLevel(Client* self) int Perl_Client_GetBotRequiredLevel(Client* self)
@ -2924,6 +2934,8 @@ void perl_register_client()
package.add("CalcPriceMod", (float(*)(Client*))&Perl_Client_CalcPriceMod); package.add("CalcPriceMod", (float(*)(Client*))&Perl_Client_CalcPriceMod);
package.add("CalcPriceMod", (float(*)(Client*, Mob*))&Perl_Client_CalcPriceMod); package.add("CalcPriceMod", (float(*)(Client*, Mob*))&Perl_Client_CalcPriceMod);
package.add("CalcPriceMod", (float(*)(Client*, Mob*, bool))&Perl_Client_CalcPriceMod); package.add("CalcPriceMod", (float(*)(Client*, Mob*, bool))&Perl_Client_CalcPriceMod);
package.add("CanEnterZone", (bool(*)(Client*, std::string))&Perl_Client_CanEnterZone);
package.add("CanEnterZone", (bool(*)(Client*, std::string, int16))&Perl_Client_CanEnterZone);
package.add("CanHaveSkill", &Perl_Client_CanHaveSkill); package.add("CanHaveSkill", &Perl_Client_CanHaveSkill);
package.add("CashReward", &Perl_Client_CashReward); package.add("CashReward", &Perl_Client_CashReward);
package.add("ChangeLastName", &Perl_Client_ChangeLastName); package.add("ChangeLastName", &Perl_Client_ChangeLastName);

View File

@ -362,7 +362,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
ZoneChange_Struct* zc2 = (ZoneChange_Struct*)outapp->pBuffer; ZoneChange_Struct* zc2 = (ZoneChange_Struct*)outapp->pBuffer;
if (ztz->response <= 0) { if (ztz->response <= 0) {
zc2->success = ZONE_ERROR_NOTREADY; zc2->success = ZoningMessage::ZoneNotReady;
entity->CastToMob()->SetZone(ztz->current_zone_id, ztz->current_instance_id); entity->CastToMob()->SetZone(ztz->current_zone_id, ztz->current_instance_id);
entity->CastToClient()->SetZoning(false); entity->CastToClient()->SetZoning(false);
entity->CastToClient()->SetLockSavePosition(false); entity->CastToClient()->SetLockSavePosition(false);

View File

@ -297,30 +297,14 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
break; break;
}; };
//OK, now we should know where were going... auto zoning_message = ZoningMessage::ZoneSuccess;
//Check some rules first. // Check Minimum Status, Minimum Level, Maximum Level, and Zone Flag
int8 myerror = 1; //1 is succes if (
!ignore_restrictions &&
//not sure when we would use ZONE_ERROR_NOTREADY !CanEnterZone(ZoneName(target_zone_id), target_instance_version)
) {
//enforce min status and level zoning_message = ZoningMessage::ZoneNoExperience;
if (!ignore_restrictions && (Admin() < min_status || GetLevel() < zone_data->min_level)) {
myerror = ZONE_ERROR_NOEXPERIENCE;
}
if (!ignore_restrictions && !zone_data->flag_needed.empty()) {
//the flag needed string is not empty, meaning a flag is required.
if (Admin() < minStatusToIgnoreZoneFlags && !HasZoneFlag(target_zone_id)) {
LogInfo(
"Client [{}] does not have the proper flag to enter [{}] ({})",
GetCleanName(),
ZoneName(target_zone_id),
target_zone_id
);
Message(Chat::Red, "You do not have the flag to enter %s.", target_zone_name);
myerror = ZONE_ERROR_NOEXPERIENCE;
}
} }
//TODO: ADVENTURE ENTRANCE CHECK //TODO: ADVENTURE ENTRANCE CHECK
@ -345,7 +329,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
); );
if (!meets_zone_expansion_check) { if (!meets_zone_expansion_check) {
myerror = ZONE_ERROR_NOEXPANSION; zoning_message = ZoningMessage::ZoneNoExpansion;
} }
} }
@ -353,12 +337,11 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
LogInfo("[{}] Bypassing Expansion zone checks because GM status is set", GetCleanName()); LogInfo("[{}] Bypassing Expansion zone checks because GM status is set", GetCleanName());
} }
if (myerror == 1) { if (zoning_message == ZoningMessage::ZoneSuccess) {
//we have successfully zoned
DoZoneSuccess(zc, target_zone_id, target_instance_id, target_x, target_y, target_z, target_heading, ignore_restrictions); DoZoneSuccess(zc, target_zone_id, target_instance_id, target_x, target_y, target_z, target_heading, ignore_restrictions);
} else { } else {
LogError("Zoning [{}]: Rules prevent this char from zoning into [{}]", GetName(), target_zone_name); LogError("Zoning [{}]: Rules prevent this char from zoning into [{}]", GetName(), target_zone_name);
SendZoneError(zc, myerror); SendZoneError(zc, zoning_message);
} }
} }
@ -1215,47 +1198,64 @@ void Client::SetPEQZoneFlag(uint32 zone_id) {
} }
} }
bool Client::CanBeInZone() { bool Client::CanEnterZone(std::string zone_short_name, int16 instance_version) {
//check some critial rules to see if this char needs to be booted from the zone //check some critial rules to see if this char needs to be booted from the zone
//only enforce rules here which are serious enough to warrant being kicked from //only enforce rules here which are serious enough to warrant being kicked from
//the zone //the zone
if (Admin() >= RuleI(GM, MinStatusToZoneAnywhere)) { if (Admin() >= RuleI(GM, MinStatusToZoneAnywhere)) {
return (true); return true;
} }
float safe_x, safe_y, safe_z, safe_heading;
int16 min_status = AccountStatus::Player;
uint8 min_level = 0;
auto z = GetZoneVersionWithFallback( auto z = GetZoneVersionWithFallback(
ZoneID(zone->GetShortName()), zone_short_name.empty() ? ZoneID(zone->GetShortName()) : ZoneID(zone_short_name),
zone->GetInstanceVersion() instance_version == -1 ? zone->GetInstanceVersion() : instance_version
); );
if (!z) { if (!z) {
return false; return false;
} }
safe_x = z->safe_x; if (GetLevel() < z->min_level) {
safe_y = z->safe_y; LogInfo(
safe_z = z->safe_z; "Character [{}] does not meet minimum level requirement ([{}] < [{}])!",
safe_heading = z->safe_heading; GetCleanName(),
min_status = z->min_status; GetLevel(),
min_level = z->min_level; z->min_level
);
if (GetLevel() < min_level) { return false;
LogDebug("[CLIENT] Character does not meet min level requirement ([{}] < [{}])!", GetLevel(), min_level);
return (false);
} }
if (Admin() < min_status) {
LogDebug("[CLIENT] Character does not meet min status requirement ([{}] < [{}])!", Admin(), min_status); if (GetLevel() > z->max_level) {
return (false); LogInfo(
"Character [{}] does not meet maximum level requirement ([{}] > [{}])!",
GetCleanName(),
GetLevel(),
z->max_level
);
return false;
}
if (Admin() < z->min_status) {
LogInfo(
"Character [{}] does not meet minimum status requirement ([{}] < [{}])!",
GetCleanName(),
Admin(),
z->min_status
);
return false;
} }
if (!z->flag_needed.empty()) { if (!z->flag_needed.empty()) {
//the flag needed string is not empty, meaning a flag is required. if (
if (Admin() < minStatusToIgnoreZoneFlags && !HasZoneFlag(zone->GetZoneID())) { Admin() < minStatusToIgnoreZoneFlags &&
LogInfo("Character [{}] does not have the flag to be in this zone [{}]!", GetCleanName(), z->flag_needed); !HasZoneFlag(zone->GetZoneID())
) {
LogInfo(
"Character [{}] does not have the flag to be in this zone [{}]!",
GetCleanName(),
z->flag_needed
);
return false; return false;
} }
} }