mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Compare commits
9 Commits
hermensbas
...
hermensbas
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f70e1975c2 | ||
|
|
8d51092d42 | ||
|
|
3fff58df1a | ||
|
|
ca2e2ef0db | ||
|
|
4e3ac609bd | ||
|
|
c6b0424c29 | ||
|
|
2e0a161623 | ||
|
|
e4ea8e2694 | ||
|
|
ddfa919154 |
@@ -4214,6 +4214,19 @@ bool PlayerbotAI::AllowActive(ActivityType activityType)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only keep updating till initializing time has completed,
|
||||||
|
// which prevents unneeded expensive GameTime calls.
|
||||||
|
if (_isBotInitializing)
|
||||||
|
{
|
||||||
|
_isBotInitializing = GameTime::GetUptime().count() < sPlayerbotAIConfig->maxRandomBots * 0.11;
|
||||||
|
|
||||||
|
// no activity allowed during bot initialization
|
||||||
|
if (_isBotInitializing)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// General exceptions
|
// General exceptions
|
||||||
if (activityType == PACKET_ACTIVITY)
|
if (activityType == PACKET_ACTIVITY)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -611,6 +611,7 @@ private:
|
|||||||
Item* FindItemInInventory(std::function<bool(ItemTemplate const*)> checkItem) const;
|
Item* FindItemInInventory(std::function<bool(ItemTemplate const*)> checkItem) const;
|
||||||
void HandleCommands();
|
void HandleCommands();
|
||||||
void HandleCommand(uint32 type, const std::string& text, Player& fromPlayer, const uint32 lang = LANG_UNIVERSAL);
|
void HandleCommand(uint32 type, const std::string& text, Player& fromPlayer, const uint32 lang = LANG_UNIVERSAL);
|
||||||
|
bool _isBotInitializing = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Player* bot;
|
Player* bot;
|
||||||
|
|||||||
@@ -529,9 +529,6 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
|
|||||||
{
|
{
|
||||||
botAI->ResetStrategies(!sRandomPlayerbotMgr->IsRandomBot(bot));
|
botAI->ResetStrategies(!sRandomPlayerbotMgr->IsRandomBot(bot));
|
||||||
}
|
}
|
||||||
|
|
||||||
botAI->Reset(true); // Reset transient states (incl. LFG "proposal") to avoid the "one or more players are not eligible" error after reconnect.
|
|
||||||
|
|
||||||
sPlayerbotDbStore->Load(botAI);
|
sPlayerbotDbStore->Load(botAI);
|
||||||
|
|
||||||
if (master && !master->HasUnitState(UNIT_STATE_IN_FLIGHT))
|
if (master && !master->HasUnitState(UNIT_STATE_IN_FLIGHT))
|
||||||
@@ -551,21 +548,16 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
|
|||||||
if (master && master->GetGroup() && !group)
|
if (master && master->GetGroup() && !group)
|
||||||
{
|
{
|
||||||
Group* mgroup = master->GetGroup();
|
Group* mgroup = master->GetGroup();
|
||||||
// if (mgroup->GetMembersCount() >= 5)
|
if (mgroup->GetMembersCount() >= 5)
|
||||||
if (mgroup->GetMembersCount() + 1 > 5) // only convert in raid if the add of THIS bot make group > 5
|
|
||||||
{
|
{
|
||||||
if (!mgroup->isRaidGroup() && !mgroup->isLFGGroup() && !mgroup->isBGGroup() && !mgroup->isBFGroup())
|
if (!mgroup->isRaidGroup() && !mgroup->isLFGGroup() && !mgroup->isBGGroup() && !mgroup->isBFGroup())
|
||||||
{
|
{
|
||||||
mgroup->ConvertToRaid();
|
mgroup->ConvertToRaid();
|
||||||
}
|
}
|
||||||
//if (mgroup->isRaidGroup())
|
if (mgroup->isRaidGroup())
|
||||||
//{
|
{
|
||||||
//mgroup->AddMember(bot);
|
mgroup->AddMember(bot);
|
||||||
//}
|
}
|
||||||
mgroup->AddMember(bot);
|
|
||||||
|
|
||||||
LOG_DEBUG("playerbots", "[GROUP] after add: members={}, isRaid={}, isLFG={}",
|
|
||||||
(int)mgroup->GetMembersCount(), mgroup->isRaidGroup() ? 1 : 0, mgroup->isLFGGroup() ? 1 : 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,7 +30,6 @@
|
|||||||
#include "cs_playerbots.h"
|
#include "cs_playerbots.h"
|
||||||
#include "cmath"
|
#include "cmath"
|
||||||
#include "BattleGroundTactics.h"
|
#include "BattleGroundTactics.h"
|
||||||
#include "ObjectAccessor.h"
|
|
||||||
|
|
||||||
class PlayerbotsDatabaseScript : public DatabaseScript
|
class PlayerbotsDatabaseScript : public DatabaseScript
|
||||||
{
|
{
|
||||||
@@ -109,7 +108,7 @@ public:
|
|||||||
"|cffcccccchttps://github.com/liyunfan1223/mod-playerbots|r");
|
"|cffcccccchttps://github.com/liyunfan1223/mod-playerbots|r");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (sPlayerbotAIConfig->enabled || sPlayerbotAIConfig->randomBotAutologin)
|
if (sPlayerbotAIConfig->enabled || sPlayerbotAIConfig->randomBotAutologin)
|
||||||
{
|
{
|
||||||
std::string roundedTime =
|
std::string roundedTime =
|
||||||
std::to_string(std::ceil((sPlayerbotAIConfig->maxRandomBots * 0.11 / 60) * 10) / 10.0);
|
std::to_string(std::ceil((sPlayerbotAIConfig->maxRandomBots * 0.11 / 60) * 10) / 10.0);
|
||||||
@@ -118,7 +117,7 @@ public:
|
|||||||
ChatHandler(player->GetSession()).SendSysMessage(
|
ChatHandler(player->GetSession()).SendSysMessage(
|
||||||
"|cff00ff00Playerbots:|r bot initialization at server startup takes about '"
|
"|cff00ff00Playerbots:|r bot initialization at server startup takes about '"
|
||||||
+ roundedTime + "' minutes.");
|
+ roundedTime + "' minutes.");
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,7 +311,7 @@ class PlayerbotsScript : public PlayerbotScript
|
|||||||
public:
|
public:
|
||||||
PlayerbotsScript() : PlayerbotScript("PlayerbotsScript") {}
|
PlayerbotsScript() : PlayerbotScript("PlayerbotsScript") {}
|
||||||
|
|
||||||
/*bool OnPlayerbotCheckLFGQueue(lfg::Lfg5Guids const& guidsList) override
|
bool OnPlayerbotCheckLFGQueue(lfg::Lfg5Guids const& guidsList) override
|
||||||
{
|
{
|
||||||
bool nonBotFound = false;
|
bool nonBotFound = false;
|
||||||
for (ObjectGuid const& guid : guidsList.guids)
|
for (ObjectGuid const& guid : guidsList.guids)
|
||||||
@@ -326,137 +325,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nonBotFound;
|
return nonBotFound;
|
||||||
}*/
|
|
||||||
|
|
||||||
// New LFG Function
|
|
||||||
bool OnPlayerbotCheckLFGQueue(lfg::Lfg5Guids const& guidsList)
|
|
||||||
{
|
|
||||||
const size_t totalSlots = guidsList.guids.size();
|
|
||||||
size_t ignoredEmpty = 0, ignoredNonPlayer = 0;
|
|
||||||
size_t offlinePlayers = 0, botPlayers = 0, realPlayers = 0;
|
|
||||||
bool groupGuidSeen = false;
|
|
||||||
|
|
||||||
LOG_DEBUG("playerbots", "[LFG] check start: slots={}", totalSlots);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < totalSlots; ++i)
|
|
||||||
{
|
|
||||||
ObjectGuid const& guid = guidsList.guids[i];
|
|
||||||
|
|
||||||
// 1) Placeholders to ignore
|
|
||||||
if (guid.IsEmpty())
|
|
||||||
{
|
|
||||||
++ignoredEmpty;
|
|
||||||
LOG_DEBUG("playerbots", "[LFG] slot {}: <empty> -> ignored", i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Group GUID: in the original implementation this counted as "non-bot found"
|
|
||||||
if (guid.IsGroup())
|
|
||||||
{
|
|
||||||
groupGuidSeen = true;
|
|
||||||
LOG_DEBUG("playerbots", "[LFG] slot {}: <GROUP GUID> -> counts as having a real player (compat)", i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other non-Player GUIDs: various placeholders, ignore them
|
|
||||||
if (!guid.IsPlayer())
|
|
||||||
{
|
|
||||||
++ignoredNonPlayer;
|
|
||||||
LOG_DEBUG("playerbots", "[LFG] slot {}: guid={} (non-player/high={}) -> ignored", i,
|
|
||||||
static_cast<uint64>(guid.GetRawValue()), (unsigned)guid.GetHigh());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2) Player present?
|
|
||||||
Player* player = ObjectAccessor::FindPlayer(guid);
|
|
||||||
if (!player)
|
|
||||||
{
|
|
||||||
++offlinePlayers;
|
|
||||||
LOG_DEBUG("playerbots", "[LFG] slot {}: player guid={} is offline/not in world", i,
|
|
||||||
static_cast<uint64>(guid.GetRawValue()));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3) Bot or real player?
|
|
||||||
if (GET_PLAYERBOT_AI(player) != nullptr)
|
|
||||||
{
|
|
||||||
++botPlayers;
|
|
||||||
LOG_DEBUG("playerbots", "[LFG] slot {}: BOT {} (lvl {}, class {})", i, player->GetName().c_str(),
|
|
||||||
player->GetLevel(), player->getClass());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++realPlayers;
|
|
||||||
LOG_DEBUG("playerbots", "[LFG] slot {}: REAL {} (lvl {}, class {})", i, player->GetName().c_str(),
|
|
||||||
player->GetLevel(), player->getClass());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// "Ultra-early phase" detection: only placeholders => DO NOT VETO
|
|
||||||
const bool onlyPlaceholders = (realPlayers + botPlayers + (groupGuidSeen ? 1 : 0)) == 0 &&
|
|
||||||
(ignoredEmpty + ignoredNonPlayer) == totalSlots;
|
|
||||||
|
|
||||||
// "Soft" LFG preflight if we actually see players AND at least one offline
|
|
||||||
if (!onlyPlaceholders && offlinePlayers > 0)
|
|
||||||
{
|
|
||||||
// Find a plausible leader: prefer a real online player, otherwise any online player
|
|
||||||
Player* leader = nullptr;
|
|
||||||
|
|
||||||
for (ObjectGuid const& guid : guidsList.guids)
|
|
||||||
if (guid.IsPlayer())
|
|
||||||
if (Player* p = ObjectAccessor::FindPlayer(guid))
|
|
||||||
if (GET_PLAYERBOT_AI(p) == nullptr)
|
|
||||||
{
|
|
||||||
leader = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!leader)
|
|
||||||
for (ObjectGuid const& guid : guidsList.guids)
|
|
||||||
if (guid.IsPlayer())
|
|
||||||
if (Player* p = ObjectAccessor::FindPlayer(guid))
|
|
||||||
{
|
|
||||||
leader = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leader)
|
|
||||||
{
|
|
||||||
Group* g = leader->GetGroup();
|
|
||||||
if (g)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("playerbots", "[LFG-RESET] group members={}, isRaid={}, isLFGGroup={}",
|
|
||||||
(int)g->GetMembersCount(), g->isRaidGroup() ? 1 : 0, g->isLFGGroup() ? 1 : 0);
|
|
||||||
|
|
||||||
// "Soft" reset of LFG states on the bots' AI side (proposal/role-check, etc.)
|
|
||||||
for (GroupReference* ref = g->GetFirstMember(); ref; ref = ref->next())
|
|
||||||
{
|
|
||||||
Player* member = ref->GetSource();
|
|
||||||
if (!member)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (PlayerbotAI* ai = GET_PLAYERBOT_AI(member))
|
|
||||||
ai->Reset(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DEBUG("playerbots", "[LFG] preflight soft-reset triggered (offline detected) -> allowQueue=no (retry)");
|
|
||||||
return false; // ask the client to retry right after the reset
|
|
||||||
}
|
|
||||||
|
|
||||||
// "Hybrid" policy: permissive if only placeholders; otherwise original logic
|
|
||||||
bool allowQueue = onlyPlaceholders ? true : ((offlinePlayers == 0) && (realPlayers >= 1 || groupGuidSeen));
|
|
||||||
|
|
||||||
LOG_DEBUG("playerbots",
|
|
||||||
"[LFG] summary: slots={}, real={}, bots={}, offline={}, ignored(empty+nonPlayer)={}, "
|
|
||||||
"groupGuidSeen={} -> allowQueue={}",
|
|
||||||
totalSlots, realPlayers, botPlayers, offlinePlayers, (ignoredEmpty + ignoredNonPlayer),
|
|
||||||
(groupGuidSeen ? "yes" : "no"), (allowQueue ? "yes" : "no"));
|
|
||||||
|
|
||||||
return allowQueue;
|
|
||||||
}
|
}
|
||||||
// End LFG
|
|
||||||
|
|
||||||
void OnPlayerbotCheckKillTask(Player* player, Unit* victim) override
|
void OnPlayerbotCheckKillTask(Player* player, Unit* victim) override
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -164,16 +164,15 @@ void PlayerbotFactory::Init()
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(gemId);
|
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(gemId);
|
||||||
if (proto) {
|
|
||||||
if (proto->ItemLevel < 60)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (proto->Flags & ITEM_FLAG_UNIQUE_EQUIPPABLE)
|
if (proto->ItemLevel < 60)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (proto->Flags & ITEM_FLAG_UNIQUE_EQUIPPABLE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sRandomItemMgr->IsTestItem(gemId))
|
if (sRandomItemMgr->IsTestItem(gemId))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -181,11 +180,9 @@ void PlayerbotFactory::Init()
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LOG_INFO("playerbots", "Add {} to enchantment gems", gemId);
|
// LOG_INFO("playerbots", "Add {} to enchantment gems", gemId);
|
||||||
enchantGemIdCache.push_back(gemId);
|
enchantGemIdCache.push_back(gemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("playerbots", "Loading {} enchantment gems", enchantGemIdCache.size());
|
LOG_INFO("playerbots", "Loading {} enchantment gems", enchantGemIdCache.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1020,9 +1017,10 @@ void PlayerbotFactory::ClearSkills()
|
|||||||
}
|
}
|
||||||
bot->SetUInt32Value(PLAYER_SKILL_INDEX(0), 0);
|
bot->SetUInt32Value(PLAYER_SKILL_INDEX(0), 0);
|
||||||
bot->SetUInt32Value(PLAYER_SKILL_INDEX(1), 0);
|
bot->SetUInt32Value(PLAYER_SKILL_INDEX(1), 0);
|
||||||
|
|
||||||
// unlearn default race/class skills
|
// unlearn default race/class skills
|
||||||
if (PlayerInfo const* info = sObjectMgr->GetPlayerInfo(bot->getRace(), bot->getClass())) {
|
if (PlayerInfo const* info = sObjectMgr->GetPlayerInfo(bot->getRace(), bot->getClass()))
|
||||||
|
{
|
||||||
for (PlayerCreateInfoSkills::const_iterator itr = info->skills.begin(); itr != info->skills.end(); ++itr)
|
for (PlayerCreateInfoSkills::const_iterator itr = info->skills.begin(); itr != info->skills.end(); ++itr)
|
||||||
{
|
{
|
||||||
uint32 skillId = itr->SkillId;
|
uint32 skillId = itr->SkillId;
|
||||||
@@ -1030,7 +1028,7 @@ void PlayerbotFactory::ClearSkills()
|
|||||||
continue;
|
continue;
|
||||||
bot->SetSkill(skillId, 0, 0, 0);
|
bot->SetSkill(skillId, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerbotFactory::ClearEverything()
|
void PlayerbotFactory::ClearEverything()
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ bool MoveToTravelTargetAction::Execute(Event event)
|
|||||||
WorldLocation location = *target->getPosition();
|
WorldLocation location = *target->getPosition();
|
||||||
|
|
||||||
Group* group = bot->GetGroup();
|
Group* group = bot->GetGroup();
|
||||||
if (group && !urand(0, 1) && bot == botAI->GetGroupMaster() && !bot->IsInCombat())
|
if (group && !urand(0, 1) && bot == botAI->GetGroupMaster())
|
||||||
{
|
{
|
||||||
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user