Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Cleanup] Fix GM Flag Spell Restriction Bypasses #4571

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 159 additions & 90 deletions zone/spells.cpp
Original file line number Diff line number Diff line change
@@ -652,114 +652,183 @@ bool Mob::DoCastingChecksZoneRestrictions(bool check_on_casting, int32 spell_id)
- levitate zone restriction (client blocks) [cancel before begin cast message]
- can not cast outdoor [cancels after spell finishes channeling]

If the spell is a casted spell, check on CastSpell and ignore on SpellFinished.
If the spell is a initiated from SpellFinished, then check at start of SpellFinished.
If the spell is a cast spell, check on CastSpell and ignore on SpellFinished.
If the spell is initiated from SpellFinished, then check at start of SpellFinished.
*/

bool bypass_casting_restrictions = false;

if (!IsClient()) {
bypass_casting_restrictions = true;
}

if (IsClient() && CastToClient()->GetGM()) {
bypass_casting_restrictions = true;
Message(
Chat::White,
fmt::format(
"Your GM flag allows you to bypass zone casting restrictions and cast {} in this zone.",
Saylink::Silent(
fmt::format(
"#castspell {}",
spell_id
),
GetSpellName(spell_id)
)
).c_str()
);
}
bool bypass_casting_restrictions = IsClient() ? false : true;

/*
Zone ares that prevent blocked spells from being cast.
If on cast iniated then check any mob casting, if on spellfinished only check if is from client.
*/
if ((check_on_casting && !bypass_casting_restrictions) || (!check_on_casting && IsClient())) {
if (
(check_on_casting && !bypass_casting_restrictions) ||
(!check_on_casting && IsClient())
) {
if (zone->IsSpellBlocked(spell_id, glm::vec3(GetPosition()))) {
if (IsClient()) {
if (!CastToClient()->GetGM()) {
const char *msg = zone->GetSpellBlockedMessage(spell_id, glm::vec3(GetPosition()));
if (msg) {
Message(Chat::Red, msg);
return false;
}
else {
Message(Chat::Red, "You can't cast this spell here.");
return false;
}
LogSpells("Spell casting canceled [{}] : can not cast in this zone location blocked spell.", spell_id);
}
else {
Message(
Chat::White,
fmt::format(
"Your GM flag allows you to bypass zone blocked spells and cast {} in this zone.",
Saylink::Silent(
fmt::format(
"#castspell {}",
spell_id
),
GetSpellName(spell_id)
)
).c_str()
);
LogSpells("GM Cast Blocked Spell: [{}] (ID [{}])", GetSpellName(spell_id), spell_id);
if (CastToClient()->GetGM()) {
Message(
Chat::White,
fmt::format(
"Your GM flag allows you to bypass zone blocked spells and cast {} in this zone.",
Saylink::Silent(
fmt::format(
"#castspell {}",
spell_id
),
GetSpellName(spell_id)
)
).c_str()
);

LogSpells("GM Cast Blocked Spell: [{}] (ID [{}])", GetSpellName(spell_id), spell_id);
} else {
const char* msg = zone->GetSpellBlockedMessage(spell_id, glm::vec3(GetPosition()));
if (msg) {
Message(Chat::Red, msg);
return false;
} else {
Message(Chat::Red, "You can't cast this spell here.");
return false;
}

LogSpells("Spell casting canceled [{}]: cannot cast in this zone location blocked spell.", spell_id);
}
return false;
}
}
/*
Zones where you can not use levitate spells.
*/
if (!bypass_casting_restrictions && !zone->CanLevitate() && IsEffectInSpell(spell_id, SE_Levitate)) { //check on spellfinished.
Message(Chat::Red, "You have entered an area where levitation effects do not function.");
LogSpells("Spell casting canceled [{}] : can not cast levitation in this zone.", spell_id);
return false;

// Zones where you cannot use levitate spells.
if (
!bypass_casting_restrictions &&
!zone->CanLevitate() &&
IsEffectInSpell(spell_id, SE_Levitate)
) { //check on spellfinished.
if (CastToClient()->GetGM()) {
Message(
Chat::White,
fmt::format(
"Your GM flag allows you to bypass zone levitation restrictions and cast {} in this zone.",
Saylink::Silent(
fmt::format(
"#castspell {}",
spell_id
),
GetSpellName(spell_id)
)
).c_str()
);
} else {
Message(Chat::Red, "You have entered an area where levitation effects do not function.");
LogSpells("Spell casting canceled [{}]: cannot cast levitation in this zone.", spell_id);
return false;
}
}
/*
Zones where you can not use detrimental spells.
*/
if (IsDetrimentalSpell(spell_id) && !zone->CanDoCombat()) {
Message(Chat::Red, "You cannot cast detrimental spells here.");
return false;

// Zones where you can not use detrimental spells.
if (
!bypass_casting_restrictions &&
IsDetrimentalSpell(spell_id) &&
!zone->CanDoCombat()
) {
if (CastToClient()->GetGM()) {
Message(
Chat::White,
fmt::format(
"Your GM flag allows you to bypass no combat zone restrictions and cast {} in this zone.",
Saylink::Silent(
fmt::format(
"#castspell {}",
spell_id
),
GetSpellName(spell_id)
)
).c_str()
);
} else {
Message(Chat::Red, "You cannot cast detrimental spells here.");
return false;
}
}
/*
Zones where you can not cast a spell that is for daytime or nighttime only
*/
if (spells[spell_id].time_of_day == SpellTimeRestrictions::Day && !zone->zone_time.IsDayTime()) {
MessageString(Chat::Red, CAST_DAYTIME);
return false;

// Zones where you can not cast a spell that is for daytime only
if (
!bypass_casting_restrictions &&
spells[spell_id].time_of_day == SpellTimeRestrictions::Day &&
!zone->zone_time.IsDayTime()
) {
if (CastToClient()->GetGM()) {
Message(
Chat::White,
fmt::format(
"Your GM flag allows you to bypass spell daytime restrictions and cast {} during nighttime.",
Saylink::Silent(
fmt::format(
"#castspell {}",
spell_id
),
GetSpellName(spell_id)
)
).c_str()
);
} else {
MessageString(Chat::Red, CAST_DAYTIME);
return false;
}
}

if (spells[spell_id].time_of_day == SpellTimeRestrictions::Night && !zone->zone_time.IsNightTime()) {
MessageString(Chat::Red, CAST_NIGHTTIME);
return false;
// Zones where you can not cast a spell that is for nighttime only
if (
!bypass_casting_restrictions &&
spells[spell_id].time_of_day == SpellTimeRestrictions::Night &&
!zone->zone_time.IsNightTime()
) {
if (CastToClient()->GetGM()) {
Message(
Chat::White,
fmt::format(
"Your GM flag allows you to bypass spell nighttime restrictions and cast {} during daytime.",
Saylink::Silent(
fmt::format(
"#castspell {}",
spell_id
),
GetSpellName(spell_id)
)
).c_str()
);
} else {
MessageString(Chat::Red, CAST_NIGHTTIME);
return false;
}
}

if (check_on_casting) {
/*
Zones where you can not cast out door only spells. This is only checked when casting is completed.
*/
if (!bypass_casting_restrictions && spells[spell_id].zone_type == 1 && !zone->CanCastOutdoor()) {
if (IsClient()) {
if (!CastToClient()->GetGM()) {
MessageString(Chat::Red, CAST_OUTDOORS);
LogSpells("Spell casting canceled [{}] : can not cast outdoors.", spell_id);
return false;
} else {
Message(Chat::White, "Your GM flag allows you to cast outdoor spells when indoors.");
}
}
// Zones where you can not cast out door only spells.
// This is only checked when casting is completed.
if (
check_on_casting &&
!bypass_casting_restrictions &&
spells[spell_id].zone_type == 1 &&
!zone->CanCastOutdoor()
) {
if (CastToClient()->GetGM()) {
Message(
Chat::White,
fmt::format(
"Your GM flag allows you to bypass zone outdoor restrictions and cast {} while indoors.",
Saylink::Silent(
fmt::format(
"#castspell {}",
spell_id
),
GetSpellName(spell_id)
)
).c_str()
);
} else {
MessageString(Chat::Red, CAST_OUTDOORS);
LogSpells("Spell casting canceled [{}]: cannot cast outdoors.", spell_id);
return false;
}
}