вывод из самбомудлей модов для азероткор

This commit is contained in:
2026-03-07 22:28:31 +04:00
parent 5877ea78cd
commit adcfe8e31d
1720 changed files with 1941740 additions and 40 deletions
@@ -0,0 +1,39 @@
#include "FlightMasterCache.h"
void FlightMasterCache::AddHordeFlightMaster(uint32 entry, WorldPosition pos)
{
hordeFlightMasterCache[entry] = pos;
}
void FlightMasterCache::AddAllianceFlightMaster(uint32 entry, WorldPosition pos)
{
allianceFlightMasterCache[entry] = pos;
}
Creature* FlightMasterCache::GetNearestFlightMaster(Player* bot)
{
std::map<uint32, WorldPosition>& flightMasterCache =
(bot->GetTeamId() == TEAM_ALLIANCE) ? allianceFlightMasterCache : hordeFlightMasterCache;
Creature* nearestFlightMaster = nullptr;
float nearestDistance = std::numeric_limits<float>::max();
for (auto const& [entry, pos] : flightMasterCache)
{
if (pos.GetMapId() == bot->GetMapId())
{
float distance = bot->GetExactDist2dSq(pos);
if (distance < nearestDistance)
{
Creature* flightMaster = ObjectAccessor::GetSpawnedCreatureByDBGUID(bot->GetMapId(), entry);
if (flightMaster)
{
nearestDistance = distance;
nearestFlightMaster = flightMaster;
}
}
}
}
return nearestFlightMaster;
}
@@ -0,0 +1,36 @@
#ifndef _PLAYERBOT_FLIGHTMASTER_H
#define _PLAYERBOT_FLIGHTMASTER_H
#include "Creature.h"
#include "Player.h"
#include "TravelMgr.h"
class FlightMasterCache
{
public:
static FlightMasterCache& Instance()
{
static FlightMasterCache instance;
return instance;
}
Creature* GetNearestFlightMaster(Player* bot);
void AddHordeFlightMaster(uint32 entry, WorldPosition pos);
void AddAllianceFlightMaster(uint32 entry, WorldPosition pos);
private:
FlightMasterCache() = default;
~FlightMasterCache() = default;
FlightMasterCache(const FlightMasterCache&) = delete;
FlightMasterCache& operator=(const FlightMasterCache&) = delete;
FlightMasterCache(FlightMasterCache&&) = delete;
FlightMasterCache& operator=(FlightMasterCache&&) = delete;
std::map<uint32, WorldPosition> allianceFlightMasterCache;
std::map<uint32, WorldPosition> hordeFlightMasterCache;
};
#endif
@@ -0,0 +1,54 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#include "Log.h"
#include "Timer.h"
#include "DatabaseEnv.h"
#include "Field.h"
#include "World.h"
// Required import due to poor implementation by AC
#include "QueryResult.h"
#include "PlayerbotDungeonRepository.h"
std::vector<DungeonSuggestion> const PlayerbotDungeonRepository::GetDungeonSuggestions()
{
return m_dungeonSuggestions;
}
void PlayerbotDungeonRepository::LoadDungeonSuggestions()
{
LOG_INFO("server.loading", "Loading playerbots dungeon suggestions...");
uint32 oldMSTime = getMSTime();
uint32 count = 0;
auto statement = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_DUNGEON_SUGGESTION);
uint8 const expansion = sWorld->getIntConfig(CONFIG_EXPANSION);
statement->SetData(0, expansion);
PreparedQueryResult result = PlayerbotsDatabase.Query(statement);
if (result)
{
do
{
Field* fields = result->Fetch();
std::string const name = fields[0].Get<std::string>();
uint8 const difficulty = fields[1].Get<uint8>();
uint8 const min_level = fields[2].Get<uint8>();
uint8 const max_level = fields[3].Get<uint8>();
std::string const abbrevation = fields[4].Get<std::string>();
std::string const strategy = fields[5].Get<std::string>();
DungeonSuggestion const row = {
name, static_cast<Difficulty>(difficulty), min_level, max_level, abbrevation, strategy};
m_dungeonSuggestions.push_back(row);
++count;
} while (result->NextRow());
}
LOG_INFO("server.loading", "{} playerbots dungeon suggestions loaded in {} ms", count,
GetMSTimeDiffToNow(oldMSTime));
}
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_PLAYERBOTDUNGEONREPOSITORY_H
#define _PLAYERBOT_PLAYERBOTDUNGEONREPOSITORY_H
#include <vector>
#include <string>
#include "DBCEnums.h"
struct DungeonSuggestion
{
std::string name;
Difficulty difficulty;
uint8 min_level;
uint8 max_level;
std::string abbrevation;
std::string strategy;
};
// @TODO: Completely unused at this moment.
class PlayerbotDungeonRepository
{
public:
static PlayerbotDungeonRepository& instance()
{
static PlayerbotDungeonRepository instance;
return instance;
}
void LoadDungeonSuggestions();
std::vector<DungeonSuggestion> const GetDungeonSuggestions();
private:
PlayerbotDungeonRepository() = default;
~PlayerbotDungeonRepository() = default;
PlayerbotDungeonRepository(const PlayerbotDungeonRepository&) = delete;
PlayerbotDungeonRepository& operator=(const PlayerbotDungeonRepository&) = delete;
PlayerbotDungeonRepository(PlayerbotDungeonRepository&&) = delete;
PlayerbotDungeonRepository& operator=(PlayerbotDungeonRepository&&) = delete;
std::vector<DungeonSuggestion> m_dungeonSuggestions;
};
#endif
@@ -0,0 +1,94 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#include "PlayerbotRepository.h"
#include "AiObjectContext.h"
void PlayerbotRepository::Load(PlayerbotAI* botAI)
{
ObjectGuid::LowType guid = botAI->GetBot()->GetGUID().GetCounter();
PlayerbotsDatabasePreparedStatement* stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_DB_STORE);
stmt->SetData(0, guid);
if (PreparedQueryResult result = PlayerbotsDatabase.Query(stmt))
{
std::vector<std::string> values;
do
{
Field* fields = result->Fetch();
std::string const key = fields[0].Get<std::string>();
std::string const value = fields[1].Get<std::string>();
if (key == "value")
values.push_back(value);
else if (key == "co")
{
botAI->ClearStrategies(BOT_STATE_COMBAT);
botAI->ChangeStrategy("+chat", BOT_STATE_COMBAT);
botAI->ChangeStrategy(value, BOT_STATE_COMBAT);
}
else if (key == "nc")
{
botAI->ClearStrategies(BOT_STATE_NON_COMBAT);
botAI->ChangeStrategy("+chat", BOT_STATE_NON_COMBAT);
botAI->ChangeStrategy(value, BOT_STATE_NON_COMBAT);
}
else if (key == "dead")
botAI->ChangeStrategy(value, BOT_STATE_DEAD);
} while (result->NextRow());
botAI->GetAiObjectContext()->Load(values);
}
}
void PlayerbotRepository::Save(PlayerbotAI* botAI)
{
ObjectGuid::LowType guid = botAI->GetBot()->GetGUID().GetCounter();
Reset(botAI);
PlayerbotsDatabasePreparedStatement* deleteStatement =
PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_DB_STORE);
deleteStatement->SetData(0, guid);
PlayerbotsDatabase.Execute(deleteStatement);
std::vector<std::string> data = botAI->GetAiObjectContext()->Save();
for (std::vector<std::string>::iterator i = data.begin(); i != data.end(); ++i)
{
SaveValue(guid, "value", *i);
}
SaveValue(guid, "co", FormatStrategies("co", botAI->GetStrategies(BOT_STATE_COMBAT)));
SaveValue(guid, "nc", FormatStrategies("nc", botAI->GetStrategies(BOT_STATE_NON_COMBAT)));
SaveValue(guid, "dead", FormatStrategies("dead", botAI->GetStrategies(BOT_STATE_DEAD)));
}
std::string const PlayerbotRepository::FormatStrategies(std::string const type, std::vector<std::string> strategies)
{
std::ostringstream out;
for (std::vector<std::string>::iterator i = strategies.begin(); i != strategies.end(); ++i)
out << "+" << (*i).c_str() << ",";
std::string const res = out.str();
return res.substr(0, res.size() - 1);
}
void PlayerbotRepository::Reset(PlayerbotAI* botAI)
{
ObjectGuid::LowType guid = botAI->GetBot()->GetGUID().GetCounter();
PlayerbotsDatabasePreparedStatement* stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_DB_STORE);
stmt->SetData(0, guid);
PlayerbotsDatabase.Execute(stmt);
}
void PlayerbotRepository::SaveValue(uint32 guid, std::string const key, std::string const value)
{
PlayerbotsDatabasePreparedStatement* stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_INS_DB_STORE);
stmt->SetData(0, guid);
stmt->SetData(1, key);
stmt->SetData(2, value);
PlayerbotsDatabase.Execute(stmt);
}
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_PLAYERBOTREPOSITORY_H
#define _PLAYERBOT_PLAYERBOTREPOSITORY_H
#include <cstdint>
#include <string>
#include <vector>
#include "PlayerbotAI.h"
class PlayerbotRepository
{
public:
static PlayerbotRepository& instance()
{
static PlayerbotRepository instance;
return instance;
}
void Save(PlayerbotAI* botAI);
void Load(PlayerbotAI* botAI);
void Reset(PlayerbotAI* botAI);
private:
PlayerbotRepository() = default;
~PlayerbotRepository() = default;
PlayerbotRepository(const PlayerbotRepository&) = delete;
PlayerbotRepository& operator=(const PlayerbotRepository&) = delete;
PlayerbotRepository(PlayerbotRepository&&) = delete;
PlayerbotRepository& operator=(PlayerbotRepository&&) = delete;
void SaveValue(uint32_t guid, std::string const key, std::string const value);
std::string const FormatStrategies(std::string const type, std::vector<std::string> strategies);
};
#endif
@@ -0,0 +1,53 @@
#include "Log.h"
#include "DBCStores.h"
#include "DatabaseEnv.h"
#include "Field.h"
// Required due to poor implementation on AC side
#include "QueryResult.h"
#include "PlayerbotSpellRepository.h"
// caches the result set
void PlayerbotSpellRepository::Initialize()
{
LOG_INFO("playerbots", "Playerbots: ListSpellsAction caches initialized");
for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
{
if (SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j))
skillSpells[skillLine->Spell] = skillLine;
}
// Fill the vendorItems cache once from the world database.
QueryResult results = WorldDatabase.Query("SELECT item FROM npc_vendor WHERE maxcount = 0");
if (results)
{
do
{
Field* fields = results->Fetch();
int32 entry = fields[0].Get<int32>();
if (entry <= 0)
continue;
vendorItems.insert(static_cast<uint32>(entry));
}
while (results->NextRow());
}
LOG_DEBUG("playerbots",
"ListSpellsAction: initialized caches (skillSpells={}, vendorItems={}).",
skillSpells.size(), vendorItems.size());
}
SkillLineAbilityEntry const* PlayerbotSpellRepository::GetSkillLine(uint32 spellId) const
{
auto itr = skillSpells.find(spellId);
if (itr != skillSpells.end())
return itr->second;
return nullptr;
}
bool PlayerbotSpellRepository::IsItemBuyable(uint32 itemId) const
{
return vendorItems.find(itemId) != vendorItems.end();
}
@@ -0,0 +1,42 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_PLAYERBOTSPELLREPOSITORY_H
#define _PLAYERBOT_PLAYERBOTSPELLREPOSITORY_H
#include <cstdint>
#include "DBCStructure.h"
class PlayerbotSpellRepository
{
public:
static PlayerbotSpellRepository& Instance()
{
static PlayerbotSpellRepository instance;
return instance;
}
void Initialize();
SkillLineAbilityEntry const* GetSkillLine(uint32_t spellId) const;
bool IsItemBuyable(uint32_t itemId) const;
private:
PlayerbotSpellRepository() = default;
~PlayerbotSpellRepository() = default;
PlayerbotSpellRepository(const PlayerbotSpellRepository&) = delete;
PlayerbotSpellRepository& operator=(const PlayerbotSpellRepository&) = delete;
PlayerbotSpellRepository(PlayerbotSpellRepository&&) = delete;
PlayerbotSpellRepository& operator=(PlayerbotSpellRepository&&) = delete;
std::map<uint32_t, SkillLineAbilityEntry const*> skillSpells;
std::set<uint32_t> vendorItems;
};
#endif