mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-24 09:28:21 +00:00
Correct DoLosChecks
This commit is contained in:
+10
-7
@@ -2272,7 +2272,6 @@ void Bot::AI_Process()
|
|||||||
|
|
||||||
// This causes conflicts with default pet handler (bounces between targets)
|
// This causes conflicts with default pet handler (bounces between targets)
|
||||||
if (NOT_PULLING_BOT && HasPet() && (GetClass() != Class::Enchanter || GetPet()->GetPetType() != petAnimation || GetAA(aaAnimationEmpathy) >= 2)) {
|
if (NOT_PULLING_BOT && HasPet() && (GetClass() != Class::Enchanter || GetPet()->GetPetType() != petAnimation || GetAA(aaAnimationEmpathy) >= 2)) {
|
||||||
|
|
||||||
// We don't add to hate list here because it's assumed to already be on the list
|
// We don't add to hate list here because it's assumed to already be on the list
|
||||||
GetPet()->SetTarget(tar);
|
GetPet()->SetTarget(tar);
|
||||||
}
|
}
|
||||||
@@ -2316,7 +2315,7 @@ void Bot::AI_Process()
|
|||||||
if (GetPullingFlag()) {
|
if (GetPullingFlag()) {
|
||||||
if (!TargetValidation(tar)) { return; }
|
if (!TargetValidation(tar)) { return; }
|
||||||
|
|
||||||
if (!DoLosChecks(this, tar)) {
|
if (!DoLosChecks(tar)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3196,7 +3195,7 @@ bool Bot::IsValidTarget(
|
|||||||
(!Charmed() && tar->GetUltimateOwner()->IsOfClientBotMerc()) ||
|
(!Charmed() && tar->GetUltimateOwner()->IsOfClientBotMerc()) ||
|
||||||
lo_distance > leash_distance ||
|
lo_distance > leash_distance ||
|
||||||
tar_distance > leash_distance ||
|
tar_distance > leash_distance ||
|
||||||
(!GetAttackingFlag() && !CheckLosCheat(this, tar) && !CheckLosCheat(leash_owner, tar)) ||
|
(!GetAttackingFlag() && !CheckLosCheat(tar) && !leash_owner->CheckLosCheat(tar)) ||
|
||||||
!IsAttackAllowed(tar)
|
!IsAttackAllowed(tar)
|
||||||
) {
|
) {
|
||||||
invalid_target_state = true;
|
invalid_target_state = true;
|
||||||
@@ -9382,6 +9381,10 @@ void Bot::DoItemClick(const EQ::ItemData *item, uint16 slot_id)
|
|||||||
bool is_casting_bard_song = false;
|
bool is_casting_bard_song = false;
|
||||||
Mob* tar = (GetOwner()->GetTarget() ? GetOwner()->GetTarget() : this);
|
Mob* tar = (GetOwner()->GetTarget() ? GetOwner()->GetTarget() : this);
|
||||||
|
|
||||||
|
if (!DoLosChecks(tar)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (IsCasting()) {
|
if (IsCasting()) {
|
||||||
InterruptSpell();
|
InterruptSpell();
|
||||||
}
|
}
|
||||||
@@ -10252,7 +10255,7 @@ bool Bot::IsValidMezTarget(Mob* owner, Mob* npc, uint16 spell_id) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DoLosChecks(this, npc)) {
|
if (!DoLosChecks(npc)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11084,7 +11087,7 @@ bool Bot::AttemptAACastSpell(Mob* tar, uint16 spell_id, AA::Rank* rank) {
|
|||||||
tar = this;
|
tar = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DoLosChecks(this, tar)) {
|
if (!DoLosChecks(tar)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11219,7 +11222,7 @@ bool Bot::AttemptForcedCastSpell(Mob* tar, uint16 spell_id, bool is_disc) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DoLosChecks(this, tar)) {
|
if (!DoLosChecks(tar)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11712,7 +11715,7 @@ bool Bot::HasRequiredLoSForPositioning(Mob* tar) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RequiresLoSForPositioning() && !DoLosChecks(this, tar)) {
|
if (RequiresLoSForPositioning() && !DoLosChecks(tar)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -803,7 +803,7 @@ void helper_send_usage_required_bots(Client *bot_owner, uint16 spell_type)
|
|||||||
auto& spell_map = bot->GetCommandedSpellTypesMinLevels();
|
auto& spell_map = bot->GetCommandedSpellTypesMinLevels();
|
||||||
|
|
||||||
if (spell_map.empty()) {
|
if (spell_map.empty()) {
|
||||||
bot_owner->Message(Chat::Yellow, "No bots are capable of casting this spell type"); //deleteme
|
bot_owner->Message(Chat::Yellow, "No bots are capable of casting this spell type");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,12 @@ void bot_command_attack(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
if (!target_mob) {
|
if (!target_mob) {
|
||||||
|
|
||||||
c->Message(Chat::White, "You must <target> an enemy to use this command");
|
c->Message(Chat::Yellow, "You must <target> an enemy to use this command");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!c->DoLosChecks(target_mob)) {
|
||||||
|
c->Message(Chat::Red, "You must have Line of Sight to use this command.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +76,7 @@ void bot_command_attack(Client *c, const Seperator *sep)
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
c->Message(
|
c->Message(
|
||||||
Chat::White,
|
Chat::PetResponse,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} of your bots are attacking {}.",
|
"{} of your bots are attacking {}.",
|
||||||
sbl.size(),
|
sbl.size(),
|
||||||
|
|||||||
@@ -47,11 +47,22 @@ void bot_command_click_item(Client* c, const Seperator* sep)
|
|||||||
|
|
||||||
sbl.erase(std::remove(sbl.begin(), sbl.end(), nullptr), sbl.end());
|
sbl.erase(std::remove(sbl.begin(), sbl.end(), nullptr), sbl.end());
|
||||||
|
|
||||||
|
Mob* tar = c->GetTarget();
|
||||||
|
|
||||||
for (auto my_bot : sbl) {
|
for (auto my_bot : sbl) {
|
||||||
if (my_bot->BotPassiveCheck()) {
|
if (my_bot->BotPassiveCheck()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
tar &&
|
||||||
|
tar != c &&
|
||||||
|
tar->GetOwner() != c &&
|
||||||
|
!c->DoLosChecks(tar)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (RuleI(Bots, BotsClickItemsMinLvl) > my_bot->GetLevel()) {
|
if (RuleI(Bots, BotsClickItemsMinLvl) > my_bot->GetLevel()) {
|
||||||
c->Message(Chat::White, "%s must be level %i to use clickable items.", my_bot->GetCleanName(), RuleI(Bots, BotsClickItemsMinLvl));
|
c->Message(Chat::White, "%s must be level %i to use clickable items.", my_bot->GetCleanName(), RuleI(Bots, BotsClickItemsMinLvl));
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -5,15 +5,22 @@ void bot_command_precombat(Client* c, const Seperator* sep)
|
|||||||
if (helper_command_alias_fail(c, "bot_command_precombat", sep->arg[0], "precombat")) {
|
if (helper_command_alias_fail(c, "bot_command_precombat", sep->arg[0], "precombat")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
|
||||||
|
|
||||||
|
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||||
c->Message(Chat::White, "usage: %s ([set | clear])", sep->arg[0]);
|
c->Message(Chat::White, "usage: %s ([set | clear])", sep->arg[0]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!c->GetTarget() || !c->IsAttackAllowed(c->GetTarget())) {
|
if (!c->GetTarget() || !c->IsAttackAllowed(c->GetTarget())) {
|
||||||
|
|
||||||
c->Message(Chat::White, "This command requires an attackable target.");
|
c->Message(Chat::White, "This command requires an attackable target.");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!c->DoLosChecks(c->GetTarget())) {
|
||||||
|
c->Message(Chat::Red, "You must have Line of Sight to use this command.");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,12 @@ void bot_command_pull(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!c->DoLosChecks(target_mob)) {
|
||||||
|
c->Message(Chat::Red, "You must have Line of Sight to use this command.");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (target_mob->IsNPC() && target_mob->GetHateList().size()) {
|
if (target_mob->IsNPC() && target_mob->GetHateList().size()) {
|
||||||
|
|
||||||
c->Message(Chat::White, "Your current target is already engaged!");
|
c->Message(Chat::White, "Your current target is already engaged!");
|
||||||
@@ -55,8 +61,8 @@ void bot_command_pull(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Bot* bot_puller = nullptr;
|
Bot* bot_puller = nullptr;
|
||||||
for (auto bot_iter : sbl) {
|
|
||||||
|
|
||||||
|
for (auto bot_iter : sbl) {
|
||||||
if (bot_iter->GetAppearance() == eaDead || bot_iter->GetBotStance() == Stance::Passive) {
|
if (bot_iter->GetAppearance() == eaDead || bot_iter->GetBotStance() == Stance::Passive) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 chance, uint16 spell_type, uint16 sub_targ
|
|||||||
bot_spell.ManaCost = 0;
|
bot_spell.ManaCost = 0;
|
||||||
|
|
||||||
if (BotSpellTypeRequiresLoS(spell_type) && tar != this) {
|
if (BotSpellTypeRequiresLoS(spell_type) && tar != this) {
|
||||||
SetHasLoS(DoLosChecks(this, tar));
|
SetHasLoS(DoLosChecks(tar));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SetHasLoS(true);
|
SetHasLoS(true);
|
||||||
|
|||||||
+15
-1
@@ -11091,10 +11091,17 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
case PET_ATTACK: {
|
case PET_ATTACK: {
|
||||||
if (!target)
|
if (!target)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (!DoLosChecks(target)) {
|
||||||
|
mypet->SayString(this, NOT_LEGAL_TARGET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (target->IsMezzed()) {
|
if (target->IsMezzed()) {
|
||||||
MessageString(Chat::NPCQuestSay, CANNOT_WAKE, mypet->GetCleanName(), target->GetCleanName());
|
MessageString(Chat::NPCQuestSay, CANNOT_WAKE, mypet->GetCleanName(), target->GetCleanName());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mypet->IsFeared())
|
if (mypet->IsFeared())
|
||||||
break; //prevent pet from attacking stuff while feared
|
break; //prevent pet from attacking stuff while feared
|
||||||
|
|
||||||
@@ -11149,8 +11156,15 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
if (mypet->IsFeared())
|
if (mypet->IsFeared())
|
||||||
break; //prevent pet from attacking stuff while feared
|
break; //prevent pet from attacking stuff while feared
|
||||||
|
|
||||||
if (!GetTarget())
|
if (!GetTarget()) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DoLosChecks(GetTarget())) {
|
||||||
|
mypet->SayString(this, NOT_LEGAL_TARGET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetTarget()->IsMezzed()) {
|
if (GetTarget()->IsMezzed()) {
|
||||||
MessageString(Chat::NPCQuestSay, CANNOT_WAKE, mypet->GetCleanName(), GetTarget()->GetCleanName());
|
MessageString(Chat::NPCQuestSay, CANNOT_WAKE, mypet->GetCleanName(), GetTarget()->GetCleanName());
|
||||||
break;
|
break;
|
||||||
|
|||||||
+42
-17
@@ -8679,31 +8679,52 @@ bool Mob::IsInGroupOrRaid(Mob* other, bool same_raid_group) {
|
|||||||
return group && group == other_group;
|
return group && group == other_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::DoLosChecks(Mob* who, Mob* other) {
|
bool Mob::DoLosChecks(Mob* other) {
|
||||||
if (!who->CheckLosFN(other) || !who->CheckWaterLoS(other)) {
|
if (!CheckLosFN(other) || !CheckWaterLoS(other)) {
|
||||||
if (who->CheckLosCheatExempt(who, other)) {
|
if (CheckLosCheatExempt(other)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
if (CheckLosCheat(who, other)) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!CheckLosCheat(other)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::CheckLosCheat(Mob* who, Mob* other) {
|
bool Mob::CheckLosCheat(Mob* other) {
|
||||||
if (RuleB(Map, CheckForLoSCheat)) {
|
if (RuleB(Map, CheckForLoSCheat)) {
|
||||||
for (auto itr : entity_list.GetDoorsList()) {
|
for (auto itr : entity_list.GetDoorsList()) {
|
||||||
Doors* d = itr.second;
|
Doors* d = itr.second;
|
||||||
if (d && !d->IsDoorOpen() && (d->GetTriggerType() == 255 || d->GetLockpick() != 0 || d->GetKeyItem() != 0 || d->GetNoKeyring() != 0)) {
|
|
||||||
if (DistanceNoZ(who->GetPosition(), d->GetPosition()) <= 50) {
|
if (
|
||||||
auto who_to_door = DistanceNoZ(who->GetPosition(), d->GetPosition());
|
!d->IsDoorOpen() &&
|
||||||
|
(
|
||||||
|
d->GetKeyItem() ||
|
||||||
|
d->GetLockpick() ||
|
||||||
|
d->IsDoorOpen() ||
|
||||||
|
d->IsDoorBlacklisted() ||
|
||||||
|
d->GetNoKeyring() != 0 ||
|
||||||
|
d->GetDoorParam() > 0
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
// If the door is a trigger door, check if the trigger door is open
|
||||||
|
if (d->GetTriggerDoorID() > 0) {
|
||||||
|
auto td = entity_list.GetDoorsByDoorID(d->GetTriggerDoorID());
|
||||||
|
|
||||||
|
if (td) {
|
||||||
|
if (Strings::RemoveNumbers(d->GetDoorName()) != Strings::RemoveNumbers(td->GetDoorName())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DistanceNoZ(GetPosition(), d->GetPosition()) <= 50) {
|
||||||
|
auto who_to_door = DistanceNoZ(GetPosition(), d->GetPosition());
|
||||||
auto other_to_door = DistanceNoZ(other->GetPosition(), d->GetPosition());
|
auto other_to_door = DistanceNoZ(other->GetPosition(), d->GetPosition());
|
||||||
auto who_to_other = DistanceNoZ(who->GetPosition(), other->GetPosition());
|
auto who_to_other = DistanceNoZ(GetPosition(), other->GetPosition());
|
||||||
auto distance_difference = who_to_other - (who_to_door + other_to_door);
|
auto distance_difference = who_to_other - (who_to_door + other_to_door);
|
||||||
|
|
||||||
if (distance_difference >= (-1 * RuleR(Maps, RangeCheckForLoSCheat)) && distance_difference <= RuleR(Maps, RangeCheckForLoSCheat)) {
|
if (distance_difference >= (-1 * RuleR(Maps, RangeCheckForLoSCheat)) && distance_difference <= RuleR(Maps, RangeCheckForLoSCheat)) {
|
||||||
@@ -8717,19 +8738,23 @@ bool Mob::CheckLosCheat(Mob* who, Mob* other) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::CheckLosCheatExempt(Mob* who, Mob* other) {
|
bool Mob::CheckLosCheatExempt(Mob* other) {
|
||||||
if (RuleB(Map, EnableLoSCheatExemptions)) {
|
if (RuleB(Map, EnableLoSCheatExemptions)) {
|
||||||
|
/* This is an exmaple of how to configure exemptions for LoS checks.
|
||||||
glm::vec4 exempt_check_who;
|
glm::vec4 exempt_check_who;
|
||||||
glm::vec4 exempt_check_other;
|
glm::vec4 exempt_check_other;
|
||||||
/* This is an exmaple of how to configure exemptions for LoS checks.
|
|
||||||
if (zone->GetZoneID() == 222) { //PoEarthB
|
switch (zone->GetZoneID()) {
|
||||||
|
case POEARTHB:
|
||||||
exempt_check_who.x = 2051; exempt_check_who.y = 407; exempt_check_who.z = -219; //Middle of councilman spawns
|
exempt_check_who.x = 2051; exempt_check_who.y = 407; exempt_check_who.z = -219; //Middle of councilman spawns
|
||||||
//check to be sure the player and the target are in the pit to PoEarthB
|
//exempt_check_other.x = 1455; exempt_check_other.y = 415; exempt_check_other.z = -242;
|
||||||
|
//check to be sure the player and the target are outside of the councilman area
|
||||||
//if the player is inside the cove they cannot be higher than the ceiling (no exploiting from uptop)
|
//if the player is inside the cove they cannot be higher than the ceiling (no exploiting from uptop)
|
||||||
//otherwise they can pass LoS checks even if they don't have true LoS
|
if (GetZ() <= -171 && other->GetZ() <= -171 && DistanceNoZ(other->GetPosition(), exempt_check_who) <= 800 && DistanceNoZ(GetPosition(), exempt_check_who) <= 800) {
|
||||||
if (who->GetZ() <= -171 && other->GetZ() <= -171 && DistanceNoZ(other->GetPosition(), exempt_check_who) <= 800 && DistanceNoZ(who->GetPosition(), exempt_check_who) <= 800) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -872,9 +872,9 @@ public:
|
|||||||
static bool CheckLosFN(glm::vec3 posWatcher, float sizeWatcher, glm::vec3 posTarget, float sizeTarget);
|
static bool CheckLosFN(glm::vec3 posWatcher, float sizeWatcher, glm::vec3 posTarget, float sizeTarget);
|
||||||
virtual bool CheckWaterLoS(Mob* m);
|
virtual bool CheckWaterLoS(Mob* m);
|
||||||
bool CheckPositioningLosFN(Mob* other, float posX, float posY, float posZ);
|
bool CheckPositioningLosFN(Mob* other, float posX, float posY, float posZ);
|
||||||
bool CheckLosCheat(Mob* who, Mob* other);
|
bool CheckLosCheat(Mob* other);
|
||||||
bool CheckLosCheatExempt(Mob* who, Mob* other);
|
bool CheckLosCheatExempt(Mob* other);
|
||||||
bool DoLosChecks(Mob* who, Mob* other);
|
bool DoLosChecks(Mob* other);
|
||||||
bool TargetValidation(Mob* other);
|
bool TargetValidation(Mob* other);
|
||||||
inline void SetLastLosState(bool value) { last_los_check = value; }
|
inline void SetLastLosState(bool value) { last_los_check = value; }
|
||||||
inline bool CheckLastLosState() const { return last_los_check; }
|
inline bool CheckLastLosState() const { return last_los_check; }
|
||||||
|
|||||||
Reference in New Issue
Block a user