mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-17 07:18:37 +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)
|
||||
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
|
||||
GetPet()->SetTarget(tar);
|
||||
}
|
||||
@@ -2316,7 +2315,7 @@ void Bot::AI_Process()
|
||||
if (GetPullingFlag()) {
|
||||
if (!TargetValidation(tar)) { return; }
|
||||
|
||||
if (!DoLosChecks(this, tar)) {
|
||||
if (!DoLosChecks(tar)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3196,7 +3195,7 @@ bool Bot::IsValidTarget(
|
||||
(!Charmed() && tar->GetUltimateOwner()->IsOfClientBotMerc()) ||
|
||||
lo_distance > leash_distance ||
|
||||
tar_distance > leash_distance ||
|
||||
(!GetAttackingFlag() && !CheckLosCheat(this, tar) && !CheckLosCheat(leash_owner, tar)) ||
|
||||
(!GetAttackingFlag() && !CheckLosCheat(tar) && !leash_owner->CheckLosCheat(tar)) ||
|
||||
!IsAttackAllowed(tar)
|
||||
) {
|
||||
invalid_target_state = true;
|
||||
@@ -9382,6 +9381,10 @@ void Bot::DoItemClick(const EQ::ItemData *item, uint16 slot_id)
|
||||
bool is_casting_bard_song = false;
|
||||
Mob* tar = (GetOwner()->GetTarget() ? GetOwner()->GetTarget() : this);
|
||||
|
||||
if (!DoLosChecks(tar)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsCasting()) {
|
||||
InterruptSpell();
|
||||
}
|
||||
@@ -10252,7 +10255,7 @@ bool Bot::IsValidMezTarget(Mob* owner, Mob* npc, uint16 spell_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DoLosChecks(this, npc)) {
|
||||
if (!DoLosChecks(npc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -11084,7 +11087,7 @@ bool Bot::AttemptAACastSpell(Mob* tar, uint16 spell_id, AA::Rank* rank) {
|
||||
tar = this;
|
||||
}
|
||||
|
||||
if (!DoLosChecks(this, tar)) {
|
||||
if (!DoLosChecks(tar)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -11219,7 +11222,7 @@ bool Bot::AttemptForcedCastSpell(Mob* tar, uint16 spell_id, bool is_disc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DoLosChecks(this, tar)) {
|
||||
if (!DoLosChecks(tar)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -11712,7 +11715,7 @@ bool Bot::HasRequiredLoSForPositioning(Mob* tar) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (RequiresLoSForPositioning() && !DoLosChecks(this, tar)) {
|
||||
if (RequiresLoSForPositioning() && !DoLosChecks(tar)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -803,7 +803,7 @@ void helper_send_usage_required_bots(Client *bot_owner, uint16 spell_type)
|
||||
auto& spell_map = bot->GetCommandedSpellTypesMinLevels();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,12 @@ void bot_command_attack(Client *c, const Seperator *sep)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -71,7 +76,7 @@ void bot_command_attack(Client *c, const Seperator *sep)
|
||||
);
|
||||
} else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
Chat::PetResponse,
|
||||
fmt::format(
|
||||
"{} of your bots are attacking {}.",
|
||||
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());
|
||||
|
||||
Mob* tar = c->GetTarget();
|
||||
|
||||
for (auto my_bot : sbl) {
|
||||
if (my_bot->BotPassiveCheck()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
tar &&
|
||||
tar != c &&
|
||||
tar->GetOwner() != c &&
|
||||
!c->DoLosChecks(tar)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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));
|
||||
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")) {
|
||||
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]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!c->GetTarget() || !c->IsAttackAllowed(c->GetTarget())) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,12 @@ void bot_command_pull(Client *c, const Seperator *sep)
|
||||
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()) {
|
||||
|
||||
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;
|
||||
for (auto bot_iter : sbl) {
|
||||
|
||||
for (auto bot_iter : sbl) {
|
||||
if (bot_iter->GetAppearance() == eaDead || bot_iter->GetBotStance() == Stance::Passive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 chance, uint16 spell_type, uint16 sub_targ
|
||||
bot_spell.ManaCost = 0;
|
||||
|
||||
if (BotSpellTypeRequiresLoS(spell_type) && tar != this) {
|
||||
SetHasLoS(DoLosChecks(this, tar));
|
||||
SetHasLoS(DoLosChecks(tar));
|
||||
}
|
||||
else {
|
||||
SetHasLoS(true);
|
||||
|
||||
+15
-1
@@ -11091,10 +11091,17 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
case PET_ATTACK: {
|
||||
if (!target)
|
||||
break;
|
||||
|
||||
if (!DoLosChecks(target)) {
|
||||
mypet->SayString(this, NOT_LEGAL_TARGET);
|
||||
break;
|
||||
}
|
||||
|
||||
if (target->IsMezzed()) {
|
||||
MessageString(Chat::NPCQuestSay, CANNOT_WAKE, mypet->GetCleanName(), target->GetCleanName());
|
||||
break;
|
||||
}
|
||||
|
||||
if (mypet->IsFeared())
|
||||
break; //prevent pet from attacking stuff while feared
|
||||
|
||||
@@ -11149,8 +11156,15 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
if (mypet->IsFeared())
|
||||
break; //prevent pet from attacking stuff while feared
|
||||
|
||||
if (!GetTarget())
|
||||
if (!GetTarget()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!DoLosChecks(GetTarget())) {
|
||||
mypet->SayString(this, NOT_LEGAL_TARGET);
|
||||
break;
|
||||
}
|
||||
|
||||
if (GetTarget()->IsMezzed()) {
|
||||
MessageString(Chat::NPCQuestSay, CANNOT_WAKE, mypet->GetCleanName(), GetTarget()->GetCleanName());
|
||||
break;
|
||||
|
||||
+49
-24
@@ -8679,33 +8679,54 @@ bool Mob::IsInGroupOrRaid(Mob* other, bool same_raid_group) {
|
||||
return group && group == other_group;
|
||||
}
|
||||
|
||||
bool Mob::DoLosChecks(Mob* who, Mob* other) {
|
||||
if (!who->CheckLosFN(other) || !who->CheckWaterLoS(other)) {
|
||||
if (who->CheckLosCheatExempt(who, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CheckLosCheat(who, other)) {
|
||||
bool Mob::DoLosChecks(Mob* other) {
|
||||
if (!CheckLosFN(other) || !CheckWaterLoS(other)) {
|
||||
if (CheckLosCheatExempt(other)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CheckLosCheat(other)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mob::CheckLosCheat(Mob* who, Mob* other) {
|
||||
bool Mob::CheckLosCheat(Mob* other) {
|
||||
if (RuleB(Map, CheckForLoSCheat)) {
|
||||
for (auto itr : entity_list.GetDoorsList()) {
|
||||
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) {
|
||||
auto who_to_door = DistanceNoZ(who->GetPosition(), d->GetPosition());
|
||||
auto other_to_door = DistanceNoZ(other->GetPosition(), d->GetPosition());
|
||||
auto who_to_other = DistanceNoZ(who->GetPosition(), other->GetPosition());
|
||||
auto distance_difference = who_to_other - (who_to_door + other_to_door);
|
||||
|
||||
if (
|
||||
!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 who_to_other = DistanceNoZ(GetPosition(), other->GetPosition());
|
||||
auto distance_difference = who_to_other - (who_to_door + other_to_door);
|
||||
|
||||
if (distance_difference >= (-1 * RuleR(Maps, RangeCheckForLoSCheat)) && distance_difference <= RuleR(Maps, RangeCheckForLoSCheat)) {
|
||||
return false;
|
||||
}
|
||||
@@ -8717,19 +8738,23 @@ bool Mob::CheckLosCheat(Mob* who, Mob* other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mob::CheckLosCheatExempt(Mob* who, Mob* other) {
|
||||
bool Mob::CheckLosCheatExempt(Mob* other) {
|
||||
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_other;
|
||||
/* This is an exmaple of how to configure exemptions for LoS checks.
|
||||
if (zone->GetZoneID() == 222) { //PoEarthB
|
||||
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
|
||||
//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 (who->GetZ() <= -171 && other->GetZ() <= -171 && DistanceNoZ(other->GetPosition(), exempt_check_who) <= 800 && DistanceNoZ(who->GetPosition(), exempt_check_who) <= 800) {
|
||||
return true;
|
||||
}
|
||||
|
||||
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_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 (GetZ() <= -171 && other->GetZ() <= -171 && DistanceNoZ(other->GetPosition(), exempt_check_who) <= 800 && DistanceNoZ(GetPosition(), exempt_check_who) <= 800) {
|
||||
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);
|
||||
virtual bool CheckWaterLoS(Mob* m);
|
||||
bool CheckPositioningLosFN(Mob* other, float posX, float posY, float posZ);
|
||||
bool CheckLosCheat(Mob* who, Mob* other);
|
||||
bool CheckLosCheatExempt(Mob* who, Mob* other);
|
||||
bool DoLosChecks(Mob* who, Mob* other);
|
||||
bool CheckLosCheat(Mob* other);
|
||||
bool CheckLosCheatExempt(Mob* other);
|
||||
bool DoLosChecks(Mob* other);
|
||||
bool TargetValidation(Mob* other);
|
||||
inline void SetLastLosState(bool value) { last_los_check = value; }
|
||||
inline bool CheckLastLosState() const { return last_los_check; }
|
||||
|
||||
Reference in New Issue
Block a user