mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-18 04:08:27 +00:00
[Spells] Rework of Virus Effect code (#1593)
* start of rework * functional * virus updates * Update npc.cpp * updates * updates * update v2 * pre remove old code * removed old code1 * remove debugs * description * Update spell_effects.cpp * changed function name * remove unused var * merge error fix * fix formating issue * Update spdat.cpp * Update spell_effects.cpp * Convert virus entity range code to use vectors and GetCloseMobList * Formatting [skip ci] Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
+73
-38
@@ -1219,7 +1219,7 @@ uint32 EntityList::CountSpawnedNPCs(std::vector<uint32> npc_ids)
|
||||
npc_ids.begin(),
|
||||
npc_ids.end(),
|
||||
current_npc.second->GetNPCTypeID()
|
||||
) != npc_ids.end() &&
|
||||
) != npc_ids.end() &&
|
||||
current_npc.second->GetID() != 0
|
||||
) {
|
||||
npc_count++;
|
||||
@@ -5222,59 +5222,94 @@ Client *EntityList::FindCorpseDragger(uint16 CorpseID)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Mob *EntityList::GetTargetForVirus(Mob *spreader, int range)
|
||||
std::vector<Mob*> EntityList::GetTargetsForVirusEffect(Mob *spreader, Mob *original_caster, int range, int pcnpc, int32 spell_id)
|
||||
{
|
||||
int max_spread_range = RuleI(Spells, VirusSpreadDistance);
|
||||
/*
|
||||
Live Mechanics
|
||||
Virus spreader does NOT need LOS
|
||||
There is no max target limit
|
||||
*/
|
||||
if (!spreader) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (range)
|
||||
max_spread_range = range;
|
||||
std::vector<Mob *> spreader_list = {};
|
||||
bool is_detrimental_spell = IsDetrimentalSpell(spell_id);
|
||||
for (auto &it : entity_list.GetCloseMobList(spreader, range)) {
|
||||
Mob *mob = it.second;
|
||||
if (mob == spreader) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<Mob *> TargetsInRange;
|
||||
// check PC/NPC only flag 1 = PCs, 2 = NPCs
|
||||
if (pcnpc == 1 && !mob->IsClient() && !mob->IsMerc() && !mob->IsBot()) {
|
||||
continue;
|
||||
}
|
||||
else if (pcnpc == 2 && (mob->IsClient() || mob->IsMerc() || mob->IsBot())) {
|
||||
continue;
|
||||
}
|
||||
if (mob->IsClient() && !mob->CastToClient()->ClientFinishedLoading()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto it = mob_list.begin();
|
||||
while (it != mob_list.end()) {
|
||||
Mob *cur = it->second;
|
||||
// Make sure the target is in range, has los and is not the mob doing the spreading
|
||||
if ((cur->GetID() != spreader->GetID()) &&
|
||||
(cur->CalculateDistance(spreader->GetX(), spreader->GetY(),
|
||||
spreader->GetZ()) <= max_spread_range) &&
|
||||
(spreader->CheckLosFN(cur))) {
|
||||
// If the spreader is an npc it can only spread to other npc controlled mobs
|
||||
if (spreader->IsNPC() && !spreader->IsPet() && !spreader->CastToNPC()->GetSwarmOwner() && cur->IsNPC()) {
|
||||
TargetsInRange.push_back(cur);
|
||||
if (mob->IsAura() || mob->IsTrap()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make sure the target is in range
|
||||
if (mob->CalculateDistance(spreader->GetX(), spreader->GetY(), spreader->GetZ()) <= range) {
|
||||
|
||||
//Do not allow detrimental spread to anything the original caster couldn't normally attack.
|
||||
if (is_detrimental_spell && !original_caster->IsAttackAllowed(mob, true)) {
|
||||
continue;
|
||||
}
|
||||
// If the spreader is an npc controlled pet it can spread to any other npc or an npc controlled pet
|
||||
else if (spreader->IsNPC() && spreader->IsPet() && spreader->GetOwner()->IsNPC()) {
|
||||
if (cur->IsNPC() && !cur->IsPet()) {
|
||||
TargetsInRange.push_back(cur);
|
||||
} else if (cur->IsNPC() && cur->IsPet() && cur->GetOwner()->IsNPC()) {
|
||||
TargetsInRange.push_back(cur);
|
||||
|
||||
//For non-NPCs, do not allow beneficial spread to anything the original caster could normally attack.
|
||||
if (!is_detrimental_spell && !original_caster->IsNPC() && original_caster->IsAttackAllowed(mob, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the spreader is an npc and NOT a PET, then spread to other npc controlled mobs that are not pets
|
||||
if (spreader->IsNPC() && !spreader->IsPet() && !spreader->IsTempPet() && mob->IsNPC() && !mob->IsPet() && !mob->IsTempPet()) {
|
||||
spreader_list.push_back(mob);
|
||||
}
|
||||
// If the spreader is an npc and NOT a PET, then spread to npc controlled pet
|
||||
else if (spreader->IsNPC() && !spreader->IsPet() && !spreader->IsTempPet() && mob->IsNPC() && (mob->IsPet() || mob->IsTempPet()) && mob->IsPetOwnerNPC()) {
|
||||
spreader_list.push_back(mob);
|
||||
}
|
||||
// If the spreader is an npc controlled PET it can spread to any other npc or an npc controlled pet
|
||||
else if (spreader->IsNPC() && (spreader->IsPet() || spreader->IsTempPet()) && spreader->IsPetOwnerNPC()) {
|
||||
if (mob->IsNPC() && (!mob->IsPet() || !mob->IsTempPet())) {
|
||||
spreader_list.push_back(mob);
|
||||
}
|
||||
else if (cur->IsNPC() && cur->CastToNPC()->GetSwarmOwner() && cur->GetOwner()->IsNPC()) {
|
||||
TargetsInRange.push_back(cur);
|
||||
else if (mob->IsNPC() && (mob->IsPet() || mob->IsTempPet()) && mob->IsPetOwnerNPC()) {
|
||||
spreader_list.push_back(mob);
|
||||
}
|
||||
}
|
||||
// if the spreader is anything else(bot, pet, etc) then it should spread to everything but non client controlled npcs
|
||||
else if (!spreader->IsNPC() && !cur->IsNPC()) {
|
||||
TargetsInRange.push_back(cur);
|
||||
else if (!spreader->IsNPC() && !mob->IsNPC()) {
|
||||
spreader_list.push_back(mob);
|
||||
}
|
||||
// if its a pet we need to determine appropriate targets(pet to client, pet to pet, pet to bot, etc)
|
||||
else if (spreader->IsNPC() && (spreader->IsPet() || spreader->CastToNPC()->GetSwarmOwner()) && !spreader->GetOwner()->IsNPC()) {
|
||||
if (!cur->IsNPC()) {
|
||||
TargetsInRange.push_back(cur);
|
||||
// if spreader is not an NPC, and Target is an NPC, then spread to non-NPC controlled pets
|
||||
else if (!spreader->IsNPC() && mob->IsNPC() && (mob->IsPet() || mob->IsTempPet()) && !mob->IsPetOwnerNPC()) {
|
||||
spreader_list.push_back(mob);
|
||||
}
|
||||
|
||||
// if spreader is a non-NPC controlled pet we need to determine appropriate targets(pet to client, pet to pet, pet to bot, etc)
|
||||
else if (spreader->IsNPC() && (spreader->IsPet() || spreader->IsTempPet()) && !spreader->IsPetOwnerNPC()) {
|
||||
//Spread to non-NPCs
|
||||
if (!mob->IsNPC()) {
|
||||
spreader_list.push_back(mob);
|
||||
}
|
||||
else if (cur->IsNPC() && (cur->IsPet() || cur->CastToNPC()->GetSwarmOwner()) && !cur->GetOwner()->IsNPC()) {
|
||||
TargetsInRange.push_back(cur);
|
||||
//Spread to other non-NPC Pets
|
||||
else if (mob->IsNPC() && (mob->IsPet() || mob->IsTempPet()) && !mob->IsPetOwnerNPC()) {
|
||||
spreader_list.push_back(mob);
|
||||
}
|
||||
}
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
if(TargetsInRange.empty())
|
||||
return nullptr;
|
||||
|
||||
return TargetsInRange[zone->random.Int(0, TargetsInRange.size() - 1)];
|
||||
return spreader_list;
|
||||
}
|
||||
|
||||
void EntityList::StopMobAI()
|
||||
|
||||
Reference in New Issue
Block a user