Merge branch 'master' into git

This commit is contained in:
ShinDarth 2016-08-07 14:55:21 +02:00
commit a7a81f90b1
84 changed files with 1531 additions and 680 deletions

20
.gitignore vendored
View file

@ -1,7 +1,24 @@
#
# AzerothCore
#
*/compiler/config.sh
conf/*
!conf/*.dist
modules/*
#
# Allow modules to control git ignoring
#
!modules/*
modules/*/*
!modules/*/.gitignore
build*/
#
#Generic
#
.directory
.mailmap
*.orig
@ -27,6 +44,7 @@ CMakeLists.txt.user
# exclude in all levels
nbproject/
.sync.ffs_db
*.kate-swp
.browse.VC*
.vscode

View file

@ -28,11 +28,6 @@ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH 1)
# set macro-directory
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/src/cmake/macros")
# build in Release-mode by default if not explicitly set
if( NOT CMAKE_BUILD_TYPE )
set(CMAKE_BUILD_TYPE "Release")
endif()
include(CheckCXXSourceRuns)
include(CheckIncludeFiles)
@ -40,7 +35,19 @@ include(CheckIncludeFiles)
include(src/cmake/utils.cmake)
# set default buildoptions and print them
include(src/cmake/options.cmake)
include(conf/config.cmake.dist)
# load custom configurations for cmake if exists
if(EXISTS "conf/config.cmake")
include(conf/config.cmake)
endif()
RUN_HOOK("AFTER_LOAD_CONF")
# build in Release-mode by default if not explicitly set
if( NOT CMAKE_BUILD_TYPE )
set(CMAKE_BUILD_TYPE "Release")
endif()
# turn off PCH totally if enabled (hidden setting, mainly for devs)
if( NOPCH )
@ -79,9 +86,11 @@ include(src/cmake/showoptions.cmake)
# add modules and dependencies
AZTH_SUBDIRLIST(sub_DIRS "${CMAKE_SOURCE_DIR}/modules" FALSE FALSE)
FOREACH(subdir ${sub_DIRS})
STRING(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/" "" subdir ${subdir})
message("Loading module: ${subdir}")
add_subdirectory("${subdir}")
STRING(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/" "" subdir_rel ${subdir})
if(EXISTS "${subdir}/CMakeLists.txt")
message("Loading module: ${subdir_rel}")
add_subdirectory("${subdir_rel}")
endif()
ENDFOREACH()
RUN_HOOK("BEFORE_SRC_LOAD")

View file

@ -2,4 +2,6 @@ AZTH_PATH_ROOT=$(readlink -f "$AZTH_PATH_BIN/../")
AZTH_PATH_CONF="$AZTH_PATH_ROOT/conf"
AZTH_PATH_MODULES="$AZTH_PATH_ROOT/modules"
AZTH_PATH_CUSTOM=$(readlink -f "$AZTH_PATH_ROOT/../azth_custom")

View file

@ -5,3 +5,20 @@ AZTH_PATH_SHARED="$AZTH_PATH_BIN/bash_shared"
source "$AZTH_PATH_SHARED/defines.sh"
source "$AZTH_PATH_SHARED/functions.sh"
source "$AZTH_PATH_CONF/config.sh.dist" # "hack" to avoid missing conf variables
if [ -f "$AZTH_PATH_CONF/config.sh" ]; then
source "$AZTH_PATH_CONF/config.sh" # should overwrite previous
fi
#
# Load modules
#
for entry in "$AZTH_PATH_MODULES/"*/include.sh
do
if [ -e $entry ]; then
source $entry
fi
done

2
bin/compiler/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
config.sh

View file

@ -1,8 +1,5 @@
#!/bin/bash
CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$CURRENT_PATH/includes/common.sh"
source "$CURRENT_PATH/includes/includes.sh"
clean
bash "$CURRENT_PATH/compiler.sh" 1

View file

@ -1,8 +1,5 @@
#!/bin/bash
CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$CURRENT_PATH/includes/common.sh"
source "$CURRENT_PATH/includes/includes.sh"
configure
bash "$CURRENT_PATH/compiler.sh" 2

View file

@ -1,8 +1,5 @@
#!/bin/bash
CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$CURRENT_PATH/includes/common.sh"
source "$CURRENT_PATH/includes/includes.sh"
build
bash "$CURRENT_PATH/compiler.sh" 3

View file

@ -1,7 +1,7 @@
## How to compile:
first of all, if you need some custom configuration you have to copy and rename
config.sh.dist in config.sh and configure it
/conf/config.sh.dist in /conf/config.sh and configure it
* for a "clean" compilation you must run all scripts in their order:
@ -21,4 +21,4 @@ config.sh.dist in config.sh and configure it
## Note:
For an optimal development process and **really faster** compilation time, is suggested to use clang instead of gcc
For an optimal development process and **really faster** compilation time, is suggested to use clang instead of gcc

43
bin/compiler/compiler.sh Executable file
View file

@ -0,0 +1,43 @@
#!/bin/bash
CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$CURRENT_PATH/includes/includes.sh"
function all() {
clean
configure
build
}
function run_option() {
if test "${comp_functions[$1-1]+'test'}"; then
${comp_functions[$1-1]}
else
echo "invalid option"
fi
}
comp_options=("Clean" "Configure" "Build" "All")
comp_functions=("clean" "configure" "build" "all")
runHooks "ON_AFTER_OPTIONS" #you can create your custom options
# push exit after custom options
comp_options+=('Exit')
comp_functions+=('exit 0')
# run option directly if specified in argument
[ ! -z $1 ] && run_option $1 && exit 0
PS3='[ Please enter your choice ]: '
select opt in "${comp_options[@]}"
do
case $opt in
'Exit')
break
;;
*)
run_option $REPLY
;;
esac
done

View file

@ -1,38 +0,0 @@
#!/bin/bash
# set preferred compilers
#CCOMPILERC="/usr/bin/clang-3.6"
#CCOMPILERCC="/usr/bin/clang-3.6"
#CCOMPILERCXX="/usr/bin/clang++-3.6"
CCOMPILERC="/usr/bin/gcc"
CCOMPILERCC="/usr/bin/gcc"
CCOMPILERCXX="/usr/bin/g++"
# how many thread must be used for compilation ( leave zero to use all available )
MTHREADS=0
# enable/disable warnings during compilation
CWARNINGS=1
# enable/disable some debug informations ( it's not a debug compilation )
CDEBUG=0
# specify compilation type
CCTYPE=Release
# compile scripts
CSCRIPTS=1
# compile server
CSERVERS=1
# compile tools
CTOOLS=0
# use precompiled headers ( fatest compilation but not optimized if you change headers often )
CSCRIPTPCH=1
CCOREPCH=1
# absolute root path of your azerothshard repository
SRCPATH=
# absolute path where binary files must be stored
BINPATH=
# absolute path where config. files must be stored
CONFDIR=

View file

@ -1,5 +0,0 @@
source "./config.sh.dist" # "hack" to avoid missing conf variables
if [ -f "./config.sh" ]; then
source "./config.sh" # should overwrite previous
fi

View file

@ -11,6 +11,6 @@ BUILDPATH=$BINPATH
INSTALL_PATH=$(readlink -f "$BINPATH/../")
[ $CCTYPE == "Debug" ] && BUILDPATH="$BUILDPATH/debug/build/" || BUILDPATH="$BUILDPATH/release/build/"
[ $CTYPE == "Debug" ] && BUILDPATH="$BUILDPATH/debug/build/" || BUILDPATH="$BUILDPATH/release/build/"
[ $CCTYPE == "Debug" ] && BINPATH="$BINPATH/debug" || BINPATH="$BINPATH/release"
[ $CTYPE == "Debug" ] && BINPATH="$BINPATH/debug" || BINPATH="$BINPATH/release"

View file

@ -20,7 +20,7 @@ function configure() {
echo "Build path: $BUILDPATH"
echo "DEBUG info: $CDEBUG"
echo "Compilation type: $CCTYPE"
echo "Compilation type: $CTYPE"
# -DCMAKE_BUILD_TYPE=$CCTYPE disable optimization "slow and huge amount of ram"
# -DWITH_COREDEBUG=$CDEBUG compiled with debug information
@ -30,8 +30,8 @@ function configure() {
cmake $SRCPATH -DCMAKE_INSTALL_PREFIX=$BINPATH -DCONF_DIR=$CONFDIR -DSERVERS=$CSERVERS \
-DSCRIPTS=$CSCRIPTS \
-DTOOLS=$CTOOLS -DUSE_SCRIPTPCH=$CSCRIPTPCH -DUSE_COREPCH=$CCOREPCH -DWITH_COREDEBUG=$CDEBUG -DCMAKE_BUILD_TYPE=$CCTYPE -DWITH_WARNINGS=$CWARNINGS \
-DCMAKE_C_COMPILER=$CCOMPILERC -DCMAKE_CXX_COMPILER=$CCOMPILERCXX
-DTOOLS=$CTOOLS -DUSE_SCRIPTPCH=$CSCRIPTPCH -DUSE_COREPCH=$CCOREPCH -DWITH_COREDEBUG=$CDEBUG -DCMAKE_BUILD_TYPE=$CTYPE -DWITH_WARNINGS=$CWARNINGS \
-DCMAKE_C_COMPILER=$CCOMPILERC -DCMAKE_CXX_COMPILER=$CCOMPILERCXX $CCUSTOMOPTIONS
cd $CWD

View file

@ -4,6 +4,10 @@ source "$CURRENT_PATH/../../bash_shared/includes.sh"
AZTH_PATH_COMPILER="$AZTH_PATH_BIN/compiler"
if [ -f "$AZTH_PATH_COMPILER/config.sh" ]; then
source "$AZTH_PATH_COMPILER/config.sh" # should overwrite previous
fi
function azth_on_after_build() {
# move the run engine
cp -rvf "$AZTH_PATH_BIN/runners/"* "$INSTALL_PATH/bin/"

View file

@ -1,49 +0,0 @@
#!/bin/bash
# 0 if you want create an sql for each kind of following categories
# 1 to create a single big file to import ( suggested for new installations )
ALL_IN_ONE=0
DATABASES=(
"AUTH"
"CHARACTERS"
"WORLD"
)
OUTPUT_FOLDER="output/"
# FULL DB
DB_CHARACTERS_PATHS=(
$SRCPATH"/data/sql/databases/characters.sql"
)
DB_AUTH_PATHS=(
$SRCPATH"/data/sql/databases/auth.sql"
)
DB_WORLD_PATHS=(
$SRCPATH"/data/sql/databases/world.sql"
)
# UPDATES
DB_CHARACTERS_UPDATE_PATHS=(
$SRCPATH"/data/sql/updates/characters/"
)
DB_AUTH_UPDATE_PATHS=(
$SRCPATH"/data/sql/updates/auth/"
)
DB_WORLD_UPDATE_PATHS=(
$SRCPATH"/data/sql/updates/world/"
)
# CUSTOM
DB_CHARACTERS_CUSTOM_PATHS=(
)
DB_AUTH_CUSTOM_PATHS=(
)
DB_WORLD_CUSTOM_PATHS=(
)

View file

@ -7,128 +7,148 @@ else
SRCPATH=$(readlink -f "../../")
fi
#
# You can pass latest version as first argument of this script
#
if [ -z "$1" ]; then
read -p "Enter latest sql version ( leave blank to use : 0000_00_00_00 )" $version
version=${version:-0000_00_00_00}
else
version=$1
fi
source "./config.sh.dist" # "hack" to avoid missing conf variables
source $SRCPATH"/bin/bash_shared/includes.sh"
if [ -f "./config.sh" ]; then
source "./config.sh" # should overwrite previous
fi
unamestr=`uname`
if [[ "$unamestr" == 'Darwin' ]]; then
MD5_CMD="md5"
else
MD5_CMD="md5sum"
fi
reg_file="$OUTPUT_FOLDER/.zzz_db_assembler_registry.sh"
declare -A registry
if [ -f "$reg_file" ]; then
source "$reg_file"
fi
echo "===== STARTING PROCESS ====="
gtversion=""
function assemble() {
database=$1
start_sql=$2
database=$1
start_sql=$2
var_full="DB_"$database"_PATHS"
full=${!var_full}
var_base="DB_"$database"_PATHS"
base=${!var_base}
var_updates="DB_"$database"_UPDATE_PATHS"
updates=${!var_updates}
var_updates="DB_"$database"_UPDATE_PATHS"
updates=${!var_updates}
var_custom="DB_"$database"_CUSTOM_PATHS"
custom=${!var_custom}
var_custom="DB_"$database"_CUSTOM_PATHS"
custom=${!var_custom}
suffix_base=""
suffix_upd=""
suffix_custom=""
suffix_base=""
suffix_upd=""
suffix_custom=""
if (( $ALL_IN_ONE == 0 )); then
suffix_base="_base"
fi;
if (( $ALL_IN_ONE == 0 )); then
suffix_base="_base"
fi;
echo "" > $OUTPUT_FOLDER$database$suffix_base".sql"
echo "" > $OUTPUT_FOLDER$database$suffix_base".sql"
if [ ! ${#full[@]} -eq 0 ]; then
echo "Generating $OUTPUT_FOLDER$database$suffix_based ..."
if [ ! ${#base[@]} -eq 0 ]; then
echo "Generating $OUTPUT_FOLDER$database$suffix_base ..."
for entry in "${full[@]}"
do
if [ ! -z $entry ]; then
if [ -e $entry ]; then
cat "$entry" >> $OUTPUT_FOLDER$database$suffix_base".sql"
fi
fi
done
fi
for d in "${base[@]}"
do
if [ ! -z $d ]; then
for entry in "$d"/*.sql "$d"/**/*.sql
do
if [[ -e $entry ]]; then
cat "$entry" >> $OUTPUT_FOLDER$database$suffix_base".sql"
fi
done
fi
done
fi
if (( $ALL_IN_ONE == 0 )); then
suffix_upd="_updates"
if (( $ALL_IN_ONE == 0 )); then
suffix_upd="_updates"
echo "" > $OUTPUT_FOLDER$database$suffix_upd".sql"
fi;
echo "" > $OUTPUT_FOLDER$database$suffix_upd".sql"
fi;
if [ ! ${#updates[@]} -eq 0 ]; then
echo "Generating $OUTPUT_FOLDER$database$suffix_upd ..."
if [ ! ${#updates[@]} -eq 0 ]; then
echo "Generating $OUTPUT_FOLDER$database$suffix_upd ..."
for d in "${updates[@]}"
do
for entry in "$d"/*.sql "$d"/**/*.sql
do
if [ ! -z $d ]; then
file=$(basename $entry)
if [[ "$file" > "$start_sql" ]]
then
if [ -e $entry ]; then
if [[ "$gtversion" < "$file" ]]; then
gtversion=$file
fi
for d in "${updates[@]}"
do
if [ ! -z $d ]; then
for entry in "$d"/*.sql "$d"/**/*.sql
do
if [[ ! -e $entry ]]; then
continue
fi
cat "$entry" >> $OUTPUT_FOLDER$database$suffix_upd".sql"
fi
fi
fi
done
done
fi
file=$(basename "$entry")
hash=$($MD5_CMD "$entry")
hash="${hash%% *}" #remove file path
if [[ -z ${registry[$hash]} ]]; then
registry["$hash"]="$file"
echo "-- New update sql: "$file
cat "$entry" >> $OUTPUT_FOLDER$database$suffix_upd".sql"
fi
done
fi
done
fi
if (( $ALL_IN_ONE == 0 )); then
suffix_custom="_custom"
if (( $ALL_IN_ONE == 0 )); then
suffix_custom="_custom"
echo "" > $OUTPUT_FOLDER$database$suffix_custom".sql"
fi;
echo "" > $OUTPUT_FOLDER$database$suffix_custom".sql"
fi;
if [ ! ${#custom[@]} -eq 0 ]; then
echo "Generating $OUTPUT_FOLDER$database$suffix_custom ..."
for d in "${custom[@]}"
do
if [ ! -z $d ]; then
for entry in "$d"/*.sql "$d"/**/*.sql
do
if [ -e $entry ]; then
cat "$entry" >> $OUTPUT_FOLDER$database$suffix_custom".sql"
fi
done
fi
done
fi
if [ ! ${#custom[@]} -eq 0 ]; then
echo "Generating $OUTPUT_FOLDER$database$suffix_custom ..."
for d in "${custom[@]}"
do
if [ ! -z $d ]; then
for entry in "$d"/*.sql "$d"/**/*.sql
do
if [[ ! -e $entry ]]; then
continue
fi
file=$(basename "$entry")
hash=$($MD5_CMD "$entry")
hash="${hash%% *}" #remove file path
if [[ -z ${registry[$hash]} ]]; then
registry["$hash"]="$file"
echo "-- New custom sql: "$file
cat "$entry" >> $OUTPUT_FOLDER$database$suffix_custom".sql"
fi
done
fi
done
fi
}
mkdir -p $OUTPUT_FOLDER
for db in ${DATABASES[@]}
do
assemble "$db" $version".sql"
assemble "$db" $version".sql"
done
rm $OUTPUT_FOLDER"ZZZ_latest_version_"*
echo $gtversion > $OUTPUT_FOLDER"ZZZ_latest_version_"${gtversion%.*}
echo "" > $reg_file
for i in "${!registry[@]}"
do
echo "registry['"$i"']='"${registry[$i]}"'" >> "$reg_file"
done
echo "===== DONE ====="

View file

@ -1,31 +0,0 @@
#!/bin/bash
######################
# enable/disable GDB execution
export GDB_ENABLED=0
# gdb file
export GDB=""
# directory where binary are stored
exoirt BINPATH=""
### Put here the pid you configured on your worldserver.conf file ###
export SERVERPID=""
# path to conf file
export CONFIG=""
# path of log files
export LOGS_PATH="";
# exec name
export SERVERBIN=""
# name of screen service ( for restarter )
export SCREEN_NAME=""
######################

View file

@ -7,11 +7,10 @@ SYSERR="$5"
GBD_ENABLED="$6"
if [ $GBD_ENABLED -eq 1 ]; then
echo "run -c $3" > "$GDB_FILE"
echo "set logging on" > "$GDB_FILE"
echo "set debug timestamp" >> "$GDB_FILE"
echo "run -c $3" >> "$GDB_FILE"
echo "bt" >> "$GDB_FILE"
echo "bt full" >> "$GDB_FILE"
echo "info threads" >> "$GDB_FILE"
echo "thread apply all bt full" >> "$GDB_FILE"
[ ! -f "$SYSLOG" ] && touch "$SYSLOG"
[ ! -f "$SYSERR" ] && touch "$SYSERR"
@ -19,4 +18,4 @@ if [ $GBD_ENABLED -eq 1 ]; then
gdb -x $GDB_FILE --batch $1 >> "$SYSLOG" 2>> "$SYSERR"
elif [ $GBD_ENABLED -eq 0 ]; then
"./$1" -c "$CONFIG"
fi
fi

View file

@ -1,13 +1,3 @@
# Copyright (C)
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
option(SERVERS "Build worldserver and authserver" 1)
option(SCRIPTS "Build core with scripts included" 1)
option(TOOLS "Build map/vmap/mmap extraction/assembler tools" 0)

132
conf/config.sh.dist Normal file
View file

@ -0,0 +1,132 @@
#!/bin/bash
#!/bin/bash
# absolute root path of your azerothshard repository
SRCPATH="$AZTH_PATH_ROOT"
# absolute path where binary files must be stored
BINPATH="$AZTH_PATH_ROOT/build/"
# absolute path where config. files must be stored
CONFDIR="$AZTH_PATH_ROOT/build/etc/"
##############################################
#
# COMPILER_CONFIGURATIONS
#
##############################################
# set preferred compilers
#CCOMPILERC="/usr/bin/clang-3.6"
#CCOMPILERCC="/usr/bin/clang-3.6"
#CCOMPILERCXX="/usr/bin/clang++-3.6"
CCOMPILERC="/usr/bin/gcc"
CCOMPILERCC="/usr/bin/gcc"
CCOMPILERCXX="/usr/bin/g++"
# how many thread must be used for compilation ( leave zero to use all available )
MTHREADS=0
# enable/disable warnings during compilation
CWARNINGS=1
# enable/disable some debug informations ( it's not a debug compilation )
CDEBUG=0
# specify compilation type
CTYPE=Release
# compile scripts
CSCRIPTS=1
# compile server
CSERVERS=1
# compile tools
CTOOLS=0
# use precompiled headers ( fatest compilation but not optimized if you change headers often )
CSCRIPTPCH=1
CCOREPCH=1
# you can add your custom definitions here ( -D )
CCUSTOMOPTIONS=""
##############################################
#
# RUNNER CONFIGURATION
#
##############################################
# enable/disable GDB execution
export GDB_ENABLED=0
# gdb file
export GDB=""
# directory where binary are stored
export BINPATH=""
### Put here the pid you configured on your worldserver.conf file ###
export SERVERPID=""
# path to conf file
export CONFIG=""
# path of log files
export LOGS_PATH="";
# exec name
export SERVERBIN=""
# name of screen service ( for restarter )
export SCREEN_NAME=""
##############################################
#
# DB ASSEMBLER CONFIGURATIONS
#
##############################################
# 0 if you want create an sql for each kind of following categories
# 1 to create a single big file to import ( suggested for new installations )
ALL_IN_ONE=0
DATABASES=(
"AUTH"
"CHARACTERS"
"WORLD"
)
OUTPUT_FOLDER="output/"
# FULL DB
DB_CHARACTERS_PATHS=(
$SRCPATH"/data/sql/base/characters"
)
DB_AUTH_PATHS=(
$SRCPATH"/data/sql/base/auth/"
)
DB_WORLD_PATHS=(
$SRCPATH"/data/sql/base/world/"
)
# UPDATES
DB_CHARACTERS_UPDATE_PATHS=(
$SRCPATH"/data/sql/updates/characters/"
)
DB_AUTH_UPDATE_PATHS=(
$SRCPATH"/data/sql/updates/auth/"
)
DB_WORLD_UPDATE_PATHS=(
$SRCPATH"/data/sql/updates/world/"
)
# CUSTOM
DB_CHARACTERS_CUSTOM_PATHS=(
)
DB_AUTH_CUSTOM_PATHS=(
)
DB_WORLD_CUSTOM_PATHS=(
)

@ -1 +1 @@
Subproject commit 46489f483fc41a7f1eac208f0c66dc3f4182a3ef
Subproject commit 352f3c6a77c8c455b53b997589f0838afe22b954

View file

@ -0,0 +1,25 @@
ALTER TABLE characters_db_version CHANGE COLUMN 2016_07_10_00 2016_07_30_00 bit;
CREATE TABLE IF NOT EXISTS `gm_ticket` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`type` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '0 open, 1 closed, 2 character deleted',
`playerGuid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier of ticket creator',
`name` varchar(12) NOT NULL COMMENT 'Name of ticket creator',
`description` text NOT NULL,
`createTime` int(10) unsigned NOT NULL DEFAULT '0',
`mapId` smallint(5) unsigned NOT NULL DEFAULT '0',
`posX` float NOT NULL DEFAULT '0',
`posY` float NOT NULL DEFAULT '0',
`posZ` float NOT NULL DEFAULT '0',
`lastModifiedTime` int(10) unsigned NOT NULL DEFAULT '0',
`closedBy` int(10) unsigned NOT NULL DEFAULT '0',
`assignedTo` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'GUID of admin to whom ticket is assigned',
`comment` text NOT NULL,
`response` text NOT NULL,
`completed` tinyint(3) unsigned NOT NULL DEFAULT '0',
`escalated` tinyint(3) unsigned NOT NULL DEFAULT '0',
`viewed` tinyint(3) unsigned NOT NULL DEFAULT '0',
`needMoreHelp` tinyint(3) unsigned NOT NULL DEFAULT '0',
`resolvedBy` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'GUID of GM who resolved the ticket',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10572 DEFAULT CHARSET=utf8 COMMENT='Player System';

View file

@ -0,0 +1,15 @@
-- loot for mindless servant 26536 in utgarde pinnacle
DELETE FROM `creature_loot_template` WHERE (Entry = 26536);
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `ChanceOrQuestChance`, `LootMode`, `GroupId`, `mincountOrRef`, `maxcount`) VALUES
(26536, 33470, 10.7, 1, 0, 1, 7),
(26536, 26002, 3, 1, 1, -26002, 1),
(26536, 26011, 1, 1, 1, -26011, 1),
(26536, 26012, 1, 1, 1, -26012, 1),
(26536, 26040, 21.4, 1, 0, -26040, 1),
(26536, 33370, 3.6, 1, 1, 1, 1),
(26536, 33399, 3.6, 1, 1, 1, 1),
(26536, 33454, 35.5, 1, 0, 1, 1),
(26536, 37068, 0.69, 1, 1, 1, 1),
(26536, 37069, 0.69, 1, 1, 1, 1),
(26536, 37070, 0.69, 1, 1, 1, 1),
(26536, 45912, 0.1, 1, 1, 1, 1);

View file

@ -0,0 +1,3 @@
UPDATE creature_template SET faction = 14 WHERE faction != 35 and entry in (
35572,35569,35571,35570,35617,34705,34702,34701,34657,34703,35329,35328,35331,35330,
35332,35314,35326,35325,35323,35327,35119,35518,34928,35517,35309,35305,35307,35451,35004,35005,35545,35564,33628,36085,36090,36084,35517,35490,36089,35518,36091,36087,36086,36083,36082,36088,35310,35308,35546,35568,35306);

View file

@ -0,0 +1 @@
DELETE from spell_area where spell = 60815 and area = 14;

12
install.sh Executable file
View file

@ -0,0 +1,12 @@
#!/bin/bash
CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PATH_MODULES="$CUR_PATH/modules/"
[ ! -d $PATH_MODULES/udw/joiner ] && git clone https://github.com/udw/joiner $PATH_MODULES/udw/joiner -b master
source "$PATH_MODULES/udw/joiner/joiner.sh"
if [[ $1 == "dev" ]]; then
git submodule update --init "$CUR_PATH/data/doc"
fi

49
modules/dep/.gitignore vendored Normal file
View file

@ -0,0 +1,49 @@
!.gitignore
!*
#
#Generic
#
.directory
.mailmap
*.orig
*.rej
*~
.hg/
*.kdev*
.DS_Store
CMakeLists.txt.user
*.bak
*.patch
*.diff
*.REMOTE.*
*.BACKUP.*
*.BASE.*
*.LOCAL.*
#
# IDE & other softwares
#
/.settings/
/.externalToolBuilders/*
# exclude in all levels
nbproject/
.sync.ffs_db
#
# Eclipse
#
*.pydevproject
.metadata
.gradle
tmp/
*.tmp
*.swp
*~.nib
local.properties
.settings/
.loadpath
.project
.cproject

View file

@ -37,8 +37,8 @@ MACRO(AZTH_ADD_GLOBAL name val)
AZTH_GET_GLOBAL(${name})
set_property ( GLOBAL PROPERTY ${name}
${val}
${${name}}
${val}
)
# after set , create the variable for current scope
AZTH_GET_GLOBAL(${name})
@ -68,6 +68,21 @@ MACRO(AZTH_SET_PATH name val)
AZTH_ADD_INC_PATH(${val})
ENDMACRO()
#
# AZTH_ADD_SCRIPTS
#
MACRO(AZTH_ADD_SCRIPTS script_def include)
AZTH_ADD_GLOBAL("AZTH_ADD_SCRIPTS_LIST" "Add${script_def}Scripts()\;")
if (NOT ${include} STREQUAL "")
AZTH_GET_GLOBAL("AZTH_ADD_SCRIPTS_INCLUDE")
if (NOT ";${AZTH_ADD_SCRIPTS_INCLUDE};" MATCHES ";${include};")
AZTH_ADD_GLOBAL("AZTH_ADD_SCRIPTS_INCLUDE" "${include}\;")
endif()
endif()
ENDMACRO()
#
# AZTH_ADD_INC_PATH
#

View file

@ -108,3 +108,5 @@ endif()
if (USE_COREPCH)
add_cxx_pch(authserver ${authserver_PCH_HDR} ${authserver_PCH_SRC})
endif()
RUN_HOOK("AFTER_AUTHSERVER_CMAKE")

View file

@ -104,7 +104,15 @@ extern int main(int argc, char** argv)
++count;
}
if (!sConfigMgr->LoadInitial(configFile))
std::string cfg_def_file=_TRINITY_REALM_CONFIG;
cfg_def_file += ".dist";
if (!sConfigMgr->LoadInitial(cfg_def_file.c_str())) {
printf("Invalid or missing default configuration file : %s\n", cfg_def_file.c_str());
return 1;
}
if (!sConfigMgr->LoadMore(configFile))
{
printf("Invalid or missing configuration file : %s\n", configFile);
printf("Verify that the file exists and has \'[authserver]\' written in the top of the file!\n");

View file

@ -492,16 +492,18 @@ void PetAI::HandleReturnMovement()
{
if (!me->GetCharmInfo()->IsAtStay() && !me->GetCharmInfo()->IsReturning())
{
// Return to previous position where stay was clicked
if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) == NULL_MOTION_TYPE)
if (me->GetCharmInfo()->HasStayPosition())
{
float x, y, z;
me->GetCharmInfo()->GetStayPosition(x, y, z);
ClearCharmInfoFlags();
me->GetCharmInfo()->SetIsReturning(true);
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MovePoint(me->GetGUIDLow(), x, y, z);
// Return to previous position where stay was clicked
if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) == NULL_MOTION_TYPE)
{
float x, y, z;
me->GetCharmInfo()->GetStayPosition(x, y, z);
ClearCharmInfoFlags();
me->GetCharmInfo()->SetIsReturning(true);
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MovePoint(me->GetUInt32Value(OBJECT_FIELD_GUID), x, y, z);
}
}
}
}

View file

@ -1196,7 +1196,7 @@ class SmartTrigger : public AreaTriggerScript
}
};
void AddSC_SmartSCripts()
void AddSC_SmartScripts()
{
new SmartTrigger();
}

View file

@ -201,15 +201,13 @@ bool BattlefieldWG::Update(uint32 diff)
else
m_saveTimer -= diff;
// Update Tenacity
// Update Tenacity every 2,5 sec.
if (IsWarTime())
{
if (m_tenacityUpdateTimer <= diff)
{
m_tenacityUpdateTimer = 10000;
if (!m_updateTenacityList.empty())
UpdateTenacity();
m_updateTenacityList.clear();
m_tenacityUpdateTimer = 2500;
UpdateTenacity();
}
else
m_tenacityUpdateTimer -= diff;
@ -1087,42 +1085,7 @@ void BattlefieldWG::UpdateTenacity()
newStack = int32((1.0f - ((float)alliancePlayers / hordePlayers)) * 4.0f); // negative, should cast on horde
}
// Return if no change in stack and apply tenacity to new player
if (newStack == m_tenacityStack)
{
for (GuidSet::const_iterator itr = m_updateTenacityList.begin(); itr != m_updateTenacityList.end(); ++itr)
if (Player* newPlayer = ObjectAccessor::FindPlayer(*itr))
if ((newPlayer->GetTeamId() == TEAM_ALLIANCE && m_tenacityStack > 0) || (newPlayer->GetTeamId() == TEAM_HORDE && m_tenacityStack < 0))
{
newStack = std::min(abs(newStack), 20);
uint32 buff_honor = GetHonorBuff(newStack);
newPlayer->SetAuraStack(SPELL_TENACITY, newPlayer, newStack);
if (buff_honor)
newPlayer->CastSpell(newPlayer, buff_honor, true);
}
return;
}
if (m_tenacityStack != 0)
{
if (m_tenacityStack > 0 && newStack <= 0) // old buff was on alliance
team = TEAM_ALLIANCE;
else if (m_tenacityStack < 0 && newStack >= 0) // old buff was on horde
team = TEAM_HORDE;
}
m_tenacityStack = newStack;
// Remove old buff
if (team != TEAM_NEUTRAL)
{
for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr)
if (Player* player = ObjectAccessor::FindPlayer(*itr))
player->RemoveAurasDueToSpell(SPELL_TENACITY);
for (GuidSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr)
if (Unit* unit = ObjectAccessor::FindUnit(*itr))
unit->RemoveAurasDueToSpell(SPELL_TENACITY_VEHICLE);
}
// new way to check: always add stacks if they exist, to every one in the game
// Apply new buff
if (newStack)
@ -1147,6 +1110,28 @@ void BattlefieldWG::UpdateTenacity()
unit->CastSpell(unit, buff_honor, true);
}
}
if (m_tenacityStack != 0)
{
if (m_tenacityStack > 0 && newStack <= 0) // old buff was on alliance
team = TEAM_ALLIANCE;
else if (m_tenacityStack < 0 && newStack >= 0) // old buff was on horde
team = TEAM_HORDE;
}
// Remove old buff
if (team != TEAM_NEUTRAL)
{
for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr)
if (Player* player = ObjectAccessor::FindPlayer(*itr))
player->RemoveAurasDueToSpell(SPELL_TENACITY);
for (GuidSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr)
if (Unit* unit = ObjectAccessor::FindUnit(*itr))
unit->RemoveAurasDueToSpell(SPELL_TENACITY_VEHICLE);
}
m_tenacityStack = newStack; // Assign new tenacity value
}
WintergraspCapturePoint::WintergraspCapturePoint(BattlefieldWG* battlefield, TeamId teamInControl) : BfCapturePoint(battlefield)

View file

@ -665,17 +665,48 @@ void Battleground::RewardHonorToTeam(uint32 honor, TeamId teamId)
void Battleground::RewardReputationToTeam(uint32 factionId, uint32 reputation, TeamId teamId)
{
if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId))
for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
if (itr->second->GetBgTeamId() == teamId)
{
uint32 realFactionId = GetRealRepFactionForPlayer(factionId, itr->second);
uint32 repGain = reputation;
AddPct(repGain, itr->second->GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN));
AddPct(repGain, itr->second->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, factionId));
itr->second->GetReputationMgr().ModifyReputation(factionEntry, repGain);
AddPct(repGain, itr->second->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, realFactionId));
if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(realFactionId))
itr->second->GetReputationMgr().ModifyReputation(factionEntry, repGain);
}
}
uint32 Battleground::GetRealRepFactionForPlayer(uint32 factionId, Player* player)
{
if (player)
{
// if the bg team is not the original team, reverse reputation
if (player->GetBgTeamId() != player->GetTeamId(true))
{
switch (factionId)
{
case BG_REP_AB_ALLIANCE:
return BG_REP_AB_HORDE;
case BG_REP_AB_HORDE:
return BG_REP_AB_ALLIANCE;
case BG_REP_AV_ALLIANCE:
return BG_REP_AV_HORDE;
case BG_REP_AV_HORDE:
return BG_REP_AV_ALLIANCE;
case BG_REP_WS_ALLIANCE:
return BG_REP_WS_HORDE;
case BG_REP_WS_HORDE:
return BG_REP_WS_ALLIANCE;
}
}
}
return factionId;
}
void Battleground::UpdateWorldState(uint32 Field, uint32 Value)
{
WorldPacket data;

View file

@ -116,6 +116,16 @@ enum BattlegroundSpells
SPELL_THE_LAST_STANDING = 26549, // Arena achievement related
};
enum BattlegroundReputations
{
BG_REP_AV_HORDE = 729,
BG_REP_AV_ALLIANCE = 730,
BG_REP_AB_HORDE = 510,
BG_REP_AB_ALLIANCE = 509,
BG_REP_WS_HORDE = 889,
BG_REP_WS_ALLIANCE = 890,
};
enum BattlegroundTimeIntervals
{
CHECK_PLAYER_POSITION_INVERVAL = 9000, // ms
@ -453,6 +463,7 @@ class Battleground
void RemoveAuraOnTeam(uint32 spellId, TeamId teamId);
void RewardHonorToTeam(uint32 honor, TeamId teamId);
void RewardReputationToTeam(uint32 factionId, uint32 reputation, TeamId teamId);
uint32 GetRealRepFactionForPlayer(uint32 factionId, Player* player);
void UpdateWorldState(uint32 Field, uint32 Value);
void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player* player);

View file

@ -205,6 +205,7 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/World
${CMAKE_CURRENT_SOURCE_DIR}/ArenaSpectator
${CMAKE_CURRENT_SOURCE_DIR}/Misc
${CMAKE_SOURCE_DIR}/src/server/scripts/
${CMAKE_SOURCE_DIR}/src/server/scripts/PrecompiledHeaders
${ACE_INCLUDE_DIR}
${MYSQL_INCLUDE_DIR}

View file

@ -40,7 +40,7 @@
Pet::Pet(Player* owner, PetType type) : Guardian(NULL, owner ? owner->GetGUID() : 0, true),
m_usedTalentCount(0), m_removed(false), m_owner(owner),
m_happinessTimer(PET_LOSE_HAPPINES_INTERVAL), m_petRegenTimer(PET_FOCUS_REGEN_INTERVAL), m_petType(type), m_duration(0),
m_auraRaidUpdateMask(0), m_loading(false), m_declinedname(NULL), asynchLoadType(PET_LOAD_DEFAULT)
m_auraRaidUpdateMask(0), m_loading(false), m_declinedname(NULL), m_tempspell(0), m_tempspellTarget(NULL), m_tempoldTarget(NULL), m_tempspellIsPositive(false), asynchLoadType(PET_LOAD_DEFAULT)
{
m_unitTypeMask |= UNIT_MASK_PET;
if (type == HUNTER_PET)
@ -384,6 +384,115 @@ void Pet::Update(uint32 diff)
}
}
if (m_tempspell != 0)
{
Unit* tempspellTarget = m_tempspellTarget;
Unit* tempoldTarget = m_tempoldTarget;
bool tempspellIsPositive = m_tempspellIsPositive;
uint32 tempspell = m_tempspell;
Unit* charmer = GetCharmerOrOwner();
if (!charmer)
return;
if (!GetCharmInfo())
return;
if (tempspellTarget && tempspellTarget->IsAlive())
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(tempspell);
if (!spellInfo)
return;
float max_range = GetSpellMaxRangeForTarget(tempspellTarget, spellInfo);
if (IsWithinLOSInMap(tempspellTarget) && GetDistance(tempspellTarget) < max_range)
{
if (tempspellTarget && !GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo) && !HasSpellCooldown(tempspell))
{
StopMoving();
GetMotionMaster()->Clear(false);
GetMotionMaster()->MoveIdle();
GetCharmInfo()->SetIsCommandAttack(false);
GetCharmInfo()->SetIsAtStay(true);
GetCharmInfo()->SetIsCommandFollow(false);
GetCharmInfo()->SetIsFollowing(false);
GetCharmInfo()->SetIsReturning(false);
GetCharmInfo()->SaveStayPosition(true);
CastSpell(tempspellTarget, tempspell, true);
m_tempspell = 0;
m_tempspellTarget = NULL;
if (tempspellIsPositive)
{
if (tempoldTarget && tempoldTarget->IsAlive())
{
GetCharmInfo()->SetIsCommandAttack(true);
GetCharmInfo()->SetIsAtStay(false);
GetCharmInfo()->SetIsFollowing(false);
GetCharmInfo()->SetIsCommandFollow(false);
GetCharmInfo()->SetIsReturning(false);
if (ToCreature() && ToCreature()->IsAIEnabled)
ToCreature()->AI()->AttackStart(tempoldTarget);
}
else
{
GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
GetCharmInfo()->SetIsCommandAttack(false);
GetCharmInfo()->SetIsAtStay(false);
GetCharmInfo()->SetIsReturning(true);
GetCharmInfo()->SetIsCommandFollow(true);
GetCharmInfo()->SetIsFollowing(false);
GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, GetFollowAngle());
}
m_tempoldTarget = NULL;
m_tempspellIsPositive = false;
}
}
}
}
else
{
m_tempspell = 0;
m_tempspellTarget = NULL;
m_tempoldTarget = NULL;
m_tempspellIsPositive = false;
Unit* victim = charmer->GetVictim();
if (victim && victim->IsAlive())
{
StopMoving();
GetMotionMaster()->Clear(false);
GetMotionMaster()->MoveIdle();
GetCharmInfo()->SetIsCommandAttack(true);
GetCharmInfo()->SetIsAtStay(false);
GetCharmInfo()->SetIsFollowing(false);
GetCharmInfo()->SetIsCommandFollow(false);
GetCharmInfo()->SetIsReturning(false);
if (ToCreature() && ToCreature()->IsAIEnabled)
ToCreature()->AI()->AttackStart(victim);
}
else
{
StopMoving();
GetMotionMaster()->Clear(false);
GetMotionMaster()->MoveIdle();
GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
GetCharmInfo()->SetIsCommandAttack(false);
GetCharmInfo()->SetIsAtStay(false);
GetCharmInfo()->SetIsReturning(true);
GetCharmInfo()->SetIsCommandFollow(true);
GetCharmInfo()->SetIsFollowing(false);
GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, GetFollowAngle());
}
}
}
if (getPetType() == HUNTER_PET)
{
m_happinessTimer -= diff;
@ -2103,3 +2212,44 @@ void Pet::SetDisplayId(uint32 modelId)
if (player->GetGroup())
player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID);
}
void Pet::CastWhenWillAvailable(uint32 spellid, Unit* spellTarget, Unit* oldTarget, bool spellIsPositive)
{
if (!spellid)
return;
if (!spellTarget)
return;
m_tempspellTarget = spellTarget;
m_tempspell = spellid;
m_tempspellIsPositive = spellIsPositive;
if (oldTarget)
m_tempoldTarget = oldTarget;
}
void Pet::ClearCastWhenWillAvailable()
{
m_tempspellIsPositive = false;
m_tempspell = 0;
m_tempspellTarget = NULL;
m_tempoldTarget = NULL;
}
void Pet::RemoveSpellCooldown(uint32 spell_id, bool update /* = false */)
{
m_CreatureSpellCooldowns.erase(spell_id);
if (update)
{
if (Player* playerOwner = GetCharmerOrOwnerPlayerOrPlayerItself())
{
WorldPacket data(SMSG_CLEAR_COOLDOWN, 4 + 8);
data << uint32(spell_id);
data << uint64(GetGUID());
playerOwner->SendDirectMessage(&data);
}
}
}

View file

@ -120,6 +120,10 @@ class Pet : public Guardian
void LearnPetPassives();
void CastPetAuras(bool current);
void CastWhenWillAvailable(uint32 spellid, Unit* spellTarget, Unit* oldTarget, bool spellIsPositive = false);
void ClearCastWhenWillAvailable();
void RemoveSpellCooldown(uint32 spell_id, bool update /* = false */);
void _SaveSpellCooldowns(SQLTransaction& trans, bool logout);
void _SaveAuras(SQLTransaction& trans, bool logout);
void _SaveSpells(SQLTransaction& trans);
@ -175,6 +179,12 @@ class Pet : public Guardian
int32 m_petRegenTimer; // xinef: used for focus regeneration
DeclinedName *m_declinedname;
Unit* m_tempspellTarget;
Unit* m_tempoldTarget;
bool m_tempspellIsPositive;
uint32 m_tempspell;
uint8 asynchLoadType;
private:

View file

@ -84,6 +84,7 @@
#include "GameObjectAI.h"
#include "PoolMgr.h"
#include "SavingSystem.h"
#include "TicketMgr.h"
#define ZONE_UPDATE_INTERVAL (2*IN_MILLISECONDS)
@ -678,6 +679,7 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this)
#pragma warning(default:4355)
#endif
m_drwGUID = 0;
m_speakTime = 0;
m_speakCount = 0;
@ -1114,7 +1116,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)
GetReputationMgr().SetReputation(sFactionStore.LookupEntry(1077), 42999);
// Factions depending on team, like cities and some more stuff
switch (GetTeamId())
switch (GetTeamId(true))
{
case TEAM_ALLIANCE:
GetReputationMgr().SetReputation(sFactionStore.LookupEntry(72), 42999);
@ -4729,6 +4731,11 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
// remove from arena teams
LeaveAllArenaTeams(playerguid);
// close player ticket if any
GmTicket* ticket = sTicketMgr->GetTicketByPlayer(playerguid);
if (ticket)
ticket->SetClosedBy(playerguid);
// remove from group
if (uint32 groupId = GetGroupIdFromStorage(guid))
if (Group* group = sGroupMgr->GetGroupByGUID(groupId))
@ -4923,9 +4930,18 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
stmt->setUInt32(0, guid);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_GM_TICKETS);
stmt->setUInt32(0, guid);
trans->Append(stmt);
if (sWorld->getBoolConfig(CONFIG_DELETE_CHARACTER_TICKET_TRACE))
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PLAYER_GM_TICKETS_ON_CHAR_DELETION);
stmt->setUInt32(0, guid);
trans->Append(stmt);
}
else
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_GM_TICKETS);
stmt->setUInt32(0, guid);
trans->Append(stmt);
}
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_BY_OWNER);
stmt->setUInt32(0, guid);
@ -7045,7 +7061,7 @@ void Player::RewardReputation(Unit* victim, float rate)
ChampioningFaction = GetChampioningFaction();
}
TeamId teamId = GetTeamId();
TeamId teamId = GetTeamId(true); // Always check player original reputation when rewarding
if (Rep->RepFaction1 && (!Rep->TeamDependent || teamId == TEAM_ALLIANCE))
{
@ -7168,12 +7184,13 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool awar
if (HasAura(SPELL_AURA_PLAYER_INACTIVE))
return false;
// check if player has same IP
/* check if player has same IP
if (uVictim && uVictim->GetTypeId() == TYPEID_PLAYER)
{
if (GetSession()->GetRemoteAddress() == uVictim->ToPlayer()->GetSession()->GetRemoteAddress())
return false;
}
*/
uint64 victim_guid = 0;
uint32 victim_rank = 0;
@ -7216,7 +7233,7 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool awar
// [29..38] Other title and player name
// [39+] Nothing
uint32 victim_title = victim->GetUInt32Value(PLAYER_CHOSEN_TITLE);
// Get Killer titles, CharTitlesEntry::bit_index
// Get Killer titles, CharTitlesEntry::bit_index
// Ranks:
// title[1..14] -> rank[5..18]
// title[15..28] -> rank[5..18]
@ -7471,12 +7488,12 @@ void Player::UpdateArea(uint32 newArea)
AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone);
uint32 areaFlags = area->flags;
bool isSanctuary = area->IsSanctuary();
bool isInn = area->IsInn(GetTeamId());
bool isInn = area->IsInn(GetTeamId(true));
if (zone)
{
areaFlags |= zone->flags;
isSanctuary |= zone->IsSanctuary();
isInn |= zone->IsInn(GetTeamId());
isInn |= zone->IsInn(GetTeamId(true));
}
// previously this was in UpdateZone (but after UpdateArea) so nothing will break
@ -7576,10 +7593,10 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
switch (zone->team)
{
case AREATEAM_ALLY:
pvpInfo.IsInHostileArea = GetTeamId() != TEAM_ALLIANCE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL);
pvpInfo.IsInHostileArea = GetTeamId(true) != TEAM_ALLIANCE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL);
break;
case AREATEAM_HORDE:
pvpInfo.IsInHostileArea = GetTeamId() != TEAM_HORDE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL);
pvpInfo.IsInHostileArea = GetTeamId(true) != TEAM_HORDE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL);
break;
case AREATEAM_NONE:
// overwrite for battlegrounds, maybe batter some zone flags but current known not 100% fit to this
@ -17568,7 +17585,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
else if (!taxi_nodes.empty())
{
instanceId = 0;
if (!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes, GetTeamId()))
if (!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes, GetTeamId(true)))
{
// xinef: could no load valid data for taxi, relocate to homebind and clear
m_taxi.ClearTaxiDestinations();
@ -19030,9 +19047,9 @@ bool Player::Satisfy(AccessRequirement const* ar, uint32 target_map, bool report
}
uint32 missingQuest = 0;
if (GetTeamId() == TEAM_ALLIANCE && ar->quest_A && !GetQuestRewardStatus(ar->quest_A))
if (GetTeamId(true) == TEAM_ALLIANCE && ar->quest_A && !GetQuestRewardStatus(ar->quest_A))
missingQuest = ar->quest_A;
else if (GetTeamId() == TEAM_HORDE && ar->quest_H && !GetQuestRewardStatus(ar->quest_H))
else if (GetTeamId(true) == TEAM_HORDE && ar->quest_H && !GetQuestRewardStatus(ar->quest_H))
missingQuest = ar->quest_H;
uint32 missingAchievement = 0;
@ -21196,7 +21213,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
// only one mount ID for both sides. Probably not good to use 315 in case DBC nodes
// change but I couldn't find a suitable alternative. OK to use class because only DK
// can use this taxi.
uint32 mount_display_id = sObjectMgr->GetTaxiMountDisplayId(sourcenode, GetTeamId(), npc == NULL || (sourcenode == 315 && getClass() == CLASS_DEATH_KNIGHT));
uint32 mount_display_id = sObjectMgr->GetTaxiMountDisplayId(sourcenode, GetTeamId(true), npc == NULL || (sourcenode == 315 && getClass() == CLASS_DEATH_KNIGHT));
// in spell case allow 0 model
if ((mount_display_id == 0 && spellid == 0) || sourcepath == 0)
@ -21273,7 +21290,7 @@ void Player::ContinueTaxiFlight()
;//sLog->outDebug(LOG_FILTER_UNITS, "WORLD: Restart character %u taxi flight", GetGUIDLow());
uint32 mountDisplayId = sObjectMgr->GetTaxiMountDisplayId(sourceNode, GetTeamId(), true);
uint32 mountDisplayId = sObjectMgr->GetTaxiMountDisplayId(sourceNode, GetTeamId(true), true);
if (!mountDisplayId)
return;
@ -21514,7 +21531,7 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32
return false;
}
if (!IsGameMaster() && ((pProto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && GetTeamId() == TEAM_ALLIANCE) || (pProto->Flags2 == ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && GetTeamId() == TEAM_HORDE)))
if (!IsGameMaster() && ((pProto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && GetTeamId(true) == TEAM_ALLIANCE) || (pProto->Flags2 == ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && GetTeamId(true) == TEAM_HORDE)))
return false;
Creature* creature = GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR);

View file

@ -2074,7 +2074,7 @@ class Player : public Unit, public GridObject<Player>
void CheckAreaExploreAndOutdoor(void);
static TeamId TeamIdForRace(uint8 race);
TeamId GetTeamId() const { return m_team; }
TeamId GetTeamId(bool original = false) const { return original ? TeamIdForRace(getRace()) : m_team; };
void setFactionForRace(uint8 race);
void InitDisplayIds();
@ -2573,6 +2573,11 @@ class Player : public Unit, public GridObject<Player>
uint32 m_pendingSpectatorInviteInstanceId;
std::set<uint32> m_receivedSpectatorResetFor;
// Dancing Rune weapon
void setRuneWeaponGUID(uint64 guid) { m_drwGUID = guid; };
uint64 getRuneWeaponGUID() { return m_drwGUID; };
uint64 m_drwGUID;
bool CanSeeDKPet() const { return m_ExtraFlags & PLAYER_EXTRA_SHOW_DK_PET; }
void SetShowDKPet(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_SHOW_DK_PET; else m_ExtraFlags &= ~PLAYER_EXTRA_SHOW_DK_PET; };
void PrepareCharmAISpells();

View file

@ -2749,7 +2749,7 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spell)
int32 tmp = 10000 - HitChance;
int32 rand = irand(0, 10000);
int32 rand = irand(1, 10000); // Needs to be 1 to 10000 to avoid the 1/10000 chance to miss on 100% hit rating
if (rand < tmp)
return SPELL_MISS_MISS;
@ -5047,6 +5047,11 @@ uint32 Unit::GetDiseasesByCaster(uint64 casterGUID, uint8 mode)
SPELL_AURA_NONE
};
uint64 drwGUID = 0;
if (Player* playerCaster = ObjectAccessor::GetPlayer(*this, casterGUID))
drwGUID = playerCaster->getRuneWeaponGUID();
uint32 diseases = 0;
for (uint8 index = 0; diseaseAuraTypes[index] != SPELL_AURA_NONE; ++index)
{
@ -5054,7 +5059,7 @@ uint32 Unit::GetDiseasesByCaster(uint64 casterGUID, uint8 mode)
{
// Get auras with disease dispel type by caster
if ((*i)->GetSpellInfo()->Dispel == DISPEL_DISEASE
&& (*i)->GetCasterGUID() == casterGUID)
&& ((*i)->GetCasterGUID() == casterGUID || (*i)->GetCasterGUID() == drwGUID)) // if its caster or his dancing rune weapon
{
++diseases;
@ -18618,6 +18623,18 @@ void CharmInfo::GetStayPosition(float &x, float &y, float &z)
z = _stayZ;
}
void CharmInfo::RemoveStayPosition()
{
_stayX = 0.0f;
_stayY = 0.0f;
_stayZ = 0.0f;
}
bool CharmInfo::HasStayPosition()
{
return _stayX && _stayY && _stayZ;
}
void CharmInfo::SetIsAtStay(bool val)
{
_isAtStay = val;

View file

@ -1224,6 +1224,8 @@ struct CharmInfo
bool IsReturning();
void SaveStayPosition(bool atCurrentPos);
void GetStayPosition(float &x, float &y, float &z);
void RemoveStayPosition();
bool HasStayPosition();
void SetForcedSpell(uint32 id) { _forcedSpellId = id; }
int32 GetForcedSpell() { return _forcedSpellId; }

View file

@ -2006,7 +2006,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
if (recvData.GetOpcode() == CMSG_CHAR_FACTION_CHANGE)
{
// if player is in a guild
if (playerData->guildId)
if (playerData->guildId && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
{
WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1);
data << (uint8)CHAR_CREATE_CHARACTER_IN_GUILD;

View file

@ -507,6 +507,9 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid
charmInfo->SetIsReturning(false);
charmInfo->SetIsAtStay(!controlledMotion);
charmInfo->SaveStayPosition(controlledMotion);
if (pet->ToPet())
pet->ToPet()->ClearCastWhenWillAvailable();
charmInfo->SetForcedSpell(0);
charmInfo->SetForcedTargetGUID(0);
@ -518,6 +521,8 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid
pet->InterruptNonMeleeSpells(false);
pet->ClearInPetCombat();
pet->GetMotionMaster()->MoveFollow(_player, PET_FOLLOW_DIST, pet->GetFollowAngle());
if (pet->ToPet())
pet->ToPet()->ClearCastWhenWillAvailable();
charmInfo->SetCommandState(COMMAND_FOLLOW);
charmInfo->SetIsCommandAttack(false);
@ -525,7 +530,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid
charmInfo->SetIsReturning(true);
charmInfo->SetIsCommandFollow(true);
charmInfo->SetIsFollowing(false);
charmInfo->RemoveStayPosition();
charmInfo->SetForcedSpell(0);
charmInfo->SetForcedTargetGUID(0);
break;
@ -641,6 +646,8 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid
{
case REACT_PASSIVE: //passive
pet->AttackStop();
if (pet->ToPet())
pet->ToPet()->ClearCastWhenWillAvailable();
pet->ClearInPetCombat();
case REACT_DEFENSIVE: //recovery
@ -658,9 +665,6 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid
{
Unit* unit_target = NULL;
if (guid2)
unit_target = ObjectAccessor::GetUnit(*_player, guid2);
// do not cast unknown spells
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid);
if (!spellInfo)
@ -669,6 +673,11 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid
return;
}
if (guid2)
unit_target = ObjectAccessor::GetUnit(*_player, guid2);
else if (!spellInfo->IsPositive())
return;
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if (spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY || spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY || spellInfo->Effects[i].TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY)
@ -743,6 +752,131 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid
charmInfo->SetForcedSpell(0);
charmInfo->SetForcedTargetGUID(0);
}
else if (pet->ToPet() && (result == SPELL_FAILED_LINE_OF_SIGHT || result == SPELL_FAILED_OUT_OF_RANGE))
{
unit_target = spell->m_targets.GetUnitTarget();
bool haspositiveeffect = false;
if (!unit_target)
return;
// search positive effects for spell
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if (spellInfo->_IsPositiveEffect(i, true))
{
haspositiveeffect = true;
break;
}
}
if (pet->isPossessed() || pet->IsVehicle())
Spell::SendCastResult(GetPlayer(), spellInfo, 0, result);
else if (GetPlayer()->IsFriendlyTo(unit_target) && !haspositiveeffect)
spell->SendPetCastResult(SPELL_FAILED_TARGET_FRIENDLY);
else
spell->SendPetCastResult(SPELL_FAILED_DONT_REPORT);
if (!pet->HasSpellCooldown(spellid))
if(pet->ToPet())
pet->ToPet()->RemoveSpellCooldown(spellid, true);
spell->finish(false);
delete spell;
if (_player->HasAuraType(SPELL_AURA_MOD_PACIFY))
return;
bool tempspellIsPositive = false;
if (!GetPlayer()->IsFriendlyTo(unit_target))
{
// only place where pet can be player
Unit* TargetUnit = ObjectAccessor::GetUnit(*_player, guid2);
if (!TargetUnit)
return;
if (Unit* owner = pet->GetOwner())
if (!owner->IsValidAttackTarget(TargetUnit))
return;
pet->ClearUnitState(UNIT_STATE_FOLLOW);
// This is true if pet has no target or has target but targets differs.
if (pet->GetVictim() != TargetUnit || (pet->GetVictim() == TargetUnit && !pet->GetCharmInfo()->IsCommandAttack()))
{
if (pet->GetVictim())
pet->AttackStop();
if (pet->GetTypeId() != TYPEID_PLAYER && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
{
charmInfo->SetIsCommandAttack(true);
charmInfo->SetIsAtStay(false);
charmInfo->SetIsFollowing(false);
charmInfo->SetIsCommandFollow(false);
charmInfo->SetIsReturning(false);
pet->ToCreature()->AI()->AttackStart(TargetUnit);
if (pet->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10)
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
else
pet->SendPetAIReaction(guid1);
}
else // charmed player
{
if (pet->GetVictim() && pet->GetVictim() != TargetUnit)
pet->AttackStop();
charmInfo->SetIsCommandAttack(true);
charmInfo->SetIsAtStay(false);
charmInfo->SetIsFollowing(false);
charmInfo->SetIsCommandFollow(false);
charmInfo->SetIsReturning(false);
pet->Attack(TargetUnit, true);
pet->SendPetAIReaction(guid1);
}
pet->ToPet()->CastWhenWillAvailable(spellid, unit_target, NULL, tempspellIsPositive);
}
}
else if (haspositiveeffect)
{
bool tempspellIsPositive = true;
pet->ClearUnitState(UNIT_STATE_FOLLOW);
// This is true if pet has no target or has target but targets differs.
Unit* victim = pet->GetVictim();
if (victim)
{
pet->AttackStop();
}
else
victim = NULL;
if (pet->GetTypeId() != TYPEID_PLAYER && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
{
pet->StopMoving();
pet->GetMotionMaster()->Clear();
charmInfo->SetIsCommandAttack(false);
charmInfo->SetIsAtStay(false);
charmInfo->SetIsFollowing(false);
charmInfo->SetIsCommandFollow(false);
charmInfo->SetIsReturning(false);
pet->GetMotionMaster()->MoveChase(unit_target);
if (pet->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != unit_target && urand(0, 100) < 10)
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
else
{
pet->SendPetAIReaction(guid1);
}
pet->ToPet()->CastWhenWillAvailable(spellid, unit_target, victim, tempspellIsPositive);
}
}
}
else
{
// dont spam alerts

View file

@ -35,6 +35,7 @@ struct MapEntry;
class Player;
class Group;
class InstanceSaveManager;
class InstanceSave;
struct InstancePlayerBind
{

View file

@ -2682,10 +2682,12 @@ void InstanceMap::PermBindAllPlayers()
{
player = itr->GetSource();
group = player->GetGroup();
// players inside an instance cannot be bound to other instances
// some players may already be permanently bound, in this case nothing happens
InstancePlayerBind* bind = sInstanceSaveMgr->PlayerGetBoundInstance(player->GetGUIDLow(), save->GetMapId(), save->GetDifficulty());
if ((!group || !group->isLFGGroup() || !group->IsLfgRandomInstance()) && (!bind || !bind->perm))
if (!bind || !bind->perm)
{
WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
data << uint32(0);

View file

@ -160,27 +160,33 @@ namespace Trinity
inline uint32 Gain(Player* player, Unit* u)
{
uint32 gain;
Creature* creature = u->ToCreature();
uint32 gain = 0;
if (u->GetTypeId() == TYPEID_UNIT &&
(((Creature*)u)->IsTotem() || ((Creature*)u)->IsPet() ||
(((Creature*)u)->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL) ||
u->IsCritter()))
gain = 0;
else
if (!creature || (!creature->IsTotem() && !creature->IsPet() && !creature->IsCritter() &&
!(creature->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL)))
{
float xpMod = 1.0f;
gain = BaseGain(player->getLevel(), u->getLevel(), GetContentLevelsForMapAndZone(u->GetMapId(), u->GetZoneId()));
if (gain != 0 && u->GetTypeId() == TYPEID_UNIT && ((Creature*)u)->isElite())
if (gain && creature)
{
// Elites in instances have a 2.75x XP bonus instead of the regular 2x world bonus.
if (u->GetMap()->IsDungeon())
gain = uint32(gain * 2.75);
else
gain *= 2;
if (creature->isElite())
{
// Elites in instances have a 2.75x XP bonus instead of the regular 2x world bonus.
if (u->GetMap() && u->GetMap()->IsDungeon())
xpMod *= 2.75f;
else
xpMod *= 2.0f;
}
// This requires TrinityCore creature_template.ExperienceModifier feature
// xpMod *= creature->GetCreatureTemplate()->ModExperience;
}
gain = uint32(gain * sWorld->getRate(RATE_XP_KILL));
xpMod *= isBattleGround ? sWorld->getRate(RATE_XP_BG_KILL) : sWorld->getRate(RATE_XP_KILL);
gain = uint32(gain * xpMod);
}
//sScriptMgr->OnGainCalculation(gain, player, u); // pussywizard: optimization

View file

@ -163,6 +163,7 @@ class ScriptRegistry
ScriptMgr::ScriptMgr()
: _scriptCount(0), _scheduledScripts(0)
{
}
ScriptMgr::~ScriptMgr()
@ -171,18 +172,8 @@ ScriptMgr::~ScriptMgr()
void ScriptMgr::Initialize()
{
uint32 oldMSTime = getMSTime();
LoadDatabase();
sLog->outString("Loading C++ scripts");
FillSpellSummary();
AddScripts();
CheckIfScriptsInDatabaseExist();
sLog->outString(">> Loaded %u C++ scripts in %u ms", GetScriptCount(), GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
sLog->outString("Loading C++ scripts");
}
void ScriptMgr::Unload()
@ -223,7 +214,32 @@ void ScriptMgr::Unload()
void ScriptMgr::LoadDatabase()
{
uint32 oldMSTime = getMSTime();
sScriptSystemMgr->LoadScriptWaypoints();
// Add all scripts that must be loaded after db/maps
ScriptRegistry<WorldMapScript>::AddALScripts();
ScriptRegistry<BattlegroundMapScript>::AddALScripts();
ScriptRegistry<InstanceMapScript>::AddALScripts();
ScriptRegistry<SpellScriptLoader>::AddALScripts();
ScriptRegistry<ItemScript>::AddALScripts();
ScriptRegistry<CreatureScript>::AddALScripts();
ScriptRegistry<GameObjectScript>::AddALScripts();
ScriptRegistry<AreaTriggerScript>::AddALScripts();
ScriptRegistry<BattlegroundScript>::AddALScripts();
ScriptRegistry<OutdoorPvPScript>::AddALScripts();
ScriptRegistry<WeatherScript>::AddALScripts();
ScriptRegistry<ConditionScript>::AddALScripts();
ScriptRegistry<TransportScript>::AddALScripts();
ScriptRegistry<AchievementCriteriaScript>::AddALScripts();
FillSpellSummary();
CheckIfScriptsInDatabaseExist();
sLog->outString(">> Loaded %u C++ scripts in %u ms", GetScriptCount(), GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
struct TSpellSummary
@ -232,6 +248,40 @@ struct TSpellSummary
uint8 Effects; // set of enum SelectEffect
} *SpellSummary;
void ScriptMgr::CheckIfScriptsInDatabaseExist()
{
ObjectMgr::ScriptNameContainer& sn = sObjectMgr->GetScriptNames();
for (ObjectMgr::ScriptNameContainer::iterator itr = sn.begin(); itr != sn.end(); ++itr)
if (uint32 sid = sObjectMgr->GetScriptId((*itr).c_str()))
{
if (!ScriptRegistry<SpellScriptLoader>::GetScriptById(sid) &&
!ScriptRegistry<ServerScript>::GetScriptById(sid) &&
!ScriptRegistry<WorldScript>::GetScriptById(sid) &&
!ScriptRegistry<FormulaScript>::GetScriptById(sid) &&
!ScriptRegistry<WorldMapScript>::GetScriptById(sid) &&
!ScriptRegistry<InstanceMapScript>::GetScriptById(sid) &&
!ScriptRegistry<BattlegroundMapScript>::GetScriptById(sid) &&
!ScriptRegistry<ItemScript>::GetScriptById(sid) &&
!ScriptRegistry<CreatureScript>::GetScriptById(sid) &&
!ScriptRegistry<GameObjectScript>::GetScriptById(sid) &&
!ScriptRegistry<AreaTriggerScript>::GetScriptById(sid) &&
!ScriptRegistry<BattlegroundScript>::GetScriptById(sid) &&
!ScriptRegistry<OutdoorPvPScript>::GetScriptById(sid) &&
!ScriptRegistry<CommandScript>::GetScriptById(sid) &&
!ScriptRegistry<WeatherScript>::GetScriptById(sid) &&
!ScriptRegistry<AuctionHouseScript>::GetScriptById(sid) &&
!ScriptRegistry<ConditionScript>::GetScriptById(sid) &&
!ScriptRegistry<VehicleScript>::GetScriptById(sid) &&
!ScriptRegistry<DynamicObjectScript>::GetScriptById(sid) &&
!ScriptRegistry<TransportScript>::GetScriptById(sid) &&
!ScriptRegistry<AchievementCriteriaScript>::GetScriptById(sid) &&
!ScriptRegistry<PlayerScript>::GetScriptById(sid) &&
!ScriptRegistry<GuildScript>::GetScriptById(sid) &&
!ScriptRegistry<GroupScript>::GetScriptById(sid))
sLog->outErrorDb("Script named '%s' is assigned in database, but has no code!", (*itr).c_str());
}
}
void ScriptMgr::FillSpellSummary()
{
SpellSummary = new TSpellSummary[sSpellMgr->GetSpellInfoStoreSize()];
@ -403,9 +453,14 @@ void ScriptMgr::OnOpenStateChange(bool open)
FOREACH_SCRIPT(WorldScript)->OnOpenStateChange(open);
}
void ScriptMgr::OnConfigLoad(bool reload)
void ScriptMgr::OnBeforeConfigLoad(bool reload)
{
FOREACH_SCRIPT(WorldScript)->OnConfigLoad(reload);
FOREACH_SCRIPT(WorldScript)->OnBeforeConfigLoad(reload);
}
void ScriptMgr::OnAfterConfigLoad(bool reload)
{
FOREACH_SCRIPT(WorldScript)->OnAfterConfigLoad(reload);
}
void ScriptMgr::OnMotdChange(std::string& newMotd)
@ -1292,27 +1347,18 @@ FormulaScript::FormulaScript(const char* name)
WorldMapScript::WorldMapScript(const char* name, uint32 mapId)
: ScriptObject(name), MapScript<Map>(mapId)
{
if (GetEntry() && !GetEntry()->IsWorldMap())
sLog->outError("WorldMapScript for map %u is invalid.", mapId);
ScriptRegistry<WorldMapScript>::AddScript(this);
}
InstanceMapScript::InstanceMapScript(const char* name, uint32 mapId)
: ScriptObject(name), MapScript<InstanceMap>(mapId)
{
if (GetEntry() && !GetEntry()->IsDungeon())
sLog->outError("InstanceMapScript for map %u is invalid.", mapId);
ScriptRegistry<InstanceMapScript>::AddScript(this);
}
BattlegroundMapScript::BattlegroundMapScript(const char* name, uint32 mapId)
: ScriptObject(name), MapScript<BattlegroundMap>(mapId)
{
if (GetEntry() && !GetEntry()->IsBattleground())
sLog->outError("BattlegroundMapScript for map %u is invalid.", mapId);
ScriptRegistry<BattlegroundMapScript>::AddScript(this);
}
@ -1420,6 +1466,7 @@ GroupScript::GroupScript(const char* name)
// Instantiate static members of ScriptRegistry.
template<class TScript> std::map<uint32, TScript*> ScriptRegistry<TScript>::ScriptPointerList;
template<class TScript> std::vector<TScript*> ScriptRegistry<TScript>::ALScripts;
template<class TScript> uint32 ScriptRegistry<TScript>::_scriptIdCounter = 0;
// Specialize for each script type class like so:

View file

@ -159,6 +159,8 @@ class ScriptObject
// Do not override this in scripts; it should be overridden by the various script type classes. It indicates
// whether or not this script type must be assigned in the database.
virtual bool IsDatabaseBound() const { return false; }
virtual bool isAfterLoadScript() const { return IsDatabaseBound(); }
virtual void checkValidity() { }
const std::string& GetName() const { return _name; }
@ -242,7 +244,10 @@ class WorldScript : public ScriptObject
virtual void OnOpenStateChange(bool /*open*/) { }
// Called after the world configuration is (re)loaded.
virtual void OnConfigLoad(bool /*reload*/) { }
virtual void OnAfterConfigLoad(bool /*reload*/) { }
// Called before the world configuration is (re)loaded.
virtual void OnBeforeConfigLoad(bool /*reload*/) { }
// Called before the message of the day is changed.
virtual void OnMotdChange(std::string& /*newMotd*/) { }
@ -296,17 +301,22 @@ class FormulaScript : public ScriptObject
template<class TMap> class MapScript : public UpdatableScript<TMap>
{
MapEntry const* _mapEntry;
uint32 _mapId;
protected:
MapScript(uint32 mapId)
: _mapEntry(sMapStore.LookupEntry(mapId))
: _mapId(mapId)
{
if (!_mapEntry)
sLog->outError("Invalid MapScript for %u; no such map ID.", mapId);
}
public:
void checkMap() {
_mapEntry = sMapStore.LookupEntry(_mapId);
if (!_mapEntry)
sLog->outError("Invalid MapScript for %u; no such map ID.", _mapId);
}
// Gets the MapEntry structure associated with this script. Can return NULL.
MapEntry const* GetEntry() { return _mapEntry; }
@ -338,6 +348,17 @@ class WorldMapScript : public ScriptObject, public MapScript<Map>
protected:
WorldMapScript(const char* name, uint32 mapId);
public:
bool isAfterLoadScript() const { return true; }
void checkValidity() {
checkMap();
if (GetEntry() && !GetEntry()->IsWorldMap())
sLog->outError("WorldMapScript for map %u is invalid.", GetEntry()->MapID);
}
};
class InstanceMapScript : public ScriptObject, public MapScript<InstanceMap>
@ -350,6 +371,13 @@ class InstanceMapScript : public ScriptObject, public MapScript<InstanceMap>
bool IsDatabaseBound() const { return true; }
void checkValidity() {
checkMap();
if (GetEntry() && !GetEntry()->IsDungeon())
sLog->outError("InstanceMapScript for map %u is invalid.", GetEntry()->MapID);
}
// Gets an InstanceScript object for this instance.
virtual InstanceScript* GetInstanceScript(InstanceMap* /*map*/) const { return NULL; }
};
@ -359,6 +387,17 @@ class BattlegroundMapScript : public ScriptObject, public MapScript<Battleground
protected:
BattlegroundMapScript(const char* name, uint32 mapId);
public:
bool isAfterLoadScript() const { return true; }
void checkValidity() {
checkMap();
if (GetEntry() && !GetEntry()->IsBattleground())
sLog->outError("BattlegroundMapScript for map %u is invalid.", GetEntry()->MapID);
}
};
class ItemScript : public ScriptObject
@ -799,6 +838,7 @@ class ScriptMgr
void Initialize();
void LoadDatabase();
void FillSpellSummary();
void CheckIfScriptsInDatabaseExist();
const char* ScriptsVersion() const { return "Integrated Trinity Scripts"; }
@ -825,7 +865,8 @@ class ScriptMgr
public: /* WorldScript */
void OnOpenStateChange(bool open);
void OnConfigLoad(bool reload);
void OnBeforeConfigLoad(bool reload);
void OnAfterConfigLoad(bool reload);
void OnMotdChange(std::string& newMotd);
void OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask);
void OnShutdownCancel();
@ -1023,78 +1064,95 @@ class ScriptRegistry
typedef std::map<uint32, TScript*> ScriptMap;
typedef typename ScriptMap::iterator ScriptMapIterator;
typedef std::vector<TScript*> ScriptVector;
typedef typename ScriptVector::iterator ScriptVectorIterator;
// The actual list of scripts. This will be accessed concurrently, so it must not be modified
// after server startup.
static ScriptMap ScriptPointerList;
// After database load scripts
static ScriptVector ALScripts;
static void AddScript(TScript* const script)
{
ASSERT(script);
// See if the script is using the same memory as another script. If this happens, it means that
// someone forgot to allocate new memory for a script.
for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
if (!_checkMemory(script))
return;
if (script->isAfterLoadScript())
{
if (it->second == script)
{
sLog->outError("Script '%s' has same memory pointer as '%s'.",
script->GetName().c_str(), it->second->GetName().c_str());
return;
}
}
if (script->IsDatabaseBound())
{
// Get an ID for the script. An ID only exists if it's a script that is assigned in the database
// through a script name (or similar).
uint32 id = sObjectMgr->GetScriptId(script->GetName().c_str());
if (id)
{
// Try to find an existing script.
bool existing = false;
for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
{
// If the script names match...
if (it->second->GetName() == script->GetName())
{
// ... It exists.
existing = true;
break;
}
}
// If the script isn't assigned -> assign it!
if (!existing)
{
ScriptPointerList[id] = script;
sScriptMgr->IncrementScriptCount();
}
else
{
// If the script is already assigned -> delete it!
sLog->outError("Script '%s' already assigned with the same script name, so the script can't work.",
script->GetName().c_str());
ASSERT(false); // Error that should be fixed ASAP.
}
}
else
{
// The script uses a script name from database, but isn't assigned to anything.
if (script->GetName().find("Smart") == std::string::npos)
sLog->outErrorDb("Script named '%s' does not have a script name assigned in database.",
script->GetName().c_str());
}
ALScripts.push_back(script);
}
else
{
script->checkValidity();
// We're dealing with a code-only script; just add it.
ScriptPointerList[_scriptIdCounter++] = script;
sScriptMgr->IncrementScriptCount();
}
}
static void AddALScripts() {
for(ScriptVectorIterator it = ALScripts.begin(); it != ALScripts.end(); ++it) {
TScript* const script = *it;
script->checkValidity();
if (script->IsDatabaseBound()) {
if (!_checkMemory(script))
return;
// Get an ID for the script. An ID only exists if it's a script that is assigned in the database
// through a script name (or similar).
uint32 id = sObjectMgr->GetScriptId(script->GetName().c_str());
if (id)
{
// Try to find an existing script.
bool existing = false;
for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
{
// If the script names match...
if (it->second->GetName() == script->GetName())
{
// ... It exists.
existing = true;
break;
}
}
// If the script isn't assigned -> assign it!
if (!existing)
{
ScriptPointerList[id] = script;
sScriptMgr->IncrementScriptCount();
}
else
{
// If the script is already assigned -> delete it!
sLog->outError("Script '%s' already assigned with the same script name, so the script can't work.",
script->GetName().c_str());
ASSERT(false); // Error that should be fixed ASAP.
}
}
else
{
// The script uses a script name from database, but isn't assigned to anything.
if (script->GetName().find("Smart") == std::string::npos)
sLog->outErrorDb("Script named '%s' does not have a script name assigned in database.",
script->GetName().c_str());
}
} else {
// We're dealing with a code-only script; just add it.
ScriptPointerList[_scriptIdCounter++] = script;
sScriptMgr->IncrementScriptCount();
}
}
}
// Gets a script by its ID (assigned by ObjectMgr).
static TScript* GetScriptById(uint32 id)
{
@ -1106,6 +1164,24 @@ class ScriptRegistry
}
private:
// See if the script is using the same memory as another script. If this happens, it means that
// someone forgot to allocate new memory for a script.
static bool _checkMemory(TScript* const script) {
// See if the script is using the same memory as another script. If this happens, it means that
// someone forgot to allocate new memory for a script.
for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
{
if (it->second == script)
{
sLog->outError("Script '%s' has same memory pointer as '%s'.",
script->GetName().c_str(), it->second->GetName().c_str());
return false;
}
}
return true;
}
// Counter used for code-only scripts.
static uint32 _scriptIdCounter;

View file

@ -1930,39 +1930,22 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar
// max dist which spell can reach
float searchRadius = jumpRadius;
if (isBouncingFar && !isChainHeal)
if (isBouncingFar)
searchRadius *= chainTargets;
// Xinef: the distance should be increased by caster size, it is neglected in latter calculations
std::list<WorldObject*> tempTargets;
SearchAreaTargets(tempTargets, searchRadius, (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE ? m_caster : target), m_caster, objectType, selectType, condList);
SearchAreaTargets(tempTargets, searchRadius, target, m_caster, objectType, selectType, condList);
tempTargets.remove(target);
// xinef: if we have select category nearby and checktype entry, select random of what we have, not by distance
if (selectCategory == TARGET_SELECT_CATEGORY_NEARBY && selectType == TARGET_CHECK_ENTRY)
{
Trinity::Containers::RandomResizeList(tempTargets, chainTargets);
targets = tempTargets;
return;
}
// remove targets which are always invalid for chain spells
// for some spells allow only chain targets in front of caster (swipe for example)
if (!isBouncingFar)
{
float allowedArc = 0.0f;
if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE)
allowedArc = (M_PI*7.0f) / 18.0f; // 70 degrees
else if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)
allowedArc = M_PI*0.5f; // 90 degrees
for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end();)
{
std::list<WorldObject*>::iterator checkItr = itr++;
if (!m_caster->HasInArc(static_cast<float>(M_PI), *checkItr))
tempTargets.erase(checkItr);
else if (allowedArc > 0.0f && !m_caster->HasInArc(allowedArc, *checkItr, (*checkItr)->GetObjectSize()))
tempTargets.erase(checkItr);
}
}
@ -1976,14 +1959,10 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar
uint32 maxHPDeficit = 0;
for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
{
if (Unit* itrTarget = (*itr)->ToUnit())
if (Unit* unit = (*itr)->ToUnit())
{
uint32 deficit = itrTarget->GetMaxHealth() - itrTarget->GetHealth();
// xinef: chain should not heal targets with max health
if (deficit == 0)
continue;
if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(itrTarget, jumpRadius) && target->IsWithinLOSInMap(itrTarget))
uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit))
{
foundItr = itr;
maxHPDeficit = deficit;

View file

@ -3133,6 +3133,9 @@ void SpellMgr::LoadSpellCustomAttr()
spellInfo->RecoveryTime = 1500;
spellInfo->_requireCooldownInfo = true;
break;
case 44535: // Spirit Heal, abilities also have no cost
spellInfo->Effects[EFFECT_0].MiscValue = 127;
break;
}
switch (spellInfo->SpellFamilyName)
@ -3558,12 +3561,12 @@ void SpellMgr::LoadDbcDataCorrections()
spellInfo->EffectSpellClassMask[0][0] = 0;
spellInfo->EffectSpellClassMask[0][2] = 0x8000000;
break;
// Judgements Facing
/* Judgements Facing -- SCEICCO: not sure this is offylike
case 20271:
case 53407:
case 53408:
spellInfo->FacingCasterFlags |= SPELL_FACING_FLAG_INFRONT;
break;
break;*/
// Seal of Light trigger
case 20167:
spellInfo->spellLevel = 0;

View file

@ -32,11 +32,11 @@ inline float GetAge(uint64 t) { return float(time(NULL) - t) / DAY; }
///////////////////////////////////////////////////////////////////////////////////////////////////
// GM ticket
GmTicket::GmTicket() : _id(0), _playerGuid(0), _posX(0), _posY(0), _posZ(0), _mapId(0), _createTime(0), _lastModifiedTime(0),
_closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false),
GmTicket::GmTicket() : _id(0), _type(TICKET_TYPE_OPEN), _playerGuid(0), _posX(0), _posY(0), _posZ(0), _mapId(0), _createTime(0), _lastModifiedTime(0),
_closedBy(0), _resolvedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false),
_needResponse(false), _needMoreHelp(false) { }
GmTicket::GmTicket(Player* player) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), _needMoreHelp(false)
GmTicket::GmTicket(Player* player) : _type(TICKET_TYPE_OPEN), _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _resolvedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), _needMoreHelp(false)
{
_id = sTicketMgr->GenerateTicketId();
_playerName = player->GetName();
@ -47,10 +47,11 @@ GmTicket::~GmTicket() { }
bool GmTicket::LoadFromDB(Field* fields)
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// id, type, playerGuid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket, resolvedBy
uint8 index = 0;
_id = fields[ index].GetUInt32();
_type = TicketType(fields[++index].GetUInt8());
_playerGuid = MAKE_NEW_GUID(fields[++index].GetUInt32(), 0, HIGHGUID_PLAYER);
_playerName = fields[++index].GetString();
_message = fields[++index].GetString();
@ -68,16 +69,19 @@ bool GmTicket::LoadFromDB(Field* fields)
_escalatedStatus = GMTicketEscalationStatus(fields[++index].GetUInt8());
_viewed = fields[++index].GetBool();
_needMoreHelp = fields[++index].GetBool();
_resolvedBy = fields[++index].GetInt32();
return true;
}
void GmTicket::SaveToDB(SQLTransaction& trans) const
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, completed, escalated, viewed
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// id, type, playerGuid, name, description, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, needMoreHelp, resolvedBy
uint8 index = 0;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GM_TICKET);
stmt->setUInt32( index, _id);
stmt->setUInt8 (++index, uint8(_type));
stmt->setUInt32(++index, GUID_LOPART(_playerGuid));
stmt->setString(++index, _playerName);
stmt->setString(++index, _message);
@ -95,6 +99,7 @@ void GmTicket::SaveToDB(SQLTransaction& trans) const
stmt->setUInt8 (++index, uint8(_escalatedStatus));
stmt->setBool (++index, _viewed);
stmt->setBool (++index, _needMoreHelp);
stmt->setInt32 (++index, GUID_LOPART(_resolvedBy));
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
@ -363,6 +368,20 @@ void TicketMgr::RemoveTicket(uint32 ticketId)
}
}
void TicketMgr::ResolveAndCloseTicket(uint32 ticketId, int64 source)
{
if (GmTicket* ticket = GetTicket(ticketId))
{
SQLTransaction trans = SQLTransaction(NULL);
ticket->SetClosedBy(source);
ticket->SetResolvedBy(source);
if (source)
--_openTicketCount;
ticket->SaveToDB(trans);
}
}
void TicketMgr::ShowList(ChatHandler& handler, bool onlineOnly) const
{
handler.SendSysMessage(onlineOnly ? LANG_COMMAND_TICKETSHOWONLINELIST : LANG_COMMAND_TICKETSHOWLIST);

View file

@ -78,6 +78,13 @@ enum LagReportType
LAG_REPORT_TYPE_SPELL = 6
};
enum TicketType
{
TICKET_TYPE_OPEN = 0,
TICKET_TYPE_CLOSED = 1,
TICKET_TYPE_CHARACTER_DELETED = 2,
};
class GmTicket
{
public:
@ -85,7 +92,7 @@ public:
GmTicket(Player* player);
~GmTicket();
bool IsClosed() const { return _closedBy; }
bool IsClosed() const { return _type != TICKET_TYPE_OPEN; }
bool IsCompleted() const { return _completed; }
bool IsFromPlayer(uint64 guid) const { return guid == _playerGuid; }
bool IsAssigned() const { return _assignedTo != 0; }
@ -119,7 +126,8 @@ public:
else if (_escalatedStatus == TICKET_UNASSIGNED)
_escalatedStatus = TICKET_ASSIGNED;
}
void SetClosedBy(int64 value) { _closedBy = value; }
void SetClosedBy(int64 value) { _closedBy = value; _type = TICKET_TYPE_CLOSED; }
void SetResolvedBy(int64 value) { _resolvedBy = value; }
void SetCompleted() { _completed = true; }
void SetMessage(std::string const& message)
{
@ -151,6 +159,7 @@ public:
private:
uint32 _id;
uint64 _playerGuid;
TicketType _type; // 0 = Open, 1 = Closed, 2 = Character deleted
std::string _playerName;
float _posX;
float _posY;
@ -159,7 +168,8 @@ private:
std::string _message;
uint64 _createTime;
uint64 _lastModifiedTime;
int64 _closedBy; // 0 = Open, -1 = Console, playerGuid = player abandoned ticket, other = GM who closed it.
int64 _closedBy; // 0 = Open or Closed by Console (if type = 1), playerGuid = GM who closed it or player abandoned ticket or read the GM response message.
int64 _resolvedBy; // 0 = Open, -1 = Resolved by Console, GM who resolved it by closing or completing the ticket.
uint64 _assignedTo;
std::string _comment;
bool _completed;
@ -213,6 +223,7 @@ public:
void AddTicket(GmTicket* ticket);
void CloseTicket(uint32 ticketId, int64 source = -1);
void ResolveAndCloseTicket(uint32 ticketId, int64 source); // used when GM resolves a ticket by simply closing it
void RemoveTicket(uint32 ticketId);
bool GetStatus() const { return _status; }

View file

@ -429,13 +429,18 @@ void World::LoadConfigSettings(bool reload)
{
if (!sConfigMgr->Reload())
{
sLog->outError("World settings reload fail: can't read settings from %s.", sConfigMgr->GetFilename().c_str());
sLog->outError("World settings reload fail: can't read settings.");
return;
}
sLog->ReloadConfig(); // Reload log levels and filters
}
sScriptMgr->OnBeforeConfigLoad(reload);
// Reload log levels and filters
// doing it again to allow sScriptMgr
// to change log confs at start
sLog->ReloadConfig();
///- Read the player limit and the Message of the day from the config file
if (!reload)
SetPlayerAmountLimit(sConfigMgr->GetIntDefault("PlayerLimit", 100));
@ -443,6 +448,7 @@ void World::LoadConfigSettings(bool reload)
///- Read ticket system setting from the config file
m_bool_configs[CONFIG_ALLOW_TICKETS] = sConfigMgr->GetBoolDefault("AllowTickets", true);
m_bool_configs[CONFIG_DELETE_CHARACTER_TICKET_TRACE] = sConfigMgr->GetBoolDefault("DeletedCharacterTicketTrace", false);
///- Get string for new logins (newly created characters)
SetNewCharString(sConfigMgr->GetStringDefault("PlayerStart.String", ""));
@ -1043,6 +1049,7 @@ void World::LoadConfigSettings(bool reload)
m_float_configs[CONFIG_LISTEN_RANGE_YELL] = sConfigMgr->GetFloatDefault("ListenRange.Yell", 300.0f);
m_bool_configs[CONFIG_BATTLEGROUND_CAST_DESERTER] = sConfigMgr->GetBoolDefault("Battleground.CastDeserter", true);
m_bool_configs[CONFIG_BATTLEGROUND_RANDOM_CROSSFACTION] = sConfigMgr->GetBoolDefault("Battleground.RandomCrossFaction.Enable", true); // [AZTH] RBG Crossfaction
m_bool_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE] = sConfigMgr->GetBoolDefault("Battleground.QueueAnnouncer.Enable", false);
m_int_configs[CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER] = sConfigMgr->GetIntDefault ("Battleground.PrematureFinishTimer", 5 * MINUTE * IN_MILLISECONDS);
m_int_configs[CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH] = sConfigMgr->GetIntDefault ("Battleground.PremadeGroupWaitForMatch", 30 * MINUTE * IN_MILLISECONDS);
@ -1234,8 +1241,7 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_BIRTHDAY_TIME] = sConfigMgr->GetIntDefault("BirthdayTime", 1222964635);
// call ScriptMgr if we're reloading the configuration
if (reload)
sScriptMgr->OnConfigLoad(reload);
sScriptMgr->OnAfterConfigLoad(reload);
}
extern void LoadGameObjectModelList();
@ -1251,6 +1257,9 @@ void World::SetInitialWorldSettings()
///- Initialize detour memory management
dtAllocSetCustom(dtCustomAlloc, dtCustomFree);
sLog->outString("Initializing Scripts...");
sScriptMgr->Initialize();
///- Initialize config settings
LoadConfigSettings();
@ -1698,9 +1707,8 @@ void World::SetInitialWorldSettings()
sLog->outString("Loading Creature Text Locales...");
sCreatureTextMgr->LoadCreatureTextLocales();
sLog->outString("Initializing Scripts...");
sScriptMgr->Initialize();
sScriptMgr->OnConfigLoad(false); // must be done after the ScriptMgr has been properly initialized
sLog->outString("Loading Scripts...");
sScriptMgr->LoadDatabase();
sLog->outString("Validating spell scripts...");
sObjectMgr->ValidateSpellScripts();

View file

@ -127,6 +127,7 @@ enum WorldBoolConfigs
CONFIG_DIE_COMMAND_MODE,
CONFIG_DECLINED_NAMES_USED,
CONFIG_BATTLEGROUND_CAST_DESERTER,
CONFIG_BATTLEGROUND_RANDOM_CROSSFACTION, // [AZTH] RBG Crossfaction
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE,
CONFIG_BG_XP_FOR_KILL,
CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS,
@ -143,6 +144,7 @@ enum WorldBoolConfigs
CONFIG_SHOW_KICK_IN_WORLD,
CONFIG_AUTOBROADCAST,
CONFIG_ALLOW_TICKETS,
CONFIG_DELETE_CHARACTER_TICKET_TRACE,
CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES,
CONFIG_PRESERVE_CUSTOM_CHANNELS,
CONFIG_WINTERGRASP_ENABLE,

View file

@ -22,13 +22,19 @@ include(Commands/CMakeLists.txt)
set(scripts_STAT_SRCS
${scripts_STAT_SRCS}
ScriptLoader.cpp
ScriptLoader.h
${BUILDDIR}/GenLoader.cpp
../game/AI/ScriptedAI/ScriptedEscortAI.cpp
../game/AI/ScriptedAI/ScriptedCreature.cpp
../game/AI/ScriptedAI/ScriptedFollowerAI.cpp
)
AZTH_ADD_SCRIPTS("Spell" "ScriptLoader.h")
AZTH_ADD_SCRIPTS("SC_Smart" "ScriptLoader.h")
AZTH_ADD_SCRIPTS("Command" "ScriptLoader.h")
if(SCRIPTS)
include(Custom/CMakeLists.txt)
include(World/CMakeLists.txt)
include(OutdoorPvP/CMakeLists.txt)
include(EasternKingdoms/CMakeLists.txt)
@ -39,6 +45,18 @@ if(SCRIPTS)
include(Pet/CMakeLists.txt)
endif()
AZTH_GET_GLOBAL("AZTH_ADD_SCRIPTS_LIST")
AZTH_GET_GLOBAL("AZTH_ADD_SCRIPTS_INCLUDE")
set("AZTH_SCRIPTS_INCLUDES" "")
FOREACH (include ${AZTH_ADD_SCRIPTS_INCLUDE})
set("AZTH_SCRIPTS_INCLUDES" "#include \"${include}\"\n${AZTH_SCRIPTS_INCLUDES}")
ENDFOREACH()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/GenLoader.cpp.cmake ${BUILDDIR}/GenLoader.cpp)
message(STATUS "SCRIPT PREPARATION COMPLETE")
message("")
@ -140,6 +158,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/World
${CMAKE_SOURCE_DIR}/src/server/game/ArenaSpectator
${CMAKE_SOURCE_DIR}/src/server/game/Misc
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders
${ACE_INCLUDE_DIR}
${MYSQL_INCLUDE_DIR}

View file

@ -156,7 +156,7 @@ public:
return true;
}
sTicketMgr->CloseTicket(ticket->GetId(), player ? player->GetGUID() : -1);
sTicketMgr->ResolveAndCloseTicket(ticket->GetId(), player ? player->GetGUID() : -1);
sTicketMgr->UpdateLastChange();
std::string msg = ticket->FormatMessageString(*handler, player ? player->GetName().c_str() : "Console", NULL, NULL, NULL);
@ -234,8 +234,12 @@ public:
if (Player* player = ticket->GetPlayer())
ticket->SendResponse(player->GetSession());
Player* gm = handler->GetSession() ? handler->GetSession()->GetPlayer() : NULL;
SQLTransaction trans = SQLTransaction(NULL);
ticket->SetCompleted();
ticket->SetResolvedBy(gm ? gm->GetGUID() : -1);
ticket->SaveToDB(trans);
sTicketMgr->UpdateLastChange();

View file

@ -1,15 +0,0 @@
# Copyright (C)
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
set(scripts_STAT_SRCS
${scripts_STAT_SRCS}
)
message(" -> Prepared: Custom")

View file

@ -164,4 +164,6 @@ set(scripts_STAT_SRCS
EasternKingdoms/TheStockade/instance_the_stockade.cpp
)
AZTH_ADD_SCRIPTS("EasternKingdoms" "ScriptLoader.h")
message(" -> Prepared: Eastern Kingdoms")

View file

@ -143,7 +143,9 @@ class boss_nalorakk : public CreatureScript
waitTimer = 0;
me->SetSpeed(MOVE_RUN, 2);
me->SetWalk(false);
}else
ResetMobs();
}
else
{
(*me).GetMotionMaster()->MovePoint(0, NalorakkWay[7][0], NalorakkWay[7][1], NalorakkWay[7][2]);
}
@ -160,6 +162,33 @@ class boss_nalorakk : public CreatureScript
// me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); /// @todo find the correct equipment id
}
void ResetMobs()
{
std::list<Creature*> templist;
float x, y, z;
me->GetPosition(x, y, z);
{
CellCoord pair(Trinity::ComputeCellCoord(x, y));
Cell cell(pair);
cell.SetNoCreate();
Trinity::AllFriendlyCreaturesInGrid check(me);
Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> searcher(me, templist, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid>, GridTypeMapContainer> cSearcher(searcher);
cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange());
}
if (templist.empty())
return;
for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i)
if ((*i) && me->IsWithinDistInMap((*i), 25))
(*i)->AI()->Reset();
}
void SendAttacker(Unit* target)
{
std::list<Creature*> templist;
@ -283,6 +312,7 @@ class boss_nalorakk : public CreatureScript
void JustDied(Unit* /*killer*/)
{
ResetMobs();
instance->SetData(DATA_NALORAKKEVENT, DONE);
me->MonsterYell(YELL_DEATH, LANG_UNIVERSAL, NULL);

View file

@ -235,69 +235,75 @@ class instance_zulaman : public InstanceMapScript
{
switch (type)
{
case DATA_GONGEVENT:
m_auiEncounter[DATA_GONGEVENT] = data;
if (data == IN_PROGRESS)
case DATA_GONGEVENT:
m_auiEncounter[DATA_GONGEVENT] = data;
if (data == IN_PROGRESS)
SaveToDB();
else if (data == DONE)
QuestMinute = 21;
break;
case DATA_NALORAKKEVENT:
m_auiEncounter[DATA_NALORAKKEVENT] = data;
if (data == DONE)
{
if (QuestMinute)
{
QuestMinute += 15;
DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute);
}
SummonHostage(0);
SaveToDB();
}
break;
case DATA_AKILZONEVENT:
m_auiEncounter[DATA_AKILZONEVENT] = data;
HandleGameObject(AkilzonDoorGUID, data != IN_PROGRESS);
if (data == DONE)
{
if (QuestMinute)
{
QuestMinute += 10;
DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute);
}
SummonHostage(1);
SaveToDB();
}
break;
case DATA_JANALAIEVENT:
m_auiEncounter[DATA_JANALAIEVENT] = data;
if (data == DONE)
SummonHostage(2);
SaveToDB();
else if (data == DONE)
QuestMinute = 21;
break;
case DATA_NALORAKKEVENT:
m_auiEncounter[DATA_NALORAKKEVENT] = data;
if (data == DONE)
{
if (QuestMinute)
{
QuestMinute += 15;
DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute);
}
SummonHostage(0);
}
break;
case DATA_AKILZONEVENT:
m_auiEncounter[DATA_AKILZONEVENT] = data;
HandleGameObject(AkilzonDoorGUID, data != IN_PROGRESS);
if (data == DONE)
{
if (QuestMinute)
{
QuestMinute += 10;
DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute);
}
SummonHostage(1);
}
break;
case DATA_JANALAIEVENT:
m_auiEncounter[DATA_JANALAIEVENT] = data;
if (data == DONE)
SummonHostage(2);
break;
case DATA_HALAZZIEVENT:
m_auiEncounter[DATA_HALAZZIEVENT] = data;
HandleGameObject(HalazziDoorGUID, data != IN_PROGRESS);
if (data == DONE) SummonHostage(3);
break;
case DATA_HEXLORDEVENT:
m_auiEncounter[DATA_HEXLORDEVENT] = data;
if (data == IN_PROGRESS)
HandleGameObject(HexLordGateGUID, false);
else if (data == NOT_STARTED)
CheckInstanceStatus();
break;
case DATA_ZULJINEVENT:
m_auiEncounter[DATA_ZULJINEVENT] = data;
HandleGameObject(ZulJinDoorGUID, data != IN_PROGRESS);
break;
case DATA_CHESTLOOTED:
++ChestLooted;
SaveToDB();
break;
case TYPE_RAND_VENDOR_1:
RandVendor[0] = data;
break;
case TYPE_RAND_VENDOR_2:
RandVendor[1] = data;
break;
break;
case DATA_HALAZZIEVENT:
m_auiEncounter[DATA_HALAZZIEVENT] = data;
HandleGameObject(HalazziDoorGUID, data != IN_PROGRESS);
if (data == DONE) SummonHostage(3);
SaveToDB();
break;
case DATA_HEXLORDEVENT:
m_auiEncounter[DATA_HEXLORDEVENT] = data;
if (data == IN_PROGRESS)
HandleGameObject(HexLordGateGUID, false);
else if (data == NOT_STARTED)
CheckInstanceStatus();
SaveToDB();
break;
case DATA_ZULJINEVENT:
m_auiEncounter[DATA_ZULJINEVENT] = data;
HandleGameObject(ZulJinDoorGUID, data != IN_PROGRESS);
SaveToDB();
break;
case DATA_CHESTLOOTED:
++ChestLooted;
SaveToDB();
break;
case TYPE_RAND_VENDOR_1:
RandVendor[0] = data;
break;
case TYPE_RAND_VENDOR_2:
RandVendor[1] = data;
break;
}
if (data == DONE)
@ -317,17 +323,17 @@ class instance_zulaman : public InstanceMapScript
{
switch (type)
{
case DATA_GONGEVENT: return m_auiEncounter[DATA_GONGEVENT];
case DATA_NALORAKKEVENT: return m_auiEncounter[DATA_NALORAKKEVENT];
case DATA_AKILZONEVENT: return m_auiEncounter[DATA_AKILZONEVENT];
case DATA_JANALAIEVENT: return m_auiEncounter[DATA_JANALAIEVENT];
case DATA_HALAZZIEVENT: return m_auiEncounter[DATA_HALAZZIEVENT];
case DATA_HEXLORDEVENT: return m_auiEncounter[DATA_HEXLORDEVENT];
case DATA_ZULJINEVENT: return m_auiEncounter[DATA_ZULJINEVENT];
case DATA_CHESTLOOTED: return ChestLooted;
case TYPE_RAND_VENDOR_1: return RandVendor[0];
case TYPE_RAND_VENDOR_2: return RandVendor[1];
default: return 0;
case DATA_GONGEVENT: return m_auiEncounter[DATA_GONGEVENT];
case DATA_NALORAKKEVENT: return m_auiEncounter[DATA_NALORAKKEVENT];
case DATA_AKILZONEVENT: return m_auiEncounter[DATA_AKILZONEVENT];
case DATA_JANALAIEVENT: return m_auiEncounter[DATA_JANALAIEVENT];
case DATA_HALAZZIEVENT: return m_auiEncounter[DATA_HALAZZIEVENT];
case DATA_HEXLORDEVENT: return m_auiEncounter[DATA_HEXLORDEVENT];
case DATA_ZULJINEVENT: return m_auiEncounter[DATA_ZULJINEVENT];
case DATA_CHESTLOOTED: return ChestLooted;
case TYPE_RAND_VENDOR_1: return RandVendor[0];
case TYPE_RAND_VENDOR_2: return RandVendor[1];
default: return 0;
}
}

View file

@ -9,4 +9,6 @@ set(scripts_STAT_SRCS
Events/midsummer.cpp
)
message(" -> Prepared: Events")
AZTH_ADD_SCRIPTS("Event" "ScriptLoader.h")
message(" -> Prepared: Events")

View file

@ -0,0 +1,7 @@
// This file is autogenerated, please do not modify directly!
@AZTH_SCRIPTS_INCLUDES@
void AddScripts() {
@AZTH_ADD_SCRIPTS_LIST@
}

View file

@ -105,4 +105,6 @@ set(scripts_STAT_SRCS
Kalimdor/DireMaul/dire_maul.h
)
AZTH_ADD_SCRIPTS("Kalimdor" "ScriptLoader.h")
message(" -> Prepared: Kalimdor")

View file

@ -196,4 +196,6 @@ set(scripts_STAT_SRCS
Northrend/DraktharonKeep/boss_dred.cpp
)
AZTH_ADD_SCRIPTS("Northrend" "ScriptLoader.h")
message(" -> Prepared: Northrend")

View file

@ -26,4 +26,6 @@ set(scripts_STAT_SRCS
OutdoorPvP/OutdoorPvPGH.h
)
AZTH_ADD_SCRIPTS("OutdoorPvP" "ScriptLoader.h")
message(" -> Prepared: Outdoor PVP Zones")

View file

@ -109,4 +109,6 @@ set(scripts_STAT_SRCS
Outland/zone_zangarmarsh.cpp
)
AZTH_ADD_SCRIPTS("Outland" "ScriptLoader.h")
message(" -> Prepared: Outland")

View file

@ -18,4 +18,6 @@ set(scripts_STAT_SRCS
Pet/pet_shaman.cpp
)
AZTH_ADD_SCRIPTS("Pet" "ScriptLoader.h")
message(" -> Prepared: Pet")

View file

@ -50,7 +50,11 @@ class npc_pet_dk_ebon_gargoyle : public CreatureScript
_despawnTimer = 36000; // 30 secs + 4 fly out + 2 initial attack timer
_despawning = false;
_initialSelection = true;
_ghoulSelection = true;
_targetGUID = 0;
_markedTargetGUID = 0;
_ghoulTargetGUID = 0;
}
void MovementInform(uint32 type, uint32 point)
@ -90,8 +94,17 @@ class npc_pet_dk_ebon_gargoyle : public CreatureScript
Unit* owner = me->GetOwner();
if (owner && owner->GetTypeId() == TYPEID_PLAYER && (!me->GetVictim() || me->GetVictim()->IsImmunedToSpell(sSpellMgr->GetSpellInfo(51963)) || !me->IsValidAttackTarget(me->GetVictim()) || !owner->CanSeeOrDetect(me->GetVictim())))
{
Unit* selection = owner->ToPlayer()->GetSelectedUnit();
if (selection && selection != me->GetVictim() && me->IsValidAttackTarget(selection))
Unit* ghoulTarget = ObjectAccessor::GetUnit(*me, GetGhoulTargetGUID());
Unit* dkTarget = owner->ToPlayer()->GetSelectedUnit();
if (ghoulTarget && ghoulTarget != me->GetVictim() && me->IsValidAttackTarget(ghoulTarget))
{
me->GetMotionMaster()->Clear(false);
SwitchTargetAndAttack(ghoulTarget);
return;
}
if (dkTarget && dkTarget != me->GetVictim() && me->IsValidAttackTarget(dkTarget))
{
me->GetMotionMaster()->Clear(false);
SetGazeOn(selection);
@ -171,9 +184,52 @@ class npc_pet_dk_ebon_gargoyle : public CreatureScript
(*iter)->RemoveAura(SPELL_DK_SUMMON_GARGOYLE_1, me->GetOwnerGUID());
SetGazeOn(*iter);
_targetGUID = (*iter)->GetGUID();
_markedTargetGUID = _targetGUID;
break;
}
}
if (_ghoulSelection) //find pet ghoul target
{
std::list<Unit*> targets;
Trinity::AnyFriendlyUnitInObjectRangeCheck ghoul_check(me, me, 50);
Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(me, targets, ghoul_check);
me->VisitNearbyObject(50, searcher);
for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
if ((*iter)->GetEntry() == 26125) // ghoul entry
{
if ((*iter)->GetOwnerGUID() == me->GetOwnerGUID()) // same owner
{
_ghoulTargetGUID = (*iter)->GetTarget();
break;
}
}
}
}
if (Unit* ghoulTarget = ObjectAccessor::GetUnit(*me, _ghoulTargetGUID))
{
if(ghoulTarget->IsAlive())
{
AttackStart(ghoulTarget);
}
}
else
{
_ghoulSelection = false; // check for ghoul at next update.
if (Unit* markedTarget = ObjectAccessor::GetUnit(*me, _markedTargetGUID))
{
if (markedTarget->IsAlive())
{
AttackStart(markedTarget);
}
}
}
if (_despawnTimer > 4000)
{
_despawnTimer -= diff;
@ -190,8 +246,11 @@ class npc_pet_dk_ebon_gargoyle : public CreatureScript
MySelectNextTarget();
_selectionTimer = 0;
}
if (_initialCastTimer >= 2000 && !me->HasUnitState(UNIT_STATE_CASTING|UNIT_STATE_LOST_CONTROL) && me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) == NULL_MOTION_TYPE)
me->CastSpell(me->GetVictim(), 51963, false);
// check start timer and if not casting
if(_initialCastTimer >= 2000 && !me->HasUnitState(UNIT_STATE_CASTING))
if (!(me->HasAuraType(SPELL_AURA_MOD_FEAR) || me->HasAuraType(SPELL_AURA_MOD_ROOT) || me->HasAuraType(SPELL_AURA_MOD_CONFUSE) || me->HasAuraType(SPELL_AURA_MOD_STUN)))
if (_initialCastTimer >= 2000 && !me->HasUnitState(UNIT_STATE_LOST_CONTROL) && me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) == NULL_MOTION_TYPE)
me->CastSpell(me->GetVictim(), 51963, false);
}
else
{
@ -207,11 +266,14 @@ class npc_pet_dk_ebon_gargoyle : public CreatureScript
private:
uint64 _targetGUID;
uint64 _ghoulTargetGUID;
uint64 _markedTargetGUID;
uint32 _despawnTimer;
uint32 _selectionTimer;
uint32 _initialCastTimer;
bool _despawning;
bool _initialSelection;
bool _ghoulSelection;
};
CreatureAI* GetAI(Creature* creature) const
@ -282,7 +344,12 @@ class npc_pet_dk_dancing_rune_weapon : public CreatureScript
// Xinef: Hit / Expertise scaling
me->AddAura(61017, me);
if (Unit* owner = me->GetOwner())
{
me->GetMotionMaster()->MoveFollow(owner, 0.01f, me->GetFollowAngle(), MOTION_SLOT_CONTROLLED);
if (Player* player = owner->ToPlayer())
player->setRuneWeaponGUID(me->GetGUID());
}
NullCreatureAI::InitializeAI();
}
};

View file

@ -60,7 +60,7 @@ class npc_pet_gen_mojo : public CreatureScript
me->HandleEmoteCommand(emote);
Unit* owner = me->GetOwner();
if (emote != TEXT_EMOTE_KISS || !owner || owner->GetTypeId() != TYPEID_PLAYER ||
owner->ToPlayer()->GetTeamId() != player->GetTeamId())
owner->ToPlayer()->GetTeamId(true) != player->GetTeamId(true))
{
return;
}
@ -255,13 +255,13 @@ public:
{
_state = ARGENT_PONY_STATE_ENCH;
aura = (player->GetTeamId() == TEAM_ALLIANCE ? SPELL_AURA_TIRED_S : SPELL_AURA_TIRED_G);
aura = (player->GetTeamId(true) == TEAM_ALLIANCE ? SPELL_AURA_TIRED_S : SPELL_AURA_TIRED_G);
duration = player->GetSpellCooldownDelay(aura);
me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
for (uint8 i = 0; i < 3; ++i)
{
if (player->GetTeamId() == TEAM_ALLIANCE)
if (player->GetTeamId(true) == TEAM_ALLIANCE)
{
if (uint32 cooldown = player->GetSpellCooldownDelay(SPELL_AURA_POSTMAN_S+i))
{
@ -286,7 +286,7 @@ public:
}
// Generate Banners
uint32 mask = player->GetTeamId() ? RACEMASK_HORDE : RACEMASK_ALLIANCE;
uint32 mask = player->GetTeamId(true) ? RACEMASK_HORDE : RACEMASK_ALLIANCE;
for (uint8 i = 1; i < MAX_RACES; ++i)
if (mask & (1 << (i-1)) && player->HasAchieved(argentBanners[i].achievement))
_banners[i] = true;
@ -351,7 +351,7 @@ public:
if (player->GetGUID() != creature->GetOwnerGUID())
return true;
if (!creature->HasAura(player->GetTeamId() ? SPELL_AURA_TIRED_G : SPELL_AURA_TIRED_S))
if (!creature->HasAura(player->GetTeamId(true) ? SPELL_AURA_TIRED_G : SPELL_AURA_TIRED_S))
{
uint8 _state = creature->AI()->GetData(0 /*GET_DATA_STATE*/);
if (_state == ARGENT_PONY_STATE_ENCH || _state == ARGENT_PONY_STATE_VENDOR)
@ -379,20 +379,20 @@ public:
case GOSSIP_ACTION_TRADE:
creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_VENDOR);
player->GetSession()->SendListInventory(creature->GetGUID());
spellId = player->GetTeamId() ? SPELL_AURA_SHOP_G : SPELL_AURA_SHOP_S;
spellId = player->GetTeamId(true) ? SPELL_AURA_SHOP_G : SPELL_AURA_SHOP_S;
creature->AI()->DoAction(ARGENT_PONY_STATE_VENDOR);
break;
case GOSSIP_ACTION_BANK:
creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BANKER);
player->GetSession()->SendShowBank(player->GetGUID());
spellId = player->GetTeamId() ? SPELL_AURA_BANK_G : SPELL_AURA_BANK_S;
spellId = player->GetTeamId(true) ? SPELL_AURA_BANK_G : SPELL_AURA_BANK_S;
creature->AI()->DoAction(ARGENT_PONY_STATE_BANK);
break;
case GOSSIP_ACTION_MAILBOX:
{
creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_MAILBOX);
player->GetSession()->SendShowMailBox(creature->GetGUID());
spellId = player->GetTeamId() ? SPELL_AURA_POSTMAN_G : SPELL_AURA_POSTMAN_S;
spellId = player->GetTeamId(true) ? SPELL_AURA_POSTMAN_G : SPELL_AURA_POSTMAN_S;
creature->AI()->DoAction(ARGENT_PONY_STATE_MAILBOX);
break;
}
@ -409,7 +409,7 @@ public:
{
creature->CastSpell(creature, spellId, true);
player->AddSpellCooldown(spellId, 0, 3*MINUTE*IN_MILLISECONDS);
player->AddSpellCooldown(player->GetTeamId() ? SPELL_AURA_TIRED_G : SPELL_AURA_TIRED_S, 0, 3*MINUTE*IN_MILLISECONDS + 4*HOUR*IN_MILLISECONDS);
player->AddSpellCooldown(player->GetTeamId(true) ? SPELL_AURA_TIRED_G : SPELL_AURA_TIRED_S, 0, 3*MINUTE*IN_MILLISECONDS + 4*HOUR*IN_MILLISECONDS);
creature->DespawnOrUnsummon(3*MINUTE*IN_MILLISECONDS);
}
return true;

View file

@ -1,5 +1,5 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -40,7 +40,7 @@ void AddSC_warrior_spell_scripts();
void AddSC_quest_spell_scripts();
void AddSC_item_spell_scripts();
void AddSC_SmartSCripts();
void AddSC_SmartScripts();
//Commands
void AddSC_account_commandscript();
@ -237,7 +237,7 @@ void AddSC_western_plaguelands();
void AddSC_westfall();
void AddSC_wetlands();
//kalimdor
//kalimdor
void AddSC_instance_blackfathom_deeps(); //Blackfathom Depths
void AddSC_hyjal(); //CoT Battle for Mt. Hyjal
void AddSC_boss_archimonde();
@ -588,59 +588,6 @@ void AddSC_outdoorpvp_gh();
#endif
void AddScripts()
{
AddSpellScripts();
AddSC_SmartSCripts();
AddCommandScripts();
#ifdef SCRIPTS
AddWorldScripts();
AddEventScripts();
AddEasternKingdomsScripts();
AddKalimdorScripts();
AddOutlandScripts();
AddNorthrendScripts();
AddPetScripts();
AddBattlegroundScripts();
AddOutdoorPvPScripts();
AddCustomScripts();
#endif
}
void CheckIfScriptsInDatabaseExist()
{
ObjectMgr::ScriptNameContainer& sn = sObjectMgr->GetScriptNames();
for (ObjectMgr::ScriptNameContainer::iterator itr = sn.begin(); itr != sn.end(); ++itr)
if (uint32 sid = sObjectMgr->GetScriptId((*itr).c_str()))
{
if (!ScriptRegistry<SpellScriptLoader>::GetScriptById(sid) &&
!ScriptRegistry<ServerScript>::GetScriptById(sid) &&
!ScriptRegistry<WorldScript>::GetScriptById(sid) &&
!ScriptRegistry<FormulaScript>::GetScriptById(sid) &&
!ScriptRegistry<WorldMapScript>::GetScriptById(sid) &&
!ScriptRegistry<InstanceMapScript>::GetScriptById(sid) &&
!ScriptRegistry<BattlegroundMapScript>::GetScriptById(sid) &&
!ScriptRegistry<ItemScript>::GetScriptById(sid) &&
!ScriptRegistry<CreatureScript>::GetScriptById(sid) &&
!ScriptRegistry<GameObjectScript>::GetScriptById(sid) &&
!ScriptRegistry<AreaTriggerScript>::GetScriptById(sid) &&
!ScriptRegistry<BattlegroundScript>::GetScriptById(sid) &&
!ScriptRegistry<OutdoorPvPScript>::GetScriptById(sid) &&
!ScriptRegistry<CommandScript>::GetScriptById(sid) &&
!ScriptRegistry<WeatherScript>::GetScriptById(sid) &&
!ScriptRegistry<AuctionHouseScript>::GetScriptById(sid) &&
!ScriptRegistry<ConditionScript>::GetScriptById(sid) &&
!ScriptRegistry<VehicleScript>::GetScriptById(sid) &&
!ScriptRegistry<DynamicObjectScript>::GetScriptById(sid) &&
!ScriptRegistry<TransportScript>::GetScriptById(sid) &&
!ScriptRegistry<AchievementCriteriaScript>::GetScriptById(sid) &&
!ScriptRegistry<PlayerScript>::GetScriptById(sid) &&
!ScriptRegistry<GuildScript>::GetScriptById(sid) &&
!ScriptRegistry<GroupScript>::GetScriptById(sid))
sLog->outErrorDb("Script named '%s' is assigned in database, but has no code!", (*itr).c_str());
}
}
void AddSpellScripts()
{
AddSC_deathknight_spell_scripts();
@ -1233,21 +1180,3 @@ void AddOutdoorPvPScripts()
#endif
}
void AddBattlegroundScripts()
{
#ifdef SCRIPTS
#endif
}
#ifdef SCRIPTS
/* This is where custom scripts' loading functions should be declared. */
#endif
void AddCustomScripts()
{
#ifdef SCRIPTS
/* This is where custom scripts should be added. */
#endif
}

View file

@ -19,18 +19,16 @@
#define SC_SCRIPTLOADER_H
void AddScripts();
void CheckIfScriptsInDatabaseExist();
void AddSpellScripts();
void AddCommandScripts();
void AddSC_SmartScripts();
void AddWorldScripts();
void AddEventScripts();
void AddEasternKingdomsScripts();
void AddKalimdorScripts();
void AddOutlandScripts();
void AddNorthrendScripts();
void AddBattlegroundScripts();
void AddPetScripts();
void AddOutdoorPvPScripts();
void AddCustomScripts();
#endif

View file

@ -23,4 +23,6 @@ set(scripts_STAT_SRCS
World/npcs_special.cpp
)
AZTH_ADD_SCRIPTS("World" "ScriptLoader.h")
message(" -> Prepared: World")

View file

@ -49,10 +49,9 @@ bool ConfigMgr::LoadInitial(char const* file)
GuardType guard(_configLock);
_filename = file;
_config.reset(new ACE_Configuration_Heap());
if (_config->open() == 0)
if (LoadData(_filename.c_str()))
if (LoadData(file))
return true;
_config.reset();
@ -71,11 +70,25 @@ bool ConfigMgr::LoadMore(char const* file)
bool ConfigMgr::Reload()
{
return LoadInitial(_filename.c_str());
for(std::vector<std::string>::iterator it = _confFiles.begin(); it != _confFiles.end(); ++it) {
if (it==_confFiles.begin()) {
if (!LoadInitial((*it).c_str()))
return false;
} else {
if (!LoadMore((*it).c_str()))
return false;
}
}
return true;
}
bool ConfigMgr::LoadData(char const* file)
{
if(std::find(_confFiles.begin(), _confFiles.end(), file) == _confFiles.end()) {
_confFiles.push_back(file);
}
ACE_Ini_ImpExp config_importer(*_config.get());
if (config_importer.import_config(file) == 0)
return true;
@ -112,12 +125,6 @@ float ConfigMgr::GetFloatDefault(const char* name, float def)
return GetValueHelper(name, val) ? (float)atof(val.c_str()) : def;
}
std::string const& ConfigMgr::GetFilename()
{
GuardType guard(_configLock);
return _filename;
}
std::list<std::string> ConfigMgr::GetKeysByString(std::string const& name)
{
GuardType guard(_configLock);

View file

@ -21,6 +21,7 @@
#include <string>
#include <list>
#include <vector>
#include <ace/Singleton.h>
#include <ace/Configuration_Import_Export.h>
#include <ace/Thread_Mutex.h>
@ -55,7 +56,6 @@ public:
int GetIntDefault(const char* name, int def);
float GetFloatDefault(const char* name, float def);
std::string const& GetFilename();
std::list<std::string> GetKeysByString(std::string const& name);
private:
@ -65,7 +65,7 @@ private:
typedef ACE_Thread_Mutex LockType;
typedef ACE_Guard<LockType> GuardType;
std::string _filename;
std::vector<std::string> _confFiles;
Config _config;
LockType _configLock;

View file

@ -302,10 +302,11 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_GO_RESPAWN_BY_INSTANCE, "DELETE FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_ASYNC);
// GM Tickets
PrepareStatement(CHAR_SEL_GM_TICKETS, "SELECT ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket FROM gm_tickets", CONNECTION_SYNCH);
PrepareStatement(CHAR_REP_GM_TICKET, "REPLACE INTO gm_tickets (ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GM_TICKET, "DELETE FROM gm_tickets WHERE ticketId = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PLAYER_GM_TICKETS, "DELETE FROM gm_tickets WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_GM_TICKETS, "SELECT id, type, playerGuid, name, description, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, needMoreHelp, resolvedBy FROM gm_ticket", CONNECTION_SYNCH);
PrepareStatement(CHAR_REP_GM_TICKET, "REPLACE INTO gm_ticket (id, type, playerGuid, name, description, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, needMoreHelp, resolvedBy) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GM_TICKET, "DELETE FROM gm_ticket WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PLAYER_GM_TICKETS, "DELETE FROM gm_ticket WHERE playerGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_PLAYER_GM_TICKETS_ON_CHAR_DELETION, "UPDATE gm_ticket SET type = 2 WHERE playerGuid = ?", CONNECTION_ASYNC);
// GM Survey/subsurvey/lag report
PrepareStatement(CHAR_INS_GM_SURVEY, "INSERT INTO gm_surveys (guid, surveyId, mainSurvey, overallComment, createTime) VALUES (?, ?, ?, ?, UNIX_TIMESTAMP(NOW()))", CONNECTION_ASYNC);
@ -349,7 +350,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_GROUP_MEMBER_FLAG, "UPDATE group_member SET memberFlags = ? WHERE memberGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GROUP_DIFFICULTY, "UPDATE groups SET difficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GROUP_RAID_DIFFICULTY, "UPDATE groups SET raiddifficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ALL_GM_TICKETS, "TRUNCATE TABLE gm_tickets", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ALL_GM_TICKETS, "TRUNCATE TABLE gm_ticket", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INVALID_SPELL_TALENTS, "DELETE FROM character_talent WHERE spell = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INVALID_SPELL_SPELLS, "DELETE FROM character_spell WHERE spell = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_DELETE_INFO, "UPDATE characters SET deleteInfos_Name = name, deleteInfos_Account = account, deleteDate = UNIX_TIMESTAMP(), name = '', account = 0 WHERE guid = ?", CONNECTION_ASYNC);

View file

@ -268,6 +268,7 @@ enum CharacterDatabaseStatements
CHAR_DEL_GM_TICKET,
CHAR_DEL_ALL_GM_TICKETS,
CHAR_DEL_PLAYER_GM_TICKETS,
CHAR_UPD_PLAYER_GM_TICKETS_ON_CHAR_DELETION,
CHAR_INS_GM_SURVEY,
CHAR_INS_GM_SUBSURVEY,

View file

@ -208,3 +208,5 @@ endif()
if( USE_COREPCH )
add_cxx_pch(worldserver ${worldserver_PCH_HDR} ${worldserver_PCH_SRC})
endif()
RUN_HOOK("AFTER_WORLDSERVER_CMAKE")

View file

@ -125,12 +125,21 @@ extern int main(int argc, char** argv)
++c;
}
if (!sConfigMgr->LoadInitial(cfg_file))
std::string cfg_def_file=_TRINITY_CORE_CONFIG;
cfg_def_file += ".dist";
if (!sConfigMgr->LoadInitial(cfg_def_file.c_str())) {
printf("Invalid or missing default configuration file : %s\n", cfg_def_file.c_str());
return 1;
}
if (!sConfigMgr->LoadMore(cfg_file))
{
printf("Invalid or missing configuration file : %s\n", cfg_file);
printf("Verify that the file exists and has \'[worldserver]' written in the top of the file!\n");
return 1;
}
sLog->outString("Using configuration file %s.", cfg_file);
sLog->outString("Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));

View file

@ -1407,6 +1407,15 @@ Command.LookupMaxResults = 0
AllowTickets = 1
# DeletedCharacterTicketTrace
# Description: Keep trace of tickets opened by deleted characters
# gm_ticket.playerGuid will be 0, old GUID and character name
# will be included in gm_ticket.comment
# Default: 0 - (Disabled)
# 1 - (Enabled)
DeletedCharacterTicketTrace = 0
#
# DungeonFinder.OptionsMask
# Description: Dungeon and raid finder system.
@ -2439,6 +2448,14 @@ AutoBroadcast.Timer = 60000
Battleground.CastDeserter = 1
#
# Battleground.RandomCrossFaction.Enable
# Description: Enable random battleground crossfaction randomizing system
# Default: 0 - (Disabled)
# 1 - (Enabled)
Battleground.RandomCrossFaction.Enable = 1
#
# Battleground.QueueAnnouncer.Enable
# Description: Announce battleground queue status to chat.