Merge branch 'master' into Playerbot
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
# Used by "mix format"
|
||||||
|
[
|
||||||
|
inputs: [
|
||||||
|
".formatter.exs",
|
||||||
|
"account.exs"
|
||||||
|
]
|
||||||
|
]
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
FROM elixir:1.14-slim
|
||||||
|
|
||||||
|
RUN mix local.hex --force && \
|
||||||
|
mix local.rebar --force
|
||||||
|
|
||||||
|
COPY account.exs /account.exs
|
||||||
|
COPY srp.exs /srp.exs
|
||||||
|
RUN chmod +x /account.exs
|
||||||
|
|
||||||
|
CMD /account.exs
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
# Account.exs
|
||||||
|
|
||||||
|
Simple script to create an account for AzerothCore
|
||||||
|
|
||||||
|
This script allows a server admin to create a user automatically when after the `dbimport` tool runs, without needed to open up the `worldserver` console.
|
||||||
|
|
||||||
|
## How To Use
|
||||||
|
|
||||||
|
### Pre-requisites
|
||||||
|
|
||||||
|
- MySQL is running
|
||||||
|
- The authserver database (`acore_auth`, typically) has a table named `account`
|
||||||
|
|
||||||
|
### Running
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ elixir account.exs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
This script reads from environment variables in order to control which account it creates and the MySQL server it's communicating with
|
||||||
|
|
||||||
|
|
||||||
|
- `ACORE_USERNAME` Username for account, default "admin"
|
||||||
|
- `ACORE_PASSWORD` Password for account, default "admin"
|
||||||
|
- `ACORE_GM_LEVEL` GM Level for account, default 3
|
||||||
|
- `MYSQL_DATABASE` Database name, default "acore_auth"
|
||||||
|
- `MYSQL_USERNAME` MySQL username, default "root"
|
||||||
|
- `MYSQL_PASSWORD` MySQL password, default "password"
|
||||||
|
- `MYSQL_PORT` MySQL Port, default 3306
|
||||||
|
- `MYSQL_HOST` MySQL Host, default "localhost"
|
||||||
|
|
||||||
|
To use these environment variables, execute the script like so:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ MYSQL_HOST=mysql \
|
||||||
|
MYSQL_PASSWORD="fourthehoard" \
|
||||||
|
ACORE_USERNAME=drekthar \
|
||||||
|
ACORE_PASSWORD=securepass22 \
|
||||||
|
elixir account.exs
|
||||||
|
```
|
||||||
|
|
||||||
|
This can also be used in a loop. Consider this csv file:
|
||||||
|
|
||||||
|
```csv
|
||||||
|
user,pass,gm_level
|
||||||
|
admin,adminpass,2
|
||||||
|
soapuser,soappass,3
|
||||||
|
mainuser,userpass,0
|
||||||
|
```
|
||||||
|
|
||||||
|
You can then loop over this csv file, and manage users like so:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ while IFS=, read -r user pass gm; do
|
||||||
|
ACORE_USERNAME=$user \
|
||||||
|
ACORE_PASSWORD=$pass \
|
||||||
|
GM_LEVEL=$gm \
|
||||||
|
elixir account.exs
|
||||||
|
done <<< $(tail -n '+2' users.csv)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
Running and building with docker is simple:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker build -t acore/account-create .
|
||||||
|
$ docker run \
|
||||||
|
-e MYSQL_HOST=mysql \
|
||||||
|
-v mix_cache:/root/.cache/mix/installs \
|
||||||
|
acore/account-create
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the `MYSQL_HOST` is required to be set with the docker container, as the default setting targets `localhost`.
|
||||||
|
|
||||||
|
### docker-compose
|
||||||
|
|
||||||
|
A simple way to integrate this into a docker-compose file.
|
||||||
|
|
||||||
|
This is why I wrote this script - an automatic way to have an admin account idempotently created on startup of the server.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
account-create:
|
||||||
|
image: acore/account-create:${DOCKER_IMAGE_TAG:-master}
|
||||||
|
build:
|
||||||
|
context: apps/account-create/
|
||||||
|
dockerfile: apps/account-create/Dockerfile
|
||||||
|
environment:
|
||||||
|
MYSQL_HOST: ac-database
|
||||||
|
MYSQL_PASSWORD: ${DOCKER_DB_ROOT_PASSWORD:-password}
|
||||||
|
ACORE_USERNAME: ${ACORE_ROOT_ADMIN_ACCOUNT:-admin}
|
||||||
|
ACORE_PASSWORD: ${ACORE_ROOT_ADMIN_PASSWORD:-password}
|
||||||
|
volumes:
|
||||||
|
- mix_cache:/root/.cache/mix/installs
|
||||||
|
profiles: [local, app, db-import-local]
|
||||||
|
depends_on:
|
||||||
|
ac-db-import:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
```
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
#!/usr/bin/env elixir
|
||||||
|
# Execute this Elixir script with the below command
|
||||||
|
#
|
||||||
|
# $ ACORE_USERNAME=foo ACORE_PASSWORD=barbaz123 elixir account.exs
|
||||||
|
#
|
||||||
|
# Set environment variables for basic configuration
|
||||||
|
#
|
||||||
|
# ACORE_USERNAME - Username for account, default "admin"
|
||||||
|
# ACORE_PASSWORD - Password for account, default "admin"
|
||||||
|
# ACORE_GM_LEVEL - GM level for account
|
||||||
|
# MYSQL_DATABASE - Database name, default "acore_auth"
|
||||||
|
# MYSQL_USERNAME - MySQL username, default "root"
|
||||||
|
# MYSQL_PASSWORD - MySQL password, default "password"
|
||||||
|
# MYSQL_PORT - MySQL Port, default 3306
|
||||||
|
# MYSQL_HOST - MySQL Host, default "localhost"
|
||||||
|
|
||||||
|
# Install remote dependencies
|
||||||
|
[
|
||||||
|
{:myxql, "~> 0.6.0"}
|
||||||
|
]
|
||||||
|
|> Mix.install()
|
||||||
|
|
||||||
|
# Start the logger
|
||||||
|
Application.start(:logger)
|
||||||
|
require Logger
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
default_credential = "admin"
|
||||||
|
default_gm_level = "3"
|
||||||
|
account_access_comment = "Managed via account-create script"
|
||||||
|
|
||||||
|
# Import srp functions
|
||||||
|
Code.require_file("srp.exs", Path.absname(__DIR__))
|
||||||
|
|
||||||
|
# Assume operator provided a "human-readable" name.
|
||||||
|
# The database stores usernames in all caps
|
||||||
|
username_lower =
|
||||||
|
System.get_env("ACORE_USERNAME", default_credential)
|
||||||
|
|> tap(&Logger.info("Account to create: #{&1}"))
|
||||||
|
|
||||||
|
username = String.upcase(username_lower)
|
||||||
|
|
||||||
|
password = System.get_env("ACORE_PASSWORD", default_credential)
|
||||||
|
|
||||||
|
gm_level = System.get_env("ACORE_GM_LEVEL", default_gm_level) |> String.to_integer()
|
||||||
|
|
||||||
|
if Range.new(0, 3) |> Enum.member?(gm_level) |> Kernel.not do
|
||||||
|
Logger.info("Valid ACORE_GM_LEVEL values are 0, 1, 2, and 3. The given value was: #{gm_level}.")
|
||||||
|
end
|
||||||
|
|
||||||
|
{:ok, pid} =
|
||||||
|
MyXQL.start_link(
|
||||||
|
protocol: :tcp,
|
||||||
|
database: System.get_env("MYSQL_DATABASE", "acore_auth"),
|
||||||
|
username: System.get_env("MYSQL_USERNAME", "root"),
|
||||||
|
password: System.get_env("MYSQL_PASSWORD", "password"),
|
||||||
|
port: System.get_env("MYSQL_PORT", "3306") |> String.to_integer(),
|
||||||
|
hostname: System.get_env("MYSQL_HOST", "localhost")
|
||||||
|
)
|
||||||
|
|
||||||
|
Logger.info("MySQL connection created")
|
||||||
|
|
||||||
|
Logger.info("Checking database for user #{username_lower}")
|
||||||
|
|
||||||
|
# Check if user already exists in database
|
||||||
|
{:ok, result} = MyXQL.query(pid, "SELECT salt FROM account WHERE username=?", [username])
|
||||||
|
|
||||||
|
%{salt: salt, verifier: verifier} =
|
||||||
|
case result do
|
||||||
|
%{rows: [[salt | _] | _]} ->
|
||||||
|
Logger.info("Salt for #{username_lower} found in database")
|
||||||
|
# re-use the salt if the user exists in database
|
||||||
|
Srp.generate_stored_values(username, password, salt)
|
||||||
|
_ ->
|
||||||
|
Logger.info("Salt not found in database for #{username_lower}. Generating a new one")
|
||||||
|
Srp.generate_stored_values(username, password)
|
||||||
|
end
|
||||||
|
|
||||||
|
Logger.info("New salt and verifier generated")
|
||||||
|
|
||||||
|
# Insert values into DB, replacing the verifier if the user already exists
|
||||||
|
result =
|
||||||
|
MyXQL.query(
|
||||||
|
pid,
|
||||||
|
"""
|
||||||
|
INSERT INTO account
|
||||||
|
(`username`, `salt`, `verifier`)
|
||||||
|
VALUES
|
||||||
|
(?, ?, ?)
|
||||||
|
ON DUPLICATE KEY UPDATE verifier=?
|
||||||
|
""",
|
||||||
|
[username, salt, verifier, verifier]
|
||||||
|
)
|
||||||
|
|
||||||
|
case result do
|
||||||
|
{:error, %{message: message}} ->
|
||||||
|
File.write("fail.log", message)
|
||||||
|
|
||||||
|
Logger.info(
|
||||||
|
"Account #{username_lower} failed to create. You can check the error message at fail.log."
|
||||||
|
)
|
||||||
|
|
||||||
|
exit({:shutdown, 1})
|
||||||
|
|
||||||
|
# if num_rows changed and last_insert_id == 0, it means the verifier matched. No change necessary
|
||||||
|
{:ok, %{num_rows: 1, last_insert_id: 0}} ->
|
||||||
|
Logger.info(
|
||||||
|
"Account #{username_lower} doesn't need to have its' password changed. You should be able to log in with that account"
|
||||||
|
)
|
||||||
|
|
||||||
|
{:ok, %{num_rows: 1}} ->
|
||||||
|
Logger.info(
|
||||||
|
"Account #{username_lower} has been created. You should now be able to login with that account"
|
||||||
|
)
|
||||||
|
|
||||||
|
{:ok, %{num_rows: 2}} ->
|
||||||
|
Logger.info(
|
||||||
|
"Account #{username_lower} has had its' password reset. You should now be able to login with that account"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Set GM level to configured value
|
||||||
|
{:ok, _} =
|
||||||
|
MyXQL.query(
|
||||||
|
pid,
|
||||||
|
"""
|
||||||
|
INSERT INTO account_access
|
||||||
|
(`id`, `gmlevel`, `comment`)
|
||||||
|
VALUES
|
||||||
|
((SELECT id FROM account WHERE username=?), ?, ?)
|
||||||
|
ON DUPLICATE KEY UPDATE gmlevel=?, comment=?
|
||||||
|
""", [username, gm_level, account_access_comment, gm_level, account_access_comment])
|
||||||
|
|
||||||
|
Logger.info("GM Level for #{username_lower} set to #{gm_level}")
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
defmodule Srp do
|
||||||
|
# Constants required in WoW's SRP6 implementation
|
||||||
|
@n <<137, 75, 100, 94, 137, 225, 83, 91, 189, 173, 91, 139, 41, 6, 80, 83, 8, 1, 177, 142, 191,
|
||||||
|
191, 94, 143, 171, 60, 130, 135, 42, 62, 155, 183>>
|
||||||
|
@g <<7>>
|
||||||
|
@field_length 32
|
||||||
|
|
||||||
|
# Wrapper function
|
||||||
|
def generate_stored_values(username, password, salt \\ "") do
|
||||||
|
default_state()
|
||||||
|
|> generate_salt(salt)
|
||||||
|
|> calculate_x(username, password)
|
||||||
|
|> calculate_v()
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_state() do
|
||||||
|
%{n: @n, g: @g}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Generate salt if it's not defined
|
||||||
|
def generate_salt(state, "") do
|
||||||
|
salt = :crypto.strong_rand_bytes(32)
|
||||||
|
Map.merge(state, %{salt: salt})
|
||||||
|
end
|
||||||
|
|
||||||
|
# Don't generate salt if it's already defined
|
||||||
|
def generate_salt(state, salt) do
|
||||||
|
padded_salt = pad_binary(salt)
|
||||||
|
Map.merge(state, %{salt: padded_salt})
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get h1
|
||||||
|
def calculate_x(state, username, password) do
|
||||||
|
hash = :crypto.hash(:sha, String.upcase(username) <> ":" <> String.upcase(password))
|
||||||
|
x = reverse(:crypto.hash(:sha, state.salt <> hash))
|
||||||
|
Map.merge(state, %{x: x, username: username})
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get h2
|
||||||
|
def calculate_v(state) do
|
||||||
|
verifier =
|
||||||
|
:crypto.mod_pow(state.g, state.x, state.n)
|
||||||
|
|> reverse()
|
||||||
|
|> pad_binary()
|
||||||
|
|
||||||
|
Map.merge(state, %{verifier: verifier})
|
||||||
|
end
|
||||||
|
|
||||||
|
defp pad_binary(blob) do
|
||||||
|
pad = @field_length - byte_size(blob)
|
||||||
|
<<blob::binary, 0::pad*8>>
|
||||||
|
end
|
||||||
|
|
||||||
|
defp reverse(binary) do
|
||||||
|
binary
|
||||||
|
|> :binary.decode_unsigned(:big)
|
||||||
|
|> :binary.encode_unsigned(:little)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- DB update 2023_06_21_00 -> 2023_06_22_00
|
||||||
|
--
|
||||||
|
DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_murmur_touch', 'spell_shockwave_knockback');
|
||||||
|
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||||
|
(33686, 'spell_shockwave_knockback');
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- DB update 2023_06_22_00 -> 2023_06_23_00
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 818) AND (`source_type` = 0) AND (`id` IN (2));
|
||||||
|
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`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(818, 0, 2, 0, 23, 0, 100, 0, 12544, 0, 10000, 10000, 0, 11, 12544, 64, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai\'Zoth - On Aura \'Frost Armor\' Missing - Cast \'Frost Armor\'');
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
-- DB update 2023_06_23_00 -> 2023_06_23_01
|
||||||
|
UPDATE `creature` SET `MovementType` = 2 WHERE `guid` IN (6974,6989,7210) AND `id1` IN (2718,2717,2907);
|
||||||
|
DELETE FROM `creature_addon` WHERE (`guid` IN (6974,6989,7210));
|
||||||
|
INSERT INTO `creature_addon` (`guid`, `path_id`, `bytes2`) VALUES
|
||||||
|
(6974, 69740, 1),
|
||||||
|
(6989, 69890, 1),
|
||||||
|
(7210, 72100, 1);
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- DB update 2023_06_23_01 -> 2023_06_24_00
|
||||||
|
--
|
||||||
|
UPDATE `smart_scripts` SET `action_param2`=0 WHERE `entryorguid`=1651800 AND `source_type`=9 AND `id` IN (2, 6);
|
||||||
|
|
||||||
|
UPDATE `creature_template` SET `faction`=7 WHERE `entry`=16534;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2023_06_24_00 -> 2023_06_24_01
|
||||||
|
-- Add extra flag 33554432 to several skeleton creatures in Auchenai Crypts to avoid chain pulling
|
||||||
|
UPDATE `creature_template` SET `flags_extra` = `flags_extra`|33554432 WHERE (`entry` IN (18700, 20317, 18521, 20315, 18524, 20298));
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
-- DB update 2023_06_24_01 -> 2023_06_24_02
|
||||||
|
--
|
||||||
|
DELETE FROM `npc_trainer` WHERE `SpellID` IN (
|
||||||
|
39973, -- Frost Grenades
|
||||||
|
40274, -- Furious Gizmatic Goggles
|
||||||
|
41311, -- Justicebringer 2000 Specs
|
||||||
|
41312, -- Tankatronic Goggles
|
||||||
|
41314, -- Surestrike Goggles v2.0
|
||||||
|
41315, -- Gadgetstorm Goggles
|
||||||
|
41316, -- Living Replicator Specs
|
||||||
|
41317, -- Deathblow X11 Goggles
|
||||||
|
41318, -- Wonderheal XT40 Shades
|
||||||
|
41319, -- Magnified Moon Specs
|
||||||
|
41320, -- Destruction Holo-gogs
|
||||||
|
41321 -- Powerheal 4000 Lens
|
||||||
|
);
|
||||||
|
INSERT INTO `npc_trainer` (`ID`, `SpellID`, `MoneyCost`, `ReqSkillLine`, `ReqSkillRank`, `ReqLevel`, `ReqSpell`) VALUES
|
||||||
|
(201013, 39973, 50000, 202, 335, 0, 0),
|
||||||
|
(201013, 40274, 50000, 202, 350, 0, 0),
|
||||||
|
(201013, 41311, 50000, 202, 350, 0, 0),
|
||||||
|
(201013, 41312, 50000, 202, 350, 0, 0),
|
||||||
|
(201013, 41314, 50000, 202, 350, 0, 0),
|
||||||
|
(201013, 41315, 50000, 202, 350, 0, 0),
|
||||||
|
(201013, 41316, 50000, 202, 350, 0, 0),
|
||||||
|
(201013, 41317, 50000, 202, 350, 0, 0),
|
||||||
|
(201013, 41318, 50000, 202, 350, 0, 0),
|
||||||
|
(201013, 41319, 50000, 202, 350, 0, 0),
|
||||||
|
(201013, 41320, 50000, 202, 350, 0, 0);
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- DB update 2023_06_24_02 -> 2023_06_24_03
|
||||||
|
--
|
||||||
|
DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_capacitus_polarity_charge_aura';
|
||||||
|
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||||
|
(39088, 'spell_capacitus_polarity_charge_aura'),
|
||||||
|
(39091, 'spell_capacitus_polarity_charge_aura');
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- DB update 2023_06_24_03 -> 2023_06_24_04
|
||||||
|
DELETE FROM `npc_trainer` WHERE `SpellID` = 41321;
|
||||||
|
INSERT INTO `npc_trainer` (`ID`, `SpellID`, `MoneyCost`, `ReqSkillLine`, `ReqSkillRank`, `ReqLevel`, `ReqSpell`) VALUES
|
||||||
|
(201013, 41321, 50000, 202, 350, 0, 0);
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2023_06_24_04 -> 2023_06_24_05
|
||||||
|
--
|
||||||
|
UPDATE `creature_template` SET `ScriptName` = '' WHERE `ScriptName` = 'npc_ahune_frozen_core';
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2023_06_24_05 -> 2023_06_24_06
|
||||||
|
--
|
||||||
|
UPDATE `creature_template` SET `ScriptName` = '' WHERE (`entry` = 16592);
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
-- DB update 2023_06_24_06 -> 2023_06_26_00
|
||||||
|
-- Shay Leafrunner - On Quest - Wandering Shay --
|
||||||
|
UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE (`entry` = 7774);
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 7774);
|
||||||
|
INSERT INTO `smart_scripts` VALUES
|
||||||
|
(7774, 0, 0, 0, 19, 0, 100, 0, 2845, 0, 0, 0, 0, 80, 777400, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - On Quest \'Wandering Shay\' Taken - Run Script'),
|
||||||
|
(7774, 0, 1, 0, 8, 0, 100, 0, 11402, 0, 0, 0, 0, 80, 777401, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - On Spellhit \'Shay`s Bell\' - Run Script'),
|
||||||
|
(7774, 0, 2, 0, 75, 0, 100, 0, 0, 7765, 7, 10000, 0, 80, 777402, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - On Distance To Creature - Run Script'),
|
||||||
|
(7774, 0, 3, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 80, 777403, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - On Just Died - Run Script'),
|
||||||
|
(7774, 0, 4, 0, 38, 0, 100, 0, 1, 1, 0, 0, 0, 67, 61, 30000, 35000, 60000, 65000, 100, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - On Data Set 1 1 - Create Timed Event'),
|
||||||
|
(7774, 0, 5, 6, 59, 0, 100, 0, 61, 0, 0, 0, 0, 73, 38, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - On Timed Event 61 Triggered - Trigger Timed Event 38'),
|
||||||
|
(7774, 0, 6, 7, 61, 0, 100, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - On Timed Event 61 Triggered - Stop Follow '),
|
||||||
|
(7774, 0, 7, 8, 61, 0, 100, 0, 0, 0, 0, 0, 0, 89, 15, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - On Data Set 1 1 - Start Random Movement'),
|
||||||
|
(7774, 0, 8, 9, 61, 0, 100, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - On Data Set 1 1 - Say Line 2'),
|
||||||
|
(7774, 0, 9, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - On Data Set 1 1 - Say Line 3'),
|
||||||
|
(7774, 0, 10, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 74, 61, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - On Respawn - Remove Timed Event 61'),
|
||||||
|
(7774, 0, 11, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 6, 2845, 0, 0, 0, 0, 0, 18, 10, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - On Just Died - Fail Quest \'Wandering Shay\''),
|
||||||
|
(7774, 0, 12, 0, 75, 0, 100, 1, 0, 7765, 10, 5000, 0, 1, 0, 0, 0, 0, 0, 0, 11, 7765, 10, 1, 0, 0, 0, 0, 0, 'Shay Leafrunner - On Distance To Creature - Say Line 0');
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 777400);
|
||||||
|
INSERT INTO `smart_scripts` VALUES
|
||||||
|
(777400, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 19, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - Actionlist - Remove Flags Immune To Players & Immune To NPC\'s'),
|
||||||
|
(777400, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 29, 2, 3, 7765, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - Actionlist - Start Follow Invoker'),
|
||||||
|
(777400, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - Actionlist - Say Line 0'),
|
||||||
|
(777400, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - Actionlist - Set Data 1 1');
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 777401);
|
||||||
|
INSERT INTO `smart_scripts` VALUES
|
||||||
|
(777401, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 29, 2, 3, 7765, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - Actionlist - Start Follow Invoker'),
|
||||||
|
(777401, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - Actionlist - Say Line 1');
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 777402);
|
||||||
|
INSERT INTO `smart_scripts` VALUES
|
||||||
|
(777402, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 15, 2845, 0, 0, 0, 0, 0, 18, 10, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - Actionlist - Quest Credit \'Wandering Shay\''),
|
||||||
|
(777402, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - Actionlist - Say Line 4');
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 777403);
|
||||||
|
INSERT INTO `smart_scripts` VALUES
|
||||||
|
(777403, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 6, 2845, 0, 0, 0, 0, 0, 18, 10, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - Actionlist - Fail Quest \'Wandering Shay\''),
|
||||||
|
(777403, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - Actionlist - Set Flags Immune To Players & Immune To NPC\'s'),
|
||||||
|
(777403, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 74, 61, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shay Leafrunner - Actionlist - Remove Timed Event 61');
|
||||||
@@ -0,0 +1,331 @@
|
|||||||
|
-- DB update 2023_06_26_00 -> 2023_06_26_01
|
||||||
|
--
|
||||||
|
SET @OGUID := 76200;
|
||||||
|
|
||||||
|
DELETE FROM `gameobject` WHERE `id` = 181288 AND `guid` BETWEEN @OGUID AND @OGUID+77;
|
||||||
|
INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`) VALUES
|
||||||
|
(@OGUID+0 , 181288, 0, 0, 0, 1, 1, -14376.7, 115.921, 1.4532, 2.11185, 0, 0, 0.870356, 0.492423, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+1 , 181288, 0, 0, 0, 1, 1, -14288.1, 61.8062, 0.68836, 1.37881, 0, 0, 0.636078, 0.771625, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+2 , 181288, 0, 0, 0, 1, 1, -10951.5, -3218.1, 41.3475, 1.91986, 0, 0, 0.819151, 0.573577, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+3 , 181288, 0, 0, 0, 1, 1, -10704.8, -1146.38, 24.7909, 2.09439, 0, 0, 0.866024, 0.500002, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+4 , 181288, 0, 0, 0, 1, 1, -10657.1, 1054.63, 32.6733, 2.47837, 0, 0, 0.945519, 0.325567, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+5 , 181288, 0, 0, 0, 1, 1, -10331.4, -3297.73, 21.9992, -2.89725, 0, 0, -0.992546, 0.121868, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+6 , 181288, 0, 0, 0, 1, 1, -9434.3, -2110.36, 65.8038, 0.349066, 0, 0, 0.173648, 0.984808, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+7 , 181288, 0, 0, 0, 1, 1, -9394.21, 37.5017, 59.882, 1.15192, 0, 0, 0.54464, 0.83867, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+8 , 181288, 0, 0, 0, 1, 1, -8245.62, -2623.9, 133.155, 4.04776, 0, 0, 0.899102, -0.43774, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+9 , 181288, 0, 0, 0, 1, 1, -7596.42, -2086.6, 125.17, -0.942478, 0, 0, -0.453991, 0.891006, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+10, 181288, 0, 0, 0, 1, 1, -6704.48, -2200.91, 248.609, 0.017453, 0, 0, 0.00872639, 0.999962, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+11, 181288, 0, 0, 0, 1, 1, -5404.93, -492.299, 395.597, -0.506145, 0, 0, -0.25038, 0.968148, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+12, 181288, 0, 0, 0, 1, 1, -5233.16, -2893.37, 337.286, -0.226893, 0, 0, -0.113203, 0.993572, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+13, 181288, 0, 0, 0, 1, 1, -3448.2, -938.102, 10.6583, 0.034907, 0, 0, 0.0174526, 0.999848, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+14, 181288, 0, 0, 0, 1, 1, -1211.6, -2676.88, 45.3612, -0.645772, 0, 0, -0.317305, 0.948324, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+15, 181288, 0, 0, 0, 1, 1, -1134.84, -3531.81, 51.0719, -0.820305, 0, 0, -0.398749, 0.91706, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+16, 181288, 0, 0, 0, 1, 1, -604.148, -545.813, 36.579, 0.698132, 0, 0, 0.34202, 0.939693, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+17, 181288, 0, 0, 0, 1, 1, -447.95, -4527.65, 8.59595, 1.53589, 0, 0, 0.694658, 0.71934, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+18, 181288, 0, 0, 0, 1, 1, -134.688, -802.767, 55.0147, -1.62316, 0, 0, -0.725376, 0.688353, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+19, 181288, 0, 0, 0, 1, 1, 188.243, -2132.53, 102.674, -1.37881, 0, 0, -0.636078, 0.771625, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+20, 181288, 0, 0, 0, 1, 1, 587.056, 1365.02, 90.4778, 2.6529, 0, 0, 0.970296, 0.241922, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+21, 181288, 0, 0, 0, 1, 1, 989.562, -1453.47, 61.0011, 4.9105, 0, 0, 0.633712, -0.773569, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+22, 181288, 0, 0, 0, 1, 1, 2279.25, 456.009, 33.867, 0.3665, 0, 0, 0.182226, 0.983257, 120, 0, 1, '', 0),
|
||||||
|
(@OGUID+23, 181288, 1, 0, 0, 1, 1, -7216.68, -3859.39, 11.4943, -2.72271, 0, 0, -0.978147, 0.207914, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+24, 181288, 1, 0, 0, 1, 1, -7122.51, -3657.11, 8.82202, -1.74533, 0, 0, -0.766045, 0.642787, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+25, 181288, 1, 0, 0, 1, 1, -7000.75, 918.851, 8.93831, -2.23402, 0, 0, -0.898794, 0.438372, 900, 100, 1, '', 0),
|
||||||
|
(@OGUID+26, 181288, 1, 0, 0, 1, 1, -6771.96, 527.151, -1.40004, 3.1949, 0, 0, 0.999645, -0.0266505, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+27, 181288, 1, 0, 0, 1, 1, -5513.93, -2299.73, -58.0752, 2.44346, 0, 0, 0.939692, 0.342021, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+28, 181288, 1, 0, 0, 1, 1, -4573.22, 407.388, 41.5461, 2.46091, 0, 0, 0.942641, 0.333809, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+29, 181288, 1, 0, 0, 1, 1, -4412.02, 3480.24, 12.6312, 6.12709, 0, 0, 0.0779684, -0.996956, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+30, 181288, 1, 0, 0, 1, 1, -3447.55, -4231.67, 10.6645, 0.802851, 0, 0, 0.390731, 0.920505, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+31, 181288, 1, 0, 0, 1, 1, -3110.59, -2722.41, 33.4626, 0.226893, 0, 0, 0.113203, 0.993572, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+32, 181288, 1, 0, 0, 1, 1, -2329.42, -624.806, -8.27507, 5.5, 0, 0, 0.381661, -0.924302, 0, 100, 1, '', 0),
|
||||||
|
(@OGUID+33, 181288, 1, 0, 0, 1, 1, -1862.36, 3055.71, 0.744157, 2.49582, 0, 0, 0.948324, 0.317305, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+34, 181288, 1, 0, 0, 1, 1, -273.242, -2662.82, 91.695, -1.8675, 0, 0, -0.803856, 0.594824, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+35, 181288, 1, 0, 0, 1, 1, -55.5039, 1271.35, 91.9489, 1.5708, 0, 0, 0.707108, 0.707106, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+36, 181288, 1, 0, 0, 1, 1, 145.521, -4713.82, 18.129, -2.53, 0, 0, -0.953607, 0.301053, 120, 0, 1, '', 0),
|
||||||
|
(@OGUID+37, 181288, 1, 0, 0, 1, 1, 952.992, 776.968, 104.474, -1.55334, 0, 0, -0.700908, 0.713252, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+38, 181288, 1, 0, 0, 1, 1, 2014.65, -2337.84, 89.5211, 2.37365, 0, 0, 0.927184, 0.374606, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+39, 181288, 1, 0, 0, 1, 1, 2558.73, -481.666, 109.821, -2.47837, 0, 0, -0.945519, 0.325567, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+40, 181288, 1, 0, 0, 1, 1, 6327.68, 512.61, 17.4723, 0.034907, 0, 0, 0.0174526, 0.999848, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+41, 181288, 1, 0, 0, 1, 1, 6855.99, -4564.4, 708.51, 0.855211, 0, 0, 0.414693, 0.909961, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+42, 181288, 1, 0, 0, 1, 1, 6860.03, -4767.11, 696.833, -2.63545, 0, 0, -0.968148, 0.250379, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+43, 181288, 1, 0, 0, 1, 1, 9778.64, 1019.38, 1299.79, 0.261799, 0, 0, 0.130526, 0.991445, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+44, 181288, 530, 0, 0, 1, 1, -4223.84, -12318.4, 2.47695, 5.69342, 0, 0, 0.290628, -0.956836, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+45, 181288, 530, 0, 0, 1, 1, -3941.98, 2048.49, 95.0656, 4.87742, 0, 0, 0.64642, -0.762982, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+46, 181288, 530, 0, 0, 1, 1, -3059.17, 2374.85, 63.1011, 2.03334, 0, 0, 0.850361, 0.526201, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+47, 181288, 530, 0, 0, 1, 1, -3004.07, 4152.48, 3.64988, 1.75455, 0, 0, 0.769, 0.639249, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+48, 181288, 530, 0, 0, 1, 1, -2553.32, 4277.61, 20.614, -1.36136, 0, 0, -0.629322, 0.777145, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+49, 181288, 530, 0, 0, 1, 1, -2526.69, 7548.83, -2.23534, 5.32817, 0, 0, 0.459567, -0.888143, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+50, 181288, 530, 0, 0, 1, 1, -2254.78, -11896.3, 27.4979, 5.24028, 0, 0, 0.49814, -0.867096, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+51, 181288, 530, 0, 0, 1, 1, -1211.01, 7474.44, 21.9953, -2.02458, 0, 0, -0.848048, 0.52992, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+52, 181288, 530, 0, 0, 1, 1, -528.509, 2339.11, 38.7252, 2.14675, 0, 0, 0.878816, 0.477161, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+53, 181288, 530, 0, 0, 1, 1, 41.2448, 2587.44, 68.3453, -2.28638, 0, 0, -0.909961, 0.414694, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+54, 181288, 530, 0, 0, 1, 1, 192.209, 6015.13, 22.1067, 0.00709009, 0, 0, 0.00354504, 0.999994, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+55, 181288, 530, 0, 0, 1, 1, 200.9, 7686.96, 22.508, -0.506145, 0, 0, -0.25038, 0.968148, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+56, 181288, 530, 0, 0, 1, 1, 2019.7, 6587.14, 134.985, 6.23705, 0, 0, 0.0230656, -0.999734, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+57, 181288, 530, 0, 0, 1, 1, 2282.43, 6134.5, 136.337, 6.01364, 0, 0, 0.134365, -0.990932, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+58, 181288, 530, 0, 0, 1, 1, 2922.17, 3690.15, 143.809, 5.94709, 0, 0, 0.167258, -0.985913, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+59, 181288, 530, 0, 0, 1, 1, 3121.5, 3753.88, 141.851, 5.85856, 0, 0, 0.210721, -0.977546, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+60, 181288, 530, 0, 0, 1, 1, 7693.53, -6836.51, 77.787, 2.7052, 0, 0, 0.976289, 0.216469, 120, 0, 1, '', 0),
|
||||||
|
(@OGUID+61, 181288, 530, 0, 0, 1, 1, 9386.86, -6772.24, 14.412, -2.9146, 0, 0, -0.993566, 0.113253, 120, 0, 1, '', 0),
|
||||||
|
(@OGUID+62, 181288, 571, 0, 0, 1, 1, 2454.19, -4910.31, 263.893, 1.66082, 0, 0, 0.738208, 0.674573, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+63, 181288, 571, 0, 0, 1, 1, 2579.72, -4325.59, 276.934, 5.77529, 0, 0, 0.251227, -0.967928, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+64, 181288, 571, 0, 0, 1, 1, 3368.48, -2135.25, 124.53, 0.20224, 0, 0, 0.100948, 0.994892, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+65, 181288, 571, 0, 0, 1, 1, 3403.4, -2896.41, 201.988, 2.32303, 0, 0, 0.917407, 0.39795, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+66, 181288, 571, 0, 0, 1, 1, 3773.85, 1464.02, 92.4174, 6.10863, 0, 0, 0.0871668, -0.996194, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+67, 181288, 571, 0, 0, 1, 1, 3936.15, -583.456, 240.5, 4.0611, 0, 0, 0.896162, -0.443727, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+68, 181288, 571, 0, 0, 1, 1, 4122.37, 5390.27, 27.8408, 5.32484, 0, 0, 0.461045, -0.887377, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+69, 181288, 571, 0, 0, 1, 1, 4441.05, 5627.71, 56.3487, 4.54665, 0, 0, 0.763211, -0.64615, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+70, 181288, 571, 0, 0, 1, 1, 5144.94, -695.736, 171.284, 5.22017, 0, 0, 0.506834, -0.862044, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+71, 181288, 571, 0, 0, 1, 1, 5294.92, -2761.88, 292.419, 2.12359, 0, 0, 0.873232, 0.487305, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+72, 181288, 571, 0, 0, 1, 1, 5369.18, 4842.41, -197.357, 4.53948, 0, 0, 0.765522, -0.643409, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+73, 181288, 571, 0, 0, 1, 1, 5499.12, 4869.82, -197.467, 5.88414, 0, 0, 0.198201, -0.980161, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+74, 181288, 571, 0, 0, 1, 1, 5530.53, -726.151, 148.904, 5.3977, 0, 0, 0.428419, -0.90358, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+75, 181288, 571, 0, 0, 1, 1, 5626.92, -2622.29, 292.417, 1.6785, 0, 0, 0.744142, 0.668021, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+76, 181288, 571, 0, 0, 1, 1, 6081.58, -1107.81, 419.498, 5.2117, 0, 0, 0.51048, -0.85989, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+77, 181288, 571, 0, 0, 1, 1, 6142.19, -1020.44, 408.496, 1.91604, 0, 0, 0.818054, 0.575141, 300, 0, 1, '', 0);
|
||||||
|
|
||||||
|
DELETE FROM `game_event_gameobject` WHERE `eventEntry` = 1 AND `guid` BETWEEN @OGUID AND @OGUID+77;
|
||||||
|
INSERT INTO `game_event_gameobject` (`eventEntry`, `guid`) VALUES
|
||||||
|
(1, @OGUID+0 ),
|
||||||
|
(1, @OGUID+1 ),
|
||||||
|
(1, @OGUID+2 ),
|
||||||
|
(1, @OGUID+3 ),
|
||||||
|
(1, @OGUID+4 ),
|
||||||
|
(1, @OGUID+5 ),
|
||||||
|
(1, @OGUID+6 ),
|
||||||
|
(1, @OGUID+7 ),
|
||||||
|
(1, @OGUID+8 ),
|
||||||
|
(1, @OGUID+9 ),
|
||||||
|
(1, @OGUID+10),
|
||||||
|
(1, @OGUID+11),
|
||||||
|
(1, @OGUID+12),
|
||||||
|
(1, @OGUID+13),
|
||||||
|
(1, @OGUID+14),
|
||||||
|
(1, @OGUID+15),
|
||||||
|
(1, @OGUID+16),
|
||||||
|
(1, @OGUID+17),
|
||||||
|
(1, @OGUID+18),
|
||||||
|
(1, @OGUID+19),
|
||||||
|
(1, @OGUID+20),
|
||||||
|
(1, @OGUID+21),
|
||||||
|
(1, @OGUID+22),
|
||||||
|
(1, @OGUID+23),
|
||||||
|
(1, @OGUID+24),
|
||||||
|
(1, @OGUID+25),
|
||||||
|
(1, @OGUID+26),
|
||||||
|
(1, @OGUID+27),
|
||||||
|
(1, @OGUID+28),
|
||||||
|
(1, @OGUID+29),
|
||||||
|
(1, @OGUID+30),
|
||||||
|
(1, @OGUID+31),
|
||||||
|
(1, @OGUID+32),
|
||||||
|
(1, @OGUID+33),
|
||||||
|
(1, @OGUID+34),
|
||||||
|
(1, @OGUID+35),
|
||||||
|
(1, @OGUID+36),
|
||||||
|
(1, @OGUID+37),
|
||||||
|
(1, @OGUID+38),
|
||||||
|
(1, @OGUID+39),
|
||||||
|
(1, @OGUID+40),
|
||||||
|
(1, @OGUID+41),
|
||||||
|
(1, @OGUID+42),
|
||||||
|
(1, @OGUID+43),
|
||||||
|
(1, @OGUID+44),
|
||||||
|
(1, @OGUID+45),
|
||||||
|
(1, @OGUID+46),
|
||||||
|
(1, @OGUID+47),
|
||||||
|
(1, @OGUID+48),
|
||||||
|
(1, @OGUID+49),
|
||||||
|
(1, @OGUID+50),
|
||||||
|
(1, @OGUID+51),
|
||||||
|
(1, @OGUID+52),
|
||||||
|
(1, @OGUID+53),
|
||||||
|
(1, @OGUID+54),
|
||||||
|
(1, @OGUID+55),
|
||||||
|
(1, @OGUID+56),
|
||||||
|
(1, @OGUID+57),
|
||||||
|
(1, @OGUID+58),
|
||||||
|
(1, @OGUID+59),
|
||||||
|
(1, @OGUID+60),
|
||||||
|
(1, @OGUID+61),
|
||||||
|
(1, @OGUID+62),
|
||||||
|
(1, @OGUID+63),
|
||||||
|
(1, @OGUID+64),
|
||||||
|
(1, @OGUID+65),
|
||||||
|
(1, @OGUID+66),
|
||||||
|
(1, @OGUID+67),
|
||||||
|
(1, @OGUID+68),
|
||||||
|
(1, @OGUID+69),
|
||||||
|
(1, @OGUID+70),
|
||||||
|
(1, @OGUID+71),
|
||||||
|
(1, @OGUID+72),
|
||||||
|
(1, @OGUID+73),
|
||||||
|
(1, @OGUID+74),
|
||||||
|
(1, @OGUID+75),
|
||||||
|
(1, @OGUID+76),
|
||||||
|
(1, @OGUID+77);
|
||||||
|
|
||||||
|
SET @OGUID := 76300;
|
||||||
|
|
||||||
|
DELETE FROM `gameobject` WHERE `id` IN (SELECT `entry` FROM `gameobject_template` WHERE `name` IN ('Horde Bonfire', 'Alliance Bonfire')) /* AND `guid` BETWEEN @OGUID AND @OGUID+77 */;
|
||||||
|
INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`) VALUES
|
||||||
|
(@OGUID+0 , 187951, 0, 0, 0, 1, 1, -14376.7, 115.921, 1.4532, 2.11185, 0, 0, 0.870356, 0.492423, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+1 , 187944, 0, 0, 0, 1, 1, -14288.1, 61.8062, 0.68836, 1.37881, 0, 0, 0.636078, 0.771625, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+2 , 187920, 0, 0, 0, 1, 1, -10951.5, -3218.1, 41.3475, 1.91986, 0, 0, 0.819151, 0.573577, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+3 , 187926, 0, 0, 0, 1, 1, -10704.8, -1146.38, 24.7909, 2.09439, 0, 0, 0.866024, 0.500002, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+4 , 187564, 0, 0, 0, 1, 1, -10657.1, 1054.63, 32.6733, 2.47837, 0, 0, 0.945519, 0.325567, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+5 , 187969, 0, 0, 0, 1, 1, -10331.4, -3297.73, 21.9992, -2.89725, 0, 0, -0.992546, 0.121868, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+6 , 187934, 0, 0, 0, 1, 1, -9434.3, -2110.36, 65.8038, 0.349066, 0, 0, 0.173648, 0.984808, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+7 , 187928, 0, 0, 0, 1, 1, -9394.21, 37.5017, 59.882, 1.15192, 0, 0, 0.54464, 0.83867, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+8 , 187922, 0, 0, 0, 1, 1, -8245.62, -2623.9, 133.155, 4.04776, 0, 0, 0.899102, -0.43774, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+9 , 187956, 0, 0, 0, 1, 1, -7596.42, -2086.6, 125.17, -0.942478, 0, 0, -0.453991, 0.891006, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+10, 187954, 0, 0, 0, 1, 1, -6704.48, -2200.91, 248.609, 0.017453, 0, 0, 0.00872639, 0.999962, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+11, 187925, 0, 0, 0, 1, 1, -5404.93, -492.299, 395.597, -0.506145, 0, 0, -0.25038, 0.968148, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+12, 187932, 0, 0, 0, 1, 1, -5233.16, -2893.37, 337.286, -0.226893, 0, 0, -0.113203, 0.993572, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+13, 187940, 0, 0, 0, 1, 1, -3448.2, -938.102, 10.6583, 0.034907, 0, 0, 0.0174526, 0.999848, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+14, 187914, 0, 0, 0, 1, 1, -1211.6, -2676.88, 45.3612, -0.645772, 0, 0, -0.317305, 0.948324, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+15, 187947, 0, 0, 0, 1, 1, -1134.84, -3531.81, 51.0719, -0.820305, 0, 0, -0.398749, 0.91706, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+16, 187931, 0, 0, 0, 1, 1, -604.148, -545.813, 36.579, 0.698132, 0, 0, 0.34202, 0.939693, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+17, 187972, 0, 0, 0, 1, 1, -447.95, -4527.65, 8.59595, 1.53589, 0, 0, 0.694658, 0.71934, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+18, 187964, 0, 0, 0, 1, 1, -134.688, -802.767, 55.0147, -1.62316, 0, 0, -0.725376, 0.688353, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+19, 187938, 0, 0, 0, 1, 1, 188.243, -2132.53, 102.674, -1.37881, 0, 0, -0.636078, 0.771625, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+20, 187559, 0, 0, 0, 1, 1, 587.056, 1365.02, 90.4778, 2.6529, 0, 0, 0.970296, 0.241922, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+21, 187939, 0, 0, 0, 1, 1, 989.562, -1453.47, 61.0011, 4.9105, 0, 0, 0.633712, -0.773569, 120, 255, 1, '', 0),
|
||||||
|
(@OGUID+22, 187974, 0, 0, 0, 1, 1, 2279.25, 456.009, 33.867, 0.3665, 0, 0, 0.182226, 0.983257, 120, 0, 1, '', 0),
|
||||||
|
(@OGUID+23, 187945, 1, 0, 0, 1, 1, -7216.68, -3859.39, 11.4943, -2.72271, 0, 0, -0.978147, 0.207914, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+24, 187952, 1, 0, 0, 1, 1, -7122.51, -3657.11, 8.82202, -1.74533, 0, 0, -0.766045, 0.642787, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+25, 187950, 1, 0, 0, 1, 1, -7000.75, 918.851, 8.93831, -2.23402, 0, 0, -0.898794, 0.438372, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+26, 187943, 1, 0, 0, 1, 1, -6771.96, 527.151, -1.40004, 3.1949, 0, 0, 0.999645, -0.0266505, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+27, 187973, 1, 0, 0, 1, 1, -5513.93, -2299.73, -58.0752, 2.44346, 0, 0, 0.939692, 0.342021, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+28, 187961, 1, 0, 0, 1, 1, -4573.22, 407.388, 41.5461, 2.46091, 0, 0, 0.942641, 0.333809, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+29, 187929, 1, 0, 0, 1, 1, -4412.02, 3480.24, 12.6312, 6.12709, 0, 0, 0.0779684, -0.996956, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+30, 187927, 1, 0, 0, 1, 1, -3447.55, -4231.67, 10.6645, 0.802851, 0, 0, 0.390731, 0.920505, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+31, 187959, 1, 0, 0, 1, 1, -3110.59, -2722.41, 33.4626, 0.226893, 0, 0, 0.113203, 0.993572, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+32, 187965, 1, 0, 0, 1, 1, -2329.42, -624.806, -8.27507, 5.5, 0, 0, 0.381661, -0.924302, 0, 100, 1, '', 0),
|
||||||
|
(@OGUID+33, 187957, 1, 0, 0, 1, 1, -1862.36, 3055.71, 0.744157, 2.49582, 0, 0, 0.948324, 0.317305, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+34, 187971, 1, 0, 0, 1, 1, -273.242, -2662.82, 91.695, -1.8675, 0, 0, -0.803856, 0.594824, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+35, 187924, 1, 0, 0, 1, 1, -55.5039, 1271.35, 91.9489, 1.5708, 0, 0, 0.707108, 0.707106, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+36, 187958, 1, 0, 0, 1, 1, 145.521, -4713.82, 18.129, -2.53, 0, 0, -0.953607, 0.301053, 120, 0, 1, '', 0),
|
||||||
|
(@OGUID+37, 187968, 1, 0, 0, 1, 1, 952.992, 776.968, 104.474, -1.55334, 0, 0, -0.700908, 0.713252, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+38, 187948, 1, 0, 0, 1, 1, 2014.65, -2337.84, 89.5211, 2.37365, 0, 0, 0.927184, 0.374606, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+39, 187916, 1, 0, 0, 1, 1, 2558.73, -481.666, 109.821, -2.47837, 0, 0, -0.945519, 0.325567, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+40, 187923, 1, 0, 0, 1, 1, 6327.68, 512.61, 17.4723, 0.034907, 0, 0, 0.0174526, 0.999848, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+41, 187953, 1, 0, 0, 1, 1, 6855.99, -4564.4, 708.51, 0.855211, 0, 0, 0.414693, 0.909961, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+42, 187946, 1, 0, 0, 1, 1, 6860.03, -4767.11, 696.833, -2.63545, 0, 0, -0.968148, 0.250379, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+43, 187936, 1, 0, 0, 1, 1, 9778.64, 1019.38, 1299.79, 0.261799, 0, 0, 0.130526, 0.991445, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+44, 187917, 530, 0, 0, 1, 1, -4223.84, -12318.4, 2.47695, 2.93214, 0, 0, 0.994521, 0.104535, 120, 255, 1, '', 0),
|
||||||
|
(@OGUID+45, 187935, 530, 0, 0, 1, 1, -3941.98, 2048.49, 95.0656, 4.87742, 0, 0, 0.64642, -0.762982, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+46, 187967, 530, 0, 0, 1, 1, -3059.17, 2374.85, 63.1011, 2.03334, 0, 0, 0.850361, 0.526201, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+47, 187937, 530, 0, 0, 1, 1, -3004.07, 4152.48, 3.64988, 1.75455, 0, 0, 0.769, 0.639249, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+48, 187970, 530, 0, 0, 1, 1, -2553.32, 4277.61, 20.614, -1.36136, 0, 0, -0.629322, 0.777145, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+49, 187933, 530, 0, 0, 1, 1, -2526.69, 7548.83, -2.23534, 5.32817, 0, 0, 0.459567, -0.888143, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+50, 187921, 530, 0, 0, 1, 1, -2254.78, -11896.3, 27.4979, 5.24028, 0, 0, 0.49814, -0.867096, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+51, 187966, 530, 0, 0, 1, 1, -1211.01, 7474.44, 21.9953, -2.02458, 0, 0, -0.848048, 0.52992, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+52, 187930, 530, 0, 0, 1, 1, -528.509, 2339.11, 38.7252, 2.14675, 0, 0, 0.878816, 0.477161, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+53, 187963, 530, 0, 0, 1, 1, 41.2448, 2587.44, 68.3453, -2.28638, 0, 0, -0.909961, 0.414694, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+54, 187941, 530, 0, 0, 1, 1, 192.209, 6015.13, 22.1067, 0.00709009, 0, 0, 0.00354504, 0.999994, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+55, 187975, 530, 0, 0, 1, 1, 200.9, 7686.96, 22.508, -0.506145, 0, 0, -0.25038, 0.968148, 180, 100, 1, '', 0),
|
||||||
|
(@OGUID+56, 187919, 530, 0, 0, 1, 1, 2019.7, 6587.14, 134.985, 6.23705, 0, 0, 0.0230656, -0.999734, 120, 255, 1, '', 0),
|
||||||
|
(@OGUID+57, 187955, 530, 0, 0, 1, 1, 2282.43, 6134.5, 136.337, 6.01364, 0, 0, 0.134365, -0.990932, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+58, 187949, 530, 0, 0, 1, 1, 2922.17, 3690.15, 143.809, 5.94709, 0, 0, 0.167258, -0.985913, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+59, 187942, 530, 0, 0, 1, 1, 3121.5, 3753.88, 141.851, 5.85856, 0, 0, 0.210721, -0.977546, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+60, 187962, 530, 0, 0, 1, 1, 7693.53, -6836.51, 77.787, 2.7052, 0, 0, 0.976289, 0.216469, 120, 0, 1, '', 0),
|
||||||
|
(@OGUID+61, 187960, 530, 0, 0, 1, 1, 9386.86, -6772.24, 14.412, -2.9146, 0, 0, -0.993566, 0.113253, 120, 0, 1, '', 0),
|
||||||
|
(@OGUID+62, 194038, 571, 0, 0, 1, 1, 2454.19, -4910.31, 263.893, 1.66082, 0, 0, 0.738208, 0.674573, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+63, 194039, 571, 0, 0, 1, 1, 2579.72, -4325.59, 276.934, 5.77529, 0, 0, 0.251227, -0.967928, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+64, 194042, 571, 0, 0, 1, 1, 3368.48, -2135.25, 124.53, 0.20224, 0, 0, 0.100948, 0.994892, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+65, 194040, 571, 0, 0, 1, 1, 3403.4, -2896.41, 201.988, 2.32303, 0, 0, 0.917407, 0.39795, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+66, 194037, 571, 0, 0, 1, 1, 3773.85, 1464.02, 92.4174, 6.10863, 0, 0, 0.0871668, -0.996194, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+67, 194036, 571, 0, 0, 1, 1, 3936.15, -583.456, 240.5, 4.0611, 0, 0, 0.896162, -0.443727, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+68, 194032, 571, 0, 0, 1, 1, 4122.37, 5390.27, 27.8408, 5.32484, 0, 0, 0.461045, -0.887377, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+69, 194033, 571, 0, 0, 1, 1, 4441.05, 5627.71, 56.3487, 4.54665, 0, 0, 0.763211, -0.64615, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+70, 194045, 571, 0, 0, 1, 1, 5144.94, -695.736, 171.284, 5.22017, 0, 0, 0.506834, -0.862044, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+71, 194048, 571, 0, 0, 1, 1, 5294.92, -2761.88, 292.419, 2.12359, 0, 0, 0.873232, 0.487305, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+72, 194035, 571, 0, 0, 1, 1, 5369.18, 4842.41, -197.357, 4.53948, 0, 0, 0.765522, -0.643409, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+73, 194034, 571, 0, 0, 1, 1, 5499.12, 4869.82, -197.467, 5.88414, 0, 0, 0.198201, -0.980161, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+74, 194046, 571, 0, 0, 1, 1, 5530.53, -726.151, 148.904, 5.3977, 0, 0, 0.428419, -0.90358, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+75, 194049, 571, 0, 0, 1, 1, 5626.92, -2622.29, 292.417, 1.6785, 0, 0, 0.744142, 0.668021, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+76, 194044, 571, 0, 0, 1, 1, 6081.58, -1107.81, 419.498, 5.2117, 0, 0, 0.51048, -0.85989, 300, 0, 1, '', 0),
|
||||||
|
(@OGUID+77, 194043, 571, 0, 0, 1, 1, 6142.19, -1020.44, 408.496, 1.91604, 0, 0, 0.818054, 0.575141, 300, 0, 1, '', 0);
|
||||||
|
|
||||||
|
DELETE FROM `game_event_gameobject` WHERE `eventEntry` = 1 AND `guid` BETWEEN @OGUID AND @OGUID+77;
|
||||||
|
INSERT INTO `game_event_gameobject` (`eventEntry`, `guid`) VALUES
|
||||||
|
(1, @OGUID+0 ),
|
||||||
|
(1, @OGUID+1 ),
|
||||||
|
(1, @OGUID+2 ),
|
||||||
|
(1, @OGUID+3 ),
|
||||||
|
(1, @OGUID+4 ),
|
||||||
|
(1, @OGUID+5 ),
|
||||||
|
(1, @OGUID+6 ),
|
||||||
|
(1, @OGUID+7 ),
|
||||||
|
(1, @OGUID+8 ),
|
||||||
|
(1, @OGUID+9 ),
|
||||||
|
(1, @OGUID+10),
|
||||||
|
(1, @OGUID+11),
|
||||||
|
(1, @OGUID+12),
|
||||||
|
(1, @OGUID+13),
|
||||||
|
(1, @OGUID+14),
|
||||||
|
(1, @OGUID+15),
|
||||||
|
(1, @OGUID+16),
|
||||||
|
(1, @OGUID+17),
|
||||||
|
(1, @OGUID+18),
|
||||||
|
(1, @OGUID+19),
|
||||||
|
(1, @OGUID+20),
|
||||||
|
(1, @OGUID+21),
|
||||||
|
(1, @OGUID+22),
|
||||||
|
(1, @OGUID+23),
|
||||||
|
(1, @OGUID+24),
|
||||||
|
(1, @OGUID+25),
|
||||||
|
(1, @OGUID+26),
|
||||||
|
(1, @OGUID+27),
|
||||||
|
(1, @OGUID+28),
|
||||||
|
(1, @OGUID+29),
|
||||||
|
(1, @OGUID+30),
|
||||||
|
(1, @OGUID+31),
|
||||||
|
(1, @OGUID+32),
|
||||||
|
(1, @OGUID+33),
|
||||||
|
(1, @OGUID+34),
|
||||||
|
(1, @OGUID+35),
|
||||||
|
(1, @OGUID+36),
|
||||||
|
(1, @OGUID+37),
|
||||||
|
(1, @OGUID+38),
|
||||||
|
(1, @OGUID+39),
|
||||||
|
(1, @OGUID+40),
|
||||||
|
(1, @OGUID+41),
|
||||||
|
(1, @OGUID+42),
|
||||||
|
(1, @OGUID+43),
|
||||||
|
(1, @OGUID+44),
|
||||||
|
(1, @OGUID+45),
|
||||||
|
(1, @OGUID+46),
|
||||||
|
(1, @OGUID+47),
|
||||||
|
(1, @OGUID+48),
|
||||||
|
(1, @OGUID+49),
|
||||||
|
(1, @OGUID+50),
|
||||||
|
(1, @OGUID+51),
|
||||||
|
(1, @OGUID+52),
|
||||||
|
(1, @OGUID+53),
|
||||||
|
(1, @OGUID+54),
|
||||||
|
(1, @OGUID+55),
|
||||||
|
(1, @OGUID+56),
|
||||||
|
(1, @OGUID+57),
|
||||||
|
(1, @OGUID+58),
|
||||||
|
(1, @OGUID+59),
|
||||||
|
(1, @OGUID+60),
|
||||||
|
(1, @OGUID+61),
|
||||||
|
(1, @OGUID+62),
|
||||||
|
(1, @OGUID+63),
|
||||||
|
(1, @OGUID+64),
|
||||||
|
(1, @OGUID+65),
|
||||||
|
(1, @OGUID+66),
|
||||||
|
(1, @OGUID+67),
|
||||||
|
(1, @OGUID+68),
|
||||||
|
(1, @OGUID+69),
|
||||||
|
(1, @OGUID+70),
|
||||||
|
(1, @OGUID+71),
|
||||||
|
(1, @OGUID+72),
|
||||||
|
(1, @OGUID+73),
|
||||||
|
(1, @OGUID+74),
|
||||||
|
(1, @OGUID+75),
|
||||||
|
(1, @OGUID+76),
|
||||||
|
(1, @OGUID+77);
|
||||||
|
|
||||||
|
DELETE FROM `game_event_gameobject` WHERE `eventEntry` = 1 AND `guid` BETWEEN 242500 AND 242577;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- DB update 2023_06_26_01 -> 2023_06_27_00
|
||||||
|
-- 31994 - Shoulder Charge
|
||||||
|
DELETE FROM `spell_custom_attr` WHERE `spell_id` = 31994;
|
||||||
|
INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES (31994, 16384);
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- DB update 2023_06_27_00 -> 2023_06_29_00
|
||||||
|
DELETE FROM `quest_offer_reward_locale` WHERE `ID`=1045 AND `locale`='ruRU';
|
||||||
|
INSERT INTO `quest_offer_reward_locale` (`ID`, `locale`, `RewardText`, `VerifiedBuild`) VALUES
|
||||||
|
(1045, 'ruRU', 'Славная работа, $N. Спасибо тебе.', 18019);
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- DB update 2023_06_29_00 -> 2023_06_29_01
|
||||||
|
--
|
||||||
|
UPDATE `creature_template` SET `flags_extra` = `flags_extra`|128 WHERE `entry`=22021;
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
-- DB update 2023_06_29_01 -> 2023_06_29_02
|
||||||
|
-- Fix SAI Yenniku --
|
||||||
|
DELETE FROM `creature_text` WHERE (`CreatureID` = 2530 AND `GroupID` = 0);
|
||||||
|
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
|
||||||
|
(2530, 0, 0, '%s is struck dumb by the Soul Gem!', 16, 0, 100, 0, 0, 0, 681, 0, 'Yenniku');
|
||||||
|
|
||||||
|
UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE (`entry` = 2530);
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 2530);
|
||||||
|
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`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(2530, 0, 0, 1, 8, 0, 100, 0, 3607, 0, 30000, 30000, 0, 2, 35, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Yenniku - On Spellhit \'Yenniku`s Release\' - Set Faction 35'),
|
||||||
|
(2530, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 80, 253000, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Yenniku - On Spellhit \'Yenniku`s Release\' - Run Script'),
|
||||||
|
(2530, 0, 2, 0, 20, 0, 100, 0, 593, 0, 0, 0, 0, 80, 253001, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Yenniku - On Quest \'Filling the Soul Gem\' Finished - Run Script');
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` IN (253000, 253001));
|
||||||
|
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`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(253000, 9, 0, 0, 0, 0, 100, 0, 100, 100, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 18, 6, 0, 0, 0, 0, 0, 0, 0, 'Yenniku - Actionlist - Set Orientation Closest Player'),
|
||||||
|
(253000, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Yenniku - Actionlist - Say Line 0'),
|
||||||
|
(253000, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 75, 18970, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Yenniku - Actionlist - Add Aura \'Self Stun - (Visual only)\''),
|
||||||
|
(253000, 9, 3, 0, 0, 0, 100, 0, 60000, 60000, 0, 0, 0, 28, 18970, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Yenniku - Actionlist - Remove Aura \'Self Stun - (Visual only)\''),
|
||||||
|
(253000, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 2, 28, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Yenniku - Actionlist - Set Faction 28'),
|
||||||
|
(253001, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 2, 28, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Yenniku - Actionlist - Set Faction 28'),
|
||||||
|
(253001, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 28, 18970, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Yenniku - Actionlist - Remove Aura \'Self Stun - (Visual only)\'');
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
-- DB update 2023_06_29_02 -> 2023_06_30_00
|
||||||
|
--
|
||||||
|
UPDATE `creature_loot_template` SET `Chance` = 0, `GroupId` = 1 WHERE (`Entry` = 20303);
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 18478);
|
||||||
|
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`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(18478, 0, 0, 0, 0, 0, 100, 0, 8500, 16800, 10900, 24100, 0, 11, 16856, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Avatar of the Martyred - In Combat - Cast \'Mortal Strike\''),
|
||||||
|
(18478, 0, 1, 0, 0, 0, 100, 0, 6500, 11500, 6200, 15700, 0, 11, 16145, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Avatar of the Martyred - In Combat - Cast \'Sunder Armor\''),
|
||||||
|
(18478, 0, 2, 0, 1, 0, 100, 512, 30000, 30000, 30000, 30000, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Avatar of the Martyred - Out of Combat - Despawn After 30s'),
|
||||||
|
(18478, 0, 3, 4, 54, 0, 100, 0, 0, 0, 0, 0, 0, 11, 33422, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Avatar of the Martyred - On Just Summoned - Cast \'Phase In\''),
|
||||||
|
(18478, 0, 4, 5, 61, 0, 100, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Avatar of the Martyred - On Just Summoned - Set In Combat With Zone'),
|
||||||
|
(18478, 0, 5, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 116, 900, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Avatar of the Martyred - On Just Summoned - Set Corpse Delay to 15 Minutes');
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- DB update 2023_06_30_00 -> 2023_07_02_00
|
||||||
|
--
|
||||||
|
UPDATE `smart_scripts` SET `event_param5`=5000 WHERE `entryorguid` = 16420 AND `source_type` = 0 AND `id`=0;
|
||||||
|
UPDATE `smart_scripts` SET `event_param5`=1000 WHERE `entryorguid` = 30085 AND `source_type` = 0 AND `id` = 1;
|
||||||
@@ -113,7 +113,6 @@ bool LoadRealmInfo(Acore::Asio::IoContext& ioContext);
|
|||||||
AsyncAcceptor* StartRaSocketAcceptor(Acore::Asio::IoContext& ioContext);
|
AsyncAcceptor* StartRaSocketAcceptor(Acore::Asio::IoContext& ioContext);
|
||||||
void ShutdownCLIThread(std::thread* cliThread);
|
void ShutdownCLIThread(std::thread* cliThread);
|
||||||
void AuctionListingRunnable();
|
void AuctionListingRunnable();
|
||||||
void ShutdownAuctionListingThread(std::thread* thread);
|
|
||||||
void WorldUpdateLoop();
|
void WorldUpdateLoop();
|
||||||
variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, [[maybe_unused]] std::string& cfg_service);
|
variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, [[maybe_unused]] std::string& cfg_service);
|
||||||
|
|
||||||
@@ -399,9 +398,9 @@ int main(int argc, char** argv)
|
|||||||
cliThread.reset(new std::thread(CliThread), &ShutdownCLIThread);
|
cliThread.reset(new std::thread(CliThread), &ShutdownCLIThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Launch CliRunnable thread
|
// Launch auction listing thread
|
||||||
std::shared_ptr<std::thread> auctionLisingThread;
|
std::shared_ptr<std::thread> auctionListingThread;
|
||||||
auctionLisingThread.reset(new std::thread(AuctionListingRunnable),
|
auctionListingThread.reset(new std::thread(AuctionListingRunnable),
|
||||||
[](std::thread* thr)
|
[](std::thread* thr)
|
||||||
{
|
{
|
||||||
thr->join();
|
thr->join();
|
||||||
@@ -729,35 +728,35 @@ void AuctionListingRunnable()
|
|||||||
|
|
||||||
while (!World::IsStopped())
|
while (!World::IsStopped())
|
||||||
{
|
{
|
||||||
if (AsyncAuctionListingMgr::IsAuctionListingAllowed())
|
Milliseconds diff = AsyncAuctionListingMgr::GetDiff();
|
||||||
{
|
|
||||||
uint32 diff = AsyncAuctionListingMgr::GetDiff();
|
|
||||||
AsyncAuctionListingMgr::ResetDiff();
|
AsyncAuctionListingMgr::ResetDiff();
|
||||||
|
|
||||||
if (AsyncAuctionListingMgr::GetTempList().size() || AsyncAuctionListingMgr::GetList().size())
|
if (!AsyncAuctionListingMgr::GetTempList().empty() || !AsyncAuctionListingMgr::GetList().empty())
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(AsyncAuctionListingMgr::GetLock());
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(AsyncAuctionListingMgr::GetTempLock());
|
std::lock_guard<std::mutex> guard(AsyncAuctionListingMgr::GetTempLock());
|
||||||
|
|
||||||
for (auto const& delayEvent : AsyncAuctionListingMgr::GetTempList())
|
for (auto const& delayEvent: AsyncAuctionListingMgr::GetTempList())
|
||||||
AsyncAuctionListingMgr::GetList().emplace_back(delayEvent);
|
AsyncAuctionListingMgr::GetList().emplace_back(delayEvent);
|
||||||
|
|
||||||
AsyncAuctionListingMgr::GetTempList().clear();
|
AsyncAuctionListingMgr::GetTempList().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& itr : AsyncAuctionListingMgr::GetList())
|
for (auto& itr: AsyncAuctionListingMgr::GetList())
|
||||||
{
|
{
|
||||||
if (itr._msTimer <= diff)
|
if (itr._pickupTimer <= diff)
|
||||||
itr._msTimer = 0;
|
{
|
||||||
|
itr._pickupTimer = Milliseconds::zero();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
itr._msTimer -= diff;
|
{
|
||||||
|
itr._pickupTimer -= diff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::list<AuctionListItemsDelayEvent>::iterator itr = AsyncAuctionListingMgr::GetList().begin(); itr != AsyncAuctionListingMgr::GetList().end(); ++itr)
|
for (auto itr = AsyncAuctionListingMgr::GetList().begin(); itr != AsyncAuctionListingMgr::GetList().end(); ++itr)
|
||||||
{
|
{
|
||||||
if ((*itr)._msTimer != 0)
|
if ((*itr)._pickupTimer != Milliseconds::zero())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((*itr).Execute())
|
if ((*itr).Execute())
|
||||||
@@ -766,22 +765,12 @@ void AuctionListingRunnable()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
std::this_thread::sleep_for(1ms);
|
std::this_thread::sleep_for(1ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("server", "Auction House Listing thread exiting without problems.");
|
LOG_INFO("server", "Auction House Listing thread exiting without problems.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShutdownAuctionListingThread(std::thread* thread)
|
|
||||||
{
|
|
||||||
if (thread)
|
|
||||||
{
|
|
||||||
thread->join();
|
|
||||||
delete thread;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, [[maybe_unused]] std::string& configService)
|
variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, [[maybe_unused]] std::string& configService)
|
||||||
{
|
{
|
||||||
options_description all("Allowed options");
|
options_description all("Allowed options");
|
||||||
@@ -791,7 +780,7 @@ variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, [
|
|||||||
("dry-run,d", "Dry run")
|
("dry-run,d", "Dry run")
|
||||||
("config,c", value<fs::path>(&configFile)->default_value(fs::path(sConfigMgr->GetConfigPath() + std::string(_ACORE_CORE_CONFIG))), "use <arg> as configuration file");
|
("config,c", value<fs::path>(&configFile)->default_value(fs::path(sConfigMgr->GetConfigPath() + std::string(_ACORE_CORE_CONFIG))), "use <arg> as configuration file");
|
||||||
|
|
||||||
#if AC_PLATFORM == WARHEAD_PLATFORM_WINDOWS
|
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
|
||||||
options_description win("Windows platform specific options");
|
options_description win("Windows platform specific options");
|
||||||
win.add_options()
|
win.add_options()
|
||||||
("service,s", value<std::string>(&configService)->default_value(""), "Windows service options: [install | uninstall]");
|
("service,s", value<std::string>(&configService)->default_value(""), "Windows service options: [install | uninstall]");
|
||||||
|
|||||||
@@ -3843,6 +3843,13 @@ ChangeFaction.MaxMoney = 0
|
|||||||
|
|
||||||
Pet.RankMod.Health = 1
|
Pet.RankMod.Health = 1
|
||||||
|
|
||||||
|
#
|
||||||
|
# AuctionHouse.SearchTimeout
|
||||||
|
# Description: Time (in milliseconds) after which an auction house search is discarded.
|
||||||
|
# Default: 1000 - (1 second)
|
||||||
|
|
||||||
|
AuctionHouse.SearchTimeout = 1000
|
||||||
|
|
||||||
#
|
#
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
|
|
||||||
|
|||||||
@@ -988,7 +988,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
|||||||
if (!IsSmart())
|
if (!IsSmart())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (targets.empty())
|
if (e.target.type == SMART_TARGET_NONE || e.target.type == SMART_TARGET_SELF)
|
||||||
{
|
{
|
||||||
CAST_AI(SmartAI, me->AI())->StopFollow(false);
|
CAST_AI(SmartAI, me->AI())->StopFollow(false);
|
||||||
break;
|
break;
|
||||||
@@ -1644,6 +1644,15 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.action.orientation.turnAngle)
|
||||||
|
{
|
||||||
|
float turnOri = me->GetOrientation() + (static_cast<float>(e.action.orientation.turnAngle) * M_PI / 180.0f);
|
||||||
|
me->SetFacingTo(turnOri);
|
||||||
|
if (e.action.orientation.quickChange)
|
||||||
|
me->SetOrientation(turnOri);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (e.GetTargetType() == SMART_TARGET_SELF)
|
if (e.GetTargetType() == SMART_TARGET_SELF)
|
||||||
{
|
{
|
||||||
me->SetFacingTo((me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && me->GetTransGUID() ? me->GetTransportHomePosition() : me->GetHomePosition()).GetOrientation());
|
me->SetFacingTo((me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && me->GetTransGUID() ? me->GetTransportHomePosition() : me->GetHomePosition()).GetOrientation());
|
||||||
@@ -2824,6 +2833,48 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SMART_ACTION_SET_SCALE:
|
||||||
|
{
|
||||||
|
float scale = static_cast<float>(e.action.setScale.scale) / 100.0f;
|
||||||
|
|
||||||
|
for (WorldObject* target : targets)
|
||||||
|
{
|
||||||
|
if (IsUnit(target))
|
||||||
|
{
|
||||||
|
target->ToUnit()->SetObjectScale(scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SMART_ACTION_SUMMON_RADIAL:
|
||||||
|
{
|
||||||
|
if (!me)
|
||||||
|
break;
|
||||||
|
|
||||||
|
TempSummonType spawnType = (e.action.radialSummon.summonDuration > 0) ? TEMPSUMMON_TIMED_DESPAWN : TEMPSUMMON_CORPSE_DESPAWN;
|
||||||
|
|
||||||
|
float startAngle = me->GetOrientation() + (static_cast<float>(e.action.radialSummon.startAngle) * M_PI / 180.0f);
|
||||||
|
float stepAngle = static_cast<float>(e.action.radialSummon.stepAngle) * M_PI / 180.0f;
|
||||||
|
|
||||||
|
if (e.action.radialSummon.dist)
|
||||||
|
{
|
||||||
|
for (uint32 itr = 0; itr < e.action.radialSummon.repetitions; itr++)
|
||||||
|
{
|
||||||
|
Position summonPos = me->GetPosition();
|
||||||
|
summonPos.RelocatePolarOffset(itr * stepAngle, static_cast<float>(e.action.radialSummon.dist));
|
||||||
|
me->SummonCreature(e.action.radialSummon.summonEntry, summonPos, spawnType, e.action.radialSummon.summonDuration);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32 itr = 0; itr < e.action.radialSummon.repetitions; itr++)
|
||||||
|
{
|
||||||
|
float currentAngle = startAngle + (itr * stepAngle);
|
||||||
|
me->SummonCreature(e.action.radialSummon.summonEntry, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), currentAngle, spawnType, e.action.radialSummon.summonDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry {} SourceType {}, Event {}, Unhandled Action type {}", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry {} SourceType {}, Event {}, Unhandled Action type {}", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
||||||
break;
|
break;
|
||||||
@@ -4157,34 +4208,105 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
|||||||
break;
|
break;
|
||||||
case SMART_EVENT_NEAR_PLAYERS:
|
case SMART_EVENT_NEAR_PLAYERS:
|
||||||
{
|
{
|
||||||
ObjectVector units;
|
uint32 playerCount = 0;
|
||||||
GetWorldObjectsInDist(units, static_cast<float>(e.event.nearPlayer.radius));
|
ObjectVector targets;
|
||||||
|
GetWorldObjectsInDist(targets, static_cast<float>(e.event.nearPlayer.radius));
|
||||||
|
|
||||||
if (!units.empty())
|
if (!targets.empty())
|
||||||
{
|
{
|
||||||
if (!unit || unit->GetTypeId() != TYPEID_PLAYER)
|
for (WorldObject* target : targets)
|
||||||
return;
|
{
|
||||||
|
if (IsPlayer(target))
|
||||||
|
playerCount++;
|
||||||
|
|
||||||
if (units.size() >= e.event.nearPlayer.minCount)
|
if (playerCount >= e.event.nearPlayer.minCount)
|
||||||
ProcessAction(e, unit);
|
ProcessAction(e, target->ToUnit());
|
||||||
}
|
}
|
||||||
RecalcTimer(e, e.event.nearPlayer.checkTimer, e.event.nearPlayer.checkTimer);
|
}
|
||||||
|
RecalcTimer(e, e.event.nearPlayer.repeatMin, e.event.nearPlayer.repeatMax);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SMART_EVENT_NEAR_PLAYERS_NEGATION:
|
case SMART_EVENT_NEAR_PLAYERS_NEGATION:
|
||||||
{
|
{
|
||||||
ObjectVector units;
|
uint32 playerCount = 0;
|
||||||
GetWorldObjectsInDist(units, static_cast<float>(e.event.nearPlayerNegation.radius));
|
ObjectVector targets;
|
||||||
|
GetWorldObjectsInDist(targets, static_cast<float>(e.event.nearPlayerNegation.radius));
|
||||||
|
|
||||||
if (!units.empty())
|
if (!targets.empty())
|
||||||
{
|
{
|
||||||
if (!unit || unit->GetTypeId() != TYPEID_PLAYER)
|
for (WorldObject* target : targets)
|
||||||
return;
|
{
|
||||||
|
if (IsPlayer(target))
|
||||||
|
playerCount++;
|
||||||
|
}
|
||||||
|
|
||||||
if (units.size() < e.event.nearPlayerNegation.minCount)
|
if (playerCount <= e.event.nearPlayerNegation.maxCount)
|
||||||
ProcessAction(e, unit);
|
ProcessAction(e, unit);
|
||||||
}
|
}
|
||||||
RecalcTimer(e, e.event.nearPlayerNegation.checkTimer, e.event.nearPlayerNegation.checkTimer);
|
RecalcTimer(e, e.event.nearPlayerNegation.repeatMin, e.event.nearPlayerNegation.repeatMax);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SMART_EVENT_NEAR_UNIT:
|
||||||
|
{
|
||||||
|
uint32 unitCount = 0;
|
||||||
|
ObjectVector targets;
|
||||||
|
GetWorldObjectsInDist(targets, static_cast<float>(e.event.nearUnit.range));
|
||||||
|
|
||||||
|
if (!targets.empty())
|
||||||
|
{
|
||||||
|
if (e.event.nearUnit.type)
|
||||||
|
{
|
||||||
|
for (WorldObject* target : targets)
|
||||||
|
{
|
||||||
|
if (IsGameObject(target) && target->GetEntry() == e.event.nearUnit.entry)
|
||||||
|
unitCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (WorldObject* target : targets)
|
||||||
|
{
|
||||||
|
if (IsCreature(target) && target->GetEntry() == e.event.nearUnit.entry)
|
||||||
|
unitCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unitCount >= e.event.nearUnit.count)
|
||||||
|
ProcessAction(e, unit);
|
||||||
|
}
|
||||||
|
RecalcTimer(e, e.event.nearUnit.timer, e.event.nearUnit.timer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SMART_EVENT_AREA_CASTING:
|
||||||
|
{
|
||||||
|
if (!me || !me->IsEngaged())
|
||||||
|
return;
|
||||||
|
|
||||||
|
float range = static_cast<float>(e.event.areaCasting.range);
|
||||||
|
ThreatContainer::StorageType threatList = me->GetThreatMgr().GetThreatList();
|
||||||
|
for (ThreatContainer::StorageType::const_iterator i = threatList.begin(); i != threatList.end(); ++i)
|
||||||
|
{
|
||||||
|
if (Unit* target = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()))
|
||||||
|
{
|
||||||
|
if (e.event.areaCasting.range && !me->IsWithinDistInMap(target, range))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!target || !target->IsNonMeleeSpellCast(false, false, true))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (e.event.areaCasting.spellId > 0)
|
||||||
|
if (Spell* currSpell = target->GetCurrentSpell(CURRENT_GENERIC_SPELL))
|
||||||
|
if (currSpell->m_spellInfo->Id != e.event.areaCasting.spellId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ProcessAction(e, target);
|
||||||
|
RecalcTimer(e, e.event.areaCasting.repeatMin, e.event.areaCasting.repeatMin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no targets are found and it's off cooldown, check again
|
||||||
|
RecalcTimer(e, e.event.areaCasting.checkTimer, e.event.areaCasting.checkTimer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -4223,6 +4345,12 @@ void SmartScript::InitTimer(SmartScriptHolder& e)
|
|||||||
case SMART_EVENT_DISTANCE_GAMEOBJECT:
|
case SMART_EVENT_DISTANCE_GAMEOBJECT:
|
||||||
RecalcTimer(e, e.event.distance.repeat, e.event.distance.repeat);
|
RecalcTimer(e, e.event.distance.repeat, e.event.distance.repeat);
|
||||||
break;
|
break;
|
||||||
|
case SMART_EVENT_NEAR_UNIT:
|
||||||
|
RecalcTimer(e, e.event.nearUnit.timer, e.event.nearUnit.timer);
|
||||||
|
break;
|
||||||
|
case SMART_EVENT_AREA_CASTING:
|
||||||
|
RecalcTimer(e, e.event.areaCasting.repeatMin, e.event.areaCasting.repeatMax);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
e.active = true;
|
e.active = true;
|
||||||
break;
|
break;
|
||||||
@@ -4276,6 +4404,7 @@ void SmartScript::UpdateTimer(SmartScriptHolder& e, uint32 const diff)
|
|||||||
{
|
{
|
||||||
case SMART_EVENT_NEAR_PLAYERS:
|
case SMART_EVENT_NEAR_PLAYERS:
|
||||||
case SMART_EVENT_NEAR_PLAYERS_NEGATION:
|
case SMART_EVENT_NEAR_PLAYERS_NEGATION:
|
||||||
|
case SMART_EVENT_NEAR_UNIT:
|
||||||
case SMART_EVENT_UPDATE:
|
case SMART_EVENT_UPDATE:
|
||||||
case SMART_EVENT_UPDATE_OOC:
|
case SMART_EVENT_UPDATE_OOC:
|
||||||
case SMART_EVENT_UPDATE_IC:
|
case SMART_EVENT_UPDATE_IC:
|
||||||
@@ -4285,6 +4414,7 @@ void SmartScript::UpdateTimer(SmartScriptHolder& e, uint32 const diff)
|
|||||||
case SMART_EVENT_TARGET_MANA_PCT:
|
case SMART_EVENT_TARGET_MANA_PCT:
|
||||||
case SMART_EVENT_RANGE:
|
case SMART_EVENT_RANGE:
|
||||||
case SMART_EVENT_VICTIM_CASTING:
|
case SMART_EVENT_VICTIM_CASTING:
|
||||||
|
case SMART_EVENT_AREA_CASTING:
|
||||||
case SMART_EVENT_FRIENDLY_HEALTH:
|
case SMART_EVENT_FRIENDLY_HEALTH:
|
||||||
case SMART_EVENT_FRIENDLY_IS_CC:
|
case SMART_EVENT_FRIENDLY_IS_CC:
|
||||||
case SMART_EVENT_FRIENDLY_MISSING_BUFF:
|
case SMART_EVENT_FRIENDLY_MISSING_BUFF:
|
||||||
|
|||||||
@@ -280,6 +280,10 @@ void SmartAIMgr::LoadSmartAIFromDB()
|
|||||||
if (temp.event.minMaxRepeat.min == 0 && temp.event.minMaxRepeat.max == 0)
|
if (temp.event.minMaxRepeat.min == 0 && temp.event.minMaxRepeat.max == 0)
|
||||||
temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE;
|
temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE;
|
||||||
break;
|
break;
|
||||||
|
case SMART_EVENT_AREA_CASTING:
|
||||||
|
if (temp.event.areaCasting.repeatMin == 0 && temp.event.areaCasting.repeatMax == 0)
|
||||||
|
temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE;
|
||||||
|
break;
|
||||||
case SMART_EVENT_FRIENDLY_IS_CC:
|
case SMART_EVENT_FRIENDLY_IS_CC:
|
||||||
if (temp.event.friendlyCC.repeatMin == 0 && temp.event.friendlyCC.repeatMax == 0)
|
if (temp.event.friendlyCC.repeatMin == 0 && temp.event.friendlyCC.repeatMax == 0)
|
||||||
temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE;
|
temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE;
|
||||||
@@ -346,10 +350,12 @@ void SmartAIMgr::LoadSmartAIFromDB()
|
|||||||
case SMART_EVENT_TARGET_MANA_PCT:
|
case SMART_EVENT_TARGET_MANA_PCT:
|
||||||
case SMART_EVENT_RANGE:
|
case SMART_EVENT_RANGE:
|
||||||
case SMART_EVENT_VICTIM_CASTING:
|
case SMART_EVENT_VICTIM_CASTING:
|
||||||
|
case SMART_EVENT_AREA_CASTING:
|
||||||
case SMART_EVENT_TARGET_BUFFED:
|
case SMART_EVENT_TARGET_BUFFED:
|
||||||
case SMART_EVENT_IS_BEHIND_TARGET:
|
case SMART_EVENT_IS_BEHIND_TARGET:
|
||||||
case SMART_EVENT_INSTANCE_PLAYER_ENTER:
|
case SMART_EVENT_INSTANCE_PLAYER_ENTER:
|
||||||
case SMART_EVENT_TRANSPORT_ADDCREATURE:
|
case SMART_EVENT_TRANSPORT_ADDCREATURE:
|
||||||
|
case SMART_EVENT_NEAR_PLAYERS:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@@ -572,6 +578,8 @@ bool SmartAIMgr::CheckUnusedEventParams(SmartScriptHolder const& e)
|
|||||||
case SMART_EVENT_SUMMONED_UNIT_DIES: return sizeof(SmartEvent::summoned);
|
case SMART_EVENT_SUMMONED_UNIT_DIES: return sizeof(SmartEvent::summoned);
|
||||||
case SMART_EVENT_NEAR_PLAYERS: return sizeof(SmartEvent::nearPlayer);
|
case SMART_EVENT_NEAR_PLAYERS: return sizeof(SmartEvent::nearPlayer);
|
||||||
case SMART_EVENT_NEAR_PLAYERS_NEGATION: return sizeof(SmartEvent::nearPlayerNegation);
|
case SMART_EVENT_NEAR_PLAYERS_NEGATION: return sizeof(SmartEvent::nearPlayerNegation);
|
||||||
|
case SMART_EVENT_NEAR_UNIT: return sizeof(SmartEvent::nearUnit);
|
||||||
|
case SMART_EVENT_AREA_CASTING: return sizeof(SmartEvent::areaCasting);
|
||||||
default:
|
default:
|
||||||
LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using an event {} with no unused params specified in SmartAIMgr::CheckUnusedEventParams(), please report this.",
|
LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using an event {} with no unused params specified in SmartAIMgr::CheckUnusedEventParams(), please report this.",
|
||||||
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetEventType());
|
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetEventType());
|
||||||
@@ -671,7 +679,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
|
|||||||
case SMART_ACTION_SET_COUNTER: return sizeof(SmartAction::setCounter);
|
case SMART_ACTION_SET_COUNTER: return sizeof(SmartAction::setCounter);
|
||||||
case SMART_ACTION_STORE_TARGET_LIST: return sizeof(SmartAction::storeTargets);
|
case SMART_ACTION_STORE_TARGET_LIST: return sizeof(SmartAction::storeTargets);
|
||||||
case SMART_ACTION_WP_RESUME: return NO_PARAMS;
|
case SMART_ACTION_WP_RESUME: return NO_PARAMS;
|
||||||
case SMART_ACTION_SET_ORIENTATION: return NO_PARAMS;
|
case SMART_ACTION_SET_ORIENTATION: return sizeof(SmartAction::orientation);
|
||||||
case SMART_ACTION_CREATE_TIMED_EVENT: return sizeof(SmartAction::timeEvent);
|
case SMART_ACTION_CREATE_TIMED_EVENT: return sizeof(SmartAction::timeEvent);
|
||||||
case SMART_ACTION_PLAYMOVIE: return sizeof(SmartAction::movie);
|
case SMART_ACTION_PLAYMOVIE: return sizeof(SmartAction::movie);
|
||||||
case SMART_ACTION_MOVE_TO_POS: return sizeof(SmartAction::moveToPos);
|
case SMART_ACTION_MOVE_TO_POS: return sizeof(SmartAction::moveToPos);
|
||||||
@@ -763,6 +771,8 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
|
|||||||
case SMART_ACTION_MUSIC: return sizeof(SmartAction::music);
|
case SMART_ACTION_MUSIC: return sizeof(SmartAction::music);
|
||||||
case SMART_ACTION_SET_GUID: return sizeof(SmartAction::setGuid);
|
case SMART_ACTION_SET_GUID: return sizeof(SmartAction::setGuid);
|
||||||
case SMART_ACTION_DISABLE: return sizeof(SmartAction::disable);
|
case SMART_ACTION_DISABLE: return sizeof(SmartAction::disable);
|
||||||
|
case SMART_ACTION_SET_SCALE: return sizeof(SmartAction::setScale);
|
||||||
|
case SMART_ACTION_SUMMON_RADIAL: return sizeof(SmartAction::radialSummon);
|
||||||
default:
|
default:
|
||||||
LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using an action with no unused params specified in SmartAIMgr::CheckUnusedActionParams(), please report this.",
|
LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using an action with no unused params specified in SmartAIMgr::CheckUnusedActionParams(), please report this.",
|
||||||
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
||||||
@@ -1041,6 +1051,16 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
|||||||
if (!IsMinMaxValid(e, e.event.targetCasting.repeatMin, e.event.targetCasting.repeatMax))
|
if (!IsMinMaxValid(e, e.event.targetCasting.repeatMin, e.event.targetCasting.repeatMax))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
case SMART_EVENT_AREA_CASTING:
|
||||||
|
if (e.event.areaCasting.spellId > 0 && !sSpellMgr->GetSpellInfo(e.event.areaCasting.spellId))
|
||||||
|
{
|
||||||
|
LOG_ERROR("scripts.ai.sai", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} uses non-existent Spell entry {}, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.spellHit.spell);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsMinMaxValid(e, e.event.areaCasting.repeatMin, e.event.areaCasting.repeatMax))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
case SMART_EVENT_PASSENGER_BOARDED:
|
case SMART_EVENT_PASSENGER_BOARDED:
|
||||||
case SMART_EVENT_PASSENGER_REMOVED:
|
case SMART_EVENT_PASSENGER_REMOVED:
|
||||||
if (!IsMinMaxValid(e, e.event.minMax.repeatMin, e.event.minMax.repeatMax))
|
if (!IsMinMaxValid(e, e.event.minMax.repeatMin, e.event.minMax.repeatMax))
|
||||||
@@ -1270,6 +1290,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
|||||||
case SMART_EVENT_GO_EVENT_INFORM:
|
case SMART_EVENT_GO_EVENT_INFORM:
|
||||||
case SMART_EVENT_NEAR_PLAYERS:
|
case SMART_EVENT_NEAR_PLAYERS:
|
||||||
case SMART_EVENT_NEAR_PLAYERS_NEGATION:
|
case SMART_EVENT_NEAR_PLAYERS_NEGATION:
|
||||||
|
if (!IsMinMaxValid(e, e.event.nearPlayer.repeatMin, e.event.nearPlayer.repeatMax))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case SMART_EVENT_NEAR_UNIT:
|
||||||
case SMART_EVENT_TIMED_EVENT_TRIGGERED:
|
case SMART_EVENT_TIMED_EVENT_TRIGGERED:
|
||||||
case SMART_EVENT_INSTANCE_PLAYER_ENTER:
|
case SMART_EVENT_INSTANCE_PLAYER_ENTER:
|
||||||
case SMART_EVENT_TRANSPORT_RELOCATE:
|
case SMART_EVENT_TRANSPORT_RELOCATE:
|
||||||
@@ -1920,6 +1944,8 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
|||||||
case SMART_ACTION_PLAY_CINEMATIC:
|
case SMART_ACTION_PLAY_CINEMATIC:
|
||||||
case SMART_ACTION_SET_GUID:
|
case SMART_ACTION_SET_GUID:
|
||||||
case SMART_ACTION_DISABLE:
|
case SMART_ACTION_DISABLE:
|
||||||
|
case SMART_ACTION_SET_SCALE:
|
||||||
|
case SMART_ACTION_SUMMON_RADIAL:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("sql.sql", "SmartAIMgr: Not handled action_type({}), event_type({}), Entry {} SourceType {} Event {}, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id);
|
LOG_ERROR("sql.sql", "SmartAIMgr: Not handled action_type({}), event_type({}), Entry {} SourceType {} Event {}, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id);
|
||||||
|
|||||||
@@ -206,10 +206,12 @@ enum SMART_EVENT
|
|||||||
/* AC Custom Events */
|
/* AC Custom Events */
|
||||||
SMART_EVENT_AC_START = 100,
|
SMART_EVENT_AC_START = 100,
|
||||||
|
|
||||||
SMART_EVENT_NEAR_PLAYERS = 101, // min, radius, first timer, check timer
|
SMART_EVENT_NEAR_PLAYERS = 101, // min, radius, first timer, repeatMin, repeatMax
|
||||||
SMART_EVENT_NEAR_PLAYERS_NEGATION = 102, // min, radius, first timer, check timer
|
SMART_EVENT_NEAR_PLAYERS_NEGATION = 102, // max, radius, first timer, repeatMin, repeatMax
|
||||||
|
SMART_EVENT_NEAR_UNIT = 103, // type (0: creature 1: gob), entry, count, range, timer
|
||||||
|
SMART_EVENT_AREA_CASTING = 104, // spellId (0: any), range (0: any), repeatMin, repeatMax, checkTimer
|
||||||
|
|
||||||
SMART_EVENT_AC_END = 103
|
SMART_EVENT_AC_END = 105
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SmartEvent
|
struct SmartEvent
|
||||||
@@ -482,17 +484,37 @@ struct SmartEvent
|
|||||||
uint32 minCount;
|
uint32 minCount;
|
||||||
uint32 radius;
|
uint32 radius;
|
||||||
uint32 firstTimer;
|
uint32 firstTimer;
|
||||||
uint32 checkTimer;
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
} nearPlayer;
|
} nearPlayer;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint32 minCount;
|
uint32 maxCount;
|
||||||
uint32 radius;
|
uint32 radius;
|
||||||
uint32 firstTimer;
|
uint32 firstTimer;
|
||||||
uint32 checkTimer;
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
} nearPlayerNegation;
|
} nearPlayerNegation;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 type;
|
||||||
|
uint32 entry;
|
||||||
|
uint32 count;
|
||||||
|
uint32 range;
|
||||||
|
uint32 timer;
|
||||||
|
} nearUnit;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 spellId;
|
||||||
|
uint32 range;
|
||||||
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
|
uint32 checkTimer;
|
||||||
|
} areaCasting;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint32 param1;
|
uint32 param1;
|
||||||
@@ -588,7 +610,7 @@ enum SMART_ACTION
|
|||||||
SMART_ACTION_SET_COUNTER = 63, // id, value, reset (0/1)
|
SMART_ACTION_SET_COUNTER = 63, // id, value, reset (0/1)
|
||||||
SMART_ACTION_STORE_TARGET_LIST = 64, // varID,
|
SMART_ACTION_STORE_TARGET_LIST = 64, // varID,
|
||||||
SMART_ACTION_WP_RESUME = 65, // none
|
SMART_ACTION_WP_RESUME = 65, // none
|
||||||
SMART_ACTION_SET_ORIENTATION = 66, // quick change, random orientation? (0/1)
|
SMART_ACTION_SET_ORIENTATION = 66, // quick change, random orientation? (0/1), turnAngle
|
||||||
SMART_ACTION_CREATE_TIMED_EVENT = 67, // id, InitialMin, InitialMax, RepeatMin(only if it repeats), RepeatMax(only if it repeats), chance
|
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_PLAYMOVIE = 68, // entry
|
||||||
SMART_ACTION_MOVE_TO_POS = 69, // PointId (optional x,y,z offset), transport, controlled, ContactDistance
|
SMART_ACTION_MOVE_TO_POS = 69, // PointId (optional x,y,z offset), transport, controlled, ContactDistance
|
||||||
@@ -693,9 +715,11 @@ enum SMART_ACTION
|
|||||||
SMART_ACTION_DO_ACTION = 223, // ActionId
|
SMART_ACTION_DO_ACTION = 223, // ActionId
|
||||||
SMART_ACTION_ATTACK_STOP = 224, //
|
SMART_ACTION_ATTACK_STOP = 224, //
|
||||||
SMART_ACTION_SET_GUID = 225, // Sends the invoker's or the base object's own ObjectGuid to target
|
SMART_ACTION_SET_GUID = 225, // Sends the invoker's or the base object's own ObjectGuid to target
|
||||||
SMART_ACTION_DISABLE = 226, // Disable the targeted creatures, setting them Invisible and Immune to All
|
SMART_ACTION_DISABLE = 226, // state
|
||||||
|
SMART_ACTION_SET_SCALE = 227, // scale
|
||||||
|
SMART_ACTION_SUMMON_RADIAL = 228, // summonEntry, summonDuration, repetitions, startAngle, stepAngle, dist
|
||||||
|
|
||||||
SMART_ACTION_AC_END = 227, // placeholder
|
SMART_ACTION_AC_END = 229, // placeholder
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SmartActionSummonCreatureFlags
|
enum class SmartActionSummonCreatureFlags
|
||||||
@@ -1289,6 +1313,7 @@ struct SmartAction
|
|||||||
{
|
{
|
||||||
uint32 quickChange;
|
uint32 quickChange;
|
||||||
uint32 random;
|
uint32 random;
|
||||||
|
uint32 turnAngle;
|
||||||
} orientation;
|
} orientation;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@@ -1376,6 +1401,21 @@ struct SmartAction
|
|||||||
{
|
{
|
||||||
SAIBool state;
|
SAIBool state;
|
||||||
} disable;
|
} disable;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 scale;
|
||||||
|
} setScale;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 summonEntry;
|
||||||
|
uint32 summonDuration;
|
||||||
|
uint32 repetitions;
|
||||||
|
uint32 startAngle;
|
||||||
|
uint32 stepAngle;
|
||||||
|
uint32 dist;
|
||||||
|
} radialSummon;
|
||||||
//! Note for any new future actions
|
//! Note for any new future actions
|
||||||
//! All parameters must have type uint32
|
//! All parameters must have type uint32
|
||||||
|
|
||||||
@@ -1777,8 +1817,10 @@ const uint32 SmartAIEventMask[SMART_EVENT_AC_END][2] =
|
|||||||
{ 0, 0 }, // 98
|
{ 0, 0 }, // 98
|
||||||
{ 0, 0 }, // 99
|
{ 0, 0 }, // 99
|
||||||
{ 0, 0 }, // 100
|
{ 0, 0 }, // 100
|
||||||
{SMART_EVENT_NEAR_PLAYERS, SMART_SCRIPT_TYPE_MASK_CREATURE },
|
{SMART_EVENT_NEAR_PLAYERS, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
|
||||||
{SMART_EVENT_NEAR_PLAYERS_NEGATION, SMART_SCRIPT_TYPE_MASK_CREATURE }
|
{SMART_EVENT_NEAR_PLAYERS_NEGATION, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
|
||||||
|
{SMART_EVENT_NEAR_UNIT, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
|
||||||
|
{SMART_EVENT_AREA_CASTING, SMART_SCRIPT_TYPE_MASK_CREATURE }
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SmartEventFlags
|
enum SmartEventFlags
|
||||||
|
|||||||
@@ -2394,6 +2394,11 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompletedAchievementMap const& AchievementMgr::GetCompletedAchievements()
|
||||||
|
{
|
||||||
|
return _completedAchievements;
|
||||||
|
}
|
||||||
|
|
||||||
AchievementGlobalMgr* AchievementGlobalMgr::instance()
|
AchievementGlobalMgr* AchievementGlobalMgr::instance()
|
||||||
{
|
{
|
||||||
static AchievementGlobalMgr instance;
|
static AchievementGlobalMgr instance;
|
||||||
|
|||||||
@@ -300,6 +300,7 @@ public:
|
|||||||
|
|
||||||
void RemoveCriteriaProgress(AchievementCriteriaEntry const* entry);
|
void RemoveCriteriaProgress(AchievementCriteriaEntry const* entry);
|
||||||
CriteriaProgress* GetCriteriaProgress(AchievementCriteriaEntry const* entry);
|
CriteriaProgress* GetCriteriaProgress(AchievementCriteriaEntry const* entry);
|
||||||
|
CompletedAchievementMap const& GetCompletedAchievements();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST, PROGRESS_RESET };
|
enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST, PROGRESS_RESET };
|
||||||
|
|||||||
@@ -727,7 +727,7 @@ void AuctionHouseObject::BuildListOwnerItems(WorldPacket& data, Player* player,
|
|||||||
bool AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player,
|
bool AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player,
|
||||||
std::wstring const& wsearchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable,
|
std::wstring const& wsearchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable,
|
||||||
uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality,
|
uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality,
|
||||||
uint32& count, uint32& totalcount, uint8 /*getAll*/, AuctionSortOrderVector const& sortOrder)
|
uint32& count, uint32& totalcount, uint8 /*getAll*/, AuctionSortOrderVector const& sortOrder, Milliseconds searchTimeout)
|
||||||
{
|
{
|
||||||
uint32 itrcounter = 0;
|
uint32 itrcounter = 0;
|
||||||
|
|
||||||
@@ -753,17 +753,14 @@ bool AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player
|
|||||||
int locdbc_idx = player->GetSession()->GetSessionDbcLocale();
|
int locdbc_idx = player->GetSession()->GetSessionDbcLocale();
|
||||||
|
|
||||||
for (AuctionEntryMap::const_iterator itr = _auctionsMap.begin(); itr != _auctionsMap.end(); ++itr)
|
for (AuctionEntryMap::const_iterator itr = _auctionsMap.begin(); itr != _auctionsMap.end(); ++itr)
|
||||||
{
|
|
||||||
if (!AsyncAuctionListingMgr::IsAuctionListingAllowed()) // pussywizard: World::Update is waiting for us...
|
|
||||||
{
|
{
|
||||||
if ((itrcounter++) % 100 == 0) // check condition every 100 iterations
|
if ((itrcounter++) % 100 == 0) // check condition every 100 iterations
|
||||||
{
|
{
|
||||||
if (sWorldUpdateTime.GetAverageUpdateTime() >= 30 || GetMSTimeDiff(GameTime::GetGameTimeMS(), GetTimeMS()) >= 10ms) // pussywizard: stop immediately if diff is high or waiting too long
|
if (GetMSTimeDiff(GameTime::GetGameTimeMS(), GetTimeMS()) >= searchTimeout) // pussywizard: stop immediately if diff is high or waiting too long
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
AuctionEntry* Aentry = itr->second;
|
AuctionEntry* Aentry = itr->second;
|
||||||
// Skip expired auctions
|
// Skip expired auctions
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ public:
|
|||||||
bool BuildListAuctionItems(WorldPacket& data, Player* player,
|
bool BuildListAuctionItems(WorldPacket& data, Player* player,
|
||||||
std::wstring const& searchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable,
|
std::wstring const& searchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable,
|
||||||
uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality,
|
uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality,
|
||||||
uint32& count, uint32& totalcount, uint8 getAll, AuctionSortOrderVector const& sortOrder);
|
uint32& count, uint32& totalcount, uint8 getAll, AuctionSortOrderVector const& sortOrder, Milliseconds searchTimeout);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AuctionEntryMap _auctionsMap;
|
AuctionEntryMap _auctionsMap;
|
||||||
@@ -184,7 +184,6 @@ public:
|
|||||||
|
|
||||||
AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId);
|
AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId);
|
||||||
AuctionHouseObject* GetAuctionsMapByHouseId(uint8 auctionHouseId);
|
AuctionHouseObject* GetAuctionsMapByHouseId(uint8 auctionHouseId);
|
||||||
AuctionHouseObject* GetBidsMap(uint32 factionTemplateId);
|
|
||||||
|
|
||||||
Item* GetAItem(ObjectGuid itemGuid)
|
Item* GetAItem(ObjectGuid itemGuid)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -174,11 +174,11 @@ void KillRewarder::_RewardXP(Player* player, float rate)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KillRewarder::_RewardReputation(Player* player, float rate)
|
void KillRewarder::_RewardReputation(Player* player)
|
||||||
{
|
{
|
||||||
// 4.3. Give reputation (player must not be on BG).
|
// 4.3. Give reputation (player must not be on BG).
|
||||||
// Even dead players and corpses are rewarded.
|
// Even dead players and corpses are rewarded.
|
||||||
player->RewardReputation(_victim, rate);
|
player->RewardReputation(_victim);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KillRewarder::_RewardKillCredit(Player* player)
|
void KillRewarder::_RewardKillCredit(Player* player)
|
||||||
@@ -208,7 +208,6 @@ void KillRewarder::_RewardPlayer(Player* player, bool isDungeon)
|
|||||||
if (!_isPvP || _isBattleGround)
|
if (!_isPvP || _isBattleGround)
|
||||||
{
|
{
|
||||||
float xpRate = _group ? _groupRate * float(player->GetLevel()) / _aliveSumLevel : /*Personal rate is 100%.*/ 1.0f; // Group rate depends on the sum of levels.
|
float xpRate = _group ? _groupRate * float(player->GetLevel()) / _aliveSumLevel : /*Personal rate is 100%.*/ 1.0f; // Group rate depends on the sum of levels.
|
||||||
float reputationRate = _group ? _groupRate * float(player->GetLevel()) / _sumLevel : /*Personal rate is 100%.*/ 1.0f; // Group rate depends on the sum of levels.
|
|
||||||
sScriptMgr->OnRewardKillRewarder(player, isDungeon, xpRate); // Personal rate is 100%.
|
sScriptMgr->OnRewardKillRewarder(player, isDungeon, xpRate); // Personal rate is 100%.
|
||||||
|
|
||||||
if (_xp)
|
if (_xp)
|
||||||
@@ -219,7 +218,7 @@ void KillRewarder::_RewardPlayer(Player* player, bool isDungeon)
|
|||||||
if (!_isBattleGround)
|
if (!_isBattleGround)
|
||||||
{
|
{
|
||||||
// If killer is in dungeon then all members receive full reputation at kill.
|
// If killer is in dungeon then all members receive full reputation at kill.
|
||||||
_RewardReputation(player, isDungeon ? 1.0f : reputationRate);
|
_RewardReputation(player);
|
||||||
_RewardKillCredit(player);
|
_RewardKillCredit(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ private:
|
|||||||
|
|
||||||
void _RewardHonor(Player* player);
|
void _RewardHonor(Player* player);
|
||||||
void _RewardXP(Player* player, float rate);
|
void _RewardXP(Player* player, float rate);
|
||||||
void _RewardReputation(Player* player, float rate);
|
void _RewardReputation(Player* player);
|
||||||
void _RewardKillCredit(Player* player);
|
void _RewardKillCredit(Player* player);
|
||||||
void _RewardPlayer(Player* player, bool isDungeon);
|
void _RewardPlayer(Player* player, bool isDungeon);
|
||||||
void _RewardGroup();
|
void _RewardGroup();
|
||||||
|
|||||||
@@ -5858,7 +5858,7 @@ float Player::CalculateReputationGain(ReputationSource source, uint32 creatureOr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculates how many reputation points player gains in victim's enemy factions
|
// Calculates how many reputation points player gains in victim's enemy factions
|
||||||
void Player::RewardReputation(Unit* victim, float rate)
|
void Player::RewardReputation(Unit* victim)
|
||||||
{
|
{
|
||||||
if (!victim || victim->GetTypeId() == TYPEID_PLAYER)
|
if (!victim || victim->GetTypeId() == TYPEID_PLAYER)
|
||||||
return;
|
return;
|
||||||
@@ -5887,7 +5887,6 @@ void Player::RewardReputation(Unit* victim, float rate)
|
|||||||
if (Rep->RepFaction1 && (!Rep->TeamDependent || teamId == TEAM_ALLIANCE))
|
if (Rep->RepFaction1 && (!Rep->TeamDependent || teamId == TEAM_ALLIANCE))
|
||||||
{
|
{
|
||||||
float donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), static_cast<float>(Rep->RepValue1), ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
|
float donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), static_cast<float>(Rep->RepValue1), ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
|
||||||
donerep1 *= rate;
|
|
||||||
|
|
||||||
FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
|
FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
|
||||||
if (factionEntry1)
|
if (factionEntry1)
|
||||||
@@ -5899,7 +5898,6 @@ void Player::RewardReputation(Unit* victim, float rate)
|
|||||||
if (Rep->RepFaction2 && (!Rep->TeamDependent || teamId == TEAM_HORDE))
|
if (Rep->RepFaction2 && (!Rep->TeamDependent || teamId == TEAM_HORDE))
|
||||||
{
|
{
|
||||||
float donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), static_cast<float>(Rep->RepValue2), ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
|
float donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), static_cast<float>(Rep->RepValue2), ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
|
||||||
donerep2 *= rate;
|
|
||||||
|
|
||||||
FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
|
FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
|
||||||
if (factionEntry2)
|
if (factionEntry2)
|
||||||
@@ -13443,8 +13441,11 @@ LootItem* Player::StoreLootItem(uint8 lootSlot, Loot* loot, InventoryResult& msg
|
|||||||
|
|
||||||
LootItem* item = loot->LootItemInSlot(lootSlot, this, &qitem, &ffaitem, &conditem);
|
LootItem* item = loot->LootItemInSlot(lootSlot, this, &qitem, &ffaitem, &conditem);
|
||||||
if (!item || item->is_looted)
|
if (!item || item->is_looted)
|
||||||
|
{
|
||||||
|
if (!sScriptMgr->CanSendErrorAlreadyLooted(this))
|
||||||
{
|
{
|
||||||
SendEquipError(EQUIP_ERR_ALREADY_LOOTED, nullptr, nullptr);
|
SendEquipError(EQUIP_ERR_ALREADY_LOOTED, nullptr, nullptr);
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2086,7 +2086,7 @@ public:
|
|||||||
ReputationMgr& GetReputationMgr() { return *m_reputationMgr; }
|
ReputationMgr& GetReputationMgr() { return *m_reputationMgr; }
|
||||||
[[nodiscard]] ReputationMgr const& GetReputationMgr() const { return *m_reputationMgr; }
|
[[nodiscard]] ReputationMgr const& GetReputationMgr() const { return *m_reputationMgr; }
|
||||||
[[nodiscard]] ReputationRank GetReputationRank(uint32 faction_id) const;
|
[[nodiscard]] ReputationRank GetReputationRank(uint32 faction_id) const;
|
||||||
void RewardReputation(Unit* victim, float rate);
|
void RewardReputation(Unit* victim);
|
||||||
void RewardReputation(Quest const* quest);
|
void RewardReputation(Quest const* quest);
|
||||||
|
|
||||||
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus = false);
|
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus = false);
|
||||||
|
|||||||
@@ -668,23 +668,24 @@ void WorldSession::HandleAuctionListOwnerItems(WorldPacket& recvData)
|
|||||||
recvData >> listfrom; // not used in fact (this list does not have page control in client)
|
recvData >> listfrom; // not used in fact (this list does not have page control in client)
|
||||||
|
|
||||||
// pussywizard:
|
// pussywizard:
|
||||||
const uint32 delay = 4500;
|
const Milliseconds now = GameTime::GetGameTimeMS();
|
||||||
const uint32 now = GameTime::GetGameTimeMS().count();
|
|
||||||
if (_lastAuctionListOwnerItemsMSTime > now) // list is pending
|
if (_lastAuctionListOwnerItemsMSTime > now) // list is pending
|
||||||
return;
|
return;
|
||||||
uint32 diff = getMSTimeDiff(_lastAuctionListOwnerItemsMSTime, now);
|
|
||||||
|
const Milliseconds delay = Milliseconds(4500);
|
||||||
|
Milliseconds diff = GetMSTimeDiff(_lastAuctionListOwnerItemsMSTime, now);
|
||||||
if (diff > delay)
|
if (diff > delay)
|
||||||
diff = delay;
|
diff = delay;
|
||||||
|
|
||||||
_lastAuctionListOwnerItemsMSTime = now + delay; // set longest possible here, actual exectuing will change this to getMSTime of that moment
|
_lastAuctionListOwnerItemsMSTime = now + delay; // set longest possible here, actual executing will change this to getMSTime of that moment
|
||||||
_player->m_Events.AddEvent(new AuctionListOwnerItemsDelayEvent(guid, _player->GetGUID(), true), _player->m_Events.CalculateTime(delay - diff));
|
_player->m_Events.AddEvent(new AuctionListOwnerItemsDelayEvent(guid, _player->GetGUID()), _player->m_Events.CalculateTime(delay.count() - diff.count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleAuctionListOwnerItemsEvent(ObjectGuid creatureGuid)
|
void WorldSession::HandleAuctionListOwnerItemsEvent(ObjectGuid creatureGuid)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_LIST_OWNER_ITEMS");
|
LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_LIST_OWNER_ITEMS");
|
||||||
|
|
||||||
_lastAuctionListOwnerItemsMSTime = GameTime::GetGameTimeMS().count(); // pussywizard
|
_lastAuctionListOwnerItemsMSTime = GameTime::GetGameTimeMS(); // pussywizard
|
||||||
|
|
||||||
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(creatureGuid, UNIT_NPC_FLAG_AUCTIONEER);
|
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(creatureGuid, UNIT_NPC_FLAG_AUCTIONEER);
|
||||||
if (!creature)
|
if (!creature)
|
||||||
@@ -757,17 +758,17 @@ void WorldSession::HandleAuctionListItems(WorldPacket& recvData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pussywizard:
|
// pussywizard:
|
||||||
const uint32 delay = 2000;
|
const Milliseconds delay = 2s;
|
||||||
const uint32 now = GameTime::GetGameTimeMS().count();
|
const Milliseconds now = GameTime::GetGameTimeMS();
|
||||||
uint32 diff = getMSTimeDiff(_lastAuctionListItemsMSTime, now);
|
Milliseconds diff = GetMSTimeDiff(_lastAuctionListItemsMSTime, now);
|
||||||
if (diff > delay)
|
if (diff > delay)
|
||||||
{
|
{
|
||||||
diff = delay;
|
diff = delay;
|
||||||
}
|
}
|
||||||
_lastAuctionListItemsMSTime = now + delay - diff;
|
_lastAuctionListItemsMSTime = now + delay - diff;
|
||||||
std::lock_guard<std::mutex> guard(AsyncAuctionListingMgr::GetTempLock());
|
std::lock_guard<std::mutex> guard(AsyncAuctionListingMgr::GetTempLock());
|
||||||
AsyncAuctionListingMgr::GetTempList().push_back(AuctionListItemsDelayEvent(delay - diff, _player->GetGUID(), guid, searchedname, listfrom, levelmin, levelmax, usable, auctionSlotID,
|
AsyncAuctionListingMgr::GetTempList().emplace_back(delay - diff, _player->GetGUID(), guid, searchedname, listfrom, levelmin, levelmax, usable, auctionSlotID,
|
||||||
auctionMainCategory, auctionSubCategory, quality, getAll, sortOrder));
|
auctionMainCategory, auctionSubCategory, quality, getAll, sortOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleAuctionListPendingSales(WorldPacket& recvData)
|
void WorldSession::HandleAuctionListPendingSales(WorldPacket& recvData)
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recvData)
|
|||||||
loot = &creature->loot;
|
loot = &creature->loot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sScriptMgr->OnAfterCreatureLoot(player);
|
||||||
|
|
||||||
InventoryResult msg;
|
InventoryResult msg;
|
||||||
LootItem* lootItem = player->StoreLootItem(lootSlot, loot, msg);
|
LootItem* lootItem = player->StoreLootItem(lootSlot, loot, msg);
|
||||||
if (msg != EQUIP_ERR_OK && lguid.IsItem() && loot->loot_type != LOOT_CORPSE)
|
if (msg != EQUIP_ERR_OK && lguid.IsItem() && loot->loot_type != LOOT_CORPSE)
|
||||||
@@ -209,6 +211,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
sScriptMgr->OnAfterCreatureLootMoney(player);
|
||||||
player->ModifyMoney(loot->gold);
|
player->ModifyMoney(loot->gold);
|
||||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold);
|
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold);
|
||||||
|
|
||||||
|
|||||||
@@ -22,11 +22,9 @@
|
|||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "SpellAuraEffects.h"
|
#include "SpellAuraEffects.h"
|
||||||
|
|
||||||
uint32 AsyncAuctionListingMgr::auctionListingDiff = 0;
|
Milliseconds AsyncAuctionListingMgr::auctionListingDiff = Milliseconds::zero();
|
||||||
bool AsyncAuctionListingMgr::auctionListingAllowed = false;
|
|
||||||
std::list<AuctionListItemsDelayEvent> AsyncAuctionListingMgr::auctionListingList;
|
std::list<AuctionListItemsDelayEvent> AsyncAuctionListingMgr::auctionListingList;
|
||||||
std::list<AuctionListItemsDelayEvent> AsyncAuctionListingMgr::auctionListingListTemp;
|
std::list<AuctionListItemsDelayEvent> AsyncAuctionListingMgr::auctionListingListTemp;
|
||||||
std::mutex AsyncAuctionListingMgr::auctionListingLock;
|
|
||||||
std::mutex AsyncAuctionListingMgr::auctionListingTempLock;
|
std::mutex AsyncAuctionListingMgr::auctionListingTempLock;
|
||||||
|
|
||||||
bool AuctionListOwnerItemsDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
bool AuctionListOwnerItemsDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
||||||
@@ -60,18 +58,19 @@ bool AuctionListItemsDelayEvent::Execute()
|
|||||||
|
|
||||||
wstrToLower(wsearchedname);
|
wstrToLower(wsearchedname);
|
||||||
|
|
||||||
|
uint32 searchTimeout = sWorld->getIntConfig(CONFIG_AUCTION_HOUSE_SEARCH_TIMEOUT);
|
||||||
bool result = auctionHouse->BuildListAuctionItems(data, plr,
|
bool result = auctionHouse->BuildListAuctionItems(data, plr,
|
||||||
wsearchedname, _listfrom, _levelmin, _levelmax, _usable,
|
wsearchedname, _listfrom, _levelmin, _levelmax, _usable,
|
||||||
_auctionSlotID, _auctionMainCategory, _auctionSubCategory, _quality,
|
_auctionSlotID, _auctionMainCategory, _auctionSubCategory, _quality,
|
||||||
count, totalcount, _getAll, _sortOrder);
|
count, totalcount, _getAll, _sortOrder, Milliseconds(searchTimeout));
|
||||||
|
|
||||||
if (!result)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
data.put<uint32>(0, count);
|
data.put<uint32>(0, count);
|
||||||
data << (uint32) totalcount;
|
data << (uint32) totalcount;
|
||||||
data << (uint32) 300; // clientside search cooldown [ms] (gray search button)
|
data << (uint32) 300; // clientside search cooldown [ms] (gray search button)
|
||||||
plr->GetSession()->SendPacket(&data);
|
plr->GetSession()->SendPacket(&data);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,30 +25,28 @@
|
|||||||
class AuctionListOwnerItemsDelayEvent : public BasicEvent
|
class AuctionListOwnerItemsDelayEvent : public BasicEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AuctionListOwnerItemsDelayEvent(ObjectGuid _creatureGuid, ObjectGuid guid, bool o) : creatureGuid(_creatureGuid), playerguid(guid), owner(o) {}
|
AuctionListOwnerItemsDelayEvent(ObjectGuid _creatureGuid, ObjectGuid guid) : creatureGuid(_creatureGuid), playerguid(guid) {}
|
||||||
~AuctionListOwnerItemsDelayEvent() override {}
|
~AuctionListOwnerItemsDelayEvent() override {}
|
||||||
|
|
||||||
bool Execute(uint64 e_time, uint32 p_time) override;
|
bool Execute(uint64 e_time, uint32 p_time) override;
|
||||||
void Abort(uint64 /*e_time*/) override {}
|
void Abort(uint64 /*e_time*/) override {}
|
||||||
bool getOwner() { return owner; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ObjectGuid creatureGuid;
|
ObjectGuid creatureGuid;
|
||||||
ObjectGuid playerguid;
|
ObjectGuid playerguid;
|
||||||
bool owner;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AuctionListItemsDelayEvent
|
class AuctionListItemsDelayEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AuctionListItemsDelayEvent(uint32 msTimer, ObjectGuid playerguid, ObjectGuid creatureguid, std::string searchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax,
|
AuctionListItemsDelayEvent(Milliseconds pickupTimer, ObjectGuid playerguid, ObjectGuid creatureguid, std::string searchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax,
|
||||||
uint8 usable, uint32 auctionSlotID, uint32 auctionMainCategory, uint32 auctionSubCategory, uint32 quality, uint8 getAll, AuctionSortOrderVector sortOrder) :
|
uint8 usable, uint32 auctionSlotID, uint32 auctionMainCategory, uint32 auctionSubCategory, uint32 quality, uint8 getAll, AuctionSortOrderVector sortOrder) :
|
||||||
_msTimer(msTimer), _playerguid(playerguid), _creatureguid(creatureguid), _searchedname(searchedname), _listfrom(listfrom), _levelmin(levelmin), _levelmax(levelmax),_usable(usable),
|
_pickupTimer(pickupTimer), _playerguid(playerguid), _creatureguid(creatureguid), _searchedname(searchedname), _listfrom(listfrom), _levelmin(levelmin), _levelmax(levelmax),_usable(usable),
|
||||||
_auctionSlotID(auctionSlotID), _auctionMainCategory(auctionMainCategory), _auctionSubCategory(auctionSubCategory), _quality(quality), _getAll(getAll), _sortOrder(sortOrder) { }
|
_auctionSlotID(auctionSlotID), _auctionMainCategory(auctionMainCategory), _auctionSubCategory(auctionSubCategory), _quality(quality), _getAll(getAll), _sortOrder(sortOrder) { }
|
||||||
|
|
||||||
bool Execute();
|
bool Execute();
|
||||||
|
|
||||||
uint32 _msTimer;
|
Milliseconds _pickupTimer;
|
||||||
ObjectGuid _playerguid;
|
ObjectGuid _playerguid;
|
||||||
ObjectGuid _creatureguid;
|
ObjectGuid _creatureguid;
|
||||||
std::string _searchedname;
|
std::string _searchedname;
|
||||||
@@ -67,23 +65,17 @@ public:
|
|||||||
class AsyncAuctionListingMgr
|
class AsyncAuctionListingMgr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void Update(uint32 diff) { auctionListingDiff += diff; }
|
static void Update(Milliseconds diff) { auctionListingDiff += diff; }
|
||||||
static uint32 GetDiff() { return auctionListingDiff; }
|
static Milliseconds GetDiff() { return auctionListingDiff; }
|
||||||
static void ResetDiff() { auctionListingDiff = 0; }
|
static void ResetDiff() { auctionListingDiff = Milliseconds::zero(); }
|
||||||
static bool IsAuctionListingAllowed() { return auctionListingAllowed; }
|
|
||||||
static void SetAuctionListingAllowed(bool a) { auctionListingAllowed = a; }
|
|
||||||
|
|
||||||
static std::list<AuctionListItemsDelayEvent>& GetList() { return auctionListingList; }
|
static std::list<AuctionListItemsDelayEvent>& GetList() { return auctionListingList; }
|
||||||
static std::list<AuctionListItemsDelayEvent>& GetTempList() { return auctionListingListTemp; }
|
static std::list<AuctionListItemsDelayEvent>& GetTempList() { return auctionListingListTemp; }
|
||||||
static std::mutex& GetLock() { return auctionListingLock; }
|
|
||||||
static std::mutex& GetTempLock() { return auctionListingTempLock; }
|
static std::mutex& GetTempLock() { return auctionListingTempLock; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uint32 auctionListingDiff;
|
static Milliseconds auctionListingDiff;
|
||||||
static bool auctionListingAllowed;
|
|
||||||
static std::list<AuctionListItemsDelayEvent> auctionListingList;
|
static std::list<AuctionListItemsDelayEvent> auctionListingList;
|
||||||
static std::list<AuctionListItemsDelayEvent> auctionListingListTemp;
|
static std::list<AuctionListItemsDelayEvent> auctionListingListTemp;
|
||||||
static std::mutex auctionListingLock;
|
|
||||||
static std::mutex auctionListingTempLock;
|
static std::mutex auctionListingTempLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -913,6 +913,37 @@ bool ScriptMgr::CanSendMail(Player* player, ObjectGuid receiverGuid, ObjectGuid
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScriptMgr::CanSendErrorAlreadyLooted(Player* player)
|
||||||
|
{
|
||||||
|
auto ret = IsValidBoolScript<PlayerScript>([&](PlayerScript* script)
|
||||||
|
{
|
||||||
|
return !script->CanSendErrorAlreadyLooted(player);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ret && *ret)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptMgr::OnAfterCreatureLoot(Player* player)
|
||||||
|
{
|
||||||
|
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
||||||
|
{
|
||||||
|
script->OnAfterCreatureLoot(player);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptMgr::OnAfterCreatureLootMoney(Player* player)
|
||||||
|
{
|
||||||
|
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
||||||
|
{
|
||||||
|
script->OnAfterCreatureLootMoney(player);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptMgr::PetitionBuy(Player* player, Creature* creature, uint32& charterid, uint32& cost, uint32& type)
|
void ScriptMgr::PetitionBuy(Player* player, Creature* creature, uint32& charterid, uint32& cost, uint32& type)
|
||||||
{
|
{
|
||||||
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
||||||
@@ -986,7 +1017,7 @@ void ScriptMgr::OnGetMaxSkillValue(Player* player, uint32 skill, int32& result,
|
|||||||
void ScriptMgr::OnUpdateGatheringSkill(Player *player, uint32 skillId, uint32 currentLevel, uint32 gray, uint32 green, uint32 yellow, uint32 &gain) {
|
void ScriptMgr::OnUpdateGatheringSkill(Player *player, uint32 skillId, uint32 currentLevel, uint32 gray, uint32 green, uint32 yellow, uint32 &gain) {
|
||||||
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
||||||
{
|
{
|
||||||
script->OnUpdateGatheringSkill(player, skillId, gray, green, yellow, currentLevel, gain);
|
script->OnUpdateGatheringSkill(player, skillId, currentLevel, gray, green, yellow, gain);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1483,6 +1483,30 @@ public:
|
|||||||
virtual void AnticheatUpdateMovementInfo(Player* /*player*/, MovementInfo const& /*movementInfo*/) { }
|
virtual void AnticheatUpdateMovementInfo(Player* /*player*/, MovementInfo const& /*movementInfo*/) { }
|
||||||
[[nodiscard]] virtual bool AnticheatHandleDoubleJump(Player* /*player*/, Unit* /*mover*/) { return true; }
|
[[nodiscard]] virtual bool AnticheatHandleDoubleJump(Player* /*player*/, Unit* /*mover*/) { return true; }
|
||||||
[[nodiscard]] virtual bool AnticheatCheckMovementInfo(Player* /*player*/, MovementInfo const& /*movementInfo*/, Unit* /*mover*/, bool /*jump*/) { return true; }
|
[[nodiscard]] virtual bool AnticheatCheckMovementInfo(Player* /*player*/, MovementInfo const& /*movementInfo*/, Unit* /*mover*/, bool /*jump*/) { return true; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This hook is called, to avoid displaying the error message that the body has already been stripped
|
||||||
|
*
|
||||||
|
* @param player Contains information about the Player
|
||||||
|
*
|
||||||
|
* @return true Avoiding displaying the error message that the loot has already been taken.
|
||||||
|
*/
|
||||||
|
virtual bool CanSendErrorAlreadyLooted(Player* /*player*/) { return true; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It is used when an item is taken from a creature.
|
||||||
|
*
|
||||||
|
* @param player Contains information about the Player
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual void OnAfterCreatureLoot(Player* /*player*/) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief After a creature's money is taken
|
||||||
|
*
|
||||||
|
* @param player Contains information about the Player
|
||||||
|
*/
|
||||||
|
virtual void OnAfterCreatureLootMoney(Player* /*player*/) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class AccountScript : public ScriptObject
|
class AccountScript : public ScriptObject
|
||||||
@@ -2447,6 +2471,9 @@ public: /* PlayerScript */
|
|||||||
void OnPlayerEnterCombat(Player* player, Unit* enemy);
|
void OnPlayerEnterCombat(Player* player, Unit* enemy);
|
||||||
void OnPlayerLeaveCombat(Player* player);
|
void OnPlayerLeaveCombat(Player* player);
|
||||||
void OnQuestAbandon(Player* player, uint32 questId);
|
void OnQuestAbandon(Player* player, uint32 questId);
|
||||||
|
bool CanSendErrorAlreadyLooted(Player* player);
|
||||||
|
void OnAfterCreatureLoot(Player* player);
|
||||||
|
void OnAfterCreatureLootMoney(Player* player);
|
||||||
|
|
||||||
// Anti cheat
|
// Anti cheat
|
||||||
void AnticheatSetSkipOnePacketForASH(Player* player, bool apply);
|
void AnticheatSetSkipOnePacketForASH(Player* player, bool apply);
|
||||||
|
|||||||
@@ -1079,8 +1079,8 @@ public: // opcodes handlers
|
|||||||
void HandleEnterPlayerVehicle(WorldPacket& data);
|
void HandleEnterPlayerVehicle(WorldPacket& data);
|
||||||
void HandleUpdateProjectilePosition(WorldPacket& recvPacket);
|
void HandleUpdateProjectilePosition(WorldPacket& recvPacket);
|
||||||
|
|
||||||
uint32 _lastAuctionListItemsMSTime;
|
Milliseconds _lastAuctionListItemsMSTime;
|
||||||
uint32 _lastAuctionListOwnerItemsMSTime;
|
Milliseconds _lastAuctionListOwnerItemsMSTime;
|
||||||
|
|
||||||
void HandleTeleportTimeout(bool updateInSessions);
|
void HandleTeleportTimeout(bool updateInSessions);
|
||||||
bool HandleSocketClosed();
|
bool HandleSocketClosed();
|
||||||
|
|||||||
@@ -1918,6 +1918,16 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 34026: // Kill Command
|
||||||
|
// Dungeon Set 3
|
||||||
|
if (caster->HasAura(37483))
|
||||||
|
{
|
||||||
|
if (apply)
|
||||||
|
{
|
||||||
|
caster->CastSpell(caster, 37482, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SPELLFAMILY_PALADIN:
|
case SPELLFAMILY_PALADIN:
|
||||||
|
|||||||
@@ -3436,6 +3436,11 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
|
|||||||
spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
|
spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
|
||||||
spell_bonus += int32(0.13f * m_caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()));
|
spell_bonus += int32(0.13f * m_caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()));
|
||||||
break;
|
break;
|
||||||
|
case 42463: // Seals of the Pure for Seal of Vengeance/Corruption
|
||||||
|
case 53739:
|
||||||
|
if (AuraEffect const* sealsOfPure = m_caster->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_PALADIN, 25, 0))
|
||||||
|
AddPct(totalDamagePercentMod, sealsOfPure->GetAmount());
|
||||||
|
break;
|
||||||
case 53385: // Divine Storm deals normalized damage
|
case 53385: // Divine Storm deals normalized damage
|
||||||
normalized = true;
|
normalized = true;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -413,6 +413,7 @@ enum WorldIntConfigs
|
|||||||
CONFIG_LFG_KICK_PREVENTION_TIMER,
|
CONFIG_LFG_KICK_PREVENTION_TIMER,
|
||||||
CONFIG_CHANGE_FACTION_MAX_MONEY,
|
CONFIG_CHANGE_FACTION_MAX_MONEY,
|
||||||
CONFIG_WATER_BREATH_TIMER,
|
CONFIG_WATER_BREATH_TIMER,
|
||||||
|
CONFIG_AUCTION_HOUSE_SEARCH_TIMEOUT,
|
||||||
INT_CONFIG_VALUE_COUNT
|
INT_CONFIG_VALUE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1286,6 +1286,8 @@ void World::LoadConfigSettings(bool reload)
|
|||||||
|
|
||||||
_bool_configs[CONFIG_ALLOWS_RANK_MOD_FOR_PET_HEALTH] = sConfigMgr->GetOption<bool>("Pet.RankMod.Health", true);
|
_bool_configs[CONFIG_ALLOWS_RANK_MOD_FOR_PET_HEALTH] = sConfigMgr->GetOption<bool>("Pet.RankMod.Health", true);
|
||||||
|
|
||||||
|
_int_configs[CONFIG_AUCTION_HOUSE_SEARCH_TIMEOUT] = sConfigMgr->GetOption<uint32>("AuctionHouse.SearchTimeout", 1000);
|
||||||
|
|
||||||
///- Read the "Data" directory from the config file
|
///- Read the "Data" directory from the config file
|
||||||
std::string dataPath = sConfigMgr->GetOption<std::string>("DataDir", "./");
|
std::string dataPath = sConfigMgr->GetOption<std::string>("DataDir", "./");
|
||||||
if (dataPath.empty() || (dataPath.at(dataPath.length() - 1) != '/' && dataPath.at(dataPath.length() - 1) != '\\'))
|
if (dataPath.empty() || (dataPath.at(dataPath.length() - 1) != '/' && dataPath.at(dataPath.length() - 1) != '\\'))
|
||||||
@@ -2352,13 +2354,6 @@ void World::Update(uint32 diff)
|
|||||||
|
|
||||||
sScriptMgr->OnPlayerbotUpdate(diff);
|
sScriptMgr->OnPlayerbotUpdate(diff);
|
||||||
|
|
||||||
// pussywizard:
|
|
||||||
// acquire mutex now, this is kind of waiting for listing thread to finish it's work (since it can't process next packet)
|
|
||||||
// so we don't have to do it in every packet that modifies auctions
|
|
||||||
AsyncAuctionListingMgr::SetAuctionListingAllowed(false);
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> guard(AsyncAuctionListingMgr::GetLock());
|
|
||||||
|
|
||||||
// pussywizard: handle auctions when the timer has passed
|
// pussywizard: handle auctions when the timer has passed
|
||||||
if (_timers[WUPDATE_AUCTIONS].Passed())
|
if (_timers[WUPDATE_AUCTIONS].Passed())
|
||||||
{
|
{
|
||||||
@@ -2370,7 +2365,7 @@ void World::Update(uint32 diff)
|
|||||||
sAuctionMgr->Update();
|
sAuctionMgr->Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncAuctionListingMgr::Update(diff);
|
AsyncAuctionListingMgr::Update(Milliseconds(diff));
|
||||||
|
|
||||||
if (currentGameTime > _mail_expire_check_timer)
|
if (currentGameTime > _mail_expire_check_timer)
|
||||||
{
|
{
|
||||||
@@ -2378,15 +2373,8 @@ void World::Update(uint32 diff)
|
|||||||
_mail_expire_check_timer = currentGameTime + 6h;
|
_mail_expire_check_timer = currentGameTime + 6h;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
/// <li> Handle session updates when the timer has passed
|
|
||||||
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update sessions"));
|
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update sessions"));
|
||||||
UpdateSessions(diff);
|
UpdateSessions(diff);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// end of section with mutex
|
|
||||||
AsyncAuctionListingMgr::SetAuctionListingAllowed(true);
|
|
||||||
|
|
||||||
/// <li> Handle weather updates when the timer has passed
|
/// <li> Handle weather updates when the timer has passed
|
||||||
if (_timers[WUPDATE_WEATHERS].Passed())
|
if (_timers[WUPDATE_WEATHERS].Passed())
|
||||||
|
|||||||
@@ -157,7 +157,6 @@ void AddSC_isle_of_queldanas();
|
|||||||
void AddSC_redridge_mountains();
|
void AddSC_redridge_mountains();
|
||||||
void AddSC_silverpine_forest();
|
void AddSC_silverpine_forest();
|
||||||
void AddSC_stormwind_city();
|
void AddSC_stormwind_city();
|
||||||
void AddSC_stranglethorn_vale();
|
|
||||||
void AddSC_tirisfal_glades();
|
void AddSC_tirisfal_glades();
|
||||||
void AddSC_undercity();
|
void AddSC_undercity();
|
||||||
void AddSC_western_plaguelands();
|
void AddSC_western_plaguelands();
|
||||||
@@ -310,7 +309,6 @@ void AddEasternKingdomsScripts()
|
|||||||
AddSC_redridge_mountains();
|
AddSC_redridge_mountains();
|
||||||
AddSC_silverpine_forest();
|
AddSC_silverpine_forest();
|
||||||
AddSC_stormwind_city();
|
AddSC_stormwind_city();
|
||||||
AddSC_stranglethorn_vale();
|
|
||||||
AddSC_tirisfal_glades();
|
AddSC_tirisfal_glades();
|
||||||
AddSC_undercity();
|
AddSC_undercity();
|
||||||
AddSC_western_plaguelands();
|
AddSC_western_plaguelands();
|
||||||
|
|||||||
@@ -1,129 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Affero General Public License as published by the
|
|
||||||
* Free Software Foundation; either version 3 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 Affero 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: Stranglethorn_Vale
|
|
||||||
SD%Complete: 100
|
|
||||||
SDComment: Quest support: 592
|
|
||||||
SDCategory: Stranglethorn Vale
|
|
||||||
EndScriptData */
|
|
||||||
|
|
||||||
/* ContentData
|
|
||||||
npc_yenniku
|
|
||||||
EndContentData */
|
|
||||||
|
|
||||||
#include "Player.h"
|
|
||||||
#include "ScriptMgr.h"
|
|
||||||
#include "ScriptedCreature.h"
|
|
||||||
#include "SpellInfo.h"
|
|
||||||
|
|
||||||
/*######
|
|
||||||
## npc_yenniku
|
|
||||||
######*/
|
|
||||||
|
|
||||||
class npc_yenniku : public CreatureScript
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
npc_yenniku() : CreatureScript("npc_yenniku") { }
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
|
||||||
{
|
|
||||||
return new npc_yennikuAI(creature);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct npc_yennikuAI : public ScriptedAI
|
|
||||||
{
|
|
||||||
npc_yennikuAI(Creature* creature) : ScriptedAI(creature)
|
|
||||||
{
|
|
||||||
bReset = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 Reset_Timer;
|
|
||||||
bool bReset;
|
|
||||||
|
|
||||||
void Reset() override
|
|
||||||
{
|
|
||||||
Reset_Timer = 0;
|
|
||||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpellHit(Unit* caster, SpellInfo const* spell) override
|
|
||||||
{
|
|
||||||
if (bReset || spell->Id != 3607)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (Player* player = caster->ToPlayer())
|
|
||||||
{
|
|
||||||
if (player->GetQuestStatus(592) == QUEST_STATUS_INCOMPLETE) //Yenniku's Release
|
|
||||||
{
|
|
||||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN);
|
|
||||||
me->CombatStop(); //stop combat
|
|
||||||
me->GetThreatMgr().ClearAllThreat(); //unsure of this
|
|
||||||
me->SetFaction(FACTION_HORDE_GENERIC);
|
|
||||||
|
|
||||||
bReset = true;
|
|
||||||
Reset_Timer = 60000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustEngagedWith(Unit* /*who*/) override { }
|
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
|
||||||
{
|
|
||||||
if (bReset)
|
|
||||||
{
|
|
||||||
if (Reset_Timer <= diff)
|
|
||||||
{
|
|
||||||
EnterEvadeMode();
|
|
||||||
bReset = false;
|
|
||||||
me->SetFaction(FACTION_TROLL_BLOODSCALP);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Reset_Timer -= diff;
|
|
||||||
|
|
||||||
if (me->IsInCombat() && me->GetVictim())
|
|
||||||
{
|
|
||||||
if (Player* player = me->GetVictim()->ToPlayer())
|
|
||||||
{
|
|
||||||
if (player->GetTeamId() == TEAM_HORDE)
|
|
||||||
{
|
|
||||||
me->CombatStop();
|
|
||||||
me->GetThreatMgr().ClearAllThreat();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Return since we have no target
|
|
||||||
if (!UpdateVictim())
|
|
||||||
return;
|
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/*######
|
|
||||||
##
|
|
||||||
######*/
|
|
||||||
|
|
||||||
void AddSC_stranglethorn_vale()
|
|
||||||
{
|
|
||||||
new npc_yenniku();
|
|
||||||
}
|
|
||||||
@@ -46,43 +46,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct npc_midsummer_bonfire : public ScriptedAI
|
|
||||||
{
|
|
||||||
npc_midsummer_bonfire(Creature* creature) : ScriptedAI(creature)
|
|
||||||
{
|
|
||||||
me->IsAIEnabled = true;
|
|
||||||
goGUID.Clear();
|
|
||||||
if (GameObject* go = me->SummonGameObject(GO_MIDSUMMER_BONFIRE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0))
|
|
||||||
{
|
|
||||||
goGUID = go->GetGUID();
|
|
||||||
me->RemoveGameObject(go, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectGuid goGUID;
|
|
||||||
|
|
||||||
void SpellHit(Unit*, SpellInfo const* spellInfo) override
|
|
||||||
{
|
|
||||||
if (!goGUID)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Extinguish fire
|
|
||||||
if (spellInfo->Id == SPELL_STAMP_OUT_BONFIRE)
|
|
||||||
{
|
|
||||||
if (GameObject* go = ObjectAccessor::GetGameObject(*me, goGUID))
|
|
||||||
go->SetPhaseMask(2, true);
|
|
||||||
}
|
|
||||||
else if (spellInfo->Id == SPELL_LIGHT_BONFIRE)
|
|
||||||
{
|
|
||||||
if (GameObject* go = ObjectAccessor::GetGameObject(*me, goGUID))
|
|
||||||
{
|
|
||||||
go->SetPhaseMask(1, true);
|
|
||||||
go->SendCustomAnim(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct npc_midsummer_torch_target : public ScriptedAI
|
struct npc_midsummer_torch_target : public ScriptedAI
|
||||||
{
|
{
|
||||||
npc_midsummer_torch_target(Creature* creature) : ScriptedAI(creature)
|
npc_midsummer_torch_target(Creature* creature) : ScriptedAI(creature)
|
||||||
@@ -542,7 +505,6 @@ void AddSC_event_midsummer_scripts()
|
|||||||
{
|
{
|
||||||
// NPCs
|
// NPCs
|
||||||
new go_midsummer_bonfire();
|
new go_midsummer_bonfire();
|
||||||
RegisterCreatureAI(npc_midsummer_bonfire);
|
|
||||||
RegisterCreatureAI(npc_midsummer_torch_target);
|
RegisterCreatureAI(npc_midsummer_torch_target);
|
||||||
|
|
||||||
// Spells
|
// Spells
|
||||||
|
|||||||
@@ -66,231 +66,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum WanderingShay
|
|
||||||
{
|
|
||||||
QUEST_WANDERING_SHAY = 2845,
|
|
||||||
|
|
||||||
SPELL_SHAY_BELL = 11402,
|
|
||||||
|
|
||||||
NPC_ROCKBITER = 7765,
|
|
||||||
|
|
||||||
TALK_0 = 0,
|
|
||||||
TALK_1 = 1,
|
|
||||||
TALK_2 = 2,
|
|
||||||
TALK_3 = 3,
|
|
||||||
TALK_4 = 4,
|
|
||||||
|
|
||||||
EVENT_WANDERING_START = 1,
|
|
||||||
EVENT_WANDERING_TALK = 2,
|
|
||||||
EVENT_WANDERING_RANDOM = 3,
|
|
||||||
EVENT_FINAL_TALK = 4,
|
|
||||||
EVENT_CHECK_FOLLOWER = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
class npc_shay_leafrunner : public CreatureScript
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
npc_shay_leafrunner() : CreatureScript("npc_shay_leafrunner") {}
|
|
||||||
|
|
||||||
struct npc_shay_leafrunnerAI : public ScriptedAI
|
|
||||||
{
|
|
||||||
npc_shay_leafrunnerAI(Creature* creature) : ScriptedAI(creature) {}
|
|
||||||
|
|
||||||
void InitializeAI() override
|
|
||||||
{
|
|
||||||
me->SetNpcFlag(UNIT_NPC_FLAG_QUESTGIVER);
|
|
||||||
me->SetImmuneToAll(true);
|
|
||||||
me->RestoreFaction();
|
|
||||||
|
|
||||||
_events.Reset();
|
|
||||||
_playerGUID.Clear();
|
|
||||||
_rockbiterGUID.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustRespawned() override
|
|
||||||
{
|
|
||||||
InitializeAI();
|
|
||||||
me->SetHomePosition(me->GetPosition());
|
|
||||||
}
|
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit* target) override
|
|
||||||
{
|
|
||||||
if (!_playerGUID || target->GetEntry() != NPC_ROCKBITER || !me->IsInRange(target, 0.f, 10.f))
|
|
||||||
{
|
|
||||||
if (!me->IsInCombat() && !me->GetVictim())
|
|
||||||
{
|
|
||||||
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID))
|
|
||||||
{
|
|
||||||
if (Unit* victim = player->GetVictim())
|
|
||||||
{
|
|
||||||
if (me->CanStartAttack(victim))
|
|
||||||
{
|
|
||||||
AttackStart(victim);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_rockbiterGUID = target->GetGUID();
|
|
||||||
|
|
||||||
Talk(TALK_4, target);
|
|
||||||
|
|
||||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
|
||||||
|
|
||||||
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID))
|
|
||||||
{
|
|
||||||
player->GroupEventHappens(QUEST_WANDERING_SHAY, me);
|
|
||||||
}
|
|
||||||
|
|
||||||
_events.CancelEvent(EVENT_WANDERING_START);
|
|
||||||
_events.ScheduleEvent(EVENT_FINAL_TALK, 5s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnterEvadeMode(EvadeReason why) override
|
|
||||||
{
|
|
||||||
_EnterEvadeMode(why);
|
|
||||||
|
|
||||||
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID))
|
|
||||||
{
|
|
||||||
me->GetMotionMaster()->MoveFollow(player, 3.f, M_PI);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FailQuest(Player* player, bool despawn)
|
|
||||||
{
|
|
||||||
if (player)
|
|
||||||
{
|
|
||||||
player->FailQuest(QUEST_WANDERING_SHAY);
|
|
||||||
|
|
||||||
if (Group* group = player->GetGroup())
|
|
||||||
{
|
|
||||||
for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
|
|
||||||
{
|
|
||||||
if (Player* member = groupRef->GetSource())
|
|
||||||
{
|
|
||||||
if (member->GetGUID() != player->GetGUID())
|
|
||||||
{
|
|
||||||
member->FailQuest(QUEST_WANDERING_SHAY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (despawn)
|
|
||||||
{
|
|
||||||
me->DespawnOrUnsummon(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
|
||||||
{
|
|
||||||
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID))
|
|
||||||
{
|
|
||||||
FailQuest(player, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sQuestAccept(Player* player, Quest const* quest) override
|
|
||||||
{
|
|
||||||
if (quest->GetQuestId() == QUEST_WANDERING_SHAY)
|
|
||||||
{
|
|
||||||
_playerGUID = player->GetGUID();
|
|
||||||
|
|
||||||
Talk(TALK_0, player);
|
|
||||||
|
|
||||||
me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER);
|
|
||||||
me->SetImmuneToAll(false);
|
|
||||||
me->SetFaction(FACTION_ESCORT_N_NEUTRAL_ACTIVE);
|
|
||||||
me->GetMotionMaster()->MoveFollow(player, 3.f, M_PI);
|
|
||||||
|
|
||||||
_events.ScheduleEvent(EVENT_WANDERING_START, 40s, 70s);
|
|
||||||
_events.ScheduleEvent(EVENT_CHECK_FOLLOWER, 30s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpellHit(Unit* caster, SpellInfo const* spellInfo) override
|
|
||||||
{
|
|
||||||
if (spellInfo->Id == SPELL_SHAY_BELL)
|
|
||||||
{
|
|
||||||
_playerGUID = caster->GetGUID();
|
|
||||||
|
|
||||||
Talk(TALK_1, caster);
|
|
||||||
|
|
||||||
me->GetMotionMaster()->MoveIdle();
|
|
||||||
me->GetMotionMaster()->MoveFollow(caster, 3.f, M_PI);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
|
||||||
{
|
|
||||||
if (UpdateVictim())
|
|
||||||
{
|
|
||||||
DoMeleeAttackIfReady();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_events.Update(diff);
|
|
||||||
while (uint32 eventId = _events.ExecuteEvent())
|
|
||||||
{
|
|
||||||
switch (eventId)
|
|
||||||
{
|
|
||||||
case EVENT_WANDERING_START:
|
|
||||||
{
|
|
||||||
Position pos = me->GetFirstCollisionPosition(15.f, rand_norm() * static_cast<float>(2 * M_PI));
|
|
||||||
me->GetMotionMaster()->MovePoint(0, pos);
|
|
||||||
Talk(TALK_2);
|
|
||||||
_events.ScheduleEvent(EVENT_WANDERING_START, 60s, 70s);
|
|
||||||
_events.ScheduleEvent(EVENT_WANDERING_TALK, 3s);
|
|
||||||
_events.ScheduleEvent(EVENT_WANDERING_RANDOM, 8s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EVENT_WANDERING_TALK:
|
|
||||||
Talk(TALK_3);
|
|
||||||
break;
|
|
||||||
case EVENT_WANDERING_RANDOM:
|
|
||||||
me->SetHomePosition(me->GetPosition());
|
|
||||||
me->GetMotionMaster()->MoveRandom(15.f);
|
|
||||||
break;
|
|
||||||
case EVENT_FINAL_TALK:
|
|
||||||
if (Creature* robckbiter = ObjectAccessor::GetCreature(*me, _rockbiterGUID))
|
|
||||||
{
|
|
||||||
robckbiter->AI()->Talk(TALK_0, me);
|
|
||||||
}
|
|
||||||
me->DespawnOrUnsummon(10 * IN_MILLISECONDS);
|
|
||||||
break;
|
|
||||||
case EVENT_CHECK_FOLLOWER:
|
|
||||||
{
|
|
||||||
Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID);
|
|
||||||
if (!player || !player->IsAlive() || !me->IsInRange(player, 0.f, 50.f))
|
|
||||||
{
|
|
||||||
FailQuest(player, true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ObjectGuid _playerGUID;
|
|
||||||
ObjectGuid _rockbiterGUID;
|
|
||||||
EventMap _events;
|
|
||||||
};
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
|
||||||
{
|
|
||||||
return new npc_shay_leafrunnerAI(creature);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void AddSC_feralas()
|
void AddSC_feralas()
|
||||||
{
|
{
|
||||||
new spell_gordunni_trap();
|
new spell_gordunni_trap();
|
||||||
new npc_shay_leafrunner();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,9 +97,6 @@ public:
|
|||||||
|
|
||||||
if (m_pInstance)
|
if (m_pInstance)
|
||||||
m_pInstance->SetData(TYPE_IONAR, NOT_STARTED);
|
m_pInstance->SetData(TYPE_IONAR, NOT_STARTED);
|
||||||
|
|
||||||
// Ionar is immune to nature damage
|
|
||||||
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NATURE, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScheduleEvents(bool spark)
|
void ScheduleEvents(bool spark)
|
||||||
|
|||||||
@@ -74,8 +74,11 @@ struct boss_exarch_maladaar : public BossAI
|
|||||||
_Reset();
|
_Reset();
|
||||||
ScheduleHealthCheckEvent(25, [&] {
|
ScheduleHealthCheckEvent(25, [&] {
|
||||||
Talk(SAY_SUMMON);
|
Talk(SAY_SUMMON);
|
||||||
|
scheduler.Schedule(100ms, [this](TaskContext)
|
||||||
|
{
|
||||||
DoCastSelf(SPELL_SUMMON_AVATAR);
|
DoCastSelf(SPELL_SUMMON_AVATAR);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit* who) override
|
void MoveInLineOfSight(Unit* who) override
|
||||||
@@ -133,6 +136,11 @@ struct boss_exarch_maladaar : public BossAI
|
|||||||
_JustDied();
|
_JustDied();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JustSummoned(Creature* /*creature*/) override
|
||||||
|
{
|
||||||
|
// Override JustSummoned() so we don't despawn the Avatar.
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
void UpdateAI(uint32 diff) override
|
||||||
{
|
{
|
||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
|
|||||||
@@ -208,25 +208,27 @@ class spell_murmur_thundering_storm : public SpellScript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 33711/38794 - Murmur's Touch
|
// 33686 - Shockwave (Murmur's Touch final explosion)
|
||||||
class spell_murmur_touch : public AuraScript
|
class spell_shockwave_knockback : public SpellScript
|
||||||
{
|
{
|
||||||
PrepareAuraScript(spell_murmur_touch);
|
PrepareSpellScript(spell_shockwave_knockback);
|
||||||
|
|
||||||
void HandleAfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||||
{
|
{
|
||||||
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
|
return ValidateSpellInfo({ SPELL_SHOCKWAVE_SERVERSIDE });
|
||||||
{
|
|
||||||
if (GetTarget())
|
|
||||||
{
|
|
||||||
GetTarget()->CastSpell(GetTarget(), SPELL_SHOCKWAVE_SERVERSIDE, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleOnHit()
|
||||||
|
{
|
||||||
|
if (Unit* target = GetHitUnit())
|
||||||
|
{
|
||||||
|
target->CastSpell(target, SPELL_SHOCKWAVE_SERVERSIDE, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Register() override
|
void Register() override
|
||||||
{
|
{
|
||||||
AfterEffectRemove += AuraEffectRemoveFn(spell_murmur_touch::HandleAfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
|
OnHit += SpellHitFn(spell_shockwave_knockback::HandleOnHit);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -252,6 +254,6 @@ void AddSC_boss_murmur()
|
|||||||
{
|
{
|
||||||
RegisterShadowLabyrinthCreatureAI(boss_murmur);
|
RegisterShadowLabyrinthCreatureAI(boss_murmur);
|
||||||
RegisterSpellScript(spell_murmur_thundering_storm);
|
RegisterSpellScript(spell_murmur_thundering_storm);
|
||||||
RegisterSpellScript(spell_murmur_touch);
|
RegisterSpellScript(spell_shockwave_knockback);
|
||||||
RegisterSpellScript(spell_murmur_sonic_boom_effect);
|
RegisterSpellScript(spell_murmur_sonic_boom_effect);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ enum EventSpells
|
|||||||
SPELL_SUMMON_COLDWAVE = 45952,
|
SPELL_SUMMON_COLDWAVE = 45952,
|
||||||
SPELL_SUMMON_FROSTWIND = 45953,
|
SPELL_SUMMON_FROSTWIND = 45953,
|
||||||
|
|
||||||
|
SPELL_CHILLING_AURA = 46542,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SPELL_SUMMON_ICE_SPEAR_BUNNY= 46359, // any dest
|
SPELL_SUMMON_ICE_SPEAR_BUNNY= 46359, // any dest
|
||||||
SPELL_ICE_SPEAR_KNOCKBACK = 46360, // src caster
|
SPELL_ICE_SPEAR_KNOCKBACK = 46360, // src caster
|
||||||
@@ -63,6 +65,11 @@ enum EventSpells
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CreatureIds
|
||||||
|
{
|
||||||
|
NPC_AHUNITE_HAILSTONE = 25755
|
||||||
|
};
|
||||||
|
|
||||||
enum eEvents
|
enum eEvents
|
||||||
{
|
{
|
||||||
EVENT_EMERGE = 1,
|
EVENT_EMERGE = 1,
|
||||||
@@ -81,19 +88,14 @@ enum eEvents
|
|||||||
EVENT_SPELL_SUMMON_COLDWAVE,
|
EVENT_SPELL_SUMMON_COLDWAVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_ahune : public CreatureScript
|
enum Misc
|
||||||
{
|
{
|
||||||
public:
|
SET_GUID_INVOKER = 1
|
||||||
boss_ahune() : CreatureScript("boss_ahune") { }
|
};
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* pCreature) const override
|
struct boss_ahune : public ScriptedAI
|
||||||
{
|
{
|
||||||
return GetTheSlavePensAI<boss_ahuneAI>(pCreature);
|
boss_ahune(Creature* c) : ScriptedAI(c), summons(me)
|
||||||
}
|
|
||||||
|
|
||||||
struct boss_ahuneAI : public ScriptedAI
|
|
||||||
{
|
|
||||||
boss_ahuneAI(Creature* c) : ScriptedAI(c), summons(me)
|
|
||||||
{
|
{
|
||||||
SetCombatMovement(false);
|
SetCombatMovement(false);
|
||||||
SetEquipmentSlots(false, 54806, EQUIP_UNEQUIP, EQUIP_UNEQUIP);
|
SetEquipmentSlots(false, 54806, EQUIP_UNEQUIP, EQUIP_UNEQUIP);
|
||||||
@@ -109,17 +111,6 @@ public:
|
|||||||
SummonList summons;
|
SummonList summons;
|
||||||
ObjectGuid InvokerGUID;
|
ObjectGuid InvokerGUID;
|
||||||
|
|
||||||
bool CanBeSeen(Player const* player) override
|
|
||||||
{
|
|
||||||
if (player->IsGameMaster())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Group const* group = player->GetGroup();
|
|
||||||
return group && sLFGMgr->GetDungeon(group->GetGUID()) == lfg::LFG_DUNGEON_FROST_LORD_AHUNE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartPhase1()
|
void StartPhase1()
|
||||||
{
|
{
|
||||||
me->CastSpell(me, SPELL_AHUNES_SHIELD, true);
|
me->CastSpell(me, SPELL_AHUNES_SHIELD, true);
|
||||||
@@ -136,6 +127,14 @@ public:
|
|||||||
StartPhase1();
|
StartPhase1();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetGUID(ObjectGuid guid, int32 id) override
|
||||||
|
{
|
||||||
|
if (id == SET_GUID_INVOKER)
|
||||||
|
{
|
||||||
|
InvokerGUID = guid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
void UpdateAI(uint32 diff) override
|
||||||
{
|
{
|
||||||
if (!UpdateVictim() && !me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
|
if (!UpdateVictim() && !me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
|
||||||
@@ -146,7 +145,7 @@ public:
|
|||||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch(events.ExecuteEvent())
|
switch (events.ExecuteEvent())
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
@@ -200,7 +199,7 @@ public:
|
|||||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
me->CastSpell(me, SPELL_SUBMERGE_0, true);
|
me->CastSpell(me, SPELL_SUBMERGE_0, true);
|
||||||
me->CastSpell(me, SPELL_SELF_STUN, true);
|
me->CastSpell(me, SPELL_SELF_STUN, true);
|
||||||
if (Creature* c = DoSummon(NPC_FROZEN_CORE, *me, 24000, TEMPSUMMON_TIMED_DESPAWN))
|
if (Creature* c = DoSummon(NPC_FROZEN_CORE, *me, 24000, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN))
|
||||||
{
|
{
|
||||||
c->SetHealth(me->GetHealth());
|
c->SetHealth(me->GetHealth());
|
||||||
}
|
}
|
||||||
@@ -217,6 +216,7 @@ public:
|
|||||||
me->CastSpell(me, SPELL_EMERGE_0, false);
|
me->CastSpell(me, SPELL_EMERGE_0, false);
|
||||||
// me->CastSpell(me, SPELL_AHUNE_RESURFACES, true); // done in SummonedCreatureDespawn
|
// me->CastSpell(me, SPELL_AHUNE_RESURFACES, true); // done in SummonedCreatureDespawn
|
||||||
me->RemoveAura(SPELL_SUBMERGE_0);
|
me->RemoveAura(SPELL_SUBMERGE_0);
|
||||||
|
summons.DespawnEntry(NPC_FROZEN_CORE);
|
||||||
StartPhase1();
|
StartPhase1();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -236,8 +236,7 @@ public:
|
|||||||
{
|
{
|
||||||
float dist = (float)urand(3, 10);
|
float dist = (float)urand(3, 10);
|
||||||
float angle = rand_norm() * 2 * M_PI;
|
float angle = rand_norm() * 2 * M_PI;
|
||||||
me->CastSpell(MinionSummonPos.GetPositionX() + cos(angle)*dist, MinionSummonPos.GetPositionY() + std::sin(angle)*dist, MinionSummonPos.GetPositionZ(), SPELL_SUMMON_HAILSTONE, false);
|
me->CastSpell(MinionSummonPos.GetPositionX() + cos(angle) * dist, MinionSummonPos.GetPositionY() + std::sin(angle) * dist, MinionSummonPos.GetPositionZ(), SPELL_SUMMON_HAILSTONE, false);
|
||||||
events.RepeatEvent(30000);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EVENT_SPELL_SUMMON_COLDWAVE:
|
case EVENT_SPELL_SUMMON_COLDWAVE:
|
||||||
@@ -245,14 +244,14 @@ public:
|
|||||||
{
|
{
|
||||||
float dist = (float)urand(3, 10);
|
float dist = (float)urand(3, 10);
|
||||||
float angle = rand_norm() * 2 * M_PI;
|
float angle = rand_norm() * 2 * M_PI;
|
||||||
me->CastSpell(MinionSummonPos.GetPositionX() + cos(angle)*dist, MinionSummonPos.GetPositionY() + std::sin(angle)*dist, MinionSummonPos.GetPositionZ(), SPELL_SUMMON_COLDWAVE, false);
|
me->CastSpell(MinionSummonPos.GetPositionX() + cos(angle) * dist, MinionSummonPos.GetPositionY() + std::sin(angle) * dist, MinionSummonPos.GetPositionZ(), SPELL_SUMMON_COLDWAVE, false);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
float dist = (float)urand(3, 10);
|
float dist = (float)urand(3, 10);
|
||||||
float angle = rand_norm() * 2 * M_PI;
|
float angle = rand_norm() * 2 * M_PI;
|
||||||
me->CastSpell(MinionSummonPos.GetPositionX() + cos(angle)*dist, MinionSummonPos.GetPositionY() + std::sin(angle)*dist, MinionSummonPos.GetPositionZ(), SPELL_SUMMON_FROSTWIND, false);
|
me->CastSpell(MinionSummonPos.GetPositionX() + cos(angle) * dist, MinionSummonPos.GetPositionY() + std::sin(angle) * dist, MinionSummonPos.GetPositionZ(), SPELL_SUMMON_FROSTWIND, false);
|
||||||
}
|
}
|
||||||
events.RepeatEvent(6000);
|
events.RepeatEvent(12000);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -275,11 +274,18 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JustSummoned(Creature* summon) override
|
void JustSummoned(Creature* summon) override
|
||||||
{
|
|
||||||
if (summon)
|
|
||||||
{
|
{
|
||||||
summons.Summon(summon);
|
summons.Summon(summon);
|
||||||
summon->SetInCombatWithZone();
|
summon->SetInCombatWithZone();
|
||||||
|
|
||||||
|
if (summon->GetEntry() == NPC_AHUNITE_HAILSTONE)
|
||||||
|
{
|
||||||
|
// Doesn't work when cast normally or when added to
|
||||||
|
// creature template addon. Needs further investigation.
|
||||||
|
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_CHILLING_AURA))
|
||||||
|
{
|
||||||
|
Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, summon, summon);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,10 +311,8 @@ public:
|
|||||||
me->RemoveGameObject(chest, false);
|
me->RemoveGameObject(chest, false);
|
||||||
|
|
||||||
bool finished = false;
|
bool finished = false;
|
||||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
|
||||||
if (!players.IsEmpty())
|
me->GetMap()->DoForAllPlayers([&](Player* player)
|
||||||
for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
|
|
||||||
if (Player* player = i->GetSource())
|
|
||||||
{
|
{
|
||||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, 25740, 1, me);
|
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, 25740, 1, me);
|
||||||
|
|
||||||
@@ -317,9 +321,8 @@ public:
|
|||||||
finished = true;
|
finished = true;
|
||||||
sLFGMgr->FinishDungeon(player->GetGroup()->GetGUID(), lfg::LFG_DUNGEON_FROST_LORD_AHUNE, me->FindMap());
|
sLFGMgr->FinishDungeon(player->GetGroup()->GetGUID(), lfg::LFG_DUNGEON_FROST_LORD_AHUNE, me->FindMap());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class go_ahune_ice_stone : public GameObjectScript
|
class go_ahune_ice_stone : public GameObjectScript
|
||||||
@@ -331,8 +334,18 @@ public:
|
|||||||
{
|
{
|
||||||
if (!player || !go)
|
if (!player || !go)
|
||||||
return true;
|
return true;
|
||||||
if (!player->HasItemCount(ITEM_MAGMA_TOTEM))
|
|
||||||
|
if (!player->IsGameMaster())
|
||||||
|
{
|
||||||
|
if (Group const* group = player->GetGroup())
|
||||||
|
{
|
||||||
|
if (sLFGMgr->GetDungeon(group->GetGUID()) != lfg::LFG_DUNGEON_FROST_LORD_AHUNE)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (go->FindNearestCreature(NPC_AHUNE, 200.0f, true))
|
if (go->FindNearestCreature(NPC_AHUNE, 200.0f, true))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -345,9 +358,19 @@ public:
|
|||||||
{
|
{
|
||||||
if (!player || !go)
|
if (!player || !go)
|
||||||
return true;
|
return true;
|
||||||
if (action != GOSSIP_ACTION_INFO_DEF + 1337)
|
|
||||||
|
if (!player->IsGameMaster())
|
||||||
|
{
|
||||||
|
if (Group const* group = player->GetGroup())
|
||||||
|
{
|
||||||
|
if (sLFGMgr->GetDungeon(group->GetGUID()) != lfg::LFG_DUNGEON_FROST_LORD_AHUNE)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
if (!player->HasItemCount(ITEM_MAGMA_TOTEM))
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action != GOSSIP_ACTION_INFO_DEF + 1337)
|
||||||
return true;
|
return true;
|
||||||
if (go->FindNearestCreature(NPC_AHUNE, 200.0f, true))
|
if (go->FindNearestCreature(NPC_AHUNE, 200.0f, true))
|
||||||
return true;
|
return true;
|
||||||
@@ -360,7 +383,11 @@ public:
|
|||||||
c->SetVisible(false);
|
c->SetVisible(false);
|
||||||
c->SetDisplayId(AHUNE_DEFAULT_MODEL);
|
c->SetDisplayId(AHUNE_DEFAULT_MODEL);
|
||||||
c->SetFloatValue(UNIT_FIELD_COMBATREACH, 18.0f);
|
c->SetFloatValue(UNIT_FIELD_COMBATREACH, 18.0f);
|
||||||
CAST_AI(boss_ahune::boss_ahuneAI, c->AI())->InvokerGUID = player->GetGUID();
|
if (c->AI())
|
||||||
|
{
|
||||||
|
c->AI()->SetGUID(player->GetGUID(), SET_GUID_INVOKER);
|
||||||
|
}
|
||||||
|
|
||||||
if (Creature* bunny = go->SummonCreature(NPC_AHUNE_SUMMON_LOC_BUNNY, AhuneSummonPos, TEMPSUMMON_TIMED_DESPAWN, 12000))
|
if (Creature* bunny = go->SummonCreature(NPC_AHUNE_SUMMON_LOC_BUNNY, AhuneSummonPos, TEMPSUMMON_TIMED_DESPAWN, 12000))
|
||||||
if (Creature* crystal_trigger = go->SummonCreature(WORLD_TRIGGER, go->GetPositionX(), go->GetPositionY(), 5.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 12000))
|
if (Creature* crystal_trigger = go->SummonCreature(WORLD_TRIGGER, go->GetPositionX(), go->GetPositionY(), 5.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 12000))
|
||||||
crystal_trigger->CastSpell(bunny, SPELL_STARTING_BEAM, false);
|
crystal_trigger->CastSpell(bunny, SPELL_STARTING_BEAM, false);
|
||||||
@@ -371,30 +398,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class npc_ahune_frozen_core : public CreatureScript
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
npc_ahune_frozen_core() : CreatureScript("npc_ahune_frozen_core") { }
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* pCreature) const override
|
|
||||||
{
|
|
||||||
return GetTheSlavePensAI<npc_ahune_frozen_coreAI>(pCreature);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct npc_ahune_frozen_coreAI : public NullCreatureAI
|
|
||||||
{
|
|
||||||
npc_ahune_frozen_coreAI(Creature* c) : NullCreatureAI(c) {}
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
|
||||||
{
|
|
||||||
me->DespawnOrUnsummon();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
void AddSC_boss_ahune()
|
void AddSC_boss_ahune()
|
||||||
{
|
{
|
||||||
new go_ahune_ice_stone();
|
new go_ahune_ice_stone();
|
||||||
new boss_ahune();
|
RegisterTheSlavePensCreatureAI(boss_ahune);
|
||||||
new npc_ahune_frozen_core();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ enum MekgineerSteamrigger
|
|||||||
SPELL_SAW_BLADE = 31486,
|
SPELL_SAW_BLADE = 31486,
|
||||||
SPELL_ELECTRIFIED_NET = 35107,
|
SPELL_ELECTRIFIED_NET = 35107,
|
||||||
SPELL_ENRAGE = 26662,
|
SPELL_ENRAGE = 26662,
|
||||||
SPELL_REPAIR_N = 31532,
|
|
||||||
SPELL_REPAIR_H = 37936,
|
|
||||||
|
|
||||||
SPELL_SUMMON_MECHANICS_1 = 31528,
|
SPELL_SUMMON_MECHANICS_1 = 31528,
|
||||||
SPELL_SUMMON_MECHANICS_2 = 31529,
|
SPELL_SUMMON_MECHANICS_2 = 31529,
|
||||||
|
|||||||
@@ -85,7 +85,15 @@ struct boss_swamplord_muselek : public BossAI
|
|||||||
|
|
||||||
bool CanShootVictim()
|
bool CanShootVictim()
|
||||||
{
|
{
|
||||||
return me->GetVictim() && !me->IsWithinRange(me->GetVictim(), 10.0f) && me->IsWithinLOSInMap(me->GetVictim());
|
Unit* victim = me->GetVictim();
|
||||||
|
|
||||||
|
if (!victim || !me->IsWithinLOSInMap(victim) || !me->IsWithinRange(victim, 30.f) || me->IsWithinRange(victim, 10.f))
|
||||||
|
{
|
||||||
|
_canChase = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustEngagedWith(Unit* /*who*/) override
|
void JustEngagedWith(Unit* /*who*/) override
|
||||||
@@ -100,6 +108,8 @@ struct boss_swamplord_muselek : public BossAI
|
|||||||
me->LoadEquipment(1, true);
|
me->LoadEquipment(1, true);
|
||||||
DoCastVictim(SPELL_SHOOT);
|
DoCastVictim(SPELL_SHOOT);
|
||||||
me->GetMotionMaster()->Clear();
|
me->GetMotionMaster()->Clear();
|
||||||
|
me->StopMoving();
|
||||||
|
_canChase = false;
|
||||||
}
|
}
|
||||||
else if (_canChase)
|
else if (_canChase)
|
||||||
{
|
{
|
||||||
@@ -121,7 +131,7 @@ struct boss_swamplord_muselek : public BossAI
|
|||||||
context.Repeat(20s, 30s);
|
context.Repeat(20s, 30s);
|
||||||
}).Schedule(30s, 40s, [this](TaskContext context)
|
}).Schedule(30s, 40s, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, false, true))
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, false, true))
|
||||||
{
|
{
|
||||||
_markTarget = target->GetGUID();
|
_markTarget = target->GetGUID();
|
||||||
_canChase = false;
|
_canChase = false;
|
||||||
@@ -135,6 +145,7 @@ struct boss_swamplord_muselek : public BossAI
|
|||||||
{
|
{
|
||||||
me->GetMotionMaster()->Clear();
|
me->GetMotionMaster()->Clear();
|
||||||
me->GetMotionMaster()->MoveForwards(me->GetVictim(), 10.0f);
|
me->GetMotionMaster()->MoveForwards(me->GetVictim(), 10.0f);
|
||||||
|
_canChase = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
me->m_Events.AddEventAtOffset([this]()
|
me->m_Events.AddEventAtOffset([this]()
|
||||||
|
|||||||
+29
-25
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
|
#include "TaskScheduler.h"
|
||||||
#include "hellfire_ramparts.h"
|
#include "hellfire_ramparts.h"
|
||||||
|
|
||||||
enum Says
|
enum Says
|
||||||
@@ -83,11 +84,6 @@ struct boss_vazruden_the_herald : public BossAI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustDied(Unit*) override
|
|
||||||
{
|
|
||||||
instance->SetBossState(DATA_VAZRUDEN, DONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MovementInform(uint32 type, uint32 id) override
|
void MovementInform(uint32 type, uint32 id) override
|
||||||
{
|
{
|
||||||
if (type == POINT_MOTION_TYPE && id == POINT_MIDDLE)
|
if (type == POINT_MOTION_TYPE && id == POINT_MIDDLE)
|
||||||
@@ -105,7 +101,7 @@ struct boss_vazruden_the_herald : public BossAI
|
|||||||
{
|
{
|
||||||
Talk(SAY_INTRO);
|
Talk(SAY_INTRO);
|
||||||
me->GetMotionMaster()->MovePoint(POINT_MIDDLE, -1406.5f, 1746.5f, 85.0f, false);
|
me->GetMotionMaster()->MovePoint(POINT_MIDDLE, -1406.5f, 1746.5f, 85.0f, false);
|
||||||
me->setActive(true);
|
_JustEngagedWith();
|
||||||
}
|
}
|
||||||
else if (summons.size() == 0)
|
else if (summons.size() == 0)
|
||||||
{
|
{
|
||||||
@@ -139,11 +135,11 @@ struct boss_vazruden_the_herald : public BossAI
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct boss_nazan : public BossAI
|
struct boss_nazan : public ScriptedAI
|
||||||
{
|
{
|
||||||
boss_nazan(Creature* creature) : BossAI(creature, DATA_VAZRUDEN)
|
boss_nazan(Creature* creature) : ScriptedAI(creature)
|
||||||
{
|
{
|
||||||
scheduler.SetValidator([this]
|
_scheduler.SetValidator([this]
|
||||||
{
|
{
|
||||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||||
});
|
});
|
||||||
@@ -162,11 +158,11 @@ struct boss_nazan : public BossAI
|
|||||||
|
|
||||||
void JustEngagedWith(Unit*) override
|
void JustEngagedWith(Unit*) override
|
||||||
{
|
{
|
||||||
scheduler.CancelGroup(GROUP_PHASE_2);
|
_scheduler.CancelAll();
|
||||||
scheduler.Schedule(5ms, GROUP_PHASE_1, [this](TaskContext context)
|
_scheduler.Schedule(5ms, GROUP_PHASE_1, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
me->GetMotionMaster()->MovePoint(POINT_FLIGHT, NazanPos[urand(0, 2)], false);
|
me->GetMotionMaster()->MovePoint(POINT_FLIGHT, NazanPos[urand(0, 2)], false);
|
||||||
scheduler.DelayAll(7s);
|
_scheduler.DelayAll(7s);
|
||||||
context.Repeat(30s);
|
context.Repeat(30s);
|
||||||
}).Schedule(5s, GROUP_PHASE_1, [this](TaskContext context)
|
}).Schedule(5s, GROUP_PHASE_1, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
@@ -191,6 +187,7 @@ struct boss_nazan : public BossAI
|
|||||||
{
|
{
|
||||||
if (param == ACTION_FLY_DOWN)
|
if (param == ACTION_FLY_DOWN)
|
||||||
{
|
{
|
||||||
|
_scheduler.CancelGroup(GROUP_PHASE_1);
|
||||||
Talk(EMOTE_NAZAN);
|
Talk(EMOTE_NAZAN);
|
||||||
me->SetReactState(REACT_PASSIVE);
|
me->SetReactState(REACT_PASSIVE);
|
||||||
me->InterruptNonMeleeSpells(true);
|
me->InterruptNonMeleeSpells(true);
|
||||||
@@ -205,9 +202,8 @@ struct boss_nazan : public BossAI
|
|||||||
me->SetCanFly(false);
|
me->SetCanFly(false);
|
||||||
me->SetDisableGravity(false);
|
me->SetDisableGravity(false);
|
||||||
me->SetReactState(REACT_AGGRESSIVE);
|
me->SetReactState(REACT_AGGRESSIVE);
|
||||||
scheduler.CancelGroup(GROUP_PHASE_1);
|
|
||||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||||
scheduler.Schedule(5s, GROUP_PHASE_2, [this](TaskContext context)
|
_scheduler.Schedule(5s, GROUP_PHASE_2, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
DoCastVictim(SPELL_CONE_OF_FIRE);
|
DoCastVictim(SPELL_CONE_OF_FIRE);
|
||||||
context.Repeat(12s);
|
context.Repeat(12s);
|
||||||
@@ -216,9 +212,10 @@ struct boss_nazan : public BossAI
|
|||||||
DoCastRandomTarget(SPELL_FIREBALL);
|
DoCastRandomTarget(SPELL_FIREBALL);
|
||||||
context.Repeat(4s, 6s);
|
context.Repeat(4s, 6s);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (IsHeroic())
|
if (IsHeroic())
|
||||||
{
|
{
|
||||||
scheduler.Schedule(10s, GROUP_PHASE_2, [this](TaskContext context)
|
_scheduler.Schedule(10s, GROUP_PHASE_2, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
DoCastSelf(SPELL_BELLOWING_ROAR);
|
DoCastSelf(SPELL_BELLOWING_ROAR);
|
||||||
context.Repeat(30s);
|
context.Repeat(30s);
|
||||||
@@ -227,24 +224,28 @@ struct boss_nazan : public BossAI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 /*diff*/) override
|
void UpdateAI(uint32 diff) override
|
||||||
{
|
{
|
||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
_scheduler.Update(diff, [this]
|
||||||
return;
|
{
|
||||||
|
|
||||||
if (!me->IsLevitating())
|
if (!me->IsLevitating())
|
||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TaskScheduler _scheduler;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct boss_vazruden : public BossAI
|
struct boss_vazruden : public ScriptedAI
|
||||||
{
|
{
|
||||||
boss_vazruden(Creature* creature) : BossAI(creature, DATA_VAZRUDEN)
|
boss_vazruden(Creature* creature) : ScriptedAI(creature)
|
||||||
{
|
{
|
||||||
scheduler.SetValidator([this]
|
_scheduler.SetValidator([this]
|
||||||
{
|
{
|
||||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||||
});
|
});
|
||||||
@@ -263,7 +264,7 @@ struct boss_vazruden : public BossAI
|
|||||||
|
|
||||||
void JustEngagedWith(Unit*) override
|
void JustEngagedWith(Unit*) override
|
||||||
{
|
{
|
||||||
scheduler.Schedule(5s, [this](TaskContext /*context*/)
|
_scheduler.Schedule(5s, [this](TaskContext /*context*/)
|
||||||
{
|
{
|
||||||
Talk(SAY_AGGRO);
|
Talk(SAY_AGGRO);
|
||||||
}).Schedule(4s, [this](TaskContext context)
|
}).Schedule(4s, [this](TaskContext context)
|
||||||
@@ -280,7 +281,7 @@ struct boss_vazruden : public BossAI
|
|||||||
_hasSpoken = true;
|
_hasSpoken = true;
|
||||||
Talk(SAY_KILL);
|
Talk(SAY_KILL);
|
||||||
}
|
}
|
||||||
scheduler.Schedule(6s, [this](TaskContext /*context*/)
|
_scheduler.Schedule(6s, [this](TaskContext /*context*/)
|
||||||
{
|
{
|
||||||
_hasSpoken = false;
|
_hasSpoken = false;
|
||||||
});
|
});
|
||||||
@@ -305,13 +306,16 @@ struct boss_vazruden : public BossAI
|
|||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scheduler.Update(diff);
|
_scheduler.Update(diff, [this]
|
||||||
|
{
|
||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _hasSpoken;
|
bool _hasSpoken;
|
||||||
bool _nazanCalled;
|
bool _nazanCalled;
|
||||||
|
TaskScheduler _scheduler;
|
||||||
};
|
};
|
||||||
|
|
||||||
class spell_vazruden_fireball : public SpellScript
|
class spell_vazruden_fireball : public SpellScript
|
||||||
|
|||||||
@@ -144,17 +144,21 @@ class spell_capacitus_polarity_charge : public SpellScript
|
|||||||
void HandleTargets(std::list<WorldObject*>& targetList)
|
void HandleTargets(std::list<WorldObject*>& targetList)
|
||||||
{
|
{
|
||||||
uint8 count = 0;
|
uint8 count = 0;
|
||||||
for (std::list<WorldObject*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit)
|
for (auto& ihit : targetList)
|
||||||
if ((*ihit)->GetGUID() != GetCaster()->GetGUID())
|
if (ihit->GetGUID() != GetCaster()->GetGUID())
|
||||||
if (Player* target = (*ihit)->ToPlayer())
|
if (Player* target = ihit->ToPlayer())
|
||||||
if (target->HasAura(GetTriggeringSpell()->Id))
|
if (target->HasAura(GetTriggeringSpell()->Id))
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
|
uint32 spellId = GetSpellInfo()->Id == SPELL_POSITIVE_CHARGE ? SPELL_POSITIVE_CHARGE_STACK : SPELL_NEGATIVE_CHARGE_STACK;
|
||||||
if (count)
|
if (count)
|
||||||
{
|
{
|
||||||
uint32 spellId = GetSpellInfo()->Id == SPELL_POSITIVE_CHARGE ? SPELL_POSITIVE_CHARGE_STACK : SPELL_NEGATIVE_CHARGE_STACK;
|
|
||||||
GetCaster()->SetAuraStack(spellId, GetCaster(), count);
|
GetCaster()->SetAuraStack(spellId, GetCaster(), count);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GetCaster()->RemoveAurasDueToSpell(spellId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleDamage(SpellEffIndex /*effIndex*/)
|
void HandleDamage(SpellEffIndex /*effIndex*/)
|
||||||
@@ -174,6 +178,29 @@ class spell_capacitus_polarity_charge : public SpellScript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class spell_capacitus_polarity_charge_aura : public AuraScript
|
||||||
|
{
|
||||||
|
PrepareAuraScript(spell_capacitus_polarity_charge_aura);
|
||||||
|
|
||||||
|
void HandleAfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||||
|
{
|
||||||
|
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
|
||||||
|
{
|
||||||
|
Unit* target = GetTarget();
|
||||||
|
if (!target)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target->RemoveAurasDueToSpell(SPELL_POSITIVE_CHARGE_STACK);
|
||||||
|
target->RemoveAurasDueToSpell(SPELL_NEGATIVE_CHARGE_STACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
AfterEffectRemove += AuraEffectRemoveFn(spell_capacitus_polarity_charge_aura::HandleAfterRemove, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class spell_capacitus_polarity_shift : public SpellScript
|
class spell_capacitus_polarity_shift : public SpellScript
|
||||||
{
|
{
|
||||||
PrepareSpellScript(spell_capacitus_polarity_shift);
|
PrepareSpellScript(spell_capacitus_polarity_shift);
|
||||||
@@ -194,5 +221,6 @@ void AddSC_boss_mechano_lord_capacitus()
|
|||||||
{
|
{
|
||||||
RegisterMechanarCreatureAI(boss_mechano_lord_capacitus);
|
RegisterMechanarCreatureAI(boss_mechano_lord_capacitus);
|
||||||
RegisterSpellScript(spell_capacitus_polarity_charge);
|
RegisterSpellScript(spell_capacitus_polarity_charge);
|
||||||
|
RegisterSpellScript(spell_capacitus_polarity_charge_aura);
|
||||||
RegisterSpellScript(spell_capacitus_polarity_shift);
|
RegisterSpellScript(spell_capacitus_polarity_shift);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user