mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-14 19:51:29 +00:00
AE Scanning adjustments, testing
This commit is contained in:
parent
8cb51eb253
commit
f9e822072f
@ -683,6 +683,7 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
|
|||||||
pp->RestTimer // " RestTimer) "
|
pp->RestTimer // " RestTimer) "
|
||||||
);
|
);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
/* Save Bind Points */
|
/* Save Bind Points */
|
||||||
query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
|
query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
|
||||||
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i), "
|
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i), "
|
||||||
|
|||||||
@ -87,8 +87,9 @@
|
|||||||
|
|
||||||
bool IsTargetableAESpell(uint16 spell_id)
|
bool IsTargetableAESpell(uint16 spell_id)
|
||||||
{
|
{
|
||||||
if (IsValidSpell(spell_id) && spells[spell_id].targettype == ST_AETarget)
|
if (IsValidSpell(spell_id) && spells[spell_id].targettype == ST_AETarget) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2153,6 +2153,8 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil
|
|||||||
LogCombat("Fatal blow dealt by [{}] with [{}] damage, spell [{}], skill [{}]",
|
LogCombat("Fatal blow dealt by [{}] with [{}] damage, spell [{}], skill [{}]",
|
||||||
((killer_mob) ? (killer_mob->GetName()) : ("[nullptr]")), damage, spell, attack_skill);
|
((killer_mob) ? (killer_mob->GetName()) : ("[nullptr]")), damage, spell, attack_skill);
|
||||||
|
|
||||||
|
entity_list.RemoveMobFromCloseLists(CastToMob());
|
||||||
|
|
||||||
Mob *oos = nullptr;
|
Mob *oos = nullptr;
|
||||||
if (killer_mob) {
|
if (killer_mob) {
|
||||||
oos = killer_mob->GetOwnerOrSelf();
|
oos = killer_mob->GetOwnerOrSelf();
|
||||||
|
|||||||
307
zone/effects.cpp
307
zone/effects.cpp
@ -697,110 +697,241 @@ void EntityList::AETaunt(Client* taunter, float range, int32 bonus_hate)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// causes caster to hit every mob within dist range of center with
|
/**
|
||||||
// spell_id.
|
* Causes caster to hit every mob within dist range of center with spell_id
|
||||||
// NPC spells will only affect other NPCs with compatible faction
|
*
|
||||||
void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster, int16 resist_adjust, int *max_targets)
|
* @param caster_mob
|
||||||
|
* @param center_mob
|
||||||
|
* @param spell_id
|
||||||
|
* @param affect_caster
|
||||||
|
* @param resist_adjust
|
||||||
|
* @param max_targets
|
||||||
|
*/
|
||||||
|
void EntityList::AESpell(
|
||||||
|
Mob *caster_mob,
|
||||||
|
Mob *center_mob,
|
||||||
|
uint16 spell_id,
|
||||||
|
bool affect_caster,
|
||||||
|
int16 resist_adjust,
|
||||||
|
int *max_targets
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Mob *curmob = nullptr;
|
Mob *current_mob = nullptr;
|
||||||
|
bool is_detrimental_spell = IsDetrimentalSpell(spell_id);
|
||||||
|
bool is_npc = caster_mob->IsNPC();
|
||||||
|
|
||||||
float dist = caster->GetAOERange(spell_id);
|
const auto &cast_target_position =
|
||||||
float dist2 = dist * dist;
|
spells[spell_id].targettype == ST_Ring ?
|
||||||
float min_range2 = spells[spell_id].min_range * spells[spell_id].min_range;
|
caster_mob->GetTargetRingLocation() :
|
||||||
float dist_targ = 0;
|
static_cast<glm::vec3>(center_mob->GetPosition());
|
||||||
|
|
||||||
const auto &position = spells[spell_id].targettype == ST_Ring ? caster->GetTargetRingLocation() : static_cast<glm::vec3>(center->GetPosition());
|
/**
|
||||||
glm::vec2 min = { position.x - dist, position.y - dist };
|
* If using Old Rain Targets - there is no max target limitation
|
||||||
glm::vec2 max = { position.x + dist, position.y + dist };
|
*/
|
||||||
|
if (RuleB(Spells, OldRainTargets)) {
|
||||||
|
max_targets = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool bad = IsDetrimentalSpell(spell_id);
|
/**
|
||||||
bool isnpc = caster->IsNPC();
|
* Max AOE targets
|
||||||
|
*/
|
||||||
if (RuleB(Spells, OldRainTargets))
|
|
||||||
max_targets = nullptr; // ignore it!
|
|
||||||
|
|
||||||
// if we have a passed in value, use it, otherwise default to data
|
|
||||||
// detrimental Target AEs have a default value of 4 for PCs and unlimited for NPCs
|
|
||||||
int max_targets_allowed = 0; // unlimited
|
int max_targets_allowed = 0; // unlimited
|
||||||
if (max_targets) // rains pass this in since they need to preserve the count through waves
|
if (max_targets) { // rains pass this in since they need to preserve the count through waves
|
||||||
max_targets_allowed = *max_targets;
|
max_targets_allowed = *max_targets;
|
||||||
else if (spells[spell_id].aemaxtargets)
|
}
|
||||||
|
else if (spells[spell_id].aemaxtargets) {
|
||||||
max_targets_allowed = spells[spell_id].aemaxtargets;
|
max_targets_allowed = spells[spell_id].aemaxtargets;
|
||||||
else if (IsTargetableAESpell(spell_id) && bad && !isnpc)
|
}
|
||||||
|
else if (IsTargetableAESpell(spell_id) && is_detrimental_spell && !is_npc) {
|
||||||
max_targets_allowed = 4;
|
max_targets_allowed = 4;
|
||||||
|
}
|
||||||
|
|
||||||
int iCounter = 0;
|
int target_hit_counter = 0;
|
||||||
|
float distance_to_target = 0;
|
||||||
|
|
||||||
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
|
for (auto &it : caster_mob->close_mobs) {
|
||||||
curmob = it->second;
|
current_mob = it.first;
|
||||||
// test to fix possible cause of random zone crashes..external methods accessing client properties before they're initialized
|
|
||||||
if (curmob->IsClient() && !curmob->CastToClient()->ClientFinishedLoading())
|
|
||||||
continue;
|
|
||||||
if (curmob == caster && !affect_caster) //watch for caster too
|
|
||||||
continue;
|
|
||||||
if (spells[spell_id].targettype == ST_TargetAENoPlayersPets && curmob->IsPetOwnerClient())
|
|
||||||
continue;
|
|
||||||
if (spells[spell_id].targettype == ST_AreaClientOnly && !curmob->IsClient())
|
|
||||||
continue;
|
|
||||||
if (spells[spell_id].targettype == ST_AreaNPCOnly && !curmob->IsNPC())
|
|
||||||
continue;
|
|
||||||
// check PC/NPC only flag 1 = PCs, 2 = NPCs
|
|
||||||
if (spells[spell_id].pcnpc_only_flag == 1 && !curmob->IsClient() && !curmob->IsMerc())
|
|
||||||
continue;
|
|
||||||
if (spells[spell_id].pcnpc_only_flag == 2 && (curmob->IsClient() || curmob->IsMerc()))
|
|
||||||
continue;
|
|
||||||
if (!IsWithinAxisAlignedBox(static_cast<glm::vec2>(curmob->GetPosition()), min, max))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
dist_targ = DistanceSquared(curmob->GetPosition(), position);
|
if (!current_mob) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (dist_targ > dist2) //make sure they are in range
|
LogDebug("iterating [{}]", current_mob->GetCleanName());
|
||||||
|
|
||||||
|
if (!AESpellFilterCriteria(
|
||||||
|
current_mob,
|
||||||
|
caster_mob,
|
||||||
|
center_mob,
|
||||||
|
spell_id,
|
||||||
|
max_targets,
|
||||||
|
max_targets_allowed,
|
||||||
|
target_hit_counter,
|
||||||
|
distance_to_target,
|
||||||
|
cast_target_position,
|
||||||
|
affect_caster,
|
||||||
|
resist_adjust
|
||||||
|
)) {
|
||||||
continue;
|
continue;
|
||||||
if (dist_targ < min_range2) //make sure they are in range
|
}
|
||||||
continue;
|
|
||||||
if (isnpc && curmob->IsNPC() && spells[spell_id].targettype != ST_AreaNPCOnly) { //check npc->npc casting
|
current_mob->CalcSpellPowerDistanceMod(spell_id, distance_to_target);
|
||||||
FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
|
caster_mob->SpellOnTarget(spell_id, current_mob, false, true, resist_adjust);
|
||||||
if (bad) {
|
}
|
||||||
//affect mobs that are on our hate list, or
|
|
||||||
//which have bad faction with us
|
LogDebug("Done iterating [{}]", caster_mob->GetCleanName());
|
||||||
if (!(caster->CheckAggro(curmob) || f == FACTION_THREATENLY || f == FACTION_SCOWLS) )
|
|
||||||
continue;
|
if (max_targets && max_targets_allowed) {
|
||||||
} else {
|
*max_targets = *max_targets - target_hit_counter;
|
||||||
//only affect mobs we would assist.
|
}
|
||||||
if (!(f <= FACTION_AMIABLE))
|
}
|
||||||
continue;
|
|
||||||
|
/**
|
||||||
|
* @param caster_mob
|
||||||
|
* @param center_mob
|
||||||
|
* @param spell_id
|
||||||
|
* @param affect_caster
|
||||||
|
* @param resist_adjust
|
||||||
|
* @param max_targets
|
||||||
|
*/
|
||||||
|
bool EntityList::AESpellFilterCriteria(
|
||||||
|
Mob *current_mob,
|
||||||
|
Mob *caster_mob,
|
||||||
|
Mob *center_mob,
|
||||||
|
uint16 spell_id,
|
||||||
|
int *max_targets,
|
||||||
|
int &max_targets_allowed,
|
||||||
|
int &target_hit_counter,
|
||||||
|
float &distance_to_target,
|
||||||
|
const glm::vec3 &cast_target_position,
|
||||||
|
bool affect_caster,
|
||||||
|
int16 resist_adjust
|
||||||
|
) {
|
||||||
|
|
||||||
|
if (!current_mob) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_npc = caster_mob->IsNPC();
|
||||||
|
float distance = caster_mob->GetAOERange(spell_id);
|
||||||
|
float distance_squared = distance * distance;
|
||||||
|
float min_range2 = spells[spell_id].min_range * spells[spell_id].min_range;
|
||||||
|
bool is_detrimental_spell = IsDetrimentalSpell(spell_id);
|
||||||
|
glm::vec2 min = {cast_target_position.x - distance, cast_target_position.y - distance};
|
||||||
|
glm::vec2 max = {cast_target_position.x + distance, cast_target_position.y + distance};
|
||||||
|
|
||||||
|
if (current_mob->IsClient() && !current_mob->CastToClient()->ClientFinishedLoading()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_mob == caster_mob && !affect_caster) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spells[spell_id].targettype == ST_TargetAENoPlayersPets && current_mob->IsPetOwnerClient()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spells[spell_id].targettype == ST_AreaClientOnly && !current_mob->IsClient()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spells[spell_id].targettype == ST_AreaNPCOnly && !current_mob->IsNPC()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check PC / NPC
|
||||||
|
* 1 = PC
|
||||||
|
* 2 = NPC
|
||||||
|
*/
|
||||||
|
if (spells[spell_id].pcnpc_only_flag == 1 && !current_mob->IsClient() && !current_mob->IsMerc()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spells[spell_id].pcnpc_only_flag == 2 && (current_mob->IsClient() || current_mob->IsMerc())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsWithinAxisAlignedBox(static_cast<glm::vec2>(current_mob->GetPosition()), min, max)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
distance_to_target = DistanceSquared(current_mob->GetPosition(), cast_target_position);
|
||||||
|
|
||||||
|
if (distance_to_target > distance_squared) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (distance_to_target < min_range2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_npc && current_mob->IsNPC() &&
|
||||||
|
spells[spell_id].targettype != ST_AreaNPCOnly) { //check npc->npc casting
|
||||||
|
FACTION_VALUE faction_value = current_mob->GetReverseFactionCon(caster_mob);
|
||||||
|
if (is_detrimental_spell) {
|
||||||
|
//affect mobs that are on our hate list, or
|
||||||
|
//which have bad faction with us
|
||||||
|
if (
|
||||||
|
!(caster_mob->CheckAggro(current_mob) ||
|
||||||
|
faction_value == FACTION_THREATENLY ||
|
||||||
|
faction_value == FACTION_SCOWLS)) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//finally, make sure they are within range
|
else {
|
||||||
if (bad) {
|
//only affect mobs we would assist.
|
||||||
if (!caster->IsAttackAllowed(curmob, true))
|
if (!(faction_value <= FACTION_AMIABLE)) {
|
||||||
continue;
|
return false;
|
||||||
if (center && !spells[spell_id].npc_no_los && !center->CheckLosFN(curmob))
|
}
|
||||||
continue;
|
|
||||||
if (!center && !spells[spell_id].npc_no_los && !caster->CheckLosFN(caster->GetTargetRingX(), caster->GetTargetRingY(), caster->GetTargetRingZ(), curmob->GetSize()))
|
|
||||||
continue;
|
|
||||||
} else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
|
|
||||||
// This does not check faction for beneficial AE buffs..only agro and attackable.
|
|
||||||
// I've tested for spells that I can find without problem, but a faction-based
|
|
||||||
// check may still be needed. Any changes here should also reflect in BardAEPulse()
|
|
||||||
if (caster->IsAttackAllowed(curmob, true))
|
|
||||||
continue;
|
|
||||||
if (caster->CheckAggro(curmob))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
curmob->CalcSpellPowerDistanceMod(spell_id, dist_targ);
|
|
||||||
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
|
|
||||||
|
|
||||||
if (max_targets_allowed) { // if we have a limit, increment count
|
|
||||||
iCounter++;
|
|
||||||
if (iCounter >= max_targets_allowed) // we done
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_targets && max_targets_allowed)
|
/**
|
||||||
*max_targets = *max_targets - iCounter;
|
* Finally, make sure they are within range
|
||||||
|
*/
|
||||||
|
if (is_detrimental_spell) {
|
||||||
|
if (!caster_mob->IsAttackAllowed(current_mob, true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (center_mob && !spells[spell_id].npc_no_los && !center_mob->CheckLosFN(current_mob)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!center_mob && !spells[spell_id].npc_no_los && !caster_mob->CheckLosFN(
|
||||||
|
caster_mob->GetTargetRingX(),
|
||||||
|
caster_mob->GetTargetRingY(),
|
||||||
|
caster_mob->GetTargetRingZ(),
|
||||||
|
current_mob->GetSize())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
|
||||||
|
* This does not check faction for beneficial AE buffs... only agro and attackable.
|
||||||
|
* I've tested for spells that I can find without problem, but a faction-based
|
||||||
|
* check may still be needed. Any changes here should also reflect in BardAEPulse()
|
||||||
|
*/
|
||||||
|
if (caster_mob->IsAttackAllowed(current_mob, true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (caster_mob->CheckAggro(current_mob)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment hit count if max targets
|
||||||
|
*/
|
||||||
|
if (max_targets_allowed) {
|
||||||
|
target_hit_counter++;
|
||||||
|
if (target_hit_counter >= max_targets_allowed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
|
void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
|
||||||
@ -812,8 +943,8 @@ void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool a
|
|||||||
|
|
||||||
bool bad = IsDetrimentalSpell(spell_id);
|
bool bad = IsDetrimentalSpell(spell_id);
|
||||||
|
|
||||||
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
|
for (auto & it : mob_list) {
|
||||||
curmob = it->second;
|
curmob = it.second;
|
||||||
if (curmob == center) //do not affect center
|
if (curmob == center) //do not affect center
|
||||||
continue;
|
continue;
|
||||||
if (curmob == caster && !affect_caster) //watch for caster too
|
if (curmob == caster && !affect_caster) //watch for caster too
|
||||||
|
|||||||
@ -2486,30 +2486,41 @@ void EntityList::RemoveAllEncounters()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param delete_id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
bool EntityList::RemoveMob(uint16 delete_id)
|
bool EntityList::RemoveMob(uint16 delete_id)
|
||||||
{
|
{
|
||||||
if (delete_id == 0)
|
if (delete_id == 0) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
auto it = mob_list.find(delete_id);
|
auto it = mob_list.find(delete_id);
|
||||||
if (it != mob_list.end()) {
|
if (it != mob_list.end()) {
|
||||||
|
|
||||||
RemoveMobFromCloseLists(it->second);
|
RemoveMobFromCloseLists(it->second);
|
||||||
|
|
||||||
if (npc_list.count(delete_id))
|
if (npc_list.count(delete_id)) {
|
||||||
entity_list.RemoveNPC(delete_id);
|
entity_list.RemoveNPC(delete_id);
|
||||||
else if (client_list.count(delete_id))
|
}
|
||||||
|
else if (client_list.count(delete_id)) {
|
||||||
entity_list.RemoveClient(delete_id);
|
entity_list.RemoveClient(delete_id);
|
||||||
|
}
|
||||||
safe_delete(it->second);
|
safe_delete(it->second);
|
||||||
if (!corpse_list.count(delete_id))
|
if (!corpse_list.count(delete_id)) {
|
||||||
free_ids.push(it->first);
|
free_ids.push(it->first);
|
||||||
|
}
|
||||||
mob_list.erase(it);
|
mob_list.erase(it);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is for if the ID is deleted for some reason
|
/**
|
||||||
|
* @param delete_mob
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
bool EntityList::RemoveMob(Mob *delete_mob)
|
bool EntityList::RemoveMob(Mob *delete_mob)
|
||||||
{
|
{
|
||||||
if (delete_mob == 0) {
|
if (delete_mob == 0) {
|
||||||
@ -2533,19 +2544,19 @@ bool EntityList::RemoveMob(Mob *delete_mob)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param delete_id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
bool EntityList::RemoveNPC(uint16 delete_id)
|
bool EntityList::RemoveNPC(uint16 delete_id)
|
||||||
{
|
{
|
||||||
auto it = npc_list.find(delete_id);
|
auto it = npc_list.find(delete_id);
|
||||||
if (it != npc_list.end()) {
|
if (it != npc_list.end()) {
|
||||||
NPC *npc = it->second;
|
NPC *npc = it->second;
|
||||||
// make sure its proximity is removed
|
|
||||||
RemoveProximity(delete_id);
|
RemoveProximity(delete_id);
|
||||||
// remove from client close lists
|
|
||||||
RemoveMobFromCloseLists(npc->CastToMob());
|
RemoveMobFromCloseLists(npc->CastToMob());
|
||||||
// remove from the list
|
|
||||||
npc_list.erase(it);
|
npc_list.erase(it);
|
||||||
|
|
||||||
// remove from limit list if needed
|
|
||||||
if (npc_limit_list.count(delete_id)) {
|
if (npc_limit_list.count(delete_id)) {
|
||||||
npc_limit_list.erase(delete_id);
|
npc_limit_list.erase(delete_id);
|
||||||
}
|
}
|
||||||
@ -2561,11 +2572,14 @@ bool EntityList::RemoveNPC(uint16 delete_id)
|
|||||||
*/
|
*/
|
||||||
bool EntityList::RemoveMobFromCloseLists(Mob *mob)
|
bool EntityList::RemoveMobFromCloseLists(Mob *mob)
|
||||||
{
|
{
|
||||||
|
LogDebug("Removing mob [{}] from close lists", mob->GetCleanName());
|
||||||
|
|
||||||
auto it = mob_list.begin();
|
auto it = mob_list.begin();
|
||||||
while (it != mob_list.end()) {
|
while (it != mob_list.end()) {
|
||||||
it->second->close_mobs.erase(mob);
|
it->second->close_mobs.erase(mob);
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -388,11 +388,37 @@ public:
|
|||||||
void QueueToGroupsForNPCHealthAA(Mob* sender, const EQApplicationPacket* app);
|
void QueueToGroupsForNPCHealthAA(Mob* sender, const EQApplicationPacket* app);
|
||||||
void QueueManaged(Mob* sender, const EQApplicationPacket* app, bool ignore_sender=false, bool ackreq = true);
|
void QueueManaged(Mob* sender, const EQApplicationPacket* app, bool ignore_sender=false, bool ackreq = true);
|
||||||
|
|
||||||
void AEAttack(Mob *attacker, float dist, int Hand = EQEmu::invslot::slotPrimary, int count = 0, bool IsFromSpell = false);
|
void AEAttack(
|
||||||
void AETaunt(Client *caster, float range=0, int32 bonus_hate=0);
|
Mob *attacker,
|
||||||
void AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true, int16 resist_adjust = 0, int *max_targets = nullptr);
|
float dist,
|
||||||
void MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true);
|
int Hand = EQEmu::invslot::slotPrimary,
|
||||||
void AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true);
|
int count = 0,
|
||||||
|
bool IsFromSpell = false
|
||||||
|
);
|
||||||
|
void AETaunt(Client *caster, float range = 0, int32 bonus_hate = 0);
|
||||||
|
void AESpell(
|
||||||
|
Mob *caster,
|
||||||
|
Mob *center,
|
||||||
|
uint16 spell_id,
|
||||||
|
bool affect_caster = true,
|
||||||
|
int16 resist_adjust = 0,
|
||||||
|
int *max_targets = nullptr
|
||||||
|
);
|
||||||
|
static bool AESpellFilterCriteria(
|
||||||
|
Mob *current_mob,
|
||||||
|
Mob *caster_mob,
|
||||||
|
Mob *center_mob,
|
||||||
|
uint16 spell_id,
|
||||||
|
int *max_targets,
|
||||||
|
int &max_targets_allowed,
|
||||||
|
int &target_hit_counter,
|
||||||
|
float &distance_to_target,
|
||||||
|
const glm::vec3 &cast_target_position,
|
||||||
|
bool affect_caster = true,
|
||||||
|
int16 resist_adjust = 0
|
||||||
|
);
|
||||||
|
void MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true);
|
||||||
|
void AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true);
|
||||||
|
|
||||||
//trap stuff
|
//trap stuff
|
||||||
Mob* GetTrapTrigger(Trap* trap);
|
Mob* GetTrapTrigger(Trap* trap);
|
||||||
|
|||||||
@ -4793,24 +4793,32 @@ int16 Mob::CalcFearResistChance()
|
|||||||
return resistchance;
|
return resistchance;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Mob::GetAOERange(uint16 spell_id) {
|
/**
|
||||||
float range;
|
* @param spell_id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
float Mob::GetAOERange(uint16 spell_id)
|
||||||
|
{
|
||||||
|
float range = spells[spell_id].aoerange;
|
||||||
|
|
||||||
range = spells[spell_id].aoerange;
|
/**
|
||||||
if(range == 0) //for TGB spells, they prolly do not have an aoe range
|
* For TGB
|
||||||
|
*/
|
||||||
|
if (range == 0) {
|
||||||
range = spells[spell_id].range;
|
range = spells[spell_id].range;
|
||||||
if(range == 0)
|
|
||||||
range = 10; //something....
|
|
||||||
|
|
||||||
if(IsBardSong(spell_id) && IsBeneficialSpell(spell_id)) {
|
|
||||||
//Live AA - Extended Notes, SionachiesCrescendo
|
|
||||||
float song_bonus = static_cast<float>(aabonuses.SongRange + spellbonuses.SongRange + itembonuses.SongRange);
|
|
||||||
range += range*song_bonus /100.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
range = GetActSpellRange(spell_id, range);
|
if (range == 0) {
|
||||||
|
range = 10;
|
||||||
|
}
|
||||||
|
|
||||||
return(range);
|
if (IsBardSong(spell_id) && IsBeneficialSpell(spell_id)) {
|
||||||
|
//Live AA - Extended Notes, SionachiesCrescendo
|
||||||
|
float song_bonus = static_cast<float>(aabonuses.SongRange + spellbonuses.SongRange + itembonuses.SongRange);
|
||||||
|
range += range * song_bonus / 100.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetActSpellRange(spell_id, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -1997,7 +1997,6 @@ const char *Zone::GetSpellBlockedMessage(uint32 spell_id, const glm::vec3 &locat
|
|||||||
if (spell_id != blocked_spells[x].spellid && blocked_spells[x].spellid != 0) {
|
if (spell_id != blocked_spells[x].spellid && blocked_spells[x].spellid != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (blocked_spells[x].type) {
|
switch (blocked_spells[x].type) {
|
||||||
case ZoneBlockedSpellTypes::ZoneWide: {
|
case ZoneBlockedSpellTypes::ZoneWide: {
|
||||||
return blocked_spells[x].message;
|
return blocked_spells[x].message;
|
||||||
@ -2033,21 +2032,21 @@ void Zone::SetInstanceTimer(uint32 new_duration)
|
|||||||
|
|
||||||
void Zone::LoadLDoNTraps()
|
void Zone::LoadLDoNTraps()
|
||||||
{
|
{
|
||||||
const std::string query = "SELECT id, type, spell_id, skill, locked FROM ldon_trap_templates";
|
const std::string query = "SELECT id, type, spell_id, skill, locked FROM ldon_trap_templates";
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto row = results.begin();row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
auto lt = new LDoNTrapTemplate;
|
auto lt = new LDoNTrapTemplate;
|
||||||
lt->id = atoi(row[0]);
|
lt->id = atoi(row[0]);
|
||||||
lt->type = (LDoNChestTypes)atoi(row[1]);
|
lt->type = (LDoNChestTypes) atoi(row[1]);
|
||||||
lt->spell_id = atoi(row[2]);
|
lt->spell_id = atoi(row[2]);
|
||||||
lt->skill = atoi(row[3]);
|
lt->skill = atoi(row[3]);
|
||||||
lt->locked = atoi(row[4]);
|
lt->locked = atoi(row[4]);
|
||||||
ldon_trap_list[lt->id] = lt;
|
ldon_trap_list[lt->id] = lt;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user