mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-06-20 15:39:25 +02:00
commit
a02e4ca5c1
92
.github/workflows/windows_build.yml
vendored
92
.github/workflows/windows_build.yml
vendored
@ -1,4 +1,5 @@
|
|||||||
name: windows-build
|
name: windows-build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ "master", "test-staging" ]
|
branches: [ "master", "test-staging" ]
|
||||||
@ -6,7 +7,7 @@ on:
|
|||||||
branches: [ "master", "test-staging" ]
|
branches: [ "master", "test-staging" ]
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: "windows-build-${{ github.event.pull_request.number }}"
|
group: "windows-build-${{ github.event.pull_request.number || github.ref }}"
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@ -15,35 +16,108 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [windows-latest]
|
os: [windows-latest]
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
name: ${{ matrix.os }}
|
name: ${{ matrix.os }}
|
||||||
|
|
||||||
env:
|
env:
|
||||||
BOOST_ROOT: C:\local\boost_1_82_0
|
BOOST_ROOT: C:\local\boost_1_87_0
|
||||||
|
CMAKE_GENERATOR: Ninja
|
||||||
|
CTOOLS_BUILD: all
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout AzerothCore
|
- name: Checkout AzerothCore
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: 'mod-playerbots/azerothcore-wotlk'
|
repository: 'mod-playerbots/azerothcore-wotlk'
|
||||||
ref: ${{ (github.base_ref || github.ref_name) == 'test-staging' && 'test-staging' || 'Playerbot' }}
|
ref: ${{ (github.base_ref || github.ref_name) == 'test-staging' && 'test-staging' || 'Playerbot' }}
|
||||||
path: 'ac'
|
path: a
|
||||||
|
|
||||||
- name: Checkout Playerbot Module
|
- name: Checkout Playerbot Module
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: 'mod-playerbots/mod-playerbots'
|
repository: 'mod-playerbots/mod-playerbots'
|
||||||
#path: 'modules/mod-playerbots'
|
path: a/modules/mod-playerbots
|
||||||
path: ac/modules/mod-playerbots
|
|
||||||
|
- name: Move source tree to short path
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
if (Test-Path C:\ac) {
|
||||||
|
Remove-Item C:\ac -Recurse -Force
|
||||||
|
}
|
||||||
|
|
||||||
|
New-Item -ItemType Directory -Path C:\ac | Out-Null
|
||||||
|
|
||||||
|
robocopy "${{ github.workspace }}\a" "C:\ac" /MIR
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -le 7) {
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
exit $LASTEXITCODE
|
||||||
|
|
||||||
|
- name: Install Ninja
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
choco install ninja -y
|
||||||
|
|
||||||
- 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
|
working-directory: C:\ac
|
||||||
env:
|
env:
|
||||||
CONTINUOUS_INTEGRATION: true
|
CONTINUOUS_INTEGRATION: true
|
||||||
run: |
|
run: |
|
||||||
./acore.sh install-deps
|
./acore.sh install-deps
|
||||||
|
|
||||||
|
- name: Create AzerothCore CI config
|
||||||
|
shell: bash
|
||||||
|
working-directory: C:\ac
|
||||||
|
run: |
|
||||||
|
cat > conf/config.sh <<'EOF'
|
||||||
|
CCOMPILERC="cl"
|
||||||
|
CCOMPILERCXX="cl"
|
||||||
|
|
||||||
|
CTYPE="Release"
|
||||||
|
CSCRIPTS="static"
|
||||||
|
CMODULES="static"
|
||||||
|
CTOOLS_BUILD="all"
|
||||||
|
|
||||||
|
CCUSTOMOPTIONS="-DCMAKE_RC_COMPILER=rc -DCMAKE_NINJA_FORCE_RESPONSE_FILE=ON -DCMAKE_NINJA_CMCLDEPS_RC=OFF -DCMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS=ON -DCMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS=ON -DCMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES=ON -DCMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES=ON -DCMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES=ON -DCMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES=ON"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat conf/config.sh
|
||||||
|
|
||||||
|
- name: Setup MSVC
|
||||||
|
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756
|
||||||
|
with:
|
||||||
|
arch: x64
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash
|
shell: bash
|
||||||
working-directory: ac
|
working-directory: C:\ac
|
||||||
run: |
|
run: |
|
||||||
export CTOOLS_BUILD=all
|
export CTOOLS_BUILD=all
|
||||||
|
export CMAKE_GENERATOR=Ninja
|
||||||
|
|
||||||
|
export CC=cl
|
||||||
|
export CXX=cl
|
||||||
|
export RC=rc
|
||||||
|
|
||||||
|
cmake --version
|
||||||
|
ninja --version
|
||||||
|
|
||||||
|
echo "CMAKE_GENERATOR=$CMAKE_GENERATOR"
|
||||||
|
echo "CC=$CC"
|
||||||
|
echo "CXX=$CXX"
|
||||||
|
|
||||||
|
which cl || true
|
||||||
|
which rc || true
|
||||||
|
cl || true
|
||||||
|
rc || true
|
||||||
|
|
||||||
|
rm -rf var/build/obj
|
||||||
|
|
||||||
./acore.sh compiler build
|
./acore.sh compiler build
|
||||||
|
|||||||
@ -576,7 +576,7 @@ AiPlayerbot.AutoGearScoreLimit = 0
|
|||||||
# "mana" (bots have infinite mana)
|
# "mana" (bots have infinite mana)
|
||||||
# "power" (bots have infinite energy, rage, and runic power)
|
# "power" (bots have infinite energy, rage, and runic power)
|
||||||
# "taxi" (bots may use all flight paths, though they will not actually learn them)
|
# "taxi" (bots may use all flight paths, though they will not actually learn them)
|
||||||
# "raid" (bots use cheats implemented into raid strategies (currently only for SSC and Ulduar))
|
# "raid" (bots use certain cheats implemented into raid strategies)
|
||||||
# To use multiple cheats, separate them by commas below (e.g., to enable all, use "gold,health,mana,power,raid,taxi")
|
# To use multiple cheats, separate them by commas below (e.g., to enable all, use "gold,health,mana,power,raid,taxi")
|
||||||
# Default: food, taxi, and raid are enabled
|
# Default: food, taxi, and raid are enabled
|
||||||
AiPlayerbot.BotCheats = "food,taxi,raid"
|
AiPlayerbot.BotCheats = "food,taxi,raid"
|
||||||
@ -1430,15 +1430,15 @@ AiPlayerbot.PermanentlyInWorldTime = 31104000
|
|||||||
#
|
#
|
||||||
|
|
||||||
AiPlayerbot.PremadeSpecName.1.0 = arms pve
|
AiPlayerbot.PremadeSpecName.1.0 = arms pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.1.0 = 43418,43395,43423,43399,49084,43421
|
AiPlayerbot.PremadeSpecGlyph.1.0 = 43418,43395,43423,43399,43397,43421
|
||||||
AiPlayerbot.PremadeSpecLink.1.0.60 = 3022032023335100002012211231241
|
AiPlayerbot.PremadeSpecLink.1.0.60 = 3022032023335100002012211231241
|
||||||
AiPlayerbot.PremadeSpecLink.1.0.80 = 3022032023335100102012213231251-305-2033
|
AiPlayerbot.PremadeSpecLink.1.0.80 = 3022032023335100102012213231251-305-2033
|
||||||
AiPlayerbot.PremadeSpecName.1.1 = fury pve
|
AiPlayerbot.PremadeSpecName.1.1 = fury pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.1.1 = 43418,43395,43414,43399,49084,43432
|
AiPlayerbot.PremadeSpecGlyph.1.1 = 43418,43395,43414,43396,49084,43432
|
||||||
AiPlayerbot.PremadeSpecLink.1.1.60 = -305053000500310053120501351
|
AiPlayerbot.PremadeSpecLink.1.1.60 = -305053000500310053120501351
|
||||||
AiPlayerbot.PremadeSpecLink.1.1.80 = 32002300233-305053000500310153120511351
|
AiPlayerbot.PremadeSpecLink.1.1.80 = 32002300233-305053000500310153120511351
|
||||||
AiPlayerbot.PremadeSpecName.1.2 = prot pve
|
AiPlayerbot.PremadeSpecName.1.2 = prot pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.1.2 = 43424,43395,43425,43399,49084,45793
|
AiPlayerbot.PremadeSpecGlyph.1.2 = 43429,43397,43425,43399,49084,45797
|
||||||
AiPlayerbot.PremadeSpecLink.1.2.60 = --053351225000210521030113321
|
AiPlayerbot.PremadeSpecLink.1.2.60 = --053351225000210521030113321
|
||||||
AiPlayerbot.PremadeSpecLink.1.2.80 = 3500030023-301-053351225000210521030113321
|
AiPlayerbot.PremadeSpecLink.1.2.80 = 3500030023-301-053351225000210521030113321
|
||||||
AiPlayerbot.PremadeSpecName.1.3 = arms pvp
|
AiPlayerbot.PremadeSpecName.1.3 = arms pvp
|
||||||
@ -1467,13 +1467,13 @@ AiPlayerbot.PremadeSpecLink.1.5.80 = 0502300123-3-250031220223012521332113321
|
|||||||
AiPlayerbot.PremadeSpecName.2.0 = holy pve
|
AiPlayerbot.PremadeSpecName.2.0 = holy pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.2.0 = 41106,43367,45741,43368,43365,41109
|
AiPlayerbot.PremadeSpecGlyph.2.0 = 41106,43367,45741,43368,43365,41109
|
||||||
AiPlayerbot.PremadeSpecLink.2.0.60 = 50350151020013053100515221
|
AiPlayerbot.PremadeSpecLink.2.0.60 = 50350151020013053100515221
|
||||||
AiPlayerbot.PremadeSpecLink.2.0.80 = 50350152220013053100515221-503201312
|
AiPlayerbot.PremadeSpecLink.2.0.80 = 50350152100013053100515221-50320104203
|
||||||
AiPlayerbot.PremadeSpecName.2.1 = prot pve
|
AiPlayerbot.PremadeSpecName.2.1 = prot pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.2.1 = 41099,43367,43869,43368,43369,45745
|
AiPlayerbot.PremadeSpecGlyph.2.1 = 41100,43367,43869,43368,43369,45745
|
||||||
AiPlayerbot.PremadeSpecLink.2.1.60 = -05005135203102311333112321
|
AiPlayerbot.PremadeSpecLink.2.1.60 = -05005135203102311333112321
|
||||||
AiPlayerbot.PremadeSpecLink.2.1.80 = -05005135203102311333312321-502302012003
|
AiPlayerbot.PremadeSpecLink.2.1.80 = -05005135203102311333312321-502302012003
|
||||||
AiPlayerbot.PremadeSpecName.2.2 = ret pve
|
AiPlayerbot.PremadeSpecName.2.2 = ret pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.2.2 = 41092,43367,41099,43368,43369,43869
|
AiPlayerbot.PremadeSpecGlyph.2.2 = 41092,43367,41099,43368,43340,43869
|
||||||
AiPlayerbot.PremadeSpecLink.2.2.60 = --05230051203331302133231131
|
AiPlayerbot.PremadeSpecLink.2.2.60 = --05230051203331302133231131
|
||||||
AiPlayerbot.PremadeSpecLink.2.2.65 = -05-05230051203331302133231131
|
AiPlayerbot.PremadeSpecLink.2.2.65 = -05-05230051203331302133231131
|
||||||
AiPlayerbot.PremadeSpecLink.2.2.80 = 050501-05-05232051203331302133231331
|
AiPlayerbot.PremadeSpecLink.2.2.80 = 050501-05-05232051203331302133231331
|
||||||
@ -1504,7 +1504,7 @@ AiPlayerbot.PremadeSpecName.3.0 = bm pve
|
|||||||
AiPlayerbot.PremadeSpecGlyph.3.0 = 42912,43350,42902,43351,43338,42914
|
AiPlayerbot.PremadeSpecGlyph.3.0 = 42912,43350,42902,43351,43338,42914
|
||||||
AiPlayerbot.PremadeSpecLink.3.0.40 = 512002015051122301
|
AiPlayerbot.PremadeSpecLink.3.0.40 = 512002015051122301
|
||||||
AiPlayerbot.PremadeSpecLink.3.0.60 = 51200201505112233110531151
|
AiPlayerbot.PremadeSpecLink.3.0.60 = 51200201505112233110531151
|
||||||
AiPlayerbot.PremadeSpecLink.3.0.80 = 51200201505112243130531351-005305101
|
AiPlayerbot.PremadeSpecLink.3.0.80 = 51200201505112233111531351-0323031-5
|
||||||
AiPlayerbot.PremadeSpecName.3.1 = mm pve
|
AiPlayerbot.PremadeSpecName.3.1 = mm pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.3.1 = 42912,43350,45625,43351,43338,42914
|
AiPlayerbot.PremadeSpecGlyph.3.1 = 42912,43350,45625,43351,43338,42914
|
||||||
AiPlayerbot.PremadeSpecLink.3.1.60 = -035305101030013233115031151
|
AiPlayerbot.PremadeSpecLink.3.1.60 = -035305101030013233115031151
|
||||||
@ -1530,8 +1530,8 @@ AiPlayerbot.PremadeSpecLink.3.5.80 = -005305201-2300302510233330533135001031
|
|||||||
# HUNTER PET
|
# HUNTER PET
|
||||||
#
|
#
|
||||||
# Ferocity
|
# Ferocity
|
||||||
AiPlayerbot.PremadeHunterPetLink.0.16 = 2100003030103010101
|
AiPlayerbot.PremadeHunterPetLink.0.16 = 2100003130003010101
|
||||||
AiPlayerbot.PremadeHunterPetLink.0.20 = 2100013030103010122
|
AiPlayerbot.PremadeHunterPetLink.0.20 = 2100003130103010122
|
||||||
# Tenacity
|
# Tenacity
|
||||||
AiPlayerbot.PremadeHunterPetLink.1.16 = 21103000300120101001
|
AiPlayerbot.PremadeHunterPetLink.1.16 = 21103000300120101001
|
||||||
AiPlayerbot.PremadeHunterPetLink.1.20 = 21303010300120101002
|
AiPlayerbot.PremadeHunterPetLink.1.20 = 21303010300120101002
|
||||||
@ -1552,7 +1552,7 @@ AiPlayerbot.PremadeHunterPetLink.2.20 = 21000203300002110221
|
|||||||
AiPlayerbot.PremadeSpecName.4.0 = as pve
|
AiPlayerbot.PremadeSpecName.4.0 = as pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.4.0 = 45768,43379,45761,43380,43378,45766
|
AiPlayerbot.PremadeSpecGlyph.4.0 = 45768,43379,45761,43380,43378,45766
|
||||||
AiPlayerbot.PremadeSpecLink.4.0.60 = 005303104352100520103331051
|
AiPlayerbot.PremadeSpecLink.4.0.60 = 005303104352100520103331051
|
||||||
AiPlayerbot.PremadeSpecLink.4.0.80 = 005303104352100520103331051-005005005003-2
|
AiPlayerbot.PremadeSpecLink.4.0.80 = 005303005352100520103331051-005005003-502
|
||||||
AiPlayerbot.PremadeSpecName.4.1 = combat pve
|
AiPlayerbot.PremadeSpecName.4.1 = combat pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.4.1 = 42962,43379,45762,43380,43378,42969
|
AiPlayerbot.PremadeSpecGlyph.4.1 = 42962,43379,45762,43380,43378,42969
|
||||||
AiPlayerbot.PremadeSpecLink.4.1.60 = -0252051000035015223100501251
|
AiPlayerbot.PremadeSpecLink.4.1.60 = -0252051000035015223100501251
|
||||||
@ -1593,7 +1593,7 @@ AiPlayerbot.PremadeSpecGlyph.5.1 = 42408,43371,42400,43374,43342,42396
|
|||||||
AiPlayerbot.PremadeSpecLink.5.1.60 = -035050031301152530000331331
|
AiPlayerbot.PremadeSpecLink.5.1.60 = -035050031301152530000331331
|
||||||
AiPlayerbot.PremadeSpecLink.5.1.80 = 05032031-235050032302152530000331351
|
AiPlayerbot.PremadeSpecLink.5.1.80 = 05032031-235050032302152530000331351
|
||||||
AiPlayerbot.PremadeSpecName.5.2 = shadow pve
|
AiPlayerbot.PremadeSpecName.5.2 = shadow pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.5.2 = 42406,43371,42407,43374,43342,42415
|
AiPlayerbot.PremadeSpecGlyph.5.2 = 45753,43371,42407,43374,43370,42415
|
||||||
AiPlayerbot.PremadeSpecLink.5.2.60 = --325003041203010323150301351
|
AiPlayerbot.PremadeSpecLink.5.2.60 = --325003041203010323150301351
|
||||||
AiPlayerbot.PremadeSpecLink.5.2.80 = 0503203--325023051223010323152301351
|
AiPlayerbot.PremadeSpecLink.5.2.80 = 0503203--325023051223010323152301351
|
||||||
AiPlayerbot.PremadeSpecName.5.3 = disc pvp
|
AiPlayerbot.PremadeSpecName.5.3 = disc pvp
|
||||||
@ -1620,19 +1620,19 @@ AiPlayerbot.PremadeSpecLink.5.5.80 = 50332031003--005323241223112003102311351
|
|||||||
#
|
#
|
||||||
|
|
||||||
AiPlayerbot.PremadeSpecName.6.0 = blood pve
|
AiPlayerbot.PremadeSpecName.6.0 = blood pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.6.0 = 45805,43673,43827,43544,43672,43554
|
AiPlayerbot.PremadeSpecGlyph.6.0 = 45805,43673,43538,43544,43672,43542
|
||||||
AiPlayerbot.PremadeSpecLink.6.0.60 = 035502150300331320102013111-005
|
AiPlayerbot.PremadeSpecLink.6.0.60 = 035502150300331320102013111-005
|
||||||
AiPlayerbot.PremadeSpecLink.6.0.80 = 0355021533003313201020131351-005-005032
|
AiPlayerbot.PremadeSpecLink.6.0.80 = 0055021533303310201020131-305020510002-00522
|
||||||
AiPlayerbot.PremadeSpecName.6.1 = frost pve
|
AiPlayerbot.PremadeSpecName.6.1 = frost pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.6.1 = 45805,43673,43547,43544,43672,43543
|
AiPlayerbot.PremadeSpecGlyph.6.1 = 45805,43673,43547,43544,43672,43543
|
||||||
AiPlayerbot.PremadeSpecLink.6.1.60 = -32003350332203012300023101351
|
AiPlayerbot.PremadeSpecLink.6.1.60 = -32003350332203012300023101351
|
||||||
AiPlayerbot.PremadeSpecLink.6.1.80 = -32002350352203012300033101351-230200305003
|
AiPlayerbot.PremadeSpecLink.6.1.80 = -32002350352203012300033101351-230200305003
|
||||||
AiPlayerbot.PremadeSpecName.6.2 = unholy pve
|
AiPlayerbot.PremadeSpecName.6.2 = unholy pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.6.2 = 43542,43673,43546,43544,43672,43549
|
AiPlayerbot.PremadeSpecGlyph.6.2 = 43542,43673,43546,43535,43672,43549
|
||||||
AiPlayerbot.PremadeSpecLink.6.2.60 = --2301303050032151000150013131151
|
AiPlayerbot.PremadeSpecLink.6.2.60 = --2301303050032151000150013131151
|
||||||
AiPlayerbot.PremadeSpecLink.6.2.80 = -320033500002-2301303050032151000150013133151
|
AiPlayerbot.PremadeSpecLink.6.2.80 = 23050202--2302303350032152000150003133151
|
||||||
AiPlayerbot.PremadeSpecName.6.3 = double aura blood pve
|
AiPlayerbot.PremadeSpecName.6.3 = double aura blood pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.6.3 = 45805,43673,43827,43544,43672,43554
|
AiPlayerbot.PremadeSpecGlyph.6.3 = 45805,43673,43538,43544,43672,43554
|
||||||
AiPlayerbot.PremadeSpecLink.6.3.60 = 005512153330030320102013-305
|
AiPlayerbot.PremadeSpecLink.6.3.60 = 005512153330030320102013-305
|
||||||
AiPlayerbot.PremadeSpecLink.6.3.80 = 005512153330030320102013-3050505002023001-002
|
AiPlayerbot.PremadeSpecLink.6.3.80 = 005512153330030320102013-3050505002023001-002
|
||||||
AiPlayerbot.PremadeSpecName.6.4 = blood pvp
|
AiPlayerbot.PremadeSpecName.6.4 = blood pvp
|
||||||
@ -1662,13 +1662,13 @@ AiPlayerbot.PremadeSpecLink.6.6.80 = -320050410002-23013233010021522301012031331
|
|||||||
AiPlayerbot.PremadeSpecName.7.0 = ele pve
|
AiPlayerbot.PremadeSpecName.7.0 = ele pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.7.0 = 41536,43385,41532,43386,44923,45776
|
AiPlayerbot.PremadeSpecGlyph.7.0 = 41536,43385,41532,43386,44923,45776
|
||||||
AiPlayerbot.PremadeSpecLink.7.0.60 = 4530001520213351102301351
|
AiPlayerbot.PremadeSpecLink.7.0.60 = 4530001520213351102301351
|
||||||
AiPlayerbot.PremadeSpecLink.7.0.80 = 3530001523213351322301351-005050031
|
AiPlayerbot.PremadeSpecLink.7.0.80 = 4530001523213351302301351-00525003
|
||||||
AiPlayerbot.PremadeSpecName.7.1 = enh pve
|
AiPlayerbot.PremadeSpecName.7.1 = enh pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.7.1 = 41530,43385,41539,43386,44923,45771
|
AiPlayerbot.PremadeSpecGlyph.7.1 = 41542,43385,41539,43386,43725,45771
|
||||||
AiPlayerbot.PremadeSpecLink.7.1.60 = -30305003105021333031121131051
|
AiPlayerbot.PremadeSpecLink.7.1.60 = -30305003105021333031121131051
|
||||||
AiPlayerbot.PremadeSpecLink.7.1.80 = 053030152-30305003105021333031131131051
|
AiPlayerbot.PremadeSpecLink.7.1.80 = 053030152-30305003105021333031131131051
|
||||||
AiPlayerbot.PremadeSpecName.7.2 = resto pve
|
AiPlayerbot.PremadeSpecName.7.2 = resto pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.7.2 = 41527,43385,41517,43386,44923,45775
|
AiPlayerbot.PremadeSpecGlyph.7.2 = 41527,43385,41517,43386,43725,45775
|
||||||
AiPlayerbot.PremadeSpecLink.7.2.60 = --50005301235310501102321251
|
AiPlayerbot.PremadeSpecLink.7.2.60 = --50005301235310501102321251
|
||||||
AiPlayerbot.PremadeSpecLink.7.2.80 = -00502033-50005331335310501122331251
|
AiPlayerbot.PremadeSpecLink.7.2.80 = -00502033-50005331335310501122331251
|
||||||
AiPlayerbot.PremadeSpecName.7.3 = ele pvp
|
AiPlayerbot.PremadeSpecName.7.3 = ele pvp
|
||||||
@ -1702,7 +1702,7 @@ AiPlayerbot.PremadeSpecLink.8.0.80 = 230005231100330150323102505321-03-203303001
|
|||||||
AiPlayerbot.PremadeSpecName.8.1 = fire pve
|
AiPlayerbot.PremadeSpecName.8.1 = fire pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.8.1 = 42739,43339,45737,43364,44920,42751
|
AiPlayerbot.PremadeSpecGlyph.8.1 = 42739,43339,45737,43364,44920,42751
|
||||||
AiPlayerbot.PremadeSpecLink.8.1.60 = -0055030011302231053120321341
|
AiPlayerbot.PremadeSpecLink.8.1.60 = -0055030011302231053120321341
|
||||||
AiPlayerbot.PremadeSpecLink.8.1.80 = 23000503110003-0055030011302331053120321351
|
AiPlayerbot.PremadeSpecLink.8.1.80 = 23000503110003-0055032012303330053120300351
|
||||||
AiPlayerbot.PremadeSpecName.8.2 = frost pve
|
AiPlayerbot.PremadeSpecName.8.2 = frost pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.8.2 = 42742,43339,50045,43364,43361,42751
|
AiPlayerbot.PremadeSpecGlyph.8.2 = 42742,43339,50045,43364,43361,42751
|
||||||
AiPlayerbot.PremadeSpecLink.8.2.60 = --0533030313203100030152231151
|
AiPlayerbot.PremadeSpecLink.8.2.60 = --0533030313203100030152231151
|
||||||
@ -1780,15 +1780,15 @@ AiPlayerbot.PremadeSpecLink.11.0.80 = 5032203105331303213305301231--205003012
|
|||||||
AiPlayerbot.PremadeSpecName.11.1 = bear pve
|
AiPlayerbot.PremadeSpecName.11.1 = bear pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.11.1 = 40897,43331,46372,43335,43332,40899
|
AiPlayerbot.PremadeSpecGlyph.11.1 = 40897,43331,46372,43335,43332,40899
|
||||||
AiPlayerbot.PremadeSpecLink.11.1.60 = -500232130322110353100301310501
|
AiPlayerbot.PremadeSpecLink.11.1.60 = -500232130322110353100301310501
|
||||||
AiPlayerbot.PremadeSpecLink.11.1.80 = -501232130322110353120303313511-20350001
|
AiPlayerbot.PremadeSpecLink.11.1.80 = -503232132322010353120303013511-20350001
|
||||||
AiPlayerbot.PremadeSpecName.11.2 = resto pve
|
AiPlayerbot.PremadeSpecName.11.2 = resto pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.11.2 = 40913,43331,40906,43335,44922,45602
|
AiPlayerbot.PremadeSpecGlyph.11.2 = 40913,43331,40906,43335,43674,45602
|
||||||
AiPlayerbot.PremadeSpecLink.11.2.60 = --230033312031500531050113051
|
AiPlayerbot.PremadeSpecLink.11.2.60 = --230033312031500531050113051
|
||||||
AiPlayerbot.PremadeSpecLink.11.2.80 = 05320031--230033312031501531053313051
|
AiPlayerbot.PremadeSpecLink.11.2.80 = 05320131003--230023312131500531050313051
|
||||||
AiPlayerbot.PremadeSpecName.11.3 = cat pve
|
AiPlayerbot.PremadeSpecName.11.3 = cat pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.11.3 = 40902,43331,40901,43335,44922,45604
|
AiPlayerbot.PremadeSpecGlyph.11.3 = 40902,43331,40901,43335,43674,45604
|
||||||
AiPlayerbot.PremadeSpecLink.11.3.60 = -552202032322010053100030310501
|
AiPlayerbot.PremadeSpecLink.11.3.60 = -552202032322010053100030310501
|
||||||
AiPlayerbot.PremadeSpecLink.11.3.80 = -553202032322010053100030310511-205503012
|
AiPlayerbot.PremadeSpecLink.11.3.80 = -553202032322010053120030310511-203503012
|
||||||
AiPlayerbot.PremadeSpecName.11.4 = balance pvp
|
AiPlayerbot.PremadeSpecName.11.4 = balance pvp
|
||||||
AiPlayerbot.PremadeSpecGlyph.11.4 = 40921,43331,45622,43674,43335,45623
|
AiPlayerbot.PremadeSpecGlyph.11.4 = 40921,43331,45622,43674,43335,45623
|
||||||
AiPlayerbot.PremadeSpecLink.11.4.60 = 5012203115331002213032311231
|
AiPlayerbot.PremadeSpecLink.11.4.60 = 5012203115331002213032311231
|
||||||
|
|||||||
@ -308,9 +308,8 @@ bool LfgAction::Execute(Event event)
|
|||||||
allowedRoles[BOT_ROLE_HEALER] = 1;
|
allowedRoles[BOT_ROLE_HEALER] = 1;
|
||||||
allowedRoles[BOT_ROLE_DPS] = 3;
|
allowedRoles[BOT_ROLE_DPS] = 3;
|
||||||
|
|
||||||
BotRoles role = botAI->IsTank(requester, false)
|
BotRoles role = botAI->IsTank(requester, true) ? BOT_ROLE_TANK
|
||||||
? BOT_ROLE_TANK
|
: (botAI->IsHeal(requester, true) ? BOT_ROLE_HEALER : BOT_ROLE_DPS);
|
||||||
: (botAI->IsHeal(requester, false) ? BOT_ROLE_HEALER : BOT_ROLE_DPS);
|
|
||||||
Classes cls = (Classes)requester->getClass();
|
Classes cls = (Classes)requester->getClass();
|
||||||
|
|
||||||
if (group)
|
if (group)
|
||||||
@ -383,8 +382,8 @@ bool LfgAction::Execute(Event event)
|
|||||||
if (!botAI->IsSafe(player))
|
if (!botAI->IsSafe(player))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
role = botAI->IsTank(player, false) ? BOT_ROLE_TANK
|
role = botAI->IsTank(player, true) ? BOT_ROLE_TANK
|
||||||
: (botAI->IsHeal(player, false) ? BOT_ROLE_HEALER : BOT_ROLE_DPS);
|
: (botAI->IsHeal(player, true) ? BOT_ROLE_HEALER : BOT_ROLE_DPS);
|
||||||
cls = (Classes)player->getClass();
|
cls = (Classes)player->getClass();
|
||||||
|
|
||||||
if (allowedRoles[role] > 0)
|
if (allowedRoles[role] > 0)
|
||||||
@ -403,7 +402,7 @@ bool LfgAction::Execute(Event event)
|
|||||||
allowedClassNr[cls][role]--;
|
allowedClassNr[cls][role]--;
|
||||||
}
|
}
|
||||||
|
|
||||||
role = botAI->IsTank(bot, false) ? BOT_ROLE_TANK : (botAI->IsHeal(bot, false) ? BOT_ROLE_HEALER : BOT_ROLE_DPS);
|
role = botAI->IsTank(bot, true) ? BOT_ROLE_TANK : (botAI->IsHeal(bot, true) ? BOT_ROLE_HEALER : BOT_ROLE_DPS);
|
||||||
cls = (Classes)bot->getClass();
|
cls = (Classes)bot->getClass();
|
||||||
|
|
||||||
if (allowedRoles[role] == 0)
|
if (allowedRoles[role] == 0)
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "ItemVisitors.h"
|
#include "ItemVisitors.h"
|
||||||
|
#include "PlayerbotRepository.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
#include "ItemPackets.h"
|
#include "ItemPackets.h"
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ bool OutfitAction::Execute(Event event)
|
|||||||
if (!name.empty())
|
if (!name.empty())
|
||||||
{
|
{
|
||||||
Save(name, items);
|
Save(name, items);
|
||||||
|
PlayerbotRepository::instance().Save(botAI);
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "Setting outfit " << name << " as " << param;
|
out << "Setting outfit " << name << " as " << param;
|
||||||
@ -86,6 +88,7 @@ bool OutfitAction::Execute(Event event)
|
|||||||
botAI->TellMaster(out);
|
botAI->TellMaster(out);
|
||||||
|
|
||||||
Save(name, ItemIds());
|
Save(name, ItemIds());
|
||||||
|
PlayerbotRepository::instance().Save(botAI);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (command == "update")
|
else if (command == "update")
|
||||||
@ -95,6 +98,7 @@ bool OutfitAction::Execute(Event event)
|
|||||||
botAI->TellMaster(out);
|
botAI->TellMaster(out);
|
||||||
|
|
||||||
Update(name);
|
Update(name);
|
||||||
|
PlayerbotRepository::instance().Save(botAI);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,6 +128,7 @@ bool OutfitAction::Execute(Event event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Save(name, outfit);
|
Save(name, outfit);
|
||||||
|
PlayerbotRepository::instance().Save(botAI);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -20,20 +20,23 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Commands where trigger name =/= action name.
|
||||||
void ChatCommandHandlerStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void ChatCommandHandlerStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
PassTroughStrategy::InitTriggers(triggers);
|
PassTroughStrategy::InitTriggers(triggers);
|
||||||
|
|
||||||
|
// Keep single action triggers on one line, and multi-action triggers on multiple lines.
|
||||||
triggers.push_back(new TriggerNode("rep", { NextAction("reputation", relevance) }));
|
triggers.push_back(new TriggerNode("rep", { NextAction("reputation", relevance) }));
|
||||||
triggers.push_back(new TriggerNode("pvp stats", { NextAction("tell pvp stats", relevance) }));
|
triggers.push_back(new TriggerNode("pvp stats", { NextAction("tell pvp stats", relevance) }));
|
||||||
triggers.push_back(new TriggerNode("q", { NextAction("query quest", relevance),
|
triggers.push_back(new TriggerNode("q",
|
||||||
|
{ NextAction("query quest", relevance),
|
||||||
NextAction("query item usage", relevance) }));
|
NextAction("query item usage", relevance) }));
|
||||||
triggers.push_back(new TriggerNode("add all loot", { NextAction("add all loot", relevance),
|
triggers.push_back(new TriggerNode("add all loot",
|
||||||
|
{ NextAction("add all loot", relevance),
|
||||||
NextAction("loot", relevance) }));
|
NextAction("loot", relevance) }));
|
||||||
triggers.push_back(new TriggerNode("u", { NextAction("use", relevance) }));
|
triggers.push_back(new TriggerNode("u", { NextAction("use", relevance) }));
|
||||||
triggers.push_back(new TriggerNode("c", { NextAction("item count", relevance) }));
|
triggers.push_back(new TriggerNode("c", { NextAction("item count", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("items", { NextAction("item count", relevance) }));
|
||||||
new TriggerNode("items", { NextAction("item count", relevance) }));
|
|
||||||
triggers.push_back(new TriggerNode("inv", { NextAction("item count", relevance) }));
|
triggers.push_back(new TriggerNode("inv", { NextAction("item count", relevance) }));
|
||||||
triggers.push_back(new TriggerNode("e", { NextAction("equip", relevance) }));
|
triggers.push_back(new TriggerNode("e", { NextAction("equip", relevance) }));
|
||||||
triggers.push_back(new TriggerNode("ue", { NextAction("unequip", relevance) }));
|
triggers.push_back(new TriggerNode("ue", { NextAction("unequip", relevance) }));
|
||||||
@ -42,81 +45,40 @@ void ChatCommandHandlerStrategy::InitTriggers(std::vector<TriggerNode*>& trigger
|
|||||||
triggers.push_back(new TriggerNode("s", { NextAction("sell", relevance) }));
|
triggers.push_back(new TriggerNode("s", { NextAction("sell", relevance) }));
|
||||||
triggers.push_back(new TriggerNode("b", { NextAction("buy", relevance) }));
|
triggers.push_back(new TriggerNode("b", { NextAction("buy", relevance) }));
|
||||||
triggers.push_back(new TriggerNode("r", { NextAction("reward", relevance) }));
|
triggers.push_back(new TriggerNode("r", { NextAction("reward", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("attack", { NextAction("attack my target", relevance) }));
|
||||||
new TriggerNode("attack", { NextAction("attack my target", relevance) }));
|
triggers.push_back(new TriggerNode("accept", { NextAction("accept quest", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("follow", { NextAction("follow chat shortcut", relevance) }));
|
||||||
new TriggerNode("accept", { NextAction("accept quest", relevance) }));
|
triggers.push_back(new TriggerNode("stay", { NextAction("stay chat shortcut", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("move from group", { NextAction("move from group chat shortcut", relevance) }));
|
||||||
new TriggerNode("follow", { NextAction("follow chat shortcut", relevance) }));
|
triggers.push_back(new TriggerNode("flee", { NextAction("flee chat shortcut", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("tank attack", { NextAction("tank attack chat shortcut", relevance) }));
|
||||||
new TriggerNode("stay", { NextAction("stay chat shortcut", relevance) }));
|
triggers.push_back(new TriggerNode("grind", { NextAction("grind chat shortcut", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("talk",
|
||||||
new TriggerNode("move from group", { NextAction("move from group chat shortcut", relevance) }));
|
{ NextAction("gossip hello", relevance),
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("flee", { NextAction("flee chat shortcut", relevance) }));
|
|
||||||
triggers.push_back(new TriggerNode(
|
|
||||||
"tank attack", { NextAction("tank attack chat shortcut", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("grind", { NextAction("grind chat shortcut", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("talk", { NextAction("gossip hello", relevance),
|
|
||||||
NextAction("talk to quest giver", relevance) }));
|
NextAction("talk to quest giver", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("enter vehicle", { NextAction("enter vehicle", relevance) }));
|
||||||
new TriggerNode("enter vehicle", { NextAction("enter vehicle", relevance) }));
|
triggers.push_back(new TriggerNode("leave vehicle", { NextAction("leave vehicle", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("cast", { NextAction("cast custom spell", relevance) }));
|
||||||
new TriggerNode("leave vehicle", { NextAction("leave vehicle", relevance) }));
|
triggers.push_back(new TriggerNode("castnc", { NextAction("cast custom nc spell", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("revive", { NextAction("spirit healer", relevance) }));
|
||||||
new TriggerNode("cast", { NextAction("cast custom spell", relevance) }));
|
triggers.push_back(new TriggerNode("runaway", { NextAction("runaway chat shortcut", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("warning", { NextAction("runaway chat shortcut", relevance) }));
|
||||||
new TriggerNode("castnc", { NextAction("cast custom nc spell", relevance) }));
|
triggers.push_back(new TriggerNode("max dps", { NextAction("max dps chat shortcut", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("attackers", { NextAction("tell attackers", relevance) }));
|
||||||
new TriggerNode("revive", { NextAction("spirit healer", relevance) }));
|
triggers.push_back(new TriggerNode("target", { NextAction("tell target", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("pull", { NextAction("pull my target", relevance) }));
|
||||||
new TriggerNode("runaway", { NextAction("runaway chat shortcut", relevance) }));
|
triggers.push_back(new TriggerNode("pull back", { NextAction("pull my target", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("pull rti", { NextAction("pull rti target", relevance) }));
|
||||||
new TriggerNode("warning", { NextAction("runaway chat shortcut", relevance) }));
|
triggers.push_back(new TriggerNode("ready", { NextAction("ready check", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("naxx", {NextAction("naxx chat shortcut", relevance) }));
|
||||||
new TriggerNode("max dps", { NextAction("max dps chat shortcut", relevance) }));
|
triggers.push_back(new TriggerNode("bwl", { NextAction("bwl chat shortcut", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("dps", { NextAction("tell estimated dps", relevance) }));
|
||||||
new TriggerNode("attackers", { NextAction("tell attackers", relevance) }));
|
triggers.push_back(new TriggerNode("disperse", { NextAction("disperse set", relevance) }));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("qi", { NextAction("query item usage", relevance) }));
|
||||||
new TriggerNode("target", { NextAction("tell target", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("pull", { NextAction("pull my target", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("pull back", { NextAction("pull my target", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("pull rti", { NextAction("pull rti target", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("ready", { NextAction("ready check", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("naxx", {NextAction("naxx chat shortcut", relevance)}));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("bwl", { NextAction("bwl chat shortcut", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("dps", { NextAction("tell estimated dps", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("disperse", { NextAction("disperse set", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("open items", { NextAction("open items", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("qi", { NextAction("query item usage", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("unlock items", { NextAction("unlock items", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("unlock traded item", { NextAction("unlock traded item", relevance) }));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("wipe", { NextAction("wipe", relevance) }));
|
|
||||||
triggers.push_back(new TriggerNode("tame", { NextAction("tame", relevance) }));
|
|
||||||
triggers.push_back(new TriggerNode("glyphs", { NextAction("glyphs", relevance) })); // Added for custom Glyphs
|
|
||||||
triggers.push_back(new TriggerNode("glyph equip", { NextAction("glyph equip", relevance) })); // Added for custom Glyphs
|
|
||||||
triggers.push_back(new TriggerNode("pet", { NextAction("pet", relevance) }));
|
|
||||||
triggers.push_back(new TriggerNode("pet attack", { NextAction("pet attack", relevance) }));
|
|
||||||
triggers.push_back(new TriggerNode("roll", { NextAction("roll", relevance) }));
|
|
||||||
triggers.push_back(new TriggerNode("focus heal", { NextAction("focus heal targets", relevance) }));
|
triggers.push_back(new TriggerNode("focus heal", { NextAction("focus heal targets", relevance) }));
|
||||||
triggers.push_back(new TriggerNode("emblems", { NextAction("emblems", relevance) }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Commands where trigger name == action name.
|
||||||
ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : PassTroughStrategy(botAI)
|
ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : PassTroughStrategy(botAI)
|
||||||
{
|
{
|
||||||
actionNodeFactories.Add(new ChatCommandActionNodeFactoryInternal());
|
actionNodeFactories.Add(new ChatCommandActionNodeFactoryInternal());
|
||||||
@ -199,15 +161,15 @@ ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : Pas
|
|||||||
supported.push_back("rtsc");
|
supported.push_back("rtsc");
|
||||||
supported.push_back("drink");
|
supported.push_back("drink");
|
||||||
supported.push_back("calc");
|
supported.push_back("calc");
|
||||||
|
supported.push_back("roll");
|
||||||
supported.push_back("open items");
|
supported.push_back("open items");
|
||||||
supported.push_back("qi");
|
|
||||||
supported.push_back("unlock items");
|
supported.push_back("unlock items");
|
||||||
supported.push_back("unlock traded item");
|
supported.push_back("unlock traded item");
|
||||||
|
supported.push_back("wipe");
|
||||||
supported.push_back("tame");
|
supported.push_back("tame");
|
||||||
supported.push_back("glyphs");
|
supported.push_back("glyphs");
|
||||||
supported.push_back("glyph equip");
|
supported.push_back("glyph equip");
|
||||||
supported.push_back("pet");
|
supported.push_back("pet");
|
||||||
supported.push_back("pet attack");
|
supported.push_back("pet attack");
|
||||||
supported.push_back("wait for attack time");
|
supported.push_back("wait for attack time");
|
||||||
supported.push_back("focus heal");
|
|
||||||
}
|
}
|
||||||
@ -29,7 +29,7 @@ public:
|
|||||||
if (!botAI->GetBot()->IsWithinLOSInMap(unit))
|
if (!botAI->GetBot()->IsWithinLOSInMap(unit))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return botAI->IsMovementImpaired(unit);
|
return botAI->IsMovementImpaired(unit) && !botAI->HasAnyAuraOf(unit, "stealth", "prowl", nullptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -11,8 +11,6 @@
|
|||||||
#include "ServerFacade.h"
|
#include "ServerFacade.h"
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
|
|
||||||
Value<Unit*>* CastPolymorphAction::GetTargetValue() { return context->GetValue<Unit*>("cc target", getName()); }
|
|
||||||
|
|
||||||
bool UseManaSapphireAction::isUseful()
|
bool UseManaSapphireAction::isUseful()
|
||||||
{
|
{
|
||||||
Player* bot = botAI->GetBot();
|
Player* bot = botAI->GetBot();
|
||||||
|
|||||||
@ -215,11 +215,10 @@ public:
|
|||||||
|
|
||||||
// CC, Interrupt, and Dispel Actions
|
// CC, Interrupt, and Dispel Actions
|
||||||
|
|
||||||
class CastPolymorphAction : public CastBuffSpellAction
|
class CastPolymorphAction : public CastCrowdControlSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastPolymorphAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "polymorph") {}
|
CastPolymorphAction(PlayerbotAI* botAI) : CastCrowdControlSpellAction(botAI, "polymorph") {}
|
||||||
Value<Unit*>* GetTargetValue() override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastSpellstealAction : public CastSpellAction
|
class CastSpellstealAction : public CastSpellAction
|
||||||
|
|||||||
3041
src/Ai/Raid/BlackTemple/Action/RaidBlackTempleActions.cpp
Normal file
3041
src/Ai/Raid/BlackTemple/Action/RaidBlackTempleActions.cpp
Normal file
File diff suppressed because it is too large
Load Diff
565
src/Ai/Raid/BlackTemple/Action/RaidBlackTempleActions.h
Normal file
565
src/Ai/Raid/BlackTemple/Action/RaidBlackTempleActions.h
Normal file
@ -0,0 +1,565 @@
|
|||||||
|
/*
|
||||||
|
* 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_RAIDBLACKTEMPLEACTIONS_H
|
||||||
|
#define _PLAYERBOT_RAIDBLACKTEMPLEACTIONS_H
|
||||||
|
|
||||||
|
#include "Action.h"
|
||||||
|
#include "AttackAction.h"
|
||||||
|
#include "MovementActions.h"
|
||||||
|
#include "RaidBlackTempleHelpers.h"
|
||||||
|
|
||||||
|
namespace BlackTempleHelpers
|
||||||
|
{
|
||||||
|
struct EyeBlastDangerArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
// General
|
||||||
|
|
||||||
|
class BlackTempleEraseTimersAndTrackersAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BlackTempleEraseTimersAndTrackersAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "black temple erase timers and trackers") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
|
||||||
|
class HighWarlordNajentusMisdirectBossToMainTankAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HighWarlordNajentusMisdirectBossToMainTankAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "high warlord naj'entus misdirect boss to main tank") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HighWarlordNajentusTanksPositionBossAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HighWarlordNajentusTanksPositionBossAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "high warlord naj'entus tanks position boss") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HighWarlordNajentusDisperseRangedAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HighWarlordNajentusDisperseRangedAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "naj'entus disperse ranged") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HighWarlordNajentusRemoveImpalingSpineAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HighWarlordNajentusRemoveImpalingSpineAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "high warlord naj'entus remove impaling spine") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HighWarlordNajentusThrowImpalingSpineAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HighWarlordNajentusThrowImpalingSpineAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "high warlord naj'entus throw impaling spine") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
|
||||||
|
class SupremusMisdirectBossToMainTankAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SupremusMisdirectBossToMainTankAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "supremus misdirect boss to main tank") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SupremusDisperseRangedAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SupremusDisperseRangedAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "supremus disperse ranged") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SupremusKiteBossAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SupremusKiteBossAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "supremus kite boss") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SupremusMoveAwayFromVolcanosAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SupremusMoveAwayFromVolcanosAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "supremus move away from volcanos") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Position FindSafestNearbyPosition(
|
||||||
|
const std::vector<Unit*>& volcanos, float maxRadius, float hazardRadius);
|
||||||
|
bool IsPathSafeFromVolcanos(const Position& start,
|
||||||
|
const Position& end, const std::vector<Unit*>& volcanos, float hazardRadius);
|
||||||
|
std::vector<Unit*> GetAllSupremusVolcanos();
|
||||||
|
};
|
||||||
|
|
||||||
|
class SupremusManagePhaseTimerAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SupremusManagePhaseTimerAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "supremus manage phase timer") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Shade of Akama
|
||||||
|
|
||||||
|
class ShadeOfAkamaMeleeDpsPrioritizeChannelersAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ShadeOfAkamaMeleeDpsPrioritizeChannelersAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "shade of akama melee dps prioritize channelers") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
|
||||||
|
class TeronGorefiendMisdirectBossToMainTankAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendMisdirectBossToMainTankAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "teron gorefiend misdirect boss to main tank") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendTanksPositionBossAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendTanksPositionBossAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "teron gorefiend tanks position boss") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendPositionRangedOnBalconyAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendPositionRangedOnBalconyAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "teron gorefiend position ranged on balcony") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendAvoidShadowOfDeathAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendAvoidShadowOfDeathAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "teron gorefiend avoid shadow of death") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendMoveToCornerToDieAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendMoveToCornerToDieAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "teron gorefiend move to corner to die") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendControlAndDestroyShadowyConstructsAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendControlAndDestroyShadowyConstructsAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "teron gorefiend control and destroy shadowy constructs") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
|
||||||
|
class GurtoggBloodboilMisdirectBossToMainTankAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GurtoggBloodboilMisdirectBossToMainTankAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "gurtogg bloodboil misdirect boss to main tank") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GurtoggBloodboilTanksPositionBossAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GurtoggBloodboilTanksPositionBossAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "gurtogg bloodboil tanks position boss") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GurtoggBloodboilRotateRangedGroupsAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GurtoggBloodboilRotateRangedGroupsAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "gurtogg bloodboil rotate ranged groups") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GurtoggBloodboilRangedMoveAwayFromEnragedPlayerAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GurtoggBloodboilRangedMoveAwayFromEnragedPlayerAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "gurtogg bloodboil ranged move away from enraged player") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GurtoggBloodboilManagePhaseTimerAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GurtoggBloodboilManagePhaseTimerAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "gurtogg bloodboil manage phase timer") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reliquary of Souls
|
||||||
|
|
||||||
|
class ReliquaryOfSoulsMisdirectBossToMainTankAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReliquaryOfSoulsMisdirectBossToMainTankAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "reliquary of souls misdirect boss to main tank") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReliquaryOfSoulsAdjustDistanceFromSufferingAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReliquaryOfSoulsAdjustDistanceFromSufferingAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "reliquary of souls adjust distance from suffering") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool TanksMoveToMinimumRange(Unit* suffering);
|
||||||
|
bool MeleeDpsStayAtMaximumRange(Unit* suffering);
|
||||||
|
bool RangedMoveAwayFromBoss(Unit* suffering);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReliquaryOfSoulsHealersDpsSufferingAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReliquaryOfSoulsHealersDpsSufferingAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "reliquary of souls healers dps suffering") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReliquaryOfSoulsSpellstealRuneShieldAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReliquaryOfSoulsSpellstealRuneShieldAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "reliquary of souls spellsteal rune shield") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReliquaryOfSoulsSpellReflectDeadenAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReliquaryOfSoulsSpellReflectDeadenAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "reliquary of souls spell reflect deaden") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
|
||||||
|
class MotherShahrazMisdirectBossToMainTankAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotherShahrazMisdirectBossToMainTankAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "mother shahraz misdirect boss to main tank") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MotherShahrazTanksPositionBossUnderPillarAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotherShahrazTanksPositionBossUnderPillarAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "mother shahraz tanks position boss under pillar") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MotherShahrazMeleeDpsWaitAtSafePositionAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotherShahrazMeleeDpsWaitAtSafePositionAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "mother shahraz melee dps wait at safe position") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MotherShahrazPositionRangedUnderPillarAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotherShahrazPositionRangedUnderPillarAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "mother shahraz position ranged under pillar") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MotherShahrazRunAwayToBreakFatalAttractionAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotherShahrazRunAwayToBreakFatalAttractionAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "mother shahraz run away to break fatal attraction") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Player*> GetAttractedPlayers();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Illidari Council
|
||||||
|
|
||||||
|
class IllidariCouncilMisdirectBossesToTanksAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilMisdirectBossesToTanksAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "illidari council misdirect bosses to tanks") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilMainTankPositionGathiosAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilMainTankPositionGathiosAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "illidari council main tank position gathios") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilMainTankReflectJudgementOfCommandAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilMainTankReflectJudgementOfCommandAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "illidari council main tank reflect judgement of command") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilFirstAssistTankFocusMalandeAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilFirstAssistTankFocusMalandeAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "illidari council first assist tank focus malande") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilSecondAssistTankPositionDarkshadowAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilSecondAssistTankPositionDarkshadowAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "illidari council second assist tank position darkshadow") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilMageTankPositionZerevorAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilMageTankPositionZerevorAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "illidari council mage tank position zerevor") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilPositionMageTankHealerAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilPositionMageTankHealerAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "illidari council position mage tank healer") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilAssignDpsTargetsAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilAssignDpsTargetsAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "illidari council assign dps targets") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilDisperseRangedAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilDisperseRangedAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "illidari council disperse ranged") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilCommandPetsToAttackGathiosAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilCommandPetsToAttackGathiosAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "illidari council command pets to attack gathios") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilManageDpsTimerAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilManageDpsTimerAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "illidari council manage dps timer") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
|
||||||
|
class IllidanStormrageMisdirectToTankAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageMisdirectToTankAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "illidan stormrage misdirect to tank") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool TryMisdirectToFlameTanks(Group* group);
|
||||||
|
bool TryMisdirectToWarlockTank(Unit* illidan);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageMainTankRepositionBossAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageMainTankRepositionBossAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "illidan stormrage main tank reposition boss") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool MoveToShadowTrap(GameObject* trap);
|
||||||
|
Position FindSafestNearbyPosition(
|
||||||
|
const std::vector<Unit*>& flameCrashes, float maxRadius, float hazardRadius);
|
||||||
|
bool IsPathSafeFromFlameCrashes(const Position& start,
|
||||||
|
const Position& end, const std::vector<Unit*>& flameCrashes, float hazardRadius);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageIsolateBotWithParasiteAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageIsolateBotWithParasiteAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "illidan stormrage isolate bot with parasite") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool InfectedBotMoveFromGroup(Unit* illidan, const Position& targetPos);
|
||||||
|
bool FreezeTrapShadowfiend(Player* bot, Unit* illidan, const Position& targetPos);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageSetEarthbindTotemAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageSetEarthbindTotemAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "illidan stormrage set earthbind totem") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageAssistTanksHandleFlamesOfAzzinothAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageAssistTanksHandleFlamesOfAzzinothAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "illidan stormrage assist tanks handle flames of azzinoth") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool RepositionToAvoidEyeBlast(Unit* illidan, const BlackTempleHelpers::EyeBlastDangerArea& dangerArea);
|
||||||
|
bool RepositionToAvoidBlaze(Unit* eastFlame, Unit* westFlame);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageControlPetAggressionAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageControlPetAggressionAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "illidan stormrage control pet aggression") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormragePositionAboveGrateAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormragePositionAboveGrateAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "illidan stormrage position above grate") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageRemoveDarkBarrageAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageRemoveDarkBarrageAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "illidan stormrage remove dark barrage") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageMoveAwayFromLandingPointAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageMoveAwayFromLandingPointAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "illidan stormrage move away from landing point") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageDisperseRangedAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageDisperseRangedAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "illidan stormrage disperse ranged") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool FanOutBehindInHumanPhase(Unit* illidan, Group* group);
|
||||||
|
bool SpreadInCircleInDemonPhase(Unit* illidan, Group* group);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageMeleeGoSomewhereToNotDieAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageMeleeGoSomewhereToNotDieAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "illidan stormrage melee go somewhere to not die") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageWarlockTankHandleDemonBossAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageWarlockTankHandleDemonBossAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "illidan stormrage warlock tank handle demon boss") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageDpsPrioritizeAddsAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageDpsPrioritizeAddsAction(
|
||||||
|
PlayerbotAI* botAI) : AttackAction(botAI, "illidan stormrage dps prioritize adds") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageUseShadowTrapAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageUseShadowTrapAction(
|
||||||
|
PlayerbotAI* botAI) : MovementAction(botAI, "illidan stormrage use shadow trap") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageManageDpsTimerAndRtiAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageManageDpsTimerAndRtiAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "illidan stormrage manage dps timer and rti") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageDestroyHazardsAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageDestroyHazardsAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "illidan stormrage destroy hazards") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageHandleAddsCheatAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageHandleAddsCheatAction(
|
||||||
|
PlayerbotAI* botAI) : Action(botAI, "illidan stormrage handle adds cheat") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,785 @@
|
|||||||
|
/*
|
||||||
|
* 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 "RaidBlackTempleMultipliers.h"
|
||||||
|
|
||||||
|
#include "ChooseTargetActions.h"
|
||||||
|
#include "DKActions.h"
|
||||||
|
#include "DruidActions.h"
|
||||||
|
#include "DruidBearActions.h"
|
||||||
|
#include "DruidShapeshiftActions.h"
|
||||||
|
#include "FollowActions.h"
|
||||||
|
#include "HunterActions.h"
|
||||||
|
#include "MageActions.h"
|
||||||
|
#include "PaladinActions.h"
|
||||||
|
#include "PriestActions.h"
|
||||||
|
#include "RaidBlackTempleActions.h"
|
||||||
|
#include "RaidBlackTempleHelpers.h"
|
||||||
|
#include "ReachTargetActions.h"
|
||||||
|
#include "RogueActions.h"
|
||||||
|
#include "ShamanActions.h"
|
||||||
|
#include "WarlockActions.h"
|
||||||
|
#include "WarriorActions.h"
|
||||||
|
#include "WipeAction.h"
|
||||||
|
|
||||||
|
using namespace BlackTempleHelpers;
|
||||||
|
|
||||||
|
static bool IsDpsCooldownAction(Action* action)
|
||||||
|
{
|
||||||
|
return dynamic_cast<CastHeroismAction*>(action) ||
|
||||||
|
dynamic_cast<CastBloodlustAction*>(action) ||
|
||||||
|
dynamic_cast<CastMetamorphosisAction*>(action) ||
|
||||||
|
dynamic_cast<CastAdrenalineRushAction*>(action) ||
|
||||||
|
dynamic_cast<CastBladeFlurryAction*>(action) ||
|
||||||
|
dynamic_cast<CastIcyVeinsAction*>(action) ||
|
||||||
|
dynamic_cast<CastColdSnapAction*>(action) ||
|
||||||
|
dynamic_cast<CastArcanePowerAction*>(action) ||
|
||||||
|
dynamic_cast<CastPresenceOfMindAction*>(action) ||
|
||||||
|
dynamic_cast<CastCombustionAction*>(action) ||
|
||||||
|
dynamic_cast<CastRapidFireAction*>(action) ||
|
||||||
|
dynamic_cast<CastReadinessAction*>(action) ||
|
||||||
|
dynamic_cast<CastAvengingWrathAction*>(action) ||
|
||||||
|
dynamic_cast<CastElementalMasteryAction*>(action) ||
|
||||||
|
dynamic_cast<CastFeralSpiritAction*>(action) ||
|
||||||
|
dynamic_cast<CastFireElementalTotemAction*>(action) ||
|
||||||
|
dynamic_cast<CastFireElementalTotemMeleeAction*>(action) ||
|
||||||
|
dynamic_cast<CastForceOfNatureAction*>(action) ||
|
||||||
|
dynamic_cast<CastArmyOfTheDeadAction*>(action) ||
|
||||||
|
dynamic_cast<CastSummonGargoyleAction*>(action) ||
|
||||||
|
dynamic_cast<CastBerserkingAction*>(action) ||
|
||||||
|
dynamic_cast<CastBloodFuryAction*>(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
|
||||||
|
float HighWarlordNajentusDelayDpsCooldownsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* najentus = AI_VALUE2(Unit*, "find target", "high warlord naj'entus");
|
||||||
|
if (!najentus || najentus->GetHealthPct() < 95.0f)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (IsDpsCooldownAction(action) ||
|
||||||
|
(botAI->IsDps(bot) && dynamic_cast<UseTrinketAction*>(action)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float HighWarlordNajentusDisableCombatFormationMoveMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "high warlord naj'entus"))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<CombatFormationMoveAction*>(action) &&
|
||||||
|
!dynamic_cast<SetBehindTargetAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
|
||||||
|
float SupremusDelayDpsCooldownsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* supremus = AI_VALUE2(Unit*, "find target", "supremus");
|
||||||
|
if (!supremus || supremus->GetHealthPct() < 95.0f)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (IsDpsCooldownAction(action) ||
|
||||||
|
(botAI->IsDps(bot) && dynamic_cast<UseTrinketAction*>(action)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SupremusFocusOnAvoidanceInPhase2Multiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* supremus = AI_VALUE2(Unit*, "find target", "supremus");
|
||||||
|
if (!supremus || supremus->GetVictim() != bot ||
|
||||||
|
!supremus->HasAura(static_cast<uint32>(BlackTempleSpells::SPELL_SNARE_SELF)))
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<MovementAction*>(action) &&
|
||||||
|
!dynamic_cast<SupremusKiteBossAction*>(action) &&
|
||||||
|
!dynamic_cast<SupremusMoveAwayFromVolcanosAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SupremusHitboxIsBuggedMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_ROGUE ||
|
||||||
|
!AI_VALUE2(Unit*, "find target", "supremus"))
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<CastKillingSpreeAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
|
||||||
|
float TeronGorefiendDelayDpsCooldownsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* gorefiend = AI_VALUE2(Unit*, "find target", "teron gorefiend");
|
||||||
|
if (!gorefiend || gorefiend->GetHealthPct() < 95.0f)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (IsDpsCooldownAction(action) ||
|
||||||
|
(botAI->IsDps(bot) && dynamic_cast<UseTrinketAction*>(action)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TeronGorefiendControlMovementMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "teron gorefiend"))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<CombatFormationMoveAction*>(action) &&
|
||||||
|
!dynamic_cast<SetBehindTargetAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<FollowAction*>(action) ||
|
||||||
|
dynamic_cast<FleeAction*>(action) ||
|
||||||
|
dynamic_cast<CastDisengageAction*>(action) ||
|
||||||
|
dynamic_cast<CastBlinkBackAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (botAI->IsRanged(bot) && dynamic_cast<ReachTargetAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TeronGorefiendMarkedBotOnlyMoveToDieMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Aura* aura = bot->GetAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_SHADOW_OF_DEATH));
|
||||||
|
if (!aura || aura->GetDuration() >= 15000)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<WipeAction*>(action))
|
||||||
|
return 1.0f;
|
||||||
|
else if (!dynamic_cast<TeronGorefiendMoveToCornerToDieAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TeronGorefiendSpiritsAttackOnlyShadowyConstructsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (!bot->HasAura(static_cast<uint32>(BlackTempleSpells::SPELL_SPIRITUAL_VENGEANCE)) ||
|
||||||
|
dynamic_cast<WipeAction*>(action))
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dynamic_cast<TeronGorefiendControlAndDestroyShadowyConstructsAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TeronGorefiendDisableAttackingConstructsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "teron gorefiend"))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (bot->GetVictim() != nullptr &&
|
||||||
|
dynamic_cast<TankAssistAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!botAI->IsRangedDps(bot))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
auto castSpellAction = dynamic_cast<CastSpellAction*>(action);
|
||||||
|
if (castSpellAction &&
|
||||||
|
castSpellAction->getThreatType() == Action::ActionThreatType::Aoe)
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
|
||||||
|
float GurtoggBloodboilDelayDpsCooldownsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* gurtogg = AI_VALUE2(Unit*, "find target", "gurtogg bloodboil");
|
||||||
|
if (!gurtogg || gurtogg->GetHealthPct() < 95.0f)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (IsDpsCooldownAction(action) ||
|
||||||
|
(botAI->IsDps(bot) && dynamic_cast<UseTrinketAction*>(action)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float GurtoggBloodboilControlMovementMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "gurtogg bloodboil"))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<CombatFormationMoveAction*>(action) &&
|
||||||
|
!dynamic_cast<SetBehindTargetAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<FollowAction*>(action) ||
|
||||||
|
dynamic_cast<FleeAction*>(action) ||
|
||||||
|
dynamic_cast<CastDisengageAction*>(action) ||
|
||||||
|
dynamic_cast<CastBlinkBackAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bot->HasAura(static_cast<uint32>(BlackTempleSpells::SPELL_PLAYER_FEL_RAGE)) &&
|
||||||
|
(dynamic_cast<MovementAction*>(action) &&
|
||||||
|
!dynamic_cast<AttackAction*>(action)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reliquary of Souls
|
||||||
|
|
||||||
|
float ReliquaryOfSoulsDelayDpsCooldownsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* suffering = AI_VALUE2(Unit*, "find target", "essence of suffering");
|
||||||
|
if (!suffering || suffering->GetHealthPct() < 95.0f)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (IsDpsCooldownAction(action) ||
|
||||||
|
(botAI->IsDps(bot) && dynamic_cast<UseTrinketAction*>(action)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ReliquaryOfSoulsDontWasteHealingMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "essence of suffering"))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<CastPowerWordShieldOnAlmostFullHealthBelowAction*>(action) ||
|
||||||
|
dynamic_cast<CastPowerWordShieldOnNotFullAction*>(action) ||
|
||||||
|
dynamic_cast<CastPowerWordShieldAction*>(action) ||
|
||||||
|
dynamic_cast<CastPowerWordShieldOnPartyAction*>(action))
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<CastTreeFormAction*>(action) ||
|
||||||
|
dynamic_cast<CastHealingSpellAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
|
||||||
|
float MotherShahrazDelayDpsCooldownsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* shahraz = AI_VALUE2(Unit*, "find target", "mother shahraz");
|
||||||
|
if (!shahraz || shahraz->GetHealthPct() < 90.0f)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (IsDpsCooldownAction(action) ||
|
||||||
|
(botAI->IsDps(bot) && dynamic_cast<UseTrinketAction*>(action)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MotherShahrazControlMovementMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "mother shahraz"))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<CombatFormationMoveAction*>(action) &&
|
||||||
|
!dynamic_cast<SetBehindTargetAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<FollowAction*>(action) ||
|
||||||
|
dynamic_cast<FleeAction*>(action) ||
|
||||||
|
dynamic_cast<CastDisengageAction*>(action) ||
|
||||||
|
dynamic_cast<CastBlinkBackAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MotherShahrazBotsWithFatalAttractionOnlyRunAwayMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "mother shahraz") ||
|
||||||
|
!bot->HasAura(static_cast<uint32>(BlackTempleSpells::SPELL_FATAL_ATTRACTION)))
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<WipeAction*>(action))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (!dynamic_cast<MotherShahrazRunAwayToBreakFatalAttractionAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Illidari Council
|
||||||
|
|
||||||
|
float IllidariCouncilDelayDpsCooldownsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* gathios = AI_VALUE2(Unit*, "find target", "gathios the shatterer");
|
||||||
|
if (!gathios || gathios->GetHealthPct() < 90.0f)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (IsDpsCooldownAction(action) ||
|
||||||
|
(botAI->IsDps(bot) && dynamic_cast<UseTrinketAction*>(action)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float IllidariCouncilDisableTankActionsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (!botAI->IsTank(bot) ||
|
||||||
|
!AI_VALUE2(Unit*, "find target", "gathios the shatterer"))
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bot->GetVictim() != nullptr && dynamic_cast<TankAssistAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<CastTauntAction*>(action) ||
|
||||||
|
dynamic_cast<CastChallengingShoutAction*>(action) ||
|
||||||
|
dynamic_cast<CastShockwaveAction*>(action) ||
|
||||||
|
dynamic_cast<CastCleaveAction*>(action) ||
|
||||||
|
dynamic_cast<CastGrowlAction*>(action) ||
|
||||||
|
dynamic_cast<CastSwipeAction*>(action) ||
|
||||||
|
dynamic_cast<CastHandOfReckoningAction*>(action) ||
|
||||||
|
dynamic_cast<CastRighteousDefenseAction*>(action) ||
|
||||||
|
dynamic_cast<CastDarkCommandAction*>(action) ||
|
||||||
|
dynamic_cast<CastDeathAndDecayAction*>(action) ||
|
||||||
|
dynamic_cast<CastBloodBoilAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float IllidariCouncilControlMovementMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "high nethermancer zerevor"))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<CombatFormationMoveAction*>(action) &&
|
||||||
|
!dynamic_cast<SetBehindTargetAction*>(action) &&
|
||||||
|
!dynamic_cast<TankFaceAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<FollowAction*>(action) ||
|
||||||
|
dynamic_cast<FleeAction*>(action) ||
|
||||||
|
dynamic_cast<CastDisengageAction*>(action) ||
|
||||||
|
dynamic_cast<CastBlinkBackAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (botAI->IsAssistHealOfIndex(bot, 0, true) &&
|
||||||
|
(dynamic_cast<MovementAction*>(action) &&
|
||||||
|
!dynamic_cast<IllidariCouncilPositionMageTankHealerAction*>(action)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!botAI->IsAssistTankOfIndex(bot, 0, false) &&
|
||||||
|
dynamic_cast<TankFaceAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((botAI->IsMainTank(bot) ||
|
||||||
|
botAI->IsAssistTankOfIndex(bot, 0, false) ||
|
||||||
|
botAI->IsAssistTankOfIndex(bot, 1, false) ||
|
||||||
|
GetZerevorMageTank(bot) == bot) &&
|
||||||
|
dynamic_cast<AvoidAoeAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float IllidariCouncilControlMisdirectionMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_HUNTER ||
|
||||||
|
!AI_VALUE2(Unit*, "find target", "high nethermancer zerevor"))
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<CastMisdirectionOnMainTankAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float IllidariCouncilDisableIceBlockMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_MAGE ||
|
||||||
|
!AI_VALUE2(Unit*, "find target", "high nethermancer zerevor"))
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetZerevorMageTank(bot) != bot)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<CastIceBlockAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float IllidariCouncilDisableArcaneShotOnZerevorMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* zerevor = AI_VALUE2(Unit*, "find target", "high nethermancer zerevor");
|
||||||
|
if (!zerevor)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
if (!target || target->GetGUID() != zerevor->GetGUID())
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<CastArcaneShotAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float IllidariCouncilWaitForDpsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (botAI->IsMainTank(bot) ||
|
||||||
|
botAI->IsAssistTankOfIndex(bot, 0, false) ||
|
||||||
|
botAI->IsAssistTankOfIndex(bot, 1, false) ||
|
||||||
|
GetZerevorMageTank(bot) == bot)
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* gathios = AI_VALUE2(Unit*, "find target", "gathios the shatterer");
|
||||||
|
if (!gathios)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<IllidariCouncilMisdirectBossesToTanksAction*>(action))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
const time_t now = std::time(nullptr);
|
||||||
|
constexpr uint8 dpsWaitSeconds = 5;
|
||||||
|
|
||||||
|
auto it = councilDpsWaitTimer.find(gathios->GetMap()->GetInstanceId());
|
||||||
|
if (it == councilDpsWaitTimer.end() || (now - it->second) >= dpsWaitSeconds)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<AttackAction*>(action) ||
|
||||||
|
(dynamic_cast<CastSpellAction*>(action) &&
|
||||||
|
!dynamic_cast<CastHealingSpellAction*>(action)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
|
||||||
|
float IllidanStormrageDelayDpsCooldownsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (illidan->GetHealthPct() > 62.0f &&
|
||||||
|
(dynamic_cast<CastHeroismAction*>(action) ||
|
||||||
|
dynamic_cast<CastBloodlustAction*>(action)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (illidan->GetHealthPct() <= 62.0f || illidan->GetHealthPct() > 95.0f)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (IsDpsCooldownAction(action) ||
|
||||||
|
(botAI->IsDps(bot) && dynamic_cast<UseTrinketAction*>(action)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float IllidanStormrageControlTankActionsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (!botAI->IsTank(bot))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan || illidan->GetHealth() == 1)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<TankFaceAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
if (GetIllidanPhase(illidan) != 2)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (botAI->IsMainTank(bot))
|
||||||
|
{
|
||||||
|
if (dynamic_cast<MovementAction*>(action) &&
|
||||||
|
!dynamic_cast<IllidanStormragePositionAboveGrateAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<CastMeleeSpellAction*>(action) ||
|
||||||
|
dynamic_cast<CastReachTargetSpellAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (botAI->IsAssistTankOfIndex(bot, 0, false) ||
|
||||||
|
botAI->IsAssistTankOfIndex(bot, 1, false))
|
||||||
|
{
|
||||||
|
if (dynamic_cast<MovementAction*>(action) &&
|
||||||
|
!dynamic_cast<IllidanStormrageAssistTanksHandleFlamesOfAzzinothAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<CastHealingSpellAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float IllidanStormrageDisableDefaultTargetingMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (bot->GetVictim() == nullptr)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan || illidan->GetHealth() == 1)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<TankAssistAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
int phase = GetIllidanPhase(illidan);
|
||||||
|
|
||||||
|
if (phase == 4 && dynamic_cast<DpsAssistAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
if (botAI->IsRangedDps(bot))
|
||||||
|
{
|
||||||
|
if (phase != 2)
|
||||||
|
context->GetValue<bool>("neglect threat")->Set(true);
|
||||||
|
|
||||||
|
if (dynamic_cast<DpsAssistAction*>(action))
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr float searchRadius = 40.0f;
|
||||||
|
Unit* shadowDemon = bot->FindNearestCreature(
|
||||||
|
static_cast<uint32>(BlackTempleNpcs::NPC_SHADOW_DEMON), searchRadius);
|
||||||
|
Unit* shadowfiend = bot->FindNearestCreature(
|
||||||
|
static_cast<uint32>(BlackTempleNpcs::NPC_PARASITIC_SHADOWFIEND), searchRadius);
|
||||||
|
|
||||||
|
if (((shadowDemon && bot->GetTarget() == shadowDemon->GetGUID()) ||
|
||||||
|
(shadowfiend && bot->GetTarget() == shadowfiend->GetGUID())) &&
|
||||||
|
dynamic_cast<CastDebuffSpellOnAttackerAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float IllidanStormrageControlNonTankMovementMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (botAI->IsTank(bot))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan || illidan->GetHealth() == 1)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<CombatFormationMoveAction*>(action) &&
|
||||||
|
!dynamic_cast<SetBehindTargetAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<CastDisengageAction*>(action) ||
|
||||||
|
dynamic_cast<CastBlinkBackAction*>(action) ||
|
||||||
|
dynamic_cast<FleeAction*>(action) ||
|
||||||
|
dynamic_cast<FollowAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int phase = GetIllidanPhase(illidan);
|
||||||
|
|
||||||
|
if (phase == 2 &&
|
||||||
|
(dynamic_cast<SetBehindTargetAction*>(action) ||
|
||||||
|
dynamic_cast<CastKillingSpreeAction*>(action) ||
|
||||||
|
dynamic_cast<ReachTargetAction*>(action) ||
|
||||||
|
dynamic_cast<CastReachTargetSpellAction*>(action) ||
|
||||||
|
dynamic_cast<AvoidAoeAction*>(action)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phase == 4 && botAI->IsHeal(bot) &&
|
||||||
|
dynamic_cast<ReachTargetAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float IllidanStormrageUseEarthbindTotemMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_SHAMAN)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan || GetIllidanPhase(illidan) == 2)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<CastStrengthOfEarthTotemAction*>(action) ||
|
||||||
|
dynamic_cast<CastStoneskinTotemAction*>(action) ||
|
||||||
|
dynamic_cast<CastStoneclawTotemAction*>(action) ||
|
||||||
|
dynamic_cast<CastTremorTotemAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float IllidanStormrageWaitForDpsMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (dynamic_cast<IllidanStormrageMisdirectToTankAction*>(action))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
const time_t now = std::time(nullptr);
|
||||||
|
const uint32 instanceId = illidan->GetMap()->GetInstanceId();
|
||||||
|
|
||||||
|
int phase = GetIllidanPhase(illidan);
|
||||||
|
|
||||||
|
if ((phase == 1 || phase == 3 || phase == 5) &&
|
||||||
|
!botAI->IsMainTank(bot))
|
||||||
|
{
|
||||||
|
constexpr uint8 humanoidPhaseDpsWaitSeconds = 3;
|
||||||
|
auto it = illidanBossDpsWaitTimer.find(instanceId);
|
||||||
|
|
||||||
|
if ((it == illidanBossDpsWaitTimer.end() ||
|
||||||
|
(now - it->second) < humanoidPhaseDpsWaitSeconds) &&
|
||||||
|
(dynamic_cast<AttackAction*>(action) ||
|
||||||
|
(dynamic_cast<CastSpellAction*>(action) &&
|
||||||
|
!dynamic_cast<CastHealingSpellAction*>(action))))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phase == 4 && GetIllidanWarlockTank(bot) != bot)
|
||||||
|
{
|
||||||
|
constexpr uint8 demonPhaseDpsWaitSeconds = 8;
|
||||||
|
auto it = illidanBossDpsWaitTimer.find(instanceId);
|
||||||
|
|
||||||
|
if ((it == illidanBossDpsWaitTimer.end() ||
|
||||||
|
(now - it->second) < demonPhaseDpsWaitSeconds) &&
|
||||||
|
(dynamic_cast<AttackAction*>(action) ||
|
||||||
|
(dynamic_cast<CastSpellAction*>(action) &&
|
||||||
|
!dynamic_cast<CastHealingSpellAction*>(action))))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AI_VALUE2(Unit*, "find target", "flame of azzinoth") &&
|
||||||
|
!botAI->IsAssistTankOfIndex(bot, 0, true) &&
|
||||||
|
!botAI->IsAssistTankOfIndex(bot, 1, true))
|
||||||
|
{
|
||||||
|
constexpr uint8 flamePhaseDpsWaitSeconds = 6;
|
||||||
|
auto it = illidanFlameDpsWaitTimer.find(instanceId);
|
||||||
|
|
||||||
|
if ((it == illidanFlameDpsWaitTimer.end() ||
|
||||||
|
(now - it->second) < flamePhaseDpsWaitSeconds) &&
|
||||||
|
(dynamic_cast<AttackAction*>(action) ||
|
||||||
|
(dynamic_cast<CastSpellAction*>(action) &&
|
||||||
|
!dynamic_cast<CastHealingSpellAction*>(action))))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
267
src/Ai/Raid/BlackTemple/Multiplier/RaidBlackTempleMultipliers.h
Normal file
267
src/Ai/Raid/BlackTemple/Multiplier/RaidBlackTempleMultipliers.h
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
/*
|
||||||
|
* 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_RAIDBLACKTEMPLEMULTIPLIERS_H
|
||||||
|
#define _PLAYERBOT_RAIDBLACKTEMPLEMULTIPLIERS_H
|
||||||
|
|
||||||
|
#include "Multiplier.h"
|
||||||
|
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
|
||||||
|
class HighWarlordNajentusDelayDpsCooldownsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HighWarlordNajentusDelayDpsCooldownsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "high warlord naj'entus delay dps cooldowns multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class HighWarlordNajentusDisableCombatFormationMoveMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HighWarlordNajentusDisableCombatFormationMoveMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "high warlord naj'entus disable combat formation move multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
|
||||||
|
class SupremusDelayDpsCooldownsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SupremusDelayDpsCooldownsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "supremus delay dps cooldowns multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SupremusFocusOnAvoidanceInPhase2Multiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SupremusFocusOnAvoidanceInPhase2Multiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "supremus focus on avoidance in phase 2 multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SupremusHitboxIsBuggedMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SupremusHitboxIsBuggedMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "supremus hitbox is bugged multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
|
||||||
|
class TeronGorefiendDelayDpsCooldownsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendDelayDpsCooldownsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "teron gorefiend delay dps cooldowns multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendControlMovementMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendControlMovementMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "teron gorefiend control movement multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendMarkedBotOnlyMoveToDieMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendMarkedBotOnlyMoveToDieMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "teron gorefiend marked bot only move to die multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendSpiritsAttackOnlyShadowyConstructsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendSpiritsAttackOnlyShadowyConstructsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "teron gorefiend spirits attack only shadowy constructs multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendDisableAttackingConstructsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendDisableAttackingConstructsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "teron gorefiend disable attacking constructs multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
|
||||||
|
class GurtoggBloodboilDelayDpsCooldownsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GurtoggBloodboilDelayDpsCooldownsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "gurtogg bloodboil delay dps cooldowns multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class GurtoggBloodboilControlMovementMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GurtoggBloodboilControlMovementMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "gurtogg bloodboil control movement multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reliquary of Souls
|
||||||
|
|
||||||
|
class ReliquaryOfSoulsDelayDpsCooldownsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReliquaryOfSoulsDelayDpsCooldownsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "reliquary of souls delay dps cooldowns multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReliquaryOfSoulsDontWasteHealingMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReliquaryOfSoulsDontWasteHealingMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "reliquary of souls don't waste healing multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
|
||||||
|
class MotherShahrazDelayDpsCooldownsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotherShahrazDelayDpsCooldownsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "mother shahraz delay dps cooldowns multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class MotherShahrazControlMovementMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotherShahrazControlMovementMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "mother shahraz control movement multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class MotherShahrazBotsWithFatalAttractionOnlyRunAwayMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotherShahrazBotsWithFatalAttractionOnlyRunAwayMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "mother shahraz bots with fatal attraction only run away multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Illidari Council
|
||||||
|
|
||||||
|
class IllidariCouncilDelayDpsCooldownsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilDelayDpsCooldownsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "illidari council delay dps cooldowns multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilDisableTankActionsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilDisableTankActionsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "illidari council disable tank actions multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilControlMovementMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilControlMovementMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "illidari council control movement multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilControlMisdirectionMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilControlMisdirectionMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "illidari council control misdirection multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilDisableArcaneShotOnZerevorMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilDisableArcaneShotOnZerevorMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "illidari council disable arcane shot on zerevor multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilDisableIceBlockMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilDisableIceBlockMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "illidari council disable ice block multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilWaitForDpsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilWaitForDpsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "illidari council wait for dps multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
|
||||||
|
class IllidanStormrageDelayDpsCooldownsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageDelayDpsCooldownsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "illidan stormrage delay dps cooldowns multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageControlTankActionsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageControlTankActionsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "illidan stormrage control tank actions multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageDisableDefaultTargetingMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageDisableDefaultTargetingMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "illidan stormrage disable default targeting multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageControlNonTankMovementMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageControlNonTankMovementMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "illidan stormrage control non-tank movement multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageUseEarthbindTotemMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageUseEarthbindTotemMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "illidan stormrage use earthbind totem multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageWaitForDpsMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageWaitForDpsMultiplier(
|
||||||
|
PlayerbotAI* botAI) : Multiplier(botAI, "illidan stormrage wait for dps multiplier") {}
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
406
src/Ai/Raid/BlackTemple/RaidBlackTempleActionContext.h
Normal file
406
src/Ai/Raid/BlackTemple/RaidBlackTempleActionContext.h
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
/*
|
||||||
|
* 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_RAIDBLACKTEMPLEACTIONCONTEXT_H
|
||||||
|
#define _PLAYERBOT_RAIDBLACKTEMPLEACTIONCONTEXT_H
|
||||||
|
|
||||||
|
#include "NamedObjectContext.h"
|
||||||
|
#include "RaidBlackTempleActions.h"
|
||||||
|
|
||||||
|
class RaidBlackTempleActionContext : public NamedObjectContext<Action>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RaidBlackTempleActionContext()
|
||||||
|
{
|
||||||
|
// General
|
||||||
|
creators["black temple erase timers and trackers"] =
|
||||||
|
&RaidBlackTempleActionContext::black_temple_erase_timers_and_trackers;
|
||||||
|
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
creators["high warlord naj'entus misdirect boss to main tank"] =
|
||||||
|
&RaidBlackTempleActionContext::high_warlord_najentus_misdirect_boss_to_main_tank;
|
||||||
|
|
||||||
|
creators["high warlord naj'entus tanks position boss"] =
|
||||||
|
&RaidBlackTempleActionContext::high_warlord_najentus_tanks_position_boss;
|
||||||
|
|
||||||
|
creators["high warlord naj'entus disperse ranged"] =
|
||||||
|
&RaidBlackTempleActionContext::high_warlord_najentus_disperse_ranged;
|
||||||
|
|
||||||
|
creators["high warlord naj'entus remove impaling spine"] =
|
||||||
|
&RaidBlackTempleActionContext::high_warlord_najentus_remove_impaling_spine;
|
||||||
|
|
||||||
|
creators["high warlord naj'entus throw impaling spine"] =
|
||||||
|
&RaidBlackTempleActionContext::high_warlord_najentus_throw_impaling_spine;
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
creators["supremus misdirect boss to main tank"] =
|
||||||
|
&RaidBlackTempleActionContext::supremus_misdirect_boss_to_main_tank;
|
||||||
|
|
||||||
|
creators["supremus disperse ranged"] =
|
||||||
|
&RaidBlackTempleActionContext::supremus_disperse_ranged;
|
||||||
|
|
||||||
|
creators["supremus kite boss"] =
|
||||||
|
&RaidBlackTempleActionContext::supremus_kite_boss;
|
||||||
|
|
||||||
|
creators["supremus move away from volcanos"] =
|
||||||
|
&RaidBlackTempleActionContext::supremus_move_away_from_volcanos;
|
||||||
|
|
||||||
|
creators["supremus manage phase timer"] =
|
||||||
|
&RaidBlackTempleActionContext::supremus_manage_phase_timer;
|
||||||
|
|
||||||
|
// Shade of Akama
|
||||||
|
creators["shade of akama melee dps prioritize channelers"] =
|
||||||
|
&RaidBlackTempleActionContext::shade_of_akama_melee_dps_prioritize_channelers;
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
creators["teron gorefiend misdirect boss to main tank"] =
|
||||||
|
&RaidBlackTempleActionContext::teron_gorefiend_misdirect_boss_to_main_tank;
|
||||||
|
|
||||||
|
creators["teron gorefiend tanks position boss"] =
|
||||||
|
&RaidBlackTempleActionContext::teron_gorefiend_tanks_position_boss;
|
||||||
|
|
||||||
|
creators["teron gorefiend position ranged on balcony"] =
|
||||||
|
&RaidBlackTempleActionContext::teron_gorefiend_position_ranged_on_balcony;
|
||||||
|
|
||||||
|
creators["teron gorefiend avoid shadow of death"] =
|
||||||
|
&RaidBlackTempleActionContext::teron_gorefiend_avoid_shadow_of_death;
|
||||||
|
|
||||||
|
creators["teron gorefiend move to corner to die"] =
|
||||||
|
&RaidBlackTempleActionContext::teron_gorefiend_move_to_corner_to_die;
|
||||||
|
|
||||||
|
creators["teron gorefiend control and destroy shadowy constructs"] =
|
||||||
|
&RaidBlackTempleActionContext::teron_gorefiend_control_and_destroy_shadowy_constructs;
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
creators["gurtogg bloodboil misdirect boss to main tank"] =
|
||||||
|
&RaidBlackTempleActionContext::gurtogg_bloodboil_misdirect_boss_to_main_tank;
|
||||||
|
|
||||||
|
creators["gurtogg bloodboil tanks position boss"] =
|
||||||
|
&RaidBlackTempleActionContext::gurtogg_bloodboil_tanks_position_boss;
|
||||||
|
|
||||||
|
creators["gurtogg bloodboil rotate ranged groups"] =
|
||||||
|
&RaidBlackTempleActionContext::gurtogg_bloodboil_rotate_ranged_groups;
|
||||||
|
|
||||||
|
creators["gurtogg bloodboil ranged move away from enraged player"] =
|
||||||
|
&RaidBlackTempleActionContext::gurtogg_bloodboil_ranged_move_away_from_enraged_player;
|
||||||
|
|
||||||
|
creators["gurtogg bloodboil manage phase timer"] =
|
||||||
|
&RaidBlackTempleActionContext::gurtogg_bloodboil_manage_phase_timer;
|
||||||
|
|
||||||
|
// Reliquary of Souls
|
||||||
|
creators["reliquary of souls misdirect boss to main tank"] =
|
||||||
|
&RaidBlackTempleActionContext::reliquary_of_souls_misdirect_boss_to_main_tank;
|
||||||
|
|
||||||
|
creators["reliquary of souls adjust distance from suffering"] =
|
||||||
|
&RaidBlackTempleActionContext::reliquary_of_souls_adjust_distance_from_suffering;
|
||||||
|
|
||||||
|
creators["reliquary of souls healers dps suffering"] =
|
||||||
|
&RaidBlackTempleActionContext::reliquary_of_souls_healers_dps_suffering;
|
||||||
|
|
||||||
|
creators["reliquary of souls spellsteal rune shield"] =
|
||||||
|
&RaidBlackTempleActionContext::reliquary_of_souls_spellsteal_rune_shield;
|
||||||
|
|
||||||
|
creators["reliquary of souls spell reflect deaden"] =
|
||||||
|
&RaidBlackTempleActionContext::reliquary_of_souls_spell_reflect_deaden;
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
creators["mother shahraz misdirect boss to main tank"] =
|
||||||
|
&RaidBlackTempleActionContext::mother_shahraz_misdirect_boss_to_main_tank;
|
||||||
|
|
||||||
|
creators["mother shahraz tanks position boss under pillar"] =
|
||||||
|
&RaidBlackTempleActionContext::mother_shahraz_tanks_position_boss_under_pillar;
|
||||||
|
|
||||||
|
creators["mother shahraz melee dps wait at safe position"] =
|
||||||
|
&RaidBlackTempleActionContext::mother_shahraz_melee_dps_wait_at_safe_position;
|
||||||
|
|
||||||
|
creators["mother shahraz position ranged under pillar"] =
|
||||||
|
&RaidBlackTempleActionContext::mother_shahraz_position_ranged_under_pillar;
|
||||||
|
|
||||||
|
creators["mother shahraz run away to break fatal attraction"] =
|
||||||
|
&RaidBlackTempleActionContext::mother_shahraz_run_away_to_break_fatal_attraction;
|
||||||
|
|
||||||
|
// Illidari Council
|
||||||
|
creators["illidari council misdirect bosses to tanks"] =
|
||||||
|
&RaidBlackTempleActionContext::illidari_council_misdirect_bosses_to_tanks;
|
||||||
|
|
||||||
|
creators["illidari council main tank position gathios"] =
|
||||||
|
&RaidBlackTempleActionContext::illidari_council_main_tank_position_gathios;
|
||||||
|
|
||||||
|
creators["illidari council main tank reflect judgement of command"] =
|
||||||
|
&RaidBlackTempleActionContext::illidari_council_main_tank_reflect_judgement_of_command;
|
||||||
|
|
||||||
|
creators["illidari council first assist tank focus malande"] =
|
||||||
|
&RaidBlackTempleActionContext::illidari_council_first_assist_tank_focus_malande;
|
||||||
|
|
||||||
|
creators["illidari council second assist tank position darkshadow"] =
|
||||||
|
&RaidBlackTempleActionContext::illidari_council_second_assist_tank_position_darkshadow;
|
||||||
|
|
||||||
|
creators["illidari council mage tank position zerevor"] =
|
||||||
|
&RaidBlackTempleActionContext::illidari_council_mage_tank_position_zerevor;
|
||||||
|
|
||||||
|
creators["illidari council position mage tank healer"] =
|
||||||
|
&RaidBlackTempleActionContext::illidari_council_position_mage_tank_healer;
|
||||||
|
|
||||||
|
creators["illidari council disperse ranged"] =
|
||||||
|
&RaidBlackTempleActionContext::illidari_council_disperse_ranged;
|
||||||
|
|
||||||
|
creators["illidari council command pets to attack gathios"] =
|
||||||
|
&RaidBlackTempleActionContext::illidari_council_command_pets_to_attack_gathios;
|
||||||
|
|
||||||
|
creators["illidari council assign dps targets"] =
|
||||||
|
&RaidBlackTempleActionContext::illidari_council_assign_dps_targets;
|
||||||
|
|
||||||
|
creators["illidari council manage dps timer"] =
|
||||||
|
&RaidBlackTempleActionContext::illidari_council_manage_dps_timer;
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
creators["illidan stormrage misdirect to tank"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_misdirect_to_tank;
|
||||||
|
|
||||||
|
creators["illidan stormrage main tank reposition boss"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_main_tank_reposition_boss;
|
||||||
|
|
||||||
|
creators["illidan stormrage isolate bot with parasite"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_isolate_bot_with_parasite;
|
||||||
|
|
||||||
|
creators["illidan stormrage set earthbind totem"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_set_earthbind_totem;
|
||||||
|
|
||||||
|
creators["illidan stormrage assist tanks handle flames of azzinoth"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_assist_tanks_handle_flames_of_azzinoth;
|
||||||
|
|
||||||
|
creators["illidan stormrage control pet aggression"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_control_pet_aggression;
|
||||||
|
|
||||||
|
creators["illidan stormrage position above grate"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_position_above_grate;
|
||||||
|
|
||||||
|
creators["illidan stormrage remove dark barrage"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_remove_dark_barrage;
|
||||||
|
|
||||||
|
creators["illidan stormrage move away from landing point"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_move_away_from_landing_point;
|
||||||
|
|
||||||
|
creators["illidan stormrage disperse ranged"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_disperse_ranged;
|
||||||
|
|
||||||
|
creators["illidan stormrage melee go somewhere to not die"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_melee_go_somewhere_to_not_die;
|
||||||
|
|
||||||
|
creators["illidan stormrage warlock tank handle demon boss"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_warlock_tank_handle_demon_boss;
|
||||||
|
|
||||||
|
creators["illidan stormrage dps prioritize adds"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_dps_prioritize_adds;
|
||||||
|
|
||||||
|
creators["illidan stormrage use shadow trap"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_use_shadow_trap;
|
||||||
|
|
||||||
|
creators["illidan stormrage manage dps timer and rti"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_manage_dps_timer_and_rti;
|
||||||
|
|
||||||
|
creators["illidan stormrage destroy hazards"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_destroy_hazards;
|
||||||
|
|
||||||
|
creators["illidan stormrage handle adds cheat"] =
|
||||||
|
&RaidBlackTempleActionContext::illidan_stormrage_handle_adds_cheat;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// General
|
||||||
|
static Action* black_temple_erase_timers_and_trackers(
|
||||||
|
PlayerbotAI* botAI) { return new BlackTempleEraseTimersAndTrackersAction(botAI); }
|
||||||
|
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
static Action* high_warlord_najentus_misdirect_boss_to_main_tank(
|
||||||
|
PlayerbotAI* botAI) { return new HighWarlordNajentusMisdirectBossToMainTankAction(botAI); }
|
||||||
|
|
||||||
|
static Action* high_warlord_najentus_tanks_position_boss(
|
||||||
|
PlayerbotAI* botAI) { return new HighWarlordNajentusTanksPositionBossAction(botAI); }
|
||||||
|
|
||||||
|
static Action* high_warlord_najentus_disperse_ranged(
|
||||||
|
PlayerbotAI* botAI) { return new HighWarlordNajentusDisperseRangedAction(botAI); }
|
||||||
|
|
||||||
|
static Action* high_warlord_najentus_remove_impaling_spine(
|
||||||
|
PlayerbotAI* botAI) { return new HighWarlordNajentusRemoveImpalingSpineAction(botAI); }
|
||||||
|
|
||||||
|
static Action* high_warlord_najentus_throw_impaling_spine(
|
||||||
|
PlayerbotAI* botAI) { return new HighWarlordNajentusThrowImpalingSpineAction(botAI); }
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
static Action* supremus_misdirect_boss_to_main_tank(
|
||||||
|
PlayerbotAI* botAI) { return new SupremusMisdirectBossToMainTankAction(botAI); }
|
||||||
|
|
||||||
|
static Action* supremus_disperse_ranged(
|
||||||
|
PlayerbotAI* botAI) { return new SupremusDisperseRangedAction(botAI); }
|
||||||
|
|
||||||
|
static Action* supremus_kite_boss(
|
||||||
|
PlayerbotAI* botAI) { return new SupremusKiteBossAction(botAI); }
|
||||||
|
|
||||||
|
static Action* supremus_move_away_from_volcanos(
|
||||||
|
PlayerbotAI* botAI) { return new SupremusMoveAwayFromVolcanosAction(botAI); }
|
||||||
|
|
||||||
|
static Action* supremus_manage_phase_timer(
|
||||||
|
PlayerbotAI* botAI) { return new SupremusManagePhaseTimerAction(botAI); }
|
||||||
|
|
||||||
|
// Shade of Akama
|
||||||
|
static Action* shade_of_akama_melee_dps_prioritize_channelers(
|
||||||
|
PlayerbotAI* botAI) { return new ShadeOfAkamaMeleeDpsPrioritizeChannelersAction(botAI); }
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
static Action* teron_gorefiend_misdirect_boss_to_main_tank(
|
||||||
|
PlayerbotAI* botAI) { return new TeronGorefiendMisdirectBossToMainTankAction(botAI); }
|
||||||
|
|
||||||
|
static Action* teron_gorefiend_tanks_position_boss(
|
||||||
|
PlayerbotAI* botAI) { return new TeronGorefiendTanksPositionBossAction(botAI); }
|
||||||
|
|
||||||
|
static Action* teron_gorefiend_position_ranged_on_balcony(
|
||||||
|
PlayerbotAI* botAI) { return new TeronGorefiendPositionRangedOnBalconyAction(botAI); }
|
||||||
|
|
||||||
|
static Action* teron_gorefiend_avoid_shadow_of_death(
|
||||||
|
PlayerbotAI* botAI) { return new TeronGorefiendAvoidShadowOfDeathAction(botAI); }
|
||||||
|
|
||||||
|
static Action* teron_gorefiend_move_to_corner_to_die(
|
||||||
|
PlayerbotAI* botAI) { return new TeronGorefiendMoveToCornerToDieAction(botAI); }
|
||||||
|
|
||||||
|
static Action* teron_gorefiend_control_and_destroy_shadowy_constructs(
|
||||||
|
PlayerbotAI* botAI) { return new TeronGorefiendControlAndDestroyShadowyConstructsAction(botAI); }
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
static Action* gurtogg_bloodboil_misdirect_boss_to_main_tank(
|
||||||
|
PlayerbotAI* botAI) { return new GurtoggBloodboilMisdirectBossToMainTankAction(botAI); }
|
||||||
|
|
||||||
|
static Action* gurtogg_bloodboil_tanks_position_boss(
|
||||||
|
PlayerbotAI* botAI) { return new GurtoggBloodboilTanksPositionBossAction(botAI); }
|
||||||
|
|
||||||
|
static Action* gurtogg_bloodboil_rotate_ranged_groups(
|
||||||
|
PlayerbotAI* botAI) { return new GurtoggBloodboilRotateRangedGroupsAction(botAI); }
|
||||||
|
|
||||||
|
static Action* gurtogg_bloodboil_ranged_move_away_from_enraged_player(
|
||||||
|
PlayerbotAI* botAI) { return new GurtoggBloodboilRangedMoveAwayFromEnragedPlayerAction(botAI); }
|
||||||
|
|
||||||
|
static Action* gurtogg_bloodboil_manage_phase_timer(
|
||||||
|
PlayerbotAI* botAI) { return new GurtoggBloodboilManagePhaseTimerAction(botAI); }
|
||||||
|
|
||||||
|
// Reliquary of Souls
|
||||||
|
static Action* reliquary_of_souls_misdirect_boss_to_main_tank(
|
||||||
|
PlayerbotAI* botAI) { return new ReliquaryOfSoulsMisdirectBossToMainTankAction(botAI); }
|
||||||
|
|
||||||
|
static Action* reliquary_of_souls_adjust_distance_from_suffering(
|
||||||
|
PlayerbotAI* botAI) { return new ReliquaryOfSoulsAdjustDistanceFromSufferingAction(botAI); }
|
||||||
|
|
||||||
|
static Action* reliquary_of_souls_healers_dps_suffering(
|
||||||
|
PlayerbotAI* botAI) { return new ReliquaryOfSoulsHealersDpsSufferingAction(botAI); }
|
||||||
|
|
||||||
|
static Action* reliquary_of_souls_spellsteal_rune_shield(
|
||||||
|
PlayerbotAI* botAI) { return new ReliquaryOfSoulsSpellstealRuneShieldAction(botAI); }
|
||||||
|
|
||||||
|
static Action* reliquary_of_souls_spell_reflect_deaden(
|
||||||
|
PlayerbotAI* botAI) { return new ReliquaryOfSoulsSpellReflectDeadenAction(botAI); }
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
static Action* mother_shahraz_misdirect_boss_to_main_tank(
|
||||||
|
PlayerbotAI* botAI) { return new MotherShahrazMisdirectBossToMainTankAction(botAI); }
|
||||||
|
|
||||||
|
static Action* mother_shahraz_tanks_position_boss_under_pillar(
|
||||||
|
PlayerbotAI* botAI) { return new MotherShahrazTanksPositionBossUnderPillarAction(botAI); }
|
||||||
|
|
||||||
|
static Action* mother_shahraz_melee_dps_wait_at_safe_position(
|
||||||
|
PlayerbotAI* botAI) { return new MotherShahrazMeleeDpsWaitAtSafePositionAction(botAI); }
|
||||||
|
|
||||||
|
static Action* mother_shahraz_position_ranged_under_pillar(
|
||||||
|
PlayerbotAI* botAI) { return new MotherShahrazPositionRangedUnderPillarAction(botAI); }
|
||||||
|
|
||||||
|
static Action* mother_shahraz_run_away_to_break_fatal_attraction(
|
||||||
|
PlayerbotAI* botAI) { return new MotherShahrazRunAwayToBreakFatalAttractionAction(botAI); }
|
||||||
|
|
||||||
|
// Illidari Council
|
||||||
|
static Action* illidari_council_misdirect_bosses_to_tanks(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilMisdirectBossesToTanksAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidari_council_main_tank_position_gathios(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilMainTankPositionGathiosAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidari_council_main_tank_reflect_judgement_of_command(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilMainTankReflectJudgementOfCommandAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidari_council_first_assist_tank_focus_malande(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilFirstAssistTankFocusMalandeAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidari_council_second_assist_tank_position_darkshadow(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilSecondAssistTankPositionDarkshadowAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidari_council_mage_tank_position_zerevor(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilMageTankPositionZerevorAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidari_council_position_mage_tank_healer(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilPositionMageTankHealerAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidari_council_disperse_ranged(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilDisperseRangedAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidari_council_command_pets_to_attack_gathios(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilCommandPetsToAttackGathiosAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidari_council_assign_dps_targets(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilAssignDpsTargetsAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidari_council_manage_dps_timer(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilManageDpsTimerAction(botAI); }
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
static Action* illidan_stormrage_misdirect_to_tank(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageMisdirectToTankAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_main_tank_reposition_boss(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageMainTankRepositionBossAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_isolate_bot_with_parasite(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageIsolateBotWithParasiteAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_set_earthbind_totem(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageSetEarthbindTotemAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_assist_tanks_handle_flames_of_azzinoth(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageAssistTanksHandleFlamesOfAzzinothAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_control_pet_aggression(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageControlPetAggressionAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_position_above_grate(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormragePositionAboveGrateAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_remove_dark_barrage(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageRemoveDarkBarrageAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_move_away_from_landing_point(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageMoveAwayFromLandingPointAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_disperse_ranged(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageDisperseRangedAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_melee_go_somewhere_to_not_die(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageMeleeGoSomewhereToNotDieAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_warlock_tank_handle_demon_boss(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageWarlockTankHandleDemonBossAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_dps_prioritize_adds(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageDpsPrioritizeAddsAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_use_shadow_trap(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageUseShadowTrapAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_manage_dps_timer_and_rti(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageManageDpsTimerAndRtiAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_destroy_hazards(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageDestroyHazardsAction(botAI); }
|
||||||
|
|
||||||
|
static Action* illidan_stormrage_handle_adds_cheat(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageHandleAddsCheatAction(botAI); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
406
src/Ai/Raid/BlackTemple/RaidBlackTempleTriggerContext.h
Normal file
406
src/Ai/Raid/BlackTemple/RaidBlackTempleTriggerContext.h
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
/*
|
||||||
|
* 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_RAIDBLACKTEMPLETRIGGERCONTEXT_H
|
||||||
|
#define _PLAYERBOT_RAIDBLACKTEMPLETRIGGERCONTEXT_H
|
||||||
|
|
||||||
|
#include "NamedObjectContext.h"
|
||||||
|
#include "RaidBlackTempleTriggers.h"
|
||||||
|
|
||||||
|
class RaidBlackTempleTriggerContext : public NamedObjectContext<Trigger>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RaidBlackTempleTriggerContext()
|
||||||
|
{
|
||||||
|
// General
|
||||||
|
creators["black temple bot is not in combat"] =
|
||||||
|
&RaidBlackTempleTriggerContext::black_temple_bot_is_not_in_combat;
|
||||||
|
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
creators["high warlord naj'entus pulling boss"] =
|
||||||
|
&RaidBlackTempleTriggerContext::high_warlord_najentus_pulling_boss;
|
||||||
|
|
||||||
|
creators["high warlord naj'entus boss engaged by tanks"] =
|
||||||
|
&RaidBlackTempleTriggerContext::high_warlord_najentus_boss_engaged_by_tanks;
|
||||||
|
|
||||||
|
creators["high warlord naj'entus casts needle spines"] =
|
||||||
|
&RaidBlackTempleTriggerContext::high_warlord_najentus_casts_needle_spines;
|
||||||
|
|
||||||
|
creators["high warlord naj'entus player is impaled"] =
|
||||||
|
&RaidBlackTempleTriggerContext::high_warlord_najentus_player_is_impaled;
|
||||||
|
|
||||||
|
creators["high warlord naj'entus boss has tidal shield"] =
|
||||||
|
&RaidBlackTempleTriggerContext::high_warlord_najentus_boss_has_tidal_shield;
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
creators["supremus pulling boss or changing phase"] =
|
||||||
|
&RaidBlackTempleTriggerContext::supremus_pulling_boss_or_changing_phase;
|
||||||
|
|
||||||
|
creators["supremus boss engaged by ranged"] =
|
||||||
|
&RaidBlackTempleTriggerContext::supremus_boss_engaged_by_ranged;
|
||||||
|
|
||||||
|
creators["supremus boss is fixated on bot"] =
|
||||||
|
&RaidBlackTempleTriggerContext::supremus_boss_is_fixated_on_bot;
|
||||||
|
|
||||||
|
creators["supremus volcano is nearby"] =
|
||||||
|
&RaidBlackTempleTriggerContext::supremus_volcano_is_nearby;
|
||||||
|
|
||||||
|
creators["supremus need to manage phase timer"] =
|
||||||
|
&RaidBlackTempleTriggerContext::supremus_need_to_manage_phase_timer;
|
||||||
|
|
||||||
|
// Shade of Akama
|
||||||
|
creators["shade of akama killing channelers starts phase 2"] =
|
||||||
|
&RaidBlackTempleTriggerContext::shade_of_akama_killing_channelers_starts_phase_2;
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
creators["teron gorefiend pulling boss"] =
|
||||||
|
&RaidBlackTempleTriggerContext::teron_gorefiend_pulling_boss;
|
||||||
|
|
||||||
|
creators["teron gorefiend boss engaged by tanks"] =
|
||||||
|
&RaidBlackTempleTriggerContext::teron_gorefiend_boss_engaged_by_tanks;
|
||||||
|
|
||||||
|
creators["teron gorefiend boss engaged by ranged"] =
|
||||||
|
&RaidBlackTempleTriggerContext::teron_gorefiend_boss_engaged_by_ranged;
|
||||||
|
|
||||||
|
creators["teron gorefiend boss is casting shadow of death"] =
|
||||||
|
&RaidBlackTempleTriggerContext::teron_gorefiend_boss_is_casting_shadow_of_death;
|
||||||
|
|
||||||
|
creators["teron gorefiend bot has shadow of death"] =
|
||||||
|
&RaidBlackTempleTriggerContext::teron_gorefiend_bot_has_shadow_of_death;
|
||||||
|
|
||||||
|
creators["teron gorefiend bot transformed into vengeful spirit"] =
|
||||||
|
&RaidBlackTempleTriggerContext::teron_gorefiend_bot_transformed_into_vengeful_spirit;
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
creators["gurtogg bloodboil pulling boss"] =
|
||||||
|
&RaidBlackTempleTriggerContext::gurtogg_bloodboil_pulling_boss;
|
||||||
|
|
||||||
|
creators["gurtogg bloodboil boss engaged by tanks"] =
|
||||||
|
&RaidBlackTempleTriggerContext::gurtogg_bloodboil_boss_engaged_by_tanks;
|
||||||
|
|
||||||
|
creators["gurtogg bloodboil boss casts bloodboil"] =
|
||||||
|
&RaidBlackTempleTriggerContext::gurtogg_bloodboil_boss_casts_bloodboil;
|
||||||
|
|
||||||
|
creators["gurtogg bloodboil bot has fel rage"] =
|
||||||
|
&RaidBlackTempleTriggerContext::gurtogg_bloodboil_bot_has_fel_rage;
|
||||||
|
|
||||||
|
creators["gurtogg bloodboil need to manage phase timer"] =
|
||||||
|
&RaidBlackTempleTriggerContext::gurtogg_bloodboil_need_to_manage_phase_timer;
|
||||||
|
|
||||||
|
// Reliquary of Souls
|
||||||
|
creators["reliquary of souls aggro resets upon phase change"] =
|
||||||
|
&RaidBlackTempleTriggerContext::reliquary_of_souls_aggro_resets_upon_phase_change;
|
||||||
|
|
||||||
|
creators["reliquary of souls essence of suffering fixates on closest target"] =
|
||||||
|
&RaidBlackTempleTriggerContext::reliquary_of_souls_essence_of_suffering_fixates_on_closest_target;
|
||||||
|
|
||||||
|
creators["reliquary of souls essence of suffering disables healing"] =
|
||||||
|
&RaidBlackTempleTriggerContext::reliquary_of_souls_essence_of_suffering_disables_healing;
|
||||||
|
|
||||||
|
creators["reliquary of souls essence of desire has rune shield"] =
|
||||||
|
&RaidBlackTempleTriggerContext::reliquary_of_souls_essence_of_desire_has_rune_shield;
|
||||||
|
|
||||||
|
creators["reliquary of souls essence of desire casting deaden"] =
|
||||||
|
&RaidBlackTempleTriggerContext::reliquary_of_souls_essence_of_desire_casting_deaden;
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
creators["mother shahraz pulling boss"] =
|
||||||
|
&RaidBlackTempleTriggerContext::mother_shahraz_pulling_boss;
|
||||||
|
|
||||||
|
creators["mother shahraz boss engaged by tanks"] =
|
||||||
|
&RaidBlackTempleTriggerContext::mother_shahraz_boss_engaged_by_tanks;
|
||||||
|
|
||||||
|
creators["mother shahraz tanks are positioning boss"] =
|
||||||
|
&RaidBlackTempleTriggerContext::mother_shahraz_tanks_are_positioning_boss;
|
||||||
|
|
||||||
|
creators["mother shahraz sinister beam knocks back players"] =
|
||||||
|
&RaidBlackTempleTriggerContext::mother_shahraz_sinister_beam_knocks_back_players;
|
||||||
|
|
||||||
|
creators["mother shahraz bots are linked by fatal attraction"] =
|
||||||
|
&RaidBlackTempleTriggerContext::mother_shahraz_bots_are_linked_by_fatal_attraction;
|
||||||
|
|
||||||
|
// Illidari Council
|
||||||
|
creators["illidari council pulling bosses"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidari_council_pulling_bosses;
|
||||||
|
|
||||||
|
creators["illidari council gathios engaged by main tank"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidari_council_gathios_engaged_by_main_tank;
|
||||||
|
|
||||||
|
creators["illidari council gathios casting judgement of command"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidari_council_gathios_casting_judgement_of_command;
|
||||||
|
|
||||||
|
creators["illidari council malande engaged by first assist tank"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidari_council_malande_engaged_by_first_assist_tank;
|
||||||
|
|
||||||
|
creators["illidari council darkshadow engaged by second assist tank"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidari_council_darkshadow_engaged_by_second_assist_tank;
|
||||||
|
|
||||||
|
creators["illidari council zerevor engaged by mage tank"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidari_council_zerevor_engaged_by_mage_tank;
|
||||||
|
|
||||||
|
creators["illidari council mage tank needs dedicated healer"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidari_council_mage_tank_needs_dedicated_healer;
|
||||||
|
|
||||||
|
creators["illidari council zerevor casts dangerous aoes"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidari_council_zerevor_casts_dangerous_aoes;
|
||||||
|
|
||||||
|
creators["illidari council pets screw up the pull"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidari_council_pets_screw_up_the_pull;
|
||||||
|
|
||||||
|
creators["illidari council determining dps assignments"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidari_council_determining_dps_assignments;
|
||||||
|
|
||||||
|
creators["illidari council need to manage dps timer"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidari_council_need_to_manage_dps_timer;
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
creators["illidan stormrage tank needs aggro"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_tank_needs_aggro;
|
||||||
|
|
||||||
|
creators["illidan stormrage boss casts flame crash in front of main tank"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_boss_casts_flame_crash_in_front_of_main_tank;
|
||||||
|
|
||||||
|
creators["illidan stormrage bot has parasitic shadowfiend"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_bot_has_parasitic_shadowfiend;
|
||||||
|
|
||||||
|
creators["illidan stormrage parasitic shadowfiends run wild"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_parasitic_shadowfiends_run_wild;
|
||||||
|
|
||||||
|
creators["illidan stormrage boss summoned flames of azzinoth"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_boss_summoned_flames_of_azzinoth;
|
||||||
|
|
||||||
|
creators["illidan stormrage pets die to fire"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_pets_die_to_fire;
|
||||||
|
|
||||||
|
creators["illidan stormrage grate is safe from flames"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_grate_is_safe_from_flames;
|
||||||
|
|
||||||
|
creators["illidan stormrage bot struck by dark barrage"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_bot_struck_by_dark_barrage;
|
||||||
|
|
||||||
|
creators["illidan stormrage boss is preparing to land"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_boss_is_preparing_to_land;
|
||||||
|
|
||||||
|
creators["illidan stormrage boss deals splash damage"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_boss_deals_splash_damage;
|
||||||
|
|
||||||
|
creators["illidan stormrage this expansion hates melee"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_this_expansion_hates_melee;
|
||||||
|
|
||||||
|
creators["illidan stormrage boss transforms into demon"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_boss_transforms_into_demon;
|
||||||
|
|
||||||
|
creators["illidan stormrage boss spawns adds"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_boss_spawns_adds;
|
||||||
|
|
||||||
|
creators["illidan stormrage maiev placed shadow trap"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_maiev_placed_shadow_trap;
|
||||||
|
|
||||||
|
creators["illidan stormrage need to manage dps timer and rti"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_need_to_manage_dps_timer_and_rti;
|
||||||
|
|
||||||
|
creators["illidan stormrage need to clear hazards between phases"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_need_to_clear_hazards_between_phases;
|
||||||
|
|
||||||
|
creators["illidan stormrage cheat"] =
|
||||||
|
&RaidBlackTempleTriggerContext::illidan_stormrage_cheat;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// General
|
||||||
|
static Trigger* black_temple_bot_is_not_in_combat(
|
||||||
|
PlayerbotAI* botAI) { return new BlackTempleBotIsNotInCombatTrigger(botAI); }
|
||||||
|
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
static Trigger* high_warlord_najentus_pulling_boss(
|
||||||
|
PlayerbotAI* botAI) { return new HighWarlordNajentusPullingBossTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* high_warlord_najentus_boss_engaged_by_tanks(
|
||||||
|
PlayerbotAI* botAI) { return new HighWarlordNajentusBossEngagedByTanksTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* high_warlord_najentus_casts_needle_spines(
|
||||||
|
PlayerbotAI* botAI) { return new HighWarlordNajentusCastsNeedleSpinesTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* high_warlord_najentus_player_is_impaled(
|
||||||
|
PlayerbotAI* botAI) { return new HighWarlordNajentusPlayerIsImpaledTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* high_warlord_najentus_boss_has_tidal_shield(
|
||||||
|
PlayerbotAI* botAI) { return new HighWarlordNajentusBossHasTidalShieldTrigger(botAI); }
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
static Trigger* supremus_pulling_boss_or_changing_phase(
|
||||||
|
PlayerbotAI* botAI) { return new SupremusPullingBossOrChangingPhaseTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* supremus_boss_engaged_by_ranged(
|
||||||
|
PlayerbotAI* botAI) { return new SupremusBossEngagedByRangedTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* supremus_boss_is_fixated_on_bot(
|
||||||
|
PlayerbotAI* botAI) { return new SupremusBossIsFixatedOnBotTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* supremus_volcano_is_nearby(
|
||||||
|
PlayerbotAI* botAI) { return new SupremusVolcanoIsNearbyTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* supremus_need_to_manage_phase_timer(
|
||||||
|
PlayerbotAI* botAI) { return new SupremusNeedToManagePhaseTimerTrigger(botAI); }
|
||||||
|
|
||||||
|
// Shade of Akama
|
||||||
|
static Trigger* shade_of_akama_killing_channelers_starts_phase_2(
|
||||||
|
PlayerbotAI* botAI) { return new ShadeOfAkamaKillingChannelersStartsPhase2Trigger(botAI); }
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
static Trigger* teron_gorefiend_pulling_boss(
|
||||||
|
PlayerbotAI* botAI) { return new TeronGorefiendPullingBossTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* teron_gorefiend_boss_engaged_by_tanks(
|
||||||
|
PlayerbotAI* botAI) { return new TeronGorefiendBossEngagedByTanksTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* teron_gorefiend_boss_engaged_by_ranged(
|
||||||
|
PlayerbotAI* botAI) { return new TeronGorefiendBossEngagedByRangedTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* teron_gorefiend_boss_is_casting_shadow_of_death(
|
||||||
|
PlayerbotAI* botAI) { return new TeronGorefiendBossIsCastingShadowOfDeathTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* teron_gorefiend_bot_has_shadow_of_death(
|
||||||
|
PlayerbotAI* botAI) { return new TeronGorefiendBotHasShadowOfDeathTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* teron_gorefiend_bot_transformed_into_vengeful_spirit(
|
||||||
|
PlayerbotAI* botAI) { return new TeronGorefiendBotTransformedIntoVengefulSpiritTrigger(botAI); }
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
static Trigger* gurtogg_bloodboil_pulling_boss(
|
||||||
|
PlayerbotAI* botAI) { return new GurtoggBloodboilPullingBossTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* gurtogg_bloodboil_boss_engaged_by_tanks(
|
||||||
|
PlayerbotAI* botAI) { return new GurtoggBloodboilBossEngagedByTanksTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* gurtogg_bloodboil_boss_casts_bloodboil(
|
||||||
|
PlayerbotAI* botAI) { return new GurtoggBloodboilBossCastsBloodboilTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* gurtogg_bloodboil_bot_has_fel_rage(
|
||||||
|
PlayerbotAI* botAI) { return new GurtoggBloodboilBotHasFelRageTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* gurtogg_bloodboil_need_to_manage_phase_timer(
|
||||||
|
PlayerbotAI* botAI) { return new GurtoggBloodboilNeedToManagePhaseTimerTrigger(botAI); }
|
||||||
|
|
||||||
|
// Reliquary of Souls
|
||||||
|
static Trigger* reliquary_of_souls_aggro_resets_upon_phase_change(
|
||||||
|
PlayerbotAI* botAI) { return new ReliquaryOfSoulsAggroResetsUponPhaseChangeTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* reliquary_of_souls_essence_of_suffering_fixates_on_closest_target(
|
||||||
|
PlayerbotAI* botAI) { return new ReliquaryOfSoulsEssenceOfSufferingFixatesOnClosestTargetTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* reliquary_of_souls_essence_of_suffering_disables_healing(
|
||||||
|
PlayerbotAI* botAI) { return new ReliquaryOfSoulsEssenceOfSufferingDisablesHealingTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* reliquary_of_souls_essence_of_desire_has_rune_shield(
|
||||||
|
PlayerbotAI* botAI) { return new ReliquaryOfSoulsEssenceOfDesireHasRuneShieldTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* reliquary_of_souls_essence_of_desire_casting_deaden(
|
||||||
|
PlayerbotAI* botAI) { return new ReliquaryOfSoulsEssenceOfDesireCastingDeadenTrigger(botAI); }
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
static Trigger* mother_shahraz_pulling_boss(
|
||||||
|
PlayerbotAI* botAI) { return new MotherShahrazPullingBossTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* mother_shahraz_boss_engaged_by_tanks(
|
||||||
|
PlayerbotAI* botAI) { return new MotherShahrazBossEngagedByTanksTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* mother_shahraz_tanks_are_positioning_boss(
|
||||||
|
PlayerbotAI* botAI) { return new MotherShahrazTanksArePositioningBossTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* mother_shahraz_sinister_beam_knocks_back_players(
|
||||||
|
PlayerbotAI* botAI) { return new MotherShahrazSinisterBeamKnocksBackPlayersTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* mother_shahraz_bots_are_linked_by_fatal_attraction(
|
||||||
|
PlayerbotAI* botAI) { return new MotherShahrazBotsAreLinkedByFatalAttractionTrigger(botAI); }
|
||||||
|
|
||||||
|
// Illidari Council
|
||||||
|
static Trigger* illidari_council_pulling_bosses(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilPullingBossesTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidari_council_gathios_engaged_by_main_tank(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilGathiosEngagedByMainTankTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidari_council_gathios_casting_judgement_of_command(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilGathiosCastingJudgementOfCommandTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidari_council_malande_engaged_by_first_assist_tank(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilMalandeEngagedByFirstAssistTankTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidari_council_darkshadow_engaged_by_second_assist_tank(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilDarkshadowEngagedBySecondAssistTankTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidari_council_zerevor_engaged_by_mage_tank(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilZerevorEngagedByMageTankTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidari_council_mage_tank_needs_dedicated_healer(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilMageTankNeedsDedicatedHealerTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidari_council_zerevor_casts_dangerous_aoes(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilZerevorCastsDangerousAoesTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidari_council_pets_screw_up_the_pull(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilPetsScrewUpThePullTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidari_council_determining_dps_assignments(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilDeterminingDpsAssignmentsTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidari_council_need_to_manage_dps_timer(
|
||||||
|
PlayerbotAI* botAI) { return new IllidariCouncilNeedToManageDpsTimerTrigger(botAI); }
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
static Trigger* illidan_stormrage_tank_needs_aggro(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageTankNeedsAggroTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_boss_casts_flame_crash_in_front_of_main_tank(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageBossCastsFlameCrashInFrontOfMainTankTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_bot_has_parasitic_shadowfiend(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageBotHasParasiticShadowfiendTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_parasitic_shadowfiends_run_wild(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageParasiticShadowfiendsRunWildTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_boss_summoned_flames_of_azzinoth(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageBossSummonedFlamesOfAzzinothTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_pets_die_to_fire(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormragePetsDieToFireTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_grate_is_safe_from_flames(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageGrateIsSafeFromFlamesTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_bot_struck_by_dark_barrage(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageBotStruckByDarkBarrageTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_boss_is_preparing_to_land(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageBossIsPreparingToLandTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_boss_deals_splash_damage(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageBossDealsSplashDamageTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_this_expansion_hates_melee(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageThisExpansionHatesMeleeTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_boss_transforms_into_demon(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageBossTransformsIntoDemonTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_boss_spawns_adds(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageBossSpawnsAddsTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_maiev_placed_shadow_trap(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageMaievPlacedShadowTrapTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_need_to_manage_dps_timer_and_rti(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageNeedToManageDpsTimerAndRtiTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_need_to_clear_hazards_between_phases(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageNeedToClearHazardsBetweenPhasesTrigger(botAI); }
|
||||||
|
|
||||||
|
static Trigger* illidan_stormrage_cheat(
|
||||||
|
PlayerbotAI* botAI) { return new IllidanStormrageCheatTrigger(botAI); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
253
src/Ai/Raid/BlackTemple/Strategy/RaidBlackTempleStrategy.cpp
Normal file
253
src/Ai/Raid/BlackTemple/Strategy/RaidBlackTempleStrategy.cpp
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
/*
|
||||||
|
* 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 "RaidBlackTempleStrategy.h"
|
||||||
|
|
||||||
|
#include "RaidBlackTempleMultipliers.h"
|
||||||
|
|
||||||
|
void RaidBlackTempleStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
// General
|
||||||
|
triggers.push_back(new TriggerNode("black temple bot is not in combat", {
|
||||||
|
NextAction("black temple erase timers and trackers", ACTION_EMERGENCY + 11) }));
|
||||||
|
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
triggers.push_back(new TriggerNode("high warlord naj'entus pulling boss", {
|
||||||
|
NextAction("high warlord naj'entus misdirect boss to main tank", ACTION_RAID + 2) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("high warlord naj'entus boss engaged by tanks", {
|
||||||
|
NextAction("high warlord naj'entus tanks position boss", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("high warlord naj'entus casts needle spines", {
|
||||||
|
NextAction("high warlord naj'entus disperse ranged", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("high warlord naj'entus player is impaled", {
|
||||||
|
NextAction("high warlord naj'entus remove impaling spine", ACTION_EMERGENCY + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("high warlord naj'entus boss has tidal shield", {
|
||||||
|
NextAction("high warlord naj'entus throw impaling spine", ACTION_RAID + 2) }));
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
triggers.push_back(new TriggerNode("supremus pulling boss or changing phase", {
|
||||||
|
NextAction("supremus misdirect boss to main tank", ACTION_RAID + 2) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("supremus boss engaged by ranged", {
|
||||||
|
NextAction("supremus disperse ranged", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("supremus boss is fixated on bot", {
|
||||||
|
NextAction("supremus kite boss", ACTION_EMERGENCY + 7) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("supremus volcano is nearby", {
|
||||||
|
NextAction("supremus move away from volcanos", ACTION_EMERGENCY + 6) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("supremus need to manage phase timer", {
|
||||||
|
NextAction("supremus manage phase timer", ACTION_EMERGENCY + 10) }));
|
||||||
|
|
||||||
|
// Shade of Akama
|
||||||
|
triggers.push_back(new TriggerNode("shade of akama killing channelers starts phase 2", {
|
||||||
|
NextAction("shade of akama melee dps prioritize channelers", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
triggers.push_back(new TriggerNode("teron gorefiend pulling boss", {
|
||||||
|
NextAction("teron gorefiend misdirect boss to main tank", ACTION_RAID + 2) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("teron gorefiend boss engaged by tanks", {
|
||||||
|
NextAction("teron gorefiend tanks position boss", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("teron gorefiend boss engaged by ranged", {
|
||||||
|
NextAction("teron gorefiend position ranged on balcony", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("teron gorefiend boss is casting shadow of death", {
|
||||||
|
NextAction("teron gorefiend avoid shadow of death", ACTION_EMERGENCY + 10) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("teron gorefiend bot has shadow of death", {
|
||||||
|
NextAction("teron gorefiend move to corner to die", ACTION_EMERGENCY + 10) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("teron gorefiend bot transformed into vengeful spirit", {
|
||||||
|
NextAction("teron gorefiend control and destroy shadowy constructs", ACTION_EMERGENCY + 10) }));
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
triggers.push_back(new TriggerNode("gurtogg bloodboil pulling boss", {
|
||||||
|
NextAction("gurtogg bloodboil misdirect boss to main tank", ACTION_RAID + 2) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("gurtogg bloodboil boss engaged by tanks", {
|
||||||
|
NextAction("gurtogg bloodboil tanks position boss", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("gurtogg bloodboil boss casts bloodboil", {
|
||||||
|
NextAction("gurtogg bloodboil rotate ranged groups", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("gurtogg bloodboil bot has fel rage", {
|
||||||
|
NextAction("gurtogg bloodboil ranged move away from enraged player", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("gurtogg bloodboil need to manage phase timer", {
|
||||||
|
NextAction("gurtogg bloodboil manage phase timer", ACTION_EMERGENCY + 10) }));
|
||||||
|
|
||||||
|
// Reliquary of Souls
|
||||||
|
triggers.push_back(new TriggerNode("reliquary of souls aggro resets upon phase change", {
|
||||||
|
NextAction("reliquary of souls misdirect boss to main tank", ACTION_RAID + 3) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("reliquary of souls essence of suffering fixates on closest target", {
|
||||||
|
NextAction("reliquary of souls adjust distance from suffering", ACTION_RAID + 2) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("reliquary of souls essence of suffering disables healing", {
|
||||||
|
NextAction("reliquary of souls healers dps suffering", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("reliquary of souls essence of desire has rune shield", {
|
||||||
|
NextAction("reliquary of souls spellsteal rune shield", ACTION_EMERGENCY + 6) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("reliquary of souls essence of desire casting deaden", {
|
||||||
|
NextAction("reliquary of souls spell reflect deaden", ACTION_EMERGENCY + 6) }));
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
triggers.push_back(new TriggerNode("mother shahraz pulling boss", {
|
||||||
|
NextAction("mother shahraz misdirect boss to main tank", ACTION_RAID + 2) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("mother shahraz boss engaged by tanks", {
|
||||||
|
NextAction("mother shahraz tanks position boss under pillar", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("mother shahraz tanks are positioning boss", {
|
||||||
|
NextAction("mother shahraz melee dps wait at safe position", ACTION_EMERGENCY + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("mother shahraz sinister beam knocks back players", {
|
||||||
|
NextAction("mother shahraz position ranged under pillar", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("mother shahraz bots are linked by fatal attraction", {
|
||||||
|
NextAction("mother shahraz run away to break fatal attraction", ACTION_EMERGENCY + 10) }));
|
||||||
|
|
||||||
|
// Illidari Council
|
||||||
|
triggers.push_back(new TriggerNode("illidari council pulling bosses", {
|
||||||
|
NextAction("illidari council misdirect bosses to tanks", ACTION_RAID + 4) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidari council gathios engaged by main tank", {
|
||||||
|
NextAction("illidari council main tank position gathios", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidari council gathios casting judgement of command", {
|
||||||
|
NextAction("illidari council main tank reflect judgement of command", ACTION_EMERGENCY + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidari council malande engaged by first assist tank", {
|
||||||
|
NextAction("illidari council first assist tank focus malande", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidari council darkshadow engaged by second assist tank", {
|
||||||
|
NextAction("illidari council second assist tank position darkshadow", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidari council zerevor engaged by mage tank", {
|
||||||
|
NextAction("illidari council mage tank position zerevor", ACTION_EMERGENCY + 6) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidari council mage tank needs dedicated healer", {
|
||||||
|
NextAction("illidari council position mage tank healer", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidari council zerevor casts dangerous aoes", {
|
||||||
|
NextAction("illidari council disperse ranged", ACTION_RAID + 2) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidari council pets screw up the pull", {
|
||||||
|
NextAction("illidari council command pets to attack gathios", ACTION_RAID + 3) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidari council determining dps assignments", {
|
||||||
|
NextAction("illidari council assign dps targets", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidari council need to manage dps timer", {
|
||||||
|
NextAction("illidari council manage dps timer", ACTION_EMERGENCY + 10) }));
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage tank needs aggro", {
|
||||||
|
NextAction("illidan stormrage misdirect to tank", ACTION_RAID + 3) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage boss casts flame crash in front of main tank", {
|
||||||
|
NextAction("illidan stormrage main tank reposition boss", ACTION_EMERGENCY + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage bot has parasitic shadowfiend", {
|
||||||
|
NextAction("illidan stormrage isolate bot with parasite", ACTION_RAID + 3) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage parasitic shadowfiends run wild", {
|
||||||
|
NextAction("illidan stormrage set earthbind totem", ACTION_RAID + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage boss summoned flames of azzinoth", {
|
||||||
|
NextAction("illidan stormrage assist tanks handle flames of azzinoth", ACTION_EMERGENCY + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage pets die to fire", {
|
||||||
|
NextAction("illidan stormrage control pet aggression", ACTION_RAID + 4) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage grate is safe from flames", {
|
||||||
|
NextAction("illidan stormrage position above grate", ACTION_EMERGENCY + 2) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage bot struck by dark barrage", {
|
||||||
|
NextAction("illidan stormrage remove dark barrage", ACTION_EMERGENCY + 6) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage boss is preparing to land", {
|
||||||
|
NextAction("illidan stormrage move away from landing point", ACTION_EMERGENCY + 3) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage boss deals splash damage", {
|
||||||
|
NextAction("illidan stormrage disperse ranged", ACTION_RAID + 2) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage this expansion hates melee", {
|
||||||
|
NextAction("illidan stormrage melee go somewhere to not die", ACTION_RAID + 2) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage boss transforms into demon", {
|
||||||
|
NextAction("illidan stormrage warlock tank handle demon boss", ACTION_EMERGENCY + 9) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage boss spawns adds", {
|
||||||
|
NextAction("illidan stormrage dps prioritize adds", ACTION_EMERGENCY + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage maiev placed shadow trap", {
|
||||||
|
NextAction("illidan stormrage use shadow trap", ACTION_EMERGENCY + 1) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage need to manage dps timer and rti", {
|
||||||
|
NextAction("illidan stormrage manage dps timer and rti", ACTION_EMERGENCY + 11) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage need to clear hazards between phases", {
|
||||||
|
NextAction("illidan stormrage destroy hazards", ACTION_EMERGENCY + 10) }));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("illidan stormrage cheat", {
|
||||||
|
NextAction("illidan stormrage handle adds cheat", ACTION_EMERGENCY + 10) }));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaidBlackTempleStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
|
||||||
|
{
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
multipliers.push_back(new HighWarlordNajentusDelayDpsCooldownsMultiplier(botAI));
|
||||||
|
multipliers.push_back(new HighWarlordNajentusDisableCombatFormationMoveMultiplier(botAI));
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
multipliers.push_back(new SupremusDelayDpsCooldownsMultiplier(botAI));
|
||||||
|
multipliers.push_back(new SupremusFocusOnAvoidanceInPhase2Multiplier(botAI));
|
||||||
|
multipliers.push_back(new SupremusHitboxIsBuggedMultiplier(botAI));
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
multipliers.push_back(new TeronGorefiendDelayDpsCooldownsMultiplier(botAI));
|
||||||
|
multipliers.push_back(new TeronGorefiendControlMovementMultiplier(botAI));
|
||||||
|
multipliers.push_back(new TeronGorefiendMarkedBotOnlyMoveToDieMultiplier(botAI));
|
||||||
|
multipliers.push_back(new TeronGorefiendSpiritsAttackOnlyShadowyConstructsMultiplier(botAI));
|
||||||
|
multipliers.push_back(new TeronGorefiendDisableAttackingConstructsMultiplier(botAI));
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
multipliers.push_back(new GurtoggBloodboilDelayDpsCooldownsMultiplier(botAI));
|
||||||
|
multipliers.push_back(new GurtoggBloodboilControlMovementMultiplier(botAI));
|
||||||
|
|
||||||
|
// Reliquary of Souls
|
||||||
|
multipliers.push_back(new ReliquaryOfSoulsDelayDpsCooldownsMultiplier(botAI));
|
||||||
|
multipliers.push_back(new ReliquaryOfSoulsDontWasteHealingMultiplier(botAI));
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
multipliers.push_back(new MotherShahrazDelayDpsCooldownsMultiplier(botAI));
|
||||||
|
multipliers.push_back(new MotherShahrazControlMovementMultiplier(botAI));
|
||||||
|
multipliers.push_back(new MotherShahrazBotsWithFatalAttractionOnlyRunAwayMultiplier(botAI));
|
||||||
|
|
||||||
|
// Illidari Council
|
||||||
|
multipliers.push_back(new IllidariCouncilDelayDpsCooldownsMultiplier(botAI));
|
||||||
|
multipliers.push_back(new IllidariCouncilDisableTankActionsMultiplier(botAI));
|
||||||
|
multipliers.push_back(new IllidariCouncilControlMovementMultiplier(botAI));
|
||||||
|
multipliers.push_back(new IllidariCouncilControlMisdirectionMultiplier(botAI));
|
||||||
|
multipliers.push_back(new IllidariCouncilDisableArcaneShotOnZerevorMultiplier(botAI));
|
||||||
|
multipliers.push_back(new IllidariCouncilDisableIceBlockMultiplier(botAI));
|
||||||
|
multipliers.push_back(new IllidariCouncilWaitForDpsMultiplier(botAI));
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
multipliers.push_back(new IllidanStormrageDelayDpsCooldownsMultiplier(botAI));
|
||||||
|
multipliers.push_back(new IllidanStormrageControlTankActionsMultiplier(botAI));
|
||||||
|
multipliers.push_back(new IllidanStormrageDisableDefaultTargetingMultiplier(botAI));
|
||||||
|
multipliers.push_back(new IllidanStormrageControlNonTankMovementMultiplier(botAI));
|
||||||
|
multipliers.push_back(new IllidanStormrageUseEarthbindTotemMultiplier(botAI));
|
||||||
|
multipliers.push_back(new IllidanStormrageWaitForDpsMultiplier(botAI));
|
||||||
|
}
|
||||||
22
src/Ai/Raid/BlackTemple/Strategy/RaidBlackTempleStrategy.h
Normal file
22
src/Ai/Raid/BlackTemple/Strategy/RaidBlackTempleStrategy.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* 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_RAIDBLACKTEMPLESTRATEGY_H_
|
||||||
|
#define _PLAYERBOT_RAIDBLACKTEMPLESTRATEGY_H_
|
||||||
|
|
||||||
|
#include "Strategy.h"
|
||||||
|
|
||||||
|
class RaidBlackTempleStrategy : public Strategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RaidBlackTempleStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||||
|
|
||||||
|
std::string const getName() override { return "blacktemple"; }
|
||||||
|
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
void InitMultipliers(std::vector<Multiplier*>& multipliers) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
863
src/Ai/Raid/BlackTemple/Trigger/RaidBlackTempleTriggers.cpp
Normal file
863
src/Ai/Raid/BlackTemple/Trigger/RaidBlackTempleTriggers.cpp
Normal file
@ -0,0 +1,863 @@
|
|||||||
|
/*
|
||||||
|
* 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 "RaidBlackTempleTriggers.h"
|
||||||
|
|
||||||
|
#include "AiFactory.h"
|
||||||
|
#include "Playerbots.h"
|
||||||
|
#include "RaidBlackTempleActions.h"
|
||||||
|
#include "RaidBlackTempleHelpers.h"
|
||||||
|
#include "RaidBossHelpers.h"
|
||||||
|
#include "SharedDefines.h"
|
||||||
|
|
||||||
|
using namespace BlackTempleHelpers;
|
||||||
|
|
||||||
|
// General
|
||||||
|
|
||||||
|
bool BlackTempleBotIsNotInCombatTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return !bot->IsInCombat() && bot->GetMapId() == BLACK_TEMPLE_MAP_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
|
||||||
|
bool HighWarlordNajentusPullingBossTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_HUNTER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* najentus = AI_VALUE2(Unit*, "find target", "high warlord naj'entus");
|
||||||
|
return najentus && najentus->GetHealthPct() > 95.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HighWarlordNajentusBossEngagedByTanksTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return botAI->IsTank(bot) &&
|
||||||
|
AI_VALUE2(Unit*, "find target", "high warlord naj'entus");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HighWarlordNajentusCastsNeedleSpinesTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return botAI->IsRanged(bot) &&
|
||||||
|
AI_VALUE2(Unit*, "find target", "high warlord naj'entus");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HighWarlordNajentusPlayerIsImpaledTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (botAI->IsTank(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "high warlord naj'entus"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Player* impaledPlayer = nullptr;
|
||||||
|
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
|
{
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (!member || member == bot)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (member->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_IMPALING_SPINE)))
|
||||||
|
{
|
||||||
|
impaledPlayer = member;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Player* closestBot = nullptr;
|
||||||
|
float closestDist = std::numeric_limits<float>::max();
|
||||||
|
|
||||||
|
if (impaledPlayer)
|
||||||
|
{
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
|
{
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (!member || !member->IsAlive() || member == impaledPlayer ||
|
||||||
|
!GET_PLAYERBOT_AI(member) || botAI->IsTank(member))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dist = member->GetDistance(impaledPlayer);
|
||||||
|
if (dist < closestDist)
|
||||||
|
{
|
||||||
|
closestDist = dist;
|
||||||
|
closestBot = member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return closestBot == bot;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HighWarlordNajentusBossHasTidalShieldTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* najentus = AI_VALUE2(Unit*, "find target", "high warlord naj'entus");
|
||||||
|
if (!najentus || !najentus->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_TIDAL_SHIELD)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return botAI->HasItemInInventory(
|
||||||
|
static_cast<uint32>(BlackTempleItems::ITEM_NAJENTUS_SPINE));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
|
||||||
|
bool SupremusPullingBossOrChangingPhaseTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_HUNTER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* supremus = AI_VALUE2(Unit*, "find target", "supremus");
|
||||||
|
if (!supremus)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto it = supremusPhaseTimer.find(supremus->GetMap()->GetInstanceId());
|
||||||
|
if (it == supremusPhaseTimer.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const time_t now = time(nullptr);
|
||||||
|
const time_t elapsed = now - it->second;
|
||||||
|
|
||||||
|
// Active during first 10 seconds, or during 60-70, 120-130, etc.
|
||||||
|
return (elapsed < 10) || ((elapsed % 60) < 10 && elapsed >= 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SupremusBossEngagedByRangedTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsRanged(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* supremus = AI_VALUE2(Unit*, "find target", "supremus");
|
||||||
|
return supremus && !supremus->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_SNARE_SELF));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SupremusBossIsFixatedOnBotTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* supremus = AI_VALUE2(Unit*, "find target", "supremus");
|
||||||
|
return supremus && supremus->GetVictim() == bot &&
|
||||||
|
supremus->HasAura(static_cast<uint32>(
|
||||||
|
BlackTempleSpells::SPELL_SNARE_SELF));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SupremusVolcanoIsNearbyTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return AI_VALUE2(Unit*, "find target", "supremus") &&
|
||||||
|
HasSupremusVolcanoNearby(botAI, bot);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SupremusNeedToManagePhaseTimerTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsDps(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "supremus"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return IsMechanicTrackerBot(botAI, bot, BLACK_TEMPLE_MAP_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shade of Akama
|
||||||
|
|
||||||
|
bool ShadeOfAkamaKillingChannelersStartsPhase2Trigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsDps(bot) || !botAI->IsMelee(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
constexpr float searchRadius = 30.0f;
|
||||||
|
Unit* channeler = bot->FindNearestCreature(
|
||||||
|
static_cast<uint32>(BlackTempleNpcs::NPC_ASHTONGUE_CHANNELER),
|
||||||
|
searchRadius, true);
|
||||||
|
|
||||||
|
return channeler && !channeler->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
|
||||||
|
bool TeronGorefiendPullingBossTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_HUNTER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* gorefiend =
|
||||||
|
AI_VALUE2(Unit*, "find target", "teron gorefiend");
|
||||||
|
|
||||||
|
return gorefiend && gorefiend->GetHealthPct() > 95.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TeronGorefiendBossEngagedByTanksTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return botAI->IsTank(bot) &&
|
||||||
|
AI_VALUE2(Unit*, "find target", "teron gorefiend");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TeronGorefiendBossEngagedByRangedTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return botAI->IsRanged(bot) &&
|
||||||
|
AI_VALUE2(Unit*, "find target", "teron gorefiend");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TeronGorefiendBossIsCastingShadowOfDeathTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_HUNTER && bot->getClass() != CLASS_MAGE &&
|
||||||
|
bot->getClass() != CLASS_PALADIN && bot->getClass() != CLASS_ROGUE)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* gorefiend = AI_VALUE2(Unit*, "find target", "teron gorefiend");
|
||||||
|
if (!gorefiend)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (botAI->HasAura("feign death", bot))
|
||||||
|
{
|
||||||
|
botAI->RemoveAura("feign death");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (botAI->HasAura("ice block", bot))
|
||||||
|
{
|
||||||
|
botAI->RemoveAura("ice block");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (!botAI->IsHeal(bot) && botAI->HasAura("divine shield", bot))
|
||||||
|
{
|
||||||
|
botAI->RemoveAura("divine shield");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gorefiend->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Spell* spell = gorefiend->GetCurrentSpell(CURRENT_GENERIC_SPELL);
|
||||||
|
if (!spell || spell->m_spellInfo->Id !=
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_SHADOW_OF_DEATH))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* target = spell->m_targets.GetUnitTarget();
|
||||||
|
return target && target->GetGUID() == bot->GetGUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TeronGorefiendBotHasShadowOfDeathTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Aura* aura = bot->GetAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_SHADOW_OF_DEATH));
|
||||||
|
return aura && aura->GetDuration() < 12000;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TeronGorefiendBotTransformedIntoVengefulSpiritTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return bot->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_SPIRITUAL_VENGEANCE));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
|
||||||
|
bool GurtoggBloodboilPullingBossTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_HUNTER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* gurtogg = AI_VALUE2(Unit*, "find target", "gurtogg bloodboil");
|
||||||
|
if (!gurtogg)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto it = gurtoggPhaseTimer.find(gurtogg->GetMap()->GetInstanceId());
|
||||||
|
if (it == gurtoggPhaseTimer.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const time_t elapsed = std::time(nullptr) - it->second;
|
||||||
|
return elapsed < 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GurtoggBloodboilBossEngagedByTanksTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsTank(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* gurtogg = AI_VALUE2(Unit*, "find target", "gurtogg bloodboil");
|
||||||
|
return gurtogg && !gurtogg->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_BOSS_FEL_RAGE));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GurtoggBloodboilBossCastsBloodboilTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsRanged(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* gurtogg = AI_VALUE2(Unit*, "find target", "gurtogg bloodboil");
|
||||||
|
return gurtogg && !gurtogg->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_BOSS_FEL_RAGE));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GurtoggBloodboilBotHasFelRageTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsRanged(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* gurtogg = AI_VALUE2(Unit*, "find target", "gurtogg bloodboil");
|
||||||
|
if (!gurtogg || !gurtogg->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_BOSS_FEL_RAGE)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Group* group = bot->GetGroup())
|
||||||
|
{
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
|
{
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (member && member->HasAura
|
||||||
|
(static_cast<uint32>(BlackTempleSpells::SPELL_PLAYER_FEL_RAGE)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GurtoggBloodboilNeedToManagePhaseTimerTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return AI_VALUE2(Unit*, "find target", "gurtogg bloodboil") &&
|
||||||
|
IsMechanicTrackerBot(botAI, bot, BLACK_TEMPLE_MAP_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reliquary of Souls
|
||||||
|
|
||||||
|
bool ReliquaryOfSoulsAggroResetsUponPhaseChangeTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return bot->getClass() == CLASS_HUNTER &&
|
||||||
|
AI_VALUE2(Unit*, "find target", "reliquary of the lost");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReliquaryOfSoulsEssenceOfSufferingFixatesOnClosestTargetTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return AI_VALUE2(Unit*, "find target", "essence of suffering");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReliquaryOfSoulsEssenceOfSufferingDisablesHealingTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsHeal(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (bot->getClass() == CLASS_PRIEST &&
|
||||||
|
AiFactory::GetPlayerSpecTab(bot) == PRIEST_TAB_DISCIPLINE)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AI_VALUE2(Unit*, "find target", "essence of suffering");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReliquaryOfSoulsEssenceOfDesireHasRuneShieldTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_MAGE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* desire = AI_VALUE2(Unit*, "find target", "essence of desire");
|
||||||
|
return desire && desire->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_RUNE_SHIELD));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReliquaryOfSoulsEssenceOfDesireCastingDeadenTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsTank(bot) || bot->getClass() != CLASS_WARRIOR)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* desire = AI_VALUE2(Unit*, "find target", "essence of desire");
|
||||||
|
if (!desire || !desire->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Spell* spell = desire->GetCurrentSpell(CURRENT_GENERIC_SPELL);
|
||||||
|
if (!spell || spell->m_spellInfo->Id !=
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_DEADEN))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* target = spell->m_targets.GetUnitTarget();
|
||||||
|
return target && target->GetGUID() == bot->GetGUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
|
||||||
|
bool MotherShahrazPullingBossTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_HUNTER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* shahraz = AI_VALUE2(Unit*, "find target", "mother shahraz");
|
||||||
|
return shahraz && shahraz->GetHealthPct() > 95.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MotherShahrazBossEngagedByTanksTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsTank(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "mother shahraz"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !bot->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_FATAL_ATTRACTION));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MotherShahrazTanksArePositioningBossTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsMelee(bot) || !botAI->IsDps(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* shahraz = AI_VALUE2(Unit*, "find target", "mother shahraz");
|
||||||
|
if (!shahraz || shahraz->GetHealthPct() < 90.0f)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
TankPositionState tankState = GetShahrazTankPositionState(botAI, bot);
|
||||||
|
return tankState != TankPositionState::Positioned;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MotherShahrazSinisterBeamKnocksBackPlayersTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsRanged(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "mother shahraz"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !bot->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_FATAL_ATTRACTION));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MotherShahrazBotsAreLinkedByFatalAttractionTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return bot->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_FATAL_ATTRACTION));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Illidari Council
|
||||||
|
|
||||||
|
bool IllidariCouncilPullingBossesTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_HUNTER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* gathios = AI_VALUE2(Unit*, "find target", "gathios the shatterer");
|
||||||
|
return gathios && gathios->GetHealthPct() > 95.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidariCouncilGathiosEngagedByMainTankTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return botAI->IsMainTank(bot) &&
|
||||||
|
AI_VALUE2(Unit*, "find target", "gathios the shatterer");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidariCouncilGathiosCastingJudgementOfCommandTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_WARRIOR || !botAI->IsMainTank(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* gathios = AI_VALUE2(Unit*, "find target", "gathios the shatterer");
|
||||||
|
if (!gathios || !gathios->HasUnitState(UNIT_STATE_CASTING) || !gathios->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_SEAL_OF_COMMAND)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Spell* spell = gathios->GetCurrentSpell(CURRENT_GENERIC_SPELL);
|
||||||
|
if (!spell || spell->m_spellInfo->Id !=
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_JUDGEMENT))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* target = spell->m_targets.GetUnitTarget();
|
||||||
|
return target && target->GetGUID() == bot->GetGUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidariCouncilMalandeEngagedByFirstAssistTankTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return botAI->IsAssistTankOfIndex(bot, 0, false) &&
|
||||||
|
AI_VALUE2(Unit*, "find target", "lady malande");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidariCouncilDarkshadowEngagedBySecondAssistTankTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsAssistTankOfIndex(bot, 1, false))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* darkshadow = AI_VALUE2(Unit*, "find target", "veras darkshadow");
|
||||||
|
return darkshadow && !darkshadow->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_VANISH));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidariCouncilZerevorEngagedByMageTankTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_MAGE || GetZerevorMageTank(bot) != bot)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return AI_VALUE2(Unit*, "find target", "high nethermancer zerevor");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidariCouncilMageTankNeedsDedicatedHealerTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return botAI->IsAssistHealOfIndex(bot, 0, true) &&
|
||||||
|
AI_VALUE2(Unit*, "find target", "high nethermancer zerevor");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidariCouncilZerevorCastsDangerousAoesTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsRanged(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "high nethermancer zerevor"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !HasDangerousCouncilAura(bot);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidariCouncilPetsScrewUpThePullTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_HUNTER && bot->getClass() != CLASS_WARLOCK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Pet* pet = bot->GetPet();
|
||||||
|
if (!pet || !pet->IsAlive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return AI_VALUE2(Unit*, "find target", "gathios the shatterer");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidariCouncilDeterminingDpsAssignmentsTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (botAI->IsHeal(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "gathios the shatterer"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (botAI->IsMainTank(bot) || botAI->IsAssistTankOfIndex(bot, 0, false) ||
|
||||||
|
GetZerevorMageTank(bot) == bot)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* darkshadow = AI_VALUE2(Unit*, "find target", "veras darkshadow");
|
||||||
|
if (botAI->IsTank(bot) && botAI->IsAssistTankOfIndex(bot, 1, false) &&
|
||||||
|
darkshadow && !darkshadow->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_VANISH)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidariCouncilNeedToManageDpsTimerTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsDps(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "gathios the shatterer"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return IsMechanicTrackerBot(
|
||||||
|
botAI, bot, BLACK_TEMPLE_MAP_ID, GetZerevorMageTank(bot));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
|
||||||
|
bool IllidanStormrageTankNeedsAggroTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_HUNTER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
return illidan && illidan->GetHealth() > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageBossCastsFlameCrashInFrontOfMainTankTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsMainTank(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int phase = GetIllidanPhase(illidan);
|
||||||
|
return phase == 1 || phase == 3 || phase == 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageBotHasParasiticShadowfiendTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan || illidan->GetHealth() == 1 ||
|
||||||
|
illidan->GetVictim() == bot)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int phase = GetIllidanPhase(illidan);
|
||||||
|
if (phase == 2 || phase == 4)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (botAI->IsMainTank(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (phase == 5 && FindNearestTrap(botAI, bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Player* infected = GetBotWithParasiticShadowfiend(bot);
|
||||||
|
if (!infected)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (infected == bot ||
|
||||||
|
(phase != 1 && bot->getClass() == CLASS_HUNTER))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageParasiticShadowfiendsRunWildTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_SHAMAN)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan || illidan->GetHealth() == 1 || GetIllidanPhase(illidan) == 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ObjectGuid guid = bot->m_SummonSlot[SUMMON_SLOT_TOTEM_EARTH];
|
||||||
|
if (guid.IsEmpty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
Creature* totem = bot->GetMap()->GetCreature(guid);
|
||||||
|
return !totem || totem->GetDistance(bot) > 20.0f ||
|
||||||
|
totem->GetUInt32Value(UNIT_CREATED_BY_SPELL) !=
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_EARTHBIND_TOTEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageBossSummonedFlamesOfAzzinothTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsAssistTankOfIndex(bot, 0, true) &&
|
||||||
|
!botAI->IsAssistTankOfIndex(bot, 1, true))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
return illidan && GetIllidanPhase(illidan) == 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormragePetsDieToFireTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan || illidan->GetHealth() == 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Pet* pet = bot->GetPet();
|
||||||
|
return pet && pet->IsAlive();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageGrateIsSafeFromFlamesTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (botAI->IsAssistTankOfIndex(bot, 0, true) ||
|
||||||
|
botAI->IsAssistTankOfIndex(bot, 1, true))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
return illidan && GetIllidanPhase(illidan) == 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageBotStruckByDarkBarrageTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_MAGE && bot->getClass() != CLASS_PALADIN &&
|
||||||
|
bot->getClass() != CLASS_ROGUE)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AI_VALUE2(Unit*, "find target", "illidan stormrage"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (botAI->HasAura("ice block", bot))
|
||||||
|
{
|
||||||
|
botAI->RemoveAura("ice block");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (!botAI->IsHeal(bot) && botAI->HasAura("divine shield", bot))
|
||||||
|
{
|
||||||
|
botAI->RemoveAura("divine shield");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bot->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_DARK_BARRAGE));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageBossIsPreparingToLandTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (botAI->IsMainTank(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
return illidan && GetIllidanPhase(illidan) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageBossDealsSplashDamageTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsRanged(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan || illidan->HasAura
|
||||||
|
(static_cast<uint32>(BlackTempleSpells::SPELL_CAGED)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int phase = GetIllidanPhase(illidan);
|
||||||
|
|
||||||
|
if (phase == 4 && GetIllidanWarlockTank(bot) == bot)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return phase == 3 || phase == 4 || phase == 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageThisExpansionHatesMeleeTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsMelee(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
return illidan && GetIllidanPhase(illidan) == 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageBossTransformsIntoDemonTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (bot->getClass() != CLASS_WARLOCK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan || GetIllidanPhase(illidan) != 4)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return GetIllidanWarlockTank(bot) == bot;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageBossSpawnsAddsTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (botAI->IsHeal(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan || illidan->GetHealth() == 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (botAI->IsTank(bot) && GetIllidanPhase(illidan) != 4)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageMaievPlacedShadowTrapTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan || illidan->GetHealth() == 1 ||
|
||||||
|
GetIllidanPhase(illidan) != 5)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject* trap = FindNearestTrap(botAI, bot);
|
||||||
|
if (!trap)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Player* closestBot = nullptr;
|
||||||
|
float closestDist = std::numeric_limits<float>::max();
|
||||||
|
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
|
{
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (!member || !member->IsAlive() || illidan->GetVictim() == member ||
|
||||||
|
!GET_PLAYERBOT_AI(member) || botAI->IsMainTank(member))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dist = member->GetDistance(trap);
|
||||||
|
if (dist < closestDist)
|
||||||
|
{
|
||||||
|
closestDist = dist;
|
||||||
|
closestBot = member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return closestBot == bot;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageNeedToManageDpsTimerAndRtiTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsDps(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan || illidan->GetHealth() == 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return IsMechanicTrackerBot(
|
||||||
|
botAI, bot, BLACK_TEMPLE_MAP_ID, GetIllidanWarlockTank(bot));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroying hazards behind phases is not gated behind CheatMask
|
||||||
|
// The strategy simply cannot work without doing this
|
||||||
|
bool IllidanStormrageNeedToClearHazardsBetweenPhasesTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsDps(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan || illidan->GetHealth() == 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int phase = GetIllidanPhase(illidan);
|
||||||
|
if (phase != 0 && phase != 2 && phase != 4)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return IsMechanicTrackerBot(
|
||||||
|
botAI, bot, BLACK_TEMPLE_MAP_ID, GetIllidanWarlockTank(bot));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IllidanStormrageCheatTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->HasCheat(BotCheatMask::raid) || !botAI->IsDps(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* illidan = AI_VALUE2(Unit*, "find target", "illidan stormrage");
|
||||||
|
if (!illidan)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int phase = GetIllidanPhase(illidan);
|
||||||
|
return phase == 2 || phase == 4;
|
||||||
|
}
|
||||||
518
src/Ai/Raid/BlackTemple/Trigger/RaidBlackTempleTriggers.h
Normal file
518
src/Ai/Raid/BlackTemple/Trigger/RaidBlackTempleTriggers.h
Normal file
@ -0,0 +1,518 @@
|
|||||||
|
/*
|
||||||
|
* 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_RAIDBLACKTEMPLETRIGGERS_H
|
||||||
|
#define _PLAYERBOT_RAIDBLACKTEMPLETRIGGERS_H
|
||||||
|
|
||||||
|
#include "Trigger.h"
|
||||||
|
|
||||||
|
// General
|
||||||
|
|
||||||
|
class BlackTempleBotIsNotInCombatTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BlackTempleBotIsNotInCombatTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "black temple bot is not in combat") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
|
||||||
|
class HighWarlordNajentusPullingBossTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HighWarlordNajentusPullingBossTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "high warlord naj'entus pulling boss") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HighWarlordNajentusBossEngagedByTanksTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HighWarlordNajentusBossEngagedByTanksTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "high warlord naj'entus boss engaged by tanks") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HighWarlordNajentusCastsNeedleSpinesTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HighWarlordNajentusCastsNeedleSpinesTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "high warlord naj'entus casts needle spines") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HighWarlordNajentusPlayerIsImpaledTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HighWarlordNajentusPlayerIsImpaledTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "high warlord naj'entus player is impaled") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HighWarlordNajentusBossHasTidalShieldTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HighWarlordNajentusBossHasTidalShieldTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "high warlord naj'entus boss has tidal shield") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
|
||||||
|
class SupremusPullingBossOrChangingPhaseTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SupremusPullingBossOrChangingPhaseTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "supremus pulling boss or changing phase") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SupremusBossEngagedByRangedTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SupremusBossEngagedByRangedTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "supremus boss engaged by ranged") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SupremusBossIsFixatedOnBotTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SupremusBossIsFixatedOnBotTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "supremus boss is fixated on bot") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SupremusVolcanoIsNearbyTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SupremusVolcanoIsNearbyTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "supremus volcano is nearby") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SupremusNeedToManagePhaseTimerTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SupremusNeedToManagePhaseTimerTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "supremus need to manage phase timer") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Shade of Akama
|
||||||
|
|
||||||
|
class ShadeOfAkamaKillingChannelersStartsPhase2Trigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ShadeOfAkamaKillingChannelersStartsPhase2Trigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "shade of akama killing channelers starts phase 2") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
class TeronGorefiendPullingBossTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendPullingBossTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "teron gorefiend pulling boss") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendBossEngagedByTanksTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendBossEngagedByTanksTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "teron gorefiend boss engaged by tanks") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendBossEngagedByRangedTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendBossEngagedByRangedTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "teron gorefiend boss engaged by ranged") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendBossIsCastingShadowOfDeathTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendBossIsCastingShadowOfDeathTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "teron gorefiend boss is casting shadow of death") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendBotHasShadowOfDeathTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendBotHasShadowOfDeathTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "teron gorefiend bot has shadow of death") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TeronGorefiendBotTransformedIntoVengefulSpiritTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TeronGorefiendBotTransformedIntoVengefulSpiritTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "teron gorefiend bot transformed into vengeful spirit") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
|
||||||
|
class GurtoggBloodboilPullingBossTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GurtoggBloodboilPullingBossTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "gurtogg bloodboil pulling boss") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GurtoggBloodboilBossEngagedByTanksTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GurtoggBloodboilBossEngagedByTanksTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "gurtogg bloodboil boss engaged by tanks") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GurtoggBloodboilBossCastsBloodboilTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GurtoggBloodboilBossCastsBloodboilTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "gurtogg bloodboil boss casts bloodboil") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GurtoggBloodboilBotHasFelRageTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GurtoggBloodboilBotHasFelRageTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "gurtogg bloodboil bot has fel rage") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GurtoggBloodboilNeedToManagePhaseTimerTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GurtoggBloodboilNeedToManagePhaseTimerTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "gurtogg bloodboil need to manage phase timer") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reliquary of Souls
|
||||||
|
|
||||||
|
class ReliquaryOfSoulsAggroResetsUponPhaseChangeTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReliquaryOfSoulsAggroResetsUponPhaseChangeTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "reliquary of souls aggro resets upon phase change") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReliquaryOfSoulsEssenceOfSufferingFixatesOnClosestTargetTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReliquaryOfSoulsEssenceOfSufferingFixatesOnClosestTargetTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "reliquary of souls essence of suffering fixates on closest target") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReliquaryOfSoulsEssenceOfSufferingDisablesHealingTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReliquaryOfSoulsEssenceOfSufferingDisablesHealingTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "reliquary of souls essence of suffering disables healing") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReliquaryOfSoulsEssenceOfDesireHasRuneShieldTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReliquaryOfSoulsEssenceOfDesireHasRuneShieldTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "reliquary of souls essence of desire has rune shield") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReliquaryOfSoulsEssenceOfDesireCastingDeadenTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReliquaryOfSoulsEssenceOfDesireCastingDeadenTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "reliquary of souls essence of desire casting deaden") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
|
||||||
|
class MotherShahrazPullingBossTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotherShahrazPullingBossTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "mother shahraz pulling boss") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MotherShahrazBossEngagedByTanksTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotherShahrazBossEngagedByTanksTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "mother shahraz boss engaged by tanks") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MotherShahrazTanksArePositioningBossTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotherShahrazTanksArePositioningBossTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "mother shahraz tanks are positioning boss") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MotherShahrazSinisterBeamKnocksBackPlayersTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotherShahrazSinisterBeamKnocksBackPlayersTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "mother shahraz sinister beam knocks back players") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MotherShahrazBotsAreLinkedByFatalAttractionTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotherShahrazBotsAreLinkedByFatalAttractionTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "mother shahraz bots are linked by fatal attraction") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Illidari Council
|
||||||
|
|
||||||
|
class IllidariCouncilPullingBossesTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilPullingBossesTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidari council pulling bosses") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilGathiosEngagedByMainTankTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilGathiosEngagedByMainTankTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidari council gathios engaged by main tank") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilGathiosCastingJudgementOfCommandTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilGathiosCastingJudgementOfCommandTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidari council gathios casting judgement of command") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilMalandeEngagedByFirstAssistTankTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilMalandeEngagedByFirstAssistTankTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidari council malande engaged by first assist tank") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilDarkshadowEngagedBySecondAssistTankTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilDarkshadowEngagedBySecondAssistTankTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidari council darkshadow engaged by second assist tank") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilZerevorEngagedByMageTankTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilZerevorEngagedByMageTankTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidari council zerevor engaged by mage tank") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilMageTankNeedsDedicatedHealerTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilMageTankNeedsDedicatedHealerTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidari council mage tank needs dedicated healer") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilZerevorCastsDangerousAoesTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilZerevorCastsDangerousAoesTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidari council zerevor casts dangerous aoes") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilPetsScrewUpThePullTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilPetsScrewUpThePullTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidari council pets screw up the pull") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilNeedToManageDpsTimerTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilNeedToManageDpsTimerTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidari council need to manage dps timer") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidariCouncilDeterminingDpsAssignmentsTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidariCouncilDeterminingDpsAssignmentsTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidari council determining dps assignments") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
|
||||||
|
class IllidanStormrageTankNeedsAggroTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageTankNeedsAggroTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage tank needs aggro") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageBossCastsFlameCrashInFrontOfMainTankTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageBossCastsFlameCrashInFrontOfMainTankTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage boss casts flame crash in front of main tank") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageBotHasParasiticShadowfiendTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageBotHasParasiticShadowfiendTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage bot has parasitic shadowfiend") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageParasiticShadowfiendsRunWildTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageParasiticShadowfiendsRunWildTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage parasitic shadowfiends run wild") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageBossSummonedFlamesOfAzzinothTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageBossSummonedFlamesOfAzzinothTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage boss summoned flames of azzinoth") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormragePetsDieToFireTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormragePetsDieToFireTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage pets die to fire") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageGrateIsSafeFromFlamesTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageGrateIsSafeFromFlamesTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage grate is safe from flames") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageBotStruckByDarkBarrageTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageBotStruckByDarkBarrageTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage bot struck by dark barrage") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageBossIsPreparingToLandTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageBossIsPreparingToLandTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage boss is preparing to land") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageBossDealsSplashDamageTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageBossDealsSplashDamageTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage boss deals splash damage") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageThisExpansionHatesMeleeTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageThisExpansionHatesMeleeTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage this expansion hates melee") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageBossTransformsIntoDemonTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageBossTransformsIntoDemonTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage boss transforms into demon") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageBossSpawnsAddsTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageBossSpawnsAddsTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage boss spawns adds") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageMaievPlacedShadowTrapTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageMaievPlacedShadowTrapTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage maiev placed shadow trap") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageNeedToManageDpsTimerAndRtiTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageNeedToManageDpsTimerAndRtiTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage need to manage dps timer and rti") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageNeedToClearHazardsBetweenPhasesTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageNeedToClearHazardsBetweenPhasesTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage need to clear hazards between phases") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IllidanStormrageCheatTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IllidanStormrageCheatTrigger(
|
||||||
|
PlayerbotAI* botAI) : Trigger(botAI, "illidan stormrage cheat") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
468
src/Ai/Raid/BlackTemple/Util/RaidBlackTempleHelpers.cpp
Normal file
468
src/Ai/Raid/BlackTemple/Util/RaidBlackTempleHelpers.cpp
Normal file
@ -0,0 +1,468 @@
|
|||||||
|
/*
|
||||||
|
* 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 "RaidBlackTempleHelpers.h"
|
||||||
|
|
||||||
|
#include "Playerbots.h"
|
||||||
|
#include "RaidBossHelpers.h"
|
||||||
|
|
||||||
|
namespace BlackTempleHelpers
|
||||||
|
{
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
const Position NAJENTUS_TANK_POSITION = { 438.515f, 772.436f, 11.931f };
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
std::unordered_map<uint32, time_t> supremusPhaseTimer;
|
||||||
|
|
||||||
|
bool HasSupremusVolcanoNearby(PlayerbotAI* botAI, Player* bot)
|
||||||
|
{
|
||||||
|
constexpr float searchRadius = 20.0f;
|
||||||
|
std::list<Creature*> creatureList;
|
||||||
|
bot->GetCreatureListWithEntryInGrid(
|
||||||
|
creatureList, static_cast<uint32>(
|
||||||
|
BlackTempleNpcs::NPC_SUPREMUS_VOLCANO), searchRadius);
|
||||||
|
|
||||||
|
for (Creature* creature : creatureList)
|
||||||
|
{
|
||||||
|
if (creature && creature->IsAlive())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shade of Akama
|
||||||
|
const Position AKAMA_CHANNELER_POSITION = { 467.851f, 401.622f, 118.538f };
|
||||||
|
|
||||||
|
std::unordered_set<ObjectGuid> hasReachedAkamaChannelerPosition;
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
const Position GOREFIEND_TANK_POSITION = { 597.653f, 402.284f, 187.090f };
|
||||||
|
const Position GOREFIEND_DIE_POSITION = { 525.709f, 377.177f, 193.203f };
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
const Position GURTOGG_TANK_POSITION = { 735.987f, 272.451f, 063.554f };
|
||||||
|
const Position GURTOGG_RANGED_POSITION = { 762.265f, 277.183f, 063.781f };
|
||||||
|
const Position GURTOGG_SOAKER_POSITION = { 769.348f, 280.116f, 063.780f };
|
||||||
|
|
||||||
|
std::unordered_map<uint32, time_t> gurtoggPhaseTimer;
|
||||||
|
|
||||||
|
std::vector<std::vector<Player*>> GetGurtoggRangedRotationGroups(Player* bot)
|
||||||
|
{
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
std::vector<Player*> rangedMembers;
|
||||||
|
std::vector<std::vector<Player*>> groups(3);
|
||||||
|
|
||||||
|
if (!group)
|
||||||
|
return groups;
|
||||||
|
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
|
{
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (member && member->IsAlive())
|
||||||
|
{
|
||||||
|
PlayerbotAI* memberAI = GET_PLAYERBOT_AI(member);
|
||||||
|
if (memberAI && memberAI->IsRanged(member))
|
||||||
|
rangedMembers.push_back(member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < rangedMembers.size(); ++i)
|
||||||
|
{
|
||||||
|
groups[i / 5].push_back(rangedMembers[i]);
|
||||||
|
if (groups[2].size() == 5)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetGurtoggActiveRotationGroup(Unit* gurtogg)
|
||||||
|
{
|
||||||
|
if (!gurtogg)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
auto it = gurtoggPhaseTimer.find(gurtogg->GetMap()->GetInstanceId());
|
||||||
|
if (it == gurtoggPhaseTimer.end())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const time_t now = std::time(nullptr);
|
||||||
|
const time_t elapsed = now - it->second;
|
||||||
|
const int groupIndex = (elapsed % 30) / 10; // 3 groups, swapping every 10 seconds
|
||||||
|
|
||||||
|
return groupIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
const Position SHAHRAZ_TANK_POSITION = { 960.438f, 178.989f, 192.826f };
|
||||||
|
const Position SHAHRAZ_TRANSITION_POSITION = { 951.327f, 179.550f, 192.550f };
|
||||||
|
const Position SHAHRAZ_RANGED_POSITION = { 935.267f, 175.459f, 192.821f };
|
||||||
|
std::unordered_map<ObjectGuid, TankPositionState> shahrazTankStep;
|
||||||
|
|
||||||
|
TankPositionState GetShahrazTankPositionState(PlayerbotAI* botAI, Player* bot)
|
||||||
|
{
|
||||||
|
Player* mainTank = GetGroupMainTank(botAI, bot);
|
||||||
|
if (!mainTank)
|
||||||
|
return TankPositionState::Unknown;
|
||||||
|
|
||||||
|
auto it = shahrazTankStep.find(mainTank->GetGUID());
|
||||||
|
if (it != shahrazTankStep.end())
|
||||||
|
return it->second;
|
||||||
|
|
||||||
|
return TankPositionState::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Illidari Council
|
||||||
|
const std::array<Position, 4> GATHIOS_TANK_POSITIONS = {{
|
||||||
|
{ 662.977f, 296.246f, 271.688f },
|
||||||
|
{ 636.238f, 283.719f, 271.629f },
|
||||||
|
{ 655.571f, 261.377f, 271.687f },
|
||||||
|
{ 673.789f, 274.139f, 271.689f }
|
||||||
|
}};
|
||||||
|
const Position ZEREVOR_TANK_POSITION = { 686.219f, 377.644f, 271.689f };
|
||||||
|
const std::array<Position, 2> ZEREVOR_HEALER_POSITIONS = {{
|
||||||
|
{ 661.385f, 351.219f, 271.690f },
|
||||||
|
{ 667.003f, 363.768f, 271.690f }
|
||||||
|
}};
|
||||||
|
const Position MALANDE_TANK_POSITION = { 690.590f, 299.790f, 277.443f };
|
||||||
|
|
||||||
|
std::unordered_map<uint32, time_t> councilDpsWaitTimer;
|
||||||
|
std::unordered_map<ObjectGuid, uint8> gathiosTankStep;
|
||||||
|
std::unordered_map<ObjectGuid, uint8> zerevorHealStep;
|
||||||
|
|
||||||
|
// (1) First priority is an assistant Mage (real player or bot)
|
||||||
|
// (2) If no assistant Mage, then look for any Mage bot
|
||||||
|
Player* GetZerevorMageTank(Player* bot)
|
||||||
|
{
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
Player* fallbackMage = nullptr;
|
||||||
|
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
|
{
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (!member || !member->IsAlive() || member->getClass() != CLASS_MAGE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (group->IsAssistant(member->GetGUID()))
|
||||||
|
return member;
|
||||||
|
|
||||||
|
if (!fallbackMage && GET_PLAYERBOT_AI(member))
|
||||||
|
fallbackMage = member;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fallbackMage;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasDangerousCouncilAura(Unit* unit)
|
||||||
|
{
|
||||||
|
static const std::array<uint32, 3> dangerousAuras =
|
||||||
|
{
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_CONSECRATION),
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_BLIZZARD),
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_FLAMESTRIKE)
|
||||||
|
};
|
||||||
|
|
||||||
|
for (uint32 aura : dangerousAuras)
|
||||||
|
{
|
||||||
|
if (unit->HasAura(aura))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
const Position ILLIDAN_LANDING_POSITION = { 676.648f, 304.761f, 354.189f };
|
||||||
|
const Position ILLIDAN_N_GRATE_POSITION = { 682.100f, 306.000f, 353.192f };
|
||||||
|
const Position ILLIDAN_E_GRATE_POSITION = { 673.500f, 298.500f, 353.192f };
|
||||||
|
const Position ILLIDAN_W_GRATE_POSITION = { 672.400f, 312.500f, 353.192f };
|
||||||
|
const std::array<Position, 3> GRATE_POSITIONS = {{
|
||||||
|
ILLIDAN_N_GRATE_POSITION,
|
||||||
|
ILLIDAN_E_GRATE_POSITION,
|
||||||
|
ILLIDAN_W_GRATE_POSITION
|
||||||
|
}};
|
||||||
|
|
||||||
|
const Position ILLIDAN_E_GLAIVE_WAITING_POSITION = { 677.656f, 294.066f, 353.192f };
|
||||||
|
const std::array<Position, 7> E_GLAIVE_TANK_POSITIONS = {{
|
||||||
|
{ 683.000f, 295.000f, 354.000f },
|
||||||
|
{ 696.969f, 300.982f, 354.302f },
|
||||||
|
{ 691.112f, 287.461f, 354.363f },
|
||||||
|
{ 676.674f, 280.797f, 354.268f },
|
||||||
|
{ 664.414f, 284.834f, 354.271f },
|
||||||
|
{ 656.826f, 295.113f, 354.165f },
|
||||||
|
{ 665.000f, 304.000f, 354.000f }
|
||||||
|
}};
|
||||||
|
|
||||||
|
const Position ILLIDAN_W_GLAIVE_WAITING_POSITION = { 676.102f, 316.305f, 353.192f };
|
||||||
|
const std::array<Position, 7> W_GLAIVE_TANK_POSITIONS = {{
|
||||||
|
{ 697.208f, 313.475f, 354.234f },
|
||||||
|
{ 681.000f, 318.000f, 354.000f },
|
||||||
|
{ 664.000f, 307.000f, 354.000f },
|
||||||
|
{ 656.161f, 314.132f, 354.092f },
|
||||||
|
{ 665.080f, 326.905f, 354.128f },
|
||||||
|
{ 678.809f, 329.968f, 354.387f },
|
||||||
|
{ 690.889f, 324.277f, 354.204f }
|
||||||
|
}};
|
||||||
|
|
||||||
|
std::unordered_map<ObjectGuid, size_t> flameTankWaypointIndex;
|
||||||
|
std::unordered_map<ObjectGuid, ObjectGuid> illidanShadowTrapGuid;
|
||||||
|
std::unordered_map<ObjectGuid, Position> illidanShadowTrapDestination;
|
||||||
|
std::unordered_map<uint32, int> illidanLastPhase;
|
||||||
|
std::unordered_map<uint32, time_t> illidanBossDpsWaitTimer;
|
||||||
|
std::unordered_map<uint32, time_t> illidanFlameDpsWaitTimer;
|
||||||
|
std::unordered_map<uint32, ObjectGuid> eastFlameGuid;
|
||||||
|
std::unordered_map<uint32, ObjectGuid> westFlameGuid;
|
||||||
|
|
||||||
|
int GetIllidanPhase(Unit* illidan)
|
||||||
|
{
|
||||||
|
if (!illidan || illidan->GetHealth() == 1 || illidan->HasAura(
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_SHADOW_PRISON)))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transitioning from Phase 2 to Phase 3
|
||||||
|
float x, y, z;
|
||||||
|
illidan->GetMotionMaster()->GetDestination(x, y, z);
|
||||||
|
Position dest(x, y, z);
|
||||||
|
if ((dest.GetExactDist2d(ILLIDAN_LANDING_POSITION) < 0.2f ||
|
||||||
|
illidan->GetExactDist2d(ILLIDAN_LANDING_POSITION) < 0.2f) &&
|
||||||
|
illidan->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Phase 2: Flying
|
||||||
|
if (illidan->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
// Phase 1: Health > 65%
|
||||||
|
if (illidan->GetHealthPct() > 65.0f)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// Phase 4: Demon Form
|
||||||
|
if (!illidan->HasAura(static_cast<uint32>(BlackTempleSpells::SPELL_CAGED)) &&
|
||||||
|
(illidan->HasAura(static_cast<uint32>(BlackTempleSpells::SPELL_DEMON_FORM)) ||
|
||||||
|
illidan->HasAura(static_cast<uint32>(BlackTempleSpells::SPELL_DEMON_TRANSFORM_1)) ||
|
||||||
|
illidan->HasAura(static_cast<uint32>(BlackTempleSpells::SPELL_DEMON_TRANSFORM_2)) ||
|
||||||
|
illidan->HasAura(static_cast<uint32>(BlackTempleSpells::SPELL_DEMON_TRANSFORM_3))))
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Phase 3: Normal (ground, 65-30%, not demon)
|
||||||
|
if (illidan->GetHealthPct() > 30.0f)
|
||||||
|
return 3;
|
||||||
|
|
||||||
|
// Phase 5: Health <= 30%
|
||||||
|
if (illidan->GetHealthPct() <= 30.0f)
|
||||||
|
return 5;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Unit*> GetAllFlameCrashes(Player* bot)
|
||||||
|
{
|
||||||
|
std::vector<Unit*> flameCrashes;
|
||||||
|
std::list<Creature*> creatureList;
|
||||||
|
constexpr float searchRadius = 30.0f;
|
||||||
|
bot->GetCreatureListWithEntryInGrid(
|
||||||
|
creatureList, static_cast<uint32>(BlackTempleNpcs::NPC_FLAME_CRASH), searchRadius);
|
||||||
|
|
||||||
|
for (Creature* creature : creatureList)
|
||||||
|
{
|
||||||
|
if (creature && creature->IsAlive())
|
||||||
|
flameCrashes.push_back(creature);
|
||||||
|
}
|
||||||
|
|
||||||
|
return flameCrashes;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<Unit*, Unit*> GetFlamesOfAzzinoth(Player* bot)
|
||||||
|
{
|
||||||
|
Unit* eastFlame = nullptr;
|
||||||
|
Unit* westFlame = nullptr;
|
||||||
|
|
||||||
|
const uint32 instanceId = bot->GetMap()->GetInstanceId();
|
||||||
|
|
||||||
|
if (eastFlameGuid.find(instanceId) != eastFlameGuid.end())
|
||||||
|
{
|
||||||
|
if (Unit* unit = ObjectAccessor::GetUnit(*bot, eastFlameGuid[instanceId]))
|
||||||
|
{
|
||||||
|
if (unit->IsAlive())
|
||||||
|
eastFlame = unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (westFlameGuid.find(instanceId) != westFlameGuid.end())
|
||||||
|
{
|
||||||
|
if (Unit* unit = ObjectAccessor::GetUnit(*bot, westFlameGuid[instanceId]))
|
||||||
|
{
|
||||||
|
if (unit->IsAlive())
|
||||||
|
westFlame = unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { eastFlame, westFlame };
|
||||||
|
}
|
||||||
|
|
||||||
|
// (1) First priority is an assistant Warlock (real player or bot)
|
||||||
|
// (2) If no assistant Warlock, then look for any Warlock bot
|
||||||
|
Player* GetIllidanWarlockTank(Player* bot)
|
||||||
|
{
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
Player* fallbackWarlock = nullptr;
|
||||||
|
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
|
{
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (!member || !member->IsAlive() || member->getClass() != CLASS_WARLOCK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (group->IsAssistant(member->GetGUID()))
|
||||||
|
return member;
|
||||||
|
|
||||||
|
if (!fallbackWarlock && GET_PLAYERBOT_AI(member))
|
||||||
|
fallbackWarlock = member;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fallbackWarlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasParasiticShadowfiend(Player* member)
|
||||||
|
{
|
||||||
|
if (!member)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
constexpr uint32 shadowfiendAura1 =
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_PARASITIC_SHADOWFIEND_1);
|
||||||
|
constexpr uint32 shadowfiendAura2 =
|
||||||
|
static_cast<uint32>(BlackTempleSpells::SPELL_PARASITIC_SHADOWFIEND_2);
|
||||||
|
|
||||||
|
return member->HasAura(shadowfiendAura1) || member->HasAura(shadowfiendAura2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the first bot hunter that doesn't have Parasitic Shadowfiend
|
||||||
|
Player* GetIllidanTrapperHunter(Player* bot)
|
||||||
|
{
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
|
{
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (member && member->IsAlive() && member->getClass() == CLASS_HUNTER &&
|
||||||
|
GET_PLAYERBOT_AI(member) && !HasParasiticShadowfiend(member))
|
||||||
|
{
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player* GetBotWithParasiticShadowfiend(Player* bot)
|
||||||
|
{
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
|
{
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (member && member->IsAlive() && GET_PLAYERBOT_AI(member) &&
|
||||||
|
HasParasiticShadowfiend(member))
|
||||||
|
{
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
EyeBlastDangerArea GetEyeBlastDangerArea(Player* bot)
|
||||||
|
{
|
||||||
|
constexpr float searchRadius = 100.0f;
|
||||||
|
std::list<Creature*> creatureList;
|
||||||
|
bot->GetCreatureListWithEntryInGrid(
|
||||||
|
creatureList, static_cast<uint32>(BlackTempleNpcs::NPC_ILLIDAN_DB_TARGET), searchRadius);
|
||||||
|
|
||||||
|
Creature* eyeBlastTrigger = nullptr;
|
||||||
|
for (Creature* creature : creatureList)
|
||||||
|
{
|
||||||
|
if (creature && creature->IsAlive())
|
||||||
|
{
|
||||||
|
eyeBlastTrigger = creature;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eyeBlastTrigger)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
Position startPos = Position(eyeBlastTrigger->GetPositionX(), eyeBlastTrigger->GetPositionY(),
|
||||||
|
eyeBlastTrigger->GetPositionZ());
|
||||||
|
|
||||||
|
float destX, destY, destZ;
|
||||||
|
eyeBlastTrigger->GetMotionMaster()->GetDestination(destX, destY, destZ);
|
||||||
|
Position endPos(destX, destY, destZ);
|
||||||
|
|
||||||
|
if (startPos.GetExactDist2d(endPos) < 0.1f)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
constexpr float eyeBlastWidth = 9.0f;
|
||||||
|
return { startPos, endPos, eyeBlastWidth };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsPositionInEyeBlastDangerArea(const Position& pos, const EyeBlastDangerArea& area)
|
||||||
|
{
|
||||||
|
const float dx = area.end.GetPositionX() - area.start.GetPositionX();
|
||||||
|
const float dy = area.end.GetPositionY() - area.start.GetPositionY();
|
||||||
|
const float length = area.start.GetExactDist2d(area.end.GetPositionX(), area.end.GetPositionY());
|
||||||
|
|
||||||
|
if (length < 0.1f)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const float projectionFactor = (
|
||||||
|
(pos.GetPositionX() - area.start.GetPositionX()) * dx + (
|
||||||
|
pos.GetPositionY() - area.start.GetPositionY()) * dy) / (length * length);
|
||||||
|
|
||||||
|
const float clampedProjectionFactor = std::clamp(projectionFactor, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
const float closestX = area.start.GetPositionX() + clampedProjectionFactor * dx;
|
||||||
|
const float closestY = area.start.GetPositionY() + clampedProjectionFactor * dy;
|
||||||
|
|
||||||
|
const float distToLine = pos.GetExactDist2d(closestX, closestY);
|
||||||
|
|
||||||
|
return distToLine < area.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject* FindNearestTrap(PlayerbotAI* botAI, Player* bot)
|
||||||
|
{
|
||||||
|
GuidVector const& gos =
|
||||||
|
botAI->GetAiObjectContext()->GetValue<GuidVector>("nearest game objects")->Get();
|
||||||
|
|
||||||
|
GameObject* nearestTrap = nullptr;
|
||||||
|
for (ObjectGuid const& guid : gos)
|
||||||
|
{
|
||||||
|
GameObject* go = botAI->GetGameObject(guid);
|
||||||
|
if (go && go->isSpawned() &&
|
||||||
|
go->GetEntry() == static_cast<uint32>(BlackTempleObjects::GO_SHADOW_TRAP))
|
||||||
|
{
|
||||||
|
nearestTrap = go;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nearestTrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
216
src/Ai/Raid/BlackTemple/Util/RaidBlackTempleHelpers.h
Normal file
216
src/Ai/Raid/BlackTemple/Util/RaidBlackTempleHelpers.h
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
* 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_RAIDBLACKTEMPLEHELPERS_H_
|
||||||
|
#define _PLAYERBOT_RAIDBLACKTEMPLEHELPERS_H_
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "ObjectGuid.h"
|
||||||
|
#include "Position.h"
|
||||||
|
|
||||||
|
class GameObject;
|
||||||
|
class Player;
|
||||||
|
class PlayerbotAI;
|
||||||
|
class Unit;
|
||||||
|
|
||||||
|
namespace BlackTempleHelpers
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class BlackTempleSpells : uint32
|
||||||
|
{
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
SPELL_IMPALING_SPINE = 39837,
|
||||||
|
SPELL_TIDAL_SHIELD = 39872,
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
SPELL_SNARE_SELF = 41922,
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
SPELL_SHADOW_OF_DEATH = 40251,
|
||||||
|
SPELL_SPIRITUAL_VENGEANCE = 40268,
|
||||||
|
|
||||||
|
SPELL_SPIRIT_LANCE = 40157,
|
||||||
|
SPELL_SPIRIT_CHAINS = 40175,
|
||||||
|
SPELL_SPIRIT_VOLLEY = 40314,
|
||||||
|
SPELL_SPIRIT_STRIKE = 40325,
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
SPELL_BOSS_FEL_RAGE = 40594,
|
||||||
|
SPELL_PLAYER_FEL_RAGE = 40604,
|
||||||
|
SPELL_BLOODBOIL = 42005,
|
||||||
|
|
||||||
|
// Reliquary of Souls
|
||||||
|
SPELL_DEADEN = 41410,
|
||||||
|
SPELL_RUNE_SHIELD = 41431,
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
SPELL_FATAL_ATTRACTION = 41001,
|
||||||
|
|
||||||
|
// Gathios the Shatterer
|
||||||
|
SPELL_BLESSING_OF_PROTECTION = 41450,
|
||||||
|
SPELL_BLESSING_OF_SPELL_WARDING = 41451,
|
||||||
|
SPELL_JUDGEMENT = 41467,
|
||||||
|
SPELL_SEAL_OF_COMMAND = 41469,
|
||||||
|
SPELL_CONSECRATION = 41541,
|
||||||
|
|
||||||
|
// Veras Darkshadow
|
||||||
|
SPELL_VANISH = 41476,
|
||||||
|
|
||||||
|
// High Nethermancer Zerevor
|
||||||
|
SPELL_DAMPEN_MAGIC = 41478,
|
||||||
|
SPELL_FLAMESTRIKE = 41481,
|
||||||
|
SPELL_BLIZZARD = 41482,
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
SPELL_DEMON_TRANSFORM_1 = 40511,
|
||||||
|
SPELL_DEMON_TRANSFORM_2 = 40398,
|
||||||
|
SPELL_DEMON_TRANSFORM_3 = 40510,
|
||||||
|
SPELL_DEMON_FORM = 40506,
|
||||||
|
SPELL_DARK_BARRAGE = 40585,
|
||||||
|
SPELL_SHADOW_PRISON = 40647,
|
||||||
|
SPELL_CAGED = 40695,
|
||||||
|
SPELL_PARASITIC_SHADOWFIEND_1 = 41917, // cast by Illidan (primary infection)
|
||||||
|
SPELL_PARASITIC_SHADOWFIEND_2 = 41914, // cast by Shadowfiend on contact (secondary infection)
|
||||||
|
|
||||||
|
// Hunter
|
||||||
|
SPELL_FROST_TRAP = 13809,
|
||||||
|
SPELL_MISDIRECTION = 35079,
|
||||||
|
|
||||||
|
// Shaman
|
||||||
|
SPELL_EARTHBIND_TOTEM = 2484,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class BlackTempleNpcs : uint32
|
||||||
|
{
|
||||||
|
// Supremus
|
||||||
|
NPC_SUPREMUS_VOLCANO = 23085,
|
||||||
|
|
||||||
|
// Shade of Akama
|
||||||
|
NPC_ASHTONGUE_CHANNELER = 23421,
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
NPC_SHADOWY_CONSTRUCT = 23111,
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
NPC_FLAME_OF_AZZINOTH = 22997,
|
||||||
|
NPC_DEMON_FIRE = 23069,
|
||||||
|
NPC_ILLIDAN_DB_TARGET = 23070,
|
||||||
|
NPC_BLAZE = 23259,
|
||||||
|
NPC_FLAME_CRASH = 23336,
|
||||||
|
NPC_SHADOW_DEMON = 23375,
|
||||||
|
NPC_PARASITIC_SHADOWFIEND = 23498,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class BlackTempleItems : uint32
|
||||||
|
{
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
ITEM_NAJENTUS_SPINE = 32408,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class BlackTempleObjects : uint32
|
||||||
|
{
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
GO_NAJENTUS_SPINE = 185584,
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
GO_SHADOW_TRAP = 185916,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class TankPositionState : uint8
|
||||||
|
{
|
||||||
|
MovingToTransition = 0,
|
||||||
|
MovingToFinal = 1,
|
||||||
|
Positioned = 2,
|
||||||
|
Unknown = 255,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint32 BLACK_TEMPLE_MAP_ID = 564;
|
||||||
|
|
||||||
|
// High Warlord Naj'entus
|
||||||
|
extern const Position NAJENTUS_TANK_POSITION;
|
||||||
|
|
||||||
|
// Supremus
|
||||||
|
extern std::unordered_map<uint32, time_t> supremusPhaseTimer;
|
||||||
|
bool HasSupremusVolcanoNearby(PlayerbotAI* botAI, Player* bot);
|
||||||
|
|
||||||
|
// Shade of Akama
|
||||||
|
extern const Position AKAMA_CHANNELER_POSITION;
|
||||||
|
extern std::unordered_set<ObjectGuid> hasReachedAkamaChannelerPosition;
|
||||||
|
|
||||||
|
// Teron Gorefiend
|
||||||
|
extern const Position GOREFIEND_TANK_POSITION;
|
||||||
|
extern const Position GOREFIEND_DIE_POSITION;
|
||||||
|
|
||||||
|
// Gurtogg Bloodboil
|
||||||
|
extern const Position GURTOGG_TANK_POSITION;
|
||||||
|
extern const Position GURTOGG_RANGED_POSITION;
|
||||||
|
extern const Position GURTOGG_SOAKER_POSITION;
|
||||||
|
extern std::unordered_map<uint32, time_t> gurtoggPhaseTimer;
|
||||||
|
std::vector<std::vector<Player*>> GetGurtoggRangedRotationGroups(Player* bot);
|
||||||
|
int GetGurtoggActiveRotationGroup(Unit* gurtogg);
|
||||||
|
|
||||||
|
// Mother Shahraz
|
||||||
|
extern const Position SHAHRAZ_TANK_POSITION;
|
||||||
|
extern const Position SHAHRAZ_TRANSITION_POSITION;
|
||||||
|
extern const Position SHAHRAZ_RANGED_POSITION;
|
||||||
|
extern std::unordered_map<ObjectGuid, TankPositionState> shahrazTankStep;
|
||||||
|
TankPositionState GetShahrazTankPositionState(PlayerbotAI* botAI, Player* bot);
|
||||||
|
|
||||||
|
// Illidari Council
|
||||||
|
constexpr float COUNCIL_FLOOR_Z_THRESHOLD = 270.000f;
|
||||||
|
extern const std::array<Position, 4> GATHIOS_TANK_POSITIONS;
|
||||||
|
extern const Position MALANDE_TANK_POSITION;
|
||||||
|
extern const Position ZEREVOR_TANK_POSITION;
|
||||||
|
extern const std::array<Position, 2> ZEREVOR_HEALER_POSITIONS;
|
||||||
|
extern std::unordered_map<uint32, time_t> councilDpsWaitTimer;
|
||||||
|
extern std::unordered_map<ObjectGuid, uint8> gathiosTankStep;
|
||||||
|
extern std::unordered_map<ObjectGuid, uint8> zerevorHealStep;
|
||||||
|
Player* GetZerevorMageTank(Player* bot);
|
||||||
|
bool HasDangerousCouncilAura(Unit* unit);
|
||||||
|
|
||||||
|
// Illidan Stormrage <The Betrayer>
|
||||||
|
extern const Position ILLIDAN_LANDING_POSITION;
|
||||||
|
extern const Position ILLIDAN_N_GRATE_POSITION;
|
||||||
|
extern const Position ILLIDAN_E_GRATE_POSITION;
|
||||||
|
extern const Position ILLIDAN_W_GRATE_POSITION;
|
||||||
|
extern const std::array<Position, 3> GRATE_POSITIONS;
|
||||||
|
extern const Position ILLIDAN_E_GLAIVE_WAITING_POSITION;
|
||||||
|
extern const std::array<Position, 7> E_GLAIVE_TANK_POSITIONS;
|
||||||
|
extern const Position ILLIDAN_W_GLAIVE_WAITING_POSITION;
|
||||||
|
extern const std::array<Position, 7> W_GLAIVE_TANK_POSITIONS;
|
||||||
|
extern std::unordered_map<ObjectGuid, size_t> flameTankWaypointIndex;
|
||||||
|
extern std::unordered_map<ObjectGuid, ObjectGuid> illidanShadowTrapGuid;
|
||||||
|
extern std::unordered_map<ObjectGuid, Position> illidanShadowTrapDestination;
|
||||||
|
extern std::unordered_map<uint32, int> illidanLastPhase;
|
||||||
|
extern std::unordered_map<uint32, time_t> illidanBossDpsWaitTimer;
|
||||||
|
extern std::unordered_map<uint32, time_t> illidanFlameDpsWaitTimer;
|
||||||
|
extern std::unordered_map<uint32, ObjectGuid> eastFlameGuid;
|
||||||
|
extern std::unordered_map<uint32, ObjectGuid> westFlameGuid;
|
||||||
|
int GetIllidanPhase(Unit* illidan);
|
||||||
|
std::vector<Unit*> GetAllFlameCrashes(Player* bot);
|
||||||
|
std::pair<Unit*, Unit*> GetFlamesOfAzzinoth(Player* bot);
|
||||||
|
Player* GetIllidanWarlockTank(Player* bot);
|
||||||
|
bool HasParasiticShadowfiend(Player* member);
|
||||||
|
Player* GetIllidanTrapperHunter(Player* bot);
|
||||||
|
Player* GetBotWithParasiticShadowfiend(Player* bot);
|
||||||
|
struct EyeBlastDangerArea
|
||||||
|
{
|
||||||
|
Position start;
|
||||||
|
Position end;
|
||||||
|
float width;
|
||||||
|
};
|
||||||
|
EyeBlastDangerArea GetEyeBlastDangerArea(Player* bot);
|
||||||
|
bool IsPositionInEyeBlastDangerArea(const Position& pos, const EyeBlastDangerArea& area);
|
||||||
|
GameObject* FindNearestTrap(PlayerbotAI* botAI, Player* bot);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -19,7 +19,7 @@ bool HighKingMaulgarMainTankAttackMaulgarAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithSquare(bot, maulgar);
|
MarkTargetWithSquare(bot, maulgar);
|
||||||
SetRtiTarget(botAI, "square", maulgar);
|
SetRtiTarget(botAI, "square", maulgar);
|
||||||
|
|
||||||
if (bot->GetVictim() != maulgar)
|
if (AI_VALUE(Unit*, "current target") != maulgar)
|
||||||
return Attack(maulgar);
|
return Attack(maulgar);
|
||||||
|
|
||||||
if (maulgar->GetVictim() == bot)
|
if (maulgar->GetVictim() == bot)
|
||||||
@ -53,7 +53,7 @@ bool HighKingMaulgarFirstAssistTankAttackOlmAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithCircle(bot, olm);
|
MarkTargetWithCircle(bot, olm);
|
||||||
SetRtiTarget(botAI, "circle", olm);
|
SetRtiTarget(botAI, "circle", olm);
|
||||||
|
|
||||||
if (bot->GetVictim() != olm)
|
if (AI_VALUE(Unit*, "current target") != olm)
|
||||||
return Attack(olm);
|
return Attack(olm);
|
||||||
|
|
||||||
if (olm->GetVictim() == bot)
|
if (olm->GetVictim() == bot)
|
||||||
@ -88,7 +88,7 @@ bool HighKingMaulgarSecondAssistTankAttackBlindeyeAction::Execute(Event /*event*
|
|||||||
MarkTargetWithStar(bot, blindeye);
|
MarkTargetWithStar(bot, blindeye);
|
||||||
SetRtiTarget(botAI, "star", blindeye);
|
SetRtiTarget(botAI, "star", blindeye);
|
||||||
|
|
||||||
if (bot->GetVictim() != blindeye)
|
if (AI_VALUE(Unit*, "current target") != blindeye)
|
||||||
return Attack(blindeye);
|
return Attack(blindeye);
|
||||||
|
|
||||||
if (blindeye->GetVictim() == bot)
|
if (blindeye->GetVictim() == bot)
|
||||||
@ -128,7 +128,7 @@ bool HighKingMaulgarMageTankAttackKroshAction::Execute(Event /*event*/)
|
|||||||
if (!bot->HasAura(SPELL_SPELL_SHIELD) && botAI->CanCastSpell("fire ward", bot))
|
if (!bot->HasAura(SPELL_SPELL_SHIELD) && botAI->CanCastSpell("fire ward", bot))
|
||||||
return botAI->CastSpell("fire ward", bot);
|
return botAI->CastSpell("fire ward", bot);
|
||||||
|
|
||||||
if (bot->GetTarget() != krosh->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != krosh)
|
||||||
return Attack(krosh);
|
return Attack(krosh);
|
||||||
|
|
||||||
if (krosh->GetVictim() == bot)
|
if (krosh->GetVictim() == bot)
|
||||||
@ -175,7 +175,7 @@ bool HighKingMaulgarMoonkinTankAttackKigglerAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithDiamond(bot, kiggler);
|
MarkTargetWithDiamond(bot, kiggler);
|
||||||
SetRtiTarget(botAI, "diamond", kiggler);
|
SetRtiTarget(botAI, "diamond", kiggler);
|
||||||
|
|
||||||
if (bot->GetTarget() != kiggler->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != kiggler)
|
||||||
return Attack(kiggler);
|
return Attack(kiggler);
|
||||||
|
|
||||||
Position safePos;
|
Position safePos;
|
||||||
@ -205,7 +205,7 @@ bool HighKingMaulgarAssignDPSPriorityAction::Execute(Event /*event*/)
|
|||||||
|
|
||||||
SetRtiTarget(botAI, "star", blindeye);
|
SetRtiTarget(botAI, "star", blindeye);
|
||||||
|
|
||||||
if (bot->GetTarget() != blindeye->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != blindeye)
|
||||||
return Attack(blindeye);
|
return Attack(blindeye);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -226,7 +226,7 @@ bool HighKingMaulgarAssignDPSPriorityAction::Execute(Event /*event*/)
|
|||||||
|
|
||||||
SetRtiTarget(botAI, "circle", olm);
|
SetRtiTarget(botAI, "circle", olm);
|
||||||
|
|
||||||
if (bot->GetTarget() != olm->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != olm)
|
||||||
return Attack(olm);
|
return Attack(olm);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -247,7 +247,7 @@ bool HighKingMaulgarAssignDPSPriorityAction::Execute(Event /*event*/)
|
|||||||
|
|
||||||
SetRtiTarget(botAI, "triangle", krosh);
|
SetRtiTarget(botAI, "triangle", krosh);
|
||||||
|
|
||||||
if (bot->GetTarget() != krosh->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != krosh)
|
||||||
return Attack(krosh);
|
return Attack(krosh);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -268,7 +268,7 @@ bool HighKingMaulgarAssignDPSPriorityAction::Execute(Event /*event*/)
|
|||||||
|
|
||||||
SetRtiTarget(botAI, "diamond", kiggler);
|
SetRtiTarget(botAI, "diamond", kiggler);
|
||||||
|
|
||||||
if (bot->GetTarget() != kiggler->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != kiggler)
|
||||||
return Attack(kiggler);
|
return Attack(kiggler);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -289,7 +289,7 @@ bool HighKingMaulgarAssignDPSPriorityAction::Execute(Event /*event*/)
|
|||||||
|
|
||||||
SetRtiTarget(botAI, "square", maulgar);
|
SetRtiTarget(botAI, "square", maulgar);
|
||||||
|
|
||||||
if (bot->GetTarget() != maulgar->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != maulgar)
|
||||||
return Attack(maulgar);
|
return Attack(maulgar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,7 +499,7 @@ bool GruulTheDragonkillerTanksPositionBossAction::Execute(Event /*event*/)
|
|||||||
if (!gruul)
|
if (!gruul)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetVictim() != gruul)
|
if (AI_VALUE(Unit*, "current target") != gruul)
|
||||||
return Attack(gruul);
|
return Attack(gruul);
|
||||||
|
|
||||||
if (gruul->GetVictim() == bot)
|
if (gruul->GetVictim() == bot)
|
||||||
|
|||||||
@ -15,6 +15,9 @@ using namespace GruulsLairHelpers;
|
|||||||
|
|
||||||
float HighKingMaulgarDisableTankAssistMultiplier::GetValue(Action* action)
|
float HighKingMaulgarDisableTankAssistMultiplier::GetValue(Action* action)
|
||||||
{
|
{
|
||||||
|
if (bot->GetVictim() == nullptr)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
if (IsAnyOgreBossAlive(botAI) && dynamic_cast<TankAssistAction*>(action))
|
if (IsAnyOgreBossAlive(botAI) && dynamic_cast<TankAssistAction*>(action))
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
@ -46,9 +49,8 @@ float HighKingMaulgarAvoidWhirlwindMultiplier::GetValue(Action* action)
|
|||||||
float HighKingMaulgarDisableArcaneShotOnKroshMultiplier::GetValue(Action* action)
|
float HighKingMaulgarDisableArcaneShotOnKroshMultiplier::GetValue(Action* action)
|
||||||
{
|
{
|
||||||
Unit* krosh = AI_VALUE2(Unit*, "find target", "krosh firehand");
|
Unit* krosh = AI_VALUE2(Unit*, "find target", "krosh firehand");
|
||||||
Unit* target = AI_VALUE(Unit*, "current target");
|
|
||||||
|
|
||||||
if (krosh && target && target->GetGUID() == krosh->GetGUID() &&
|
if (krosh && AI_VALUE(Unit*, "current target") == krosh &&
|
||||||
dynamic_cast<CastArcaneShotAction*>(action))
|
dynamic_cast<CastArcaneShotAction*>(action))
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
|
|||||||
@ -97,7 +97,7 @@ bool RageWinterchillMainTankPositionBossAction::Execute(Event /*event*/)
|
|||||||
if (!winterchill)
|
if (!winterchill)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetVictim() != winterchill)
|
if (AI_VALUE(Unit*, "current target") != winterchill)
|
||||||
return Attack(winterchill);
|
return Attack(winterchill);
|
||||||
|
|
||||||
if (winterchill->GetVictim() == bot)
|
if (winterchill->GetVictim() == bot)
|
||||||
@ -265,7 +265,7 @@ bool AnetheronMainTankPositionBossAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithSquare(bot, anetheron);
|
MarkTargetWithSquare(bot, anetheron);
|
||||||
SetRtiTarget(botAI, "square", anetheron);
|
SetRtiTarget(botAI, "square", anetheron);
|
||||||
|
|
||||||
if (bot->GetVictim() != anetheron)
|
if (AI_VALUE(Unit*, "current target") != anetheron)
|
||||||
return Attack(anetheron);
|
return Attack(anetheron);
|
||||||
|
|
||||||
if (anetheron->GetVictim() == bot)
|
if (anetheron->GetVictim() == bot)
|
||||||
@ -395,7 +395,7 @@ bool AnetheronFirstAssistTankPickUpInfernalsAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithDiamond(bot, infernal);
|
MarkTargetWithDiamond(bot, infernal);
|
||||||
SetRtiTarget(botAI, "diamond", infernal);
|
SetRtiTarget(botAI, "diamond", infernal);
|
||||||
|
|
||||||
if (bot->GetVictim() != infernal)
|
if (AI_VALUE(Unit*, "current target") != infernal)
|
||||||
return Attack(infernal);
|
return Attack(infernal);
|
||||||
|
|
||||||
if ((infernoTarget && infernoTarget == bot) ||
|
if ((infernoTarget && infernoTarget == bot) ||
|
||||||
@ -432,7 +432,7 @@ bool AnetheronAssignDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "square", anetheron);
|
SetRtiTarget(botAI, "square", anetheron);
|
||||||
|
|
||||||
if (bot->GetVictim() != anetheron)
|
if (AI_VALUE(Unit*, "current target") != anetheron)
|
||||||
return Attack(anetheron);
|
return Attack(anetheron);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -455,7 +455,7 @@ bool AnetheronAssignDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "diamond", infernal);
|
SetRtiTarget(botAI, "diamond", infernal);
|
||||||
|
|
||||||
if (bot->GetTarget() != infernal->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != infernal)
|
||||||
return Attack(infernal);
|
return Attack(infernal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -464,7 +464,7 @@ bool AnetheronAssignDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "square", anetheron);
|
SetRtiTarget(botAI, "square", anetheron);
|
||||||
|
|
||||||
if (bot->GetTarget() != anetheron->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != anetheron)
|
||||||
return Attack(anetheron);
|
return Attack(anetheron);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,7 +500,7 @@ bool KazrogalMainTankPositionBossAction::Execute(Event /*event*/)
|
|||||||
if (!kazrogal)
|
if (!kazrogal)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetVictim() != kazrogal)
|
if (AI_VALUE(Unit*, "current target") != kazrogal)
|
||||||
return Attack(kazrogal);
|
return Attack(kazrogal);
|
||||||
|
|
||||||
if (kazrogal->GetVictim() == bot && bot->IsWithinMeleeRange(kazrogal))
|
if (kazrogal->GetVictim() == bot && bot->IsWithinMeleeRange(kazrogal))
|
||||||
@ -734,7 +734,7 @@ bool AzgalorMainTankPositionBossAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithStar(bot, azgalor);
|
MarkTargetWithStar(bot, azgalor);
|
||||||
SetRtiTarget(botAI, "star", azgalor);
|
SetRtiTarget(botAI, "star", azgalor);
|
||||||
|
|
||||||
if (bot->GetVictim() != azgalor)
|
if (AI_VALUE(Unit*, "current target") != azgalor)
|
||||||
return Attack(azgalor);
|
return Attack(azgalor);
|
||||||
|
|
||||||
if (azgalor->GetVictim() == bot && bot->IsWithinMeleeRange(azgalor))
|
if (azgalor->GetVictim() == bot && bot->IsWithinMeleeRange(azgalor))
|
||||||
@ -801,7 +801,7 @@ bool AzgalorDisperseRangedAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
return FleePosition(doomguard->GetPosition(), safeDistFromDoomguard);
|
return FleePosition(doomguard->GetPosition(), safeDistFromDoomguard);
|
||||||
}
|
}
|
||||||
else if (!doomguard || bot->GetTarget() != doomguard->GetGUID())
|
else if (!doomguard || AI_VALUE(Unit*, "current target") != doomguard)
|
||||||
{
|
{
|
||||||
Unit* nearestPlayer = GetNearestPlayerInRadius(bot, safeDistFromPlayer);
|
Unit* nearestPlayer = GetNearestPlayerInRadius(bot, safeDistFromPlayer);
|
||||||
if (nearestPlayer)
|
if (nearestPlayer)
|
||||||
@ -848,7 +848,7 @@ bool AzgalorMeleeGetOutOfFireAndSwapTargetsAction::Execute(Event /*event*/)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bot->GetVictim() != desiredTarget || bot->GetTarget() != desiredTarget->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != desiredTarget)
|
||||||
return Attack(desiredTarget);
|
return Attack(desiredTarget);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -912,7 +912,7 @@ bool AzgalorFirstAssistTankPositionDoomguardAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithCircle(bot, doomguard);
|
MarkTargetWithCircle(bot, doomguard);
|
||||||
SetRtiTarget(botAI, "circle", doomguard);
|
SetRtiTarget(botAI, "circle", doomguard);
|
||||||
|
|
||||||
if (bot->GetVictim() != doomguard)
|
if (AI_VALUE(Unit*, "current target") != doomguard)
|
||||||
return Attack(doomguard);
|
return Attack(doomguard);
|
||||||
|
|
||||||
if (doomguard->GetVictim() == bot && bot->IsWithinMeleeRange(doomguard) &&
|
if (doomguard->GetVictim() == bot && bot->IsWithinMeleeRange(doomguard) &&
|
||||||
@ -963,7 +963,7 @@ bool AzgalorRangedDpsPrioritizeDoomguardsAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "circle", doomguard);
|
SetRtiTarget(botAI, "circle", doomguard);
|
||||||
|
|
||||||
if (bot->GetTarget() != doomguard->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != doomguard)
|
||||||
return Attack(doomguard);
|
return Attack(doomguard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -971,7 +971,7 @@ bool AzgalorRangedDpsPrioritizeDoomguardsAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "star", azgalor);
|
SetRtiTarget(botAI, "star", azgalor);
|
||||||
|
|
||||||
if (bot->GetTarget() != azgalor->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != azgalor)
|
||||||
return Attack(azgalor);
|
return Attack(azgalor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1007,7 +1007,7 @@ bool ArchimondeMoveBossToInitialPositionAction::Execute(Event /*event*/)
|
|||||||
if (!archimonde)
|
if (!archimonde)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetVictim() != archimonde)
|
if (AI_VALUE(Unit*, "current target") != archimonde)
|
||||||
return Attack(archimonde);
|
return Attack(archimonde);
|
||||||
|
|
||||||
if (archimonde->GetVictim() == bot && bot->IsWithinMeleeRange(archimonde) &&
|
if (archimonde->GetVictim() == bot && bot->IsWithinMeleeRange(archimonde) &&
|
||||||
|
|||||||
@ -50,11 +50,9 @@ bool AttumenTheHuntsmanMarkTargetAction::Execute(Event /*event*/)
|
|||||||
|
|
||||||
SetRtiTarget(botAI, "star", attumenMounted);
|
SetRtiTarget(botAI, "star", attumenMounted);
|
||||||
|
|
||||||
if (bot->GetTarget() != attumenMounted->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != attumenMounted)
|
||||||
{
|
|
||||||
bot->SetTarget(attumenMounted->GetGUID());
|
|
||||||
return Attack(attumenMounted);
|
return Attack(attumenMounted);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (Unit* midnight = AI_VALUE2(Unit*, "find target", "midnight"))
|
else if (Unit* midnight = AI_VALUE2(Unit*, "find target", "midnight"))
|
||||||
{
|
{
|
||||||
@ -65,13 +63,10 @@ bool AttumenTheHuntsmanMarkTargetAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "star", midnight);
|
SetRtiTarget(botAI, "star", midnight);
|
||||||
|
|
||||||
if (bot->GetTarget() != midnight->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != midnight)
|
||||||
{
|
|
||||||
bot->SetTarget(midnight->GetGUID());
|
|
||||||
return Attack(midnight);
|
return Attack(midnight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -90,7 +85,7 @@ bool AttumenTheHuntsmanSplitBossesAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithSquare(bot, attumen);
|
MarkTargetWithSquare(bot, attumen);
|
||||||
SetRtiTarget(botAI, "square", attumen);
|
SetRtiTarget(botAI, "square", attumen);
|
||||||
|
|
||||||
if (bot->GetVictim() != attumen)
|
if (AI_VALUE(Unit*, "current target") != attumen)
|
||||||
return Attack(attumen);
|
return Attack(attumen);
|
||||||
|
|
||||||
if (attumen->GetVictim() == bot && midnight->GetVictim() != bot)
|
if (attumen->GetVictim() == bot && midnight->GetVictim() != bot)
|
||||||
@ -162,7 +157,7 @@ bool MoroesMainTankAttackBossAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithCircle(bot, moroes);
|
MarkTargetWithCircle(bot, moroes);
|
||||||
SetRtiTarget(botAI, "circle", moroes);
|
SetRtiTarget(botAI, "circle", moroes);
|
||||||
|
|
||||||
if (bot->GetVictim() != moroes)
|
if (AI_VALUE(Unit*, "current target") != moroes)
|
||||||
return Attack(moroes);
|
return Attack(moroes);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -200,7 +195,7 @@ bool MaidenOfVirtueMoveBossToHealerAction::Execute(Event /*event*/)
|
|||||||
if (!maiden)
|
if (!maiden)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetVictim() != maiden)
|
if (AI_VALUE(Unit*, "current target") != maiden)
|
||||||
return Attack(maiden);
|
return Attack(maiden);
|
||||||
|
|
||||||
Unit* healer = nullptr;
|
Unit* healer = nullptr;
|
||||||
@ -294,7 +289,7 @@ bool BigBadWolfPositionBossAction::Execute(Event /*event*/)
|
|||||||
if (!wolf)
|
if (!wolf)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetVictim() != wolf)
|
if (AI_VALUE(Unit*, "current target") != wolf)
|
||||||
return Attack(wolf);
|
return Attack(wolf);
|
||||||
|
|
||||||
if (wolf->GetVictim() == bot)
|
if (wolf->GetVictim() == bot)
|
||||||
@ -425,7 +420,7 @@ bool TheCuratorPositionBossAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithCircle(bot, curator);
|
MarkTargetWithCircle(bot, curator);
|
||||||
SetRtiTarget(botAI, "circle", curator);
|
SetRtiTarget(botAI, "circle", curator);
|
||||||
|
|
||||||
if (bot->GetVictim() != curator)
|
if (AI_VALUE(Unit*, "current target") != curator)
|
||||||
return Attack(curator);
|
return Attack(curator);
|
||||||
|
|
||||||
if (curator->GetVictim() == bot)
|
if (curator->GetVictim() == bot)
|
||||||
@ -1193,7 +1188,7 @@ bool PrinceMalchezaarMainTankMovementAction::Execute(Event /*event*/)
|
|||||||
if (!malchezaar)
|
if (!malchezaar)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetVictim() != malchezaar)
|
if (AI_VALUE(Unit*, "current target") != malchezaar)
|
||||||
return Attack(malchezaar);
|
return Attack(malchezaar);
|
||||||
|
|
||||||
std::vector<Unit*> infernals = GetSpawnedInfernals(botAI);
|
std::vector<Unit*> infernals = GetSpawnedInfernals(botAI);
|
||||||
@ -1261,7 +1256,7 @@ bool NightbaneGroundPhasePositionBossAction::Execute(Event /*event*/)
|
|||||||
|
|
||||||
MarkTargetWithSkull(bot, nightbane);
|
MarkTargetWithSkull(bot, nightbane);
|
||||||
|
|
||||||
if (bot->GetVictim() != nightbane)
|
if (AI_VALUE(Unit*, "current target") != nightbane)
|
||||||
return Attack(nightbane);
|
return Attack(nightbane);
|
||||||
|
|
||||||
const ObjectGuid botGuid = bot->GetGUID();
|
const ObjectGuid botGuid = bot->GetGUID();
|
||||||
@ -1400,8 +1395,7 @@ bool NightbaneFlightPhaseMovementAction::Execute(Event /*event*/)
|
|||||||
|
|
||||||
MarkTargetWithMoon(bot, nightbane);
|
MarkTargetWithMoon(bot, nightbane);
|
||||||
|
|
||||||
Unit* botTarget = botAI->GetUnit(bot->GetTarget());
|
if (AI_VALUE(Unit*, "current target") == nightbane)
|
||||||
if (botTarget && botTarget == nightbane)
|
|
||||||
{
|
{
|
||||||
bot->AttackStop();
|
bot->AttackStop();
|
||||||
bot->InterruptNonMeleeSpells(true);
|
bot->InterruptNonMeleeSpells(true);
|
||||||
|
|||||||
@ -61,7 +61,7 @@ bool MagtheridonMainTankAttackFirstThreeChannelersAction::Execute(Event /*event*
|
|||||||
|
|
||||||
SetRtiTarget(botAI, rtiName, currentTarget);
|
SetRtiTarget(botAI, rtiName, currentTarget);
|
||||||
|
|
||||||
if (currentTarget && bot->GetVictim() != currentTarget)
|
if (currentTarget && AI_VALUE(Unit*, "current target") != currentTarget)
|
||||||
return Attack(currentTarget);
|
return Attack(currentTarget);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -76,7 +76,7 @@ bool MagtheridonFirstAssistTankAttackNWChannelerAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithDiamond(bot, channelerDiamond);
|
MarkTargetWithDiamond(bot, channelerDiamond);
|
||||||
SetRtiTarget(botAI, "diamond", channelerDiamond);
|
SetRtiTarget(botAI, "diamond", channelerDiamond);
|
||||||
|
|
||||||
if (bot->GetVictim() != channelerDiamond)
|
if (AI_VALUE(Unit*, "current target") != channelerDiamond)
|
||||||
return Attack(channelerDiamond);
|
return Attack(channelerDiamond);
|
||||||
|
|
||||||
if (channelerDiamond->GetVictim() == bot)
|
if (channelerDiamond->GetVictim() == bot)
|
||||||
@ -109,7 +109,7 @@ bool MagtheridonSecondAssistTankAttackNEChannelerAction::Execute(Event /*event*/
|
|||||||
MarkTargetWithTriangle(bot, channelerTriangle);
|
MarkTargetWithTriangle(bot, channelerTriangle);
|
||||||
SetRtiTarget(botAI, "triangle", channelerTriangle);
|
SetRtiTarget(botAI, "triangle", channelerTriangle);
|
||||||
|
|
||||||
if (bot->GetVictim() != channelerTriangle)
|
if (AI_VALUE(Unit*, "current target") != channelerTriangle)
|
||||||
return Attack(channelerTriangle);
|
return Attack(channelerTriangle);
|
||||||
|
|
||||||
if (channelerTriangle->GetVictim() == bot)
|
if (channelerTriangle->GetVictim() == bot)
|
||||||
@ -219,7 +219,7 @@ bool MagtheridonAssignDPSPriorityAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "square", channelerSquare);
|
SetRtiTarget(botAI, "square", channelerSquare);
|
||||||
|
|
||||||
if (bot->GetTarget() != channelerSquare->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != channelerSquare)
|
||||||
return Attack(channelerSquare);
|
return Attack(channelerSquare);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -230,7 +230,7 @@ bool MagtheridonAssignDPSPriorityAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "star", channelerStar);
|
SetRtiTarget(botAI, "star", channelerStar);
|
||||||
|
|
||||||
if (bot->GetTarget() != channelerStar->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != channelerStar)
|
||||||
return Attack(channelerStar);
|
return Attack(channelerStar);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -241,7 +241,7 @@ bool MagtheridonAssignDPSPriorityAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "circle", channelerCircle);
|
SetRtiTarget(botAI, "circle", channelerCircle);
|
||||||
|
|
||||||
if (bot->GetTarget() != channelerCircle->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != channelerCircle)
|
||||||
return Attack(channelerCircle);
|
return Attack(channelerCircle);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -252,7 +252,7 @@ bool MagtheridonAssignDPSPriorityAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "diamond", channelerDiamond);
|
SetRtiTarget(botAI, "diamond", channelerDiamond);
|
||||||
|
|
||||||
if (bot->GetTarget() != channelerDiamond->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != channelerDiamond)
|
||||||
return Attack(channelerDiamond);
|
return Attack(channelerDiamond);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -263,7 +263,7 @@ bool MagtheridonAssignDPSPriorityAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "triangle", channelerTriangle);
|
SetRtiTarget(botAI, "triangle", channelerTriangle);
|
||||||
|
|
||||||
if (bot->GetTarget() != channelerTriangle->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != channelerTriangle)
|
||||||
return Attack(channelerTriangle);
|
return Attack(channelerTriangle);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -276,7 +276,7 @@ bool MagtheridonAssignDPSPriorityAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "cross", magtheridon);
|
SetRtiTarget(botAI, "cross", magtheridon);
|
||||||
|
|
||||||
if (bot->GetTarget() != magtheridon->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != magtheridon)
|
||||||
return Attack(magtheridon);
|
return Attack(magtheridon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,7 +347,7 @@ bool MagtheridonMainTankPositionBossAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithCross(bot, magtheridon);
|
MarkTargetWithCross(bot, magtheridon);
|
||||||
SetRtiTarget(botAI, "cross", magtheridon);
|
SetRtiTarget(botAI, "cross", magtheridon);
|
||||||
|
|
||||||
if (bot->GetVictim() != magtheridon)
|
if (AI_VALUE(Unit*, "current target") != magtheridon)
|
||||||
return Attack(magtheridon);
|
return Attack(magtheridon);
|
||||||
|
|
||||||
if (magtheridon->GetVictim() == bot)
|
if (magtheridon->GetVictim() == bot)
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
#include "RaidSSCStrategy.h"
|
#include "RaidSSCStrategy.h"
|
||||||
#include "RaidTempestKeepStrategy.h"
|
#include "RaidTempestKeepStrategy.h"
|
||||||
#include "RaidHyjalSummitStrategy.h"
|
#include "RaidHyjalSummitStrategy.h"
|
||||||
|
#include "RaidBlackTempleStrategy.h"
|
||||||
#include "RaidZulAmanStrategy.h"
|
#include "RaidZulAmanStrategy.h"
|
||||||
#include "RaidOsStrategy.h"
|
#include "RaidOsStrategy.h"
|
||||||
#include "RaidEoEStrategy.h"
|
#include "RaidEoEStrategy.h"
|
||||||
@ -35,6 +36,7 @@ public:
|
|||||||
creators["ssc"] = &RaidStrategyContext::ssc;
|
creators["ssc"] = &RaidStrategyContext::ssc;
|
||||||
creators["tempestkeep"] = &RaidStrategyContext::tempestkeep;
|
creators["tempestkeep"] = &RaidStrategyContext::tempestkeep;
|
||||||
creators["hyjal"] = &RaidStrategyContext::hyjal;
|
creators["hyjal"] = &RaidStrategyContext::hyjal;
|
||||||
|
creators["blacktemple"] = &RaidStrategyContext::blacktemple;
|
||||||
creators["zulaman"] = &RaidStrategyContext::zulaman;
|
creators["zulaman"] = &RaidStrategyContext::zulaman;
|
||||||
creators["wotlk-os"] = &RaidStrategyContext::wotlk_os;
|
creators["wotlk-os"] = &RaidStrategyContext::wotlk_os;
|
||||||
creators["wotlk-eoe"] = &RaidStrategyContext::wotlk_eoe;
|
creators["wotlk-eoe"] = &RaidStrategyContext::wotlk_eoe;
|
||||||
@ -55,6 +57,7 @@ private:
|
|||||||
static Strategy* ssc(PlayerbotAI* botAI) { return new RaidSSCStrategy(botAI); }
|
static Strategy* ssc(PlayerbotAI* botAI) { return new RaidSSCStrategy(botAI); }
|
||||||
static Strategy* tempestkeep(PlayerbotAI* botAI) { return new RaidTempestKeepStrategy(botAI); }
|
static Strategy* tempestkeep(PlayerbotAI* botAI) { return new RaidTempestKeepStrategy(botAI); }
|
||||||
static Strategy* hyjal(PlayerbotAI* botAI) { return new RaidHyjalSummitStrategy(botAI); }
|
static Strategy* hyjal(PlayerbotAI* botAI) { return new RaidHyjalSummitStrategy(botAI); }
|
||||||
|
static Strategy* blacktemple(PlayerbotAI* botAI) { return new RaidBlackTempleStrategy(botAI); }
|
||||||
static Strategy* zulaman(PlayerbotAI* botAI) { return new RaidZulAmanStrategy(botAI); }
|
static Strategy* zulaman(PlayerbotAI* botAI) { return new RaidZulAmanStrategy(botAI); }
|
||||||
static Strategy* wotlk_os(PlayerbotAI* botAI) { return new RaidOsStrategy(botAI); }
|
static Strategy* wotlk_os(PlayerbotAI* botAI) { return new RaidOsStrategy(botAI); }
|
||||||
static Strategy* wotlk_eoe(PlayerbotAI* botAI) { return new RaidEoEStrategy(botAI); }
|
static Strategy* wotlk_eoe(PlayerbotAI* botAI) { return new RaidEoEStrategy(botAI); }
|
||||||
|
|||||||
@ -153,7 +153,7 @@ bool HydrossTheUnstablePositionFrostTankAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithSquare(bot, hydross);
|
MarkTargetWithSquare(bot, hydross);
|
||||||
SetRtiTarget(botAI, "square", hydross);
|
SetRtiTarget(botAI, "square", hydross);
|
||||||
|
|
||||||
if (bot->GetTarget() != hydross->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != hydross)
|
||||||
return Attack(hydross);
|
return Attack(hydross);
|
||||||
|
|
||||||
if (hydross->GetVictim() == bot && bot->IsWithinMeleeRange(hydross))
|
if (hydross->GetVictim() == bot && bot->IsWithinMeleeRange(hydross))
|
||||||
@ -233,7 +233,7 @@ bool HydrossTheUnstablePositionNatureTankAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithTriangle(bot, hydross);
|
MarkTargetWithTriangle(bot, hydross);
|
||||||
SetRtiTarget(botAI, "triangle", hydross);
|
SetRtiTarget(botAI, "triangle", hydross);
|
||||||
|
|
||||||
if (bot->GetTarget() != hydross->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != hydross)
|
||||||
return Attack(hydross);
|
return Attack(hydross);
|
||||||
|
|
||||||
if (hydross->GetVictim() == bot && bot->IsWithinMeleeRange(hydross))
|
if (hydross->GetVictim() == bot && bot->IsWithinMeleeRange(hydross))
|
||||||
@ -308,7 +308,7 @@ bool HydrossTheUnstablePrioritizeElementalAddsAction::Execute(Event /*event*/)
|
|||||||
|
|
||||||
SetRtiTarget(botAI, "skull", waterElemental);
|
SetRtiTarget(botAI, "skull", waterElemental);
|
||||||
|
|
||||||
if (bot->GetTarget() != waterElemental->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != waterElemental)
|
||||||
return Attack(waterElemental);
|
return Attack(waterElemental);
|
||||||
}
|
}
|
||||||
else if (Unit* natureElemental = GetFirstAliveUnitByEntry(botAI, NPC_TAINTED_SPAWN_OF_HYDROSS))
|
else if (Unit* natureElemental = GetFirstAliveUnitByEntry(botAI, NPC_TAINTED_SPAWN_OF_HYDROSS))
|
||||||
@ -318,7 +318,7 @@ bool HydrossTheUnstablePrioritizeElementalAddsAction::Execute(Event /*event*/)
|
|||||||
|
|
||||||
SetRtiTarget(botAI, "skull", natureElemental);
|
SetRtiTarget(botAI, "skull", natureElemental);
|
||||||
|
|
||||||
if (bot->GetTarget() != natureElemental->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != natureElemental)
|
||||||
return Attack(natureElemental);
|
return Attack(natureElemental);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +518,7 @@ bool TheLurkerBelowPositionMainTankAction::Execute(Event /*event*/)
|
|||||||
if (!lurker)
|
if (!lurker)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetTarget() != lurker->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != lurker)
|
||||||
return Attack(lurker);
|
return Attack(lurker);
|
||||||
|
|
||||||
const Position& position = LURKER_MAIN_TANK_POSITION;
|
const Position& position = LURKER_MAIN_TANK_POSITION;
|
||||||
@ -639,7 +639,7 @@ bool TheLurkerBelowTanksPickUpAddsAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithIcon(bot, guardian, rtiIndices[i]);
|
MarkTargetWithIcon(bot, guardian, rtiIndices[i]);
|
||||||
SetRtiTarget(botAI, rtiNames[i], guardian);
|
SetRtiTarget(botAI, rtiNames[i], guardian);
|
||||||
|
|
||||||
if (bot->GetVictim() != guardian)
|
if (AI_VALUE(Unit*, "current target") != guardian)
|
||||||
return Attack(guardian);
|
return Attack(guardian);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -841,7 +841,7 @@ bool LeotherasTheBlindDestroyInnerDemonAction::Execute(Event /*event*/)
|
|||||||
|
|
||||||
// Roles without a strategy need to affirmatively attack their Inner Demons
|
// Roles without a strategy need to affirmatively attack their Inner Demons
|
||||||
// Because DPS assist is disabled via multipliers
|
// Because DPS assist is disabled via multipliers
|
||||||
if (bot->GetTarget() != innerDemon->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != innerDemon)
|
||||||
return Attack(innerDemon);
|
return Attack(innerDemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,7 +978,7 @@ bool LeotherasTheBlindFinalPhaseAssignDpsPriorityAction::Execute(Event /*event*/
|
|||||||
MarkTargetWithStar(bot, leotherasHuman);
|
MarkTargetWithStar(bot, leotherasHuman);
|
||||||
SetRtiTarget(botAI, "star", leotherasHuman);
|
SetRtiTarget(botAI, "star", leotherasHuman);
|
||||||
|
|
||||||
if (bot->GetTarget() != leotherasHuman->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != leotherasHuman)
|
||||||
return Attack(leotherasHuman);
|
return Attack(leotherasHuman);
|
||||||
|
|
||||||
Unit* leotherasDemon = GetPhase3LeotherasDemon(bot);
|
Unit* leotherasDemon = GetPhase3LeotherasDemon(bot);
|
||||||
@ -1092,7 +1092,7 @@ bool FathomLordKarathressMainTankPositionBossAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithTriangle(bot, karathress);
|
MarkTargetWithTriangle(bot, karathress);
|
||||||
SetRtiTarget(botAI, "triangle", karathress);
|
SetRtiTarget(botAI, "triangle", karathress);
|
||||||
|
|
||||||
if (bot->GetTarget() != karathress->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != karathress)
|
||||||
return Attack(karathress);
|
return Attack(karathress);
|
||||||
|
|
||||||
if (karathress->GetVictim() == bot && bot->IsWithinMeleeRange(karathress))
|
if (karathress->GetVictim() == bot && bot->IsWithinMeleeRange(karathress))
|
||||||
@ -1128,7 +1128,7 @@ bool FathomLordKarathressFirstAssistTankPositionCaribdisAction::Execute(Event /*
|
|||||||
MarkTargetWithDiamond(bot, caribdis);
|
MarkTargetWithDiamond(bot, caribdis);
|
||||||
SetRtiTarget(botAI, "diamond", caribdis);
|
SetRtiTarget(botAI, "diamond", caribdis);
|
||||||
|
|
||||||
if (bot->GetTarget() != caribdis->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != caribdis)
|
||||||
return Attack(caribdis);
|
return Attack(caribdis);
|
||||||
|
|
||||||
if (caribdis->GetVictim() == bot)
|
if (caribdis->GetVictim() == bot)
|
||||||
@ -1163,7 +1163,7 @@ bool FathomLordKarathressSecondAssistTankPositionSharkkisAction::Execute(Event /
|
|||||||
MarkTargetWithStar(bot, sharkkis);
|
MarkTargetWithStar(bot, sharkkis);
|
||||||
SetRtiTarget(botAI, "star", sharkkis);
|
SetRtiTarget(botAI, "star", sharkkis);
|
||||||
|
|
||||||
if (bot->GetTarget() != sharkkis->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != sharkkis)
|
||||||
return Attack(sharkkis);
|
return Attack(sharkkis);
|
||||||
|
|
||||||
if (sharkkis->GetVictim() == bot && bot->IsWithinMeleeRange(sharkkis))
|
if (sharkkis->GetVictim() == bot && bot->IsWithinMeleeRange(sharkkis))
|
||||||
@ -1198,7 +1198,7 @@ bool FathomLordKarathressThirdAssistTankPositionTidalvessAction::Execute(Event /
|
|||||||
MarkTargetWithCircle(bot, tidalvess);
|
MarkTargetWithCircle(bot, tidalvess);
|
||||||
SetRtiTarget(botAI, "circle", tidalvess);
|
SetRtiTarget(botAI, "circle", tidalvess);
|
||||||
|
|
||||||
if (bot->GetTarget() != tidalvess->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != tidalvess)
|
||||||
return Attack(tidalvess);
|
return Attack(tidalvess);
|
||||||
|
|
||||||
if (tidalvess->GetVictim() == bot && bot->IsWithinMeleeRange(tidalvess))
|
if (tidalvess->GetVictim() == bot && bot->IsWithinMeleeRange(tidalvess))
|
||||||
@ -1322,7 +1322,7 @@ bool FathomLordKarathressAssignDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithSkull(bot, totem);
|
MarkTargetWithSkull(bot, totem);
|
||||||
SetRtiTarget(botAI, "skull", totem);
|
SetRtiTarget(botAI, "skull", totem);
|
||||||
|
|
||||||
if (bot->GetTarget() != totem->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != totem)
|
||||||
return Attack(totem);
|
return Attack(totem);
|
||||||
|
|
||||||
// Direct movement order due to path between Sharkkis and totem sometimes being screwy
|
// Direct movement order due to path between Sharkkis and totem sometimes being screwy
|
||||||
@ -1343,7 +1343,7 @@ bool FathomLordKarathressAssignDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithCircle(bot, tidalvess);
|
MarkTargetWithCircle(bot, tidalvess);
|
||||||
SetRtiTarget(botAI, "circle", tidalvess);
|
SetRtiTarget(botAI, "circle", tidalvess);
|
||||||
|
|
||||||
if (bot->GetTarget() != tidalvess->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != tidalvess)
|
||||||
return Attack(tidalvess);
|
return Attack(tidalvess);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1363,7 +1363,7 @@ bool FathomLordKarathressAssignDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
position.GetPositionZ(), 8.0f, MovementPriority::MOVEMENT_COMBAT);
|
position.GetPositionZ(), 8.0f, MovementPriority::MOVEMENT_COMBAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bot->GetTarget() != caribdis->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != caribdis)
|
||||||
return Attack(caribdis);
|
return Attack(caribdis);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1376,7 +1376,7 @@ bool FathomLordKarathressAssignDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithStar(bot, sharkkis);
|
MarkTargetWithStar(bot, sharkkis);
|
||||||
SetRtiTarget(botAI, "star", sharkkis);
|
SetRtiTarget(botAI, "star", sharkkis);
|
||||||
|
|
||||||
if (bot->GetTarget() != sharkkis->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != sharkkis)
|
||||||
return Attack(sharkkis);
|
return Attack(sharkkis);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1389,7 +1389,7 @@ bool FathomLordKarathressAssignDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithCross(bot, fathomSporebat);
|
MarkTargetWithCross(bot, fathomSporebat);
|
||||||
SetRtiTarget(botAI, "cross", fathomSporebat);
|
SetRtiTarget(botAI, "cross", fathomSporebat);
|
||||||
|
|
||||||
if (bot->GetTarget() != fathomSporebat->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != fathomSporebat)
|
||||||
return Attack(fathomSporebat);
|
return Attack(fathomSporebat);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1401,7 +1401,7 @@ bool FathomLordKarathressAssignDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithSquare(bot, fathomLurker);
|
MarkTargetWithSquare(bot, fathomLurker);
|
||||||
SetRtiTarget(botAI, "square", fathomLurker);
|
SetRtiTarget(botAI, "square", fathomLurker);
|
||||||
|
|
||||||
if (bot->GetTarget() != fathomLurker->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != fathomLurker)
|
||||||
return Attack(fathomLurker);
|
return Attack(fathomLurker);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1414,7 +1414,7 @@ bool FathomLordKarathressAssignDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithTriangle(bot, karathress);
|
MarkTargetWithTriangle(bot, karathress);
|
||||||
SetRtiTarget(botAI, "triangle", karathress);
|
SetRtiTarget(botAI, "triangle", karathress);
|
||||||
|
|
||||||
if (bot->GetTarget() != karathress->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != karathress)
|
||||||
return Attack(karathress);
|
return Attack(karathress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1460,7 +1460,7 @@ bool MorogrimTidewalkerMoveBossToTankPositionAction::Execute(Event /*event*/)
|
|||||||
if (!tidewalker)
|
if (!tidewalker)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetTarget() != tidewalker->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != tidewalker)
|
||||||
return Attack(tidewalker);
|
return Attack(tidewalker);
|
||||||
|
|
||||||
if (tidewalker->GetVictim() == bot && bot->IsWithinMeleeRange(tidewalker))
|
if (tidewalker->GetVictim() == bot && bot->IsWithinMeleeRange(tidewalker))
|
||||||
@ -1610,7 +1610,7 @@ bool LadyVashjMainTankPositionBossAction::Execute(Event /*event*/)
|
|||||||
if (!vashj)
|
if (!vashj)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetTarget() != vashj->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != vashj)
|
||||||
return Attack(vashj);
|
return Attack(vashj);
|
||||||
|
|
||||||
if (vashj->GetVictim() == bot && bot->IsWithinMeleeRange(vashj))
|
if (vashj->GetVictim() == bot && bot->IsWithinMeleeRange(vashj))
|
||||||
@ -1929,7 +1929,8 @@ bool LadyVashjAssignPhase2AndPhase3DpsPriorityAction::Execute(Event /*event*/)
|
|||||||
currentTarget = nullptr;
|
currentTarget = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target && currentTarget != target && bot->GetTarget() != target->GetGUID())
|
if (target && currentTarget != target &&
|
||||||
|
AI_VALUE(Unit*, "current target") != target)
|
||||||
return Attack(target);
|
return Attack(target);
|
||||||
|
|
||||||
// If bots have wandered too far from the center, move them back
|
// If bots have wandered too far from the center, move them back
|
||||||
@ -1984,7 +1985,8 @@ bool LadyVashjTankAttackAndMoveAwayStriderAction::Execute(Event /*event*/)
|
|||||||
if (!bot->HasAura(SPELL_FEAR_WARD))
|
if (!bot->HasAura(SPELL_FEAR_WARD))
|
||||||
bot->AddAura(SPELL_FEAR_WARD, bot);
|
bot->AddAura(SPELL_FEAR_WARD, bot);
|
||||||
|
|
||||||
if (botAI->IsAssistTankOfIndex(bot, 0, true) && bot->GetTarget() != strider->GetGUID())
|
if (botAI->IsAssistTankOfIndex(bot, 0, true) &&
|
||||||
|
AI_VALUE(Unit*, "current target") != strider)
|
||||||
return Attack(strider);
|
return Attack(strider);
|
||||||
|
|
||||||
float currentDistance = bot->GetExactDist2d(vashj);
|
float currentDistance = bot->GetExactDist2d(vashj);
|
||||||
@ -2040,7 +2042,7 @@ bool LadyVashjTeleportToTaintedElementalAction::Execute(Event /*event*/)
|
|||||||
tainted->GetPositionZ(), tainted->GetOrientation());
|
tainted->GetPositionZ(), tainted->GetOrientation());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bot->GetTarget() != tainted->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != tainted)
|
||||||
{
|
{
|
||||||
MarkTargetWithStar(bot, tainted);
|
MarkTargetWithStar(bot, tainted);
|
||||||
SetRtiTarget(botAI, "star", tainted);
|
SetRtiTarget(botAI, "star", tainted);
|
||||||
|
|||||||
@ -752,7 +752,7 @@ float LadyVashjDisableAutomaticTargetingAndMovementModifier::GetValue(Action *ac
|
|||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
Unit* enchanted = AI_VALUE2(Unit*, "find target", "enchanted elemental");
|
Unit* enchanted = AI_VALUE2(Unit*, "find target", "enchanted elemental");
|
||||||
if (enchanted && bot->GetVictim() == enchanted &&
|
if (enchanted && AI_VALUE(Unit*, "current target") == enchanted &&
|
||||||
dynamic_cast<CastDebuffSpellOnAttackerAction*>(action))
|
dynamic_cast<CastDebuffSpellOnAttackerAction*>(action))
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
@ -772,7 +772,7 @@ float LadyVashjDisableAutomaticTargetingAndMovementModifier::GetValue(Action *ac
|
|||||||
dynamic_cast<FleeAction*>(action))
|
dynamic_cast<FleeAction*>(action))
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
if (enchanted && bot->GetVictim() == enchanted &&
|
if (enchanted && AI_VALUE(Unit*, "current target") == enchanted &&
|
||||||
dynamic_cast<CastDebuffSpellOnAttackerAction*>(action))
|
dynamic_cast<CastDebuffSpellOnAttackerAction*>(action))
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -209,35 +209,24 @@ namespace SerpentShrineCavernHelpers
|
|||||||
{
|
{
|
||||||
Unit* vashj =
|
Unit* vashj =
|
||||||
botAI->GetAiObjectContext()->GetValue<Unit*>("find target", "lady vashj")->Get();
|
botAI->GetAiObjectContext()->GetValue<Unit*>("find target", "lady vashj")->Get();
|
||||||
if (!vashj)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Creature* vashjCreature = vashj->ToCreature();
|
return vashj && vashj->GetHealthPct() > 70.0f;
|
||||||
return vashjCreature && vashjCreature->GetHealthPct() > 70.0f &&
|
|
||||||
vashjCreature->GetReactState() != REACT_PASSIVE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsLadyVashjInPhase2(PlayerbotAI* botAI)
|
bool IsLadyVashjInPhase2(PlayerbotAI* botAI)
|
||||||
{
|
{
|
||||||
Unit* vashj =
|
Unit* vashj =
|
||||||
botAI->GetAiObjectContext()->GetValue<Unit*>("find target", "lady vashj")->Get();
|
botAI->GetAiObjectContext()->GetValue<Unit*>("find target", "lady vashj")->Get();
|
||||||
if (!vashj)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Creature* vashjCreature = vashj->ToCreature();
|
return vashj && vashj->GetHealthPct() <= 70.0f && vashj->HasAura(SPELL_MAGIC_BARRIER);
|
||||||
return vashjCreature && vashjCreature->GetReactState() == REACT_PASSIVE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsLadyVashjInPhase3(PlayerbotAI* botAI)
|
bool IsLadyVashjInPhase3(PlayerbotAI* botAI)
|
||||||
{
|
{
|
||||||
Unit* vashj =
|
Unit* vashj =
|
||||||
botAI->GetAiObjectContext()->GetValue<Unit*>("find target", "lady vashj")->Get();
|
botAI->GetAiObjectContext()->GetValue<Unit*>("find target", "lady vashj")->Get();
|
||||||
if (!vashj)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Creature* vashjCreature = vashj->ToCreature();
|
return vashj && vashj->GetHealthPct() <= 70.0f && !vashj->HasAura(SPELL_MAGIC_BARRIER);
|
||||||
return vashjCreature && vashjCreature->GetHealthPct() <= 50.0f &&
|
|
||||||
vashjCreature->GetReactState() != REACT_PASSIVE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValidLadyVashjCombatNpc(Unit* unit, PlayerbotAI* botAI)
|
bool IsValidLadyVashjCombatNpc(Unit* unit, PlayerbotAI* botAI)
|
||||||
|
|||||||
@ -48,6 +48,7 @@ namespace SerpentShrineCavernHelpers
|
|||||||
|
|
||||||
// Lady Vashj <Coilfang Matron>
|
// Lady Vashj <Coilfang Matron>
|
||||||
SPELL_FEAR_WARD = 6346,
|
SPELL_FEAR_WARD = 6346,
|
||||||
|
SPELL_MAGIC_BARRIER = 38112,
|
||||||
SPELL_POISON_BOLT = 38253,
|
SPELL_POISON_BOLT = 38253,
|
||||||
SPELL_STATIC_CHARGE = 38280,
|
SPELL_STATIC_CHARGE = 38280,
|
||||||
SPELL_ENTANGLE = 38316,
|
SPELL_ENTANGLE = 38316,
|
||||||
|
|||||||
@ -93,7 +93,7 @@ bool AlarBossTanksMoveBetweenPlatformsAction::PositionMainTank(
|
|||||||
MovementPriority::MOVEMENT_COMBAT, true, false);
|
MovementPriority::MOVEMENT_COMBAT, true, false);
|
||||||
}
|
}
|
||||||
else if ((locationIndex == PLATFORM_0_IDX || locationIndex == PLATFORM_2_IDX) &&
|
else if ((locationIndex == PLATFORM_0_IDX || locationIndex == PLATFORM_2_IDX) &&
|
||||||
bot->GetTarget() != alar->GetGUID())
|
AI_VALUE(Unit*, "current target") != alar)
|
||||||
return Attack(alar);
|
return Attack(alar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ bool AlarBossTanksMoveBetweenPlatformsAction::PositionAssistTank(
|
|||||||
MovementPriority::MOVEMENT_COMBAT, true, false);
|
MovementPriority::MOVEMENT_COMBAT, true, false);
|
||||||
}
|
}
|
||||||
else if ((locationIndex == PLATFORM_1_IDX || locationIndex == PLATFORM_3_IDX) &&
|
else if ((locationIndex == PLATFORM_1_IDX || locationIndex == PLATFORM_3_IDX) &&
|
||||||
bot->GetTarget() != alar->GetGUID())
|
AI_VALUE(Unit*, "current target") != alar)
|
||||||
return Attack(alar);
|
return Attack(alar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ bool AlarMeleeDpsMoveBetweenPlatformsAction::Execute(Event /*event*/)
|
|||||||
MovementPriority::MOVEMENT_COMBAT, true, false);
|
MovementPriority::MOVEMENT_COMBAT, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bot->GetTarget() != alar->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != alar)
|
||||||
return Attack(alar);
|
return Attack(alar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ bool AlarAssistTanksPickUpEmbersAction::HandlePhase1Embers(Unit* alar)
|
|||||||
MarkTargetWithSquare(bot, ember);
|
MarkTargetWithSquare(bot, ember);
|
||||||
SetRtiTarget(botAI, "square", ember);
|
SetRtiTarget(botAI, "square", ember);
|
||||||
|
|
||||||
if (bot->GetTarget() != ember->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != ember)
|
||||||
return Attack(ember);
|
return Attack(ember);
|
||||||
|
|
||||||
if (ember->GetVictim() == bot)
|
if (ember->GetVictim() == bot)
|
||||||
@ -286,7 +286,7 @@ bool AlarAssistTanksPickUpEmbersAction::HandlePhase2Embers()
|
|||||||
|
|
||||||
if (firstEmber->GetVictim() != bot)
|
if (firstEmber->GetVictim() != bot)
|
||||||
{
|
{
|
||||||
if (bot->GetTarget() != firstEmber->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != firstEmber)
|
||||||
return Attack(firstEmber);
|
return Attack(firstEmber);
|
||||||
|
|
||||||
return botAI->DoSpecificAction("taunt spell", Event(), true);
|
return botAI->DoSpecificAction("taunt spell", Event(), true);
|
||||||
@ -305,7 +305,7 @@ bool AlarAssistTanksPickUpEmbersAction::HandlePhase2Embers()
|
|||||||
|
|
||||||
if (secondEmber->GetVictim() != bot)
|
if (secondEmber->GetVictim() != bot)
|
||||||
{
|
{
|
||||||
if (bot->GetTarget() != secondEmber->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != secondEmber)
|
||||||
return Attack(secondEmber);
|
return Attack(secondEmber);
|
||||||
|
|
||||||
return botAI->DoSpecificAction("taunt spell", Event(), true);
|
return botAI->DoSpecificAction("taunt spell", Event(), true);
|
||||||
@ -336,7 +336,7 @@ bool AlarRangedDpsPrioritizeEmbersAction::Execute(Event /*event*/)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetRtiTarget(botAI, "square", firstEmber);
|
SetRtiTarget(botAI, "square", firstEmber);
|
||||||
if (bot->GetTarget() != firstEmber->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != firstEmber)
|
||||||
return Attack(firstEmber);
|
return Attack(firstEmber);
|
||||||
}
|
}
|
||||||
else if (secondEmber)
|
else if (secondEmber)
|
||||||
@ -349,13 +349,13 @@ bool AlarRangedDpsPrioritizeEmbersAction::Execute(Event /*event*/)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetRtiTarget(botAI, "circle", secondEmber);
|
SetRtiTarget(botAI, "circle", secondEmber);
|
||||||
if (bot->GetTarget() != secondEmber->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != secondEmber)
|
||||||
return Attack(secondEmber);
|
return Attack(secondEmber);
|
||||||
}
|
}
|
||||||
else if (Unit* alar = AI_VALUE2(Unit*, "find target", "al'ar"))
|
else if (Unit* alar = AI_VALUE2(Unit*, "find target", "al'ar"))
|
||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "star", alar);
|
SetRtiTarget(botAI, "star", alar);
|
||||||
if (bot->GetTarget() != alar->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != alar)
|
||||||
return Attack(alar);
|
return Attack(alar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,7 +469,7 @@ bool AlarSwapTanksOnBossAction::Execute(Event /*event*/)
|
|||||||
if (alar->GetHealth() == alar->GetMaxHealth())
|
if (alar->GetHealth() == alar->GetMaxHealth())
|
||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "star", alar);
|
SetRtiTarget(botAI, "star", alar);
|
||||||
if (bot->GetTarget() != alar->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != alar)
|
||||||
return Attack(alar);
|
return Attack(alar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,7 +477,7 @@ bool AlarSwapTanksOnBossAction::Execute(Event /*event*/)
|
|||||||
if (secondEmberTank && secondEmberTank != bot)
|
if (secondEmberTank && secondEmberTank != bot)
|
||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "star", alar);
|
SetRtiTarget(botAI, "star", alar);
|
||||||
if (bot->GetTarget() != alar->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != alar)
|
||||||
return Attack(alar);
|
return Attack(alar);
|
||||||
else if (alar->GetVictim() != bot)
|
else if (alar->GetVictim() != bot)
|
||||||
return botAI->DoSpecificAction("taunt spell", Event(), true);
|
return botAI->DoSpecificAction("taunt spell", Event(), true);
|
||||||
@ -555,7 +555,7 @@ bool AlarReturnToRoomCenterAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
constexpr float distFromCenter = 45.0f;
|
constexpr float distFromCenter = 45.0f;
|
||||||
const Position& center = ALAR_ROOM_CENTER;
|
const Position& center = ALAR_ROOM_CENTER;
|
||||||
if (bot->GetVictim() == nullptr &&
|
if (AI_VALUE(Unit*, "current target") == nullptr &&
|
||||||
bot->GetExactDist2d(center.GetPositionX(), center.GetPositionY()) > distFromCenter)
|
bot->GetExactDist2d(center.GetPositionX(), center.GetPositionY()) > distFromCenter)
|
||||||
{
|
{
|
||||||
return MoveInside(TEMPEST_KEEP_MAP_ID, center.GetPositionX(), center.GetPositionY(),
|
return MoveInside(TEMPEST_KEEP_MAP_ID, center.GetPositionX(), center.GetPositionY(),
|
||||||
@ -887,7 +887,7 @@ bool HighAstromancerSolarianTargetSolariumPriestsAction::Execute(Event /*event*/
|
|||||||
SetRtiTarget(botAI, "star", targetPriest);
|
SetRtiTarget(botAI, "star", targetPriest);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bot->GetTarget() != targetPriest->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != targetPriest)
|
||||||
return Attack(targetPriest);
|
return Attack(targetPriest);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1047,7 +1047,7 @@ bool KaelthasSunstriderMainTankPositionSanguinarAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithStar(bot, sanguinar);
|
MarkTargetWithStar(bot, sanguinar);
|
||||||
SetRtiTarget(botAI, "star", sanguinar);
|
SetRtiTarget(botAI, "star", sanguinar);
|
||||||
|
|
||||||
if (bot->GetTarget() != sanguinar->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != sanguinar)
|
||||||
return Attack(sanguinar);
|
return Attack(sanguinar);
|
||||||
|
|
||||||
if (sanguinar->GetVictim() == bot && bot->IsWithinMeleeRange(sanguinar))
|
if (sanguinar->GetVictim() == bot && bot->IsWithinMeleeRange(sanguinar))
|
||||||
@ -1090,7 +1090,7 @@ bool KaelthasSunstriderWarlockTankPositionCapernianAction::Execute(Event /*event
|
|||||||
MarkTargetWithCircle(bot, capernian);
|
MarkTargetWithCircle(bot, capernian);
|
||||||
SetRtiTarget(botAI, "circle", capernian);
|
SetRtiTarget(botAI, "circle", capernian);
|
||||||
|
|
||||||
if (bot->GetTarget() != capernian->GetGUID() &&
|
if (AI_VALUE(Unit*, "current target") != capernian &&
|
||||||
botAI->CanCastSpell("searing pain", capernian) &&
|
botAI->CanCastSpell("searing pain", capernian) &&
|
||||||
botAI->CastSpell("searing pain", capernian))
|
botAI->CastSpell("searing pain", capernian))
|
||||||
return true;
|
return true;
|
||||||
@ -1251,7 +1251,7 @@ bool KaelthasSunstriderFirstAssistTankPositionTelonicusAction::Execute(Event /*e
|
|||||||
MarkTargetWithTriangle(bot, telonicus);
|
MarkTargetWithTriangle(bot, telonicus);
|
||||||
SetRtiTarget(botAI, "triangle", telonicus);
|
SetRtiTarget(botAI, "triangle", telonicus);
|
||||||
|
|
||||||
if (bot->GetTarget() != telonicus->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != telonicus)
|
||||||
return Attack(telonicus);
|
return Attack(telonicus);
|
||||||
|
|
||||||
if (telonicus->GetVictim() == bot && bot->IsWithinMeleeRange(telonicus))
|
if (telonicus->GetVictim() == bot && bot->IsWithinMeleeRange(telonicus))
|
||||||
@ -1331,7 +1331,7 @@ bool KaelthasSunstriderAssignAdvisorDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithSquare(bot, thaladred);
|
MarkTargetWithSquare(bot, thaladred);
|
||||||
SetRtiTarget(botAI, "square", thaladred);
|
SetRtiTarget(botAI, "square", thaladred);
|
||||||
|
|
||||||
if (bot->GetTarget() != thaladred->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != thaladred)
|
||||||
return Attack(thaladred);
|
return Attack(thaladred);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1346,7 +1346,7 @@ bool KaelthasSunstriderAssignAdvisorDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "circle", capernian);
|
SetRtiTarget(botAI, "circle", capernian);
|
||||||
|
|
||||||
if (bot->GetTarget() != capernian->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != capernian)
|
||||||
return Attack(capernian);
|
return Attack(capernian);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1360,7 +1360,7 @@ bool KaelthasSunstriderAssignAdvisorDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "star", sanguinar);
|
SetRtiTarget(botAI, "star", sanguinar);
|
||||||
|
|
||||||
if (bot->GetTarget() != sanguinar->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != sanguinar)
|
||||||
return Attack(sanguinar);
|
return Attack(sanguinar);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1373,7 +1373,7 @@ bool KaelthasSunstriderAssignAdvisorDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
!telonicus->HasAura(SPELL_PERMANENT_FEIGN_DEATH))
|
!telonicus->HasAura(SPELL_PERMANENT_FEIGN_DEATH))
|
||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "triangle", telonicus);
|
SetRtiTarget(botAI, "triangle", telonicus);
|
||||||
if (bot->GetTarget() != telonicus->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != telonicus)
|
||||||
return Attack(telonicus);
|
return Attack(telonicus);
|
||||||
|
|
||||||
// Melee DPS need to stay at max-ish melee range behind Telonicus to avoid bombs
|
// Melee DPS need to stay at max-ish melee range behind Telonicus to avoid bombs
|
||||||
@ -1461,7 +1461,7 @@ bool KaelthasSunstriderAssignLegendaryWeaponDpsPriorityAction::Execute(Event /*e
|
|||||||
MarkTargetWithSkull(bot, staff);
|
MarkTargetWithSkull(bot, staff);
|
||||||
SetRtiTarget(botAI, "skull", staff);
|
SetRtiTarget(botAI, "skull", staff);
|
||||||
|
|
||||||
if (bot->GetTarget() != staff->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != staff)
|
||||||
return Attack(staff);
|
return Attack(staff);
|
||||||
}
|
}
|
||||||
// Priority 2: Cosmic Infuser (Skull)
|
// Priority 2: Cosmic Infuser (Skull)
|
||||||
@ -1470,7 +1470,7 @@ bool KaelthasSunstriderAssignLegendaryWeaponDpsPriorityAction::Execute(Event /*e
|
|||||||
MarkTargetWithSkull(bot, mace);
|
MarkTargetWithSkull(bot, mace);
|
||||||
SetRtiTarget(botAI, "skull", mace);
|
SetRtiTarget(botAI, "skull", mace);
|
||||||
|
|
||||||
if (bot->GetTarget() != mace->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != mace)
|
||||||
return Attack(mace);
|
return Attack(mace);
|
||||||
}
|
}
|
||||||
// Priority 3: Warp Slicer (Skull)
|
// Priority 3: Warp Slicer (Skull)
|
||||||
@ -1479,7 +1479,7 @@ bool KaelthasSunstriderAssignLegendaryWeaponDpsPriorityAction::Execute(Event /*e
|
|||||||
MarkTargetWithSkull(bot, sword);
|
MarkTargetWithSkull(bot, sword);
|
||||||
SetRtiTarget(botAI, "skull", sword);
|
SetRtiTarget(botAI, "skull", sword);
|
||||||
|
|
||||||
if (bot->GetTarget() != sword->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != sword)
|
||||||
return Attack(sword);
|
return Attack(sword);
|
||||||
}
|
}
|
||||||
// Priority 4: Infinity Blades (Skull)
|
// Priority 4: Infinity Blades (Skull)
|
||||||
@ -1488,7 +1488,7 @@ bool KaelthasSunstriderAssignLegendaryWeaponDpsPriorityAction::Execute(Event /*e
|
|||||||
MarkTargetWithSkull(bot, dagger);
|
MarkTargetWithSkull(bot, dagger);
|
||||||
SetRtiTarget(botAI, "skull", dagger);
|
SetRtiTarget(botAI, "skull", dagger);
|
||||||
|
|
||||||
if (bot->GetTarget() != dagger->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != dagger)
|
||||||
return Attack(dagger);
|
return Attack(dagger);
|
||||||
}
|
}
|
||||||
// Priority 5: Devastation - ranged only (Diamond--marked in other method by main tank)
|
// Priority 5: Devastation - ranged only (Diamond--marked in other method by main tank)
|
||||||
@ -1496,7 +1496,7 @@ bool KaelthasSunstriderAssignLegendaryWeaponDpsPriorityAction::Execute(Event /*e
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "diamond", axe);
|
SetRtiTarget(botAI, "diamond", axe);
|
||||||
|
|
||||||
if (bot->GetTarget() != axe->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != axe)
|
||||||
return Attack(axe);
|
return Attack(axe);
|
||||||
}
|
}
|
||||||
// Priority 6: Netherstrand Longbow (Skull)
|
// Priority 6: Netherstrand Longbow (Skull)
|
||||||
@ -1505,7 +1505,7 @@ bool KaelthasSunstriderAssignLegendaryWeaponDpsPriorityAction::Execute(Event /*e
|
|||||||
MarkTargetWithSkull(bot, longbow);
|
MarkTargetWithSkull(bot, longbow);
|
||||||
SetRtiTarget(botAI, "skull", longbow);
|
SetRtiTarget(botAI, "skull", longbow);
|
||||||
|
|
||||||
if (bot->GetTarget() != longbow->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != longbow)
|
||||||
return Attack(longbow);
|
return Attack(longbow);
|
||||||
}
|
}
|
||||||
// Priority 7: Phaseshift Bulwark (Skull)
|
// Priority 7: Phaseshift Bulwark (Skull)
|
||||||
@ -1514,7 +1514,7 @@ bool KaelthasSunstriderAssignLegendaryWeaponDpsPriorityAction::Execute(Event /*e
|
|||||||
MarkTargetWithSkull(bot, shield);
|
MarkTargetWithSkull(bot, shield);
|
||||||
SetRtiTarget(botAI, "skull", shield);
|
SetRtiTarget(botAI, "skull", shield);
|
||||||
|
|
||||||
if (bot->GetTarget() != shield->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != shield)
|
||||||
return Attack(shield);
|
return Attack(shield);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1531,7 +1531,7 @@ bool KaelthasSunstriderMoveDevastationAwayAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithDiamond(bot, axe);
|
MarkTargetWithDiamond(bot, axe);
|
||||||
SetRtiTarget(botAI, "diamond", axe);
|
SetRtiTarget(botAI, "diamond", axe);
|
||||||
|
|
||||||
if (bot->GetTarget() != axe->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != axe)
|
||||||
return Attack(axe);
|
return Attack(axe);
|
||||||
|
|
||||||
constexpr float safeDistance = 13.0f;
|
constexpr float safeDistance = 13.0f;
|
||||||
@ -1764,7 +1764,7 @@ bool KaelthasSunstriderMainTankPositionBossAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithStar(bot, kaelthas);
|
MarkTargetWithStar(bot, kaelthas);
|
||||||
SetRtiTarget(botAI, "star", kaelthas);
|
SetRtiTarget(botAI, "star", kaelthas);
|
||||||
|
|
||||||
if (bot->GetTarget() != kaelthas->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != kaelthas)
|
||||||
return Attack(kaelthas);
|
return Attack(kaelthas);
|
||||||
|
|
||||||
if (kaelthas->GetVictim() == bot && bot->IsWithinMeleeRange(kaelthas))
|
if (kaelthas->GetVictim() == bot && bot->IsWithinMeleeRange(kaelthas))
|
||||||
@ -1862,7 +1862,7 @@ bool KaelthasSunstriderHandlePhoenixesAndEggsAction::AssistTanksPickUpPhoenixes(
|
|||||||
if (!targetPhoenix)
|
if (!targetPhoenix)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetTarget() != targetPhoenix->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != targetPhoenix)
|
||||||
return Attack(targetPhoenix);
|
return Attack(targetPhoenix);
|
||||||
|
|
||||||
constexpr float safeDistance = 12.0f;
|
constexpr float safeDistance = 12.0f;
|
||||||
@ -1886,7 +1886,7 @@ bool KaelthasSunstriderHandlePhoenixesAndEggsAction::NonTanksDestroyEggsAndAvoid
|
|||||||
MarkTargetWithDiamond(bot, phoenixEgg);
|
MarkTargetWithDiamond(bot, phoenixEgg);
|
||||||
SetRtiTarget(botAI, "diamond", phoenixEgg);
|
SetRtiTarget(botAI, "diamond", phoenixEgg);
|
||||||
|
|
||||||
if (bot->GetTarget() != phoenixEgg->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != phoenixEgg)
|
||||||
return Attack(phoenixEgg);
|
return Attack(phoenixEgg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1991,7 +1991,7 @@ bool KaelthasSunstriderBreakThroughShockBarrierAction::Execute(Event /*event*/)
|
|||||||
return botAI->CastSpell(spell, kaelthas);
|
return botAI->CastSpell(spell, kaelthas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (bot->GetTarget() != kaelthas->GetGUID())
|
else if (AI_VALUE(Unit*, "current target") != kaelthas)
|
||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "star", kaelthas);
|
SetRtiTarget(botAI, "star", kaelthas);
|
||||||
return Attack(kaelthas);
|
return Attack(kaelthas);
|
||||||
|
|||||||
@ -100,7 +100,7 @@ float AlarPhase2NoTankingIfArmorMeltedMultiplier::GetValue(Action* action)
|
|||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
|
||||||
Unit* alar = AI_VALUE2(Unit*, "find target", "al'ar");
|
Unit* alar = AI_VALUE2(Unit*, "find target", "al'ar");
|
||||||
if (!alar || bot->GetTarget() != alar->GetGUID())
|
if (!alar || AI_VALUE(Unit*, "current target") != alar)
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
|
||||||
if (dynamic_cast<CastTauntAction*>(action) ||
|
if (dynamic_cast<CastTauntAction*>(action) ||
|
||||||
|
|||||||
@ -56,7 +56,7 @@ bool AkilzonTanksPositionBossAction::Execute(Event /*event*/)
|
|||||||
if (!akilzon)
|
if (!akilzon)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetVictim() != akilzon)
|
if (AI_VALUE(Unit*, "current target") != akilzon)
|
||||||
return Attack(akilzon);
|
return Attack(akilzon);
|
||||||
|
|
||||||
if (akilzon->GetVictim() == bot)
|
if (akilzon->GetVictim() == bot)
|
||||||
@ -168,7 +168,7 @@ bool NalorakkTanksPositionBossAction::MainTankPositionTrollForm(Unit* nalorakk)
|
|||||||
{
|
{
|
||||||
if (!nalorakk->HasAura(static_cast<uint32>(ZulAmanSpells::SPELL_BEARFORM)))
|
if (!nalorakk->HasAura(static_cast<uint32>(ZulAmanSpells::SPELL_BEARFORM)))
|
||||||
{
|
{
|
||||||
if (bot->GetVictim() != nalorakk)
|
if (AI_VALUE(Unit*, "current target") != nalorakk)
|
||||||
return Attack(nalorakk);
|
return Attack(nalorakk);
|
||||||
|
|
||||||
if (nalorakk->GetVictim() != bot)
|
if (nalorakk->GetVictim() != bot)
|
||||||
@ -198,7 +198,7 @@ bool NalorakkTanksPositionBossAction::FirstAssistTankPositionBearForm(Unit* nalo
|
|||||||
{
|
{
|
||||||
if (nalorakk->HasAura(static_cast<uint32>(ZulAmanSpells::SPELL_BEARFORM)))
|
if (nalorakk->HasAura(static_cast<uint32>(ZulAmanSpells::SPELL_BEARFORM)))
|
||||||
{
|
{
|
||||||
if (bot->GetVictim() != nalorakk)
|
if (AI_VALUE(Unit*, "current target") != nalorakk)
|
||||||
return Attack(nalorakk);
|
return Attack(nalorakk);
|
||||||
|
|
||||||
if (nalorakk->GetVictim() != bot)
|
if (nalorakk->GetVictim() != bot)
|
||||||
@ -262,7 +262,7 @@ bool JanalaiTanksPositionBossAction::Execute(Event /*event*/)
|
|||||||
if (!janalai)
|
if (!janalai)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetVictim() != janalai)
|
if (AI_VALUE(Unit*, "current target") != janalai)
|
||||||
return Attack(janalai);
|
return Attack(janalai);
|
||||||
|
|
||||||
if (janalai->GetVictim() == bot)
|
if (janalai->GetVictim() == bot)
|
||||||
@ -409,7 +409,7 @@ bool HalazziMainTankPositionBossAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithStar(bot, halazzi);
|
MarkTargetWithStar(bot, halazzi);
|
||||||
SetRtiTarget(botAI, "star", halazzi);
|
SetRtiTarget(botAI, "star", halazzi);
|
||||||
|
|
||||||
if (bot->GetVictim() != halazzi)
|
if (AI_VALUE(Unit*, "current target") != halazzi)
|
||||||
return Attack(halazzi);
|
return Attack(halazzi);
|
||||||
|
|
||||||
if (halazzi->GetVictim() == bot)
|
if (halazzi->GetVictim() == bot)
|
||||||
@ -443,7 +443,7 @@ bool HalazziFirstAssistTankAttackSpiritLynxAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithCircle(bot, lynx);
|
MarkTargetWithCircle(bot, lynx);
|
||||||
SetRtiTarget(botAI, "circle", lynx);
|
SetRtiTarget(botAI, "circle", lynx);
|
||||||
|
|
||||||
if (bot->GetVictim() != lynx)
|
if (AI_VALUE(Unit*, "current target") != lynx)
|
||||||
return Attack(lynx);
|
return Attack(lynx);
|
||||||
|
|
||||||
if (lynx->GetVictim() != bot)
|
if (lynx->GetVictim() != bot)
|
||||||
@ -455,7 +455,7 @@ bool HalazziFirstAssistTankAttackSpiritLynxAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "star", halazzi);
|
SetRtiTarget(botAI, "star", halazzi);
|
||||||
|
|
||||||
if (bot->GetVictim() != halazzi)
|
if (AI_VALUE(Unit*, "current target") != halazzi)
|
||||||
return Attack(halazzi);
|
return Attack(halazzi);
|
||||||
|
|
||||||
targetFound = true;
|
targetFound = true;
|
||||||
@ -492,7 +492,7 @@ bool HalazziAssignDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
MarkTargetWithSkull(bot, totem);
|
MarkTargetWithSkull(bot, totem);
|
||||||
SetRtiTarget(botAI, "skull", totem);
|
SetRtiTarget(botAI, "skull", totem);
|
||||||
|
|
||||||
if (bot->GetTarget() != totem->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != totem)
|
||||||
return Attack(totem);
|
return Attack(totem);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -503,7 +503,7 @@ bool HalazziAssignDpsPriorityAction::Execute(Event /*event*/)
|
|||||||
{
|
{
|
||||||
SetRtiTarget(botAI, "star", halazzi);
|
SetRtiTarget(botAI, "star", halazzi);
|
||||||
|
|
||||||
if (bot->GetTarget() != halazzi->GetGUID())
|
if (AI_VALUE(Unit*, "current target") != halazzi)
|
||||||
return Attack(halazzi);
|
return Attack(halazzi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,7 +602,7 @@ bool HexLordMalacrassCastersStopAttackingAction::Execute(Event /*event*/)
|
|||||||
!malacrass->HasAura(static_cast<uint32>(ZulAmanSpells::SPELL_HEX_LORD_SPELL_REFLECTION)))
|
!malacrass->HasAura(static_cast<uint32>(ZulAmanSpells::SPELL_HEX_LORD_SPELL_REFLECTION)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetVictim() == malacrass)
|
if (AI_VALUE(Unit*, "current target") == malacrass)
|
||||||
{
|
{
|
||||||
bot->AttackStop();
|
bot->AttackStop();
|
||||||
bot->InterruptNonMeleeSpells(true);
|
bot->InterruptNonMeleeSpells(true);
|
||||||
@ -657,7 +657,7 @@ bool ZuljinTanksPositionBossAction::Execute(Event /*event*/)
|
|||||||
if (!zuljin)
|
if (!zuljin)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetVictim() != zuljin)
|
if (AI_VALUE(Unit*, "current target") != zuljin)
|
||||||
return Attack(zuljin);
|
return Attack(zuljin);
|
||||||
|
|
||||||
if (zuljin->GetVictim() == bot)
|
if (zuljin->GetVictim() == bot)
|
||||||
|
|||||||
@ -267,7 +267,7 @@ float HexLordMalacrassStopAttackingDuringSpellReflectionMultiplier::GetValue(Act
|
|||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
|
||||||
if (castSpellAction->getThreatType() == Action::ActionThreatType::Aoe ||
|
if (castSpellAction->getThreatType() == Action::ActionThreatType::Aoe ||
|
||||||
(bot->GetVictim() == malacrass &&
|
(AI_VALUE(Unit*, "current target") == malacrass &&
|
||||||
castSpellAction->getThreatType() == Action::ActionThreatType::Single))
|
castSpellAction->getThreatType() == Action::ActionThreatType::Single))
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
#include "Ai/Raid/SerpentshrineCavern/RaidSSCActionContext.h"
|
#include "Ai/Raid/SerpentshrineCavern/RaidSSCActionContext.h"
|
||||||
#include "Ai/Raid/TempestKeep/RaidTempestKeepActionContext.h"
|
#include "Ai/Raid/TempestKeep/RaidTempestKeepActionContext.h"
|
||||||
#include "Ai/Raid/HyjalSummit/RaidHyjalSummitActionContext.h"
|
#include "Ai/Raid/HyjalSummit/RaidHyjalSummitActionContext.h"
|
||||||
|
#include "Ai/Raid/BlackTemple/RaidBlackTempleActionContext.h"
|
||||||
#include "Ai/Raid/ZulAman/RaidZulAmanActionContext.h"
|
#include "Ai/Raid/ZulAman/RaidZulAmanActionContext.h"
|
||||||
#include "Ai/Raid/ObsidianSanctum/RaidOsActionContext.h"
|
#include "Ai/Raid/ObsidianSanctum/RaidOsActionContext.h"
|
||||||
#include "Ai/Raid/EyeOfEternity/RaidEoEActionContext.h"
|
#include "Ai/Raid/EyeOfEternity/RaidEoEActionContext.h"
|
||||||
@ -36,6 +37,7 @@ void AiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList<Act
|
|||||||
actionContexts.Add(new RaidSSCActionContext());
|
actionContexts.Add(new RaidSSCActionContext());
|
||||||
actionContexts.Add(new RaidTempestKeepActionContext());
|
actionContexts.Add(new RaidTempestKeepActionContext());
|
||||||
actionContexts.Add(new RaidHyjalSummitActionContext());
|
actionContexts.Add(new RaidHyjalSummitActionContext());
|
||||||
|
actionContexts.Add(new RaidBlackTempleActionContext());
|
||||||
actionContexts.Add(new RaidZulAmanActionContext());
|
actionContexts.Add(new RaidZulAmanActionContext());
|
||||||
actionContexts.Add(new RaidNaxxActionContext());
|
actionContexts.Add(new RaidNaxxActionContext());
|
||||||
actionContexts.Add(new RaidOsActionContext());
|
actionContexts.Add(new RaidOsActionContext());
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
#include "Ai/Raid/SerpentshrineCavern/RaidSSCTriggerContext.h"
|
#include "Ai/Raid/SerpentshrineCavern/RaidSSCTriggerContext.h"
|
||||||
#include "Ai/Raid/TempestKeep/RaidTempestKeepTriggerContext.h"
|
#include "Ai/Raid/TempestKeep/RaidTempestKeepTriggerContext.h"
|
||||||
#include "Ai/Raid/HyjalSummit/RaidHyjalSummitTriggerContext.h"
|
#include "Ai/Raid/HyjalSummit/RaidHyjalSummitTriggerContext.h"
|
||||||
|
#include "Ai/Raid/BlackTemple/RaidBlackTempleTriggerContext.h"
|
||||||
#include "Ai/Raid/ZulAman/RaidZulAmanTriggerContext.h"
|
#include "Ai/Raid/ZulAman/RaidZulAmanTriggerContext.h"
|
||||||
#include "Ai/Raid/ObsidianSanctum/RaidOsTriggerContext.h"
|
#include "Ai/Raid/ObsidianSanctum/RaidOsTriggerContext.h"
|
||||||
#include "Ai/Raid/EyeOfEternity/RaidEoETriggerContext.h"
|
#include "Ai/Raid/EyeOfEternity/RaidEoETriggerContext.h"
|
||||||
@ -37,6 +38,7 @@ void AiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList<Tr
|
|||||||
triggerContexts.Add(new RaidSSCTriggerContext());
|
triggerContexts.Add(new RaidSSCTriggerContext());
|
||||||
triggerContexts.Add(new RaidTempestKeepTriggerContext());
|
triggerContexts.Add(new RaidTempestKeepTriggerContext());
|
||||||
triggerContexts.Add(new RaidHyjalSummitTriggerContext());
|
triggerContexts.Add(new RaidHyjalSummitTriggerContext());
|
||||||
|
triggerContexts.Add(new RaidBlackTempleTriggerContext());
|
||||||
triggerContexts.Add(new RaidZulAmanTriggerContext());
|
triggerContexts.Add(new RaidZulAmanTriggerContext());
|
||||||
triggerContexts.Add(new RaidOsTriggerContext());
|
triggerContexts.Add(new RaidOsTriggerContext());
|
||||||
triggerContexts.Add(new RaidEoETriggerContext());
|
triggerContexts.Add(new RaidEoETriggerContext());
|
||||||
|
|||||||
@ -1619,9 +1619,9 @@ void PlayerbotAI::ApplyInstanceStrategies(uint32 mapId, bool tellMaster)
|
|||||||
{
|
{
|
||||||
static const std::vector<std::string> allInstanceStrategies =
|
static const std::vector<std::string> allInstanceStrategies =
|
||||||
{
|
{
|
||||||
"aq20", "bwl", "karazhan", "gruulslair", "hyjal", "icc", "magtheridon",
|
"aq20", "blacktemple", "bwl", "gruulslair", "hyjal", "icc", "karazhan",
|
||||||
"moltencore", "naxx", "onyxia", "ssc", "tbc-ac", "tempestkeep", "ulduar",
|
"magtheridon", "moltencore", "naxx", "onyxia", "ssc", "tbc-ac", "tempestkeep",
|
||||||
"voa", "wotlk-an", "wotlk-cos", "wotlk-dtk", "wotlk-eoe", "wotlk-fos",
|
"ulduar", "voa", "wotlk-an", "wotlk-cos", "wotlk-dtk", "wotlk-eoe", "wotlk-fos",
|
||||||
"wotlk-gd", "wotlk-hol", "wotlk-hor", "wotlk-hos", "wotlk-nex", "wotlk-occ",
|
"wotlk-gd", "wotlk-hol", "wotlk-hor", "wotlk-hos", "wotlk-nex", "wotlk-occ",
|
||||||
"wotlk-ok", "wotlk-os", "wotlk-pos", "wotlk-toc", "wotlk-uk", "wotlk-up",
|
"wotlk-ok", "wotlk-os", "wotlk-pos", "wotlk-toc", "wotlk-uk", "wotlk-up",
|
||||||
"wotlk-vh", "zulaman"
|
"wotlk-vh", "zulaman"
|
||||||
@ -1669,6 +1669,9 @@ void PlayerbotAI::ApplyInstanceStrategies(uint32 mapId, bool tellMaster)
|
|||||||
case 558:
|
case 558:
|
||||||
strategyName = "tbc-ac"; // Auchindoun: Auchenai Crypts
|
strategyName = "tbc-ac"; // Auchindoun: Auchenai Crypts
|
||||||
break;
|
break;
|
||||||
|
case 564:
|
||||||
|
strategyName = "blacktemple"; // Black Temple
|
||||||
|
break;
|
||||||
case 565:
|
case 565:
|
||||||
strategyName = "gruulslair"; // Gruul's Lair
|
strategyName = "gruulslair"; // Gruul's Lair
|
||||||
break;
|
break;
|
||||||
@ -2874,7 +2877,7 @@ bool PlayerbotAI::SayToParty(const std::string& msg)
|
|||||||
|
|
||||||
bool PlayerbotAI::SayToRaid(const std::string& msg)
|
bool PlayerbotAI::SayToRaid(const std::string& msg)
|
||||||
{
|
{
|
||||||
if (!bot->GetGroup() || bot->GetGroup()->isRaidGroup())
|
if (!bot->GetGroup() || !bot->GetGroup()->isRaidGroup())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
@ -5560,7 +5563,7 @@ Item* PlayerbotAI::FindStoneFor(Item* weapon) const
|
|||||||
SOLID_SHARPENING_STONE, HEAVY_SHARPENING_STONE, COARSE_SHARPENING_STONE, ROUGH_SHARPENING_STONE};
|
SOLID_SHARPENING_STONE, HEAVY_SHARPENING_STONE, COARSE_SHARPENING_STONE, ROUGH_SHARPENING_STONE};
|
||||||
|
|
||||||
static const std::vector<uint32_t> uPrioritizedWeightStoneIds = {
|
static const std::vector<uint32_t> uPrioritizedWeightStoneIds = {
|
||||||
ADAMANTITE_WEIGHTSTONE, FEL_WEIGHTSTONE, DENSE_WEIGHTSTONE, SOLID_WEIGHTSTONE,
|
ADAMANTITE_WEIGHTSTONE, FEL_WEIGHTSTONE, ELEMENTAL_SHARPENING_STONE, DENSE_WEIGHTSTONE, SOLID_WEIGHTSTONE,
|
||||||
HEAVY_WEIGHTSTONE, COARSE_WEIGHTSTONE, ROUGH_WEIGHTSTONE};
|
HEAVY_WEIGHTSTONE, COARSE_WEIGHTSTONE, ROUGH_WEIGHTSTONE};
|
||||||
|
|
||||||
Item* stone = nullptr;
|
Item* stone = nullptr;
|
||||||
|
|||||||
@ -39,6 +39,8 @@ void PlayerbotRepository::Load(PlayerbotAI* botAI)
|
|||||||
botAI->ChangeStrategy(value, BOT_STATE_DEAD);
|
botAI->ChangeStrategy(value, BOT_STATE_DEAD);
|
||||||
} while (result->NextRow());
|
} while (result->NextRow());
|
||||||
|
|
||||||
|
botAI->GetAiObjectContext()->GetUntypedValue("outfit list");
|
||||||
|
|
||||||
botAI->GetAiObjectContext()->Load(values);
|
botAI->GetAiObjectContext()->Load(values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user