mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-25 06:26:24 +00:00
Compare commits
20 Commits
59d6eb139e
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
378254af3f | ||
|
|
3d467ce3bb | ||
|
|
3e21563669 | ||
|
|
bf456ee07f | ||
|
|
a5bd0b9a41 | ||
|
|
34bab48dd4 | ||
|
|
41c53365ae | ||
|
|
fd07e02a8a | ||
|
|
6cf7f1aaef | ||
|
|
9f54d7e702 | ||
|
|
aeaaee15da | ||
|
|
a1137dbddc | ||
|
|
2eb98c3233 | ||
|
|
29613e29b7 | ||
|
|
e2c203a35e | ||
|
|
1b1ed18a23 | ||
|
|
2ab73c1fd5 | ||
|
|
6b97c379ba | ||
|
|
965d300203 | ||
|
|
dc55ecfd9c |
6
.github/workflows/windows_build.yml
vendored
6
.github/workflows/windows_build.yml
vendored
@@ -25,21 +25,25 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
repository: 'mod-playerbots/azerothcore-wotlk'
|
repository: 'mod-playerbots/azerothcore-wotlk'
|
||||||
ref: 'Playerbot'
|
ref: 'Playerbot'
|
||||||
|
path: 'ac'
|
||||||
- name: Checkout Playerbot Module
|
- name: Checkout Playerbot Module
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: 'mod-playerbots/mod-playerbots'
|
repository: 'mod-playerbots/mod-playerbots'
|
||||||
path: 'modules/mod-playerbots'
|
#path: 'modules/mod-playerbots'
|
||||||
|
path: ac/modules/mod-playerbots
|
||||||
- name: ccache
|
- name: ccache
|
||||||
uses: hendrikmuhs/ccache-action@v1.2.13
|
uses: hendrikmuhs/ccache-action@v1.2.13
|
||||||
- name: Configure OS
|
- name: Configure OS
|
||||||
shell: bash
|
shell: bash
|
||||||
|
working-directory: ac
|
||||||
env:
|
env:
|
||||||
CONTINUOUS_INTEGRATION: true
|
CONTINUOUS_INTEGRATION: true
|
||||||
run: |
|
run: |
|
||||||
./acore.sh install-deps
|
./acore.sh install-deps
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash
|
shell: bash
|
||||||
|
working-directory: ac
|
||||||
run: |
|
run: |
|
||||||
export CTOOLS_BUILD=all
|
export CTOOLS_BUILD=all
|
||||||
./acore.sh compiler build
|
./acore.sh compiler build
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
# Overview
|
# Overview
|
||||||
# "Randombot": randomly generated bots that log in separately from players and populate the world. Depending on settings, randombots may automatically grind, quest, and upgrade equipment and can be invited to groups and given commands.
|
# "Randombot": randomly generated bots that log in separately from players and populate the world. Randombots may automatically grind, quest, level up, and upgrade equipment and can be invited to groups and given commands.
|
||||||
# "Altbot": characters created on player accounts, which may be logged in by the player and invited to groups and given commands like randombots. Depending on settings, altbots can be limited to characters on the active player's account or in the active player's guild.
|
# "AddClass bot": bots from the AddClassAccountPoolSize accounts. They are used for quickly adding a leveled and geared bot of any class to your party. They are recommended for a quick formation of a party.
|
||||||
|
# "Altbot": characters created on player accounts, which may be logged in by the player and invited to groups and given commands like randombots. They are best suited for long-progression playthroughs.
|
||||||
# Information about commands to control bots and set their strategies can be found on the wiki at https://github.com/mod-playerbots/mod-playerbots/wiki/Playerbot-Commands.
|
# Information about commands to control bots and set their strategies can be found on the wiki at https://github.com/mod-playerbots/mod-playerbots/wiki/Playerbot-Commands.
|
||||||
|
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
@@ -269,7 +270,7 @@ AiPlayerbot.UseFastFlyMountAtMinLevel = 70
|
|||||||
AiPlayerbot.RandomBotShowHelmet = 1
|
AiPlayerbot.RandomBotShowHelmet = 1
|
||||||
AiPlayerbot.RandomBotShowCloak = 1
|
AiPlayerbot.RandomBotShowCloak = 1
|
||||||
|
|
||||||
# Randombots and altbots automatically equip any items in their inventory that are sufficient upgrades
|
# Toggles whether altbots will automatically equip items in their inventory that are sufficient upgrades
|
||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
AiPlayerbot.AutoEquipUpgradeLoot = 1
|
AiPlayerbot.AutoEquipUpgradeLoot = 1
|
||||||
|
|
||||||
@@ -669,7 +670,7 @@ AiPlayerbot.DisableDeathKnightLogin = 0
|
|||||||
# Default: 0 (disabled)
|
# Default: 0 (disabled)
|
||||||
AiPlayerbot.LimitTalentsExpansion = 0
|
AiPlayerbot.LimitTalentsExpansion = 0
|
||||||
|
|
||||||
# Configure randombots and addClass bot trading (0: Disabled, 1: Enabled, 2: Only Buy, 3: Only Sell)
|
# Configure randombot trading (0: Disabled, 1: Enabled, 2: Only Buy, 3: Only Sell)
|
||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
AiPlayerbot.EnableRandomBotTrading = 1
|
AiPlayerbot.EnableRandomBotTrading = 1
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ bool AcceptInvitationAction::Execute(Event event)
|
|||||||
if (sRandomPlayerbotMgr->IsRandomBot(bot))
|
if (sRandomPlayerbotMgr->IsRandomBot(bot))
|
||||||
botAI->SetMaster(inviter);
|
botAI->SetMaster(inviter);
|
||||||
// else
|
// else
|
||||||
// sPlayerbotDbStore->Save(botAI);
|
// sPlayerbotRepository->Save(botAI);
|
||||||
|
|
||||||
botAI->ResetStrategies();
|
botAI->ResetStrategies();
|
||||||
botAI->ChangeStrategy("+follow,-lfg,-bg", BOT_STATE_NON_COMBAT);
|
botAI->ChangeStrategy("+follow,-lfg,-bg", BOT_STATE_NON_COMBAT);
|
||||||
@@ -75,36 +75,79 @@ void AutoMaintenanceOnLevelupAction::LearnSpells(std::ostringstream* out)
|
|||||||
void AutoMaintenanceOnLevelupAction::LearnTrainerSpells(std::ostringstream* out)
|
void AutoMaintenanceOnLevelupAction::LearnTrainerSpells(std::ostringstream* out)
|
||||||
{
|
{
|
||||||
PlayerbotFactory factory(bot, bot->GetLevel());
|
PlayerbotFactory factory(bot, bot->GetLevel());
|
||||||
|
factory.InitSkills();
|
||||||
factory.InitClassSpells();
|
factory.InitClassSpells();
|
||||||
factory.InitAvailableSpells();
|
factory.InitAvailableSpells();
|
||||||
factory.InitSkills();
|
|
||||||
factory.InitPet();
|
factory.InitPet();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoMaintenanceOnLevelupAction::LearnQuestSpells(std::ostringstream* out)
|
void AutoMaintenanceOnLevelupAction::LearnQuestSpells(std::ostringstream* out)
|
||||||
{
|
{
|
||||||
// CreatureTemplate const* co = sCreatureStorage.LookupEntry<CreatureTemplate>(id);
|
|
||||||
ObjectMgr::QuestMap const& questTemplates = sObjectMgr->GetQuestTemplates();
|
ObjectMgr::QuestMap const& questTemplates = sObjectMgr->GetQuestTemplates();
|
||||||
for (ObjectMgr::QuestMap::const_iterator i = questTemplates.begin(); i != questTemplates.end(); ++i)
|
for (ObjectMgr::QuestMap::const_iterator i = questTemplates.begin(); i != questTemplates.end(); ++i)
|
||||||
{
|
{
|
||||||
//uint32 questId = i->first; //not used, line marked for removal.
|
|
||||||
Quest const* quest = i->second;
|
Quest const* quest = i->second;
|
||||||
|
|
||||||
if (!quest->GetRequiredClasses() || quest->IsRepeatable() || quest->GetMinLevel() < 10)
|
// only process class-specific quests to learn class-related spells, cuz
|
||||||
|
// we don't want all these bunch of entries to be handled!
|
||||||
|
if (!quest->GetRequiredClasses())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!bot->SatisfyQuestClass(quest, false) || quest->GetMinLevel() > bot->GetLevel() ||
|
// skip quests that are repeatable, too low level, or above bots' level
|
||||||
!bot->SatisfyQuestRace(quest, false))
|
if (quest->IsRepeatable() || quest->GetMinLevel() < 10 || quest->GetMinLevel() > bot->GetLevel())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (quest->GetRewSpellCast() > 0)
|
// skip if bot doesnt satisfy class, race, or skill requirements
|
||||||
|
if (!bot->SatisfyQuestClass(quest, false) || !bot->SatisfyQuestRace(quest, false) ||
|
||||||
|
!bot->SatisfyQuestSkill(quest, false))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// use the same logic and impl from Player::learnQuestRewardedSpells
|
||||||
|
|
||||||
|
int32 spellId = quest->GetRewSpellCast();
|
||||||
|
if (!spellId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||||
|
if (!spellInfo)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// xinef: find effect with learn spell and check if we have this spell
|
||||||
|
bool found = false;
|
||||||
|
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||||
{
|
{
|
||||||
LearnSpell(quest->GetRewSpellCast(), out);
|
if (spellInfo->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL && spellInfo->Effects[i].TriggerSpell &&
|
||||||
|
!bot->HasSpell(spellInfo->Effects[i].TriggerSpell))
|
||||||
|
{
|
||||||
|
// pusywizard: don't re-add profession specialties!
|
||||||
|
if (SpellInfo const* triggeredInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[i].TriggerSpell))
|
||||||
|
if (triggeredInfo->Effects[0].Effect == SPELL_EFFECT_TRADE_SKILL)
|
||||||
|
break; // pussywizard: break and not cast the spell (found is false)
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (quest->GetRewSpell() > 0)
|
|
||||||
|
// xinef: we know the spell, continue
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bot->CastSpell(bot, spellId, true);
|
||||||
|
|
||||||
|
// Check if RewardDisplaySpell is set to output the proper spell learned
|
||||||
|
// after processing quests. Output the original RewardSpell otherwise.
|
||||||
|
uint32 rewSpellId = quest->GetRewSpell();
|
||||||
|
if (rewSpellId)
|
||||||
{
|
{
|
||||||
LearnSpell(quest->GetRewSpell(), out);
|
if (SpellInfo const* rewSpellInfo = sSpellMgr->GetSpellInfo(rewSpellId))
|
||||||
|
{
|
||||||
|
*out << FormatSpell(rewSpellInfo) << ", ";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*out << FormatSpell(spellInfo) << ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,39 +164,6 @@ std::string const AutoMaintenanceOnLevelupAction::FormatSpell(SpellInfo const* s
|
|||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoMaintenanceOnLevelupAction::LearnSpell(uint32 spellId, std::ostringstream* out)
|
|
||||||
{
|
|
||||||
SpellInfo const* proto = sSpellMgr->GetSpellInfo(spellId);
|
|
||||||
if (!proto)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool learned = false;
|
|
||||||
for (uint8 j = 0; j < 3; ++j)
|
|
||||||
{
|
|
||||||
if (proto->Effects[j].Effect == SPELL_EFFECT_LEARN_SPELL)
|
|
||||||
{
|
|
||||||
uint32 learnedSpell = proto->Effects[j].TriggerSpell;
|
|
||||||
|
|
||||||
if (!bot->HasSpell(learnedSpell))
|
|
||||||
{
|
|
||||||
bot->learnSpell(learnedSpell);
|
|
||||||
*out << FormatSpell(sSpellMgr->GetSpellInfo(learnedSpell)) << ", ";
|
|
||||||
}
|
|
||||||
|
|
||||||
learned = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!learned)
|
|
||||||
{
|
|
||||||
if (!bot->HasSpell(spellId))
|
|
||||||
{
|
|
||||||
bot->learnSpell(spellId);
|
|
||||||
*out << FormatSpell(proto) << ", ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AutoMaintenanceOnLevelupAction::AutoUpgradeEquip()
|
void AutoMaintenanceOnLevelupAction::AutoUpgradeEquip()
|
||||||
{
|
{
|
||||||
if (!sPlayerbotAIConfig->autoUpgradeEquip || !sRandomPlayerbotMgr->IsRandomBot(bot))
|
if (!sPlayerbotAIConfig->autoUpgradeEquip || !sRandomPlayerbotMgr->IsRandomBot(bot))
|
||||||
@@ -28,7 +28,6 @@ protected:
|
|||||||
void LearnSpells(std::ostringstream* out);
|
void LearnSpells(std::ostringstream* out);
|
||||||
void LearnTrainerSpells(std::ostringstream* out);
|
void LearnTrainerSpells(std::ostringstream* out);
|
||||||
void LearnQuestSpells(std::ostringstream* out);
|
void LearnQuestSpells(std::ostringstream* out);
|
||||||
void LearnSpell(uint32 spellId, std::ostringstream* out);
|
|
||||||
std::string const FormatSpell(SpellInfo const* sInfo);
|
std::string const FormatSpell(SpellInfo const* sInfo);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "ChangeStrategyAction.h"
|
#include "ChangeStrategyAction.h"
|
||||||
|
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "PlayerbotDbStore.h"
|
#include "PlayerbotRepository.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
|
||||||
bool ChangeCombatStrategyAction::Execute(Event event)
|
bool ChangeCombatStrategyAction::Execute(Event event)
|
||||||
@@ -24,7 +24,7 @@ bool ChangeCombatStrategyAction::Execute(Event event)
|
|||||||
case '+':
|
case '+':
|
||||||
case '-':
|
case '-':
|
||||||
case '~':
|
case '~':
|
||||||
sPlayerbotDbStore->Save(botAI);
|
sPlayerbotRepository->Save(botAI);
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
break;
|
break;
|
||||||
@@ -62,7 +62,7 @@ bool ChangeNonCombatStrategyAction::Execute(Event event)
|
|||||||
case '+':
|
case '+':
|
||||||
case '-':
|
case '-':
|
||||||
case '~':
|
case '~':
|
||||||
sPlayerbotDbStore->Save(botAI);
|
sPlayerbotRepository->Save(botAI);
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
break;
|
break;
|
||||||
@@ -261,7 +261,9 @@ bool MoveNearWaterAction::isUseful()
|
|||||||
return false;
|
return false;
|
||||||
FishingSpotValue* fishingSpotValueObject = (FishingSpotValue*)context->GetValue<WorldPosition>("fishing spot");
|
FishingSpotValue* fishingSpotValueObject = (FishingSpotValue*)context->GetValue<WorldPosition>("fishing spot");
|
||||||
WorldPosition pos = fishingSpotValueObject->Get();
|
WorldPosition pos = fishingSpotValueObject->Get();
|
||||||
return !pos.IsValid() || fishingSpotValueObject->IsStale(FISHING_LOCATION_TIMEOUT) || pos != bot->GetPosition();
|
return !pos.IsValid() || fishingSpotValueObject->IsStale(FISHING_LOCATION_TIMEOUT) ||
|
||||||
|
bot->GetExactDist(&pos) < 0.1f;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MoveNearWaterAction::isPossible()
|
bool MoveNearWaterAction::isPossible()
|
||||||
@@ -299,6 +301,17 @@ bool MoveNearWaterAction::isPossible()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Can the bot fish from current position?
|
||||||
|
WorldPosition waterAtCurrentPos =
|
||||||
|
FindWaterRadial(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), bot->GetMap(),
|
||||||
|
bot->GetPhaseMask(), MIN_DISTANCE_TO_WATER, MAX_DISTANCE_TO_WATER, SEARCH_INCREMENT, true);
|
||||||
|
if (waterAtCurrentPos.IsValid())
|
||||||
|
{
|
||||||
|
SET_AI_VALUE(WorldPosition, "fishing spot",
|
||||||
|
WorldPosition(WorldPosition(bot->GetMapId(), bot->GetPositionX(), bot->GetPositionY(),
|
||||||
|
bot->GetPositionZ())));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Lets find some water where we can fish.
|
// Lets find some water where we can fish.
|
||||||
WorldPosition water = FindWaterRadial(
|
WorldPosition water = FindWaterRadial(
|
||||||
bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
||||||
@@ -435,10 +448,14 @@ bool FishingAction::isUseful()
|
|||||||
{
|
{
|
||||||
if (!AI_VALUE(bool, "can fish"))
|
if (!AI_VALUE(bool, "can fish"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FishingSpotValue* fishingSpotValueObject = (FishingSpotValue*)context->GetValue<WorldPosition>("fishing spot");
|
FishingSpotValue* fishingSpotValueObject = (FishingSpotValue*)context->GetValue<WorldPosition>("fishing spot");
|
||||||
WorldPosition pos = fishingSpotValueObject->Get();
|
WorldPosition pos = fishingSpotValueObject->Get();
|
||||||
|
|
||||||
return pos.IsValid() && !fishingSpotValueObject->IsStale(FISHING_LOCATION_TIMEOUT) && pos == bot->GetPosition();
|
if (!pos.IsValid() || fishingSpotValueObject->IsStale(FISHING_LOCATION_TIMEOUT))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return bot->GetExactDist(&pos) < 0.1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UseBobberAction::isUseful()
|
bool UseBobberAction::isUseful()
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user