mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
movement action
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
# Playerbots Module
|
# Playerbots Module
|
||||||
|
|
||||||
This is a WIP Playerbots module for AzerothCore based on IKE3 Playerbots. Code is port from: https://github.com/ZhengPeiRu21/mod-playerbots.
|
This is a WIP Playerbots module for AzerothCore based on IKE3 Playerbots. Code is port from: https://github.com/ZhengPeiRu21/mod-playerbots
|
||||||
|
|
||||||
I tried to fix many bugs based on the source code, making this playable, and tried to add more interesting functions, such as automatic positioning of the robot to deal with different raid bosses.
|
I tried to fix many bugs based on the source code, making this playable, and tried to add more interesting functions, such as automatic positioning of the robot to deal with different raid bosses.
|
||||||
|
|
||||||
You can use this addon to better control the bot and avoid typing a lot of commands: https://github.com/liyunfan1223/unbot-addon.
|
You can use this addon to better control the bot and avoid typing a lot of commands: https://github.com/liyunfan1223/unbot-addon
|
||||||
|
|
||||||
These Playerbots use actual player data, so it is capable to use own alts and play with own party, level up characters, and more. It is mostly usuable but still has many bugs that need to be resolved. Also please note that including this module will currently significantly increase compilation time for AzerothCore.
|
These Playerbots use actual player data, so it is capable to use own alts and play with own party, level up characters, and more. It is mostly usuable but still has many bugs that need to be resolved. Also please note that including this module will currently significantly increase compilation time for AzerothCore.
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ AiPlayerbot.MinEnchantingBotLevel = 60
|
|||||||
|
|
||||||
# Randombots checking players gear score level and deny the group invite if it's too low
|
# Randombots checking players gear score level and deny the group invite if it's too low
|
||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
AiPlayerbot.GearScoreCheck = 1
|
AiPlayerbot.GearScoreCheck = 0
|
||||||
|
|
||||||
# Quest that will be completed and rewarded to all random bots
|
# Quest that will be completed and rewarded to all random bots
|
||||||
AiPlayerbot.RandomBotQuestIds = "7848,3802,5505,6502,7761"
|
AiPlayerbot.RandomBotQuestIds = "7848,3802,5505,6502,7761"
|
||||||
|
|||||||
@@ -496,7 +496,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
|||||||
nonCombatEngine->addStrategies("dps assist", "cure", nullptr);
|
nonCombatEngine->addStrategies("dps assist", "cure", nullptr);
|
||||||
break;
|
break;
|
||||||
case CLASS_MAGE:
|
case CLASS_MAGE:
|
||||||
if (tab == 1)
|
if (tab == MAGE_TAB_ARCANE || tab == MAGE_TAB_FIRE)
|
||||||
nonCombatEngine->addStrategy("bdps");
|
nonCombatEngine->addStrategy("bdps");
|
||||||
else
|
else
|
||||||
nonCombatEngine->addStrategy("bmana");
|
nonCombatEngine->addStrategy("bmana");
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ObjectGuid.h"
|
#include "ObjectGuid.h"
|
||||||
|
#include "Player.h"
|
||||||
|
#include "PlayerbotAI.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
#include "AiFactory.h"
|
#include "AiFactory.h"
|
||||||
#include "BudgetValues.h"
|
#include "BudgetValues.h"
|
||||||
@@ -1306,22 +1308,22 @@ bool PlayerbotAI::IsTank(Player* player)
|
|||||||
switch (player->getClass())
|
switch (player->getClass())
|
||||||
{
|
{
|
||||||
case CLASS_DEATH_KNIGHT:
|
case CLASS_DEATH_KNIGHT:
|
||||||
if (tab == 0) {
|
if (tab == DEATHKNIGT_TAB_BLOOD) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLASS_PALADIN:
|
case CLASS_PALADIN:
|
||||||
if (tab == 1) {
|
if (tab == PALADIN_TAB_PROTECTION) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLASS_WARRIOR:
|
case CLASS_WARRIOR:
|
||||||
if (tab == 2) {
|
if (tab == WARRIOR_TAB_PROTECTION) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLASS_DRUID:
|
case CLASS_DRUID:
|
||||||
if (tab == 1 && HasAnyAuraOf(player, "bear form", "dire bear form", "thick hide", NULL)) {
|
if (tab == DRUID_TAB_FERAL && HasAnyAuraOf(player, "bear form", "dire bear form", "thick hide", NULL)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -131,7 +131,7 @@ bool HeiganDanceMeleeAction::Execute(Event event) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// botAI->TellMaster("Let\'s go " + std::to_string(curr_safe));
|
// botAI->TellMaster("Let\'s go " + std::to_string(curr_safe));
|
||||||
return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(), botAI->IsMainTank(bot) ? 0 : 0.5f);
|
return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(), botAI->IsMainTank(bot) ? 0 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HeiganDanceRangedAction::Execute(Event event) {
|
bool HeiganDanceRangedAction::Execute(Event event) {
|
||||||
@@ -140,7 +140,7 @@ bool HeiganDanceRangedAction::Execute(Event event) {
|
|||||||
return MoveTo(bot->GetMapId(), platform.first, platform.second, 276.54f);
|
return MoveTo(bot->GetMapId(), platform.first, platform.second, 276.54f);
|
||||||
}
|
}
|
||||||
botAI->InterruptSpell();
|
botAI->InterruptSpell();
|
||||||
return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(), 0.5f);
|
return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool ThaddiusAttackNearestPetAction::isUseful()
|
// bool ThaddiusAttackNearestPetAction::isUseful()
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class BloodDKStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
|||||||
//creators["death rune_mastery"] = &death_rune_mastery;
|
//creators["death rune_mastery"] = &death_rune_mastery;
|
||||||
//creators["hysteria"] = &hysteria;
|
//creators["hysteria"] = &hysteria;
|
||||||
//creators["dancing weapon"] = &dancing_weapon;
|
//creators["dancing weapon"] = &dancing_weapon;
|
||||||
//creators["dark command"] = &dark_command;
|
creators["dark command"] = &dark_command;
|
||||||
creators["taunt spell"] = &dark_command;
|
creators["taunt spell"] = &dark_command;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ class BloodDKStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
|||||||
{
|
{
|
||||||
return new ActionNode ("heart strike",
|
return new ActionNode ("heart strike",
|
||||||
/*P*/ NextAction::array(0, new NextAction("frost presence"), nullptr),
|
/*P*/ NextAction::array(0, new NextAction("frost presence"), nullptr),
|
||||||
/*A*/ NextAction::array(0, new NextAction("death strike"), nullptr),
|
/*A*/ nullptr,
|
||||||
/*C*/ nullptr);
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ float HeiganDanceMultiplier::GetValue(Action* action)
|
|||||||
if (dynamic_cast<HeiganDanceAction*>(action) || dynamic_cast<CurePartyMemberAction*>(action)) {
|
if (dynamic_cast<HeiganDanceAction*>(action) || dynamic_cast<CurePartyMemberAction*>(action)) {
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
if (dynamic_cast<CastSpellAction*>(action))
|
if (dynamic_cast<CastSpellAction*>(action) && !dynamic_cast<CastMeleeSpellAction*>(action))
|
||||||
{
|
{
|
||||||
uint32 spellId = AI_VALUE2(uint32, "spell id", action->getName());
|
uint32 spellId = AI_VALUE2(uint32, "spell id", action->getName());
|
||||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||||
@@ -49,7 +49,7 @@ float HeiganDanceMultiplier::GetValue(Action* action)
|
|||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
uint32 castTime = spellInfo->CalcCastTime();
|
uint32 castTime = spellInfo->CalcCastTime();
|
||||||
if (castTime == 0) {
|
if (castTime == 0 && !spellInfo->IsChanneled()) {
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#ifndef _PLAYERBOT_PALADINACTIONS_H
|
#ifndef _PLAYERBOT_PALADINACTIONS_H
|
||||||
#define _PLAYERBOT_PALADINACTIONS_H
|
#define _PLAYERBOT_PALADINACTIONS_H
|
||||||
|
|
||||||
|
#include "AiObject.h"
|
||||||
#include "GenericSpellActions.h"
|
#include "GenericSpellActions.h"
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
|
|
||||||
@@ -20,10 +21,11 @@ BUFF_ACTION(CastSealOfCommandAction, "seal of command");
|
|||||||
BUFF_ACTION(CastSealOfVengeanceAction, "seal of vengeance");
|
BUFF_ACTION(CastSealOfVengeanceAction, "seal of vengeance");
|
||||||
|
|
||||||
// judgements
|
// judgements
|
||||||
DEBUFF_ACTION_R(CastJudgementAction, "judgement", 10.0f);
|
SPELL_ACTION(CastJudgementAction, "judgement");
|
||||||
DEBUFF_ACTION_R(CastJudgementOfLightAction, "judgement of light", 10.0f);
|
|
||||||
DEBUFF_ACTION_R(CastJudgementOfWisdomAction, "judgement of wisdom", 10.0f);
|
SPELL_ACTION(CastJudgementOfLightAction, "judgement of light");
|
||||||
DEBUFF_ACTION_R(CastJudgementOfJusticeAction, "judgement of justice", 10.0f);
|
SPELL_ACTION(CastJudgementOfWisdomAction, "judgement of wisdom");
|
||||||
|
SPELL_ACTION(CastJudgementOfJusticeAction, "judgement of justice");
|
||||||
|
|
||||||
// auras
|
// auras
|
||||||
BUFF_ACTION(CastDevotionAuraAction, "devotion aura");
|
BUFF_ACTION(CastDevotionAuraAction, "devotion aura");
|
||||||
@@ -39,7 +41,7 @@ SPELL_ACTION(CastHolyShockAction, "holy shock");
|
|||||||
HEAL_PARTY_ACTION(CastHolyShockOnPartyAction, "holy shock");
|
HEAL_PARTY_ACTION(CastHolyShockOnPartyAction, "holy shock");
|
||||||
|
|
||||||
// consecration
|
// consecration
|
||||||
SPELL_ACTION(CastConsecrationAction, "consecration");
|
MELEE_ACTION(CastConsecrationAction, "consecration");
|
||||||
|
|
||||||
// repentance
|
// repentance
|
||||||
SNARE_ACTION(CastRepentanceSnareAction, "repentance");
|
SNARE_ACTION(CastRepentanceSnareAction, "repentance");
|
||||||
|
|||||||
@@ -22,31 +22,57 @@ bool HasAggroValue::Calculate()
|
|||||||
|
|
||||||
while( ref )
|
while( ref )
|
||||||
{
|
{
|
||||||
ThreatMgr* threatMgr = ref->GetSource();
|
ThreatMgr *threatManager = ref->GetSource();
|
||||||
Unit* attacker = threatMgr->GetOwner();
|
Unit *attacker = threatManager->GetOwner();
|
||||||
Unit* victim = attacker->GetVictim();
|
if (attacker != target) {
|
||||||
if (victim == bot && target == attacker)
|
ref = ref->next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Unit *victim = attacker->GetVictim();
|
||||||
|
if (!victim) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ((victim == bot || (victim && victim->ToPlayer() && botAI->IsMainTank(victim->ToPlayer()))) && target == attacker)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
ref = ref->next();
|
ref = ref->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
ref = target->GetThreatMgr().getCurrentVictim();
|
|
||||||
if (ref)
|
|
||||||
{
|
|
||||||
if (Unit* victim = ref->getTarget())
|
|
||||||
{
|
|
||||||
if (Player* pl = victim->ToPlayer())
|
|
||||||
{
|
|
||||||
if (botAI->IsMainTank(pl))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Unit* target = GetTarget();
|
||||||
|
// if (!target)
|
||||||
|
// return true;
|
||||||
|
|
||||||
|
// HostileReference *ref = bot->getHostileRefMgr().getFirst();
|
||||||
|
// if (!ref)
|
||||||
|
// return true; // simulate as target is not atacking anybody yet
|
||||||
|
|
||||||
|
// while( ref )
|
||||||
|
// {
|
||||||
|
// ThreatMgr* threatMgr = ref->GetSource();
|
||||||
|
// Unit* attacker = threatMgr->GetOwner();
|
||||||
|
// Unit* victim = attacker->GetVictim();
|
||||||
|
// if (victim == bot && target == attacker)
|
||||||
|
// return true;
|
||||||
|
|
||||||
|
// ref = ref->next();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ref = target->GetThreatMgr().getCurrentVictim();
|
||||||
|
// if (ref)
|
||||||
|
// {
|
||||||
|
// if (Unit* victim = ref->getTarget())
|
||||||
|
// {
|
||||||
|
// if (Player* pl = victim->ToPlayer())
|
||||||
|
// {
|
||||||
|
// if (botAI->IsMainTank(pl))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 AttackerCountValue::Calculate()
|
uint8 AttackerCountValue::Calculate()
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class MyAttackerCountValue : public Uint8CalculatedValue, public Qualified
|
|||||||
class HasAggroValue : public BoolCalculatedValue, public Qualified
|
class HasAggroValue : public BoolCalculatedValue, public Qualified
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HasAggroValue(PlayerbotAI* botAI, std::string const name = "has agro") : BoolCalculatedValue(botAI, name) { }
|
HasAggroValue(PlayerbotAI* botAI, std::string const name = "has aggro") : BoolCalculatedValue(botAI, name) { }
|
||||||
|
|
||||||
Unit* GetTarget();
|
Unit* GetTarget();
|
||||||
bool Calculate() override;
|
bool Calculate() override;
|
||||||
|
|||||||
Reference in New Issue
Block a user