[HOT FIX] MS build issues regarding folder / command lenght usage or rc.exe (#2038)

This commit is contained in:
bashermens
2026-01-19 22:45:28 +01:00
committed by GitHub
parent fd07e02a8a
commit 41c53365ae
1119 changed files with 27 additions and 27 deletions

View File

@@ -0,0 +1,265 @@
/*
* 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 "WarlockTriggers.h"
#include "GenericTriggers.h"
#include "Playerbots.h"
#include "PlayerbotAI.h"
#include "Player.h"
static const uint32 SOUL_SHARD_ITEM_ID = 6265;
uint32 GetSoulShardCount(Player* bot)
{
return bot->GetItemCount(SOUL_SHARD_ITEM_ID, false); // false = only bags
}
// List of all Soulstone item IDs
static const std::vector<uint32> soulstoneItemIds = {
5232, // Minor Soulstone
16892, // Lesser Soulstone
16893, // Soulstone
16895, // Greater Soulstone
16896, // Major Soulstone
22116, // Master Soulstone
36895 // Demonic Soulstone
};
uint32 GetSoulstoneCount(Player* bot)
{
uint32 count = 0;
for (uint32 id : soulstoneItemIds)
count += bot->GetItemCount(id, false); // false = only bags
return count;
}
bool SpellstoneTrigger::IsActive() { return BuffTrigger::IsActive() && AI_VALUE2(uint32, "item count", getName()) > 0; }
bool FirestoneTrigger::IsActive() { return BuffTrigger::IsActive() && AI_VALUE2(uint32, "item count", getName()) > 0; }
bool WarlockConjuredItemTrigger::IsActive()
{
return ItemCountTrigger::IsActive() && AI_VALUE2(uint32, "item count", "soul shard") > 0;
}
bool OutOfSoulShardsTrigger::IsActive() { return GetSoulShardCount(botAI->GetBot()) == 0; }
bool TooManySoulShardsTrigger::IsActive() { return GetSoulShardCount(botAI->GetBot()) >= 26; }
bool OutOfSoulstoneTrigger::IsActive() { return GetSoulstoneCount(botAI->GetBot()) == 0; }
// Checks if the target marked with the moon icon can be banished
bool BanishTrigger::IsActive()
{
Unit* ccTarget = context->GetValue<Unit*>("cc target", "banish")->Get();
Unit* moonTarget = context->GetValue<Unit*>("rti cc target")->Get();
return ccTarget && moonTarget && ccTarget == moonTarget && HasCcTargetTrigger::IsActive();
}
// Checks if the target marked with the moon icon can be feared
bool FearTrigger::IsActive()
{
Unit* ccTarget = context->GetValue<Unit*>("cc target", "fear")->Get();
Unit* moonTarget = context->GetValue<Unit*>("rti cc target")->Get();
return ccTarget && moonTarget && ccTarget == moonTarget && HasCcTargetTrigger::IsActive();
}
bool DemonArmorTrigger::IsActive()
{
Unit* target = GetTarget();
return !botAI->HasAura("demon skin", target) && !botAI->HasAura("demon armor", target) &&
!botAI->HasAura("fel armor", target);
}
bool SoulLinkTrigger::IsActive()
{
Unit* target = GetTarget();
return !botAI->HasAura("soul link", target);
}
bool DemonicEmpowermentTrigger::IsActive()
{
Pet* pet = bot->GetPet();
if (!pet)
return false;
return !botAI->HasAura("demonic empowerment", pet);
}
bool DecimationTrigger::IsActive()
{
Aura* aura = botAI->GetAura(getName(), GetTarget(), false, true);
return aura && aura->GetDuration() > 3000;
}
// Checks if the bot's mana is below 85% and health is above a low health threshold
bool LifeTapTrigger::IsActive()
{
if (AI_VALUE2(uint8, "health", "self target") <= sPlayerbotAIConfig->lowHealth)
return false;
if (!AI_VALUE2(bool, "has mana", "self target"))
return false;
if (AI_VALUE2(uint8, "mana", "self target") >= 85)
return false;
return true;
}
// Checks if the Life Tap Glyph buff is active
bool LifeTapGlyphBuffTrigger::IsActive()
{
if (!botAI->HasAura(63320, bot))
return false;
return BuffTrigger::IsActive();
}
// Checks if the target has a conflicting debuff that is equal to Curse of the Elements
bool CurseOfTheElementsTrigger::IsActive()
{
Unit* target = GetTarget();
if (!target || !target->IsAlive() || !target->IsInWorld())
return false;
// List of all spell IDs for Ebon Plague, Earth and Moon, and Curse of the Elements
static const uint32 CurseOfTheElementsExclusiveDebuffs[] = {// Ebon Plague
51735, 51734, 51726,
// Earth and Moon
48511, 48513, 48514,
// Curse of the Elements
1490, 11721, 11722, 27228, 47865};
// Check if target has any of the exclusive debuffs
for (uint32 spellId : CurseOfTheElementsExclusiveDebuffs)
{
if (target->HasAura(spellId))
return false;
}
// Use default BuffTrigger logic for the rest (only trigger if debuff is missing or expiring)
return BuffTrigger::IsActive();
}
// Checks if the target has a conflicting debuff that is equal to Curse of Weakness
bool CurseOfWeaknessTrigger::IsActive()
{
Unit* target = GetTarget();
if (!target || !target->IsAlive() || !target->IsInWorld())
return false;
// List of all spell IDs for Curse of Weakness, Demoralizing Roar, Demoralizing Shout, and Vindication
static const uint32 CurseOfWeaknessExclusiveDebuffs[] = {// Curse of Weakness
702, 1108, 6205, 7646, 11707, 11708, 27224, 30909, 50511,
// Demoralizing Roar
99, 1735, 9490, 9747, 9898, 26998, 48559, 48560,
// Demoralizing Shout
1160, 6190, 11554, 11555, 11556, 25202, 25203, 47437,
// Vindication
67, 26017};
// Check if target has any of the exclusive debuffs
for (uint32 spellId : CurseOfWeaknessExclusiveDebuffs)
{
if (target->HasAura(spellId))
return false;
}
// Use default BuffTrigger logic for the rest (only trigger if debuff is missing or expiring)
return BuffTrigger::IsActive();
}
struct WarlockPetDef
{
const char* strategy; // The strategy string as recognized by the AI (e.g., "imp", "voidwalker", etc.)
uint32 spellId; // The spell ID required to summon this pet
uint32 npcEntry; // The NPC entry ID for the summoned pet creature
};
// Static array with all relevant Warlock pets and their data
static const WarlockPetDef pets[] = {{"imp", 688, 416},
{"voidwalker", 697, 1860},
{"succubus", 712, 1863},
{"felhunter", 691, 417},
{"felguard", 30146, 17252}};
bool WrongPetTrigger::IsActive()
{
// Retrieve the bot player and its current pet (if any)
Player* bot = botAI->GetBot();
Pet* pet = bot->GetPet();
// Step 1: Count how many pet strategies are currently enabled for this bot.
// While doing so, also remember which pet strategy is the only enabled one (if that's the case).
int enabledCount = 0;
const WarlockPetDef* enabledPet =
nullptr; // Pointer to the pet definition of the enabled strategy, if only one is enabled
for (const WarlockPetDef& pd : pets)
{
if (botAI->HasStrategy(pd.strategy, BOT_STATE_NON_COMBAT))
{
enabledCount++;
enabledPet = &pd; // Save the pointer to last enabled pet
}
}
// Step 2: If not exactly one pet strategy is enabled, we should not trigger.
// This prevents ambiguous or conflicting situations.
if (enabledCount != 1)
return false;
// Step 3: If there is no pet, do not trigger.
if (!pet)
return false;
// Step 4: At this point, we know only one pet strategy is enabled.
// We check if the currently summoned pet matches the enabled strategy.
bool correctPet = false;
if (pet)
{
CreatureTemplate const* ct = pet->GetCreatureTemplate();
// Check if the pet's NPC entry matches the expected one for the enabled strategy
if (ct && ct->Entry == enabledPet->npcEntry)
correctPet = true;
}
// Step 5: If the correct pet is already summoned, the trigger should not activate.
if (correctPet)
return false;
// Step 6: Finally, check if the bot actually knows the spell to summon the desired pet.
// If so, the trigger is active (bot should summon the correct pet).
if (bot->HasSpell(enabledPet->spellId))
return true;
// Step 7: If we get here, the bot doesn't know the spell required to support the active pet strategy
return false;
}
const std::set<uint32> RainOfFireChannelCheckTrigger::RAIN_OF_FIRE_SPELL_IDS = {
5740, // Rain of Fire Rank 1
6219, // Rain of Fire Rank 2
11677, // Rain of Fire Rank 3
11678, // Rain of Fire Rank 4
27212, // Rain of Fire Rank 5
47819, // Rain of Fire Rank 6
47820 // Rain of Fire Rank 7
};
bool RainOfFireChannelCheckTrigger::IsActive()
{
Player* bot = botAI->GetBot();
// Check if the bot is channeling a spell
if (Spell* spell = bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
{
// Only trigger if the spell being channeled is Rain of Fire
if (RAIN_OF_FIRE_SPELL_IDS.count(spell->m_spellInfo->Id))
{
uint8 attackerCount = AI_VALUE(uint8, "attacker count");
return attackerCount < minEnemies;
}
}
// Not channeling Rain of Fire
return false;
}

View File

@@ -0,0 +1,351 @@
/*
* 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_WARLOCKTRIGGERS_H
#define _PLAYERBOT_WARLOCKTRIGGERS_H
#include "GenericTriggers.h"
#include "PlayerbotAI.h"
#include "Playerbots.h"
#include "CureTriggers.h"
#include "Trigger.h"
#include <set>
class PlayerbotAI;
// Buff and Out of Combat Triggers
class DemonArmorTrigger : public BuffTrigger
{
public:
DemonArmorTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "demon armor") {}
bool IsActive() override;
};
class SoulLinkTrigger : public BuffTrigger
{
public:
SoulLinkTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "soul link") {}
bool IsActive() override;
};
class OutOfSoulShardsTrigger : public Trigger
{
public:
OutOfSoulShardsTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no soul shard", 2) {}
bool IsActive() override;
};
class TooManySoulShardsTrigger : public Trigger
{
public:
TooManySoulShardsTrigger(PlayerbotAI* botAI) : Trigger(botAI, "too many soul shards") {}
bool IsActive() override;
};
class FirestoneTrigger : public BuffTrigger
{
public:
FirestoneTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "firestone") {}
bool IsActive() override;
};
class SpellstoneTrigger : public BuffTrigger
{
public:
SpellstoneTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "spellstone") {}
bool IsActive() override;
};
class OutOfSoulstoneTrigger : public Trigger
{
public:
OutOfSoulstoneTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no soulstone") {}
bool IsActive() override;
};
class SoulstoneTrigger : public Trigger
{
public:
SoulstoneTrigger(PlayerbotAI* botAI) : Trigger(botAI, "soulstone") {}
bool IsActive() override
{
static const std::vector<uint32> soulstoneSpellIds = {20707, 20762, 20763, 20764, 20765, 27239, 47883};
if (AI_VALUE2(uint32, "item count", "soulstone") == 0)
return false;
for (uint32 spellId : soulstoneSpellIds)
{
if (!bot->HasSpellCooldown(spellId))
return true; // Ready to use
}
return false; // All are on cooldown
}
};
class WarlockConjuredItemTrigger : public ItemCountTrigger
{
public:
WarlockConjuredItemTrigger(PlayerbotAI* botAI, std::string const item) : ItemCountTrigger(botAI, item, 1) {}
bool IsActive() override;
};
class HasSpellstoneTrigger : public WarlockConjuredItemTrigger
{
public:
HasSpellstoneTrigger(PlayerbotAI* botAI) : WarlockConjuredItemTrigger(botAI, "spellstone") {}
};
class HasFirestoneTrigger : public WarlockConjuredItemTrigger
{
public:
HasFirestoneTrigger(PlayerbotAI* botAI) : WarlockConjuredItemTrigger(botAI, "firestone") {}
};
class HasHealthstoneTrigger : public WarlockConjuredItemTrigger
{
public:
HasHealthstoneTrigger(PlayerbotAI* botAI) : WarlockConjuredItemTrigger(botAI, "healthstone") {}
};
class WrongPetTrigger : public Trigger
{
public:
WrongPetTrigger(PlayerbotAI* botAI) : Trigger(botAI, "wrong pet") {}
bool IsActive() override;
};
// CC and Pet Triggers
class BanishTrigger : public HasCcTargetTrigger
{
public:
BanishTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "banish") {}
bool IsActive() override;
};
class FearTrigger : public HasCcTargetTrigger
{
public:
FearTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "fear") {}
bool IsActive() override;
};
class SpellLockInterruptSpellTrigger : public InterruptSpellTrigger
{
public:
SpellLockInterruptSpellTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "spell lock") {}
};
class DevourMagicPurgeTrigger : public TargetAuraDispelTrigger
{
public:
DevourMagicPurgeTrigger(PlayerbotAI* botAI) : TargetAuraDispelTrigger(botAI, "devour magic", DISPEL_MAGIC) {}
};
class DevourMagicCleanseTrigger : public PartyMemberNeedCureTrigger
{
public:
DevourMagicCleanseTrigger(PlayerbotAI* botAI) : PartyMemberNeedCureTrigger(botAI, "devour magic", DISPEL_MAGIC) {}
};
// DoT/Curse Triggers
class CorruptionTrigger : public DebuffTrigger
{
public:
CorruptionTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "corruption", 1, true, 0.5f) {}
bool IsActive() override
{
return BuffTrigger::IsActive() && !botAI->HasAura("seed of corruption", GetTarget(), false, true);
}
};
class CorruptionOnAttackerTrigger : public DebuffOnAttackerTrigger
{
public:
CorruptionOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "corruption", true) {}
bool IsActive() override
{
return BuffTrigger::IsActive() && !botAI->HasAura("seed of corruption", GetTarget(), false, true);
}
};
class ImmolateTrigger : public DebuffTrigger
{
public:
ImmolateTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "immolate", 1, true, 0.5f) {}
bool IsActive() override { return BuffTrigger::IsActive(); }
};
class ImmolateOnAttackerTrigger : public DebuffOnAttackerTrigger
{
public:
ImmolateOnAttackerTrigger(PlayerbotAI* ai) : DebuffOnAttackerTrigger(ai, "immolate", true) {}
bool IsActive() override { return BuffTrigger::IsActive(); }
};
class UnstableAfflictionTrigger : public DebuffTrigger
{
public:
UnstableAfflictionTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "unstable affliction", 1, true, 0.5f) {}
bool IsActive() override { return BuffTrigger::IsActive(); }
};
class UnstableAfflictionOnAttackerTrigger : public DebuffOnAttackerTrigger
{
public:
UnstableAfflictionOnAttackerTrigger(PlayerbotAI* ai) : DebuffOnAttackerTrigger(ai, "unstable affliction", true) {}
bool IsActive() override { return BuffTrigger::IsActive(); }
};
class HauntTrigger : public DebuffTrigger
{
public:
HauntTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "haunt", 1, true, 0) {}
};
class CurseOfAgonyTrigger : public DebuffTrigger
{
public:
CurseOfAgonyTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "curse of agony", 1, true, 0.5f) {}
bool IsActive() override { return BuffTrigger::IsActive(); }
};
class CurseOfAgonyOnAttackerTrigger : public DebuffOnAttackerTrigger
{
public:
CurseOfAgonyOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "curse of agony", true) {}
bool IsActive() override { return BuffTrigger::IsActive(); }
};
class CurseOfTheElementsTrigger : public DebuffTrigger
{
public:
CurseOfTheElementsTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "curse of the elements", 1, true, 0.5f) {}
bool IsActive() override;
};
class CurseOfDoomTrigger : public DebuffTrigger
{
public:
CurseOfDoomTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "curse of doom", 1, true, 0.5f) {}
bool IsActive() override { return BuffTrigger::IsActive(); }
};
class CurseOfExhaustionTrigger : public DebuffTrigger
{
public:
CurseOfExhaustionTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "curse of exhaustion", 1, true, 0.5f) {}
bool IsActive() override { return BuffTrigger::IsActive(); }
};
class CurseOfTonguesTrigger : public DebuffTrigger
{
public:
CurseOfTonguesTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "curse of tongues", 1, true, 0.5f) {}
bool IsActive() override { return BuffTrigger::IsActive(); }
};
class CurseOfWeaknessTrigger : public DebuffTrigger
{
public:
CurseOfWeaknessTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "curse of weakness", 1, true, 0.5f) {}
bool IsActive() override;
};
// Proc/Cooldown Triggers
class LifeTapTrigger : public Trigger
{
public:
LifeTapTrigger(PlayerbotAI* ai) : Trigger(ai, "life tap") {}
bool IsActive() override;
};
class LifeTapGlyphBuffTrigger : public BuffTrigger
{
public:
LifeTapGlyphBuffTrigger(PlayerbotAI* ai) : BuffTrigger(ai, "life tap") {}
bool IsActive() override;
};
class MetamorphosisTrigger : public BoostTrigger
{
public:
MetamorphosisTrigger(PlayerbotAI* ai) : BoostTrigger(ai, "metamorphosis") {}
};
class DemonicEmpowermentTrigger : public BuffTrigger
{
public:
DemonicEmpowermentTrigger(PlayerbotAI* ai) : BuffTrigger(ai, "demonic empowerment") {}
bool IsActive() override;
};
class ImmolationAuraActiveTrigger : public HasAuraTrigger
{
public:
ImmolationAuraActiveTrigger(PlayerbotAI* ai) : HasAuraTrigger(ai, "immolation aura") {}
};
class ShadowTranceTrigger : public HasAuraTrigger
{
public:
ShadowTranceTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "shadow trance") {}
};
class BacklashTrigger : public HasAuraTrigger
{
public:
BacklashTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "backlash") {}
};
class DecimationTrigger : public HasAuraTrigger
{
public:
DecimationTrigger(PlayerbotAI* ai) : HasAuraTrigger(ai, "decimation") {}
bool IsActive() override;
};
class MoltenCoreTrigger : public HasAuraTrigger
{
public:
MoltenCoreTrigger(PlayerbotAI* ai) : HasAuraTrigger(ai, "molten core") {}
};
class MetamorphosisNotActiveTrigger : public HasNoAuraTrigger
{
public:
MetamorphosisNotActiveTrigger(PlayerbotAI* ai) : HasNoAuraTrigger(ai, "metamorphosis") {}
};
class MetaMeleeEnemyTooCloseForSpellTrigger : public TwoTriggers
{
public:
MetaMeleeEnemyTooCloseForSpellTrigger(PlayerbotAI* ai)
: TwoTriggers(ai, "enemy too close for spell", "metamorphosis not active") {}
};
class RainOfFireChannelCheckTrigger : public Trigger
{
public:
RainOfFireChannelCheckTrigger(PlayerbotAI* botAI, uint32 minEnemies = 2)
: Trigger(botAI, "rain of fire channel check"), minEnemies(minEnemies)
{
}
bool IsActive() override;
protected:
uint32 minEnemies;
static const std::set<uint32> RAIN_OF_FIRE_SPELL_IDS;
};
#endif