aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/grafana/1_General.json889
-rw-r--r--contrib/grafana/2_Maps.json339
-rw-r--r--contrib/grafana/3_Network.json242
-rw-r--r--sql/updates/world/3.3.5/2016_06_02_00_world.sql20
-rw-r--r--sql/updates/world/3.3.5/2016_06_02_01_world.sql10
-rw-r--r--sql/updates/world/3.3.5/2016_06_04_00_world.sql19
-rw-r--r--sql/updates/world/3.3.5/2016_06_04_01_world.sql12
-rw-r--r--sql/updates/world/3.3.5/2016_06_05_00_world.sql2
-rw-r--r--sql/updates/world/3.3.5/2016_06_05_01_world.sql2
-rw-r--r--sql/updates/world/3.3.5/2016_06_05_02_world.sql2
-rw-r--r--sql/updates/world/3.3.5/2016_06_05_03_world.sql2
-rw-r--r--sql/updates/world/3.3.5/2016_06_05_04_world.sql2
-rw-r--r--sql/updates/world/3.3.5/2016_06_05_05_world.sql5
-rw-r--r--sql/updates/world/3.3.5/2016_06_05_06_world.sql2
-rw-r--r--sql/updates/world/3.3.5/2016_06_05_07_world.sql4
-rw-r--r--sql/updates/world/3.3.5/2016_06_05_08_world.sql2
-rw-r--r--sql/updates/world/3.3.5/2016_06_05_09_world.sql9
-rw-r--r--sql/updates/world/3.3.5/2016_06_05_10_world.sql5
-rw-r--r--sql/updates/world/3.3.5/2016_06_05_11_world.sql7
-rw-r--r--sql/updates/world/3.3.5/2016_06_05_12_world.sql2
-rw-r--r--sql/updates/world/3.3.5/2016_06_06_00_world.sql83
-rw-r--r--sql/updates/world/3.3.5/2016_06_07_00_world.sql2
-rw-r--r--sql/updates/world/3.3.5/2016_06_07_01_world.sql622
-rw-r--r--sql/updates/world/3.3.5/2016_06_09_00_world.sql33
-rw-r--r--sql/updates/world/3.3.5/2016_06_09_01_world.sql14
-rw-r--r--sql/updates/world/3.3.5/2016_06_09_02_world.sql21
-rw-r--r--sql/updates/world/3.3.5/2016_06_09_03_world_335.sql23
-rw-r--r--sql/updates/world/3.3.5/2016_06_09_04_world.sql6
-rw-r--r--sql/updates/world/3.3.5/2016_06_09_05_world.sql82
-rw-r--r--sql/updates/world/3.3.5/2016_06_09_06_world.sql3
-rw-r--r--src/common/Collision/DynamicTree.cpp2
-rw-r--r--src/common/Collision/Maps/MapTree.cpp5
-rw-r--r--src/common/Metric/Metric.cpp235
-rw-r--r--src/common/Metric/Metric.h141
-rw-r--r--src/server/game/AI/PlayerAI/PlayerAI.cpp2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp14
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h3
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp4
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h39
-rw-r--r--src/server/game/Entities/Item/ItemPrototype.h16
-rw-r--r--src/server/game/Entities/Object/Object.cpp4
-rw-r--r--src/server/game/Entities/Player/Player.cpp9
-rw-r--r--src/server/game/Entities/Player/Player.h4
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp30
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp55
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp9
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp2
-rw-r--r--src/server/game/Handlers/LootHandler.cpp2
-rw-r--r--src/server/game/Handlers/SpellHandler.cpp2
-rw-r--r--src/server/game/Loot/LootMgr.cpp6
-rw-r--r--src/server/game/Maps/Map.cpp4
-rw-r--r--src/server/game/Maps/Map.h2
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h5
-rw-r--r--src/server/game/Movement/MotionMaster.cpp9
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp2
-rw-r--r--src/server/game/Movement/PathGenerator.cpp3
-rw-r--r--src/server/game/Server/WorldSession.cpp5
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp24
-rw-r--r--src/server/game/World/World.cpp8
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp6
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp1
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp11
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp45
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp45
-rw-r--r--src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/zone_loch_modan.cpp106
-rw-r--r--src/server/scripts/Kalimdor/zone_feralas.cpp50
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp10
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp34
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp74
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp209
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp14
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp88
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp1
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp6
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp10
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp4
-rw-r--r--src/server/scripts/Northrend/zone_sholazar_basin.cpp2
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_illidan.cpp470
-rw-r--r--src/server/scripts/Outland/zone_shadowmoon_valley.cpp6
-rw-r--r--src/server/scripts/World/npcs_special.cpp300
-rw-r--r--src/server/worldserver/Main.cpp11
-rw-r--r--src/server/worldserver/worldserver.conf.dist42
86 files changed, 3797 insertions, 868 deletions
diff --git a/contrib/grafana/1_General.json b/contrib/grafana/1_General.json
new file mode 100644
index 00000000000..e54791f190e
--- /dev/null
+++ b/contrib/grafana/1_General.json
@@ -0,0 +1,889 @@
+{
+ "id": 1,
+ "title": "General info",
+ "originalTitle": "General info",
+ "tags": [],
+ "style": "dark",
+ "timezone": "browser",
+ "editable": true,
+ "hideControls": false,
+ "sharedCrosshair": false,
+ "rows": [
+ {
+ "collapse": false,
+ "editable": true,
+ "height": "25px",
+ "panels": [
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": "Influx",
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "id": 5,
+ "interval": null,
+ "isNew": true,
+ "links": [],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "span": 3,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ }
+ ],
+ "measurement": "online_players",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "type": "field",
+ "params": [
+ "value"
+ ]
+ },
+ {
+ "type": "last",
+ "params": []
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "realm",
+ "operator": "=~",
+ "value": "/^$realm$/"
+ }
+ ]
+ }
+ ],
+ "thresholds": "",
+ "title": "Online players",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current",
+ "timeFrom": null,
+ "timeShift": null,
+ "hideTimeOverride": false
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": "Influx",
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "id": 6,
+ "interval": null,
+ "isNew": true,
+ "links": [],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "span": 3,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "update_time_diff",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "realm",
+ "operator": "=~",
+ "value": "/^$realm$/"
+ }
+ ]
+ }
+ ],
+ "thresholds": "",
+ "title": "Update diff (avg)",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "avg",
+ "timeFrom": "1m"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": "Influx",
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "id": 7,
+ "interval": null,
+ "isNew": true,
+ "links": [],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "span": 3,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "update_time_diff",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": []
+ }
+ ],
+ "thresholds": "",
+ "title": "Update diff (avg)",
+ "transparent": false,
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "avg",
+ "timeFrom": "5m"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": "Influx",
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "id": 8,
+ "interval": null,
+ "isNew": true,
+ "links": [],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "span": 3,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "update_time_diff",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "realm",
+ "operator": "=~",
+ "value": "/^$realm$/"
+ }
+ ]
+ }
+ ],
+ "thresholds": "",
+ "title": "Update diff (avg)",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "avg",
+ "timeFrom": "15m",
+ "timeShift": null
+ }
+ ],
+ "title": "New row"
+ },
+ {
+ "collapse": false,
+ "editable": true,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "datasource": "Influx",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {
+ "leftLogBase": 1,
+ "leftMax": null,
+ "leftMin": null,
+ "rightLogBase": 1,
+ "rightMax": null,
+ "rightMin": null,
+ "threshold1": null,
+ "threshold1Color": "rgba(216, 200, 27, 0.27)",
+ "threshold2": null,
+ "threshold2Color": "rgba(234, 112, 112, 0.22)"
+ },
+ "id": 1,
+ "isNew": true,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "Update diff",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "update_time_diff",
+ "policy": "default",
+ "query": "SELECT mean(\"value\") FROM \"update_time_diff\" WHERE \"realm\" =~ /$realm$/ AND $timeFilter GROUP BY time($interval) fill(null)",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "realm",
+ "operator": "=~",
+ "value": "/$realm$/"
+ }
+ ]
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Update diff",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "x-axis": true,
+ "xaxis": {
+ "show": true
+ },
+ "y-axis": true,
+ "y_formats": [
+ "ms",
+ "short"
+ ],
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "title": "Row"
+ },
+ {
+ "collapse": false,
+ "editable": true,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "datasource": "Influx",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {
+ "leftLogBase": 1,
+ "leftMax": null,
+ "leftMin": null,
+ "rightLogBase": 1,
+ "rightMax": null,
+ "rightMin": null,
+ "threshold1": null,
+ "threshold1Color": "rgba(216, 200, 27, 0.27)",
+ "threshold2": null,
+ "threshold2Color": "rgba(234, 112, 112, 0.22)"
+ },
+ "id": 4,
+ "isNew": true,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "Online players",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "online_players",
+ "policy": "default",
+ "query": "SELECT mean(\"value\") FROM \"online_players\" WHERE \"realm\" =~ /$realm$/ AND $timeFilter GROUP BY time($interval) fill(null)",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "realm",
+ "operator": "=~",
+ "value": "/$realm$/"
+ }
+ ]
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Online players",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "x-axis": true,
+ "xaxis": {
+ "show": true
+ },
+ "y-axis": true,
+ "y_formats": [
+ "short",
+ "short"
+ ],
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "title": "New row"
+ },
+ {
+ "collapse": false,
+ "editable": true,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "datasource": "Influx",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {
+ "leftLogBase": 1,
+ "leftMax": null,
+ "leftMin": null,
+ "rightLogBase": 1,
+ "rightMax": null,
+ "rightMin": null,
+ "threshold1": null,
+ "threshold1Color": "rgba(216, 200, 27, 0.27)",
+ "threshold2": null,
+ "threshold2Color": "rgba(234, 112, 112, 0.22)"
+ },
+ "id": 3,
+ "isNew": true,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "Logouts",
+ "transform": "negative-Y"
+ }
+ ],
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "Logins",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "player_events",
+ "policy": "default",
+ "query": "SELECT count(\"text\") FROM \"player_events\" WHERE \"realm\" =~ /$realm$/ AND \"title\" = 'Login' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": true,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "text"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "count"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "realm",
+ "operator": "=",
+ "value": "Trinity"
+ }
+ ]
+ },
+ {
+ "alias": "Logouts",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "policy": "default",
+ "query": "SELECT count(\"text\") FROM \"player_events\" WHERE \"realm\" =~ /$realm$/ AND \"title\" = 'Logout' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": true,
+ "refId": "B",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": []
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Player login/logout",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "x-axis": true,
+ "xaxis": {
+ "show": true
+ },
+ "y-axis": true,
+ "y_formats": [
+ "short",
+ "short"
+ ],
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "title": "New row"
+ }
+ ],
+ "time": {
+ "from": "now-15m",
+ "to": "now"
+ },
+ "timepicker": {
+ "now": true,
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "templating": {
+ "list": [
+ {
+ "allFormat": "regex values",
+ "current": {
+ "text": "Trinity",
+ "value": "Trinity"
+ },
+ "datasource": "Influx",
+ "includeAll": false,
+ "multi": false,
+ "multiFormat": "regex values",
+ "name": "realm",
+ "options": [
+ {
+ "text": "Trinity",
+ "value": "Trinity",
+ "selected": true
+ }
+ ],
+ "query": "show tag values from events with key = realm",
+ "refresh": 1,
+ "regex": "",
+ "type": "query"
+ }
+ ]
+ },
+ "annotations": {
+ "list": [
+ {
+ "datasource": "Influx",
+ "enable": true,
+ "iconColor": "#C0C6BE",
+ "iconSize": 13,
+ "lineColor": "rgba(255, 96, 96, 0.592157)",
+ "name": "Global Events",
+ "query": "select title, text from events where $timeFilter and realm =~ /$realm$/",
+ "showLine": true,
+ "textColumn": "text",
+ "titleColumn": "title"
+ }
+ ]
+ },
+ "refresh": "1m",
+ "schemaVersion": 12,
+ "version": 7,
+ "links": []
+} \ No newline at end of file
diff --git a/contrib/grafana/2_Maps.json b/contrib/grafana/2_Maps.json
new file mode 100644
index 00000000000..6c2cecb1035
--- /dev/null
+++ b/contrib/grafana/2_Maps.json
@@ -0,0 +1,339 @@
+{
+ "id": 2,
+ "title": "Maps, vmaps and mmaps",
+ "originalTitle": "Maps, vmaps and mmaps",
+ "tags": [],
+ "style": "dark",
+ "timezone": "browser",
+ "editable": true,
+ "hideControls": false,
+ "sharedCrosshair": false,
+ "rows": [
+ {
+ "collapse": false,
+ "editable": true,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "datasource": "Influx",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {
+ "leftLogBase": 1,
+ "leftMax": null,
+ "leftMin": null,
+ "rightLogBase": 1,
+ "rightMax": null,
+ "rightMin": null,
+ "threshold1": null,
+ "threshold1Color": "rgba(216, 200, 27, 0.27)",
+ "threshold2": null,
+ "threshold2Color": "rgba(234, 112, 112, 0.22)"
+ },
+ "id": 2,
+ "isNew": true,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "Unload tile",
+ "transform": "negative-Y"
+ }
+ ],
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "Load tile",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "query": "SELECT count(\"title\") FROM \"map_events\" WHERE \"realm\" =~ /$realm$/ AND \"title\" = 'LoadMapTile' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": true,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": []
+ },
+ {
+ "alias": "Unload tile",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "query": "SELECT count(\"title\") FROM \"map_events\" WHERE \"realm\" =~ /$realm$/ AND \"title\" = 'UnloadMapTile' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": true,
+ "refId": "B",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": []
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Map",
+ "tooltip": {
+ "shared": true,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "x-axis": true,
+ "y-axis": true,
+ "y_formats": [
+ "short",
+ "short"
+ ]
+ }
+ ],
+ "title": "Row"
+ },
+ {
+ "collapse": false,
+ "editable": true,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "datasource": "Influx",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {
+ "leftLogBase": 1,
+ "leftMax": null,
+ "leftMin": null,
+ "rightLogBase": 1,
+ "rightMax": null,
+ "rightMin": null,
+ "threshold1": null,
+ "threshold1Color": "rgba(216, 200, 27, 0.27)",
+ "threshold2": null,
+ "threshold2Color": "rgba(234, 112, 112, 0.22)"
+ },
+ "id": 1,
+ "isNew": true,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "Pathfinding queries",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "query": "SELECT count(\"title\") FROM \"mmap_events\" WHERE \"realm\" =~ /$realm$/ AND \"title\" = 'CalculatePath' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": true,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": []
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "MMap",
+ "tooltip": {
+ "shared": true,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "x-axis": true,
+ "y-axis": true,
+ "y_formats": [
+ "short",
+ "short"
+ ]
+ }
+ ],
+ "title": "New row"
+ }
+ ],
+ "time": {
+ "from": "now-15m",
+ "to": "now"
+ },
+ "timepicker": {
+ "now": true,
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "templating": {
+ "list": [
+ {
+ "allFormat": "regex values",
+ "current": {
+ "text": "Trinity",
+ "value": "Trinity"
+ },
+ "datasource": "Influx",
+ "includeAll": false,
+ "multi": false,
+ "multiFormat": "regex values",
+ "name": "realm",
+ "options": [
+ {
+ "text": "Trinity",
+ "value": "Trinity",
+ "selected": true
+ }
+ ],
+ "query": "show tag values from events with key = realm",
+ "refresh": true,
+ "type": "query"
+ }
+ ]
+ },
+ "annotations": {
+ "list": [
+ {
+ "datasource": "Influx",
+ "enable": true,
+ "iconColor": "#C0C6BE",
+ "iconSize": 13,
+ "lineColor": "rgba(255, 96, 96, 0.592157)",
+ "name": "Global Events",
+ "query": "select title, text from events where $timeFilter and realm =~ /$realm$/",
+ "showLine": true,
+ "textColumn": "text",
+ "titleColumn": "title"
+ }
+ ]
+ },
+ "refresh": "1m",
+ "schemaVersion": 8,
+ "version": 11,
+ "links": []
+} \ No newline at end of file
diff --git a/contrib/grafana/3_Network.json b/contrib/grafana/3_Network.json
new file mode 100644
index 00000000000..98c190e1185
--- /dev/null
+++ b/contrib/grafana/3_Network.json
@@ -0,0 +1,242 @@
+{
+ "id": 3,
+ "title": "Network",
+ "originalTitle": "Network",
+ "tags": [],
+ "style": "dark",
+ "timezone": "browser",
+ "editable": true,
+ "hideControls": false,
+ "sharedCrosshair": false,
+ "rows": [
+ {
+ "collapse": false,
+ "editable": true,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "datasource": "Influx",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {
+ "leftLogBase": 1,
+ "leftMax": null,
+ "leftMin": null,
+ "rightLogBase": 1,
+ "rightMax": null,
+ "rightMin": null,
+ "threshold1": null,
+ "threshold1Color": "rgba(216, 200, 27, 0.27)",
+ "threshold2": null,
+ "threshold2Color": "rgba(234, 112, 112, 0.22)"
+ },
+ "id": 1,
+ "isNew": true,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "Processed packets",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "processed_packets",
+ "query": "SELECT sum(\"value\") FROM \"processed_packets\" WHERE \"realm\" =~ /$realm$/ AND $timeFilter GROUP BY time($interval) fill(0)",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "sum"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "realm",
+ "operator": "=~",
+ "value": "/$realm$/"
+ }
+ ]
+ },
+ {
+ "alias": "Processed packets / mean per session",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "processed_packets",
+ "query": "SELECT mean(\"value\") FROM \"processed_packets\" WHERE \"realm\" =~ /$realm$/ AND $timeFilter GROUP BY time($interval) fill(0)",
+ "refId": "B",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "realm",
+ "operator": "=~",
+ "value": "/$realm$/"
+ }
+ ]
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Processed packets",
+ "tooltip": {
+ "shared": true,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "x-axis": true,
+ "y-axis": true,
+ "y_formats": [
+ "short",
+ "short"
+ ]
+ }
+ ],
+ "title": "Row"
+ }
+ ],
+ "time": {
+ "from": "now-15m",
+ "to": "now"
+ },
+ "timepicker": {
+ "now": true,
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "templating": {
+ "list": [
+ {
+ "allFormat": "regex values",
+ "current": {
+ "text": "Trinity",
+ "value": "Trinity"
+ },
+ "datasource": "Influx",
+ "includeAll": false,
+ "multi": false,
+ "multiFormat": "regex values",
+ "name": "realm",
+ "options": [
+ {
+ "text": "Trinity",
+ "value": "Trinity",
+ "selected": true
+ }
+ ],
+ "query": "show tag values from events with key = realm",
+ "refresh": true,
+ "type": "query"
+ }
+ ]
+ },
+ "annotations": {
+ "list": [
+ {
+ "datasource": "Influx",
+ "enable": true,
+ "iconColor": "#C0C6BE",
+ "iconSize": 13,
+ "lineColor": "rgba(255, 96, 96, 0.592157)",
+ "name": "Global Events",
+ "query": "select title, text from events where $timeFilter and realm =~ /$realm$/",
+ "showLine": true,
+ "textColumn": "text",
+ "titleColumn": "title"
+ }
+ ]
+ },
+ "refresh": "1m",
+ "schemaVersion": 8,
+ "version": 7,
+ "links": []
+} \ No newline at end of file
diff --git a/sql/updates/world/3.3.5/2016_06_02_00_world.sql b/sql/updates/world/3.3.5/2016_06_02_00_world.sql
new file mode 100644
index 00000000000..b192efa6814
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_02_00_world.sql
@@ -0,0 +1,20 @@
+DELETE FROM `spell_script_names` where `ScriptName` IN ('spell_jormungars_burning_spray','spell_jormungars_paralytic_spray','spell_jormungars_paralytic_toxin','spell_jormungars_paralysis');
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(66902,'spell_jormungars_burning_spray'), -- Burning Spray 10m normal
+(67627,'spell_jormungars_burning_spray'), -- Burning Spray 25m normal
+(67628,'spell_jormungars_burning_spray'), -- Burning Spray 10m heroic
+(67629,'spell_jormungars_burning_spray'), -- Burning Spray 25m heroic
+(66901,'spell_jormungars_paralytic_spray'), -- Paralytic Spray 10m normal
+(67615,'spell_jormungars_paralytic_spray'), -- Paralytic Spray 25m normal
+(67616,'spell_jormungars_paralytic_spray'), -- Paralytic Spray 10m heroic
+(67617,'spell_jormungars_paralytic_spray'), -- Paralytic Spray 25m heroic
+(66823,'spell_jormungars_paralytic_toxin'), -- Paralytic Toxin 10m normal
+(67618,'spell_jormungars_paralytic_toxin'), -- Paralytic Toxin 25m normal
+(67619,'spell_jormungars_paralytic_toxin'), -- Paralytic Toxin 10m heroic
+(67620,'spell_jormungars_paralytic_toxin'), -- Paralytic Toxin 25m heroic
+(66830,'spell_jormungars_paralysis'); -- Paralysis
+
+-- Acidmaw missing text
+DELETE FROM `creature_text` where entry = 35144 AND groupid = 1;
+INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES
+(35144,1,0,'You have been infected with a Paralytic Toxin!',42,0,100,0,0,0,36323,0,'Acidmaw - Special Attack');
diff --git a/sql/updates/world/3.3.5/2016_06_02_01_world.sql b/sql/updates/world/3.3.5/2016_06_02_01_world.sql
new file mode 100644
index 00000000000..792f221e344
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_02_01_world.sql
@@ -0,0 +1,10 @@
+DELETE FROM `spell_script_names` where `ScriptName` IN ('spell_fel_streak_visual');
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(66493,'spell_fel_streak_visual');
+
+DELETE FROM `creature_template_addon` WHERE `entry` IN (34815,35262,35263,35264);
+INSERT INTO `creature_template_addon` (`entry`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES
+(34815,0,0,0,1,0,'66327'),
+(35262,0,0,0,1,0,'66327'),
+(35263,0,0,0,1,0,'66327'),
+(35264,0,0,0,1,0,'66327');
diff --git a/sql/updates/world/3.3.5/2016_06_04_00_world.sql b/sql/updates/world/3.3.5/2016_06_04_00_world.sql
new file mode 100644
index 00000000000..e44fe54de55
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_04_00_world.sql
@@ -0,0 +1,19 @@
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=6556;
+
+DELETE FROM `smart_scripts` WHERE `entryorguid`=6556 AND `source_type`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=6557 AND `source_type`=0 AND `id`=7;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=6559 AND `source_type`=0 AND `id`=1;
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(6556, 0, 0, 0, 8, 0, 100, 1, 15702, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Muculent Ooze - On Spell Hit (Filling Empty Jar) - Despawn'),
+(6557, 0, 7, 0, 8, 0, 100, 1, 15702, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Primal Ooze - On Spell Hit (Filling Empty Jar) - Despawn'),
+(6559, 0, 1, 0, 8, 0, 100, 1, 15702, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Glutinous Ooze - On Spell Hit (Filling Empty Jar) - Despawn');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=17 AND `SourceEntry`=15702;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(17, 0, 15702, 0, 0, 31, 1, 3, 6556, 0, 0, 0, 0, '', 'Filling Empty Jar can be used on Muculent Ooze'),
+(17, 0, 15702, 0, 1, 31, 1, 3, 6557, 0, 0, 0, 0, '', 'Filling Empty Jar can be used on Muculent Ooze'),
+(17, 0, 15702, 0, 2, 31, 1, 3, 6559, 0, 0, 0, 0, '', 'Filling Empty Jar can be used on Muculent Ooze'),
+(17, 0, 15702, 0, 0, 36, 1, 0, 0, 0, 1, 0, 0, '', 'Target must be dead'),
+(17, 0, 15702, 0, 1, 36, 1, 0, 0, 0, 1, 0, 0, '', 'Target must be dead'),
+(17, 0, 15702, 0, 2, 36, 1, 0, 0, 0, 1, 0, 0, '', 'Target must be dead');
diff --git a/sql/updates/world/3.3.5/2016_06_04_01_world.sql b/sql/updates/world/3.3.5/2016_06_04_01_world.sql
new file mode 100644
index 00000000000..fb048449d40
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_04_01_world.sql
@@ -0,0 +1,12 @@
+DROP TABLE IF EXISTS `playercreateinfo_cast_spell`;
+CREATE TABLE IF NOT EXISTS `playercreateinfo_cast_spell` (
+ `raceMask` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `classMask` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `spell` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
+ `note` VARCHAR(255) DEFAULT NULL
+) ENGINE=MYISAM DEFAULT CHARSET=utf8;
+
+DELETE FROM `playercreateinfo_cast_spell` WHERE `spell` IN (48266, 2457);
+INSERT INTO `playercreateinfo_cast_spell` (`racemask`, `classmask`, `spell`, `note`) VALUES
+(0, 32, 48266, 'Death Knight - Blood Presence'),
+(0, 1, 2457, 'Warrior - Battle Stance');
diff --git a/sql/updates/world/3.3.5/2016_06_05_00_world.sql b/sql/updates/world/3.3.5/2016_06_05_00_world.sql
new file mode 100644
index 00000000000..6da2282d424
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_05_00_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `page_text` SET `Text`="Westfall Stew$B$B3 parts Stringy Vulture Meat$B3 Goretusk Snouts$B3 Murloc Eyes$B3 Okra$B$BMix together and bring to a boil. Let simmer for at least two hours before serving." WHERE `ID`=213;
diff --git a/sql/updates/world/3.3.5/2016_06_05_01_world.sql b/sql/updates/world/3.3.5/2016_06_05_01_world.sql
new file mode 100644
index 00000000000..444a5be17ed
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_05_01_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `page_text` SET `Text`="Osric,$B$BPlease find below the list of armor of which we are in need:$B$B10 Mail shirts$B20 Helms$B30 Armor Patches$B15 Mail Boots$B$BWe are, as always, in your debt. And should Westfall ever be free of the thieves who threaten it, it would ease the guilt in my heart if I could invite you to my family's home, for a fine meal cooked from the bounty this land was once so well known.$B$B-Lewis$BQuartermaster, Sentinel Hill" WHERE `ID`=2512;
diff --git a/sql/updates/world/3.3.5/2016_06_05_02_world.sql b/sql/updates/world/3.3.5/2016_06_05_02_world.sql
new file mode 100644
index 00000000000..cab093eb88f
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_05_02_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `page_text` SET `Text`="Grelin,$B$BMy time is short and many matters press on my time, and I hope that your investigation of the trolls will not be one of them. Therefore I will allow you to use my authority in dealing with the trolls in whatever fashion you deem necessary, more so if you are able to find an expedient solution.$B$BMagni Bronzebeard" WHERE `ID`=80;
diff --git a/sql/updates/world/3.3.5/2016_06_05_03_world.sql b/sql/updates/world/3.3.5/2016_06_05_03_world.sql
new file mode 100644
index 00000000000..d9bd5ecab2c
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_05_03_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `quest_template_addon` SET `PrevQuestID`=315 WHERE `ID`=415;
diff --git a/sql/updates/world/3.3.5/2016_06_05_04_world.sql b/sql/updates/world/3.3.5/2016_06_05_04_world.sql
new file mode 100644
index 00000000000..fdf6b535f8d
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_05_04_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `quest_offer_reward` SET `RewardText`="The Malt is brewed, the Boars are dead$BAnd before all is done and anything said$BWe will have to fight for first dibs$BOn these savory Beer Basted Boar Ribs!" WHERE `ID`=384;
diff --git a/sql/updates/world/3.3.5/2016_06_05_05_world.sql b/sql/updates/world/3.3.5/2016_06_05_05_world.sql
new file mode 100644
index 00000000000..9c69b2d7639
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_05_05_world.sql
@@ -0,0 +1,5 @@
+--
+UPDATE `quest_template_addon` SET `PrevQuestID`=8328 WHERE `ID`=10068;
+UPDATE `quest_template_addon` SET `PrevQuestID`=9676 WHERE `ID`=10069;
+UPDATE `quest_template_addon` SET `PrevQuestID`=9393 WHERE `ID`=10070;
+UPDATE `quest_template_addon` SET `PrevQuestID`=8564 WHERE `ID`=10072;
diff --git a/sql/updates/world/3.3.5/2016_06_05_06_world.sql b/sql/updates/world/3.3.5/2016_06_05_06_world.sql
new file mode 100644
index 00000000000..5d63a2c7e37
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_05_06_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `quest_template_addon` SET `PrevQuestID`=8325 WHERE `ID` IN (9393, 8328, 9676, 8564, 9392, 8563);
diff --git a/sql/updates/world/3.3.5/2016_06_05_07_world.sql b/sql/updates/world/3.3.5/2016_06_05_07_world.sql
new file mode 100644
index 00000000000..71d39603080
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_05_07_world.sql
@@ -0,0 +1,4 @@
+-- add missing localization for item "Bamboo Cage Key" (entry: 12301)
+DELETE FROM `locales_item` WHERE `entry`=12301;
+INSERT INTO `locales_item` (`entry`, `name_loc2`, `name_loc3`, `name_loc6`, `name_loc7`, `name_loc8`) VALUES
+(12301, 'Clé de la cage en bambou', 'Bambuskäfigschlüssel', 'Llave de jaula de bambú', 'Llave de jaula de bambú', 'Ключ от бамбуковой клетки');
diff --git a/sql/updates/world/3.3.5/2016_06_05_08_world.sql b/sql/updates/world/3.3.5/2016_06_05_08_world.sql
new file mode 100644
index 00000000000..a2f5c580f92
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_05_08_world.sql
@@ -0,0 +1,2 @@
+-- adding a key requirement for gameobject "Cage Door" (entry: 143979) at Kurzen's Compound by closing it
+UPDATE `gameobject` SET `state`=1 WHERE `guid`=10673;
diff --git a/sql/updates/world/3.3.5/2016_06_05_09_world.sql b/sql/updates/world/3.3.5/2016_06_05_09_world.sql
new file mode 100644
index 00000000000..98f707aafcd
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_05_09_world.sql
@@ -0,0 +1,9 @@
+-- Plague Scientist SAI
+SET @ENTRY := 37023;
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,0,0,100,0,2000,3000,23000,24000,11,71103,0,0,0,0,0,6,0,0,0,0,0,0,0,"Plague Scientist - In Combat - Cast 'Combobulating Spray'"),
+(@ENTRY,0,1,0,0,0,100,0,5000,6000,5000,6000,11,73079,0,0,0,0,0,2,0,0,0,0,0,0,0,"Plague Scientist - In Combat - Cast 'Plague Blast'"),
+(@ENTRY,0,2,0,0,0,100,0,9000,10000,25000,26000,11,69871,0,0,0,0,0,9,0,0,30,0,0,0,0,"Plague Scientist - In Combat - Cast 'Plague Stream'"),
+(@ENTRY,0,3,0,1,0,100,0,2000,3000,10000,10000,11,69871,0,0,0,0,0,9,10404,0,10,0,0,0,0,"Plague Scientist - Out of Combat - Cast 'Plague Stream'");
diff --git a/sql/updates/world/3.3.5/2016_06_05_10_world.sql b/sql/updates/world/3.3.5/2016_06_05_10_world.sql
new file mode 100644
index 00000000000..66c6e8dbc7c
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_05_10_world.sql
@@ -0,0 +1,5 @@
+--
+DELETE FROM `spell_area` WHERE `spell` IN (74092, 74310);
+INSERT INTO `spell_area` (`spell`, `area`, `quest_start`, `quest_end`, `aura_spell`, `racemask`, `gender`, `autocast`, `quest_start_status`) VALUES
+(74092,368,25495,25445,0,0,2,1,74),
+(74310,133,25287,25393,0,0,2,1,74);
diff --git a/sql/updates/world/3.3.5/2016_06_05_11_world.sql b/sql/updates/world/3.3.5/2016_06_05_11_world.sql
new file mode 100644
index 00000000000..3a76d73f9ab
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_05_11_world.sql
@@ -0,0 +1,7 @@
+--
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` IN(13,17) AND `SourceEntry`=58912;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(17,0,58912,0,0,31,1,3,31254,0,0,0,0,'','Deathstorm requires target Lordaeron Footsoldier'),
+(17,0,58912,0,1,31,1,3,32414,0,0,0,0,'','Deathstorm requires target Lordaeron Captain'),
+(13,1,58912,0,0,31,0,3,31254,0,0,0,0,'','Deathstorm can hit Lordaeron Footsoldier'),
+(13,1,58912,0,1,31,0,3,32414,0,0,0,0,'','Deathstorm can hit Lordaeron Captain');
diff --git a/sql/updates/world/3.3.5/2016_06_05_12_world.sql b/sql/updates/world/3.3.5/2016_06_05_12_world.sql
new file mode 100644
index 00000000000..a446260985f
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_05_12_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `creature_template` SET `InhabitType` = 1 WHERE `entry` = 17312;
diff --git a/sql/updates/world/3.3.5/2016_06_06_00_world.sql b/sql/updates/world/3.3.5/2016_06_06_00_world.sql
new file mode 100644
index 00000000000..61d93dab677
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_06_00_world.sql
@@ -0,0 +1,83 @@
+-- ghoul_base_stats
+DELETE FROM `pet_levelstats` WHERE creature_entry = 26125;
+INSERT INTO `pet_levelstats` (`creature_entry`, `level`, `hp`, `mana`, `armor`, `str`, `agi`, `sta`, `inte`, `spi`) VALUES
+(26125,1,48,80,10,20,16,13,20,8),
+(26125,2,105,106,67,22,17,14,21,9),
+(26125,3,162,132,124,24,18,15,22,10),
+(26125,4,219,158,181,26,19,16,23,11),
+(26125,5,276,184,238,28,20,17,24,12),
+(26125,6,333,210,295,30,21,18,25,13),
+(26125,7,390,236,352,32,22,19,26,14),
+(26125,8,447,262,409,34,23,20,27,15),
+(26125,9,504,288,466,36,24,21,28,16),
+(26125,10,561,314,523,38,25,22,29,17),
+(26125,11,618,340,580,40,26,23,30,18),
+(26125,12,675,366,637,42,27,24,31,19),
+(26125,13,732,392,694,44,28,25,32,20),
+(26125,14,789,418,751,46,29,26,33,21),
+(26125,15,846,444,808,48,30,27,34,22),
+(26125,16,903,470,865,50,31,28,35,23),
+(26125,17,960,496,922,52,32,29,36,24),
+(26125,18,1017,522,979,54,33,30,37,25),
+(26125,19,1074,548,1036,56,34,31,38,26),
+(26125,20,1131,574,1093,58,35,32,39,27),
+(26125,21,1188,600,1150,60,36,33,40,28),
+(26125,22,1245,626,1207,62,37,34,41,29),
+(26125,23,1302,652,1264,64,38,35,42,30),
+(26125,24,1359,678,1321,66,39,36,43,31),
+(26125,25,1416,704,1378,68,40,37,44,32),
+(26125,26,1473,730,1435,70,41,38,45,33),
+(26125,27,1530,756,1492,72,42,39,46,34),
+(26125,28,1587,782,1549,74,43,40,47,35),
+(26125,29,1644,808,1606,76,44,41,48,36),
+(26125,30,1701,834,1663,78,45,42,49,37),
+(26125,31,1758,860,1720,80,46,43,50,38),
+(26125,32,1815,886,1777,82,47,44,51,39),
+(26125,33,1872,912,1834,84,48,45,52,40),
+(26125,34,1929,938,1891,86,49,46,53,41),
+(26125,35,1986,964,1948,88,50,47,54,42),
+(26125,36,2043,990,2005,90,51,48,55,43),
+(26125,37,2100,1016,2062,92,52,49,56,44),
+(26125,38,2157,1042,2119,94,53,50,57,45),
+(26125,39,2214,1068,2176,96,54,51,58,46),
+(26125,40,2271,1094,2233,98,55,52,59,47),
+(26125,41,2328,1120,2290,100,56,53,60,48),
+(26125,42,2385,1146,2347,102,57,54,61,49),
+(26125,43,2442,1172,2404,104,58,55,62,50),
+(26125,44,2499,1198,2461,106,59,56,63,51),
+(26125,45,2556,1224,2518,108,60,57,64,52),
+(26125,46,2613,1250,2575,110,61,58,65,53),
+(26125,47,2670,1276,2632,112,62,59,66,54),
+(26125,48,2727,1302,2689,114,63,60,67,55),
+(26125,49,2784,1328,2746,116,64,61,68,56),
+(26125,50,2841,1354,2803,118,65,62,69,57),
+(26125,51,2898,1380,2860,120,66,63,70,58),
+(26125,52,2955,1406,2917,122,67,64,71,59),
+(26125,53,3012,1432,2974,124,68,65,72,60),
+(26125,54,3069,1458,3031,126,69,66,73,61),
+(26125,55,3126,1484,3088,128,70,67,74,62),
+(26125,56,3183,1510,3145,130,71,68,75,63),
+(26125,57,3240,1536,3202,132,72,69,76,64),
+(26125,58,3297,1562,3259,134,73,70,77,65),
+(26125,59,3354,1588,3316,136,74,71,78,66),
+(26125,60,3411,1614,3373,138,75,72,79,67),
+(26125,61,3468,1640,3430,140,76,73,80,68),
+(26125,62,3525,1666,3487,142,77,74,81,69),
+(26125,63,3582,1692,3544,144,78,75,82,70),
+(26125,64,3639,1718,3601,146,79,76,83,71),
+(26125,65,3696,1744,3658,148,80,77,84,72),
+(26125,66,3753,1770,3715,150,81,78,85,73),
+(26125,67,3810,1796,3772,152,82,79,86,74),
+(26125,68,3867,1822,3829,154,83,80,87,75),
+(26125,69,3924,1848,3886,156,84,81,88,76),
+(26125,70,3981,1874,3943,158,85,82,89,77),
+(26125,71,4038,1900,4000,160,86,83,90,78),
+(26125,72,4095,1926,4057,162,87,84,91,79),
+(26125,73,4152,1952,4114,164,88,85,92,80),
+(26125,74,4209,1978,4171,166,89,86,93,81),
+(26125,75,4266,2004,4228,168,90,87,94,82),
+(26125,76,4323,2030,4285,170,91,88,95,83),
+(26125,77,4380,2056,4342,172,92,89,96,84),
+(26125,78,4437,2082,4399,174,93,90,97,85),
+(26125,79,4494,2108,4456,176,94,91,98,86),
+(26125,80,4551,2134,4513,331,95,92,99,87);
diff --git a/sql/updates/world/3.3.5/2016_06_07_00_world.sql b/sql/updates/world/3.3.5/2016_06_07_00_world.sql
new file mode 100644
index 00000000000..fbe7c362718
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_07_00_world.sql
@@ -0,0 +1,2 @@
+-- remove incorrect trigger flag from hodir ice blocks that prevents encounter from starting
+UPDATE `creature_template` SET `flags_extra`=(`flags_extra`&~128) WHERE `entry` IN (32938,33353);
diff --git a/sql/updates/world/3.3.5/2016_06_07_01_world.sql b/sql/updates/world/3.3.5/2016_06_07_01_world.sql
new file mode 100644
index 00000000000..09e86bc0396
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_07_01_world.sql
@@ -0,0 +1,622 @@
+--
+-- Waypoints for Ghostlands
+--
+-- Pathing for Deatholme Acolyte Entry: 16315 'TDB FORMAT'
+SET @NPC := 82514;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=6980.597,`position_y`=-5898.018,`position_z`=28.76383 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,6980.597,-5898.018,28.76383,0,0,0,0,100,0), -- 23:05:14
+(@PATH,2,6980.413,-5864.207,38.00547,0,0,0,0,100,0), -- 23:05:31
+(@PATH,3,6985.412,-5841.971,49.12637,0,0,0,0,100,0), -- 23:05:46
+(@PATH,4,6996.224,-5824.525,58.95233,0,0,0,0,100,0), -- 23:05:56
+(@PATH,5,7008.987,-5810.714,68.33813,0,0,0,0,100,0), -- 23:06:05
+(@PATH,6,7018.887,-5796.988,77.02762,0,0,0,0,100,0), -- 23:06:14
+(@PATH,7,7023.633,-5785.236,83.22521,0,0,0,0,100,0), -- 23:06:21
+(@PATH,8,7025.083,-5767.624,91.65661,0,0,0,0,100,0), -- 23:06:27
+(@PATH,9,7023.818,-5754.515,99.82605,0,0,0,0,100,0), -- 23:06:35
+(@PATH,10,7021.463,-5739.864,105.2905,0,0,0,0,100,0), -- 23:06:42
+(@PATH,11,7023.037,-5750.744,102.3329,0,0,0,0,100,0), -- 23:06:50
+(@PATH,12,7024.833,-5765.023,93.1219,0,0,0,0,100,0), -- 23:06:54
+(@PATH,13,7024.46,-5781.898,84.79234,0,0,0,0,100,0), -- 23:07:01
+(@PATH,14,7021.089,-5792.683,79.57092,0,0,0,0,100,0), -- 23:07:09
+(@PATH,15,7010.271,-5809.296,69.25038,0,0,0,0,100,0), -- 23:07:14
+(@PATH,16,6998.258,-5822.302,60.71892,0,0,0,0,100,0), -- 23:07:23
+(@PATH,17,6986.333,-5840.401,49.7908,0,0,0,0,100,0), -- 23:07:31
+(@PATH,18,6980.666,-5861.458,39.13383,0,0,0,0,100,0); -- 23:07:40
+
+-- Pathing for Deatholme Acolyte Entry: 16315 'TDB FORMAT'
+SET @NPC := 82536;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=6997.067,`position_y`=-5687.621,`position_z`=102.8226 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,6997.067,-5687.621,102.8226,0,0,0,0,100,0), -- 23:06:27
+(@PATH,2,6990.939,-5688.242,101.8386,0,0,0,0,100,0), -- 23:06:32
+(@PATH,3,6976.603,-5693.576,96.38464,0,0,0,0,100,0), -- 23:06:36
+(@PATH,4,6970.503,-5700.29,92.63046,0,0,0,0,100,0), -- 23:06:41
+(@PATH,5,6967.743,-5712.647,88.57698,0,0,0,0,100,0), -- 23:06:45
+(@PATH,6,6970.009,-5720.242,85.64739,0,0,0,0,100,0), -- 23:06:50
+(@PATH,7,6971.563,-5723.634,84.75957,0,0,0,0,100,0), -- 23:06:55
+(@PATH,8,6979.354,-5724.356,84.26402,0,0,0,0,100,0), -- 23:06:57
+(@PATH,9,6979.47,-5714.573,84.58974,0,0,0,0,100,0), -- 23:07:00
+(@PATH,10,6979.149,-5705.578,84.45787,0,0,0,0,100,0), -- 23:07:05
+(@PATH,11,6979.545,-5714.578,84.56152,0,0,0,0,100,0), -- 23:09:00
+(@PATH,12,6979.16,-5705.374,84.45621,0,0,0,0,100,0), -- 23:09:04
+(@PATH,13,6980.682,-5682.834,82.93341,0,0,0,0,100,0), -- 23:09:11
+(@PATH,14,6985.518,-5671.094,82.00629,0,0,0,0,100,0), -- 23:09:17
+(@PATH,15,6990.438,-5665.75,81.61432,0,0,0,0,100,0), -- 23:09:22
+(@PATH,16,6995.886,-5661.015,81.00694,0,0,0,0,100,0), -- 23:09:26
+(@PATH,17,6995.958,-5660.979,80.95592,0,0,0,0,100,0), -- 23:09:29
+(@PATH,18,6990.574,-5665.602,81.49225,0,0,0,0,100,0), -- 23:09:30
+(@PATH,19,6985.71,-5671.139,81.79518,0,0,0,0,100,0), -- 23:09:33
+(@PATH,20,6979.59,-5690.713,83.48748,0,0,0,0,100,0), -- 23:09:38
+(@PATH,21,6979.259,-5705.457,84.32413,0,0,0,0,100,0), -- 23:09:44
+(@PATH,22,6980.716,-5719.662,84.53703,0,0,0,0,100,0), -- 23:09:52
+(@PATH,23,6978.376,-5725.388,84.53719,0,0,0,0,100,0), -- 23:09:56
+(@PATH,24,6977.495,-5726.067,84.54002,0,0,0,0,100,0), -- 23:09:58
+(@PATH,25,6968.405,-5716.007,87.3763,0,0,0,0,100,0), -- 23:10:01
+(@PATH,26,6967.94,-5709.555,89.84632,0,0,0,0,100,0), -- 23:10:06
+(@PATH,27,6974.01,-5696.171,94.75365,0,0,0,0,100,0), -- 23:10:09
+(@PATH,28,6984.721,-5690.32,99.80565,0,0,0,0,100,0); -- 23:10:14
+
+-- Pathing for Deatholme Acolyte Entry: 16315 'TDB FORMAT'
+SET @NPC := 82537;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=7010.643,`position_y`=-5693.538,`position_z`=102.6286 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,7010.643,-5693.538,102.6286,0,0,0,0,100,0), -- 23:06:47
+(@PATH,2,7016.285,-5693.483,102.6231,0,0,0,0,100,0), -- 23:06:49
+(@PATH,3,7018.219,-5692.301,102.6074,0,0,0,0,100,0), -- 23:06:50
+(@PATH,4,7021.005,-5689.024,102.3725,0,0,0,0,100,0), -- 23:06:53
+(@PATH,5,7018.614,-5679.159,102.6098,0,0,0,0,100,0), -- 23:06:56
+(@PATH,6,7014.545,-5677.964,102.6143,0,0,0,0,100,0), -- 23:06:57
+(@PATH,7,7010.401,-5678.611,102.6134,0,0,0,0,100,0), -- 23:07:00
+(@PATH,8,7007.026,-5681.029,102.6129,0,0,0,0,100,0), -- 23:07:02
+(@PATH,9,7004.883,-5684.334,102.6098,0,0,0,0,100,0), -- 23:07:05
+(@PATH,10,7005.852,-5689.117,102.6089,0,0,0,0,100,0); -- 23:07:07
+
+-- Pathing for Deatholme Acolyte Entry: 16315 'TDB FORMAT'
+SET @NPC := 82540;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=7029.595,`position_y`=-5682.818,`position_z`=102.658 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,7029.595,-5682.818,102.658,0,0,0,0,100,0), -- 23:06:56
+(@PATH,2,7035.782,-5681.29,102.0026,0,0,0,0,100,0), -- 23:07:01
+(@PATH,3,7045.729,-5681.199,98.82371,0,0,0,0,100,0), -- 23:07:03
+(@PATH,4,7056.35,-5684.523,93.90004,0,0,0,0,100,0), -- 23:07:07
+(@PATH,5,7045.667,-5681.057,98.76253,0,0,0,0,100,0), -- 23:09:05
+(@PATH,6,7056.332,-5684.539,93.80215,0,0,0,0,100,0), -- 23:09:09
+(@PATH,7,7060.951,-5689.726,91.59099,0,0,0,0,100,0), -- 23:09:13
+(@PATH,8,7064.874,-5703.865,86.7645,0,0,0,0,100,0), -- 23:09:17
+(@PATH,9,7063.655,-5709.466,84.63042,0,0,0,0,100,0), -- 23:09:22
+(@PATH,10,7058.803,-5714.256,84.48442,0,0,0,0,100,0), -- 23:09:27
+(@PATH,11,7057.9,-5714.272,84.27392,0,0,0,0,100,0), -- 23:09:28
+(@PATH,12,7054.177,-5703.301,84.48618,0,0,0,0,100,0), -- 23:09:30
+(@PATH,13,7052.994,-5694.213,84.35367,0,0,0,0,100,0), -- 23:09:37
+(@PATH,14,7043.341,-5673.357,82.8222,0,0,0,0,100,0), -- 23:09:43
+(@PATH,15,7035.741,-5663.536,81.92133,0,0,0,0,100,0), -- 23:09:49
+(@PATH,16,7029.659,-5659.765,81.63133,0,0,0,0,100,0), -- 23:09:52
+(@PATH,17,7022.754,-5657.553,81.0175,0,0,0,0,100,0), -- 23:09:56
+(@PATH,18,7022.701,-5657.519,80.93935,0,0,0,0,100,0), -- 23:10:00
+(@PATH,19,7029.343,-5659.941,81.43478,0,0,0,0,100,0), -- 23:10:01
+(@PATH,20,7038.872,-5666.699,82.0325,0,0,0,0,100,0), -- 23:10:05
+(@PATH,21,7047.313,-5680.742,83.38,0,0,0,0,100,0), -- 23:10:08
+(@PATH,22,7052.837,-5694.202,84.4315,0,0,0,0,100,0), -- 23:10:14
+(@PATH,23,7053.863,-5703.065,84.7151,0,0,0,0,100,0), -- 23:10:20
+(@PATH,24,7054.707,-5709.983,84.50665,0,0,0,0,100,0), -- 23:10:26
+(@PATH,25,7057.84,-5714.267,84.24426,0,0,0,0,100,0), -- 23:10:29
+(@PATH,26,7064.392,-5706.512,85.34109,0,0,0,0,100,0), -- 23:10:30
+(@PATH,27,7063.626,-5695.099,89.8451,0,0,0,0,100,0), -- 23:10:34
+(@PATH,28,7059.115,-5687.389,92.43468,0,0,0,0,100,0), -- 23:10:39
+(@PATH,29,7048.491,-5681.79,97.46969,0,0,0,0,100,0), -- 23:10:43
+(@PATH,30,7038.716,-5681.117,100.7739,0,0,0,0,100,0); -- 23:10:48
+
+-- Pathing for Grimscale Oracle Entry: 15669 'TDB FORMAT'
+SET @NPC := 56234;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=8878.816,`position_y`=-5749.102,`position_z`=0.5971264 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,8878.816,-5749.102,0.5971264,0,0,0,0,100,0), -- 23:32:50
+(@PATH,2,8872.123,-5724.519,0.5082448,0,0,0,0,100,0), -- 23:33:17
+(@PATH,3,8858.525,-5719.116,0.797046,0,0,0,0,100,0), -- 23:33:23
+(@PATH,4,8820.211,-5718.883,-1.039287,0,0,0,0,100,0), -- 23:33:33
+(@PATH,5,8797.094,-5711.732,0.5297012,0,0,0,0,100,0), -- 23:33:43
+(@PATH,6,8789.655,-5709.307,0.9552886,0,0,0,0,100,0), -- 23:33:53
+(@PATH,7,8771.264,-5697.327,1.041862,0,0,0,0,100,0), -- 23:34:01
+(@PATH,8,8754.51,-5692.826,0.9234784,0,0,0,0,100,0), -- 23:34:08
+(@PATH,9,8754.548,-5692.86,0.8107796,0,0,0,0,100,0), -- 23:34:17
+(@PATH,10,8754.832,-5692.778,1.003729,0,0,0,0,100,0), -- 23:34:22
+(@PATH,11,8771.507,-5697.777,0.8035664,0,0,0,0,100,0), -- 23:34:29
+(@PATH,12,8806.005,-5714.252,-1.612888,0,0,0,0,100,0), -- 23:34:38
+(@PATH,13,8829.296,-5721.84,1.24645,0,0,0,0,100,0), -- 23:34:48
+(@PATH,14,8847.945,-5721.054,0.8082525,0,0,0,0,100,0), -- 23:34:57
+(@PATH,15,8858.877,-5719.242,0.7433279,0,0,0,0,100,0), -- 23:35:07
+(@PATH,16,8872.451,-5724.64,0.7027312,0,0,0,0,100,0); -- 23:35:13
+
+-- Pathing for Grimscale Oracle Entry: 15669 'TDB FORMAT'
+SET @NPC := 56221;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=8777.075,`position_y`=-5755.628,`position_z`=0.7944576 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,8777.075,-5755.628,0.7944576,0,0,0,0,100,0), -- 23:25:41
+(@PATH,2,8744.947,-5758.729,1.44137,0,0,0,0,100,0), -- 23:26:14
+(@PATH,3,8723.646,-5744.492,0.7795044,0,0,0,0,100,0), -- 23:26:24
+(@PATH,4,8711.309,-5729.942,1.035426,0,0,0,0,100,0), -- 23:26:32
+(@PATH,5,8691.229,-5710.955,0.2195589,0,0,0,0,100,0), -- 23:26:39
+(@PATH,6,8687.803,-5701.443,-0.1464095,0,0,0,0,100,0), -- 23:26:48
+(@PATH,7,8653.561,-5676.286,1.293998,0,0,0,0,100,0), -- 23:27:01
+(@PATH,8,8641.836,-5678.255,1.193712,0,0,0,0,100,0), -- 23:27:12
+(@PATH,9,8641.773,-5678.348,1.107449,0,0,0,0,100,0), -- 23:27:23
+(@PATH,10,8667.416,-5673.973,0.01454574,0,0,0,0,100,0), -- 23:27:32
+(@PATH,11,8675.772,-5684.51,0.2002553,0,0,0,0,100,0), -- 23:27:43
+(@PATH,12,8690.506,-5709.449,0.5053282,0,0,0,0,100,0), -- 23:27:56
+(@PATH,13,8694.455,-5720.396,0.996207,0,0,0,0,100,0), -- 23:28:04
+(@PATH,14,8711.694,-5730.25,0.9948567,0,0,0,0,100,0), -- 23:28:12
+(@PATH,15,8732.313,-5750.292,1.464421,0,0,0,0,100,0), -- 23:28:20
+(@PATH,16,8751.975,-5757.997,0.9221863,0,0,0,0,100,0), -- 23:28:30
+(@PATH,17,8777.087,-5755.516,0.800478,0,0,0,0,100,0); -- 23:28:43
+
+-- Pathing for Grimscale Forager Entry: 15670 'TDB FORMAT'
+SET @NPC := 56242;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=9071.955,`position_y`=-5877.383,`position_z`=0.6975139 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,9071.955,-5877.383,0.6975139,0,0,0,0,100,0), -- 23:37:45
+(@PATH,2,9059.324,-5868.073,-1.393102,0,0,0,0,100,0), -- 23:38:00
+(@PATH,3,9029.121,-5854.314,0.6379914,0,0,0,0,100,0), -- 23:38:11
+(@PATH,4,9026.947,-5821.172,1.145625,0,0,0,0,100,0), -- 23:38:21
+(@PATH,5,9027.102,-5820.248,1.393944,0,0,0,0,100,0), -- 23:38:35
+(@PATH,6,9032.799,-5775.275,0.952391,0,0,0,0,100,0), -- 23:38:44
+(@PATH,7,9031.125,-5767.591,0.8471048,0,0,0,0,100,0), -- 23:38:56
+(@PATH,8,9008.104,-5754.679,0.8015774,0,0,0,0,100,0), -- 23:39:07
+(@PATH,9,8966.937,-5741.705,1.29663,0,0,0,0,100,0), -- 23:39:17
+(@PATH,10,8962.295,-5740.867,1.235597,0,0,0,0,100,0), -- 23:39:27
+(@PATH,11,8927.979,-5767.035,0.04672858,0,0,0,0,100,0), -- 23:39:37
+(@PATH,12,8938.715,-5761.229,1.038244,0,0,0,0,100,0), -- 23:39:45
+(@PATH,13,8943.727,-5758.281,0.968925,0,0,0,0,100,0), -- 23:39:52
+(@PATH,14,8981.834,-5744.667,0.7889291,0,0,0,0,100,0), -- 23:40:02
+(@PATH,15,8986.465,-5746.015,0.8002989,0,0,0,0,100,0), -- 23:40:12
+(@PATH,16,9008.296,-5754.792,0.820213,0,0,0,0,100,0), -- 23:40:21
+(@PATH,17,9036.458,-5792.002,1.43752,0,0,0,0,100,0), -- 23:40:32
+(@PATH,18,9028.837,-5817.06,1.559729,0,0,0,0,100,0), -- 23:40:45
+(@PATH,19,9023.854,-5848.162,1.221549,0,0,0,0,100,0), -- 23:40:54
+(@PATH,20,9042.734,-5857.301,-2.073786,0,0,0,0,100,0); -- 23:41:08
+
+-- Pathing for Grimscale Seer Entry: 15950 'TDB FORMAT'
+SET @NPC := 56391;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=9037.592,`position_y`=-5766.527,`position_z`=0.5168767 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,9037.592,-5766.527,0.5168767,0,0,0,0,100,0), -- 23:42:42
+(@PATH,2,9048.254,-5784.458,0.9698197,0,0,0,0,100,0), -- 23:42:51
+(@PATH,3,9059.32,-5798.216,-0.9207587,0,0,0,0,100,0), -- 23:42:59
+(@PATH,4,9076.928,-5813.567,0.3946522,0,0,0,0,100,0), -- 23:43:10
+(@PATH,5,9080.393,-5815.896,0.6621327,0,0,0,0,100,0), -- 23:43:18
+(@PATH,6,9088.405,-5809.686,0.7750955,0,0,0,0,100,0), -- 23:43:21
+(@PATH,7,9106.832,-5804.949,0.821775,0,0,0,0,100,0), -- 23:43:28
+(@PATH,8,9123.148,-5807.707,0.8019806,0,0,0,0,100,0), -- 23:43:36
+(@PATH,9,9135.586,-5821.801,0.7773802,0,0,0,0,100,0), -- 23:43:43
+(@PATH,10,9149.662,-5822.438,0.7227378,0,0,0,0,100,0), -- 23:43:49
+(@PATH,11,9167.805,-5833.559,0.5458255,0,0,0,0,100,0), -- 23:43:58
+(@PATH,12,9167.66,-5833.448,0.4231594,0,0,0,0,100,0), -- 23:44:11
+(@PATH,13,9167.701,-5833.285,0.7127371,0,0,0,0,100,0), -- 23:44:23
+(@PATH,14,9149.432,-5822.394,0.7666007,0,0,0,0,100,0), -- 23:44:32
+(@PATH,15,9135.407,-5821.695,0.8019806,0,0,0,0,100,0), -- 23:44:38
+(@PATH,16,9123.027,-5807.496,0.8282324,0,0,0,0,100,0), -- 23:44:45
+(@PATH,17,9106.761,-5805.003,0.785993,0,0,0,0,100,0), -- 23:44:51
+(@PATH,18,9088.161,-5809.791,0.7095211,0,0,0,0,100,0), -- 23:45:00
+(@PATH,19,9071.598,-5809.765,-0.6348054,0,0,0,0,100,0), -- 23:45:03
+(@PATH,20,9050.107,-5787.132,0.9787122,0,0,0,0,100,0), -- 23:45:10
+(@PATH,21,9049.096,-5785.835,1.078146,0,0,0,0,100,0); -- 23:45:20
+
+-- Pathing for Ghostlands Guardian Entry: 16541 'TDB FORMAT'
+SET @NPC := 145414;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=7150.675,`position_y`=-7072.731,`position_z`=55.28159 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,7150.675,-7072.731,55.28159,0,0,0,0,100,0), -- 11:51:25
+(@PATH,2,7140.165,-7095.667,56.32489,0,0,0,0,100,0), -- 11:51:41
+(@PATH,3,7134.295,-7111.137,58.849,0,0,0,0,100,0), -- 11:51:51
+(@PATH,4,7149.599,-7137.551,55.19991,0,0,0,0,100,0), -- 11:51:59
+(@PATH,5,7183.908,-7143.587,56.03042,0,0,0,0,100,0), -- 11:52:11
+(@PATH,6,7218.184,-7136.882,58.99335,0,0,0,0,100,0), -- 11:52:25
+(@PATH,7,7235.5,-7129.492,60.65919,0,0,0,0,100,0), -- 11:52:39
+(@PATH,8,7243.874,-7125.855,61.10926,0,30000,0,0,100,0), -- 11:52:51
+(@PATH,9,7243.135,-7095.02,61.9528,0,0,0,0,100,0), -- 11:53:38
+(@PATH,10,7224.584,-7078.627,58.69924,0,0,0,0,100,0), -- 11:54:28
+(@PATH,11,7189.417,-7063.731,58.10524,0,0,0,0,100,0); -- 11:54:29
+
+-- Pathing for Ghostlands Guardian Entry: 16541 'TDB FORMAT'
+SET @NPC := 81743;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=7483.415,`position_y`=-6898.222,`position_z`=96.65485 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,7483.415,-6898.222,96.65485,0,0,0,0,100,0), -- 22:01:51
+(@PATH,2,7490.502,-6889.069,94.41743,0,0,0,0,100,0), -- 22:01:59
+(@PATH,3,7481.624,-6866.266,88.67288,0,0,0,0,100,0), -- 22:02:05
+(@PATH,4,7480.969,-6837.274,77.65476,0,0,0,0,100,0), -- 22:02:16
+(@PATH,5,7480.024,-6797.451,76.10669,0,0,0,0,100,0), -- 22:02:28
+(@PATH,6,7478.713,-6785.392,77.4765,0,0,0,0,100,0), -- 22:02:43
+(@PATH,7,7479.419,-6793.053,76.67186,0,0,0,0,100,0), -- 22:02:54
+(@PATH,8,7480.9,-6834.077,76.25935,0,0,0,0,100,0), -- 22:03:02
+(@PATH,9,7480.634,-6861.903,86.81428,0,0,0,0,100,0), -- 22:03:17
+(@PATH,10,7490.069,-6885.811,93.34169,0,0,0,0,100,0); -- 22:03:30
+
+-- Pathing for Ghostlands Guardian Entry: 16541 'TDB FORMAT'
+SET @NPC := 81737;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=7546.458,`position_y`=-6726.992,`position_z`=80.78694 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,7546.458,-6726.992,80.78694,0,0,0,0,100,0), -- 22:05:54
+(@PATH,2,7527.194,-6732.486,80.58603,0,0,0,0,100,0), -- 22:06:08
+(@PATH,3,7604.331,-6767.942,85.9845,0,0,0,0,100,0), -- 22:09:49
+(@PATH,4,7593.505,-6753.936,89.24313,0,0,0,0,100,0), -- 22:09:59
+(@PATH,5,7575.111,-6734.221,84.59973,0,0,0,0,100,0); -- 22:10:07
+
+-- Pathing for Ghostlands Guardian Entry: 16541 'TDB FORMAT'
+SET @NPC := 81723;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=7640.057,`position_y`=-6821.591,`position_z`=80.17661 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,7640.057,-6821.591,80.17661,0,0,0,0,100,0), -- 22:05:42
+(@PATH,2,7633.815,-6796.717,78.65404,0,0,0,0,100,0), -- 22:05:51
+(@PATH,3,7615.372,-6775.387,80.24687,0,0,0,0,100,0), -- 22:06:00
+(@PATH,4,7632.267,-6793.745,77.46573,0,0,0,0,100,0), -- 22:06:15
+(@PATH,5,7634.777,-6800.083,79.74638,0,0,0,0,100,0), -- 22:06:27
+(@PATH,6,7649.132,-6834.647,83.15082,0,0,0,0,100,0), -- 22:06:37
+(@PATH,7,7656.086,-6858.044,87.99471,0,0,0,0,100,0), -- 22:06:45
+(@PATH,8,7651.524,-6839.359,84.67632,0,0,0,0,100,0), -- 22:06:56
+(@PATH,9,7640.049,-6821.556,80.16749,0,0,0,0,100,0); -- 22:07:05
+
+-- Pathing for Ghostlands Guardian Entry: 16541 'TDB FORMAT'
+SET @NPC := 81719;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=7563.64,`position_y`=-6881.709,`position_z`=112.1673 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,7563.64,-6881.709,112.1673,0,0,0,0,100,0), -- 18:53:33
+(@PATH,2,7551.659,-6901.236,112.1663,0,0,0,0,100,0), -- 18:53:38
+(@PATH,3,7555.867,-6910.663,111.9691,0,0,0,0,100,0), -- 18:56:12
+(@PATH,4,7565.996,-6914.735,108.4578,0,0,0,0,100,0), -- 18:53:51
+(@PATH,5,7579.56,-6906.405,103.1527,0,0,0,0,100,0), -- 18:54:00
+(@PATH,6,7591.544,-6890.522,95.51781,0,0,0,0,100,0), -- 18:54:08
+(@PATH,7,7595.471,-6871.276,94.72267,0,0,0,0,100,0), -- 18:54:18
+(@PATH,8,7586.251,-6861.987,93.77134,0,0,0,0,100,0), -- 18:54:24
+(@PATH,9,7577.42,-6854.581,93.04897,0,0,0,0,100,0), -- 18:55:26
+(@PATH,10,7578.87,-6826.335,87.31084,0,0,0,0,100,0), -- 18:54:34
+(@PATH,11,7578.864,-6821.618,86.92613,0,0,0,0,100,0), -- 18:54:47
+(@PATH,12,7561.332,-6803.103,87.30068,0,0,0,0,100,0), -- 18:55:15
+(@PATH,13,7560.291,-6799.682,87.58893,0,0,0,0,100,0), -- 18:55:08
+(@PATH,14,7556.946,-6782.622,89.82014,0,0,0,0,100,0), -- 18:54:58
+(@PATH,15,7560.291,-6799.682,87.58893,0,0,0,0,100,0), -- 18:55:08
+(@PATH,16,7561.332,-6803.103,87.30068,0,0,0,0,100,0), -- 18:55:15
+(@PATH,17,7578.864,-6821.618,86.92613,0,0,0,0,100,0), -- 18:54:47
+(@PATH,18,7578.87,-6826.335,87.31084,0,0,0,0,100,0), -- 18:54:34
+(@PATH,19,7577.42,-6854.581,93.04897,0,0,0,0,100,0), -- 18:55:26
+(@PATH,20,7588.399,-6863.539,93.97005,0,0,0,0,100,0), -- 18:55:39
+(@PATH,21,7593.956,-6877.988,95.42189,0,0,0,0,100,0), -- 18:55:48
+(@PATH,22,7583.048,-6903.001,101.4519,0,0,0,0,100,0), -- 18:55:55
+(@PATH,23,7570.524,-6913.488,106.4994,0,0,0,0,100,0), -- 18:56:05
+(@PATH,24,7555.867,-6910.663,111.9691,0,0,0,0,100,0), -- 18:56:12
+(@PATH,25,7551.659,-6901.236,112.1663,0,0,0,0,100,0), -- 18:53:38
+(@PATH,26,7563.374,-6882.594,112.1059,0,0,0,0,100,0); -- 18:56:20
+
+-- Pathing for Ghostlands Guardian Entry: 16541 'TDB FORMAT'
+SET @NPC := 81745;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=7493.75,`position_y`=-6888.333,`position_z`=94.14599 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,7493.75,-6888.333,94.14599,0,0,0,0,100,0), -- 21:57:19
+(@PATH,2,7481.219,-6899.196,97.32906,0,0,0,0,100,0), -- 21:57:29
+(@PATH,3,7455.676,-6912.633,103.082,0,0,0,0,100,0), -- 21:57:36
+(@PATH,4,7435.434,-6934.373,107.2755,0,0,0,0,100,0), -- 21:57:49
+(@PATH,5,7429.151,-6957.596,112.5967,0,0,0,0,100,0), -- 21:58:00
+(@PATH,6,7409.229,-6988.246,112.3306,0,0,0,0,100,0), -- 21:58:16
+(@PATH,7,7398.064,-7006.403,105.4191,0,0,0,0,100,0), -- 21:58:24
+(@PATH,8,7379.978,-7023.313,98.34062,0,0,0,0,100,0), -- 21:58:33
+(@PATH,9,7368.91,-7048.285,91.6894,0,0,0,0,100,0), -- 21:58:44
+(@PATH,10,7362.03,-7076.459,81.8666,0,0,0,0,100,0), -- 21:58:55
+(@PATH,11,7335.145,-7098.242,66.09917,0,0,0,0,100,0), -- 21:59:07
+(@PATH,12,7304.179,-7104.348,54.56339,0,0,0,0,100,0), -- 21:59:23
+(@PATH,13,7332.545,-7099.682,64.96516,0,0,0,0,100,0), -- 21:59:41
+(@PATH,14,7360.992,-7078.073,81.13574,0,0,0,0,100,0), -- 21:59:57
+(@PATH,15,7367.925,-7051.186,90.94432,0,0,0,0,100,0), -- 22:00:12
+(@PATH,16,7376.316,-7028.957,96.4644,0,0,0,0,100,0), -- 22:00:25
+(@PATH,17,7397.015,-7007.736,104.9266,0,0,0,0,100,0), -- 22:00:35
+(@PATH,18,7408.008,-6990.256,111.4358,0,0,0,0,100,0), -- 22:00:46
+(@PATH,19,7411.379,-6986.646,112.7126,0,0,0,0,100,0), -- 22:00:56
+(@PATH,20,7429.151,-6957.596,112.5967,0,0,0,0,100,0), -- 21:58:00
+(@PATH,21,7433.051,-6937.843,108.0633,0,0,0,0,100,0), -- 22:01:05
+(@PATH,22,7445.005,-6922.467,103.7956,0,0,0,0,100,0), -- 22:01:28
+(@PATH,23,7450.903,-6915.155,103.3749,0,0,0,0,100,0), -- 22:01:28
+(@PATH,24,7450.903,-6915.155,103.3749,0,0,0,0,100,0), -- 22:01:28
+(@PATH,25,7477.773,-6901.932,98.37746,0,0,0,0,100,0), -- 22:01:33
+(@PATH,26,7493.729,-6888.343,94.15305,0,0,0,0,100,0); -- 22:01:45
+
+-- Pathing for Blacksmith Frances Entry: 17655 'TDB FORMAT'
+SET @NPC := 81724;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=7604.855,`position_y`=-6905.621,`position_z`=93.76188 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,7604.855,-6905.621,93.76188,0.8203048,60000,0,0,100,0), -- 22:07:38
+(@PATH,2,7600.523,-6904.995,93.88599,0,0,0,0,100,0), -- 22:08:19
+(@PATH,3,7600.523,-6904.995,93.88599,1.780236,0,0,0,100,0), -- 22:08:21
+(@PATH,4,7600.064,-6907.846,93.76472,0,0,0,0,100,0), -- 22:09:30
+(@PATH,5,7600.523,-6904.995,93.88599,0,30000,0,0,100,0), -- 22:10:03
+(@PATH,6,7600.523,-6904.995,93.88599,1.780236,0,0,0,100,0), -- 22:10:04
+(@PATH,7,7598.409,-6904.81,94.34996,0,60000,0,0,100,0), -- 22:10:58
+(@PATH,8,7596.794,-6905.625,94.31394,3.996804,0,0,0,100,0), -- 22:10:59
+(@PATH,9,7600.523,-6904.995,93.88599,0,0,0,0,100,0), -- 22:11:26
+(@PATH,10,7600.523,-6904.995,93.88599,1.780236,0,0,0,100,0), -- 22:11:27
+(@PATH,11,7598.409,-6904.81,94.34996,0,60000,0,0,100,0), -- 22:12:20
+(@PATH,12,7596.794,-6905.625,94.31394,3.996804,0,0,0,100,0), -- 22:12:22
+(@PATH,13,7600.523,-6904.995,93.88599,0,0,0,0,100,0), -- 22:12:42
+(@PATH,14,7600.523,-6904.995,93.88599,1.780236,0,0,0,100,0), -- 22:12:44
+(@PATH,15,7604.855,-6905.621,93.76188,0,120000,0,0,100,0), -- 22:14:00
+(@PATH,16,7604.855,-6905.621,93.76188,0.8203048,0,0,0,100,0); -- 22:14:02
+
+-- Pathing for Rathis Tomber Entry: 16224 'TDB FORMAT'
+SET @NPC := 81720;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=7638.232,`position_y`=-6842.241,`position_z`=84.2546 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,7638.232,-6842.241,84.2546,2.076942,0,0,0,100,0), -- 22:09:02
+(@PATH,2,7636.98,-6839.962,83.24476,0,0,0,0,100,0), -- 22:09:36
+(@PATH,3,7637.41,-6837.574,82.88759,0,0,0,0,100,0), -- 22:09:38
+(@PATH,4,7639.8,-6835.542,82.59454,0,0,0,0,100,0), -- 22:09:39
+(@PATH,5,7643.04,-6835.119,82.58206,0,0,0,0,100,0), -- 22:09:40
+(@PATH,6,7644.657,-6837.574,83.20168,0,0,0,0,100,0), -- 22:09:41
+(@PATH,7,7644.05,-6838.9,83.9032,0,60000,0,0,100,0),
+(@PATH,8,7645.192,-6836.052,83.1027,0,0,0,0,100,0), -- 22:09:50
+(@PATH,9,7642.421,-6834.729,82.59531,0,0,0,0,100,0), -- 22:09:51
+(@PATH,10,7639.884,-6835.1,82.53012,0,0,0,0,100,0), -- 22:09:52
+(@PATH,11,7637.52,-6837.243,82.75238,0,0,0,0,100,0), -- 22:09:53
+(@PATH,12,7636.066,-6839.554,82.94509,0,0,0,0,100,0), -- 22:09:55
+(@PATH,13,7637.412,-6842.98,83.70974,0,10000,0,0,100,0), -- 22:09:56
+(@PATH,14,7638.232,-6842.241,84.2546,0,0,0,0,100,0), -- 22:10:06
+(@PATH,15,7638.232,-6842.241,84.2546,2.076942,60000,0,0,100,0); -- 22:10:06
+
+-- Pathing for Sentinel Infiltrator Entry: 16333 'TDB FORMAT'
+SET @NPC := 85939;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=6826.52,`position_y`=-7216.635,`position_z`=26.2077 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,6826.52,-7216.635,26.2077,0,0,0,0,100,0), -- 18:25:44
+(@PATH,2,6840.17,-7215.392,27.32393,0,0,0,0,100,0), -- 18:25:48
+(@PATH,3,6842.315,-7214.781,27.5872,0,0,0,0,100,0), -- 18:25:52
+(@PATH,4,6847.95,-7208.919,27.60912,0,0,0,0,100,0), -- 18:25:54
+(@PATH,5,6846.517,-7200.238,27.39073,0,0,0,0,100,0), -- 18:25:58
+(@PATH,6,6836.5,-7187.716,26.55817,0,0,0,0,100,0), -- 18:26:01
+(@PATH,7,6829.814,-7187.942,25.16908,0,0,0,0,100,0), -- 18:26:05
+(@PATH,8,6828.214,-7188.198,24.70531,0,0,0,0,100,0), -- 18:26:08
+(@PATH,9,6820.545,-7191.426,24.19164,0,0,0,0,100,0), -- 18:26:11
+(@PATH,10,6816.887,-7196.539,24.25371,0,0,0,0,100,0), -- 18:26:15
+(@PATH,11,6816.825,-7206.355,24.66104,0,0,0,0,100,0), -- 18:26:18
+(@PATH,12,6824.003,-7215.546,25.92787,0,0,0,0,100,0); -- 18:26:22
+
+-- Pathing for Sentinel Infiltrator Entry: 16333 'TDB FORMAT'
+-- Needs SAI scripting
+SET @NPC := 85810;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=6834.944,`position_y`=-7216.469,`position_z`=26.75792 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,6834.944,-7216.469,26.75792,0,0,0,0,100,0), -- 18:21:32
+(@PATH,2,6826.208,-7222.83,27.19634,0,0,0,0,100,0), -- 18:21:40
+(@PATH,3,6817.325,-7206.505,24.92965,0,0,0,0,100,0), -- 18:21:52
+(@PATH,4,6819.723,-7180.195,25.83248,0,0,0,0,100,0), -- 18:22:00
+(@PATH,5,6811.1,-7153.327,37.85592,0,0,0,0,100,0), -- 18:22:11
+(@PATH,6,6794.896,-7138.714,44.19709,0,0,0,0,100,0), -- 18:22:24
+(@PATH,7,6778.596,-7138.577,47.74215,0,0,0,0,100,0), -- 18:22:34
+(@PATH,8,6770.257,-7144.743,49.66928,0,0,0,0,100,0), -- 18:22:40
+(@PATH,9,6786.903,-7138.087,45.32982,0,0,0,0,100,0), -- 18:22:53
+(@PATH,10,6817.342,-7166.106,30.71012,0,0,0,0,100,0), -- 18:23:03
+(@PATH,11,6823.649,-7165.904,28.29505,0,0,0,0,100,0), -- 18:23:20
+(@PATH,12,6835.131,-7148.97,30.26661,0,0,0,0,100,0), -- 18:23:27
+(@PATH,13,6835.175,-7162.583,27.79875,0,0,0,0,100,0), -- 18:23:38
+(@PATH,14,6835.874,-7170.188,26.83617,0,0,0,0,100,0), -- 18:23:45
+(@PATH,15,6827.219,-7186.351,24.99562,0,0,0,0,100,0), -- 18:23:49
+(@PATH,16,6818.312,-7181.476,25.84511,0,0,0,0,100,0), -- 18:23:56
+(@PATH,17,6813.708,-7178.023,26.07334,0,0,0,0,100,0), -- 18:24:03
+(@PATH,18,6800.086,-7180.936,26.13367,0,0,0,0,100,0), -- 18:24:08
+(@PATH,19,6788.234,-7196.194,26.14623,0,0,0,0,100,0), -- 18:24:16
+(@PATH,20,6784.672,-7191.459,26.15236,0,0,0,0,100,0), -- 18:25:03
+(@PATH,21,6802.208,-7180.021,26.09461,0,0,0,0,100,0), -- 18:25:13
+(@PATH,22,6821.094,-7186.088,24.97617,0,0,0,0,100,0), -- 18:25:20
+(@PATH,23,6836.174,-7190.566,26.19097,0,0,0,0,100,0), -- 18:25:24
+(@PATH,24,6844.302,-7187.855,27.69562,0,0,0,0,100,0), -- 18:25:32
+(@PATH,25,6846.742,-7212.095,27.73918,0,0,0,0,100,0); -- 18:25:45
+
+-- Pathing for Sentinel Infiltrator Entry: 16333 'TDB FORMAT'
+-- Needs SAI scripting
+SET @NPC := 85876;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=6814.882,`position_y`=-7163.52,`position_z`=33.06502 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,6814.882,-7163.52,33.06502,0,0,0,0,100,0), -- 18:26:55
+(@PATH,2,6796.829,-7138.427,44.13749,0,0,0,0,100,0), -- 18:27:03
+(@PATH,3,6778.327,-7138.773,48.00482,0,0,0,0,100,0), -- 18:27:16
+(@PATH,4,6776.107,-7139.004,48.73849,0,0,0,0,100,0), -- 18:27:24
+(@PATH,5,6783.224,-7137.825,46.49815,0,0,0,0,100,0), -- 18:27:51
+(@PATH,6,6794.398,-7137.108,44.60288,0,0,0,0,100,0), -- 18:27:56
+(@PATH,7,6800.035,-7146.845,40.49599,0,0,0,0,100,0), -- 18:28:01
+(@PATH,8,6795.779,-7165.81,32.8607,0,0,0,0,100,0), -- 18:28:05
+(@PATH,9,6794.719,-7181.562,26.63479,0,0,0,0,100,0), -- 18:28:14
+(@PATH,10,6794.198,-7190.434,25.95545,0,0,0,0,100,0), -- 18:28:24
+(@PATH,11,6789.857,-7191.004,25.8968,0,0,0,0,100,0), -- 18:28:38
+(@PATH,12,6789.924,-7190.855,26.1468,0,0,0,0,100,0), -- 18:28:41
+(@PATH,13,6801.363,-7179.81,25.90792,0,0,0,0,100,0), -- 18:28:54
+(@PATH,14,6801.586,-7179.51,26.09436,0,0,0,0,100,0), -- 18:29:01
+(@PATH,15,6817.118,-7187.298,24.99203,0,0,0,0,100,0), -- 18:29:06
+(@PATH,16,6818.806,-7191.954,24.44993,0,0,0,0,100,0), -- 18:29:13
+(@PATH,17,6819.498,-7215.1,25.45433,0,0,0,0,100,0), -- 18:29:18
+(@PATH,18,6817.387,-7217.657,26.22639,0,0,0,0,100,0), -- 18:29:24
+(@PATH,19,6815.59,-7207.964,25.15621,0,0,0,0,100,0), -- 18:29:35
+(@PATH,20,6816.641,-7195.688,24.46806,0,0,0,0,100,0), -- 18:29:44
+(@PATH,21,6830.292,-7179.979,26.3147,0,0,0,0,100,0), -- 18:29:50
+(@PATH,22,6823.895,-7177.721,26.77645,0,0,0,0,100,0); -- 18:30:03
+
+-- Pathing for Shadowpine Catlord Entry: 16345 'TDB FORMAT'
+SET @NPC := 85833;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=6825.845,`position_y`=-7407.999,`position_z`=47.05538 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,6825.845,-7407.999,47.05538,0,0,0,0,100,0), -- 18:03:11
+(@PATH,2,6819.822,-7407.742,47.8176,0,0,0,0,100,0), -- 18:03:23
+(@PATH,3,6797.965,-7395.941,47.85873,0,0,0,0,100,0), -- 18:03:32
+(@PATH,4,6790.372,-7391.337,48.14279,0,0,0,0,100,0), -- 18:05:27
+(@PATH,5,6785.934,-7382.063,48.67854,0,0,0,0,100,0), -- 18:05:12
+(@PATH,6,6780.216,-7369.419,49.53757,0,0,0,0,100,0), -- 18:03:44
+(@PATH,7,6762.875,-7356.745,49.3274,0,0,0,0,100,0), -- 18:03:59
+(@PATH,8,6757.482,-7359.899,49.68204,0,0,0,0,100,0), -- 18:04:51
+(@PATH,9,6752.945,-7365.431,51.41992,0,0,0,0,100,0), -- 18:04:05
+(@PATH,10,6736.967,-7385.644,51.58582,0,0,0,0,100,0), -- 18:04:20
+(@PATH,11,6707.192,-7407.871,51.19869,0,0,0,0,100,0), -- 18:04:48
+(@PATH,12,6706.392,-7408.471,51.19869,0,0,0,0,100,0), -- 18:04:48
+(@PATH,13,6736.911,-7385.608,51.53582,0,0,0,0,100,0), -- 18:04:48
+(@PATH,14,6752.945,-7365.431,51.41992,0,0,0,0,100,0), -- 18:04:05
+(@PATH,15,6757.482,-7359.899,49.68204,0,0,0,0,100,0), -- 18:04:51
+(@PATH,16,6765.563,-7357.226,49.71237,0,0,0,0,100,0), -- 18:05:06
+(@PATH,17,6780.216,-7369.419,49.53757,0,0,0,0,100,0), -- 18:03:44
+(@PATH,18,6785.934,-7382.063,48.67854,0,0,0,0,100,0), -- 18:05:12
+(@PATH,19,6790.372,-7391.337,48.14279,0,0,0,0,100,0), -- 18:05:27
+(@PATH,20,6797.965,-7395.941,47.85873,0,0,0,0,100,0), -- 18:03:32
+(@PATH,21,6819.822,-7407.742,47.8176,0,0,0,0,100,0); -- 18:03:23
+
+-- Pathing for Shadowpine Catlord Entry: 16345 'TDB FORMAT'
+SET @NPC := 85899;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=6642.614,`position_y`=-7403.334,`position_z`=65.37686 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,6642.614,-7403.334,65.37686,0,0,0,0,100,0), -- 18:12:02
+(@PATH,2,6655.589,-7402.668,65.25717,0,0,0,0,100,0), -- 18:12:07
+(@PATH,3,6659.145,-7404.814,64.66093,0,0,0,0,100,0), -- 18:12:13
+(@PATH,4,6666.81,-7405.762,59.45066,0,0,0,0,100,0), -- 18:12:16
+(@PATH,5,6670.078,-7400.617,57.92281,0,0,0,0,100,0), -- 18:12:19
+(@PATH,6,6683.644,-7387.567,57.7993,0,0,0,0,100,0), -- 18:12:25
+(@PATH,7,6694.211,-7385.182,53.51888,0,0,0,0,100,0), -- 18:12:30
+(@PATH,8,6701.323,-7375.21,53.19016,0,0,0,0,100,0), -- 18:12:39
+(@PATH,9,6706.042,-7306.476,52.34984,0,0,0,0,100,0), -- 18:12:56
+(@PATH,10,6698.629,-7306.6,52.3459,0,0,0,0,100,0), -- 18:13:09
+(@PATH,11,6658.128,-7346.422,53.5539,0,0,0,0,100,0), -- 18:13:25
+(@PATH,12,6663.863,-7357.194,55.34796,0,0,0,0,100,0), -- 18:13:40
+(@PATH,13,6687.574,-7370.823,53.74558,0,0,0,0,100,0), -- 18:13:48
+(@PATH,14,6692.782,-7383.596,54.75917,0,0,0,0,100,0), -- 18:14:00
+(@PATH,15,6679.604,-7389.391,57.81517,0,0,0,0,100,0), -- 18:14:09
+(@PATH,16,6668.09,-7405,57.93337,0,0,0,0,100,0), -- 18:14:14
+(@PATH,17,6663.221,-7406.32,61.86858,0,0,0,0,100,0), -- 18:14:20
+(@PATH,18,6657.667,-7403.231,64.99197,0,0,0,0,100,0), -- 18:14:23
+(@PATH,19,6646.945,-7407.651,65.2119,0,0,0,0,100,0), -- 18:14:27
+(@PATH,20,6642.138,-7401.195,67.02313,0,0,0,0,100,0), -- 18:14:32
+(@PATH,21,6643.672,-7393.591,70.57539,0,0,0,0,100,0), -- 18:14:37
+(@PATH,22,6648.191,-7390.153,70.75128,0,0,0,0,100,0), -- 18:14:41
+(@PATH,23,6655.95,-7390.098,70.72308,0,0,0,0,100,0), -- 18:14:45
+(@PATH,24,6672.11,-7389.826,70.80399,0,0,0,0,100,0), -- 18:14:49
+(@PATH,25,6674.516,-7400.391,70.78954,0,0,0,0,100,0), -- 18:14:54
+(@PATH,26,6670.333,-7405.347,70.74722,0,0,0,0,100,0), -- 18:14:58
+(@PATH,27,6655.763,-7405.991,70.77985,0,0,0,0,100,0), -- 18:15:03
+(@PATH,28,6652.884,-7398.17,70.53949,0,0,0,0,100,0), -- 18:15:08
+(@PATH,29,6648.519,-7390.229,70.74633,0,0,0,0,100,0), -- 18:15:14
+(@PATH,30,6643.527,-7393.528,70.72253,0,0,0,0,100,0), -- 18:15:17
+(@PATH,31,6642.74,-7403.402,65.47425,0,0,0,0,100,0); -- 18:15:22
+
+-- Pathing for Shadowpine Hexxer Entry: 16346 'TDB FORMAT'
+SET @NPC := 85922;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=6544.311,`position_y`=-7415.042,`position_z`=66.8414 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,6544.311,-7415.042,66.8414,0,0,0,0,100,0), -- 18:12:06
+(@PATH,2,6557.531,-7398.131,62.547,0,0,0,0,100,0), -- 18:12:18
+(@PATH,3,6584.465,-7368.215,56.64576,0,0,0,0,100,0), -- 18:12:52
+(@PATH,4,6589.184,-7361.762,55.35123,0,0,0,0,100,0), -- 18:12:52
+(@PATH,5,6593.902,-7355.309,54.72623,0,0,0,0,100,0), -- 18:12:52
+(@PATH,6,6598.534,-7348.974,54.28678,0,0,0,0,100,0), -- 18:12:52
+(@PATH,7,6603.207,-7346.335,54.47303,0,0,0,0,100,0), -- 18:15:13
+(@PATH,8,6609.078,-7343.148,54.03077,0,0,0,0,100,0), -- 18:12:53
+(@PATH,9,6619.535,-7340.988,53.94233,0,0,0,0,100,0), -- 18:15:00
+(@PATH,10,6636.512,-7345.48,53.38771,0,0,0,0,100,0), -- 18:13:02
+(@PATH,11,6650.978,-7350.788,53.67146,0,0,0,0,100,0), -- 18:14:42
+(@PATH,12,6679.457,-7366.645,54.62379,0,0,0,0,100,0), -- 18:13:15
+(@PATH,13,6688.482,-7368.755,53.68621,0,0,0,0,100,0), -- 18:13:31
+(@PATH,14,6707.076,-7373.765,53.0295,0,0,0,0,100,0), -- 18:14:20
+(@PATH,15,6724.337,-7391.231,52.32455,0,0,0,0,100,0), -- 18:13:40
+(@PATH,16,6742.169,-7407.499,51.53728,0,0,0,0,100,0), -- 18:13:54
+(@PATH,17,6740.595,-7406.18,51.4976,0,0,0,0,100,0), -- 18:14:08
+(@PATH,18,6724.337,-7391.231,52.32455,0,0,0,0,100,0), -- 18:13:40
+(@PATH,19,6707.076,-7373.765,53.0295,0,0,0,0,100,0), -- 18:14:20
+(@PATH,20,6686.671,-7368.761,53.71722,0,0,0,0,100,0), -- 18:14:34
+(@PATH,21,6679.457,-7366.645,54.62379,0,0,0,0,100,0), -- 18:13:15
+(@PATH,22,6650.978,-7350.788,53.67146,0,0,0,0,100,0), -- 18:14:42
+(@PATH,23,6636.512,-7345.48,53.38771,0,0,0,0,100,0), -- 18:13:02
+(@PATH,24,6619.535,-7340.988,53.94233,0,0,0,0,100,0), -- 18:15:00
+(@PATH,25,6609.078,-7343.148,54.03077,0,0,0,0,100,0), -- 18:12:53
+(@PATH,26,6603.207,-7346.335,54.47303,0,0,0,0,100,0), -- 18:15:13
+(@PATH,27,6598.534,-7348.974,54.28678,0,0,0,0,100,0), -- 18:12:52
+(@PATH,28,6593.902,-7355.309,54.72623,0,0,0,0,100,0), -- 18:12:52
+(@PATH,29,6586.425,-7365.703,56.44064,0,0,0,0,100,0), -- 18:15:20
+(@PATH,30,6560.438,-7394.56,61.59495,0,0,0,0,100,0), -- 18:15:30
+(@PATH,31,6544.499,-7415.031,66.93755,0,0,0,0,100,0); -- 18:15:45
diff --git a/sql/updates/world/3.3.5/2016_06_09_00_world.sql b/sql/updates/world/3.3.5/2016_06_09_00_world.sql
new file mode 100644
index 00000000000..f3a8ec3d6e8
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_09_00_world.sql
@@ -0,0 +1,33 @@
+-- Mountaineer Pebblebitty (creature_template.entry 3836)
+SET @ENTRY := 3836;
+
+UPDATE `creature_template` SET `AIName`= "SmartAI", `ScriptName`= '' WHERE `entry`= @ENTRY;
+
+-- Correct gossip_menu_options for Quest 3181 gossip
+DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (1201,1202,1203,1204,1205,1206) AND `id` = 0;
+INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`OptionBroadcastTextID`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`,`BoxBroadcastTextID`) VALUES
+(1201, 0,0, "What's the worst that could happen?", 4266, 1,1, 1202, 0,0,0,'',0),
+(1202, 0,0, "Another way? Do tell...", 4268, 1,1, 1203, 0,0,0,'',0),
+(1203, 0,0, "Orcs? Badlands? I'm invulnerable!", 4270, 1,1, 1204, 0,0,0,'',0),
+(1204, 0,0, "Absolutely!", 4272, 1,1, 1205, 0,0,0,'',0),
+(1205, 0,0, "My apologies, Pebblebitty.", 4274, 1,1, 1206, 0,0,0,'',0),
+(1206, 0,0, "Done, done, and done.", 4276, 1,1, 0, 0,0,0,'',0);
+
+-- Link gossip_menu_option.menu_id to npc_text.ID (1201,1833 already in TDB)
+DELETE FROM `gossip_menu` WHERE `entry` IN (1202,1203,1204,1205,1206);
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES
+(1202,1834),
+(1203,1835),
+(1204,1836),
+(1205,1837),
+(1206,1838);
+
+-- Mountaineer Pebblebitty gossip SAI for quest 3181 (gossip has to be closed)
+DELETE FROM `smart_scripts` WHERE `entryorguid`= @ENTRY AND `source_type` = 0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,62,0,100,0,1206,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Mountaineer Pebblebitty - on Gossip Menu Option 1206 selected - Close Gossip");
+
+-- Condition for gossip_menu_option 1201 and Quest 3181 (The Horn of the Beast)
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`= 15 AND `SourceGroup`= 1201;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(15, 1201,0, 0,0, 28,0, 3181,0,0, 0,0,0, '', 'Show gossip menu option 1201 only if Quest 3181 is completed');
diff --git a/sql/updates/world/3.3.5/2016_06_09_01_world.sql b/sql/updates/world/3.3.5/2016_06_09_01_world.sql
new file mode 100644
index 00000000000..b29242b6038
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_09_01_world.sql
@@ -0,0 +1,14 @@
+-- Majordomo Executus' gossip when friendly (entry 12018 in 3.3.5)
+UPDATE `creature_template` SET `gossip_menu_id` = 4093 WHERE `entry` = 12018;
+
+DELETE FROM `gossip_menu` WHERE `entry` IN (4108,4109,4093) AND `text_id` IN (4995,5011,5012);
+INSERT INTO gossip_menu (`entry`,`text_id`) VALUES
+(4093, 4995), -- 54404 (Majordomo Executus' DB entry ID from retail)
+(4109, 5011), -- 54404 (Majordomo Executus' DB entry ID from retail)
+(4108, 5012); -- 54404 (Majordomo Executus' DB entry ID from retail)
+
+DELETE FROM `gossip_menu_option` WHERE (`menu_id`=4108 AND `id`=0) OR (`menu_id`=4109 AND `id`=0) OR (`menu_id`=4093 AND `id`=0);
+INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`OptionBroadcastTextID`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`,`BoxBroadcastTextID`) VALUES
+(4093,0,0, 'Tell me more.', 7675,1,1,4109,0,0,0,'',0), -- menu_id + text in TDB 6.04
+(4109,0,0, 'What else do you have to say?', 7673,1,1,4108,0,0,0,'',0), -- menu_id + text in TDB 6.04
+(4108,0,0, 'You challenged us and we have come. Where is this master you speak of?\n', 7646,1,1, 0,0,0,0,'',0); -- menu_id + text in TDB 6.04
diff --git a/sql/updates/world/3.3.5/2016_06_09_02_world.sql b/sql/updates/world/3.3.5/2016_06_09_02_world.sql
new file mode 100644
index 00000000000..b2a7d985a9f
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_09_02_world.sql
@@ -0,0 +1,21 @@
+-- Correct gossip menu option lines, text found in broadcast_text:
+DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (6186,6185,6187,6208,6209,6210,6211);
+INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`OptionBroadcastTextID`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`,`BoxBroadcastTextID`) VALUES
+(6186, 0,0, "I am ready to discover where my fortune lies!",10047,1,1,6185,0,0,0,'',0),
+(6185, 0,0, "I slay the man on the spot as my liege would expect me to do, as he is nothing more than a thief and a liar.", 10049,1,1,6187,0,0,0,'',0),
+(6185, 1,0, "I turn over the man to my liege for punishment, as he has broken the law of the land and it is my sworn duty to enforce it.", 10050,1,1,6187,0,0,0,'',0),
+(6185, 2,0, "I confiscate the corn he has stolen, warn him that stealing is a path towards doom and destruction, but I let him go to return to his family.", 10051,1,1,6187,0,0,0,'',0),
+(6185, 3,0, "I allow the man to take enough corn to feed his family for a couple of days, encouraging him to leave the land.", 10052,1,1,6187,0,0,0,'',0),
+(6187, 0,0, "I execute him as per my liege's instructions, and do it in such a manner that he suffers painfully before he dies as retribution for his crimes against my people.", 10075,1,1,6208,0,0,0,'',0),
+(6187, 1,0, "I execute him as per my liege's instructions, but doing so in as painless of a way as possible. Justice must be served, but I can show some compassion.", 10076,1,1,6208,0,0,0,'',0),
+(6187, 2,0, "I risk my own life and free him so that he may prove his innocence. If I can, I'll help him in any way.", 10077,1,1,6208,0,0,0,'',0),
+(6208, 0,0, "I confront the ruler on his malicious behavior, upholding my liege's honor at the risk of any future diplomacy.", 10079,1,1,6209,0,0,0,'',0),
+(6208, 1,0, "I not-so-quietly ignore the insult, hoping to instill a fear in the ruler that he may have gaffed. I then inform my liege of the insult when I return.", 10080,1,1,6209,0,0,0,'',0),
+(6208, 2,0, "I quietly ignore the insult. I will not tell my liege, as I am to secure peace at all costs. It's only an insult - not a declaration of war.", 10081,1,1,6209,0,0,0,'',0),
+(6209, 0,0, "I would speak against my brother joining the order, rushing a permanent breach in our relationship. He would be a danger to himself and those around him, and that is too great a risk hoping he would improve over time.", 10083,1,1,6210,0,0,0,'',0),
+(6209, 1,0, "I would speak for my brother joining the order, potentially risking the safety of the order. I could help him with the order's regimens, and I'd have faith in his ability to adapt and learn.", 10084,1,1,6210,0,0,0,'',0),
+(6209, 2,0, "I would create some surreptitious means to keep my brother out of the order. I can keep him out without him being any bit wiser, thereby saving our familial bonds.", 10085,1,1,6210,0,0,0,'',0),
+(6210, 0,0, "I would show my liege the beast's ear and claim the beast's death as my own, taking the reward for my own use. It is wrong to claim a deed as your own that someone else in fact did.", 10086,1,1,6211,0,0,0,'',0),
+(6210, 1,0, "I would show my liege the beast's ear and claim the beast's death as my own - after all, I did slay it. I would then offer some of the reward to the destitute knight to help his family.", 10088,1,1,6211,0,0,0,'',0),
+(6210, 2,0, "I would remain silent about the kill and allow the knight to claim the reward to aid his family.", 10089,1,1,6211,0,0,0,'',0),
+(6211, 0,0, "I'd love to get one of those written fortunes you mentioned! I've got the space in my inventory for it.", 10091,1,1,0,0,0,0,'',0);
diff --git a/sql/updates/world/3.3.5/2016_06_09_03_world_335.sql b/sql/updates/world/3.3.5/2016_06_09_03_world_335.sql
new file mode 100644
index 00000000000..c4be18500b9
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_09_03_world_335.sql
@@ -0,0 +1,23 @@
+-- Remove outdated ScriptName from NPC 7775 Gregan Brewspewer
+UPDATE `creature_template` SET `ScriptName`= '' WHERE `entry`= 7775;
+
+-- Remove broadcast_text link from Gregan's default gossip "What can I do for ya?"
+-- to enable npc_text.ID 2433 "Hi there! The name's Gregan. What can I do for ya?"
+-- This mixup is caused by invalid duplicate use of BroadcastTextID0 = 8275,
+-- duplicate of npc_text.ID 5695, used by NPC entry 5167 Fenthwick <Rogue Trainer>
+-- Lookup queries to verify this information:
+-- SELECT * FROM `npc_text` WHERE `BroadcastTextID0`= 8275; -- (ID 2433 + 5695)
+-- SELECT * FROM `gossip_menu` WHERE `text_id`= 5695; -- (4561,5695)
+-- SELECT * FROM `gossip_menu_option` WHERE `menu_id`= 4561; -- (id 0,1,2,4) "I'm lookin' for rogue trainin'."
+-- SELECT * FROM `creature_template` WHERE `gossip_menu_id`= 4561; -- (5167 Fenthwick <Rogue Trainer>)
+
+UPDATE `npc_text` SET `BroadcastTextID0`= 0 WHERE `ID`= 2433; -- old (invalid) BroadcastTextID0 : 8275
+
+-- Activate selection of the next gossip menus in the gossip dialogue
+UPDATE `gossip_menu_option` SET `action_menu_id`= 1801 WHERE `menu_id`= 1802 AND `id`= 0;
+UPDATE `gossip_menu_option` SET `action_menu_id`= 1915 WHERE `menu_id`= 1801 AND `id`= 0;
+
+-- Condition for gossip_menu_option.menu_id 1802, shown in Gregan Brewspewer's default gossip menu 2433
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`= 15 AND `SourceGroup`= 1802 AND `SourceEntry`=0;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(15, 1802, 0, 0, 0, 9, 0, 3909, 0, 0, 0, 0, 0, "", "Show Gossip Menu Option menu_id 1802 id 0 if Quest 3909 is taken (active)");
diff --git a/sql/updates/world/3.3.5/2016_06_09_04_world.sql b/sql/updates/world/3.3.5/2016_06_09_04_world.sql
new file mode 100644
index 00000000000..ecff9eb7ce6
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_09_04_world.sql
@@ -0,0 +1,6 @@
+-- NPC ID 17603 Grandmother gossip_menu_option (new rows)
+DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (7441,7442,7443);
+INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`OptionBroadcastTextID`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`,`BoxBroadcastTextID`) VALUES
+(7441,0,0,"Oh, grandmother, what big ears you have.", 14217,0,0,7442,0,0,0,'',0),
+(7442,0,0,"Oh, grandmother, what big eyes you have.", 14219,0,0,7443,0,0,0,'',0),
+(7443,0,0,"Oh, grandmother, what phat lewts you have.",14221,0,0, 0,0,0,0,'',0);
diff --git a/sql/updates/world/3.3.5/2016_06_09_05_world.sql b/sql/updates/world/3.3.5/2016_06_09_05_world.sql
new file mode 100644
index 00000000000..50c99117c03
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_09_05_world.sql
@@ -0,0 +1,82 @@
+-- NPC entry 29665 (Pazik "The Pick" Prylock), 29725 (Benik Boltshear) and 29728 (Walter Soref)
+SET @MENU_ID := 9823;
+SET @Pazik := 29665;
+SET @Benik := 29725;
+SET @Walter := 29728;
+
+-- Corrected gossip menu options based on text found in broadcast_text:
+DELETE FROM `gossip_menu_option` WHERE `menu_id` = @MENU_ID;
+INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`OptionBroadcastTextID`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`,`BoxBroadcastTextID`) VALUES
+(@MENU_ID, 0,0, "I've lost my key to Scholomance.", 30315,1,1,0,0,0,0,'',0),
+(@MENU_ID, 1,0, "I've lost my key to The Arcatraz.", 30316,1,1,0,0,0,0,'',0),
+(@MENU_ID, 2,0, "I've lost my key to The Shattered Halls.", 30317,1,1,0,0,0,0,'',0),
+(@MENU_ID, 3,0, "I've lost my key to Searing Gorge.", 30318,1,1,0,0,0,0,'',0),
+(@MENU_ID, 4,0, "I've lost my Shadowforge Key.", 30319,1,1,0,0,0,0,'',0),
+(@MENU_ID, 5,0, "I've lost The Eye of Haramad.", 30320,1,1,0,0,0,0,'',0),
+(@MENU_ID, 6,0, "I've lost my key to Karazhan.", 30321,1,1,0,0,0,0,'',0),
+(@MENU_ID, 7,0, "I've lost my key to the Violet Hold.", 35500,1,1,0,0,0,0,'',0),
+(@MENU_ID, 8,0, "I've lost my Essence-Infused Moonstone. Can you replace it?", 20969,1,1,0,0,0,0,'',0);
+
+-- Walter Soref is missing his npcflag for gossip (the other 2 locksmiths are OK)
+UPDATE `creature` SET `npcflag`=(`npcflag`|1) WHERE `id` = @Walter;
+
+UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName`= '' WHERE `entry` IN (@Pazik,@Benik,@Walter);
+
+DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryorguid` IN (@Pazik,@Benik,@Walter);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@Pazik, 0,0,9,62,0,100,0,9823,0,0,0,11,54883,0,0,0,0,0,7,0,0,0,0,0,0,0,"Pazik \"The Pick\" Prylock - on Gossip Option 0 selected - cast 'Create Skeleton Key'"),
+(@Pazik, 0,1,9,62,0,100,0,9823,1,0,0,11,54881,0,0,0,0,0,7,0,0,0,0,0,0,0,"Pazik \"The Pick\" Prylock - on Gossip Option 1 selected - cast 'Create Key to the Arcatraz'"),
+(@Pazik, 0,2,9,62,0,100,0,9823,2,0,0,11,54884,0,0,0,0,0,7,0,0,0,0,0,0,0,"Pazik \"The Pick\" Prylock - on Gossip Option 2 selected - cast 'Create Shattered Halls Key'"),
+(@Pazik, 0,3,9,62,0,100,0,9823,3,0,0,11,54880,0,0,0,0,0,7,0,0,0,0,0,0,0,"Pazik \"The Pick\" Prylock - on Gossip Option 3 selected - cast 'Create Key to Searing Gorge'"),
+(@Pazik, 0,4,9,62,0,100,0,9823,4,0,0,11,54882,0,0,0,0,0,7,0,0,0,0,0,0,0,"Pazik \"The Pick\" Prylock - on Gossip Option 4 selected - cast 'Create Shadowforge Key'"),
+(@Pazik, 0,5,9,62,0,100,0,9823,5,0,0,11,54887,0,0,0,0,0,7,0,0,0,0,0,0,0,"Pazik \"The Pick\" Prylock - on Gossip Option 5 selected - cast 'Create They Eye of Haramad'"),
+(@Pazik, 0,6,9,62,0,100,0,9823,6,0,0,11,54885,0,0,0,0,0,7,0,0,0,0,0,0,0,"Pazik \"The Pick\" Prylock - on Gossip Option 6 selected - cast 'Create The Master's Key'"),
+(@Pazik, 0,7,9,62,0,100,0,9823,7,0,0,11,67253,0,0,0,0,0,7,0,0,0,0,0,0,0,"Pazik \"The Pick\" Prylock - on Gossip Option 7 selected - cast 'Create The Violet Hold Key'"),
+(@Pazik, 0,8,9,62,0,100,0,9823,8,0,0,11,40173,0,0,0,0,0,7,0,0,0,0,0,0,0,"Pazik \"The Pick\" Prylock - on Gossip Option 8 selected - cast 'Create Essence-Infused Moonstone'"),
+(@Pazik, 0,9,0,61,0,100,0, 0,0,0,0,72, 0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Pazik \"The Pick\" Prylock - on Gossip Option * selected - close Gossip"),
+(@Benik, 0,0,9,62,0,100,0,9823,0,0,0,11,54883,0,0,0,0,0,7,0,0,0,0,0,0,0,"Benik Boltshear - on Gossip Option 0 selected - cast 'Create Skeleton Key'"),
+(@Benik, 0,1,9,62,0,100,0,9823,1,0,0,11,54881,0,0,0,0,0,7,0,0,0,0,0,0,0,"Benik Boltshear - on Gossip Option 1 selected - cast 'Create Key to the Arcatraz'"),
+(@Benik, 0,2,9,62,0,100,0,9823,2,0,0,11,54884,0,0,0,0,0,7,0,0,0,0,0,0,0,"Benik Boltshear - on Gossip Option 2 selected - cast 'Create Shattered Halls Key'"),
+(@Benik, 0,3,9,62,0,100,0,9823,3,0,0,11,54880,0,0,0,0,0,7,0,0,0,0,0,0,0,"Benik Boltshear - on Gossip Option 3 selected - cast 'Create Key to Searing Gorge'"),
+(@Benik, 0,4,9,62,0,100,0,9823,4,0,0,11,54882,0,0,0,0,0,7,0,0,0,0,0,0,0,"Benik Boltshear - on Gossip Option 4 selected - cast 'Create Shadowforge Key'"),
+(@Benik, 0,5,9,62,0,100,0,9823,5,0,0,11,54887,0,0,0,0,0,7,0,0,0,0,0,0,0,"Benik Boltshear - on Gossip Option 5 selected - cast 'Create They Eye of Haramad'"),
+(@Benik, 0,6,9,62,0,100,0,9823,6,0,0,11,54885,0,0,0,0,0,7,0,0,0,0,0,0,0,"Benik Boltshear - on Gossip Option 6 selected - cast 'Create The Master's Key'"),
+(@Benik, 0,7,9,62,0,100,0,9823,7,0,0,11,67253,0,0,0,0,0,7,0,0,0,0,0,0,0,"Benik Boltshear - on Gossip Option 7 selected - cast 'Create The Violet Hold Key'"),
+(@Benik, 0,8,9,62,0,100,0,9823,8,0,0,11,40173,0,0,0,0,0,7,0,0,0,0,0,0,0,"Benik Boltshear - on Gossip Option 8 selected - cast 'Create Essence-Infused Moonstone'"),
+(@Benik, 0,9,0,61,0,100,0, 0,0,0,0,72, 0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Benik Boltshear - on Gossip Option * selected - close Gossip"),
+(@Walter,0,0,9,62,0,100,0,9823,0,0,0,11,54883,0,0,0,0,0,7,0,0,0,0,0,0,0,"Walter Soref - on Gossip Option 0 selected - cast 'Create Skeleton Key'"),
+(@Walter,0,1,9,62,0,100,0,9823,1,0,0,11,54881,0,0,0,0,0,7,0,0,0,0,0,0,0,"Walter Soref - on Gossip Option 1 selected - cast 'Create Key to the Arcatraz'"),
+(@Walter,0,2,9,62,0,100,0,9823,2,0,0,11,54884,0,0,0,0,0,7,0,0,0,0,0,0,0,"Walter Soref - on Gossip Option 2 selected - cast 'Create Shattered Halls Key'"),
+(@Walter,0,3,9,62,0,100,0,9823,3,0,0,11,54880,0,0,0,0,0,7,0,0,0,0,0,0,0,"Walter Soref - on Gossip Option 3 selected - cast 'Create Key to Searing Gorge'"),
+(@Walter,0,4,9,62,0,100,0,9823,4,0,0,11,54882,0,0,0,0,0,7,0,0,0,0,0,0,0,"Walter Soref - on Gossip Option 4 selected - cast 'Create Shadowforge Key'"),
+(@Walter,0,5,9,62,0,100,0,9823,5,0,0,11,54887,0,0,0,0,0,7,0,0,0,0,0,0,0,"Walter Soref - on Gossip Option 5 selected - cast 'Create They Eye of Haramad'"),
+(@Walter,0,6,9,62,0,100,0,9823,6,0,0,11,54885,0,0,0,0,0,7,0,0,0,0,0,0,0,"Walter Soref - on Gossip Option 6 selected - cast 'Create The Master's Key'"),
+(@Walter,0,7,9,62,0,100,0,9823,7,0,0,11,67253,0,0,0,0,0,7,0,0,0,0,0,0,0,"Walter Soref - on Gossip Option 7 selected - cast 'Create The Violet Hold Key'"),
+(@Walter,0,8,9,62,0,100,0,9823,8,0,0,11,40173,0,0,0,0,0,7,0,0,0,0,0,0,0,"Walter Soref - on Gossip Option 8 selected - cast 'Create Essence-Infused Moonstone'"),
+(@Walter,0,9,0,61,0,100,0, 0,0,0,0,72, 0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Walter Soref - on Gossip Option * selected - close Gossip");
+
+-- conditions for gossip_menu_option.menu_id 9823:
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`= 15 AND `SourceGroup`= @MENU_ID;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(15,@MENU_ID,0,0, 0, 8,0, 5505,0,0, 0,0,0,'',"Show gossip option 9823 id 0 if quest 5505 is rewarded AND player does NOT have item 13704."),
+(15,@MENU_ID,0,0, 0, 2,0,13704,1,0, 1,0,0,'',"Show gossip option 9823 id 0 if player does NOT have item 13704 AND quest 5505 is rewarded."),
+(15,@MENU_ID,0,0, 1, 8,0, 5511,0,0, 0,0,0,'',"Show gossip option 9823 id 0 if quest 5511 is rewarded AND player does NOT have item 13704."),
+(15,@MENU_ID,0,0, 1, 2,0,13704,1,0, 1,0,0,'',"Show gossip option 9823 id 0 if player does NOT have item 13704 AND quest 5511 is rewarded."),
+(15,@MENU_ID,1,0, 0, 8,0,10704,0,0, 0,0,0,'',"Show gossip option 9823 id 1 if quest 10704 is rewarded AND player does NOT have item 31084."),
+(15,@MENU_ID,1,0, 0, 2,0,31084,1,0, 1,0,0,'',"Show gossip option 9823 id 1 if player does NOT have item 31084 AND quest 10704 is rewarded."),
+(15,@MENU_ID,2,0, 0, 8,0,10758,0,0, 0,0,0,'',"Show gossip option 9823 id 2 if quest 10758 is rewarded AND player does NOT have item 28395."),
+(15,@MENU_ID,2,0, 0, 2,0,28395,1,0, 1,0,0,'',"Show gossip option 9823 id 2 if player does NOT have item 28395 AND quest 10758 is rewarded."),
+(15,@MENU_ID,2,0, 1, 8,0,10764,0,0, 0,0,0,'',"Show gossip option 9823 id 2 if quest 10764 is rewarded AND player does NOT have item 28395."),
+(15,@MENU_ID,2,0, 1, 2,0,28395,1,0, 1,0,0,'',"Show gossip option 9823 id 2 if player does NOT have item 28395 AND quest 10764 is rewarded."),
+(15,@MENU_ID,3,0, 0, 8,0, 3201,0,0, 0,0,0,'',"Show gossip option 9823 id 3 if quest 3201 is rewarded AND player does NOT have item 5396."),
+(15,@MENU_ID,3,0, 0, 2,0, 5396,1,0, 1,0,0,'',"Show gossip option 9823 id 3 if player does NOT have item 5396 AND quest 3201 is rewarded."),
+(15,@MENU_ID,4,0, 0, 8,0, 3802,0,0, 0,0,0,'',"Show gossip option 9823 id 4 if quest 3802 is rewarded AND player does NOT have item 11000."),
+(15,@MENU_ID,4,0, 0, 2,0,11000,1,0, 1,0,0,'',"Show gossip option 9823 id 4 if player does NOT have item 11000 AND quest 3802 is rewarded."),
+(15,@MENU_ID,5,0, 0, 8,0,10982,0,0, 0,0,0,'',"Show gossip option 9823 id 5 if quest 10982 is rewarded AND player does NOT have item 32092."),
+(15,@MENU_ID,5,0, 0, 2,0,32092,1,0, 1,0,0,'',"Show gossip option 9823 id 5 if player does NOT have item 32092 AND quest 10982 is rewarded."),
+(15,@MENU_ID,6,0, 0, 8,0, 9837,0,0, 0,0,0,'',"Show gossip option 9823 id 6 if quest 9837 is rewarded AND player does NOT have item 24490."),
+(15,@MENU_ID,6,0, 0, 2,0,24490,1,0, 1,0,0,'',"Show gossip option 9823 id 6 if player does NOT have item 24490 AND quest 9837 is rewarded."),
+(15,@MENU_ID,7,0, 0, 8,0,13159,0,0, 0,0,0,'',"Show gossip option 9823 id 7 if quest 13159 is rewarded AND player does NOT have item 42482."),
+(15,@MENU_ID,7,0, 0, 2,0,42482,1,0, 1,0,0,'',"Show gossip option 9823 id 7 if player does NOT have item 42482 AND quest 13159 is rewarded."),
+(15,@MENU_ID,8,0, 0, 8,0,11011,0,0, 0,0,0,'',"Show gossip option 9823 id 8 if quest 11011 is rewarded AND player does NOT have item 32449."),
+(15,@MENU_ID,8,0, 0, 2,0,32449,1,0, 1,0,0,'',"Show gossip option 9823 id 8 if player does NOT have item 32449 AND quest 11011 is rewarded.");
diff --git a/sql/updates/world/3.3.5/2016_06_09_06_world.sql b/sql/updates/world/3.3.5/2016_06_09_06_world.sql
new file mode 100644
index 00000000000..9037a2a2fe5
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_06_09_06_world.sql
@@ -0,0 +1,3 @@
+-- Wrong respawntimer for Quest GameObjects
+-- Bingles's Toolbucket, Bingles's Blastencapper
+UPDATE `gameobject` SET `spawntimesecs` = 10 WHERE `id` IN (104564,104569,104574,104575);
diff --git a/src/common/Collision/DynamicTree.cpp b/src/common/Collision/DynamicTree.cpp
index 5d2e18b1a2e..111606644de 100644
--- a/src/common/Collision/DynamicTree.cpp
+++ b/src/common/Collision/DynamicTree.cpp
@@ -248,7 +248,7 @@ bool DynamicMapTree::isInLineOfSight(float x1, float y1, float z1, float x2, flo
float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const
{
- G3D::Vector3 v(x, y, z);
+ G3D::Vector3 v(x, y, z + 0.5f);
G3D::Ray r(v, G3D::Vector3(0, 0, -1));
DynamicTreeIntersectionCallback callback(phasemask);
impl->intersectZAllignedRay(r, callback, maxSearchDist);
diff --git a/src/common/Collision/Maps/MapTree.cpp b/src/common/Collision/Maps/MapTree.cpp
index 4d0996e1961..5907971efb9 100644
--- a/src/common/Collision/Maps/MapTree.cpp
+++ b/src/common/Collision/Maps/MapTree.cpp
@@ -22,6 +22,7 @@
#include "VMapDefinitions.h"
#include "Log.h"
#include "Errors.h"
+#include "Metric.h"
#include <string>
#include <sstream>
@@ -415,6 +416,8 @@ namespace VMAP
}
else
iLoadedTiles[packTileID(tileX, tileY)] = false;
+ TC_METRIC_EVENT("map_events", "LoadMapTile",
+ "Map: " + std::to_string(iMapID) + " TileX: " + std::to_string(tileX) + " TileY: " + std::to_string(tileY));
return result;
}
@@ -473,6 +476,8 @@ namespace VMAP
}
}
iLoadedTiles.erase(tile);
+ TC_METRIC_EVENT("map_events", "UnloadMapTile",
+ "Map: " + std::to_string(iMapID) + " TileX: " + std::to_string(tileX) + " TileY: " + std::to_string(tileY));
}
void StaticMapTree::getModelInstances(ModelInstance* &models, uint32 &count)
diff --git a/src/common/Metric/Metric.cpp b/src/common/Metric/Metric.cpp
new file mode 100644
index 00000000000..9484cebcc72
--- /dev/null
+++ b/src/common/Metric/Metric.cpp
@@ -0,0 +1,235 @@
+/*
+* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "Metric.h"
+#include "Log.h"
+#include "Config.h"
+#include "Util.h"
+
+void Metric::Initialize(std::string const& realmName, boost::asio::io_service& ioService, std::function<void()> overallStatusLogger)
+{
+ _realmName = realmName;
+ _batchTimer = Trinity::make_unique<boost::asio::deadline_timer>(ioService);
+ _overallStatusTimer = Trinity::make_unique<boost::asio::deadline_timer>(ioService);
+ _overallStatusLogger = overallStatusLogger;
+ LoadFromConfigs();
+}
+
+bool Metric::Connect()
+{
+ _dataStream.connect(_hostname, _port);
+ auto error = _dataStream.error();
+ if (error)
+ {
+ TC_LOG_ERROR("metric", "Error connecting to '%s:%s', disabling Metric. Error message : %s",
+ _hostname.c_str(), _port.c_str(), error.message().c_str());
+ _enabled = false;
+ return false;
+ }
+ _dataStream.clear();
+ return true;
+}
+
+void Metric::LoadFromConfigs()
+{
+ bool previousValue = _enabled;
+ _enabled = sConfigMgr->GetBoolDefault("Metric.Enable", false);
+ _updateInterval = sConfigMgr->GetIntDefault("Metric.Interval", 10);
+ if (_updateInterval < 1)
+ {
+ TC_LOG_ERROR("metric", "'Metric.Interval' config set to %d, overriding to 1.", _updateInterval);
+ _updateInterval = 1;
+ }
+
+ _overallStatusTimerInterval = sConfigMgr->GetIntDefault("Metric.OverallStatusInterval", 1);
+ if (_overallStatusTimerInterval < 1)
+ {
+ TC_LOG_ERROR("metric", "'Metric.OverallStatusInterval' config set to %d, overriding to 1.", _overallStatusTimerInterval);
+ _overallStatusTimerInterval = 1;
+ }
+
+ // Schedule a send at this point only if the config changed from Disabled to Enabled.
+ // Cancel any scheduled operation if the config changed from Enabled to Disabled.
+ if (_enabled && !previousValue)
+ {
+ std::string connectionInfo = sConfigMgr->GetStringDefault("Metric.ConnectionInfo", "");
+ if (connectionInfo.empty())
+ {
+ TC_LOG_ERROR("metric", "'Metric.ConnectionInfo' not specified in configuration file.");
+ return;
+ }
+
+ Tokenizer tokens(connectionInfo, ';');
+ if (tokens.size() != 3)
+ {
+ TC_LOG_ERROR("metric", "'Metric.ConnectionInfo' specified with wrong format in configuration file.");
+ return;
+ }
+
+ _hostname.assign(tokens[0]);
+ _port.assign(tokens[1]);
+ _databaseName.assign(tokens[2]);
+ Connect();
+
+ ScheduleSend();
+ ScheduleOverallStatusLog();
+ }
+}
+
+void Metric::Update()
+{
+ if (_overallStatusTimerTriggered)
+ {
+ _overallStatusTimerTriggered = false;
+ _overallStatusLogger();
+ }
+}
+
+void Metric::LogEvent(std::string const& category, std::string const& title, std::string const& description)
+{
+ using namespace std::chrono;
+
+ MetricData* data = new MetricData;
+ data->Category = category;
+ data->Timestamp = system_clock::now();
+ data->Type = METRIC_DATA_EVENT;
+ data->Title = title;
+ data->Text = description;
+
+ _queuedData.Enqueue(data);
+}
+
+void Metric::SendBatch()
+{
+ using namespace std::chrono;
+
+ std::stringstream batchedData;
+ MetricData* data;
+ bool firstLoop = true;
+ while (_queuedData.Dequeue(data))
+ {
+ if (!firstLoop)
+ batchedData << "\n";
+
+ batchedData << data->Category;
+ if (!_realmName.empty())
+ batchedData << ",realm=" << _realmName;
+
+ batchedData << " ";
+
+ switch (data->Type)
+ {
+ case METRIC_DATA_VALUE:
+ batchedData << "value=" << data->Value;
+ break;
+ case METRIC_DATA_EVENT:
+ batchedData << "title=\"" << data->Title << "\",text=\"" << data->Text << "\"";
+ break;
+ }
+
+ batchedData << " ";
+
+ batchedData << std::to_string(duration_cast<nanoseconds>(data->Timestamp.time_since_epoch()).count());
+
+ firstLoop = false;
+ delete data;
+ }
+
+ // Check if there's any data to send
+ if (batchedData.tellp() == std::streampos(0))
+ {
+ ScheduleSend();
+ return;
+ }
+
+ if (!_dataStream.good() && !Connect())
+ return;
+
+ _dataStream << "POST " << "/write?db=" << _databaseName << " HTTP/1.1\r\n";
+ _dataStream << "Host: " << _hostname << ":" << _port << "\r\n";
+ _dataStream << "Accept: */*\r\n";
+ _dataStream << "Content-Type: application/octet-stream\r\n";
+ _dataStream << "Content-Transfer-Encoding: binary\r\n";
+
+ _dataStream << "Content-Length: " << std::to_string(batchedData.tellp()) << "\r\n\r\n";
+ _dataStream << batchedData.rdbuf();
+
+ std::string http_version;
+ _dataStream >> http_version;
+ unsigned int status_code = 0;
+ _dataStream >> status_code;
+ if (status_code != 204)
+ {
+ TC_LOG_ERROR("metric", "Error sending data, returned HTTP code: %u", status_code);
+ }
+
+ // Read and ignore the status description
+ std::string status_description;
+ std::getline(_dataStream, status_description);
+ // Read headers
+ std::string header;
+ while (std::getline(_dataStream, header) && header != "\r")
+ {
+ if (header == "Connection: close\r")
+ _dataStream.close();
+ }
+
+ ScheduleSend();
+}
+
+void Metric::ScheduleSend()
+{
+ if (_enabled)
+ {
+ _batchTimer->expires_from_now(boost::posix_time::seconds(_updateInterval));
+ _batchTimer->async_wait(std::bind(&Metric::SendBatch, this));
+ }
+ else
+ {
+ _dataStream.close();
+ MetricData* data;
+ // Clear the queue
+ while (_queuedData.Dequeue(data))
+ ;
+ }
+}
+
+void Metric::ForceSend()
+{
+ // Send what's queued only if io_service is stopped (so only on shutdown)
+ if (_enabled && _batchTimer->get_io_service().stopped())
+ SendBatch();
+}
+
+void Metric::ScheduleOverallStatusLog()
+{
+ if (_enabled)
+ {
+ _overallStatusTimer->expires_from_now(boost::posix_time::seconds(_overallStatusTimerInterval));
+ _overallStatusTimer->async_wait([this](const boost::system::error_code&)
+ {
+ _overallStatusTimerTriggered = true;
+ ScheduleOverallStatusLog();
+ });
+ }
+}
+
+Metric* Metric::instance()
+{
+ static Metric instance;
+ return &instance;
+}
diff --git a/src/common/Metric/Metric.h b/src/common/Metric/Metric.h
new file mode 100644
index 00000000000..1855e1d0098
--- /dev/null
+++ b/src/common/Metric/Metric.h
@@ -0,0 +1,141 @@
+/*
+* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef METRIC_H__
+#define METRIC_H__
+
+#include "Common.h"
+#include "Threading/MPSCQueue.h"
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/algorithm/string.hpp>
+#include <type_traits>
+
+enum MetricDataType
+{
+ METRIC_DATA_VALUE,
+ METRIC_DATA_EVENT
+};
+
+struct MetricData
+{
+ std::string Category;
+ std::chrono::time_point<std::chrono::system_clock> Timestamp;
+ MetricDataType Type;
+
+ // LogValue-specific fields
+ std::string Value;
+
+ // LogEvent-specific fields
+ std::string Title;
+ std::string Text;
+};
+
+class TC_COMMON_API Metric
+{
+private:
+ boost::asio::ip::tcp::iostream _dataStream;
+ MPSCQueue<MetricData> _queuedData;
+ std::unique_ptr<boost::asio::deadline_timer> _batchTimer;
+ std::unique_ptr<boost::asio::deadline_timer> _overallStatusTimer;
+ int32 _updateInterval = 0;
+ int32 _overallStatusTimerInterval = 0;
+ bool _enabled = false;
+ bool _overallStatusTimerTriggered = false;
+ std::string _hostname;
+ std::string _port;
+ std::string _databaseName;
+ std::function<void()> _overallStatusLogger;
+ std::string _realmName;
+
+ bool Connect();
+ void SendBatch();
+ void ScheduleSend();
+ void ScheduleOverallStatusLog();
+
+ template<class T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
+ static std::string FormatInfluxDBValue(T value) { return std::to_string(value) + 'i'; }
+
+ static std::string FormatInfluxDBValue(std::string const& value)
+ {
+ return '"' + boost::replace_all_copy(value, "\"", "\\\"") + '"';
+ }
+
+ static std::string FormatInfluxDBValue(bool value) { return value ? "t" : "f"; }
+ static std::string FormatInfluxDBValue(const char* value) { return FormatInfluxDBValue(std::string(value)); }
+ static std::string FormatInfluxDBValue(double value) { return std::to_string(value); }
+ static std::string FormatInfluxDBValue(float value) { return FormatInfluxDBValue(double(value)); }
+
+public:
+ static Metric* instance();
+
+ void Initialize(std::string const& realmName, boost::asio::io_service& ioService, std::function<void()> overallStatusLogger = [](){});
+ void LoadFromConfigs();
+ void Update();
+
+ template<class T>
+ void LogValue(std::string const& category, T value)
+ {
+ using namespace std::chrono;
+
+ MetricData* data = new MetricData;
+ data->Category = category;
+ data->Timestamp = system_clock::now();
+ data->Type = METRIC_DATA_VALUE;
+ data->Value = FormatInfluxDBValue(value);
+
+ _queuedData.Enqueue(data);
+ }
+
+ void LogEvent(std::string const& category, std::string const& title, std::string const& description);
+
+ void ForceSend();
+ bool IsEnabled() const { return _enabled; }
+};
+
+#define sMetric Metric::instance()
+
+#if PLATFORM != PLATFORM_WINDOWS
+#define TC_METRIC_EVENT(category, title, description) \
+ do { \
+ if (sMetric->IsEnabled()) \
+ sMetric->LogEvent(category, title, description); \
+ } while (0)
+#define TC_METRIC_VALUE(category, value) \
+ do { \
+ if (sMetric->IsEnabled()) \
+ sMetric->LogValue(category, value); \
+ } while (0)
+#else
+#define TC_METRIC_EVENT(category, title, description) \
+ __pragma(warning(push)) \
+ __pragma(warning(disable:4127)) \
+ do { \
+ if (sMetric->IsEnabled()) \
+ sMetric->LogEvent(category, title, description); \
+ } while (0) \
+ __pragma(warning(pop))
+#define TC_METRIC_VALUE(category, value) \
+ __pragma(warning(push)) \
+ __pragma(warning(disable:4127)) \
+ do { \
+ if (sMetric->IsEnabled()) \
+ sMetric->LogValue(category, value); \
+ } while (0) \
+ __pragma(warning(pop))
+#endif
+
+#endif // METRIC_H__
diff --git a/src/server/game/AI/PlayerAI/PlayerAI.cpp b/src/server/game/AI/PlayerAI/PlayerAI.cpp
index 68cb268ac6c..d5c17cce3ad 100644
--- a/src/server/game/AI/PlayerAI/PlayerAI.cpp
+++ b/src/server/game/AI/PlayerAI/PlayerAI.cpp
@@ -893,7 +893,7 @@ PlayerAI::TargetedSpell SimpleCharmedPlayerAI::SelectAppropriateCastForSpec()
VerifyAndPushSpellCast(spells, SPELL_BLIND, TARGET_VICTIM, 2);
VerifyAndPushSpellCast(spells, SPELL_CLOAK_OF_SHADOWS, TARGET_NONE, 2);
- uint32 builder, finisher;
+ uint32 builder = 0, finisher = 0;
switch (GetSpec())
{
case SPEC_ROGUE_ASSASSINATION:
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 7c258e09b09..c631874f18d 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -1480,10 +1480,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (TransportBase* trans = me->GetDirectTransport())
trans->CalculatePassengerPosition(dest.x, dest.y, dest.z);
- me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, dest.x, dest.y, dest.z);
+ me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, dest.x, dest.y, dest.z, e.action.MoveToPos.disablePathfinding == 0);
}
else
- me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
+ me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), e.action.MoveToPos.disablePathfinding == 0);
break;
}
case SMART_ACTION_RESPAWN_TARGET:
@@ -3356,6 +3356,16 @@ void SmartScript::UpdateTimer(SmartScriptHolder& e, uint32 const diff)
}
}
+ // Delay flee for assist event if stunned or rooted
+ if (e.GetActionType() == SMART_ACTION_FLEE_FOR_ASSIST)
+ {
+ if (me && me->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED))
+ {
+ e.timer = 1;
+ return;
+ }
+ }
+
e.active = true;//activate events with cooldown
switch (e.GetEventType())//process ONLY timed events
{
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index 3105f087bf7..828b89ff2d7 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -504,7 +504,7 @@ enum SMART_ACTION
SMART_ACTION_SET_ORIENTATION = 66, //
SMART_ACTION_CREATE_TIMED_EVENT = 67, // id, InitialMin, InitialMax, RepeatMin(only if it repeats), RepeatMax(only if it repeats), chance
SMART_ACTION_PLAYMOVIE = 68, // entry
- SMART_ACTION_MOVE_TO_POS = 69, // PointId, xyz
+ SMART_ACTION_MOVE_TO_POS = 69, // PointId, transport, disablePathfinding
SMART_ACTION_RESPAWN_TARGET = 70, //
SMART_ACTION_EQUIP = 71, // entry, slotmask slot1, slot2, slot3 , only slots with mask set will be sent to client, bits are 1, 2, 4, leaving mask 0 is defaulted to mask 7 (send all), slots1-3 are only used if no entry is set
SMART_ACTION_CLOSE_GOSSIP = 72, // none
@@ -958,6 +958,7 @@ struct SmartAction
{
uint32 pointId;
uint32 transport;
+ uint32 disablePathfinding;
} MoveToPos;
struct
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index d7e478bb4e5..fed41f79b88 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -2004,7 +2004,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED);
SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED);
- uint32 modelId = m_goInfo->building.damagedDisplayId;
+ uint32 modelId = m_goInfo->displayId;
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
if (modelData->DamagedDisplayId)
modelId = modelData->DamagedDisplayId;
@@ -2032,7 +2032,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED);
SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED);
- uint32 modelId = m_goInfo->building.destroyedDisplayId;
+ uint32 modelId = m_goInfo->displayId;
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
if (modelData->DestroyedDisplayId)
modelId = modelData->DestroyedDisplayId;
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 2b092427178..ff3d9ce8e20 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -57,6 +57,7 @@ struct GameObjectTemplate
uint32 openTextID; //4 can be used to replace castBarCaption?
uint32 closeTextID; //5
uint32 ignoredByPathing; //6
+ uint32 conditionID1; //7
} door;
//1 GAMEOBJECT_TYPE_BUTTON
struct
@@ -70,6 +71,7 @@ struct GameObjectTemplate
uint32 openTextID; //6 can be used to replace castBarCaption?
uint32 closeTextID; //7
uint32 losOK; //8
+ uint32 conditionID1; //9
} button;
//2 GAMEOBJECT_TYPE_QUESTGIVER
struct
@@ -84,6 +86,7 @@ struct GameObjectTemplate
uint32 losOK; //7
uint32 allowMounted; //8 Is usable while on mount/vehicle. (0/1)
uint32 large; //9
+ uint32 conditionID1; //10
} questgiver;
//3 GAMEOBJECT_TYPE_CHEST
struct
@@ -105,6 +108,7 @@ struct GameObjectTemplate
uint32 openTextID; //14 can be used to replace castBarCaption?
uint32 groupLootRules; //15
uint32 floatingTooltip; //16
+ uint32 conditionID1; //17
} chest;
//4 GAMEOBJECT_TYPE_BINDER - empty
//5 GAMEOBJECT_TYPE_GENERIC
@@ -117,6 +121,7 @@ struct GameObjectTemplate
uint32 floatOnWater; //4
int32 questID; //5
} _generic;
+ uint32 conditionID1; //6
//6 GAMEOBJECT_TYPE_TRAP
struct
{
@@ -135,6 +140,7 @@ struct GameObjectTemplate
uint32 openTextID; //12 can be used to replace castBarCaption?
uint32 closeTextID; //13
uint32 ignoreTotems; //14
+ uint32 conditionID1; //15
} trap;
//7 GAMEOBJECT_TYPE_CHAIR
struct
@@ -143,6 +149,7 @@ struct GameObjectTemplate
uint32 height; //1
uint32 onlyCreatorUse; //2
uint32 triggeredEvent; //3
+ uint32 conditionID1; //4
} chair;
//8 GAMEOBJECT_TYPE_SPELL_FOCUS
struct
@@ -154,6 +161,8 @@ struct GameObjectTemplate
uint32 questID; //4
uint32 large; //5
uint32 floatingTooltip; //6
+ uint32 floatOnWater; //7
+ uint32 conditionID1; //8
} spellFocus;
//9 GAMEOBJECT_TYPE_TEXT
struct
@@ -162,6 +171,7 @@ struct GameObjectTemplate
uint32 language; //1
uint32 pageMaterial; //2
uint32 allowMounted; //3 Is usable while on mount/vehicle. (0/1)
+ uint32 conditionID1; //4
} text;
//10 GAMEOBJECT_TYPE_GOOBER
struct
@@ -187,6 +197,8 @@ struct GameObjectTemplate
uint32 floatingTooltip; //18
uint32 gossipID; //19
uint32 WorldStateSetsState; //20
+ uint32 floatOnWater; //21
+ uint32 conditionID1; //22
} goober;
//11 GAMEOBJECT_TYPE_TRANSPORT
struct
@@ -196,6 +208,7 @@ struct GameObjectTemplate
uint32 autoCloseTime; //2 secs till autoclose = autoCloseTime / 0x10000
uint32 pause1EventID; //3
uint32 pause2EventID; //4
+ uint32 mapID; //5
} transport;
//12 GAMEOBJECT_TYPE_AREADAMAGE
struct
@@ -216,6 +229,7 @@ struct GameObjectTemplate
uint32 cinematicId; //1
uint32 eventID; //2
uint32 openTextID; //3 can be used to replace castBarCaption?
+ uint32 conditionID1; //4
} camera;
//14 GAMEOBJECT_TYPE_MAPOBJECT - empty
//15 GAMEOBJECT_TYPE_MO_TRANSPORT
@@ -244,9 +258,14 @@ struct GameObjectTemplate
uint32 casterTargetSpellTargets; //5
uint32 castersGrouped; //6
uint32 ritualNoTargetCheck; //7
+ uint32 conditionID1; //8
} summoningRitual;
- //19 GAMEOBJECT_TYPE_MAILBOX - empty
- //20 GAMEOBJECT_TYPE_DONOTUSE - empty
+ //19 GAMEOBJECT_TYPE_MAILBOX
+ struct
+ {
+ uint32 conditionID1; //0
+ } mailbox;
+ //20 GAMEOBJECT_TYPE_DO_NOT_USE - empty
//21 GAMEOBJECT_TYPE_GUARDPOST
struct
{
@@ -261,6 +280,7 @@ struct GameObjectTemplate
uint32 partyOnly; //2
uint32 allowMounted; //3 Is usable while on mount/vehicle. (0/1)
uint32 large; //4
+ uint32 conditionID1; //5
} spellcaster;
//23 GAMEOBJECT_TYPE_MEETINGSTONE
struct
@@ -280,6 +300,7 @@ struct GameObjectTemplate
uint32 noDamageImmune; //5
uint32 openTextID; //6
uint32 losOK; //7
+ uint32 conditionID1; //8
} flagstand;
//25 GAMEOBJECT_TYPE_FISHINGHOLE
struct
@@ -358,21 +379,21 @@ struct GameObjectTemplate
{
uint32 intactNumHits; //0
uint32 creditProxyCreature; //1
- uint32 state1Name; //2
+ uint32 empty1; //2
uint32 intactEvent; //3
- uint32 damagedDisplayId; //4
+ uint32 empty2; //4
uint32 damagedNumHits; //5
uint32 empty3; //6
uint32 empty4; //7
uint32 empty5; //8
uint32 damagedEvent; //9
- uint32 destroyedDisplayId; //10
+ uint32 empty6; //10
uint32 empty7; //11
uint32 empty8; //12
uint32 empty9; //13
uint32 destroyedEvent; //14
uint32 empty10; //15
- uint32 debuildingTimeSecs; //16
+ uint32 rebuildingTimeSecs; //16
uint32 empty11; //17
uint32 destructibleData; //18
uint32 rebuildingEvent; //19
@@ -381,7 +402,11 @@ struct GameObjectTemplate
uint32 damageEvent; //22
uint32 empty14; //23
} building;
- //34 GAMEOBJECT_TYPE_GUILDBANK - empty
+ //34 GAMEOBJECT_TYPE_GUILDBANK
+ struct
+ {
+ uint32 conditionID1; //0
+ } guildbank;
//35 GAMEOBJECT_TYPE_TRAPDOOR
struct
{
diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h
index 9b0f4628364..5478c43326c 100644
--- a/src/server/game/Entities/Item/ItemPrototype.h
+++ b/src/server/game/Entities/Item/ItemPrototype.h
@@ -107,20 +107,20 @@ enum ItemBondingType
enum ItemProtoFlags
{
- ITEM_PROTO_FLAG_UNK1 = 0x00000001, // ?
+ ITEM_PROTO_FLAG_NO_PICKUP = 0x00000001, // ?
ITEM_PROTO_FLAG_CONJURED = 0x00000002, // Conjured item
- ITEM_PROTO_FLAG_OPENABLE = 0x00000004, // Item can be right clicked to open for loot
+ ITEM_PROTO_FLAG_HAS_LOOT = 0x00000004, // Item can be right clicked to open for loot
ITEM_PROTO_FLAG_HEROIC = 0x00000008, // Makes green "Heroic" text appear on item
ITEM_PROTO_FLAG_DEPRECATED = 0x00000010, // Cannot equip or use
ITEM_PROTO_FLAG_INDESTRUCTIBLE = 0x00000020, // Item can not be destroyed, except by using spell (item can be reagent for spell)
- ITEM_PROTO_FLAG_UNK2 = 0x00000040, // ?
+ ITEM_PROTO_FLAG_PLAYER_CAST = 0x00000040, // Item's spells are castable by players
ITEM_PROTO_FLAG_NO_EQUIP_COOLDOWN = 0x00000080, // No default 30 seconds cooldown when equipped
- ITEM_PROTO_FLAG_UNK3 = 0x00000100, // ?
- ITEM_PROTO_FLAG_WRAPPER = 0x00000200, // Item can wrap other items
- ITEM_PROTO_FLAG_UNK4 = 0x00000400, // ?
- ITEM_PROTO_FLAG_PARTY_LOOT = 0x00000800, // Looting this item does not remove it from available loot
+ ITEM_PROTO_FLAG_INT_BONUS_INSTEAD = 0x00000100, // ?
+ ITEM_PROTO_FLAG_IS_WRAPPER = 0x00000200, // Item can wrap other items
+ ITEM_PROTO_FLAG_USES_RESOURCES = 0x00000400, // ?
+ ITEM_PROTO_FLAG_MULTI_DROP = 0x00000800, // Looting this item does not remove it from available loot
ITEM_PROTO_FLAG_REFUNDABLE = 0x00001000, // Item can be returned to vendor for its original cost (extended cost)
- ITEM_PROTO_FLAG_CHARTER = 0x00002000, // Item is guild or arena charter
+ ITEM_PROTO_FLAG_PETITION = 0x00002000, // Item is guild or arena charter
ITEM_PROTO_FLAG_UNK5 = 0x00004000, // Only readable items have this (but not all)
ITEM_PROTO_FLAG_UNK6 = 0x00008000, // ?
ITEM_PROTO_FLAG_UNK7 = 0x00010000, // ?
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index daad0c9d958..e389af1f636 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1445,7 +1445,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
bool canSwim = ToCreature()->CanSwim();
float ground_z = z;
float max_z = canSwim
- ? GetMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK))
+ ? GetMap()->GetWaterOrGroundLevel(GetPhaseMask(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK))
: ((ground_z = GetMap()->GetHeight(GetPhaseMask(), x, y, z, true)));
if (max_z > INVALID_HEIGHT)
{
@@ -1469,7 +1469,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
if (!ToPlayer()->CanFly())
{
float ground_z = z;
- float max_z = GetMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK));
+ float max_z = GetMap()->GetWaterOrGroundLevel(GetPhaseMask(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK));
if (max_z > INVALID_HEIGHT)
{
if (z > max_z)
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index e133e550e9b..bcf16b08b27 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -7210,6 +7210,13 @@ void Player::DuelComplete(DuelCompleteType type)
if (!duel)
return;
+ // Check if DuelComplete() has been called already up in the stack and in that case don't do anything else here
+ if (duel->isCompleted || ASSERT_NOTNULL(duel->opponent->duel)->isCompleted)
+ return;
+
+ duel->isCompleted = true;
+ duel->opponent->duel->isCompleted = true;
+
TC_LOG_DEBUG("entities.unit", "Player::DuelComplete: Player '%s' (%s), Opponent: '%s' (%s)",
GetName().c_str(), GetGUID().ToString().c_str(), duel->opponent->GetName().c_str(), duel->opponent->GetGUID().ToString().c_str());
@@ -12323,7 +12330,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
// Delete rolled money / loot from db.
// MUST be done before RemoveFromWorld() or GetTemplate() fails
if (ItemTemplate const* pTmp = pItem->GetTemplate())
- if (pTmp->Flags & ITEM_PROTO_FLAG_OPENABLE)
+ if (pTmp->Flags & ITEM_PROTO_FLAG_HAS_LOOT)
pItem->ItemContainerDeleteLootMoneyAndLootItemsFromDB();
if (IsInWorld() && update)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 45f94eb5b17..80c14b3fbae 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -269,6 +269,7 @@ struct PlayerInfo
uint16 displayId_f;
PlayerCreateInfoItems item;
PlayerCreateInfoSpells customSpells;
+ PlayerCreateInfoSpells castSpells;
PlayerCreateInfoActions action;
PlayerCreateInfoSkills skills;
@@ -288,7 +289,7 @@ struct PvPInfo
struct DuelInfo
{
- DuelInfo() : initiator(nullptr), opponent(nullptr), startTimer(0), startTime(0), outOfBound(0), isMounted(false) { }
+ DuelInfo() : initiator(nullptr), opponent(nullptr), startTimer(0), startTime(0), outOfBound(0), isMounted(false), isCompleted(false) { }
Player* initiator;
Player* opponent;
@@ -296,6 +297,7 @@ struct DuelInfo
time_t startTime;
time_t outOfBound;
bool isMounted;
+ bool isCompleted;
};
struct Areas
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 2aa32374087..fe8cb996135 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -11398,10 +11398,8 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy)
if (enemy)
{
if (IsAIEnabled)
- {
creature->AI()->EnterCombat(enemy);
- RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); // unit has engaged in combat, remove immunity so players can fight back
- }
+
if (creature->GetFormation())
creature->GetFormation()->MemberAttackStart(creature, enemy);
}
@@ -11442,9 +11440,6 @@ void Unit::ClearInCombat()
// Player's state will be cleared in Player::UpdateContestedPvP
if (Creature* creature = ToCreature())
{
- if (creature->GetCreatureTemplate() && creature->GetCreatureTemplate()->unit_flags & UNIT_FLAG_IMMUNE_TO_PC)
- SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); // set immunity state to the one from db on evade
-
ClearUnitState(UNIT_STATE_ATTACK_PLAYER);
if (HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TAPPED))
SetUInt32Value(UNIT_DYNAMIC_FLAGS, creature->GetCreatureTemplate()->dynamicflags);
@@ -16759,7 +16754,7 @@ void Unit::_ExitVehicle(Position const* exitPosition)
Movement::MoveSplineInit init(this);
// Creatures without inhabit type air should begin falling after exiting the vehicle
- if (GetTypeId() == TYPEID_UNIT && !CanFly() && height > GetMap()->GetWaterOrGroundLevel(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), &height) + 0.1f)
+ if (GetTypeId() == TYPEID_UNIT && !CanFly() && height > GetMap()->GetWaterOrGroundLevel(GetPhaseMask(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), &height) + 0.1f)
init.SetFall();
init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), height, false);
@@ -17236,7 +17231,6 @@ bool Unit::SetWalk(bool enable)
AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
else
RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
-
return true;
}
@@ -17251,15 +17245,7 @@ bool Unit::SetDisableGravity(bool disable, bool /*packetOnly = false*/)
RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
}
else
- {
RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
- if (!HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
- {
- m_movementInfo.SetFallTime(0);
- AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
- }
- }
-
return true;
}
@@ -17272,7 +17258,6 @@ bool Unit::SetSwim(bool enable)
AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
else
RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
-
return true;
}
@@ -17287,15 +17272,7 @@ bool Unit::SetCanFly(bool enable, bool /*packetOnly = false */)
RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
}
else
- {
RemoveUnitMovementFlag(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_MASK_MOVING_FLY);
- if (!IsLevitating())
- {
- m_movementInfo.SetFallTime(0);
- AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
- }
- }
-
return true;
}
@@ -17308,7 +17285,6 @@ bool Unit::SetWaterWalking(bool enable, bool /*packetOnly = false */)
AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
else
RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
-
return true;
}
@@ -17321,7 +17297,6 @@ bool Unit::SetFeatherFall(bool enable, bool /*packetOnly = false */)
AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
else
RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
-
return true;
}
@@ -17349,7 +17324,6 @@ bool Unit::SetHover(bool enable, bool /*packetOnly = false*/)
UpdateHeight(newZ);
}
}
-
return true;
}
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 33a0325851a..73dd7e49f30 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -3529,6 +3529,61 @@ void ObjectMgr::LoadPlayerInfo()
}
}
+ // Load playercreate cast spell
+ TC_LOG_INFO("server.loading", "Loading Player Create Cast Spell Data...");
+ {
+ uint32 oldMSTime = getMSTime();
+
+ QueryResult result = WorldDatabase.PQuery("SELECT raceMask, classMask, spell FROM playercreateinfo_cast_spell");
+
+ if (!result)
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 player create cast spells. DB table `playercreateinfo_cast_spell` is empty.");
+ else
+ {
+ uint32 count = 0;
+
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 raceMask = fields[0].GetUInt32();
+ uint32 classMask = fields[1].GetUInt32();
+ uint32 spellId = fields[2].GetUInt32();
+
+ if (raceMask != 0 && !(raceMask & RACEMASK_ALL_PLAYABLE))
+ {
+ TC_LOG_ERROR("sql.sql", "Wrong race mask %u in `playercreateinfo_cast_spell` table, ignoring.", raceMask);
+ continue;
+ }
+
+ if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
+ {
+ TC_LOG_ERROR("sql.sql", "Wrong class mask %u in `playercreateinfo_cast_spell` table, ignoring.", classMask);
+ continue;
+ }
+
+ for (uint32 raceIndex = RACE_HUMAN; raceIndex < MAX_RACES; ++raceIndex)
+ {
+ if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
+ {
+ for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
+ {
+ if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
+ {
+ if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
+ {
+ info->castSpells.push_back(spellId);
+ ++count;
+ }
+ }
+ }
+ }
+ }
+ } while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u player create cast spells in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ }
+ }
+
// Load playercreate actions
TC_LOG_INFO("server.loading", "Loading Player Create Action Data...");
{
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 19638ec1bf8..786c708da93 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -45,6 +45,7 @@
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
+#include "Metric.h"
class LoginQueryHolder : public SQLQueryHolder
@@ -969,8 +970,14 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
bool firstLogin = pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST);
if (firstLogin)
+ {
pCurrChar->RemoveAtLoginFlag(AT_LOGIN_FIRST);
+ PlayerInfo const* info = sObjectMgr->GetPlayerInfo(pCurrChar->getRace(), pCurrChar->getClass());
+ for (uint32 spellId : info->castSpells)
+ pCurrChar->CastSpell(pCurrChar, spellId, true);
+ }
+
// show time before shutdown if shutdown planned.
if (sWorld->IsShuttingDown())
sWorld->ShutdownMsg(true, pCurrChar);
@@ -995,6 +1002,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
sScriptMgr->OnPlayerLogin(pCurrChar, firstLogin);
+ TC_METRIC_EVENT("player_events", "Login", pCurrChar->GetName());
+
delete holder;
}
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 7f5d882a912..42ce01708eb 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -1095,7 +1095,7 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recvData)
return;
}
- if (!(gift->GetTemplate()->Flags & ITEM_PROTO_FLAG_WRAPPER)) // cheating: non-wrapper wrapper
+ if (!(gift->GetTemplate()->Flags & ITEM_PROTO_FLAG_IS_WRAPPER)) // cheating: non-wrapper wrapper
{
_player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, gift, NULL);
return;
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index 82fdc2e54c7..ad5d8259e15 100644
--- a/src/server/game/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -338,7 +338,7 @@ void WorldSession::DoLootRelease(ObjectGuid lguid)
else
{
// Only delete item if no loot or money (unlooted loot is saved to db) or if it isn't an openable item
- if (pItem->loot.isLooted() || !(proto->Flags & ITEM_PROTO_FLAG_OPENABLE))
+ if (pItem->loot.isLooted() || !(proto->Flags & ITEM_PROTO_FLAG_HAS_LOOT))
player->DestroyItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
}
return; // item can be looted only single player
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index e07e10ab00c..93e986b0339 100644
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -196,7 +196,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
}
// Verify that the bag is an actual bag or wrapped item that can be used "normally"
- if (!(proto->Flags & ITEM_PROTO_FLAG_OPENABLE) && !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
+ if (!(proto->Flags & ITEM_PROTO_FLAG_HAS_LOOT) && !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
{
pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL);
TC_LOG_ERROR("network", "Possible hacking attempt: Player %s [guid: %u] tried to open item [guid: %u, entry: %u] which is not openable!",
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index 390b636bb5e..ebdeb4016dd 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -353,7 +353,7 @@ LootItem::LootItem(LootStoreItem const& li)
conditions = li.conditions;
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemid);
- freeforall = proto && (proto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT);
+ freeforall = proto && (proto->Flags & ITEM_PROTO_FLAG_MULTI_DROP);
follow_loot_rules = proto && (proto->FlagsCu & ITEM_FLAGS_CU_FOLLOW_LOOT_RULES);
needs_quest = li.needs_quest;
@@ -429,7 +429,7 @@ void Loot::AddItem(LootStoreItem const& item)
// non-conditional one-player only items are counted here,
// free for all items are counted in FillFFALoot(),
// non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot()
- if (!item.needs_quest && item.conditions.empty() && !(proto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT))
+ if (!item.needs_quest && item.conditions.empty() && !(proto->Flags & ITEM_PROTO_FLAG_MULTI_DROP))
++unlootedCount;
}
}
@@ -1640,7 +1640,7 @@ void LoadLootTemplates_Item()
// remove real entries and check existence loot
ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
- if (lootIdSet.find(itr->second.ItemId) != lootIdSet.end() && itr->second.Flags & ITEM_PROTO_FLAG_OPENABLE)
+ if (lootIdSet.find(itr->second.ItemId) != lootIdSet.end() && itr->second.Flags & ITEM_PROTO_FLAG_HAS_LOOT)
lootIdSet.erase(itr->second.ItemId);
// output error for any still listed (not referenced from appropriate table) ids
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 794be12ee7c..d9bf1d3bbad 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -2299,12 +2299,12 @@ inline GridMap* Map::GetGrid(float x, float y)
return GridMaps[gx][gy];
}
-float Map::GetWaterOrGroundLevel(float x, float y, float z, float* ground /*= NULL*/, bool /*swim = false*/) const
+float Map::GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, float* ground /*= NULL*/, bool /*swim = false*/) const
{
if (const_cast<Map*>(this)->GetGrid(x, y))
{
// we need ground level (including grid height version) for proper return water level in point
- float ground_z = GetHeight(PHASEMASK_NORMAL, x, y, z, true, 50.0f);
+ float ground_z = GetHeight(phasemask, x, y, z, true, 50.0f);
if (ground)
*ground = ground_z;
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 5f134613e85..48864180b84 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -494,7 +494,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
BattlegroundMap* ToBattlegroundMap() { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap*>(this); else return NULL; }
BattlegroundMap const* ToBattlegroundMap() const { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap const*>(this); return NULL; }
- float GetWaterOrGroundLevel(float x, float y, float z, float* ground = NULL, bool swim = false) const;
+ float GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, float* ground = NULL, bool swim = false) const;
float GetHeight(uint32 phasemask, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const;
void Balance() { _dynamicTree.balance(); }
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index b9df9e3accc..7f77453d00b 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -1490,11 +1490,12 @@ enum GameObjectFlags
{
GO_FLAG_IN_USE = 0x00000001, // disables interaction while animated
GO_FLAG_LOCKED = 0x00000002, // require key, spell, event, etc to be opened. Makes "Locked" appear in tooltip
- GO_FLAG_INTERACT_COND = 0x00000004, // cannot interact (condition to interact)
+ GO_FLAG_INTERACT_COND = 0x00000004, // cannot interact (condition to interact - requires GO_DYNFLAG_LO_ACTIVATE to enable interaction clientside)
GO_FLAG_TRANSPORT = 0x00000008, // any kind of transport? Object can transport (elevator, boat, car)
GO_FLAG_NOT_SELECTABLE = 0x00000010, // not selectable even in GM mode
GO_FLAG_NODESPAWN = 0x00000020, // never despawn, typically for doors, they just change state
- GO_FLAG_TRIGGERED = 0x00000040, // typically, summoned objects. Triggered by spell or other events
+ GO_FLAG_AI_OBSTACLE = 0x00000040, // makes the client register the object in something called AIObstacleMgr, unknown what it does
+ GO_FLAG_FREEZE_ANIMATION = 0x00000080,
GO_FLAG_DAMAGED = 0x00000200,
GO_FLAG_DESTROYED = 0x00000400
};
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 6f7dae1d4f2..d2059886f40 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -479,11 +479,12 @@ void MotionMaster::MoveFall(uint32 id /*=0*/)
if (std::fabs(_owner->GetPositionZ() - tz) < 0.1f)
return;
+ _owner->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
+ _owner->m_movementInfo.SetFallTime(0);
+
+ // don't run spline movement for players
if (_owner->GetTypeId() == TYPEID_PLAYER)
- {
- _owner->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
- _owner->m_movementInfo.SetFallTime(0);
- }
+ return;
Movement::MoveSplineInit init(_owner);
init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz, false);
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
index 421678ded17..59e1fdb3de0 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
@@ -57,7 +57,7 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)
// Limit height change
const float distanceZ = float(rand_norm()) * travelDistZ/2.0f;
destZ = respZ + distanceZ;
- float levelZ = map->GetWaterOrGroundLevel(destX, destY, destZ-2.0f);
+ float levelZ = map->GetWaterOrGroundLevel(creature->GetPhaseMask(), destX, destY, destZ-2.5f);
// Problem here, we must fly above the ground and water, not under. Let's try on next tick
if (levelZ >= destZ)
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 3b4f19adb0b..45d8401bcba 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -25,6 +25,7 @@
#include "DisableMgr.h"
#include "DetourCommon.h"
#include "DetourNavMeshQuery.h"
+#include "Metric.h"
////////////////// PathGenerator //////////////////
PathGenerator::PathGenerator(const Unit* owner) :
@@ -61,6 +62,8 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo
if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z))
return false;
+ TC_METRIC_EVENT("mmap_events", "CalculatePath", "");
+
G3D::Vector3 dest(destX, destY, destZ);
SetEndPosition(dest);
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index ddcc10b53dd..b774463e8fd 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -43,6 +43,7 @@
#include "WardenWin.h"
#include "MoveSpline.h"
#include "WardenMac.h"
+#include "Metric.h"
#include <zlib.h>
@@ -380,6 +381,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
break;
}
+ TC_METRIC_VALUE("processed_packets", processedPackets);
+
_recvQueue.readd(requeuePackets.begin(), requeuePackets.end());
if (m_Socket && m_Socket->IsOpen() && _warden)
@@ -536,6 +539,8 @@ void WorldSession::LogoutPlayer(bool save)
//! Call script hook before deletion
sScriptMgr->OnPlayerLogout(_player);
+ TC_METRIC_EVENT("player_events", "Logout", _player->GetName());
+
//! Remove the player from the world
// the player may not be in the world when logging out
// e.g if he got disconnected during a transfer to another map
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 4133d0c8d65..77757606aad 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -846,16 +846,6 @@ void AuraEffect::UpdatePeriodic(Unit* caster)
case 59911: // Tenacity (vehicle)
GetBase()->RefreshDuration();
break;
- case 66823: case 67618: case 67619: case 67620: // Paralytic Toxin
- // Get 0 effect aura
- if (AuraEffect* slow = GetBase()->GetEffect(0))
- {
- int32 newAmount = slow->GetAmount() - 10;
- if (newAmount < -100)
- newAmount = -100;
- slow->ChangeAmount(newAmount);
- }
- break;
default:
break;
}
@@ -2545,10 +2535,9 @@ void AuraEffect::HandleAuraAllowFlight(AuraApplication const* aurApp, uint8 mode
return;
}
- target->SetCanFly(apply);
-
- if (!apply && target->GetTypeId() == TYPEID_UNIT && !target->IsLevitating())
- target->GetMotionMaster()->MoveFall();
+ if (target->SetCanFly(apply))
+ if (!apply && !target->IsLevitating())
+ target->GetMotionMaster()->MoveFall();
}
void AuraEffect::HandleAuraWaterWalk(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -2938,10 +2927,9 @@ void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const* aurApp,
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if (mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK && (apply || (!target->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !target->HasAuraType(SPELL_AURA_FLY))))
{
- target->SetCanFly(apply);
-
- if (!apply && target->GetTypeId() == TYPEID_UNIT && !target->IsLevitating())
- target->GetMotionMaster()->MoveFall();
+ if (target->SetCanFly(apply))
+ if (!apply && !target->IsLevitating())
+ target->GetMotionMaster()->MoveFall();
}
//! Someone should clean up these hacks and remove it from this function. It doesn't even belong here.
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 37457f36145..b5c5b9f82b6 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -58,6 +58,7 @@
#include "SkillDiscovery.h"
#include "SkillExtraItems.h"
#include "SmartAI.h"
+#include "Metric.h"
#include "TicketMgr.h"
#include "TransportMgr.h"
#include "Unit.h"
@@ -396,6 +397,7 @@ void World::LoadConfigSettings(bool reload)
return;
}
sLog->LoadFromConfig();
+ sMetric->LoadFromConfigs();
}
///- Read the player limit and the Message of the day from the config file
@@ -1937,6 +1939,8 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.worldserver", "World initialized in %u minutes %u seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000));
+ TC_METRIC_EVENT("events", "World initialized", "World initialized in " + std::to_string(startupDuration / 60000) + " minutes " + std::to_string((startupDuration % 60000) / 1000) + " seconds");
+
if (uint32 realmId = sConfigMgr->GetIntDefault("RealmID", 0)) // 0 reserved for auth
sLog->SetRealmId(realmId);
}
@@ -2251,6 +2255,10 @@ void World::Update(uint32 diff)
ProcessCliCommands();
sScriptMgr->OnWorldUpdate(diff);
+
+ // Stats logger update
+ sMetric->Update();
+ TC_METRIC_VALUE("update_time_diff", diff);
}
void World::ForceGameEventUpdate()
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp
index 817aaf0a253..f962a019da6 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp
@@ -187,6 +187,12 @@ public:
events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(17000, 19000));
}
+ void IsSummonedBy(Unit* /*summoner*/) override
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ DoZoneInCombat();
+ }
+
void JustDied(Unit* /*killer*/) override
{
_JustDied();
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
index 4a6fee12098..6fa1093c38f 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
@@ -209,6 +209,7 @@ public:
me->SetUInt32Value(UNIT_NPC_FLAGS, 0);
DoCast(me, SPELL_NEFARIANS_BARRIER);
me->SetStandState(UNIT_STAND_STATE_STAND);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
AttackStart(target);
events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(3000, 10000));
events.ScheduleEvent(EVENT_FEAR, urand(10000, 20000));
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp
index e58bded801b..e97b7cba388 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp
@@ -32,6 +32,7 @@ enum Say
enum Spells
{
+ // @todo orb uses the wrong spell, this needs sniffs
SPELL_MINDCONTROL = 42013,
SPELL_CHANNEL = 45537,
SPELL_EGG_DESTROY = 19873,
@@ -103,7 +104,7 @@ public:
secondPhase = true;
me->RemoveAllAuras();
- me->SetHealth(me->GetMaxHealth());
+ me->SetFullHealth();
}
void DoAction(int32 action) override
@@ -114,6 +115,7 @@ public:
void DamageTaken(Unit* /*who*/, uint32& damage) override
{
+ // @todo this is wrong - razorgore should still take damage, he should just nuke the whole room and respawn if he dies during P1
if (!secondPhase)
damage = 0;
}
@@ -146,6 +148,7 @@ public:
break;
case EVENT_CONFLAGRATION:
DoCastVictim(SPELL_CONFLAGRATION);
+ // @todo is this even necessary? pretty sure AI ignores targets with disorient by default
if (me->GetVictim() && me->EnsureVictim()->HasAura(SPELL_CONFLAGRATION))
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true))
me->TauntApply(target);
@@ -175,10 +178,10 @@ public:
{
if (InstanceScript* instance = go->GetInstanceScript())
if (instance->GetData(DATA_EGG_EVENT) != DONE)
- if (Creature* razor = instance->GetCreature(DATA_RAZORGORE_THE_UNTAMED))
+ if (Creature* razorgore = instance->GetCreature(DATA_RAZORGORE_THE_UNTAMED))
{
- razor->Attack(player, true);
- player->CastSpell(razor, SPELL_MINDCONTROL);
+ razorgore->Attack(player, true);
+ player->CastSpell(razorgore, SPELL_MINDCONTROL);
}
return true;
}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp
index 9b487f7b5f9..8cff67d9f28 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp
@@ -44,16 +44,20 @@ enum Texts
enum Spells
{
- SPELL_MAGIC_REFLECTION = 20619,
- SPELL_DAMAGE_REFLECTION = 21075,
+ SPELL_SUMMON_RAGNAROS = 19774,
SPELL_BLAST_WAVE = 20229,
- SPELL_AEGIS_OF_RAGNAROS = 20620,
SPELL_TELEPORT = 20618,
- SPELL_SUMMON_RAGNAROS = 19774,
+ SPELL_MAGIC_REFLECTION = 20619,
+ SPELL_AEGIS_OF_RAGNAROS = 20620,
+ SPELL_DAMAGE_REFLECTION = 21075
};
-#define GOSSIP_HELLO 4995
-#define GOSSIP_SELECT "Tell me more."
+enum Extras
+{
+ OPTION_ID_YOU_CHALLENGED_US = 0,
+ FACTION_FRIENDLY = 35,
+ MENU_OPTION_YOU_CHALLENGED_US = 4108
+};
enum Events
{
@@ -64,7 +68,7 @@ enum Events
EVENT_OUTRO_1 = 5,
EVENT_OUTRO_2 = 6,
- EVENT_OUTRO_3 = 7,
+ EVENT_OUTRO_3 = 7
};
class boss_majordomo : public CreatureScript
@@ -106,7 +110,7 @@ class boss_majordomo : public CreatureScript
if (!me->FindNearestCreature(NPC_FLAMEWAKER_HEALER, 100.0f) && !me->FindNearestCreature(NPC_FLAMEWAKER_ELITE, 100.0f))
{
instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, me->GetEntry(), me);
- me->setFaction(35);
+ me->setFaction(FACTION_FRIENDLY);
EnterEvadeMode();
Talk(SAY_DEFEAT);
_JustDied();
@@ -184,25 +188,20 @@ class boss_majordomo : public CreatureScript
}
else if (action == ACTION_START_RAGNAROS_ALT)
{
- me->setFaction(35);
+ me->setFaction(FACTION_FRIENDLY);
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
}
- };
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(GOSSIP_HELLO, creature->GetGUID());
- return true;
- }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 /*action*/) override
- {
- player->CLOSE_GOSSIP_MENU();
- creature->AI()->DoAction(ACTION_START_RAGNAROS);
- return true;
- }
+ void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
+ {
+ if (menuId == MENU_OPTION_YOU_CHALLENGED_US && gossipListId == OPTION_ID_YOU_CHALLENGED_US)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ DoAction(ACTION_START_RAGNAROS);
+ }
+ }
+ };
CreatureAI* GetAI(Creature* creature) const override
{
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
index e0cae87051f..a89a6b491e8 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
@@ -159,7 +159,7 @@ class boss_ragnaros : public CreatureScript
break;
case EVENT_INTRO_5:
me->SetReactState(REACT_AGGRESSIVE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
_introState = 2;
break;
default:
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp
index 3f236c060d7..2e4ac11d3fa 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp
@@ -797,46 +797,43 @@ enum RedRidingHood
SAY_WOLF_AGGRO = 0,
SAY_WOLF_SLAY = 1,
SAY_WOLF_HOOD = 2,
+ OPTION_WHAT_PHAT_LEWTS_YOU_HAVE = 7443,
SOUND_WOLF_DEATH = 9275,
SPELL_LITTLE_RED_RIDING_HOOD = 30768,
SPELL_TERRIFYING_HOWL = 30752,
SPELL_WIDE_SWIPE = 30761,
- CREATURE_BIG_BAD_WOLF = 17521,
+ CREATURE_BIG_BAD_WOLF = 17521
};
-
-#define GOSSIP_GRANDMA "What phat lewtz you have grandmother?"
-
-
-
class npc_grandmother : public CreatureScript
{
-public:
- npc_grandmother() : CreatureScript("npc_grandmother") { }
+ public:
+ npc_grandmother() : CreatureScript("npc_grandmother") { }
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_INFO_DEF)
+ struct npc_grandmotherAI : public ScriptedAI
{
- if (Creature* pBigBadWolf = creature->SummonCreature(CREATURE_BIG_BAD_WOLF, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, HOUR*2*IN_MILLISECONDS))
- pBigBadWolf->AI()->AttackStart(player);
+ npc_grandmotherAI(Creature* creature) : ScriptedAI(creature) { }
- creature->DespawnOrUnsummon();
- }
+ void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
+ {
+ if (menuId == OPTION_WHAT_PHAT_LEWTS_YOU_HAVE && gossipListId == 0)
+ {
+ player->CLOSE_GOSSIP_MENU();
- return true;
- }
+ if (Creature* pBigBadWolf = me->SummonCreature(CREATURE_BIG_BAD_WOLF, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, HOUR*2*IN_MILLISECONDS))
+ pBigBadWolf->AI()->AttackStart(player);
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_GRANDMA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
- player->SEND_GOSSIP_MENU(8990, creature->GetGUID());
+ me->DespawnOrUnsummon();
+ }
+ }
+ };
- return true;
- }
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_grandmotherAI(creature);
+ }
};
class boss_bigbadwolf : public CreatureScript
diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
index b794a653791..adcb4f9fc9a 100644
--- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
+++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
@@ -179,7 +179,6 @@ void AddSC_eastern_plaguelands();
void AddSC_ghostlands();
void AddSC_hinterlands();
void AddSC_isle_of_queldanas();
-void AddSC_loch_modan();
void AddSC_redridge_mountains();
void AddSC_silverpine_forest();
void AddSC_stormwind_city();
@@ -357,7 +356,6 @@ void AddEasternKingdomsScripts()
AddSC_ghostlands();
AddSC_hinterlands();
AddSC_isle_of_queldanas();
- AddSC_loch_modan();
AddSC_redridge_mountains();
AddSC_silverpine_forest();
AddSC_stormwind_city();
diff --git a/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp b/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp
deleted file mode 100644
index 151f8270c47..00000000000
--- a/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* ScriptData
-SDName: Loch_Modan
-SD%Complete: 100
-SDComment: Quest support: 3181
-SDCategory: Loch Modan
-EndScriptData */
-
-/* ContentData
-npc_mountaineer_pebblebitty
-EndContentData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "ScriptedGossip.h"
-#include "Player.h"
-
-/*######
-## npc_mountaineer_pebblebitty
-######*/
-
-#define GOSSIP_MP "Open the gate please, i need to get to Searing Gorge"
-
-#define GOSSIP_MP1 "But i need to get there, now open the gate!"
-#define GOSSIP_MP2 "Ok, so what is this other way?"
-#define GOSSIP_MP3 "Doesn't matter, i'm invulnerable."
-#define GOSSIP_MP4 "Yes..."
-#define GOSSIP_MP5 "Ok, i'll try to remember that."
-#define GOSSIP_MP6 "A key? Ok!"
-
-class npc_mountaineer_pebblebitty : public CreatureScript
-{
-public:
- npc_mountaineer_pebblebitty() : CreatureScript("npc_mountaineer_pebblebitty") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(1833, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(1834, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
- player->SEND_GOSSIP_MENU(1835, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+4:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
- player->SEND_GOSSIP_MENU(1836, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+5:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
- player->SEND_GOSSIP_MENU(1837, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+6:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7);
- player->SEND_GOSSIP_MENU(1838, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+7:
- player->CLOSE_GOSSIP_MENU();
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (!player->GetQuestRewardStatus(3181) == 1)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-};
-
-void AddSC_loch_modan()
-{
- new npc_mountaineer_pebblebitty();
-}
diff --git a/src/server/scripts/Kalimdor/zone_feralas.cpp b/src/server/scripts/Kalimdor/zone_feralas.cpp
index 3e67a95b503..f366c3e2c19 100644
--- a/src/server/scripts/Kalimdor/zone_feralas.cpp
+++ b/src/server/scripts/Kalimdor/zone_feralas.cpp
@@ -19,10 +19,15 @@
/* ScriptData
SDName: Feralas
SD%Complete: 100
-SDComment: Quest support: 2767, Special vendor Gregan Brewspewer
+SDComment: Quest support: 2767, 2987
SDCategory: Feralas
EndScriptData */
+/* ContentData
+npc_oox22fe
+spell_gordunni_trap
+EndContentData */
+
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
@@ -32,44 +37,6 @@ EndScriptData */
#include "WorldSession.h"
/*######
-## npc_gregan_brewspewer
-######*/
-
-#define GOSSIP_HELLO "Buy somethin', will ya?"
-
-class npc_gregan_brewspewer : public CreatureScript
-{
-public:
- npc_gregan_brewspewer() : CreatureScript("npc_gregan_brewspewer") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
- player->SEND_GOSSIP_MENU(2434, creature->GetGUID());
- }
- if (action == GOSSIP_ACTION_TRADE)
- player->GetSession()->SendListInventory(creature->GetGUID());
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (creature->IsVendor() && player->GetQuestStatus(3909) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(2433, creature->GetGUID());
- return true;
- }
-
-};
-
-/*######
## npc_oox22fe
######*/
@@ -183,6 +150,10 @@ public:
};
+/*######
+## spell_gordunni_trap
+######*/
+
enum GordunniTrap
{
GO_GORDUNNI_DIRT_MOUND = 144064,
@@ -225,7 +196,6 @@ class spell_gordunni_trap : public SpellScriptLoader
void AddSC_feralas()
{
- new npc_gregan_brewspewer();
new npc_oox22fe();
new spell_gordunni_trap();
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
index 7440984d7c5..dfe0cacdef7 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
@@ -222,10 +222,10 @@ class boss_anubarak_trial : public CreatureScript
instance->SetBossState(BOSS_ANUBARAK, FAIL);
//Summon Scarab Swarms neutral at random places
for (int i = 0; i < 10; i++)
- if (Creature* temp = me->SummonCreature(NPC_SCARAB, AnubarakLoc[1].GetPositionX()+urand(0, 50)-25, AnubarakLoc[1].GetPositionY()+urand(0, 50)-25, AnubarakLoc[1].GetPositionZ()))
+ if (Creature* scarab = me->SummonCreature(NPC_SCARAB, AnubarakLoc[1].GetPositionX()+urand(0, 50)-25, AnubarakLoc[1].GetPositionY()+urand(0, 50)-25, AnubarakLoc[1].GetPositionZ()))
{
- temp->setFaction(31);
- temp->GetMotionMaster()->MoveRandom(10);
+ scarab->setFaction(31);
+ scarab->GetMotionMaster()->MoveRandom(10);
}
}
@@ -881,9 +881,9 @@ class spell_anubarak_leeching_swarm : public SpellScriptLoader
if (lifeLeeched < 250)
lifeLeeched = 250;
// Damage
- caster->CastCustomSpell(target, SPELL_LEECHING_SWARM_DMG, &lifeLeeched, 0, 0, false);
+ caster->CastCustomSpell(target, SPELL_LEECHING_SWARM_DMG, &lifeLeeched, 0, 0, true);
// Heal
- caster->CastCustomSpell(caster, SPELL_LEECHING_SWARM_HEAL, &lifeLeeched, 0, 0, false);
+ caster->CastCustomSpell(caster, SPELL_LEECHING_SWARM_HEAL, &lifeLeeched, 0, 0, true);
}
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
index 6c1b516c7de..ee44e1391b4 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
@@ -453,22 +453,22 @@ class boss_toc_champion_controller : public CreatureScript
for (uint8 i = 0; i < vChampionEntries.size(); ++i)
{
uint8 pos = urand(0, vChampionJumpTarget.size()-1);
- if (Creature* temp = me->SummonCreature(vChampionEntries[i], vChampionJumpOrigin[urand(0, vChampionJumpOrigin.size()-1)], TEMPSUMMON_MANUAL_DESPAWN))
+ if (Creature* champion = me->SummonCreature(vChampionEntries[i], vChampionJumpOrigin[urand(0, vChampionJumpOrigin.size()-1)], TEMPSUMMON_MANUAL_DESPAWN))
{
- _summons.Summon(temp);
- temp->SetReactState(REACT_PASSIVE);
- temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
+ _summons.Summon(champion);
+ champion->SetReactState(REACT_PASSIVE);
+ champion->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
if (playerTeam == ALLIANCE)
{
- temp->SetHomePosition(vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 0);
- temp->GetMotionMaster()->MoveJump(vChampionJumpTarget[pos], 20.0f, 20.0f);
- temp->SetOrientation(0);
+ champion->SetHomePosition(vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 0);
+ champion->GetMotionMaster()->MoveJump(vChampionJumpTarget[pos], 20.0f, 20.0f);
+ champion->SetOrientation(0);
}
else
{
- temp->SetHomePosition((ToCCommonLoc[1].GetPositionX()*2)-vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 3);
- temp->GetMotionMaster()->MoveJump((ToCCommonLoc[1].GetPositionX() * 2) - vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), vChampionJumpTarget[pos].GetOrientation(), 20.0f, 20.0f);
- temp->SetOrientation(3);
+ champion->SetHomePosition((ToCCommonLoc[1].GetPositionX()*2)-vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 3);
+ champion->GetMotionMaster()->MoveJump((ToCCommonLoc[1].GetPositionX() * 2) - vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), vChampionJumpTarget[pos].GetOrientation(), 20.0f, 20.0f);
+ champion->SetOrientation(3);
}
}
vChampionJumpTarget.erase(vChampionJumpTarget.begin()+pos);
@@ -485,10 +485,10 @@ class boss_toc_champion_controller : public CreatureScript
case 1:
for (SummonList::iterator i = _summons.begin(); i != _summons.end(); ++i)
{
- if (Creature* temp = ObjectAccessor::GetCreature(*me, *i))
+ if (Creature* summon = ObjectAccessor::GetCreature(*me, *i))
{
- temp->SetReactState(REACT_AGGRESSIVE);
- temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
+ summon->SetReactState(REACT_AGGRESSIVE);
+ summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
}
}
break;
@@ -640,12 +640,12 @@ struct boss_faction_championsAI : public BossAI
if (TeamInInstance == ALLIANCE)
{
- if (Creature* temp = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_VARIAN)))
- temp->AI()->Talk(SAY_KILL_PLAYER);
+ if (Creature* varian = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_VARIAN)))
+ varian->AI()->Talk(SAY_KILL_PLAYER);
}
else
- if (Creature* temp = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_GARROSH)))
- temp->AI()->Talk(SAY_KILL_PLAYER);
+ if (Creature* garrosh = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_GARROSH)))
+ garrosh->AI()->Talk(SAY_KILL_PLAYER);
}
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
index 2fba0c2af42..93823987d78 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
@@ -67,10 +67,12 @@ enum BossSpells
SPELL_SHIVAN_SLASH = 67098,
SPELL_SPINNING_STRIKE = 66283,
SPELL_MISTRESS_KISS = 66336,
- SPELL_FEL_INFERNO = 67047,
- SPELL_FEL_STREAK = 66494,
SPELL_LORD_HITTIN = 66326, // special effect preventing more specific spells be cast on the same player within 10 seconds
- SPELL_MISTRESS_KISS_DAMAGE_SILENCE = 66359
+ SPELL_MISTRESS_KISS_DAMAGE_SILENCE = 66359,
+
+ // Felflame Infernal
+ SPELL_FEL_STREAK_VISUAL = 66493,
+ SPELL_FEL_STREAK = 66494,
};
enum Events
@@ -116,7 +118,7 @@ class boss_jaraxxus : public CreatureScript
_JustReachedHome();
instance->SetBossState(BOSS_JARAXXUS, FAIL);
DoCast(me, SPELL_JARAXXUS_CHAINS);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
}
void KilledUnit(Unit* who) override
@@ -305,18 +307,17 @@ class npc_fel_infernal : public CreatureScript
{
npc_fel_infernalAI(Creature* creature) : ScriptedAI(creature)
{
- Initialize();
_instance = creature->GetInstanceScript();
}
- void Initialize()
- {
- _felStreakTimer = 30 * IN_MILLISECONDS;
- }
-
void Reset() override
{
- Initialize();
+ _scheduler.Schedule(Seconds(2), [this](TaskContext context)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ DoCast(target, SPELL_FEL_STREAK_VISUAL);
+ context.Repeat(Seconds(15));
+ });
me->SetInCombatWithZone();
}
@@ -328,23 +329,20 @@ class npc_fel_infernal : public CreatureScript
return;
}
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
if (!UpdateVictim())
return;
- if (_felStreakTimer <= diff)
+ _scheduler.Update(diff, [this]
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
- DoCast(target, SPELL_FEL_STREAK);
- _felStreakTimer = 30*IN_MILLISECONDS;
- }
- else
- _felStreakTimer -= diff;
-
- DoMeleeAttackIfReady();
+ DoMeleeAttackIfReady();
+ });
}
private:
- uint32 _felStreakTimer;
InstanceScript* _instance;
+ TaskScheduler _scheduler;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -579,6 +577,39 @@ class spell_mistress_kiss_area : public SpellScriptLoader
}
};
+class spell_fel_streak_visual : public SpellScriptLoader
+{
+public:
+ spell_fel_streak_visual() : SpellScriptLoader("spell_fel_streak_visual") { }
+
+ class spell_fel_streak_visual_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_fel_streak_visual_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_FEL_STREAK))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_fel_streak_visual_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_fel_streak_visual_SpellScript();
+ }
+};
+
void AddSC_boss_jaraxxus()
{
new boss_jaraxxus();
@@ -590,4 +621,5 @@ void AddSC_boss_jaraxxus()
new spell_mistress_kiss();
new spell_mistress_kiss_area();
+ new spell_fel_streak_visual();
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
index 566c296a60e..b2283ec6fde 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
@@ -25,6 +25,7 @@
#include "Vehicle.h"
#include "Player.h"
#include "SpellScript.h"
+#include "SpellAuraEffects.h"
enum Yells
{
@@ -33,6 +34,7 @@ enum Yells
// Acidmaw & Dreadscale
EMOTE_ENRAGE = 0,
+ SAY_SPECIAL = 1,
// Icehowl
EMOTE_TRAMPLE_START = 0,
@@ -78,22 +80,29 @@ enum BossSpells
SPELL_FIRE_BOMB_DOT = 66318,
SPELL_HEAD_CRACK = 66407,
- //Acidmaw & Dreadscale
+ //Acidmaw & Dreadscale Generic
+ SPELL_SWEEP = 66794,
+ SUMMON_SLIME_POOL = 66883,
+ SPELL_EMERGE = 66947,
+ SPELL_SUBMERGE = 66948,
+ SPELL_ENRAGE = 68335,
+ SPELL_SLIME_POOL_EFFECT = 66882, //In 60s it diameter grows from 10y to 40y (r=r+0.25 per second)
+ SPELL_GROUND_VISUAL_0 = 66969,
+ SPELL_GROUND_VISUAL_1 = 68302,
+ SPELL_HATE_TO_ZERO = 63984,
+ //Acidmaw
SPELL_ACID_SPIT = 66880,
SPELL_PARALYTIC_SPRAY = 66901,
- SPELL_ACID_SPEW = 66819,
- SPELL_PARALYTIC_BITE = 66824,
- SPELL_SWEEP_0 = 66794,
- SUMMON_SLIME_POOL = 66883,
- SPELL_FIRE_SPIT = 66796,
+ SPELL_PARALYTIC_BITE = 66824, //Paralytic Toxin
+ SPELL_ACID_SPEW = 66818,
+ SPELL_PARALYSIS = 66830,
+ SPELL_PARALYTIC_TOXIN = 66823,
+ //Dreadscale
+ SPELL_BURNING_BITE = 66879, // Burning Bile
SPELL_MOLTEN_SPEW = 66821,
- SPELL_BURNING_BITE = 66879,
+ SPELL_FIRE_SPIT = 66796,
SPELL_BURNING_SPRAY = 66902,
- SPELL_SWEEP_1 = 67646,
- SPELL_EMERGE_0 = 66947,
- SPELL_SUBMERGE_0 = 66948,
- SPELL_ENRAGE = 68335,
- SPELL_SLIME_POOL_EFFECT = 66882, //In 60s it diameter grows from 10y to 40y (r=r+0.25 per second)
+ SPELL_BURNING_BILE = 66869,
//Icehowl
SPELL_FEROCIOUS_BUTT = 66770,
@@ -182,7 +191,7 @@ class boss_gormok : public CreatureScript
{
case 0:
instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR));
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
me->SetReactState(REACT_AGGRESSIVE);
me->SetInCombatWithZone();
break;
@@ -549,7 +558,7 @@ struct boss_jormungarAI : public BossAI
if (!Enraged && instance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL)
{
- me->RemoveAurasDueToSpell(SPELL_SUBMERGE_0);
+ me->RemoveAurasDueToSpell(SPELL_SUBMERGE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
DoCast(SPELL_ENRAGE);
Enraged = true;
@@ -586,10 +595,11 @@ struct boss_jormungarAI : public BossAI
case EVENT_SUMMON_ACIDMAW:
if (Creature* acidmaw = me->SummonCreature(NPC_ACIDMAW, ToCCommonLoc[9].GetPositionX(), ToCCommonLoc[9].GetPositionY(), ToCCommonLoc[9].GetPositionZ(), 5, TEMPSUMMON_MANUAL_DESPAWN))
{
- acidmaw->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ acidmaw->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
acidmaw->SetReactState(REACT_AGGRESSIVE);
acidmaw->SetInCombatWithZone();
- acidmaw->CastSpell(acidmaw, SPELL_EMERGE_0);
+ acidmaw->CastSpell(acidmaw, SPELL_EMERGE);
+ acidmaw->CastSpell(acidmaw, SPELL_GROUND_VISUAL_1, true);
}
return;
case EVENT_SPRAY:
@@ -598,7 +608,7 @@ struct boss_jormungarAI : public BossAI
events.ScheduleEvent(EVENT_SPRAY, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_STATIONARY);
return;
case EVENT_SWEEP:
- DoCastAOE(SPELL_SWEEP_0);
+ DoCastAOE(SPELL_SWEEP);
events.ScheduleEvent(EVENT_SWEEP, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_STATIONARY);
return;
default:
@@ -608,13 +618,14 @@ struct boss_jormungarAI : public BossAI
if (events.IsInPhase(PHASE_MOBILE))
DoMeleeAttackIfReady();
if (events.IsInPhase(PHASE_STATIONARY))
- DoSpellAttackIfReady(SpitSpell);
+ DoCastVictim(SpitSpell);
}
void Submerge()
{
- DoCast(me, SPELL_SUBMERGE_0);
- me->RemoveAurasDueToSpell(SPELL_EMERGE_0);
+ DoCast(me, SPELL_SUBMERGE);
+ DoCast(me, SPELL_GROUND_VISUAL_0, true);
+ me->RemoveAurasDueToSpell(SPELL_EMERGE);
me->SetInCombatWithZone();
events.SetPhase(PHASE_SUBMERGED);
events.ScheduleEvent(EVENT_EMERGE, 5*IN_MILLISECONDS, 0, PHASE_SUBMERGED);
@@ -625,9 +636,11 @@ struct boss_jormungarAI : public BossAI
void Emerge()
{
- DoCast(me, SPELL_EMERGE_0);
+ DoCast(me, SPELL_EMERGE);
+ DoCastAOE(SPELL_HATE_TO_ZERO, true);
me->SetDisplayId(ModelMobile);
- me->RemoveAurasDueToSpell(SPELL_SUBMERGE_0);
+ me->RemoveAurasDueToSpell(SPELL_SUBMERGE);
+ me->RemoveAurasDueToSpell(SPELL_GROUND_VISUAL_0);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
// if the worm was mobile before submerging, make him stationary now
@@ -636,6 +649,7 @@ struct boss_jormungarAI : public BossAI
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL);
SetCombatMovement(false);
me->SetDisplayId(ModelStationary);
+ me->CastSpell(me, SPELL_GROUND_VISUAL_1, true);
events.SetPhase(PHASE_STATIONARY);
events.ScheduleEvent(EVENT_SUBMERGE, 45*IN_MILLISECONDS, 0, PHASE_STATIONARY);
events.ScheduleEvent(EVENT_SPIT, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_STATIONARY);
@@ -648,6 +662,7 @@ struct boss_jormungarAI : public BossAI
SetCombatMovement(true);
me->GetMotionMaster()->MoveChase(me->GetVictim());
me->SetDisplayId(ModelMobile);
+ me->RemoveAurasDueToSpell(SPELL_GROUND_VISUAL_1);
events.SetPhase(PHASE_MOBILE);
events.ScheduleEvent(EVENT_SUBMERGE, 45*IN_MILLISECONDS, 0, PHASE_MOBILE);
events.ScheduleEvent(EVENT_BITE, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_MOBILE);
@@ -737,7 +752,7 @@ class boss_dreadscale : public CreatureScript
{
case 0:
instance->DoCloseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR));
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
me->SetReactState(REACT_AGGRESSIVE);
me->SetInCombatWithZone();
break;
@@ -910,7 +925,7 @@ class boss_icehowl : public CreatureScript
break;
case 2:
instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR));
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
me->SetReactState(REACT_AGGRESSIVE);
me->SetInCombatWithZone();
break;
@@ -1122,6 +1137,148 @@ class boss_icehowl : public CreatureScript
}
};
+class spell_jormungars_paralytic_toxin : public SpellScriptLoader
+{
+public:
+ spell_jormungars_paralytic_toxin() : SpellScriptLoader("spell_jormungars_paralytic_toxin") { }
+
+ class spell_jormungars_paralytic_toxin_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_jormungars_paralytic_toxin_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_PARALYSIS))
+ return false;
+ return true;
+ }
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* caster = GetCaster();
+ if (caster && caster->GetEntry() == NPC_ACIDMAW)
+ {
+ if (Creature* acidMaw = caster->ToCreature())
+ acidMaw->AI()->Talk(SAY_SPECIAL, GetTarget());
+ }
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->RemoveAurasDueToSpell(SPELL_PARALYSIS);
+ }
+
+ void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated)
+ {
+ if (!canBeRecalculated)
+ amount = aurEff->GetAmount();
+
+ canBeRecalculated = false;
+ }
+
+ void HandleDummy(AuraEffect const* /*aurEff*/)
+ {
+ if (AuraEffect* slowEff = GetEffect(EFFECT_0))
+ {
+ int32 newAmount = slowEff->GetAmount() - 10;
+ if (newAmount < -100)
+ newAmount = -100;
+ slowEff->ChangeAmount(newAmount);
+
+ if (newAmount <= -100 && !GetTarget()->HasAura(SPELL_PARALYSIS))
+ GetTarget()->CastSpell(GetTarget(), SPELL_PARALYSIS, true, NULL, slowEff, GetCasterGUID());
+ }
+ }
+
+ void Register() override
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_jormungars_paralytic_toxin_AuraScript::OnApply, EFFECT_0, SPELL_AURA_MOD_DECREASE_SPEED, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_jormungars_paralytic_toxin_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_DECREASE_SPEED, AURA_EFFECT_HANDLE_REAL);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_jormungars_paralytic_toxin_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_DECREASE_SPEED);
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_jormungars_paralytic_toxin_AuraScript::HandleDummy, EFFECT_2, SPELL_AURA_PERIODIC_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_jormungars_paralytic_toxin_AuraScript();
+ }
+};
+
+class spell_jormungars_snakes_spray : public SpellScriptLoader
+{
+public:
+ spell_jormungars_snakes_spray(const char* name, uint32 spellId) : SpellScriptLoader(name), _spellId(spellId) { }
+
+ class spell_jormungars_snakes_spray_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_jormungars_snakes_spray_SpellScript);
+
+ public:
+ spell_jormungars_snakes_spray_SpellScript(uint32 spellId) : SpellScript(), _spellId(spellId) { }
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(_spellId))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Player* target = GetHitPlayer())
+ GetCaster()->CastSpell(target, _spellId, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_jormungars_snakes_spray_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
+ }
+
+ private:
+ uint32 _spellId;
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_jormungars_snakes_spray_SpellScript(_spellId);
+ }
+
+private:
+ uint32 _spellId;
+};
+
+class spell_jormungars_paralysis : public SpellScriptLoader
+{
+public:
+ spell_jormungars_paralysis() : SpellScriptLoader("spell_jormungars_paralysis") { }
+
+ class spell_jormungars_paralysis_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_jormungars_paralysis_AuraScript);
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (InstanceScript* instance = caster->GetInstanceScript())
+ if (instance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_IN_PROGRESS || instance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL)
+ return;
+
+ Remove();
+ }
+
+ void Register() override
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_jormungars_paralysis_AuraScript::OnApply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_jormungars_paralysis_AuraScript();
+ }
+};
+
void AddSC_boss_northrend_beasts()
{
new boss_gormok();
@@ -1132,6 +1289,10 @@ void AddSC_boss_northrend_beasts()
new boss_acidmaw();
new boss_dreadscale();
new npc_slime_pool();
+ new spell_jormungars_paralytic_toxin();
+ new spell_jormungars_snakes_spray("spell_jormungars_burning_spray", SPELL_BURNING_BILE);
+ new spell_jormungars_snakes_spray("spell_jormungars_paralytic_spray", SPELL_PARALYTIC_TOXIN);
+ new spell_jormungars_paralysis();
new boss_icehowl();
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
index 278f6a7ab4f..c6ac59218ea 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
@@ -440,10 +440,8 @@ class boss_fjola : public CreatureScript
// Allocate an unique random stage to each position in the array.
for (int i = 0; i < MAX_STAGES - 1; ++i)
{
- int random = i + (rand32() % (MAX_STAGES - i));
- int temp = Stage[i];
- Stage[i] = Stage[random];
- Stage[random] = temp;
+ int random = i + urand(0, MAX_STAGES - i);
+ std::swap(Stage[i], Stage[random]);
}
}
private:
@@ -804,8 +802,8 @@ class spell_valkyr_essences : public SpellScriptLoader
else
{
owner->CastSpell(owner, poweringUp, true);
- if (Aura* pTemp = owner->GetAura(poweringUp))
- pTemp->ModStackAmount(stacksCount);
+ if ((pAura = owner->GetAura(poweringUp)))
+ pAura->ModStackAmount(stacksCount);
}
}
}
@@ -829,8 +827,8 @@ class spell_valkyr_essences : public SpellScriptLoader
else
{
owner->CastSpell(owner, poweringUp, true);
- if (Aura* pTemp = owner->GetAura(poweringUp))
- pTemp->ModStackAmount(stacksCount);
+ if ((pAura = owner->GetAura(poweringUp)))
+ pAura->ModStackAmount(stacksCount);
}
}
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
index 0ffe74932e0..c2f2c8e8547 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
@@ -174,7 +174,7 @@ class npc_announcer_toc10 : public CreatureScript
if (Creature* jaraxxus = ObjectAccessor::GetCreature(*player, instance->GetGuidData(NPC_JARAXXUS)))
{
jaraxxus->RemoveAurasDueToSpell(SPELL_JARAXXUS_CHAINS);
- jaraxxus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ jaraxxus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
jaraxxus->SetReactState(REACT_DEFENSIVE);
jaraxxus->SetInCombatWithZone();
}
@@ -360,11 +360,11 @@ class npc_fizzlebang_toc : public CreatureScript
{
Talk(SAY_STAGE_1_06, killer);
_instance->SetData(TYPE_EVENT, 1180);
- if (Creature* temp = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_JARAXXUS)))
+ if (Creature* jaraxxus = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_JARAXXUS)))
{
- temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- temp->SetReactState(REACT_AGGRESSIVE);
- temp->SetInCombatWithZone();
+ jaraxxus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
+ jaraxxus->SetReactState(REACT_AGGRESSIVE);
+ jaraxxus->SetInCombatWithZone();
}
}
@@ -457,18 +457,18 @@ class npc_fizzlebang_toc : public CreatureScript
break;
case 1140:
Talk(SAY_STAGE_1_04);
- if (Creature* temp = me->SummonCreature(NPC_JARAXXUS, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 5.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME))
+ if (Creature* jaraxxus = me->SummonCreature(NPC_JARAXXUS, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 5.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME))
{
- temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- temp->SetReactState(REACT_PASSIVE);
- temp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY()-10, ToCCommonLoc[1].GetPositionZ());
+ jaraxxus->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
+ jaraxxus->SetReactState(REACT_PASSIVE);
+ jaraxxus->GetMotionMaster()->MovePoint(0, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY()-10, ToCCommonLoc[1].GetPositionZ());
}
_instance->SetData(TYPE_EVENT, 1142);
_updateTimer = 5*IN_MILLISECONDS;
break;
case 1142:
- if (Creature* temp = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_JARAXXUS)))
- temp->SetTarget(me->GetGUID());
+ if (Creature* jaraxxus = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_JARAXXUS)))
+ jaraxxus->SetTarget(me->GetGUID());
if (Creature* pTrigger = ObjectAccessor::GetCreature(*me, _triggerGUID))
pTrigger->DespawnOrUnsummon();
if (Creature* pPortal = ObjectAccessor::GetCreature(*me, _portalGUID))
@@ -477,19 +477,19 @@ class npc_fizzlebang_toc : public CreatureScript
_updateTimer = 10*IN_MILLISECONDS;
break;
case 1144:
- if (Creature* temp = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_JARAXXUS)))
- temp->AI()->Talk(SAY_STAGE_1_05);
+ if (Creature* jaraxxus = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_JARAXXUS)))
+ jaraxxus->AI()->Talk(SAY_STAGE_1_05);
_instance->SetData(TYPE_EVENT, 1150);
_updateTimer = 5*IN_MILLISECONDS;
break;
case 1150:
- if (Creature* temp = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_JARAXXUS)))
+ if (Creature* jaraxxus = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_JARAXXUS)))
{
//1-shot Fizzlebang
- temp->CastSpell(me, 67888, false);
- me->SetInCombatWith(temp);
- temp->AddThreat(me, 1000.0f);
- temp->AI()->AttackStart(me);
+ jaraxxus->CastSpell(me, 67888, false); // 67888 - Fel Lightning
+ me->SetInCombatWith(jaraxxus);
+ jaraxxus->AddThreat(me, 1000.0f);
+ jaraxxus->AI()->AttackStart(me);
}
_instance->SetData(TYPE_EVENT, 1160);
_updateTimer = 3*IN_MILLISECONDS;
@@ -561,11 +561,11 @@ class npc_tirion_toc : public CreatureScript
{
_instance->DoUseDoorOrButton(_instance->GetGuidData(GO_MAIN_GATE_DOOR));
- if (Creature* temp = me->SummonCreature(NPC_GORMOK, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30*IN_MILLISECONDS))
+ if (Creature* gormok = me->SummonCreature(NPC_GORMOK, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30*IN_MILLISECONDS))
{
- temp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ());
- temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- temp->SetReactState(REACT_PASSIVE);
+ gormok->GetMotionMaster()->MovePoint(0, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ());
+ gormok->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ gormok->SetReactState(REACT_PASSIVE);
}
}
_updateTimer = 3*IN_MILLISECONDS;
@@ -582,11 +582,11 @@ class npc_tirion_toc : public CreatureScript
if (_instance->GetBossState(BOSS_BEASTS) != DONE)
{
_instance->DoUseDoorOrButton(_instance->GetGuidData(GO_MAIN_GATE_DOOR));
- if (Creature* temp = me->SummonCreature(NPC_DREADSCALE, ToCSpawnLoc[1].GetPositionX(), ToCSpawnLoc[1].GetPositionY(), ToCSpawnLoc[1].GetPositionZ(), 5, TEMPSUMMON_MANUAL_DESPAWN))
+ if (Creature* dreadscale = me->SummonCreature(NPC_DREADSCALE, ToCSpawnLoc[1].GetPositionX(), ToCSpawnLoc[1].GetPositionY(), ToCSpawnLoc[1].GetPositionZ(), 5, TEMPSUMMON_MANUAL_DESPAWN))
{
- temp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ());
- temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- temp->SetReactState(REACT_PASSIVE);
+ dreadscale->GetMotionMaster()->MovePoint(0, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ());
+ dreadscale->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ dreadscale->SetReactState(REACT_PASSIVE);
}
}
_updateTimer = 5*IN_MILLISECONDS;
@@ -600,9 +600,9 @@ class npc_tirion_toc : public CreatureScript
if (_instance->GetBossState(BOSS_BEASTS) != DONE)
{
_instance->DoUseDoorOrButton(_instance->GetGuidData(GO_MAIN_GATE_DOOR));
- if (Creature* temp = me->SummonCreature(NPC_ICEHOWL, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 5, TEMPSUMMON_DEAD_DESPAWN))
+ if (Creature* icehowl = me->SummonCreature(NPC_ICEHOWL, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 5, TEMPSUMMON_DEAD_DESPAWN))
{
- temp->GetMotionMaster()->MovePoint(2, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ());
+ icehowl->GetMotionMaster()->MovePoint(2, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ());
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
me->SetReactState(REACT_PASSIVE);
}
@@ -698,34 +698,34 @@ class npc_tirion_toc : public CreatureScript
break;
case 4010:
Talk(SAY_STAGE_3_02);
- if (Creature* temp = me->SummonCreature(NPC_LIGHTBANE, ToCSpawnLoc[1].GetPositionX(), ToCSpawnLoc[1].GetPositionY(), ToCSpawnLoc[1].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME))
+ if (Creature* lightbane = me->SummonCreature(NPC_LIGHTBANE, ToCSpawnLoc[1].GetPositionX(), ToCSpawnLoc[1].GetPositionY(), ToCSpawnLoc[1].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME))
{
- temp->SetVisible(false);
- temp->SetReactState(REACT_PASSIVE);
- temp->SummonCreature(NPC_LIGHT_ESSENCE, TwinValkyrsLoc[0].GetPositionX(), TwinValkyrsLoc[0].GetPositionY(), TwinValkyrsLoc[0].GetPositionZ());
- temp->SummonCreature(NPC_LIGHT_ESSENCE, TwinValkyrsLoc[1].GetPositionX(), TwinValkyrsLoc[1].GetPositionY(), TwinValkyrsLoc[1].GetPositionZ());
+ lightbane->SetVisible(false);
+ lightbane->SetReactState(REACT_PASSIVE);
+ lightbane->SummonCreature(NPC_LIGHT_ESSENCE, TwinValkyrsLoc[0].GetPositionX(), TwinValkyrsLoc[0].GetPositionY(), TwinValkyrsLoc[0].GetPositionZ());
+ lightbane->SummonCreature(NPC_LIGHT_ESSENCE, TwinValkyrsLoc[1].GetPositionX(), TwinValkyrsLoc[1].GetPositionY(), TwinValkyrsLoc[1].GetPositionZ());
}
- if (Creature* temp = me->SummonCreature(NPC_DARKBANE, ToCSpawnLoc[2].GetPositionX(), ToCSpawnLoc[2].GetPositionY(), ToCSpawnLoc[2].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME))
+ if (Creature* darkbane = me->SummonCreature(NPC_DARKBANE, ToCSpawnLoc[2].GetPositionX(), ToCSpawnLoc[2].GetPositionY(), ToCSpawnLoc[2].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME))
{
- temp->SetVisible(false);
- temp->SetReactState(REACT_PASSIVE);
- temp->SummonCreature(NPC_DARK_ESSENCE, TwinValkyrsLoc[2].GetPositionX(), TwinValkyrsLoc[2].GetPositionY(), TwinValkyrsLoc[2].GetPositionZ());
- temp->SummonCreature(NPC_DARK_ESSENCE, TwinValkyrsLoc[3].GetPositionX(), TwinValkyrsLoc[3].GetPositionY(), TwinValkyrsLoc[3].GetPositionZ());
+ darkbane->SetVisible(false);
+ darkbane->SetReactState(REACT_PASSIVE);
+ darkbane->SummonCreature(NPC_DARK_ESSENCE, TwinValkyrsLoc[2].GetPositionX(), TwinValkyrsLoc[2].GetPositionY(), TwinValkyrsLoc[2].GetPositionZ());
+ darkbane->SummonCreature(NPC_DARK_ESSENCE, TwinValkyrsLoc[3].GetPositionX(), TwinValkyrsLoc[3].GetPositionY(), TwinValkyrsLoc[3].GetPositionZ());
}
_updateTimer = 3*IN_MILLISECONDS;
_instance->SetData(TYPE_EVENT, 4015);
break;
case 4015:
_instance->DoUseDoorOrButton(_instance->GetGuidData(GO_MAIN_GATE_DOOR));
- if (Creature* temp = ObjectAccessor::GetCreature((*me), _instance->GetGuidData(NPC_LIGHTBANE)))
+ if (Creature* lightbane = ObjectAccessor::GetCreature((*me), _instance->GetGuidData(NPC_LIGHTBANE)))
{
- temp->GetMotionMaster()->MovePoint(1, ToCCommonLoc[8].GetPositionX(), ToCCommonLoc[8].GetPositionY(), ToCCommonLoc[8].GetPositionZ());
- temp->SetVisible(true);
+ lightbane->GetMotionMaster()->MovePoint(1, ToCCommonLoc[8].GetPositionX(), ToCCommonLoc[8].GetPositionY(), ToCCommonLoc[8].GetPositionZ());
+ lightbane->SetVisible(true);
}
- if (Creature* temp = ObjectAccessor::GetCreature((*me), _instance->GetGuidData(NPC_DARKBANE)))
+ if (Creature* darkbane = ObjectAccessor::GetCreature((*me), _instance->GetGuidData(NPC_DARKBANE)))
{
- temp->GetMotionMaster()->MovePoint(1, ToCCommonLoc[9].GetPositionX(), ToCCommonLoc[9].GetPositionY(), ToCCommonLoc[9].GetPositionZ());
- temp->SetVisible(true);
+ darkbane->GetMotionMaster()->MovePoint(1, ToCCommonLoc[9].GetPositionX(), ToCCommonLoc[9].GetPositionY(), ToCCommonLoc[9].GetPositionZ());
+ darkbane->SetVisible(true);
}
_updateTimer = 10*IN_MILLISECONDS;
_instance->SetData(TYPE_EVENT, 4016);
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
index 3ac85809fa2..6b20ae6a373 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
@@ -1921,6 +1921,7 @@ class npc_frostsworn_general : public CreatureScript
{
if (Creature* reflection = me->SummonCreature(NPC_REFLECTION, *target, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000))
{
+ reflection->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
target->CastSpell(reflection, SPELL_CLONE, true);
target->CastSpell(reflection, SPELL_GHOST_VISUAL, true);
reflection->AI()->AttackStart(target);
@@ -2155,6 +2156,7 @@ struct npc_escape_event_trash : public ScriptedAI
DoZoneInCombat(me, 0.0f);
if (Creature* leader = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_ESCAPE_LEADER)))
{
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
me->SetInCombatWith(leader);
leader->SetInCombatWith(me);
me->AddThreat(leader, 0.0f);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
index 4a0a8217af8..de8d65693b9 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
@@ -528,6 +528,7 @@ class boss_the_lich_king : public CreatureScript
void SetupEncounter()
{
_Reset();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
me->SetReactState(REACT_PASSIVE);
events.SetPhase(PHASE_INTRO);
Initialize();
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
index 3d5a6ee8dfb..54e3b51fb0d 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
@@ -376,6 +376,8 @@ public:
me->SetDisableGravity(true);
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
// TO DO: find what in core is making boss slower than in retail (when correct speed data) or find missing movement flag update or forced spline change
me->SetSpeedRate(MOVE_FLIGHT, _flySpeed * 0.25f);
if (_despawned)
@@ -464,7 +466,7 @@ public:
pos.m_positionZ = alexstraszaBunny->GetPositionZ();
alexstraszaBunny->GetNearPoint2D(pos.m_positionX, pos.m_positionY, 30.0f, alexstraszaBunny->GetAngle(me));
me->GetMotionMaster()->MoveLand(POINT_LAND_P_ONE, pos);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
me->SetReactState(REACT_AGGRESSIVE);
me->SetInCombatWithZone();
events.ScheduleEvent(EVENT_LAND_START_ENCOUNTER, 7*IN_MILLISECONDS, 1, PHASE_NOT_STARTED);
@@ -604,8 +606,6 @@ public:
// Set speed to normal value
me->SetSpeedRate(MOVE_FLIGHT, _flySpeed);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->RemoveAllAuras();
me->CombatStop(); // Sometimes threat can remain, so it's a safety measure
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
index 86068a1ecba..c03a1c6fbc1 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
@@ -30,6 +30,8 @@
Destroying of Toasty Fires
*/
+/* @todo Hodir aggro behavior is wonky. He gets set to _PASSIVE, but never to _AGGRESSIVE unless you kill an ice block which doesn't spawn unless you have*/
+
enum HodirYells
{
SAY_AGGRO = 0,
@@ -375,7 +377,7 @@ class boss_hodir : public CreatureScript
Talk(SAY_SLAY);
}
- void DamageTaken(Unit* /*who*/, uint32& damage) override
+ void DamageTaken(Unit* who, uint32& damage) override
{
if (damage >= me->GetHealth())
{
@@ -403,6 +405,12 @@ class boss_hodir : public CreatureScript
_JustDied();
}
+ else if (!me->IsInCombat())
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->AI()->DoZoneInCombat();
+ me->AI()->AttackStart(who);
+ }
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
index 7106e9e4ebe..a50643c5deb 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
@@ -178,7 +178,7 @@ class boss_ignis : public CreatureScript
{
summon->setFaction(16);
summon->SetReactState(REACT_AGGRESSIVE);
- summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED | UNIT_FLAG_STUNNED | UNIT_FLAG_REMOVE_CLIENT_CONTROL);
+ summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED | UNIT_FLAG_STUNNED | UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_IMMUNE_TO_PC);
}
summon->AI()->AttackStart(me->GetVictim());
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
index 8aa443cba3f..9342b3a068e 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
@@ -972,7 +972,7 @@ class boss_vx_001 : public CreatureScript
events.ScheduleEvent(EVENT_FLAME_SUPPRESSANT_VX, 6000);
// Missing break intended.
case DO_START_VX001:
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
me->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); // Remove emotestate.
//me->SetUInt32Value(UNIT_FIELD_BYTES_1, 33554432); Blizzard handles hover animation like this it seems.
@@ -1145,7 +1145,7 @@ class boss_aerial_command_unit : public CreatureScript
events.ScheduleEvent(EVENT_SUMMON_FIRE_BOTS, 1000, 0, PHASE_AERIAL_COMMAND_UNIT);
// Missing break intended.
case DO_START_AERIAL:
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
me->SetReactState(REACT_AGGRESSIVE);
events.SetPhase(PHASE_AERIAL_COMMAND_UNIT);
diff --git a/src/server/scripts/Northrend/zone_sholazar_basin.cpp b/src/server/scripts/Northrend/zone_sholazar_basin.cpp
index f2edccd99b5..95250682782 100644
--- a/src/server/scripts/Northrend/zone_sholazar_basin.cpp
+++ b/src/server/scripts/Northrend/zone_sholazar_basin.cpp
@@ -780,7 +780,7 @@ public:
bird->KillSelf();
crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(),
- bird->GetMap()->GetWaterOrGroundLevel(bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ()));
+ bird->GetMap()->GetWaterOrGroundLevel(bird->GetPhaseMask(), bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ()));
/// @todo Make crunchy perform emote eat when he reaches the bird
break;
diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
index 14aeda04a7e..39718a6b418 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
@@ -539,6 +539,7 @@ public:
void EnterCombat(Unit* /*who*/) override
{
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
me->setActive(true);
DoZoneInCombat();
}
@@ -585,7 +586,7 @@ public:
void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override
{
- if (spell->Id == SPELL_GLAIVE_RETURNS) // Re-equip our warblades!
+ if (spell->Id == SPELL_GLAIVE_RETURNS) // Re-equip our warglaives!
{
if (!me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID))
SetEquipmentSlots(false, EQUIP_ID_MAIN_HAND, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
@@ -673,7 +674,7 @@ public:
Timer[EVENT_TALK_SEQUENCE] = 100;
me->RemoveAllAuras();
me->InterruptNonMeleeSpells(false);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
me->GetMotionMaster()->Clear(false);
me->AttackStop();
break;
@@ -791,99 +792,99 @@ public:
{
switch (FlightCount)
{
- case 1: // lift off
- me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- me->SetDisableGravity(true);
- me->StopMoving();
- Talk(SAY_ILLIDAN_TAKEOFF);
- Timer[EVENT_FLIGHT_SEQUENCE] = 3000;
- break;
- case 2: // move to center
- me->GetMotionMaster()->MovePoint(0, CENTER_X + 5, CENTER_Y, CENTER_Z); // +5, for SPELL_THROW_GLAIVE bug
- Timer[EVENT_FLIGHT_SEQUENCE] = 0;
- break;
- case 3: // throw one glaive
- {
- uint8 i=1;
- Creature* Glaive = me->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
- if (Glaive)
+ case 1: // lift off
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
+ me->SetDisableGravity(true);
+ me->StopMoving();
+ Talk(SAY_ILLIDAN_TAKEOFF);
+ Timer[EVENT_FLIGHT_SEQUENCE] = 3000;
+ break;
+ case 2: // move to center
+ me->GetMotionMaster()->MovePoint(0, CENTER_X + 5, CENTER_Y, CENTER_Z); // +5, for SPELL_THROW_GLAIVE bug
+ Timer[EVENT_FLIGHT_SEQUENCE] = 0;
+ break;
+ case 3: // throw one glaive
{
- GlaiveGUID[i] = Glaive->GetGUID();
- Glaive->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Glaive->SetDisplayId(MODEL_INVISIBLE);
- Glaive->setFaction(me->getFaction());
- DoCast(Glaive, SPELL_THROW_GLAIVE2);
+ uint8 i=1;
+ Creature* Glaive = me->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+ if (Glaive)
+ {
+ GlaiveGUID[i] = Glaive->GetGUID();
+ Glaive->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ Glaive->SetDisplayId(MODEL_INVISIBLE);
+ Glaive->setFaction(me->getFaction());
+ DoCast(Glaive, SPELL_THROW_GLAIVE2);
+ }
}
- }
- Timer[EVENT_FLIGHT_SEQUENCE] = 700;
- break;
- case 4: // throw another
- SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
- {
- uint8 i=0;
- Creature* Glaive = me->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
- if (Glaive)
+ Timer[EVENT_FLIGHT_SEQUENCE] = 700;
+ break;
+ case 4: // throw another
+ SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
{
- GlaiveGUID[i] = Glaive->GetGUID();
- Glaive->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Glaive->SetDisplayId(MODEL_INVISIBLE);
- Glaive->setFaction(me->getFaction());
- DoCast(Glaive, SPELL_THROW_GLAIVE, true);
+ uint8 i=0;
+ Creature* Glaive = me->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+ if (Glaive)
+ {
+ GlaiveGUID[i] = Glaive->GetGUID();
+ Glaive->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ Glaive->SetDisplayId(MODEL_INVISIBLE);
+ Glaive->setFaction(me->getFaction());
+ DoCast(Glaive, SPELL_THROW_GLAIVE, true);
+ }
}
- }
- Timer[EVENT_FLIGHT_SEQUENCE] = 5000;
- break;
- case 5: // summon flames
- SummonFlamesOfAzzinoth();
- Timer[EVENT_FLIGHT_SEQUENCE] = 3000;
- break;
- case 6: // fly to hover point
- me->GetMotionMaster()->MovePoint(0, HoverPosition[HoverPoint].x, HoverPosition[HoverPoint].y, HoverPosition[HoverPoint].z);
- Timer[EVENT_FLIGHT_SEQUENCE] = 0;
- break;
- case 7: // return to center
- me->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, CENTER_Z);
- Timer[EVENT_FLIGHT_SEQUENCE] = 0;
- break;
- case 8: // glaive return
- for (uint8 i = 0; i < 2; ++i)
- {
- if (GlaiveGUID[i])
+ Timer[EVENT_FLIGHT_SEQUENCE] = 5000;
+ break;
+ case 5: // summon flames
+ SummonFlamesOfAzzinoth();
+ Timer[EVENT_FLIGHT_SEQUENCE] = 3000;
+ break;
+ case 6: // fly to hover point
+ me->GetMotionMaster()->MovePoint(0, HoverPosition[HoverPoint].x, HoverPosition[HoverPoint].y, HoverPosition[HoverPoint].z);
+ Timer[EVENT_FLIGHT_SEQUENCE] = 0;
+ break;
+ case 7: // return to center
+ me->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, CENTER_Z);
+ Timer[EVENT_FLIGHT_SEQUENCE] = 0;
+ break;
+ case 8: // glaive return
+ for (uint8 i = 0; i < 2; ++i)
{
- Unit* Glaive = ObjectAccessor::GetUnit(*me, GlaiveGUID[i]);
- if (Glaive)
+ if (GlaiveGUID[i])
{
- Glaive->CastSpell(me, SPELL_GLAIVE_RETURNS, false); // Make it look like the Glaive flies back up to us
- Glaive->SetDisplayId(MODEL_INVISIBLE); // disappear but not die for now
+ Unit* Glaive = ObjectAccessor::GetUnit(*me, GlaiveGUID[i]);
+ if (Glaive)
+ {
+ Glaive->CastSpell(me, SPELL_GLAIVE_RETURNS, false); // Make it look like the Glaive flies back up to us
+ Glaive->SetDisplayId(MODEL_INVISIBLE); // disappear but not die for now
+ }
}
}
- }
- Timer[EVENT_FLIGHT_SEQUENCE] = 2000;
- break;
- case 9: // land
- me->SetDisableGravity(false);
- me->StopMoving();
- me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
- for (uint8 i = 0; i < 2; ++i)
- {
- if (GlaiveGUID[i])
+ Timer[EVENT_FLIGHT_SEQUENCE] = 2000;
+ break;
+ case 9: // land
+ me->SetDisableGravity(false);
+ me->StopMoving();
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
+ for (uint8 i = 0; i < 2; ++i)
{
- if (Creature* glaive = ObjectAccessor::GetCreature(*me, GlaiveGUID[i]))
- glaive->DespawnOrUnsummon();
+ if (GlaiveGUID[i])
+ {
+ if (Creature* glaive = ObjectAccessor::GetCreature(*me, GlaiveGUID[i]))
+ glaive->DespawnOrUnsummon();
- GlaiveGUID[i].Clear();
+ GlaiveGUID[i].Clear();
+ }
}
- }
- Timer[EVENT_FLIGHT_SEQUENCE] = 2000;
- break;
- case 10: // attack
- DoResetThreat();
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
- me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
- EnterPhase(PHASE_NORMAL_2);
- break;
- default:
- break;
+ Timer[EVENT_FLIGHT_SEQUENCE] = 2000;
+ break;
+ case 10: // attack
+ DoResetThreat();
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
+ me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
+ EnterPhase(PHASE_NORMAL_2);
+ break;
+ default:
+ break;
}
++FlightCount;
}
@@ -913,23 +914,23 @@ public:
switch (TransformCount)
{
- case 2:
- DoResetThreat();
- break;
- case 4:
- EnterPhase(PHASE_DEMON);
- break;
- case 7:
- DoResetThreat();
- break;
- case 9:
- if (MaievGUID)
- EnterPhase(PHASE_NORMAL_MAIEV); // Depending on whether we summoned Maiev, we switch to either phase 5 or 3
- else
- EnterPhase(PHASE_NORMAL_2);
- break;
- default:
- break;
+ case 2:
+ DoResetThreat();
+ break;
+ case 4:
+ EnterPhase(PHASE_DEMON);
+ break;
+ case 7:
+ DoResetThreat();
+ break;
+ case 9:
+ if (MaievGUID)
+ EnterPhase(PHASE_NORMAL_MAIEV); // Depending on whether we summoned Maiev, we switch to either phase 5 or 3
+ else
+ EnterPhase(PHASE_NORMAL_2);
+ break;
+ default:
+ break;
}
if (Phase == PHASE_TRANSFORM_SEQUENCE)
Timer[EVENT_TRANSFORM_SEQUENCE] = DemonTransformation[TransformCount].timer;
@@ -957,37 +958,37 @@ public:
switch (Phase)
{
- case PHASE_NORMAL:
- if (HealthBelowPct(65))
- EnterPhase(PHASE_FLIGHT_SEQUENCE);
- break;
+ case PHASE_NORMAL:
+ if (HealthBelowPct(65))
+ EnterPhase(PHASE_FLIGHT_SEQUENCE);
+ break;
- case PHASE_NORMAL_2:
- if (HealthBelowPct(30))
- EnterPhase(PHASE_TALK_SEQUENCE);
- break;
+ case PHASE_NORMAL_2:
+ if (HealthBelowPct(30))
+ EnterPhase(PHASE_TALK_SEQUENCE);
+ break;
- case PHASE_NORMAL_MAIEV:
- if (HealthBelowPct(1))
- EnterPhase(PHASE_TALK_SEQUENCE);
- break;
+ case PHASE_NORMAL_MAIEV:
+ if (HealthBelowPct(1))
+ EnterPhase(PHASE_TALK_SEQUENCE);
+ break;
- case PHASE_TALK_SEQUENCE:
- if (Event == EVENT_TALK_SEQUENCE)
- HandleTalkSequence();
- break;
+ case PHASE_TALK_SEQUENCE:
+ if (Event == EVENT_TALK_SEQUENCE)
+ HandleTalkSequence();
+ break;
- case PHASE_FLIGHT_SEQUENCE:
- if (Event == EVENT_FLIGHT_SEQUENCE)
- HandleFlightSequence();
- break;
+ case PHASE_FLIGHT_SEQUENCE:
+ if (Event == EVENT_FLIGHT_SEQUENCE)
+ HandleFlightSequence();
+ break;
- case PHASE_TRANSFORM_SEQUENCE:
- if (Event == EVENT_TRANSFORM_SEQUENCE)
- HandleTransformSequence();
- break;
- default:
- break;
+ case PHASE_TRANSFORM_SEQUENCE:
+ if (Event == EVENT_TRANSFORM_SEQUENCE)
+ HandleTransformSequence();
+ break;
+ default:
+ break;
}
if (me->IsNonMeleeSpellCast(false))
@@ -998,63 +999,63 @@ public:
switch (Event)
{
// PHASE_NORMAL
- case EVENT_BERSERK:
- Talk(SAY_ILLIDAN_ENRAGE);
- DoCast(me, SPELL_BERSERK, true);
- Timer[EVENT_BERSERK] = 5000; // The buff actually lasts forever.
- break;
-
- case EVENT_TAUNT:
- Talk(SAY_ILLIDAN_TAUNT);
- Timer[EVENT_TAUNT] = urand(25000, 35000);
- break;
-
- case EVENT_SHEAR:
- // no longer exists in 3.0f.2
- // DoCastVictim(SPELL_SHEAR);
- Timer[EVENT_SHEAR] = 25000 + (rand32() % 16 * 1000);
- break;
-
- case EVENT_FLAME_CRASH:
- DoCastVictim(SPELL_FLAME_CRASH);
- Timer[EVENT_FLAME_CRASH] = urand(30000, 40000);
- break;
-
- case EVENT_PARASITIC_SHADOWFIEND:
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true))
- DoCast(target, SPELL_PARASITIC_SHADOWFIEND, true);
- Timer[EVENT_PARASITIC_SHADOWFIEND] = urand(35000, 45000);
- }
- break;
-
- case EVENT_PARASITE_CHECK:
- Timer[EVENT_PARASITE_CHECK] = 0;
- break;
-
- case EVENT_DRAW_SOUL:
- DoCastVictim(SPELL_DRAW_SOUL);
- Timer[EVENT_DRAW_SOUL] = urand(50000, 60000);
- break;
-
- // PHASE_NORMAL_2
- case EVENT_AGONIZING_FLAMES:
- DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_AGONIZING_FLAMES);
- Timer[EVENT_AGONIZING_FLAMES] = 0;
- break;
-
- case EVENT_TRANSFORM_NORMAL:
- EnterPhase(PHASE_TRANSFORM_SEQUENCE);
- break;
-
- // PHASE_NORMAL_MAIEV
- case EVENT_ENRAGE:
- DoCast(me, SPELL_ENRAGE);
- Timer[EVENT_ENRAGE] = 0;
- break;
-
- default:
- break;
+ case EVENT_BERSERK:
+ Talk(SAY_ILLIDAN_ENRAGE);
+ DoCast(me, SPELL_BERSERK, true);
+ Timer[EVENT_BERSERK] = 5000; // The buff actually lasts forever.
+ break;
+
+ case EVENT_TAUNT:
+ Talk(SAY_ILLIDAN_TAUNT);
+ Timer[EVENT_TAUNT] = urand(25000, 35000);
+ break;
+
+ case EVENT_SHEAR:
+ // no longer exists in 3.0f.2
+ // DoCastVictim(SPELL_SHEAR);
+ Timer[EVENT_SHEAR] = 25000 + (rand32() % 16 * 1000);
+ break;
+
+ case EVENT_FLAME_CRASH:
+ DoCastVictim(SPELL_FLAME_CRASH);
+ Timer[EVENT_FLAME_CRASH] = urand(30000, 40000);
+ break;
+
+ case EVENT_PARASITIC_SHADOWFIEND:
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true))
+ DoCast(target, SPELL_PARASITIC_SHADOWFIEND, true);
+ Timer[EVENT_PARASITIC_SHADOWFIEND] = urand(35000, 45000);
+ }
+ break;
+
+ case EVENT_PARASITE_CHECK:
+ Timer[EVENT_PARASITE_CHECK] = 0;
+ break;
+
+ case EVENT_DRAW_SOUL:
+ DoCastVictim(SPELL_DRAW_SOUL);
+ Timer[EVENT_DRAW_SOUL] = urand(50000, 60000);
+ break;
+
+ // PHASE_NORMAL_2
+ case EVENT_AGONIZING_FLAMES:
+ DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_AGONIZING_FLAMES);
+ Timer[EVENT_AGONIZING_FLAMES] = 0;
+ break;
+
+ case EVENT_TRANSFORM_NORMAL:
+ EnterPhase(PHASE_TRANSFORM_SEQUENCE);
+ break;
+
+ // PHASE_NORMAL_MAIEV
+ case EVENT_ENRAGE:
+ DoCast(me, SPELL_ENRAGE);
+ Timer[EVENT_ENRAGE] = 0;
+ break;
+
+ default:
+ break;
}
DoMeleeAttackIfReady();
}
@@ -1063,32 +1064,32 @@ public:
{
switch (Event)
{
- case EVENT_FIREBALL:
- DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_FIREBALL);
- Timer[EVENT_FIREBALL] = 3000;
- break;
-
- case EVENT_DARK_BARRAGE:
- DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_DARK_BARRAGE);
- Timer[EVENT_DARK_BARRAGE] = 0;
- break;
-
- case EVENT_EYE_BLAST:
- CastEyeBlast();
- Timer[EVENT_EYE_BLAST] = 0;
- break;
-
- case EVENT_MOVE_POINT:
- Phase = PHASE_FLIGHT_SEQUENCE;
- Timer[EVENT_FLIGHT_SEQUENCE] = 0; // do not start Event when changing hover point
- HoverPoint += (rand32() % 3 + 1);
- if (HoverPoint > 3)
- HoverPoint -= 4;
- me->GetMotionMaster()->MovePoint(0, HoverPosition[HoverPoint].x, HoverPosition[HoverPoint].y, HoverPosition[HoverPoint].z);
- break;
-
- default:
- break;
+ case EVENT_FIREBALL:
+ DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_FIREBALL);
+ Timer[EVENT_FIREBALL] = 3000;
+ break;
+
+ case EVENT_DARK_BARRAGE:
+ DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_DARK_BARRAGE);
+ Timer[EVENT_DARK_BARRAGE] = 0;
+ break;
+
+ case EVENT_EYE_BLAST:
+ CastEyeBlast();
+ Timer[EVENT_EYE_BLAST] = 0;
+ break;
+
+ case EVENT_MOVE_POINT:
+ Phase = PHASE_FLIGHT_SEQUENCE;
+ Timer[EVENT_FLIGHT_SEQUENCE] = 0; // do not start Event when changing hover point
+ HoverPoint += (rand32() % 3 + 1);
+ if (HoverPoint > 3)
+ HoverPoint -= 4;
+ me->GetMotionMaster()->MovePoint(0, HoverPosition[HoverPoint].x, HoverPosition[HoverPoint].y, HoverPosition[HoverPoint].z);
+ break;
+
+ default:
+ break;
}
}
@@ -1096,29 +1097,29 @@ public:
{
switch (Event)
{
- case EVENT_SHADOW_BLAST:
- me->GetMotionMaster()->Clear(false);
- if (me->GetVictim() && (!me->IsWithinDistInMap(me->GetVictim(), 50) || !me->IsWithinLOSInMap(me->GetVictim())))
- me->GetMotionMaster()->MoveChase(me->GetVictim(), 30);
- else
- me->GetMotionMaster()->MoveIdle();
- DoCastVictim(SPELL_SHADOW_BLAST);
- Timer[EVENT_SHADOW_BLAST] = 4000;
- break;
- case EVENT_SHADOWDEMON:
- DoCast(me, SPELL_SUMMON_SHADOWDEMON);
- Timer[EVENT_SHADOWDEMON] = 0;
- Timer[EVENT_FLAME_BURST] += 10000;
- break;
- case EVENT_FLAME_BURST:
- DoCast(me, SPELL_FLAME_BURST);
- Timer[EVENT_FLAME_BURST] = 15000;
- break;
- case EVENT_TRANSFORM_DEMON:
- EnterPhase(PHASE_TRANSFORM_SEQUENCE);
- break;
- default:
- break;
+ case EVENT_SHADOW_BLAST:
+ me->GetMotionMaster()->Clear(false);
+ if (me->GetVictim() && (!me->IsWithinDistInMap(me->GetVictim(), 50) || !me->IsWithinLOSInMap(me->GetVictim())))
+ me->GetMotionMaster()->MoveChase(me->GetVictim(), 30);
+ else
+ me->GetMotionMaster()->MoveIdle();
+ DoCastVictim(SPELL_SHADOW_BLAST);
+ Timer[EVENT_SHADOW_BLAST] = 4000;
+ break;
+ case EVENT_SHADOWDEMON:
+ DoCast(me, SPELL_SUMMON_SHADOWDEMON);
+ Timer[EVENT_SHADOWDEMON] = 0;
+ Timer[EVENT_FLAME_BURST] += 10000;
+ break;
+ case EVENT_FLAME_BURST:
+ DoCast(me, SPELL_FLAME_BURST);
+ Timer[EVENT_FLAME_BURST] = 15000;
+ break;
+ case EVENT_TRANSFORM_DEMON:
+ EnterPhase(PHASE_TRANSFORM_SEQUENCE);
+ break;
+ default:
+ break;
}
}
}
@@ -1148,7 +1149,7 @@ public:
/********************************** End of Illidan AI* *****************************************/
-/******* Functions and vars for Akama's AI* *****/
+/******* Functions and vars for Maiev's AI* *****/
class boss_maiev_shadowsong : public CreatureScript
{
public:
@@ -1377,6 +1378,7 @@ public:
}
};
+/******* Functions and vars for Akama's AI* *****/
class npc_akama_illidan : public CreatureScript
{
public:
diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
index 7ea87a3c0c4..c6815c3be42 100644
--- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
+++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
@@ -90,8 +90,10 @@ public:
void SummonInfernal()
{
- Creature* infernal = me->SummonCreature(NPC_INFERNAL_ATTACKER, me->GetPositionX(), me->GetPositionY(), ground + 0.05f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
- infernalGUID = infernal->GetGUID();
+ if (Creature* infernal = me->SummonCreature(NPC_INFERNAL_ATTACKER, me->GetPositionX(), me->GetPositionY(), ground + 0.05f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000))
+ infernalGUID = infernal->GetGUID();
+ else
+ infernalGUID = ObjectGuid::Empty;
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index 159faa38c62..da753568ee0 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -36,7 +36,6 @@ npc_doctor 100% Gustaf Vanhowzen and Gregory Victor, quest 6622
npc_sayge 100% Darkmoon event fortune teller, buff player based on answers given
npc_snake_trap_serpents 80% AI for snakes that summoned by Snake Trap
npc_shadowfiend 100% restore 5% of owner's mana when shadowfiend die from damage
-npc_locksmith 75% list of keys needs to be confirmed
npc_firework 100% NPC's summoned by rockets and rocket clusters, for making them cast visual
npc_train_wrecker 100% Wind-Up Train Wrecker that kills train set
EndContentData */
@@ -1188,36 +1187,49 @@ public:
enum Sayge
{
- SPELL_DMG = 23768, // dmg
- SPELL_RES = 23769, // res
- SPELL_ARM = 23767, // arm
- SPELL_SPI = 23738, // spi
- SPELL_INT = 23766, // int
- SPELL_STM = 23737, // stm
- SPELL_STR = 23735, // str
- SPELL_AGI = 23736, // agi
- SPELL_FORTUNE = 23765 // faire fortune
+ GOSSIP_MENU_OPTION_ID_ANSWER_1 = 0,
+ GOSSIP_MENU_OPTION_ID_ANSWER_2 = 1,
+ GOSSIP_MENU_OPTION_ID_ANSWER_3 = 2,
+ GOSSIP_MENU_OPTION_ID_ANSWER_4 = 3,
+ GOSSIP_I_AM_READY_TO_DISCOVER = 6186,
+ GOSSIP_MENU_OPTION_SAYGE1 = 6185,
+ GOSSIP_MENU_OPTION_SAYGE2 = 6185,
+ GOSSIP_MENU_OPTION_SAYGE3 = 6185,
+ GOSSIP_MENU_OPTION_SAYGE4 = 6185,
+ GOSSIP_MENU_OPTION_SAYGE5 = 6187,
+ GOSSIP_MENU_OPTION_SAYGE6 = 6187,
+ GOSSIP_MENU_OPTION_SAYGE7 = 6187,
+ GOSSIP_MENU_OPTION_SAYGE8 = 6208,
+ GOSSIP_MENU_OPTION_SAYGE9 = 6208,
+ GOSSIP_MENU_OPTION_SAYGE10 = 6208,
+ GOSSIP_MENU_OPTION_SAYGE11 = 6209,
+ GOSSIP_MENU_OPTION_SAYGE12 = 6209,
+ GOSSIP_MENU_OPTION_SAYGE13 = 6209,
+ GOSSIP_MENU_OPTION_SAYGE14 = 6210,
+ GOSSIP_MENU_OPTION_SAYGE15 = 6210,
+ GOSSIP_MENU_OPTION_SAYGE16 = 6210,
+ GOSSIP_MENU_OPTION_SAYGE17 = 6211,
+ GOSSIP_MENU_I_HAVE_LONG_KNOWN = 7339,
+ GOSSIP_MENU_YOU_HAVE_BEEN_TASKED = 7340,
+ GOSSIP_MENU_SWORN_EXECUTIONER = 7341,
+ GOSSIP_MENU_DIPLOMATIC_MISSION = 7361,
+ GOSSIP_MENU_YOUR_BROTHER_SEEKS = 7362,
+ GOSSIP_MENU_A_TERRIBLE_BEAST = 7363,
+ GOSSIP_MENU_YOUR_FORTUNE_IS_CAST = 7364,
+ GOSSIP_MENU_HERE_IS_YOUR_FORTUNE = 7365,
+ GOSSIP_MENU_CANT_GIVE_YOU_YOUR = 7393,
+
+ SPELL_STRENGTH = 23735, // +10% Strength
+ SPELL_AGILITY = 23736, // +10% Agility
+ SPELL_STAMINA = 23737, // +10% Stamina
+ SPELL_SPIRIT = 23738, // +10% Spirit
+ SPELL_INTELLECT = 23766, // +10% Intellect
+ SPELL_ARMOR = 23767, // +10% Armor
+ SPELL_DAMAGE = 23768, // +10% Damage
+ SPELL_RESISTANCE = 23769, // +25 Magic Resistance (All)
+ SPELL_FORTUNE = 23765 // Darkmoon Faire Fortune
};
-#define GOSSIP_HELLO_SAYGE "Yes"
-#define GOSSIP_SENDACTION_SAYGE1 "Slay the Man"
-#define GOSSIP_SENDACTION_SAYGE2 "Turn him over to liege"
-#define GOSSIP_SENDACTION_SAYGE3 "Confiscate the corn"
-#define GOSSIP_SENDACTION_SAYGE4 "Let him go and have the corn"
-#define GOSSIP_SENDACTION_SAYGE5 "Execute your friend painfully"
-#define GOSSIP_SENDACTION_SAYGE6 "Execute your friend painlessly"
-#define GOSSIP_SENDACTION_SAYGE7 "Let your friend go"
-#define GOSSIP_SENDACTION_SAYGE8 "Confront the diplomat"
-#define GOSSIP_SENDACTION_SAYGE9 "Show not so quiet defiance"
-#define GOSSIP_SENDACTION_SAYGE10 "Remain quiet"
-#define GOSSIP_SENDACTION_SAYGE11 "Speak against your brother openly"
-#define GOSSIP_SENDACTION_SAYGE12 "Help your brother in"
-#define GOSSIP_SENDACTION_SAYGE13 "Keep your brother out without letting him know"
-#define GOSSIP_SENDACTION_SAYGE14 "Take credit, keep gold"
-#define GOSSIP_SENDACTION_SAYGE15 "Take credit, share the gold"
-#define GOSSIP_SENDACTION_SAYGE16 "Let the knight take credit"
-#define GOSSIP_SENDACTION_SAYGE17 "Thanks"
-
class npc_sayge : public CreatureScript
{
public:
@@ -1228,19 +1240,19 @@ public:
if (creature->IsQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
- if (player->GetSpellHistory()->HasCooldown(SPELL_INT) ||
- player->GetSpellHistory()->HasCooldown(SPELL_ARM) ||
- player->GetSpellHistory()->HasCooldown(SPELL_DMG) ||
- player->GetSpellHistory()->HasCooldown(SPELL_RES) ||
- player->GetSpellHistory()->HasCooldown(SPELL_STR) ||
- player->GetSpellHistory()->HasCooldown(SPELL_AGI) ||
- player->GetSpellHistory()->HasCooldown(SPELL_STM) ||
- player->GetSpellHistory()->HasCooldown(SPELL_SPI))
- player->SEND_GOSSIP_MENU(7393, creature->GetGUID());
+ if (player->GetSpellHistory()->HasCooldown(SPELL_STRENGTH) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_AGILITY) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_STAMINA) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_SPIRIT) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_INTELLECT) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_ARMOR) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_DAMAGE) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_RESISTANCE))
+ player->SEND_GOSSIP_MENU(GOSSIP_MENU_CANT_GIVE_YOU_YOUR, creature->GetGUID());
else
{
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_SAYGE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(7339, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_I_AM_READY_TO_DISCOVER, GOSSIP_MENU_OPTION_ID_ANSWER_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ player->SEND_GOSSIP_MENU(GOSSIP_MENU_I_HAVE_LONG_KNOWN, creature->GetGUID());
}
return true;
@@ -1251,43 +1263,43 @@ public:
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
- player->SEND_GOSSIP_MENU(7340, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE1, GOSSIP_MENU_OPTION_ID_ANSWER_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE2, GOSSIP_MENU_OPTION_ID_ANSWER_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE3, GOSSIP_MENU_OPTION_ID_ANSWER_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE4, GOSSIP_MENU_OPTION_ID_ANSWER_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
+ player->SEND_GOSSIP_MENU(GOSSIP_MENU_YOU_HAVE_BEEN_TASKED, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE5, GOSSIP_SENDER_MAIN + 1, GOSSIP_ACTION_INFO_DEF);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE6, GOSSIP_SENDER_MAIN + 2, GOSSIP_ACTION_INFO_DEF);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE7, GOSSIP_SENDER_MAIN + 3, GOSSIP_ACTION_INFO_DEF);
- player->SEND_GOSSIP_MENU(7341, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE5, GOSSIP_MENU_OPTION_ID_ANSWER_1, GOSSIP_SENDER_MAIN + 1, GOSSIP_ACTION_INFO_DEF);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE6, GOSSIP_MENU_OPTION_ID_ANSWER_2, GOSSIP_SENDER_MAIN + 2, GOSSIP_ACTION_INFO_DEF);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE7, GOSSIP_MENU_OPTION_ID_ANSWER_3, GOSSIP_SENDER_MAIN + 3, GOSSIP_ACTION_INFO_DEF);
+ player->SEND_GOSSIP_MENU(GOSSIP_MENU_SWORN_EXECUTIONER, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE8, GOSSIP_SENDER_MAIN + 4, GOSSIP_ACTION_INFO_DEF);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE9, GOSSIP_SENDER_MAIN + 5, GOSSIP_ACTION_INFO_DEF);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE10, GOSSIP_SENDER_MAIN + 2, GOSSIP_ACTION_INFO_DEF);
- player->SEND_GOSSIP_MENU(7361, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE8, GOSSIP_MENU_OPTION_ID_ANSWER_1, GOSSIP_SENDER_MAIN + 4, GOSSIP_ACTION_INFO_DEF);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE9, GOSSIP_MENU_OPTION_ID_ANSWER_2, GOSSIP_SENDER_MAIN + 5, GOSSIP_ACTION_INFO_DEF);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE10,GOSSIP_MENU_OPTION_ID_ANSWER_3, GOSSIP_SENDER_MAIN + 2, GOSSIP_ACTION_INFO_DEF);
+ player->SEND_GOSSIP_MENU(GOSSIP_MENU_DIPLOMATIC_MISSION, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE11, GOSSIP_SENDER_MAIN + 6, GOSSIP_ACTION_INFO_DEF);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE12, GOSSIP_SENDER_MAIN + 7, GOSSIP_ACTION_INFO_DEF);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE13, GOSSIP_SENDER_MAIN + 8, GOSSIP_ACTION_INFO_DEF);
- player->SEND_GOSSIP_MENU(7362, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE11, GOSSIP_MENU_OPTION_ID_ANSWER_1, GOSSIP_SENDER_MAIN + 6, GOSSIP_ACTION_INFO_DEF);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE12, GOSSIP_MENU_OPTION_ID_ANSWER_2, GOSSIP_SENDER_MAIN + 7, GOSSIP_ACTION_INFO_DEF);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE13, GOSSIP_MENU_OPTION_ID_ANSWER_3, GOSSIP_SENDER_MAIN + 8, GOSSIP_ACTION_INFO_DEF);
+ player->SEND_GOSSIP_MENU(GOSSIP_MENU_YOUR_BROTHER_SEEKS, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE14, GOSSIP_SENDER_MAIN + 5, GOSSIP_ACTION_INFO_DEF);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE15, GOSSIP_SENDER_MAIN + 4, GOSSIP_ACTION_INFO_DEF);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE16, GOSSIP_SENDER_MAIN + 3, GOSSIP_ACTION_INFO_DEF);
- player->SEND_GOSSIP_MENU(7363, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE14, GOSSIP_MENU_OPTION_ID_ANSWER_1, GOSSIP_SENDER_MAIN + 5, GOSSIP_ACTION_INFO_DEF);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE15, GOSSIP_MENU_OPTION_ID_ANSWER_2, GOSSIP_SENDER_MAIN + 4, GOSSIP_ACTION_INFO_DEF);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE16, GOSSIP_MENU_OPTION_ID_ANSWER_3, GOSSIP_SENDER_MAIN + 3, GOSSIP_ACTION_INFO_DEF);
+ player->SEND_GOSSIP_MENU(GOSSIP_MENU_A_TERRIBLE_BEAST, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE17, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
- player->SEND_GOSSIP_MENU(7364, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_OPTION_SAYGE17, GOSSIP_MENU_OPTION_ID_ANSWER_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
+ player->SEND_GOSSIP_MENU(GOSSIP_MENU_YOUR_FORTUNE_IS_CAST, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6:
creature->CastSpell(player, SPELL_FORTUNE, false);
- player->SEND_GOSSIP_MENU(7365, creature->GetGUID());
+ player->SEND_GOSSIP_MENU(GOSSIP_MENU_HERE_IS_YOUR_FORTUNE, creature->GetGUID());
break;
}
}
@@ -1302,28 +1314,28 @@ public:
SendAction(player, creature, action);
break;
case GOSSIP_SENDER_MAIN + 1:
- spellId = SPELL_DMG;
+ spellId = SPELL_DAMAGE;
break;
case GOSSIP_SENDER_MAIN + 2:
- spellId = SPELL_RES;
+ spellId = SPELL_RESISTANCE;
break;
case GOSSIP_SENDER_MAIN + 3:
- spellId = SPELL_ARM;
+ spellId = SPELL_ARMOR;
break;
case GOSSIP_SENDER_MAIN + 4:
- spellId = SPELL_SPI;
+ spellId = SPELL_SPIRIT;
break;
case GOSSIP_SENDER_MAIN + 5:
- spellId = SPELL_INT;
+ spellId = SPELL_INTELLECT;
break;
case GOSSIP_SENDER_MAIN + 6:
- spellId = SPELL_STM;
+ spellId = SPELL_STAMINA;
break;
case GOSSIP_SENDER_MAIN + 7:
- spellId = SPELL_STR;
+ spellId = SPELL_STRENGTH;
break;
case GOSSIP_SENDER_MAIN + 8:
- spellId = SPELL_AGI;
+ spellId = SPELL_AGILITY;
break;
}
@@ -1743,149 +1755,6 @@ public:
};
/*######
-## npc_locksmith
-######*/
-
-enum LockSmith
-{
- QUEST_HOW_TO_BRAKE_IN_TO_THE_ARCATRAZ = 10704,
- QUEST_DARK_IRON_LEGACY = 3802,
- QUEST_THE_KEY_TO_SCHOLOMANCE_A = 5505,
- QUEST_THE_KEY_TO_SCHOLOMANCE_H = 5511,
- QUEST_HOTTER_THAN_HELL_A = 10758,
- QUEST_HOTTER_THAN_HELL_H = 10764,
- QUEST_RETURN_TO_KHAGDAR = 9837,
- QUEST_CONTAINMENT = 13159,
- QUEST_ETERNAL_VIGILANCE = 11011,
- QUEST_KEY_TO_THE_FOCUSING_IRIS = 13372,
- QUEST_HC_KEY_TO_THE_FOCUSING_IRIS = 13375,
-
- ITEM_ARCATRAZ_KEY = 31084,
- ITEM_SHADOWFORGE_KEY = 11000,
- ITEM_SKELETON_KEY = 13704,
- ITEM_SHATTERED_HALLS_KEY = 28395,
- ITEM_THE_MASTERS_KEY = 24490,
- ITEM_VIOLET_HOLD_KEY = 42482,
- ITEM_ESSENCE_INFUSED_MOONSTONE = 32449,
- ITEM_KEY_TO_THE_FOCUSING_IRIS = 44582,
- ITEM_HC_KEY_TO_THE_FOCUSING_IRIS = 44581,
-
- SPELL_ARCATRAZ_KEY = 54881,
- SPELL_SHADOWFORGE_KEY = 54882,
- SPELL_SKELETON_KEY = 54883,
- SPELL_SHATTERED_HALLS_KEY = 54884,
- SPELL_THE_MASTERS_KEY = 54885,
- SPELL_VIOLET_HOLD_KEY = 67253,
- SPELL_ESSENCE_INFUSED_MOONSTONE = 40173,
-};
-
-#define GOSSIP_LOST_ARCATRAZ_KEY "I've lost my key to the Arcatraz."
-#define GOSSIP_LOST_SHADOWFORGE_KEY "I've lost my key to the Blackrock Depths."
-#define GOSSIP_LOST_SKELETON_KEY "I've lost my key to the Scholomance."
-#define GOSSIP_LOST_SHATTERED_HALLS_KEY "I've lost my key to the Shattered Halls."
-#define GOSSIP_LOST_THE_MASTERS_KEY "I've lost my key to the Karazhan."
-#define GOSSIP_LOST_VIOLET_HOLD_KEY "I've lost my key to the Violet Hold."
-#define GOSSIP_LOST_ESSENCE_INFUSED_MOONSTONE "I've lost my Essence-Infused Moonstone."
-#define GOSSIP_LOST_KEY_TO_THE_FOCUSING_IRIS "I've lost my Key to the Focusing Iris."
-#define GOSSIP_LOST_HC_KEY_TO_THE_FOCUSING_IRIS "I've lost my Heroic Key to the Focusing Iris."
-
-class npc_locksmith : public CreatureScript
-{
-public:
- npc_locksmith() : CreatureScript("npc_locksmith") { }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- // Arcatraz Key
- if (player->GetQuestRewardStatus(QUEST_HOW_TO_BRAKE_IN_TO_THE_ARCATRAZ) && !player->HasItemCount(ITEM_ARCATRAZ_KEY, 1, true))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_ARCATRAZ_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
-
- // Shadowforge Key
- if (player->GetQuestRewardStatus(QUEST_DARK_IRON_LEGACY) && !player->HasItemCount(ITEM_SHADOWFORGE_KEY, 1, true))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_SHADOWFORGE_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
-
- // Skeleton Key
- if ((player->GetQuestRewardStatus(QUEST_THE_KEY_TO_SCHOLOMANCE_A) || player->GetQuestRewardStatus(QUEST_THE_KEY_TO_SCHOLOMANCE_H)) &&
- !player->HasItemCount(ITEM_SKELETON_KEY, 1, true))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_SKELETON_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
-
- // Shatered Halls Key
- if ((player->GetQuestRewardStatus(QUEST_HOTTER_THAN_HELL_A) || player->GetQuestRewardStatus(QUEST_HOTTER_THAN_HELL_H)) &&
- !player->HasItemCount(ITEM_SHATTERED_HALLS_KEY, 1, true))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_SHATTERED_HALLS_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
-
- // Master's Key
- if (player->GetQuestRewardStatus(QUEST_RETURN_TO_KHAGDAR) && !player->HasItemCount(ITEM_THE_MASTERS_KEY, 1, true))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_THE_MASTERS_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
-
- // Violet Hold Key
- if (player->GetQuestRewardStatus(QUEST_CONTAINMENT) && !player->HasItemCount(ITEM_VIOLET_HOLD_KEY, 1, true))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_VIOLET_HOLD_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
-
- // Essence-Infused Moonstone
- if (player->GetQuestRewardStatus(QUEST_ETERNAL_VIGILANCE) && !player->HasItemCount(ITEM_ESSENCE_INFUSED_MOONSTONE, 1, true))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_ESSENCE_INFUSED_MOONSTONE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7);
-
- // Key to the Focusing Iris
- if (player->GetQuestRewardStatus(QUEST_KEY_TO_THE_FOCUSING_IRIS) && !player->HasItemCount(ITEM_KEY_TO_THE_FOCUSING_IRIS, 1, true))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_KEY_TO_THE_FOCUSING_IRIS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8);
-
- // Heroic Key to the Focusing Iris
- if (player->GetQuestRewardStatus(QUEST_HC_KEY_TO_THE_FOCUSING_IRIS) && !player->HasItemCount(ITEM_HC_KEY_TO_THE_FOCUSING_IRIS, 1, true))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_HC_KEY_TO_THE_FOCUSING_IRIS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-
- bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF + 1:
- player->CLOSE_GOSSIP_MENU();
- player->CastSpell(player, SPELL_ARCATRAZ_KEY, false);
- break;
- case GOSSIP_ACTION_INFO_DEF + 2:
- player->CLOSE_GOSSIP_MENU();
- player->CastSpell(player, SPELL_SHADOWFORGE_KEY, false);
- break;
- case GOSSIP_ACTION_INFO_DEF + 3:
- player->CLOSE_GOSSIP_MENU();
- player->CastSpell(player, SPELL_SKELETON_KEY, false);
- break;
- case GOSSIP_ACTION_INFO_DEF + 4:
- player->CLOSE_GOSSIP_MENU();
- player->CastSpell(player, SPELL_SHATTERED_HALLS_KEY, false);
- break;
- case GOSSIP_ACTION_INFO_DEF + 5:
- player->CLOSE_GOSSIP_MENU();
- player->CastSpell(player, SPELL_THE_MASTERS_KEY, false);
- break;
- case GOSSIP_ACTION_INFO_DEF + 6:
- player->CLOSE_GOSSIP_MENU();
- player->CastSpell(player, SPELL_VIOLET_HOLD_KEY, false);
- break;
- case GOSSIP_ACTION_INFO_DEF + 7:
- player->CLOSE_GOSSIP_MENU();
- player->CastSpell(player, SPELL_ESSENCE_INFUSED_MOONSTONE, false);
- break;
- case GOSSIP_ACTION_INFO_DEF + 8:
- player->CLOSE_GOSSIP_MENU();
- player->AddItem(ITEM_KEY_TO_THE_FOCUSING_IRIS, 1);
- break;
- case GOSSIP_ACTION_INFO_DEF + 9:
- player->CLOSE_GOSSIP_MENU();
- player->AddItem(ITEM_HC_KEY_TO_THE_FOCUSING_IRIS, 1);
- break;
- }
- return true;
- }
-};
-
-/*######
## npc_experience
######*/
@@ -2589,7 +2458,6 @@ void AddSC_npcs_special()
new npc_training_dummy();
new npc_wormhole();
new npc_pet_trainer();
- new npc_locksmith();
new npc_experience();
new npc_firework();
new npc_spring_rabbit();
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index f4d736ac675..0241221a2ac 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -52,6 +52,7 @@
#include "Realm/Realm.h"
#include "DatabaseLoader.h"
#include "AppenderDB.h"
+#include "Metric.h"
using namespace boost::program_options;
namespace fs = boost::filesystem;
@@ -196,6 +197,13 @@ extern int main(int argc, char** argv)
LoadRealmInfo();
+ sMetric->Initialize(realm.Name, _ioService, []()
+ {
+ TC_METRIC_VALUE("online_players", sWorld->GetPlayerCount());
+ });
+
+ TC_METRIC_EVENT("events", "Worldserver started", "");
+
// Initialize the World
sScriptMgr->SetScriptLoader(AddScripts);
sWorld->SetInitialWorldSettings();
@@ -295,6 +303,9 @@ extern int main(int argc, char** argv)
StopDB();
+ TC_METRIC_EVENT("events", "Worldserver shutdown", "");
+ sMetric->ForceSend();
+
TC_LOG_INFO("server.worldserver", "Halting process...");
ShutdownCLIThread(cliThread);
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index ccb784f8c2b..b832d0e8224 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -34,6 +34,7 @@
# AUCTION HOUSE BOT BUYER CONFIG
# LOGGING SYSTEM SETTINGS
# PACKET SPOOF PROTECTION SETTINGS
+# METRIC SETTINGS
#
###################################################################################################
@@ -3283,7 +3284,7 @@ AuctionHouseBot.Items.Amount.Yellow = 0
# Armor: 8
# Reagent: 1
# Projectile: 2
-# TradeGod: 10
+# TradeGood: 10
# Generic: 1
# Recipe: 6
# Quiver: 1
@@ -3700,3 +3701,42 @@ PacketSpoof.BanDuration = 86400
#
###################################################################################################
+
+###################################################################################################
+# METRIC SETTINGS
+#
+# These settings control the statistics sent to the metric database (currently InfluxDB)
+#
+# Metric.Enable
+# Description: Enables statistics sent to the metric database.
+# Default: 0 - (Disabled)
+# 1 - (Enabled)
+
+Metric.Enable = 0
+
+#
+# Metric.Interval
+# Description: Interval between every batch of data sent in seconds
+# Default: 10 seconds
+#
+
+Metric.Interval = 10
+
+#
+# Metric.ConnectionInfo
+# Description: Connection settings for metric database (currently InfluxDB).
+# Example: "hostname;port;database"
+# Default: "127.0.0.1;8086;worldserver"
+
+Metric.ConnectionInfo = "127.0.0.1;8086;worldserver"
+
+#
+# Metric.OverallStatusInterval
+# Description: Interval between every gathering of overall worldserver status data in seconds
+# Default: 1 second
+#
+
+Metric.OverallStatusInterval = 1
+
+#
+###################################################################################################