mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 18:52:22 +00:00
[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:
+51
-51
@@ -297,30 +297,14 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
|
||||
break;
|
||||
};
|
||||
|
||||
//OK, now we should know where were going...
|
||||
auto zoning_message = ZoningMessage::ZoneSuccess;
|
||||
|
||||
//Check some rules first.
|
||||
int8 myerror = 1; //1 is succes
|
||||
|
||||
//not sure when we would use ZONE_ERROR_NOTREADY
|
||||
|
||||
//enforce min status and level
|
||||
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;
|
||||
}
|
||||
// Check Minimum Status, Minimum Level, Maximum Level, and Zone Flag
|
||||
if (
|
||||
!ignore_restrictions &&
|
||||
!CanEnterZone(ZoneName(target_zone_id), target_instance_version)
|
||||
) {
|
||||
zoning_message = ZoningMessage::ZoneNoExperience;
|
||||
}
|
||||
|
||||
//TODO: ADVENTURE ENTRANCE CHECK
|
||||
@@ -345,7 +329,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
|
||||
);
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
if (myerror == 1) {
|
||||
//we have successfully zoned
|
||||
if (zoning_message == ZoningMessage::ZoneSuccess) {
|
||||
DoZoneSuccess(zc, target_zone_id, target_instance_id, target_x, target_y, target_z, target_heading, ignore_restrictions);
|
||||
} else {
|
||||
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
|
||||
//only enforce rules here which are serious enough to warrant being kicked from
|
||||
//the zone
|
||||
|
||||
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(
|
||||
ZoneID(zone->GetShortName()),
|
||||
zone->GetInstanceVersion()
|
||||
zone_short_name.empty() ? ZoneID(zone->GetShortName()) : ZoneID(zone_short_name),
|
||||
instance_version == -1 ? zone->GetInstanceVersion() : instance_version
|
||||
);
|
||||
|
||||
if (!z) {
|
||||
return false;
|
||||
}
|
||||
|
||||
safe_x = z->safe_x;
|
||||
safe_y = z->safe_y;
|
||||
safe_z = z->safe_z;
|
||||
safe_heading = z->safe_heading;
|
||||
min_status = z->min_status;
|
||||
min_level = z->min_level;
|
||||
|
||||
if (GetLevel() < min_level) {
|
||||
LogDebug("[CLIENT] Character does not meet min level requirement ([{}] < [{}])!", GetLevel(), min_level);
|
||||
return (false);
|
||||
if (GetLevel() < z->min_level) {
|
||||
LogInfo(
|
||||
"Character [{}] does not meet minimum level requirement ([{}] < [{}])!",
|
||||
GetCleanName(),
|
||||
GetLevel(),
|
||||
z->min_level
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (Admin() < min_status) {
|
||||
LogDebug("[CLIENT] Character does not meet min status requirement ([{}] < [{}])!", Admin(), min_status);
|
||||
return (false);
|
||||
|
||||
if (GetLevel() > z->max_level) {
|
||||
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()) {
|
||||
//the flag needed string is not empty, meaning a flag is required.
|
||||
if (Admin() < minStatusToIgnoreZoneFlags && !HasZoneFlag(zone->GetZoneID())) {
|
||||
LogInfo("Character [{}] does not have the flag to be in this zone [{}]!", GetCleanName(), z->flag_needed);
|
||||
if (
|
||||
Admin() < minStatusToIgnoreZoneFlags &&
|
||||
!HasZoneFlag(zone->GetZoneID())
|
||||
) {
|
||||
LogInfo(
|
||||
"Character [{}] does not have the flag to be in this zone [{}]!",
|
||||
GetCleanName(),
|
||||
z->flag_needed
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user