added custom AI for dungeonhelper bot
This commit is contained in:
1 parent
1a9cd340b7
commit
816d506867
4 files changed
+199
-2
No files matched your search
@@ -344,6 +344,19 @@ void LFGMgr::Update(uint32 diff)
|
|||||||
TC_LOG_DEBUG("lfg", "Low-population solo LFG group %s expired after %u seconds outside the dungeon.",
|
TC_LOG_DEBUG("lfg", "Low-population solo LFG group %s expired after %u seconds outside the dungeon.",
|
||||||
gguid.ToString().c_str(), uint32(lowPopulationOutsideTimeout));
|
gguid.ToString().c_str(), uint32(lowPopulationOutsideTimeout));
|
||||||
|
|
||||||
|
// LOWPOP_TIMEOUT_CLEANUP
|
||||||
|
// Mirror the clean client-side state produced by voluntary LeaveParty().
|
||||||
|
// Group::Disband()/RemoveGroupData() resets player state/group linkage,
|
||||||
|
// but the RideTicket must be cleared explicitly.
|
||||||
|
GuidSet const& lowPopulationPlayers = GetPlayers(gguid);
|
||||||
|
if (lowPopulationPlayers.size() == 1)
|
||||||
|
{
|
||||||
|
ObjectGuid const pguid = *lowPopulationPlayers.begin();
|
||||||
|
ClearTicket(pguid);
|
||||||
|
SendLfgUpdateStatus(pguid, LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE), true);
|
||||||
|
SendLfgUpdateStatus(pguid, LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE), false);
|
||||||
|
}
|
||||||
|
|
||||||
LeaveLfg(gguid);
|
LeaveLfg(gguid);
|
||||||
group->Disband();
|
group->Disband();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,12 @@
|
|||||||
// This is where scripts' loading functions should be declared:
|
// This is where scripts' loading functions should be declared:
|
||||||
|
|
||||||
|
|
||||||
|
// VIANO_ADVENTURERS
|
||||||
|
void AddSC_viano_adventurers();
|
||||||
|
|
||||||
// The name of this function should match:
|
// The name of this function should match:
|
||||||
// void Add${NameOfDirectory}Scripts()
|
// void Add${NameOfDirectory}Scripts()
|
||||||
void AddCustomScripts()
|
void AddCustomScripts()
|
||||||
{
|
{
|
||||||
|
AddSC_viano_adventurers();
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* Viano custom dungeon adventurers
|
||||||
|
* Initial melee companion implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ScriptMgr.h"
|
||||||
|
#include "ScriptedCreature.h"
|
||||||
|
#include "ObjectAccessor.h"
|
||||||
|
#include "Player.h"
|
||||||
|
#include "TemporarySummon.h"
|
||||||
|
#include "MotionMaster.h"
|
||||||
|
|
||||||
|
namespace VianoAdventurers
|
||||||
|
{
|
||||||
|
static constexpr float FOLLOW_DISTANCE = 2.5f;
|
||||||
|
static constexpr float FOLLOW_ANGLE = 3.14159265f;
|
||||||
|
static constexpr float TELEPORT_DISTANCE = 45.0f;
|
||||||
|
static constexpr uint32 UPDATE_INTERVAL = 500;
|
||||||
|
|
||||||
|
class npc_horde_adventurer_melee : public CreatureScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
npc_horde_adventurer_melee() : CreatureScript("npc_horde_adventurer_melee") { }
|
||||||
|
|
||||||
|
struct npc_horde_adventurer_meleeAI : public ScriptedAI
|
||||||
|
{
|
||||||
|
npc_horde_adventurer_meleeAI(Creature* creature) : ScriptedAI(creature) { }
|
||||||
|
|
||||||
|
ObjectGuid ownerGuid;
|
||||||
|
uint32 updateTimer = 0;
|
||||||
|
|
||||||
|
Player* GetOwnerPlayer() const
|
||||||
|
{
|
||||||
|
if (!ownerGuid)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return ObjectAccessor::GetPlayer(*me, ownerGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FollowOwner(Player* owner)
|
||||||
|
{
|
||||||
|
if (!owner)
|
||||||
|
return;
|
||||||
|
|
||||||
|
me->GetMotionMaster()->MoveFollow(owner, FOLLOW_DISTANCE, FOLLOW_ANGLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeAI() override
|
||||||
|
{
|
||||||
|
ScriptedAI::InitializeAI();
|
||||||
|
|
||||||
|
TempSummon* summon = me->ToTempSummon();
|
||||||
|
if (!summon)
|
||||||
|
{
|
||||||
|
me->DespawnOrUnsummon();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* summoner = summon->GetSummoner();
|
||||||
|
Player* owner = summoner ? summoner->ToPlayer() : nullptr;
|
||||||
|
if (!owner)
|
||||||
|
{
|
||||||
|
me->DespawnOrUnsummon();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ownerGuid = owner->GetGUID();
|
||||||
|
|
||||||
|
me->SetOwnerGUID(ownerGuid);
|
||||||
|
me->SetFaction(owner->GetFaction());
|
||||||
|
me->SetLevel(owner->getLevel());
|
||||||
|
me->UpdateLevelDependantStats();
|
||||||
|
|
||||||
|
me->SetReactState(REACT_PASSIVE);
|
||||||
|
FollowOwner(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
|
{
|
||||||
|
if (Player* owner = GetOwnerPlayer())
|
||||||
|
FollowOwner(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoveInLineOfSight(Unit* /*who*/) override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* SelectAssistTarget(Player* owner)
|
||||||
|
{
|
||||||
|
if (!owner)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (Unit* target = owner->GetVictim())
|
||||||
|
if (target->IsAlive() && me->IsValidAttackTarget(target))
|
||||||
|
return target;
|
||||||
|
|
||||||
|
for (Unit* attacker : owner->getAttackers())
|
||||||
|
if (attacker && attacker->IsAlive() && me->IsValidAttackTarget(attacker))
|
||||||
|
return attacker;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
if (updateTimer > diff)
|
||||||
|
{
|
||||||
|
updateTimer -= diff;
|
||||||
|
|
||||||
|
if (UpdateVictim())
|
||||||
|
DoMeleeAttackIfReady();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTimer = UPDATE_INTERVAL;
|
||||||
|
|
||||||
|
Player* owner = GetOwnerPlayer();
|
||||||
|
if (!owner || !owner->IsInWorld() || !me->IsInMap(owner))
|
||||||
|
{
|
||||||
|
me->DespawnOrUnsummon();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (me->getLevel() != owner->getLevel())
|
||||||
|
{
|
||||||
|
me->SetLevel(owner->getLevel());
|
||||||
|
me->UpdateLevelDependantStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (me->GetDistance(owner) > TELEPORT_DISTANCE)
|
||||||
|
{
|
||||||
|
me->CombatStop(true);
|
||||||
|
me->GetMotionMaster()->Clear();
|
||||||
|
|
||||||
|
me->NearTeleportTo(
|
||||||
|
owner->GetPositionX() + 1.5f,
|
||||||
|
owner->GetPositionY(),
|
||||||
|
owner->GetPositionZ(),
|
||||||
|
owner->GetOrientation()
|
||||||
|
);
|
||||||
|
|
||||||
|
FollowOwner(owner);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* desiredTarget = SelectAssistTarget(owner);
|
||||||
|
|
||||||
|
if (desiredTarget)
|
||||||
|
{
|
||||||
|
if (me->GetVictim() != desiredTarget)
|
||||||
|
AttackStart(desiredTarget);
|
||||||
|
}
|
||||||
|
else if (me->IsInCombat())
|
||||||
|
{
|
||||||
|
me->CombatStop(true);
|
||||||
|
FollowOwner(owner);
|
||||||
|
}
|
||||||
|
else if (!me->GetVictim())
|
||||||
|
{
|
||||||
|
FollowOwner(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UpdateVictim())
|
||||||
|
DoMeleeAttackIfReady();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CreatureAI* GetAI(Creature* creature) const override
|
||||||
|
{
|
||||||
|
return new npc_horde_adventurer_meleeAI(creature);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddSC_viano_adventurers()
|
||||||
|
{
|
||||||
|
using namespace VianoAdventurers;
|
||||||
|
new npc_horde_adventurer_melee();
|
||||||
|
}
|
||||||
@@ -419,7 +419,7 @@ class item_generic_limit_chance_above_60 : public ItemScript
|
|||||||
|
|
||||||
enum HordeAdventurerHorn
|
enum HordeAdventurerHorn
|
||||||
{
|
{
|
||||||
NPC_ORGRIMMAR_GRUNT = 3296
|
NPC_HORDE_ADVENTURER = 900001
|
||||||
};
|
};
|
||||||
|
|
||||||
class item_horde_adventurer_horn : public ItemScript
|
class item_horde_adventurer_horn : public ItemScript
|
||||||
@@ -445,7 +445,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
player->SummonCreature(
|
player->SummonCreature(
|
||||||
NPC_ORGRIMMAR_GRUNT,
|
NPC_HORDE_ADVENTURER,
|
||||||
player->GetPositionX() + 2.0f,
|
player->GetPositionX() + 2.0f,
|
||||||
player->GetPositionY(),
|
player->GetPositionY(),
|
||||||
player->GetPositionZ(),
|
player->GetPositionZ(),
|
||||||
|
|||||||
Reference in new issue
Block a user