mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-03-15 13:25:09 +00:00
Compare commits
6 Commits
e9e79ad696
...
610fdc16d7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
610fdc16d7 | ||
|
|
c9c936d5c1 | ||
|
|
cfb2ed4bf3 | ||
|
|
79fb3a5bbc | ||
|
|
52d4191b43 | ||
|
|
254055ff32 |
@@ -173,7 +173,7 @@ std::vector<GuidPosition> ActiveQuestGiversValue::Calculate()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (guidp.isDead())
|
||||
if (!guidp.IsCreatureOrGOAccessible())
|
||||
continue;
|
||||
|
||||
retQuestGivers.push_back(guidp);
|
||||
@@ -231,7 +231,7 @@ std::vector<GuidPosition> ActiveQuestTakersValue::Calculate()
|
||||
|
||||
for (auto& guidp : entry.second)
|
||||
{
|
||||
if (guidp.isDead())
|
||||
if (!guidp.IsCreatureOrGOAccessible())
|
||||
continue;
|
||||
|
||||
retQuestTakers.push_back(guidp);
|
||||
@@ -298,7 +298,7 @@ std::vector<GuidPosition> ActiveQuestObjectivesValue::Calculate()
|
||||
{
|
||||
for (auto& guidp : entry.second)
|
||||
{
|
||||
if (guidp.isDead())
|
||||
if (!guidp.IsCreatureOrGOAccessible())
|
||||
continue;
|
||||
|
||||
retQuestObjectives.push_back(guidp);
|
||||
|
||||
@@ -41,6 +41,18 @@ public:
|
||||
std::string const GetTargetName() override { return "pet target"; }
|
||||
};
|
||||
|
||||
class CastUnendingBreathAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastUnendingBreathAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "unending breath") {}
|
||||
};
|
||||
|
||||
class CastUnendingBreathOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastUnendingBreathOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "unending breath") {}
|
||||
};
|
||||
|
||||
class CreateSoulShardAction : public Action
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -85,6 +85,8 @@ void GenericWarlockNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& tr
|
||||
triggers.push_back(new TriggerNode("too many soul shards", { NextAction("destroy soul shard", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("soul link", { NextAction("soul link", 28.0f) }));
|
||||
triggers.push_back(new TriggerNode("demon armor", { NextAction("fel armor", 27.0f) }));
|
||||
triggers.push_back(new TriggerNode("unending breath", { NextAction("unending breath", 12.0f) }));
|
||||
triggers.push_back(new TriggerNode("unending breath on party", { NextAction("unending breath on party", 11.0f) }));
|
||||
triggers.push_back(new TriggerNode("no healthstone", { NextAction("create healthstone", 26.0f) }));
|
||||
triggers.push_back(new TriggerNode("no soulstone", { NextAction("create soulstone", 25.0f) }));
|
||||
triggers.push_back(new TriggerNode("life tap", { NextAction("life tap", 23.0f) }));
|
||||
|
||||
@@ -79,6 +79,16 @@ bool SoulLinkTrigger::IsActive()
|
||||
return !botAI->HasAura("soul link", target);
|
||||
}
|
||||
|
||||
bool UnendingBreathTrigger::IsActive()
|
||||
{
|
||||
return BuffTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target");
|
||||
}
|
||||
|
||||
bool UnendingBreathOnPartyTrigger::IsActive()
|
||||
{
|
||||
return BuffOnPartyTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target");
|
||||
}
|
||||
|
||||
bool DemonicEmpowermentTrigger::IsActive()
|
||||
{
|
||||
Pet* pet = bot->GetPet();
|
||||
|
||||
@@ -32,6 +32,20 @@ public:
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class UnendingBreathTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
UnendingBreathTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "unending breath", 5 * 2000) {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class UnendingBreathOnPartyTrigger : public BuffOnPartyTrigger
|
||||
{
|
||||
public:
|
||||
UnendingBreathOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "unending breath on party", 2 * 2000) {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class OutOfSoulShardsTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -143,6 +143,8 @@ public:
|
||||
creators["shadow trance"] = &WarlockTriggerFactoryInternal::shadow_trance;
|
||||
creators["demon armor"] = &WarlockTriggerFactoryInternal::demon_armor;
|
||||
creators["soul link"] = &WarlockTriggerFactoryInternal::soul_link;
|
||||
creators["unending breath"] = &WarlockTriggerFactoryInternal::unending_breath;
|
||||
creators["unending breath on party"] = &WarlockTriggerFactoryInternal::unending_breath_on_party;
|
||||
creators["no soul shard"] = &WarlockTriggerFactoryInternal::no_soul_shard;
|
||||
creators["too many soul shards"] = &WarlockTriggerFactoryInternal::too_many_soul_shards;
|
||||
creators["no healthstone"] = &WarlockTriggerFactoryInternal::HasHealthstone;
|
||||
@@ -189,6 +191,8 @@ private:
|
||||
static Trigger* shadow_trance(PlayerbotAI* botAI) { return new ShadowTranceTrigger(botAI); }
|
||||
static Trigger* demon_armor(PlayerbotAI* botAI) { return new DemonArmorTrigger(botAI); }
|
||||
static Trigger* soul_link(PlayerbotAI* botAI) { return new SoulLinkTrigger(botAI); }
|
||||
static Trigger* unending_breath(PlayerbotAI* botAI) { return new UnendingBreathTrigger(botAI); }
|
||||
static Trigger* unending_breath_on_party(PlayerbotAI* botAI) { return new UnendingBreathOnPartyTrigger(botAI); }
|
||||
static Trigger* no_soul_shard(PlayerbotAI* botAI) { return new OutOfSoulShardsTrigger(botAI); }
|
||||
static Trigger* too_many_soul_shards(PlayerbotAI* botAI) { return new TooManySoulShardsTrigger(botAI); }
|
||||
static Trigger* HasHealthstone(PlayerbotAI* botAI) { return new HasHealthstoneTrigger(botAI); }
|
||||
@@ -240,6 +244,8 @@ public:
|
||||
creators["demon armor"] = &WarlockAiObjectContextInternal::demon_armor;
|
||||
creators["demon skin"] = &WarlockAiObjectContextInternal::demon_skin;
|
||||
creators["soul link"] = &WarlockAiObjectContextInternal::soul_link;
|
||||
creators["unending breath"] = &WarlockAiObjectContextInternal::unending_breath;
|
||||
creators["unending breath on party"] = &WarlockAiObjectContextInternal::unending_breath_on_party;
|
||||
creators["create soul shard"] = &WarlockAiObjectContextInternal::create_soul_shard;
|
||||
creators["destroy soul shard"] = &WarlockAiObjectContextInternal::destroy_soul_shard;
|
||||
creators["create healthstone"] = &WarlockAiObjectContextInternal::create_healthstone;
|
||||
@@ -313,6 +319,8 @@ private:
|
||||
static Action* demon_armor(PlayerbotAI* botAI) { return new CastDemonArmorAction(botAI); }
|
||||
static Action* demon_skin(PlayerbotAI* botAI) { return new CastDemonSkinAction(botAI); }
|
||||
static Action* soul_link(PlayerbotAI* botAI) { return new CastSoulLinkAction(botAI); }
|
||||
static Action* unending_breath(PlayerbotAI* botAI) { return new CastUnendingBreathAction(botAI); }
|
||||
static Action* unending_breath_on_party(PlayerbotAI* botAI) { return new CastUnendingBreathOnPartyAction(botAI); }
|
||||
static Action* create_soul_shard(PlayerbotAI* botAI) { return new CreateSoulShardAction(botAI); }
|
||||
static Action* destroy_soul_shard(PlayerbotAI* botAI) { return new DestroySoulShardAction(botAI); }
|
||||
static Action* create_healthstone(PlayerbotAI* botAI) { return new CastCreateHealthstoneAction(botAI); }
|
||||
|
||||
@@ -62,7 +62,7 @@ bool MountDrakeAction::Execute(Event event)
|
||||
break;
|
||||
}
|
||||
|
||||
std::vector<Player*> players = botAI->GetPlayersInGroup();
|
||||
std::vector<Player*> players = botAI->GetAllPlayersInGroup();
|
||||
for (Player* player : players)
|
||||
{
|
||||
if (!player || !player->IsInWorld() || player->IsDuringRemoveFromWorld())
|
||||
|
||||
@@ -2584,7 +2584,7 @@ std::string PlayerbotAI::GetLocalizedGameObjectName(uint32 entry)
|
||||
return name;
|
||||
}
|
||||
|
||||
std::vector<Player*> PlayerbotAI::GetPlayersInGroup()
|
||||
std::vector<Player*> PlayerbotAI::GetRealPlayersInGroup()
|
||||
{
|
||||
std::vector<Player*> members;
|
||||
|
||||
@@ -2611,6 +2611,30 @@ std::vector<Player*> PlayerbotAI::GetPlayersInGroup()
|
||||
return members;
|
||||
}
|
||||
|
||||
std::vector<Player*> PlayerbotAI::GetAllPlayersInGroup()
|
||||
{
|
||||
std::vector<Player*> members;
|
||||
|
||||
Group* group = bot->GetGroup();
|
||||
|
||||
if (!group)
|
||||
return members;
|
||||
|
||||
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||
{
|
||||
Player* member = ref->GetSource();
|
||||
|
||||
if (!member)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
members.push_back(ref->GetSource());
|
||||
}
|
||||
|
||||
return members;
|
||||
}
|
||||
|
||||
bool PlayerbotAI::SayToGuild(const std::string& msg)
|
||||
{
|
||||
if (msg.empty())
|
||||
@@ -2719,9 +2743,9 @@ bool PlayerbotAI::SayToParty(const std::string& msg)
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_PARTY, msg.c_str(), LANG_UNIVERSAL, CHAT_TAG_NONE, bot->GetGUID(),
|
||||
bot->GetName());
|
||||
|
||||
for (auto reciever : GetPlayersInGroup())
|
||||
for (auto receiver : GetRealPlayersInGroup())
|
||||
{
|
||||
ServerFacade::instance().SendPacket(reciever, &data);
|
||||
ServerFacade::instance().SendPacket(receiver, &data);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2736,9 +2760,9 @@ bool PlayerbotAI::SayToRaid(const std::string& msg)
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, msg.c_str(), LANG_UNIVERSAL, CHAT_TAG_NONE, bot->GetGUID(),
|
||||
bot->GetName());
|
||||
|
||||
for (auto reciever : GetPlayersInGroup())
|
||||
for (auto receiver : GetRealPlayersInGroup())
|
||||
{
|
||||
ServerFacade::instance().SendPacket(reciever, &data);
|
||||
ServerFacade::instance().SendPacket(receiver, &data);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -446,7 +446,8 @@ public:
|
||||
GameObject* GetGameObject(ObjectGuid guid);
|
||||
// static GameObject* GetGameObject(GameObjectData const* gameObjectData);
|
||||
WorldObject* GetWorldObject(ObjectGuid guid);
|
||||
std::vector<Player*> GetPlayersInGroup();
|
||||
std::vector<Player*> GetAllPlayersInGroup();
|
||||
std::vector<Player*> GetRealPlayersInGroup();
|
||||
const AreaTableEntry* GetCurrentArea();
|
||||
const AreaTableEntry* GetCurrentZone();
|
||||
static std::string GetLocalizedAreaName(const AreaTableEntry* entry);
|
||||
|
||||
@@ -881,107 +881,6 @@ std::vector<GameObjectData const*> WorldPosition::getGameObjectsNear(float radiu
|
||||
return worker.GetResult();
|
||||
}
|
||||
|
||||
Creature* GuidPosition::GetCreature()
|
||||
{
|
||||
if (!*this)
|
||||
return nullptr;
|
||||
|
||||
if (loadedFromDB)
|
||||
{
|
||||
auto creatureBounds = getMap()->GetCreatureBySpawnIdStore().equal_range(GetCounter());
|
||||
if (creatureBounds.first != creatureBounds.second)
|
||||
return creatureBounds.second->second;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return getMap()->GetCreature(*this);
|
||||
}
|
||||
|
||||
Unit* GuidPosition::GetUnit()
|
||||
{
|
||||
if (!*this)
|
||||
return nullptr;
|
||||
|
||||
if (loadedFromDB)
|
||||
{
|
||||
auto creatureBounds = getMap()->GetCreatureBySpawnIdStore().equal_range(GetCounter());
|
||||
if (creatureBounds.first != creatureBounds.second)
|
||||
return creatureBounds.second->second;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (IsPlayer())
|
||||
return ObjectAccessor::FindPlayer(*this);
|
||||
|
||||
if (IsPet())
|
||||
return getMap()->GetPet(*this);
|
||||
|
||||
return GetCreature();
|
||||
}
|
||||
|
||||
GameObject* GuidPosition::GetGameObject()
|
||||
{
|
||||
if (!*this)
|
||||
return nullptr;
|
||||
|
||||
if (loadedFromDB)
|
||||
{
|
||||
auto gameobjectBounds = getMap()->GetGameObjectBySpawnIdStore().equal_range(GetCounter());
|
||||
if (gameobjectBounds.first != gameobjectBounds.second)
|
||||
return gameobjectBounds.second->second;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return getMap()->GetGameObject(*this);
|
||||
}
|
||||
|
||||
Player* GuidPosition::GetPlayer()
|
||||
{
|
||||
if (!*this)
|
||||
return nullptr;
|
||||
|
||||
if (IsPlayer())
|
||||
return ObjectAccessor::FindPlayer(*this);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool GuidPosition::isDead()
|
||||
{
|
||||
if (!getMap())
|
||||
return false;
|
||||
|
||||
if (!getMap()->IsGridLoaded(getX(), getY()))
|
||||
return false;
|
||||
|
||||
if (IsUnit() && GetUnit() && GetUnit()->IsInWorld() && GetUnit()->IsAlive())
|
||||
return false;
|
||||
|
||||
if (IsGameObject() && GetGameObject() && GetGameObject()->IsInWorld())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GuidPosition::GuidPosition(WorldObject* wo) : ObjectGuid(wo->GetGUID()), WorldPosition(wo), loadedFromDB(false) {}
|
||||
|
||||
GuidPosition::GuidPosition(CreatureData const& creData)
|
||||
: ObjectGuid(HighGuid::Unit, creData.id1, creData.spawnId),
|
||||
WorldPosition(creData.mapid, creData.posX, creData.posY, creData.posZ, creData.orientation)
|
||||
{
|
||||
loadedFromDB = true;
|
||||
}
|
||||
|
||||
GuidPosition::GuidPosition(GameObjectData const& goData)
|
||||
: ObjectGuid(HighGuid::GameObject, goData.id),
|
||||
WorldPosition(goData.mapid, goData.posX, goData.posY, goData.posZ, goData.orientation)
|
||||
{
|
||||
loadedFromDB = true;
|
||||
}
|
||||
|
||||
CreatureTemplate const* GuidPosition::GetCreatureTemplate()
|
||||
{
|
||||
return IsCreature() ? sObjectMgr->GetCreatureTemplate(GetEntry()) : nullptr;
|
||||
@@ -1000,7 +899,7 @@ WorldObject* GuidPosition::GetWorldObject()
|
||||
switch (GetHigh())
|
||||
{
|
||||
case HighGuid::Player:
|
||||
return ObjectAccessor::FindPlayer(*this);
|
||||
return GetPlayer();
|
||||
case HighGuid::Transport:
|
||||
case HighGuid::Mo_Transport:
|
||||
case HighGuid::GameObject:
|
||||
@@ -1021,8 +920,93 @@ WorldObject* GuidPosition::GetWorldObject()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GameObject* GuidPosition::GetGameObject()
|
||||
{
|
||||
if (!*this)
|
||||
return nullptr;
|
||||
|
||||
if (loadedFromDB)
|
||||
return ObjectAccessor::GetSpawnedGameObjectByDBGUID(GetMapId(), GetCounter());
|
||||
|
||||
return getMap()->GetGameObject(*this); // fallback
|
||||
}
|
||||
|
||||
Unit* GuidPosition::GetUnit()
|
||||
{
|
||||
if (!*this)
|
||||
return nullptr;
|
||||
|
||||
if (IsPlayer())
|
||||
return GetPlayer();
|
||||
|
||||
if (IsPet())
|
||||
return getMap()->GetPet(*this);
|
||||
|
||||
return GetCreature();
|
||||
}
|
||||
|
||||
Creature* GuidPosition::GetCreature()
|
||||
{
|
||||
if (!*this)
|
||||
return nullptr;
|
||||
|
||||
if (loadedFromDB)
|
||||
return ObjectAccessor::GetSpawnedCreatureByDBGUID(GetMapId(), GetCounter());
|
||||
|
||||
return getMap()->GetCreature(*this); // fallback
|
||||
}
|
||||
|
||||
Player* GuidPosition::GetPlayer()
|
||||
{
|
||||
if (!*this)
|
||||
return nullptr;
|
||||
|
||||
if (IsPlayer())
|
||||
return ObjectAccessor::FindPlayer(*this);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool GuidPosition::HasNpcFlag(NPCFlags flag) { return IsCreature() && GetCreatureTemplate()->npcflag & flag; }
|
||||
|
||||
bool GuidPosition::IsCreatureOrGOAccessible()
|
||||
{
|
||||
Map* map = getMap();
|
||||
if (!map || !map->IsGridLoaded(GetPositionX(), GetPositionY()))
|
||||
return false;
|
||||
|
||||
if (IsCreature())
|
||||
{
|
||||
Creature* creature = GetCreature();
|
||||
if (creature && creature->IsInWorld() && creature->IsAlive())
|
||||
return true;
|
||||
}
|
||||
else if (IsGameObject())
|
||||
{
|
||||
GameObject* go = GetGameObject();
|
||||
if (go && go->IsInWorld())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
GuidPosition::GuidPosition(WorldObject* wo) : ObjectGuid(wo->GetGUID()), WorldPosition(wo), loadedFromDB(false) {}
|
||||
|
||||
GuidPosition::GuidPosition(CreatureData const& creData)
|
||||
: ObjectGuid(HighGuid::Unit, creData.id1, creData.spawnId),
|
||||
WorldPosition(creData.mapid, creData.posX, creData.posY, creData.posZ, creData.orientation)
|
||||
{
|
||||
loadedFromDB = true;
|
||||
}
|
||||
|
||||
GuidPosition::GuidPosition(GameObjectData const& goData)
|
||||
: ObjectGuid(HighGuid::GameObject, goData.id),
|
||||
WorldPosition(goData.mapid, goData.posX, goData.posY, goData.posZ, goData.orientation)
|
||||
{
|
||||
loadedFromDB = true;
|
||||
}
|
||||
|
||||
std::vector<WorldPosition*> TravelDestination::getPoints(bool ignoreFull)
|
||||
{
|
||||
if (ignoreFull)
|
||||
|
||||
@@ -416,14 +416,13 @@ public:
|
||||
GameObjectTemplate const* GetGameObjectTemplate();
|
||||
|
||||
WorldObject* GetWorldObject();
|
||||
Creature* GetCreature();
|
||||
Unit* GetUnit();
|
||||
GameObject* GetGameObject();
|
||||
Unit* GetUnit();
|
||||
Creature* GetCreature();
|
||||
Player* GetPlayer();
|
||||
|
||||
bool HasNpcFlag(NPCFlags flag);
|
||||
|
||||
bool isDead(); // For loaded grids check if the unit/object is unloaded/dead.
|
||||
bool IsCreatureOrGOAccessible(); // For loaded grids check if the creature/gameobject is in world + alive
|
||||
|
||||
operator bool() const { return !IsEmpty(); }
|
||||
bool operator==(ObjectGuid const& guid) const { return GetRawValue() == guid.GetRawValue(); }
|
||||
|
||||
Reference in New Issue
Block a user