[Rules] Add rules for cross-zone/world-wide casts to affect Bots/Mercenaries/Pets (#4002)

* [Rules] Add rules for cross-zone/world-wide casts to affect bots/mercenaries/pets

# Notes
- These rules allow operators to have cross-zone/world-wide casts/removals of spells affect bots, mercenaries, and/or pets.
- Adds `World:AllowWorldWideSpellsOnBots`.
- Adds `World:AllowWorldWideSpellsOnMercs`.
- Adds `World:AllowWorldWideSpellsOnPets`.
- Adds `Zone:AllowCrossZoneSpellsOnBots`.
- Adds `Zone:AllowCrossZoneSpellsOnMercs`.
- Adds `Zone:AllowCrossZoneSpellsOnPets`.

* Consolidate to 3 rules
This commit is contained in:
Alex King 2024-01-29 00:06:21 -05:00 committed by GitHub
parent b89772ca91
commit 9276966418
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 301 additions and 83 deletions

View File

@ -342,6 +342,9 @@ RULE_INT(Zone, GlobalLootMultiplier, 1, "Sets Global Loot drop multiplier for da
RULE_BOOL(Zone, KillProcessOnDynamicShutdown, true, "When process has booted a zone and has hit its zone shut down timer, it will hard kill the process to free memory back to the OS")
RULE_INT(Zone, SpawnEventMin, 3, "When strict is set in spawn_events, specifies the max EQ minutes into the trigger hour a spawn_event will fire. Going below 3 may cause the spawn_event to not fire.")
RULE_INT(Zone, ForageChance, 25, "Chance of foraging from zone table vs global table")
RULE_BOOL(Zone, AllowCrossZoneSpellsOnBots, false, "Set to true to allow cross zone spells (cast/remove) to affect bots")
RULE_BOOL(Zone, AllowCrossZoneSpellsOnMercs, false, "Set to true to allow cross zone spells (cast/remove) to affect mercenaries")
RULE_BOOL(Zone, AllowCrossZoneSpellsOnPets, false, "Set to true to allow cross zone spells (cast/remove) to affect pets")
RULE_CATEGORY_END()
RULE_CATEGORY(Map)

View File

@ -2734,97 +2734,281 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
}
case ServerOP_CZSpell:
{
CZSpell_Struct* CZS = (CZSpell_Struct*) pack->pBuffer;
uint8 update_type = CZS->update_type;
uint8 update_subtype = CZS->update_subtype;
int update_identifier = CZS->update_identifier;
uint32 spell_id = CZS->spell_id;
const char* client_name = CZS->client_name;
if (update_type == CZUpdateType_Character) {
auto client = entity_list.GetClientByCharID(update_identifier);
if (client) {
switch (update_subtype) {
case CZSpellUpdateSubtype_Cast:
client->ApplySpellBuff(spell_id);
break;
case CZSpellUpdateSubtype_Remove:
client->BuffFadeBySpellID(spell_id);
break;
}
}
} else if (update_type == CZUpdateType_Group) {
auto client_group = entity_list.GetGroupByID(update_identifier);
if (client_group) {
for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) {
if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) {
auto group_member = client_group->members[member_index]->CastToClient();
switch (update_subtype) {
case CZSpellUpdateSubtype_Cast:
group_member->ApplySpellBuff(spell_id);
break;
case CZSpellUpdateSubtype_Remove:
group_member->BuffFadeBySpellID(spell_id);
break;
}
}
}
}
} else if (update_type == CZUpdateType_Raid) {
auto client_raid = entity_list.GetRaidByID(update_identifier);
if (client_raid) {
for (const auto& m : client_raid->members) {
if (m.is_bot) {
continue;
}
auto s = (CZSpell_Struct*) pack->pBuffer;
if (m.member && m.member->IsClient()) {
auto raid_member = m.member->CastToClient();
switch (update_subtype) {
if (s->update_type == CZUpdateType_Character) {
Client* c = entity_list.GetClientByCharID(s->update_identifier);
if (c) {
switch (s->update_subtype) {
case CZSpellUpdateSubtype_Cast:
c->ApplySpellBuff(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnBots)) {
for (const auto& b : entity_list.GetBotListByCharacterID(c->CharacterID())) {
b->ApplySpellBuff(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnMercs)) {
if (c->GetMerc()) {
c->GetMerc()->ApplySpellBuff(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (c->HasPet()) {
c->GetPet()->ApplySpellBuff(s->spell_id);
}
}
break;
case CZSpellUpdateSubtype_Remove:
c->BuffFadeBySpellID(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnBots)) {
for (const auto& b : entity_list.GetBotListByCharacterID(c->CharacterID())) {
b->BuffFadeBySpellID(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnMercs)) {
if (c->GetMerc()) {
c->GetMerc()->BuffFadeBySpellID(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (c->HasPet()) {
c->GetPet()->BuffFadeBySpellID(s->spell_id);
}
}
break;
}
}
} else if (s->update_type == CZUpdateType_Group) {
Group* g = entity_list.GetGroupByID(s->update_identifier);
if (g) {
for (const auto& m : g->members) {
if (
m &&
(
m->IsClient() ||
(m->IsBot() && RuleB(Zone, AllowCrossZoneSpellsOnBots)) ||
(m->IsMerc() && RuleB(Zone, AllowCrossZoneSpellsOnMercs))
)
) {
switch (s->update_subtype) {
case CZSpellUpdateSubtype_Cast:
raid_member->ApplySpellBuff(spell_id);
m->ApplySpellBuff(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (m->HasPet()) {
m->GetPet()->ApplySpellBuff(s->spell_id);
}
}
break;
case CZSpellUpdateSubtype_Remove:
raid_member->BuffFadeBySpellID(spell_id);
m->BuffFadeBySpellID(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (m->HasPet()) {
m->GetPet()->BuffFadeBySpellID(s->spell_id);
}
}
break;
}
}
}
}
} else if (update_type == CZUpdateType_Guild) {
for (auto &client: entity_list.GetClientList()) {
if (client.second->GuildID() > 0 && client.second->GuildID() == update_identifier) {
switch (update_subtype) {
} else if (s->update_type == CZUpdateType_Raid) {
Raid* r = entity_list.GetRaidByID(s->update_identifier);
if (r) {
for (const auto& m : r->members) {
if (
m.member &&
(
m.member->IsClient() ||
(m.member->IsBot() && RuleB(Zone, AllowCrossZoneSpellsOnBots)) ||
(m.member->IsMerc() && RuleB(Zone, AllowCrossZoneSpellsOnMercs))
)
){
switch (s->update_subtype) {
case CZSpellUpdateSubtype_Cast:
m.member->ApplySpellBuff(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (m.member->HasPet()) {
m.member->GetPet()->ApplySpellBuff(s->spell_id);
}
}
break;
case CZSpellUpdateSubtype_Remove:
m.member->BuffFadeBySpellID(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (m.member->HasPet()) {
m.member->GetPet()->BuffFadeBySpellID(s->spell_id);
}
}
break;
}
}
}
}
} else if (s->update_type == CZUpdateType_Guild) {
for (const auto& c : entity_list.GetClientList()) {
if (c.second->IsInGuild(s->update_identifier)) {
switch (s->update_subtype) {
case CZSpellUpdateSubtype_Cast:
client.second->ApplySpellBuff(spell_id);
c.second->ApplySpellBuff(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnBots)) {
for (const auto& b : entity_list.GetBotListByCharacterID(c.second->CharacterID())) {
b->ApplySpellBuff(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnMercs)) {
if (c.second->GetMerc()) {
c.second->GetMerc()->ApplySpellBuff(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (c.second->HasPet()) {
c.second->GetPet()->ApplySpellBuff(s->spell_id);
}
}
break;
case CZSpellUpdateSubtype_Remove:
client.second->BuffFadeBySpellID(spell_id);
c.second->BuffFadeBySpellID(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnBots)) {
for (const auto& b : entity_list.GetBotListByCharacterID(c.second->CharacterID())) {
b->BuffFadeBySpellID(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnMercs)) {
if (c.second->GetMerc()) {
c.second->GetMerc()->BuffFadeBySpellID(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (c.second->HasPet()) {
c.second->GetPet()->BuffFadeBySpellID(s->spell_id);
}
}
break;
}
}
}
} else if (update_type == CZUpdateType_Expedition) {
for (auto &client: entity_list.GetClientList()) {
if (client.second->GetExpedition() && client.second->GetExpedition()->GetID() == update_identifier) {
switch (update_subtype) {
} else if (s->update_type == CZUpdateType_Expedition) {
for (const auto& c : entity_list.GetClientList()) {
if (c.second->GetExpedition() && c.second->GetExpedition()->GetID() == s->update_identifier) {
switch (s->update_subtype) {
case CZSpellUpdateSubtype_Cast:
client.second->ApplySpellBuff(spell_id);
c.second->ApplySpellBuff(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnBots)) {
for (const auto& b : entity_list.GetBotListByCharacterID(c.second->CharacterID())) {
b->ApplySpellBuff(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnMercs)) {
if (c.second->GetMerc()) {
c.second->GetMerc()->ApplySpellBuff(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (c.second->HasPet()) {
c.second->GetPet()->ApplySpellBuff(s->spell_id);
}
}
break;
case CZSpellUpdateSubtype_Remove:
client.second->BuffFadeBySpellID(spell_id);
c.second->BuffFadeBySpellID(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnBots)) {
for (const auto& b : entity_list.GetBotListByCharacterID(c.second->CharacterID())) {
b->BuffFadeBySpellID(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnMercs)) {
if (c.second->GetMerc()) {
c.second->GetMerc()->BuffFadeBySpellID(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (c.second->HasPet()) {
c.second->GetPet()->BuffFadeBySpellID(s->spell_id);
}
}
break;
}
}
}
} else if (update_type == CZUpdateType_ClientName) {
auto client = entity_list.GetClientByName(client_name);
if (client) {
switch (update_subtype) {
} else if (s->update_type == CZUpdateType_ClientName) {
Client* c = entity_list.GetClientByName(s->client_name);
if (c) {
switch (s->update_subtype) {
case CZSpellUpdateSubtype_Cast:
client->ApplySpellBuff(spell_id);
c->ApplySpellBuff(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnBots)) {
for (const auto& b : entity_list.GetBotListByCharacterID(c->CharacterID())) {
b->ApplySpellBuff(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnMercs)) {
if (c->GetMerc()) {
c->GetMerc()->ApplySpellBuff(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (c->HasPet()) {
c->GetPet()->ApplySpellBuff(s->spell_id);
}
}
break;
case CZSpellUpdateSubtype_Remove:
client->BuffFadeBySpellID(spell_id);
c->BuffFadeBySpellID(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnBots)) {
for (const auto& b : entity_list.GetBotListByCharacterID(c->CharacterID())) {
b->BuffFadeBySpellID(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnMercs)) {
if (c->GetMerc()) {
c->GetMerc()->BuffFadeBySpellID(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (c->HasPet()) {
c->GetPet()->BuffFadeBySpellID(s->spell_id);
}
}
break;
}
}
@ -3180,27 +3364,58 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
}
break;
}
case ServerOP_WWSpell:
{
WWSpell_Struct* WWS = (WWSpell_Struct*) pack->pBuffer;
uint8 update_type = WWS->update_type;
uint32 spell_id = WWS->spell_id;
uint8 min_status = WWS->min_status;
uint8 max_status = WWS->max_status;
if (update_type == WWSpellUpdateType_Cast) {
for (auto &client : entity_list.GetClientList()) {
if (client.second->Admin() >= min_status && (client.second->Admin() <= max_status || max_status == AccountStatus::Player)) {
client.second->ApplySpellBuff(spell_id);
}
}
} else if (update_type == WWSpellUpdateType_Remove) {
for (auto &client : entity_list.GetClientList()) {
if (client.second->Admin() >= min_status && (client.second->Admin() <= max_status || max_status == AccountStatus::Player)) {
client.second->BuffFadeBySpellID(spell_id);
case ServerOP_WWSpell: {
auto s = (WWSpell_Struct *) pack->pBuffer;
for (const auto& c : entity_list.GetClientList()) {
if (
c.second->Admin() >= s->min_status &&
(c.second->Admin() <= s->max_status || s->max_status == AccountStatus::Player)
) {
if (s->update_type == WWSpellUpdateType_Cast) {
c.second->ApplySpellBuff(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnBots)) {
for (const auto& b : entity_list.GetBotListByCharacterID(c.second->CharacterID())) {
b->ApplySpellBuff(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnMercs)) {
if (c.second->GetMerc()) {
c.second->GetMerc()->ApplySpellBuff(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (c.second->HasPet()) {
c.second->GetPet()->ApplySpellBuff(s->spell_id);
}
}
} else if (s->update_type == WWSpellUpdateType_Remove) {
c.second->BuffFadeBySpellID(s->spell_id);
if (RuleB(Zone, AllowCrossZoneSpellsOnBots)) {
for (const auto& b : entity_list.GetBotListByCharacterID(c.second->CharacterID())) {
b->BuffFadeBySpellID(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnMercs)) {
if (c.second->GetMerc()) {
c.second->GetMerc()->BuffFadeBySpellID(s->spell_id);
}
}
if (RuleB(Zone, AllowCrossZoneSpellsOnPets)) {
if (c.second->HasPet()) {
c.second->GetPet()->BuffFadeBySpellID(s->spell_id);
}
}
}
}
break;
}
break;
}
case ServerOP_WWTaskUpdate:
{