Merge branch 'master' into Playerbot

This commit is contained in:
郑佩茹
2022-05-31 09:11:39 -06:00
72 changed files with 1245 additions and 781 deletions

View File

@@ -10,22 +10,19 @@
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Specified files for Windows
if (WIN32)
# Crash logs
set(winDebugging
${CMAKE_SOURCE_DIR}/src/common/Debugging/WheatyExceptionReport.cpp
${CMAKE_SOURCE_DIR}/src/common/Debugging/WheatyExceptionReport.h)
add_subdirectory(apps)
# Service
set(winService
${CMAKE_SOURCE_DIR}/src/common/Platform/ServiceWin32.cpp
${CMAKE_SOURCE_DIR}/src/common/Platform/ServiceWin32.h)
# if ((APPS_BUILD AND NOT APPS_BUILD STREQUAL "none") OR BUILD_TOOLS_DB_IMPORT) # DB import PR
if ((APPS_BUILD AND NOT APPS_BUILD STREQUAL "none"))
add_subdirectory(database)
endif()
if (BUILD_APPLICATION_AUTHSERVER OR BUILD_APPLICATION_WORLDSERVER)
add_subdirectory(shared)
endif()
if (BUILD_APPLICATION_WORLDSERVER)
add_subdirectory(game)
add_subdirectory(scripts)
endif()
add_subdirectory(authserver)
add_subdirectory(database)
add_subdirectory(game)
add_subdirectory(shared)
add_subdirectory(scripts)
add_subdirectory(worldserver)

View File

@@ -0,0 +1,198 @@
#
# This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
#
# 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.
# Make the script module list available in the current scope
GetApplicationsList(APPLICATIONS_BUILD_LIST)
if (APPS_BUILD STREQUAL "none")
set(APPS_DEFAULT_BUILD "disabled")
else()
set(APPS_DEFAULT_BUILD "enabled")
endif()
# Sets BUILD_APPS_USE_WHITELIST
# Sets BUILD_APPS_WHITELIST
if (APPS_BUILD MATCHES "-only")
set(BUILD_APPS_USE_WHITELIST ON)
if (APPS_BUILD STREQUAL "auth-only")
list(APPEND BUILD_APPS_WHITELIST authserver)
endif()
if (APPS_BUILD STREQUAL "world-only")
list(APPEND BUILD_APPS_WHITELIST worldserver)
endif()
endif()
# Set the SCRIPTS_${BUILD_APP} variables from the
# variables set above
foreach(BUILD_APP ${APPLICATIONS_BUILD_LIST})
ApplicationNameToVariable(${BUILD_APP} BUILD_APP_VARIABLE)
if(${BUILD_APP_VARIABLE} STREQUAL "default")
if(BUILD_APPS_USE_WHITELIST)
list(FIND BUILD_APPS_WHITELIST "${BUILD_APP}" INDEX)
if(${INDEX} GREATER -1)
set(${BUILD_APP_VARIABLE} ${APPS_DEFAULT_BUILD})
else()
set(${BUILD_APP_VARIABLE} "disabled")
endif()
else()
set(${BUILD_APP_VARIABLE} ${APPS_DEFAULT_BUILD})
endif()
endif()
# Build the Graph values
if(${BUILD_APP_VARIABLE} MATCHES "enabled")
list(APPEND BUILD_APP_GRAPH_KEYS apps)
set(BUILD_APP_VALUE_DISPLAY_apps apps)
list(APPEND BUILD_APP_VALUE_CONTAINS_apps ${BUILD_APP})
if (${BUILD_APP} MATCHES "authserver")
set (BUILD_APPLICATION_AUTHSERVER 1)
elseif(${BUILD_APP} MATCHES "worldserver")
set (BUILD_APPLICATION_WORLDSERVER 1)
endif()
else()
list(APPEND BUILD_APP_GRAPH_KEYS disabled)
set(BUILD_APP_VALUE_DISPLAY_disabled disabled)
list(APPEND BUILD_APP_VALUE_CONTAINS_disabled ${BUILD_APP})
endif()
endforeach()
list(SORT BUILD_APP_GRAPH_KEYS)
list(REMOVE_DUPLICATES BUILD_APP_GRAPH_KEYS)
# Display the graphs
message("")
message("* Apps build list (${APPS_BUILD}):")
message(" |")
foreach(BUILD_APP_GRAPH_KEY ${BUILD_APP_GRAPH_KEYS})
if(NOT BUILD_APP_GRAPH_KEY STREQUAL "disabled")
message(" +- ${BUILD_APP_VALUE_DISPLAY_${BUILD_APP_GRAPH_KEY}}")
else()
message(" | ${BUILD_APP_VALUE_DISPLAY_${BUILD_APP_GRAPH_KEY}}")
endif()
foreach(BUILD_APP_GRAPH_ENTRY ${BUILD_APP_VALUE_CONTAINS_${BUILD_APP_GRAPH_KEY}})
message(" | +- ${BUILD_APP_GRAPH_ENTRY}")
endforeach()
message(" |")
endforeach()
message("")
GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
# Generates the actual apps projects
foreach(APPLICATION_NAME ${APPLICATIONS_BUILD_LIST})
GetPathToApplication(${APPLICATION_NAME} SOURCE_APP_PATH)
ApplicationNameToVariable(${APPLICATION_NAME} BUILD_APP_VARIABLE)
if (${BUILD_APP_VARIABLE} STREQUAL "disabled")
continue()
endif()
unset(APP_PRIVATE_SOURCES)
CollectSourceFiles(
${SOURCE_APP_PATH}
APP_PRIVATE_SOURCES
# Exclude
${SOURCE_APP_PATH}/PrecompiledHeaders)
if (WIN32)
list(APPEND APP_PRIVATE_SOURCES ${winDebugging})
if (${APPLICATION_NAME} MATCHES "worldserver")
list(APPEND APP_PRIVATE_SOURCES ${winService})
endif()
if (MSVC)
list(APPEND APP_PRIVATE_SOURCES ${SOURCE_APP_PATH}/${APPLICATION_NAME}.rc)
endif()
endif()
GetProjectNameOfApplicationName(${APPLICATION_NAME} APP_PROJECT_NAME)
# Create the application project
add_executable(${APP_PROJECT_NAME}
${APP_PRIVATE_SOURCES})
add_dependencies(${APP_PROJECT_NAME} revision.h)
target_link_libraries(${APP_PROJECT_NAME}
PRIVATE
acore-core-interface)
if (${APP_PROJECT_NAME} MATCHES "authserver")
target_link_libraries(${APP_PROJECT_NAME}
PUBLIC
shared)
elseif(${APP_PROJECT_NAME} MATCHES "worldserver")
target_link_libraries(${APP_PROJECT_NAME}
PUBLIC
modules
scripts
game
gsoap
readline
gperftools)
if (UNIX AND NOT NOJEM)
set(${APP_PROJECT_NAME}_LINK_FLAGS "-pthread -lncurses ${${APP_PROJECT_NAME}_LINK_FLAGS}")
endif()
set_target_properties(${APP_PROJECT_NAME} PROPERTIES LINK_FLAGS "${${APP_PROJECT_NAME}_LINK_FLAGS}")
# Add all dynamic projects as dependency to the worldserver
if (WORLDSERVER_DYNAMIC_SCRIPT_MODULES_DEPENDENCIES)
add_dependencies(${APP_PROJECT_NAME} ${WORLDSERVER_DYNAMIC_SCRIPT_MODULES_DEPENDENCIES})
endif()
endif()
unset(APP_PUBLIC_INCLUDES)
CollectIncludeDirectories(
${SOURCE_APP_PATH}
APP_PUBLIC_INCLUDES
# Exclude
${SOURCE_APP_PATH}/PrecompiledHeaders)
target_include_directories(${APP_PROJECT_NAME}
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(${APP_PROJECT_NAME}
PUBLIC
${APP_PUBLIC_INCLUDES}
PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/${APPLICATION_NAME})
set_target_properties(${APP_PROJECT_NAME}
PROPERTIES
FOLDER
"server")
# Install config
CopyApplicationConfig(${APP_PROJECT_NAME} ${APPLICATION_NAME})
if (UNIX)
install(TARGETS ${APP_PROJECT_NAME} DESTINATION bin)
elseif (WIN32)
install(TARGETS ${APP_PROJECT_NAME} DESTINATION "${CMAKE_INSTALL_PREFIX}")
endif()
set(PATH_TO_PCH ${SOURCE_APP_PATH}/PrecompiledHeaders/${APPLICATION_NAME}PCH.h)
# Generate precompiled header
if (USE_COREPCH AND EXISTS ${PATH_TO_PCH})
add_cxx_pch(${APP_PROJECT_NAME} ${PATH_TO_PCH})
endif()
endforeach()

View File

@@ -41,8 +41,11 @@
#include "SharedDefines.h"
#include "Util.h"
#include <boost/asio/signal_set.hpp>
#include <boost/program_options.hpp>
#include <boost/version.hpp>
#include <csignal>
#include <filesystem>
#include <iostream>
#include <openssl/crypto.h>
#include <openssl/opensslv.h>
@@ -51,19 +54,15 @@
#endif
using boost::asio::ip::tcp;
using namespace boost::program_options;
namespace fs = std::filesystem;
bool StartDB();
void StopDB();
void SignalHandler(std::weak_ptr<Acore::Asio::IoContext> ioContextRef, boost::system::error_code const& error, int signalNumber);
void KeepDatabaseAliveHandler(std::weak_ptr<Acore::Asio::DeadlineTimer> dbPingTimerRef, int32 dbPingInterval, boost::system::error_code const& error);
void BanExpiryHandler(std::weak_ptr<Acore::Asio::DeadlineTimer> banExpiryCheckTimerRef, int32 banExpiryCheckInterval, boost::system::error_code const& error);
/// Print out the usage string for this program on the console.
void usage(const char* prog)
{
LOG_INFO("server.authserver", "Usage: \n {} [<options>]\n"
" -c config_file use config_file as configuration file\n\r", prog);
}
variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile);
/// Launch the auth server
int main(int argc, char** argv)
@@ -71,27 +70,16 @@ int main(int argc, char** argv)
Acore::Impl::CurrentServerProcessHolder::_type = SERVER_PROCESS_AUTHSERVER;
signal(SIGABRT, &Acore::AbortHandler);
// Command line parsing to get the configuration file name
std::string configFile = sConfigMgr->GetConfigPath() + std::string(_ACORE_REALM_CONFIG);
int count = 1;
while (count < argc)
{
if (strcmp(argv[count], "-c") == 0)
{
if (++count >= argc)
{
printf("Runtime-Error: -c option requires an input argument\n");
usage(argv[0]);
return 1;
}
else
configFile = argv[count];
}
++count;
}
// Command line parsing
auto configFile = fs::path(sConfigMgr->GetConfigPath() + std::string(_ACORE_REALM_CONFIG));
auto vm = GetConsoleArguments(argc, argv, configFile);
// exit if help or version is enabled
if (vm.count("help"))
return 0;
// Add file and args in config
sConfigMgr->Configure(configFile, std::vector<std::string>(argv, argv + argc));
sConfigMgr->Configure(configFile.generic_string(), std::vector<std::string>(argv, argv + argc));
if (!sConfigMgr->LoadAppConfigs())
return 1;
@@ -149,6 +137,13 @@ int main(int argc, char** argv)
return 1;
}
// Stop auth server if dry run
if (sConfigMgr->isDryRun())
{
LOG_INFO("server.authserver", "Dry run completed, terminating.");
return 0;
}
// Start the listening port (acceptor) for auth connections
int32 port = sConfigMgr->GetOption<int32>("RealmServerPort", 3724);
if (port < 0 || port > 0xFFFF)
@@ -268,3 +263,36 @@ void BanExpiryHandler(std::weak_ptr<Acore::Asio::DeadlineTimer> banExpiryCheckTi
}
}
}
variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile)
{
options_description all("Allowed options");
all.add_options()
("help,h", "print usage message")
("version,v", "print version build info")
("dry-run,d", "Dry run")
("config,c", value<fs::path>(&configFile)->default_value(fs::path(sConfigMgr->GetConfigPath() + std::string(_ACORE_REALM_CONFIG))), "use <arg> as configuration file");
variables_map variablesMap;
try
{
store(command_line_parser(argc, argv).options(all).allow_unregistered().run(), variablesMap);
notify(variablesMap);
}
catch (std::exception const& e)
{
std::cerr << e.what() << "\n";
}
if (variablesMap.count("help"))
{
std::cout << all << "\n";
}
else if (variablesMap.count("dry-run"))
{
sConfigMgr->setDryRun(true);
}
return variablesMap;
}

View File

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

@@ -36,6 +36,7 @@
#include "IoContext.h"
#include "MapMgr.h"
#include "Metric.h"
#include "ModuleMgr.h"
#include "ModulesScriptLoader.h"
#include "MySQLThreading.h"
#include "OpenSSLCrypto.h"
@@ -54,12 +55,12 @@
#include <boost/asio/signal_set.hpp>
#include <boost/program_options.hpp>
#include <csignal>
#include <filesystem>
#include <iostream>
#include <openssl/crypto.h>
#include <openssl/opensslv.h>
#include "ModuleMgr.h"
#ifdef _WIN32
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
#include "ServiceWin32.h"
char serviceName[] = "worldserver";
char serviceLongName[] = "AzerothCore world service";
@@ -78,6 +79,8 @@ int m_ServiceStatus = -1;
#endif
#define WORLD_SLEEP_CONST 10
using namespace boost::program_options;
namespace fs = std::filesystem;
class FreezeDetector
{
@@ -110,20 +113,7 @@ void ShutdownCLIThread(std::thread* cliThread);
void AuctionListingRunnable();
void ShutdownAuctionListingThread(std::thread* thread);
void WorldUpdateLoop();
/// Print out the usage string for this program on the console.
void usage(const char* prog)
{
printf("Usage:\n");
printf(" %s [<options>]\n", prog);
printf(" -c config_file use config_file as configuration file\n");
#ifdef _WIN32
printf(" Running as service functions:\n");
printf(" --service run as service\n");
printf(" -s install install service\n");
printf(" -s uninstall uninstall service\n");
#endif
}
variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, [[maybe_unused]] std::string& cfg_service);
/// Launch the Azeroth server
int main(int argc, char** argv)
@@ -131,66 +121,26 @@ int main(int argc, char** argv)
Acore::Impl::CurrentServerProcessHolder::_type = SERVER_PROCESS_WORLDSERVER;
signal(SIGABRT, &Acore::AbortHandler);
///- Command line parsing to get the configuration file name
std::string configFile = sConfigMgr->GetConfigPath() + std::string(_ACORE_CORE_CONFIG);
int c = 1;
while (c < argc)
{
if (strcmp(argv[c], "--dry-run") == 0)
{
sConfigMgr->setDryRun(true);
}
// Command line parsing
auto configFile = fs::path(sConfigMgr->GetConfigPath() + std::string(_ACORE_CORE_CONFIG));
std::string configService;
auto vm = GetConsoleArguments(argc, argv, configFile, configService);
if (!strcmp(argv[c], "-c"))
{
if (++c >= argc)
{
printf("Runtime-Error: -c option requires an input argument");
usage(argv[0]);
return 1;
}
else
configFile = argv[c];
}
// exit if help or version is enabled
if (vm.count("help"))
return 0;
#ifdef _WIN32
if (strcmp(argv[c], "-s") == 0) // Services
{
if (++c >= argc)
{
printf("Runtime-Error: -s option requires an input argument");
usage(argv[0]);
return 1;
}
if (strcmp(argv[c], "install") == 0)
{
if (WinServiceInstall())
printf("Installing service\n");
return 1;
}
else if (strcmp(argv[c], "uninstall") == 0)
{
if (WinServiceUninstall())
printf("Uninstalling service\n");
return 1;
}
else
{
printf("Runtime-Error: unsupported option %s", argv[c]);
usage(argv[0]);
return 1;
}
}
if (strcmp(argv[c], "--service") == 0)
WinServiceRun();
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
if (configService.compare("install") == 0)
return WinServiceInstall() == true ? 0 : 1;
else if (configService.compare("uninstall") == 0)
return WinServiceUninstall() == true ? 0 : 1;
else if (configService.compare("run") == 0)
WinServiceRun();
#endif
++c;
}
// Add file and args in config
sConfigMgr->Configure(configFile, { argv, argv + argc }, CONFIG_FILE_LIST);
sConfigMgr->Configure(configFile.generic_string(), {argv, argv + argc}, CONFIG_FILE_LIST);
if (!sConfigMgr->LoadAppConfigs())
return 1;
@@ -400,7 +350,7 @@ int main(int argc, char** argv)
// Launch CliRunnable thread
std::shared_ptr<std::thread> cliThread;
#ifdef _WIN32
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
if (sConfigMgr->GetOption<bool>("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/)
#else
if (sConfigMgr->GetOption<bool>("Console.Enable", true))
@@ -780,3 +730,44 @@ void ShutdownAuctionListingThread(std::thread* thread)
delete thread;
}
}
variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, [[maybe_unused]] std::string& configService)
{
options_description all("Allowed options");
all.add_options()
("help,h", "print usage message")
("version,v", "print version build info")
("dry-run,d", "Dry run")
("config,c", value<fs::path>(&configFile)->default_value(fs::path(sConfigMgr->GetConfigPath() + std::string(_ACORE_CORE_CONFIG))), "use <arg> as configuration file");
#if AC_PLATFORM == WARHEAD_PLATFORM_WINDOWS
options_description win("Windows platform specific options");
win.add_options()
("service,s", value<std::string>(&configService)->default_value(""), "Windows service options: [install | uninstall]");
all.add(win);
#endif
variables_map vm;
try
{
store(command_line_parser(argc, argv).options(all).allow_unregistered().run(), vm);
notify(vm);
}
catch (std::exception const& e)
{
std::cerr << e.what() << "\n";
}
if (vm.count("help"))
{
std::cout << all << "\n";
}
else if (vm.count("dry-run"))
{
sConfigMgr->setDryRun(true);
}
return vm;
}

View File

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

@@ -1,77 +0,0 @@
#
# This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
#
# 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.
#
########### authserver ###############
CollectSourceFiles(
${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE_SOURCES
# Exclude
${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
if( WIN32 )
list(APPEND PRIVATE_SOURCES ${winDebugging})
if ( MSVC )
list(APPEND PRIVATE_SOURCES authserver.rc)
endif()
endif()
if (USE_COREPCH)
set(PRIVATE_PCH_HEADER PrecompiledHeaders/authPCH.h)
endif()
# Group sources
GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
add_executable(authserver
${PRIVATE_SOURCES})
add_dependencies(authserver revision.h)
target_link_libraries(authserver
PRIVATE
acore-core-interface
PUBLIC
shared)
CollectIncludeDirectories(
${CMAKE_CURRENT_SOURCE_DIR}
PUBLIC_INCLUDES
# Exclude
${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
target_include_directories(authserver
PUBLIC
${PUBLIC_INCLUDES}
PRIVATE
${CMAKE_CURRENT_BINARY_DIR})
set_target_properties(authserver
PROPERTIES
FOLDER
"server")
# Install config
CopyDefaultConfig(authserver)
if ( UNIX )
install(TARGETS authserver DESTINATION bin)
elseif ( WIN32 )
install(TARGETS authserver DESTINATION "${CMAKE_INSTALL_PREFIX}")
endif()
# Generate precompiled header
if (USE_COREPCH)
add_cxx_pch(authserver ${PRIVATE_PCH_HEADER})
endif()
CU_RUN_HOOK("AFTER_AUTHSERVER_CMAKE")

View File

@@ -90,7 +90,7 @@ uint32 MySQLConnection::Open()
MYSQL* mysqlInit = mysql_init(nullptr);
if (!mysqlInit)
{
LOG_ERROR("sql.sql", "Could not initialize Mysql connection to database `{}`", m_connectionInfo.database);
LOG_ERROR("sql.driver", "Could not initialize Mysql connection to database `{}`", m_connectionInfo.database);
return CR_UNKNOWN_ERROR;
}
@@ -170,7 +170,7 @@ uint32 MySQLConnection::Open()
}
else
{
LOG_ERROR("sql.sql", "Could not connect to MySQL database at {}: {}", m_connectionInfo.host, mysql_error(mysqlInit));
LOG_ERROR("sql.driver", "Could not connect to MySQL database at {}: {}", m_connectionInfo.host, mysql_error(mysqlInit));
uint32 errorCode = mysql_errno(mysqlInit);
mysql_close(mysqlInit);
return errorCode;

View File

@@ -181,16 +181,6 @@ void Player::SendResetFailedNotify(uint32 mapid)
GetSession()->SendPacket(&data);
}
void DeleteInstanceSavedData(uint32 instanceId)
{
if (instanceId)
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DELETE_INSTANCE_SAVED_DATA);
stmt->SetData(0, instanceId);
CharacterDatabase.Execute(stmt);
}
}
/// Reset all solo instances and optionally send a message on success for each
void Player::ResetInstances(ObjectGuid guid, uint8 method, bool isRaid)
{
@@ -223,7 +213,7 @@ void Player::ResetInstances(ObjectGuid guid, uint8 method, bool isRaid)
p->SendResetInstanceFailed(0, instanceSave->GetMapId());
}
DeleteInstanceSavedData(instanceSave->GetInstanceId());
sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId());
}
for (std::vector<InstanceSave*>::const_iterator itr = toUnbind.begin(); itr != toUnbind.end(); ++itr)
{
@@ -258,7 +248,7 @@ void Player::ResetInstances(ObjectGuid guid, uint8 method, bool isRaid)
p->SendResetInstanceFailed(0, instanceSave->GetMapId());
}
DeleteInstanceSavedData(instanceSave->GetInstanceId());
sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId());
}
for (std::vector<InstanceSave*>::const_iterator itr = toUnbind.begin(); itr != toUnbind.end(); ++itr)
sInstanceSaveMgr->UnbindAllFor(*itr);
@@ -287,7 +277,7 @@ void Player::ResetInstances(ObjectGuid guid, uint8 method, bool isRaid)
//else
// p->SendResetInstanceFailed(0, instanceSave->GetMapId());
DeleteInstanceSavedData(instanceSave->GetInstanceId());
sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId());
}
for (std::vector<InstanceSave*>::const_iterator itr = toUnbind.begin(); itr != toUnbind.end(); ++itr)
sInstanceSaveMgr->PlayerUnbindInstance(p->GetGUID(), (*itr)->GetMapId(), (*itr)->GetDifficulty(), true, p);

View File

@@ -17950,7 +17950,9 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
if (GetTypeId() == TYPEID_UNIT)
{
GetMotionMaster()->Clear(false);
GetMotionMaster()->MoveIdle();
StopMoving();
if (charmer->GetTypeId() == TYPEID_PLAYER &&
charmer->getClass() == CLASS_WARLOCK)

View File

@@ -829,12 +829,7 @@ void Group::Disband(bool hideDestroy /* = false */)
}
// Cleaning up instance saved data for gameobjects when a group is disbanded
if (instanceId)
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DELETE_INSTANCE_SAVED_DATA);
stmt->SetData(0, instanceId);
CharacterDatabase.Execute(stmt);
}
sInstanceSaveMgr->DeleteInstanceSavedData(instanceId);
sGroupMgr->RemoveGroup(this);
delete this;
@@ -2037,16 +2032,6 @@ void Group::SetRaidDifficulty(Difficulty difficulty)
}
}
void Group::ResetInstanceSavedGameobjects(uint32 instanceId)
{
if (instanceId)
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DELETE_INSTANCE_SAVED_DATA);
stmt->SetData(0, instanceId);
CharacterDatabase.Execute(stmt);
}
}
void Group::ResetInstances(uint8 method, bool isRaid, Player* leader)
{
if (isBGGroup() || isBFGroup() || isLFGGroup())
@@ -2078,7 +2063,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* leader)
leader->SendResetInstanceFailed(0, instanceSave->GetMapId());
}
ResetInstanceSavedGameobjects(instanceSave->GetInstanceId());
sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId());
}
for (std::vector<InstanceSave*>::const_iterator itr = toUnbind.begin(); itr != toUnbind.end(); ++itr)
sInstanceSaveMgr->UnbindAllFor(*itr);
@@ -2106,7 +2091,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* leader)
leader->SendResetInstanceFailed(0, instanceSave->GetMapId());
}
ResetInstanceSavedGameobjects(instanceSave->GetInstanceId());
sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId());
}
for (std::vector<InstanceSave*>::const_iterator itr = toUnbind.begin(); itr != toUnbind.end(); ++itr)
sInstanceSaveMgr->UnbindAllFor(*itr);

View File

@@ -320,8 +320,6 @@ public:
void SetDifficultyChangePrevention(DifficultyPreventionChangeType type);
void DoForAllMembers(std::function<void(Player*)> const& worker);
// Reset Instance Gameobjects
void ResetInstanceSavedGameobjects(uint32 instanceId);
protected:
void _homebindIfInstance(Player* player);
void _cancelHomebindIfInstance(Player* player);

View File

@@ -132,6 +132,7 @@ bool InstanceSaveMgr::DeleteInstanceSaveIfNeeded(InstanceSave* save, bool skipMa
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INSTANCE_BY_INSTANCE);
stmt->SetData(0, save->GetInstanceId());
CharacterDatabase.Execute(stmt);
DeleteInstanceSavedData(save->GetInstanceId());
// clear respawn times (if map is loaded do it just to be sure, if already unloaded it won't do it by itself)
Map::DeleteRespawnTimesInDB(save->GetMapId(), save->GetInstanceId());
@@ -244,6 +245,16 @@ void InstanceSaveMgr::SanitizeInstanceSavedData()
CharacterDatabase.Execute(stmt);
}
void InstanceSaveMgr::DeleteInstanceSavedData(uint32 instanceId)
{
if (instanceId)
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DELETE_INSTANCE_SAVED_DATA);
stmt->SetData(0, instanceId);
CharacterDatabase.Execute(stmt);
}
}
void InstanceSaveMgr::LoadInstances()
{
uint32 oldMSTime = getMSTime();
@@ -512,6 +523,7 @@ void InstanceSaveMgr::_ResetSave(InstanceSaveHashMap::iterator& itr)
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INSTANCE_BY_INSTANCE);
stmt->SetData(0, itr->second->GetInstanceId());
CharacterDatabase.Execute(stmt);
DeleteInstanceSavedData(itr->second->GetInstanceId());
// clear respawn times if the map is already unloaded and won't do it by itself
if (!sMapMgr->FindMap(itr->second->GetMapId(), itr->second->GetInstanceId()))

View File

@@ -183,6 +183,7 @@ public:
void UnbindAllFor(InstanceSave* save);
void SanitizeInstanceSavedData();
void DeleteInstanceSavedData(uint32 instanceId);
protected:
static uint16 ResetTimeDelay[];
static PlayerBindStorage playerBindStorage;

View File

@@ -12,11 +12,8 @@
CU_RUN_HOOK(BEFORE_SCRIPTS_LIBRARY)
message("")
# Make the script module list available in the current scope
GetScriptModuleList(SCRIPT_MODULE_LIST)
GetModuleSourceList(MODULES_MODULE_LIST)
# Make the native install offset available in this scope
GetInstallOffset(INSTALL_OFFSET)
@@ -33,18 +30,6 @@ else()
set(SCRIPTS_DEFAULT_LINKAGE "disabled")
endif()
# Sets the MODULES_${SOURCE_MODULE} variables
# when using predefined templates for script building
# like dynamic, static
# Sets MODULES_DEFAULT_LINKAGE
if(MODULES MATCHES "dynamic")
set(MODULES_DEFAULT_LINKAGE "dynamic")
elseif(MODULES MATCHES "static")
set(MODULES_DEFAULT_LINKAGE "static")
else()
set(MODULES_DEFAULT_LINKAGE "disabled")
endif()
# Sets SCRIPTS_USE_WHITELIST
# Sets SCRIPTS_WHITELIST
if(SCRIPTS MATCHES "minimal")
@@ -93,8 +78,8 @@ list(SORT SCRIPT_GRAPH_KEYS)
list(REMOVE_DUPLICATES SCRIPT_GRAPH_KEYS)
# Display the script graph
message("* Script configuration (${SCRIPTS}):
|")
message("* Script configuration (${SCRIPTS}):")
message(" |")
foreach(SCRIPT_GRAPH_KEY ${SCRIPT_GRAPH_KEYS})
if(NOT SCRIPT_GRAPH_KEY STREQUAL "disabled")
@@ -108,10 +93,8 @@ foreach(SCRIPT_GRAPH_KEY ${SCRIPT_GRAPH_KEYS})
message(" |")
endforeach()
message("")
# Base sources which are used by every script project
if(USE_SCRIPTPCH)
if (USE_SCRIPTPCH)
set(PRIVATE_PCH_HEADER ScriptPCH.h)
endif()

View File

@@ -78,7 +78,7 @@ public:
{
uint32 CurrentSolakarWave = 0;
uint32 SolakarState = NOT_STARTED; // there should be a global instance encounter state, where is it?
std::vector<TempSummon*> SolakarSummons;
GuidVector SolakarSummons;
instance_blackrock_spireMapScript(InstanceMap* map) : InstanceScript(map)
{
@@ -360,11 +360,11 @@ public:
}
break;
case FAIL:
for (const auto& creature : SolakarSummons)
for (ObjectGuid const& guid : SolakarSummons)
{
if (creature)
if (Creature* creature = instance->GetCreature(guid))
{
creature->RemoveFromWorld();
creature->DespawnOrUnsummon();
}
}
SolakarSummons.clear();
@@ -429,11 +429,19 @@ public:
{
if (number < MAX_WAVE_COUNT)
{
SolakarSummons.push_back(instance->SummonCreature(NPC_ROOKERY_GUARDIAN, SolakarPosLeft));
SolakarSummons.push_back(instance->SummonCreature(NPC_ROOKERY_HATCHER, SolakarPosRight));
if (Creature* summon = instance->SummonCreature(NPC_ROOKERY_GUARDIAN, SolakarPosLeft))
{
SolakarSummons.push_back(summon->GetGUID());
}
if (Creature* summon = instance->SummonCreature(NPC_ROOKERY_HATCHER, SolakarPosRight))
{
SolakarSummons.push_back(summon->GetGUID());
}
if (number == 0)
{
if (Creature* FirstHatcher = SolakarSummons.back()) // works because we spawned a hatcher second
if (Creature* FirstHatcher = instance->GetCreature(SolakarSummons.back())) // works because we spawned a hatcher second
{
FirstHatcher->AI()->Talk(SAY_SOLAKAR_FIRST_HATCHER);
}
@@ -441,7 +449,10 @@ public:
}
else if (number == MAX_WAVE_COUNT)
{
SolakarSummons.push_back(instance->SummonCreature(NPC_SOLAKAR, SolakarPosBoss));
if (Creature* summon = instance->SummonCreature(NPC_SOLAKAR, SolakarPosBoss))
{
SolakarSummons.push_back(summon->GetGUID());
}
}
}

View File

@@ -29,7 +29,7 @@ EndScriptData */
enum Spells
{
SPELL_FROSTBREATH = 16099,
SPELL_MASSIVEGEYSER = 22421, // Not working. (summon)
SPELL_MASSIVEGEYSER = 22421,
SPELL_SLAM = 24326
};

View File

@@ -39,7 +39,7 @@ enum Spells
{
SPELL_BLOOD_SIPHON = 24322, // Buggy ?
SPELL_CORRUPTED_BLOOD = 24328,
SPELL_CAUSE_INSANITY = 24327, // Spell needs scripting.
SPELL_CAUSE_INSANITY = 24327,
SPELL_WILL_OF_HAKKAR = 24178,
SPELL_ENRAGE = 24318,
// The Aspects of all High Priests spells
@@ -54,7 +54,7 @@ enum Events
{
EVENT_BLOOD_SIPHON = 1,
EVENT_CORRUPTED_BLOOD = 2,
EVENT_CAUSE_INSANITY = 3, // Spell needs scripting. Event disabled
EVENT_CAUSE_INSANITY = 3,
EVENT_WILL_OF_HAKKAR = 4,
EVENT_ENRAGE = 5,
// The Aspects of all High Priests events
@@ -128,8 +128,11 @@ public:
events.ScheduleEvent(EVENT_CORRUPTED_BLOOD, urand(30000, 45000));
break;
case EVENT_CAUSE_INSANITY:
// DoCast(SelectTarget(SelectTargetMethod::Random, 0, 100, true), SPELL_CAUSE_INSANITY);
// events.ScheduleEvent(EVENT_CAUSE_INSANITY, urand(35000, 45000));
if (Unit* victim = SelectTarget(SelectTargetMethod::MaxThreat, 0))
{
DoCast(victim, SPELL_CAUSE_INSANITY, true);
}
events.ScheduleEvent(EVENT_CAUSE_INSANITY, urand(35000, 45000));
break;
case EVENT_WILL_OF_HAKKAR:
// Xinef: Skip Tank

View File

@@ -110,12 +110,7 @@ public:
events.ScheduleEvent(EVENT_POWERFULLHEALINGWARD, urand(14000, 20000));
break;
case EVENT_HEX:
if (Unit* target = me->GetVictim())
{
DoCast(target, SPELL_HEX, true);
if (DoGetThreat(target))
DoModifyThreatPercent(target, -80);
}
DoCastVictim(SPELL_HEX, true);
events.ScheduleEvent(EVENT_HEX, urand(12000, 20000));
break;
case EVENT_DELUSIONSOFJINDO: // HACK
@@ -174,6 +169,11 @@ public:
DoMeleeAttackIfReady();
}
bool CanAIAttack(Unit const* target) const override
{
return !target->HasAura(SPELL_HEX);
}
};
CreatureAI* GetAI(Creature* creature) const override

View File

@@ -78,6 +78,15 @@ public:
}
};
// The cleansing
enum TurmoilTexts
{
SAY_TURMOIL_0 = 0,
SAY_TURMOIL_1 = 1,
SAY_TURMOIL_HALF_HP = 2,
SAY_TURMOIL_DEATH = 3,
};
class npc_your_inner_turmoil : public CreatureScript
{
public:
@@ -89,16 +98,18 @@ public:
uint32 timer;
short phase;
bool health50;
void Reset() override
{
timer = 0;
phase = 0;
health50 = false;
}
void UpdateAI(uint32 diff) override
{
if (timer >= 6000 && phase < 4)
if (timer >= 6000 && phase < 2)
{
phase++;
setphase(phase);
@@ -110,6 +121,20 @@ public:
DoMeleeAttackIfReady();
}
void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override
{
if (HealthBelowPct(50) && !health50)
{
Talk(SAY_TURMOIL_HALF_HP, me->ToTempSummon()->GetSummonerUnit()->ToPlayer());
health50 = true;
}
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_TURMOIL_DEATH, me->ToTempSummon()->GetSummonerUnit()->ToPlayer());
}
void setphase(short newPhase)
{
Unit* summoner = me->ToTempSummon() ? me->ToTempSummon()->GetSummonerUnit() : nullptr;
@@ -119,16 +144,11 @@ public:
switch (newPhase)
{
case 1:
me->Whisper("You think that you can get rid of me through meditation?", LANG_UNIVERSAL, summoner->ToPlayer());
Talk(SAY_TURMOIL_0, summoner->ToPlayer());
return;
case 2:
me->Whisper("Fool! I will destroy you and finally become that which has been building inside of you all these years!", LANG_UNIVERSAL, summoner->ToPlayer());
return;
case 3:
me->Whisper("You cannot defeat me. I'm an inseparable part of you!", LANG_UNIVERSAL, summoner->ToPlayer());
return;
case 4:
me->Whisper("NOOOOOOOoooooooooo!", LANG_UNIVERSAL, summoner->ToPlayer());
{
Talk(SAY_TURMOIL_1, summoner->ToPlayer());
me->SetLevel(summoner->getLevel());
me->SetFaction(FACTION_MONSTER);
if (me->GetExactDist(summoner) < 50.0f)
@@ -137,6 +157,7 @@ public:
summoner->CastSpell(me, 50218, true); // clone caster
AttackStart(summoner);
}
}
}
}
};

View File

@@ -85,6 +85,7 @@ enum AHerosBurden
NPC_JALOOT = 28667,
NPC_ZEPIK = 28668,
NPC_ARTRUIS = 28659,
EVENT_CAST_FROST_BOLT = 1,
EVENT_CAST_FROST_NOVA = 2,
@@ -99,6 +100,16 @@ enum AHerosBurden
ACTION_MAKE_FRIENDLY = 2,
GO_ARTRUIS_PHYLACTERY = 190777,
// Texts
SAY_TURNED_FRIENDLY = 0, // Zepik and Jaloot
SAY_ARTRUIS_AGGRO = 0,
SAY_ARTRUIS_TALK_1 = 1,
SAY_ARTRUIS_TALK_2 = 2,
SAY_ARTRUIS_TALK_3 = 3,
SAY_ARTRUIS_SHIELD = 4, // Boss emote
SAY_ARTRUIS_TALK_4 = 5,
};
class npc_artruis_the_hearthless : public CreatureScript
@@ -143,7 +154,7 @@ public:
void EnterCombat(Unit* /*who*/) override
{
me->Yell("Ah, the heroes. Your little friends said you would come. This certainly saves me the trouble of hunting you down myself.", LANG_UNIVERSAL);
Talk(SAY_ARTRUIS_AGGRO);
me->CastSpell(me, SPELL_ARTRUIS_ICY_VEINS, true);
events.RescheduleEvent(EVENT_CAST_FROST_BOLT, 4000);
events.RescheduleEvent(EVENT_CAST_FROST_NOVA, 15000);
@@ -187,7 +198,7 @@ public:
}
else if (action == ACTION_MAKE_FRIENDLY && me->GetVictim())
{
minion->Say("Now you not catch us with back turned! Now we hurt you bad undead. BAD!", LANG_UNIVERSAL);
minion->AI()->Talk(SAY_TURNED_FRIENDLY);
minion->RemoveAurasDueToSpell(SPELL_ARTRUIS_BINDING);
minion->SetFaction(me->GetVictim()->GetFaction());
minion->AddThreat(me, 100000.0f);
@@ -215,21 +226,22 @@ public:
if (me->GetHealthPct() <= 30)
{
me->SetControlled(true, UNIT_STATE_STUNNED);
me->TextEmote("Artruis is shielded. You must choose your side quickly to break his spell.", nullptr, true);
Talk(SAY_ARTRUIS_SHIELD);
Talk(SAY_ARTRUIS_TALK_3);
SummonsAction(ACTION_BIND_MINIONS);
break;
}
events.RepeatEvent(1000);
break;
case EVENT_ARTRUIS_TALK1:
me->Yell("I have weathered a hundred years of war and suffering. Do you truly think it wise to pit your mortal bodies against a being that cannot die? I'd venture you have more to lose.", LANG_UNIVERSAL);
Talk(SAY_ARTRUIS_TALK_1);
events.RescheduleEvent(EVENT_ARTRUIS_TALK2, 10000);
break;
case EVENT_ARTRUIS_TALK2:
me->Yell("Even shattered into countless pieces, the crystals all around weaken me... perhaps i should not have underestimated the titans so...", LANG_UNIVERSAL);
Talk(SAY_ARTRUIS_TALK_2);
break;
case EVENT_ARTRUIS_TALK3:
me->Yell("Arthas once mustered strength... of the very same sort... perhaps he is the path that you will follow.", LANG_UNIVERSAL);
Talk(SAY_ARTRUIS_TALK_4);
break;
case EVENT_CAST_FROST_BOLT:
me->CastSpell(me->GetVictim(), SPELL_ARTRUIS_FROSTBOLT, false);
@@ -261,24 +273,24 @@ public:
quest Still At It (12644)
******/
#define MCM_TEXT_START "Beginning the distillation in 5 seconds."
#define MCM_TEXT_PRESSURE "Pressure's too high! Open the pressure valve!"
#define MCM_TEXT_HEAT "The still needs heat! Light the brazier!"
#define MCM_TEXT_BANANA "Add bananas!"
#define MCM_TEXT_ORANGE "Add another orange! Quickly!"
#define MCM_TEXT_PAPAYA "Put a papaya in the still!"
#define MCM_TEXT_CORRECT1 "Nicely handled! Stay on your toes!"
#define MCM_TEXT_CORRECT2 "That'll do. Never know what it'll need next..."
#define MCM_TEXT_CORRECT3 "Good job! Keep your eyes open, now."
#define MCM_TEXT_SUCCESS1 "Well done! Be ready for anything!"
#define MCM_TEXT_SUCCESS2 "We've done it! Come get the cask."
#define MCM_TEXT_FAILED "You have FAILED!!!"
#define ACTION_PRESSURE 1
#define ACTION_HEAT 2
//#define ACTION_BANANA 3
//#define ACTION_ORANGE 4
//#define ACTION_PAPAYA 5
#define NPC_WANTS_BANANAS 28537
enum StillAtIt
{
NPC_MANUS = 28566,
NPC_WANTS_BANANAS = 28537,
QUEST_STILL_AT_IT = 12644,
GOSSIP_MANUS_MENU = 9713,
SAY_MANUS_START = 0,
SAY_MANUS_ORANGE = 1,
SAY_MANUS_PAPAYA = 2,
SAY_MANUS_BANANA = 3,
SAY_MANUS_PRESSUE = 4,
SAY_MANUS_HEAT = 5,
SAY_MANUS_WELL_DONE = 6,
SAY_MANUS_FAILED = 7,
SAY_MANUS_END = 8,
};
class npc_still_at_it_trigger : public CreatureScript
{
@@ -305,6 +317,8 @@ public:
npc_still_at_it_triggerAI(Creature* pCreature) : NullCreatureAI(pCreature) {}
Creature* GetManus() {return ObjectAccessor::GetCreature(*me, thunderbrewGUID);}
void Reset() override
{
running = false;
@@ -324,20 +338,12 @@ public:
damage = 0;
}
void Say(const char* text)
{
if (Creature* th = ObjectAccessor::GetCreature(*me, thunderbrewGUID))
th->Say(text, LANG_UNIVERSAL);
else
Reset();
}
void Start()
{
timer = 5000;
running = true;
stepcount = urand(5, 10);
Say(MCM_TEXT_START);
GetManus()->AI()->Talk(SAY_MANUS_START);
}
void CheckAction(uint8 a, ObjectGuid guid)
@@ -348,27 +354,15 @@ public:
if (a == expectedaction)
{
currentstep++;
uint8 s = urand(0, 2);
if (Creature* th = ObjectAccessor::GetCreature(*me, thunderbrewGUID))
th->HandleEmoteCommand(EMOTE_ONESHOT_CHEER_NO_SHEATHE);
switch (s)
{
case 0:
Say(MCM_TEXT_CORRECT1);
break;
case 1:
Say(MCM_TEXT_CORRECT2);
break;
default:
Say(MCM_TEXT_CORRECT3);
break;
}
GetManus()->AI()->Talk(SAY_MANUS_WELL_DONE);
if (currentstep >= stepcount)
{
Say(MCM_TEXT_SUCCESS1);
GetManus()->AI()->Talk(SAY_MANUS_WELL_DONE);
success = true;
timer = 3000;
}
@@ -380,7 +374,7 @@ public:
}
else
{
Say(MCM_TEXT_FAILED);
GetManus()->AI()->Talk(SAY_MANUS_FAILED);
Reset();
}
}
@@ -417,15 +411,15 @@ public:
if( timer < 0 )
timer = 0;
}
else if ( success)
else if (success)
{
Say(MCM_TEXT_SUCCESS2);
me->SummonGameObject(190643, 5546.55f, 5768.0f, -78.03f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 60000);
GetManus()->AI()->Talk(SAY_MANUS_END);
me->SummonGameObject(190643, 5546.55f, 5768.0f, -78.03f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0);
Reset();
}
else if (expectedaction != 0) // didn't make it in 10 seconds
{
Say(MCM_TEXT_FAILED);
GetManus()->AI()->Talk(SAY_MANUS_FAILED);
Reset();
}
else // it's time to rand next move
@@ -434,19 +428,19 @@ public:
switch (expectedaction)
{
case 1:
Say(MCM_TEXT_PRESSURE);
GetManus()->AI()->Talk(SAY_MANUS_PRESSUE);
break;
case 2:
Say(MCM_TEXT_HEAT);
GetManus()->AI()->Talk(SAY_MANUS_HEAT);
break;
case 3:
Say(MCM_TEXT_BANANA);
GetManus()->AI()->Talk(SAY_MANUS_BANANA);
break;
case 4:
Say(MCM_TEXT_ORANGE);
GetManus()->AI()->Talk(SAY_MANUS_ORANGE);
break;
case 5:
Say(MCM_TEXT_PAPAYA);
GetManus()->AI()->Talk(SAY_MANUS_PAPAYA);
break;
}
timer = 10000;
@@ -469,8 +463,8 @@ public:
if (creature->IsQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
if (player->GetQuestStatus(12644) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "I'm ready to start the distillation, uh, Tipsy.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
if (player->GetQuestStatus(QUEST_STILL_AT_IT) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, GOSSIP_MANUS_MENU, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID());
return true;
@@ -541,13 +535,13 @@ public:
## npc_vekjik
######*/
#define GOSSIP_VEKJIK_ITEM1 "Shaman Vekjik, I have spoken with the big-tongues and they desire peace. I have brought this offering on their behalf."
#define GOSSIP_VEKJIK_ITEM2 "No no... I had no intentions of betraying your people. I was only defending myself. it was all a misunderstanding."
enum Vekjik
{
GOSSIP_TEXTID_VEKJIK1 = 13137,
GOSSIP_TEXTID_VEKJIK2 = 13138,
GOSSIP_VEKJIK_MENU_1 = 9678,
GOSSIP_VEKJIK_MENU_2 = 9686,
GOSSIP_TEXTID_VEKJIK_1 = 13137,
GOSSIP_TEXTID_VEKJIK_2 = 13138,
SAY_TEXTID_VEKJIK1 = 0,
@@ -568,8 +562,8 @@ public:
if (player->GetQuestStatus(QUEST_MAKING_PEACE) == QUEST_STATUS_INCOMPLETE)
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_VEKJIK_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
SendGossipMenuFor(player, GOSSIP_TEXTID_VEKJIK1, creature->GetGUID());
AddGossipItemFor(player, GOSSIP_VEKJIK_MENU_1, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
SendGossipMenuFor(player, GOSSIP_TEXTID_VEKJIK_1, creature->GetGUID());
return true;
}
@@ -583,8 +577,8 @@ public:
switch (action)
{
case GOSSIP_ACTION_INFO_DEF+1:
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_VEKJIK_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
SendGossipMenuFor(player, GOSSIP_TEXTID_VEKJIK2, creature->GetGUID());
AddGossipItemFor(player, GOSSIP_VEKJIK_MENU_2, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
SendGossipMenuFor(player, GOSSIP_TEXTID_VEKJIK_2, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
CloseGossipMenuFor(player);
@@ -603,19 +597,19 @@ public:
## avatar_of_freya
######*/
#define GOSSIP_ITEM_AOF1 "I want to stop the Scourge as much as you do. How can I help?"
#define GOSSIP_ITEM_AOF2 "You can trust me. I am no friend of the Lich King."
#define GOSSIP_ITEM_AOF3 "I will not fail."
enum Freya
{
QUEST_FREYA_PACT = 12621,
SPELL_FREYA_CONVERSATION = 52045,
GOSSIP_TEXTID_AVATAR1 = 13303,
GOSSIP_TEXTID_AVATAR2 = 13304,
GOSSIP_TEXTID_AVATAR3 = 13305
GOSSIP_AVATAR_MENU_1 = 9720,
GOSSIP_AVATAR_MENU_2 = 9721,
GOSSIP_AVATAR_MENU_3 = 9722,
GOSSIP_TEXTID_AVATAR_1 = 13303,
GOSSIP_TEXTID_AVATAR_2 = 13304,
GOSSIP_TEXTID_AVATAR_3 = 13305,
};
class npc_avatar_of_freya : public CreatureScript
@@ -629,9 +623,9 @@ public:
player->PrepareQuestMenu(creature->GetGUID());
if (player->GetQuestStatus(QUEST_FREYA_PACT) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
AddGossipItemFor(player, GOSSIP_AVATAR_MENU_1, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
SendGossipMenuFor(player, GOSSIP_TEXTID_AVATAR1, creature);
SendGossipMenuFor(player, GOSSIP_TEXTID_AVATAR_1, creature);
return true;
}
@@ -641,12 +635,12 @@ public:
switch (action)
{
case GOSSIP_ACTION_INFO_DEF+1:
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
SendGossipMenuFor(player, GOSSIP_TEXTID_AVATAR2, creature);
AddGossipItemFor(player, GOSSIP_AVATAR_MENU_2, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
SendGossipMenuFor(player, GOSSIP_TEXTID_AVATAR_2, creature);
break;
case GOSSIP_ACTION_INFO_DEF+2:
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
SendGossipMenuFor(player, GOSSIP_TEXTID_AVATAR3, creature);
AddGossipItemFor(player, GOSSIP_AVATAR_MENU_3, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
SendGossipMenuFor(player, GOSSIP_TEXTID_AVATAR_3, creature);
break;
case GOSSIP_ACTION_INFO_DEF+3:
player->CastSpell(player, SPELL_FREYA_CONVERSATION, true);
@@ -828,8 +822,6 @@ public:
## npc_jungle_punch_target
#####*/
constexpr auto SAY_OFFER = "Care to try Grimbooze Thunderbrew's new jungle punch?";
enum JunglePunch
{
ITEM_TANKARD = 2705,
@@ -846,7 +838,10 @@ enum JunglePunch
SAY_HEMET_HADRIUS_TAMARA_3 = 2,
SAY_HEMET_4 = 3, // unused
SAY_HEMET_5 = 4 // unused
SAY_HEMET_5 = 4, // unused
// Player Say
SAY_OFFER = 28558,
};
enum NesingwaryChildrensWeek
@@ -1013,7 +1008,7 @@ public:
continue;
player->KilledMonsterCredit(me->GetEntry());
player->Say(SAY_OFFER, LANG_UNIVERSAL);
player->Say(SAY_OFFER);
sayStep = 1;
break;
}
@@ -1038,10 +1033,6 @@ public:
## npc_adventurous_dwarf
######*/
#define GOSSIP_OPTION_ORANGE "Can you spare an orange?"
#define GOSSIP_OPTION_BANANAS "Have a spare bunch of bananas?"
#define GOSSIP_OPTION_PAPAYA "I could really use a papaya."
enum AdventurousDwarf
{
QUEST_12634 = 12634,
@@ -1054,10 +1045,14 @@ enum AdventurousDwarf
SPELL_ADD_BANANAS = 52074,
SPELL_ADD_PAPAYA = 52076,
GOSSIP_MENU_DWARF = 13307,
SAY_DWARF_OUCH = 0,
SAY_DWARF_HELP = 1
SAY_DWARF_HELP = 1,
// Gossips
GOSSIP_DWARF_MENU = 9724,
GOSSIP_DWARF_ORANGE = 0,
GOSSIP_DWARF_BANANA = 1,
GOSSIP_DWARF_PAPAYA = 2,
};
class npc_adventurous_dwarf : public CreatureScript
@@ -1084,15 +1079,15 @@ public:
return false;
if (player->GetItemCount(ITEM_ORANGE) < 1)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_OPTION_ORANGE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
AddGossipItemFor(player, GOSSIP_DWARF_MENU, GOSSIP_DWARF_ORANGE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
if (player->GetItemCount(ITEM_BANANAS) < 2)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_OPTION_BANANAS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
AddGossipItemFor(player, GOSSIP_DWARF_MENU, GOSSIP_DWARF_BANANA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
if (player->GetItemCount(ITEM_PAPAYA) < 1)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_OPTION_PAPAYA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
AddGossipItemFor(player, GOSSIP_DWARF_MENU, GOSSIP_DWARF_PAPAYA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
SendGossipMenuFor(player, GOSSIP_MENU_DWARF, creature);
SendGossipMenuFor(player, player->GetGossipTextId(creature), creature);
return true;
}

View File

@@ -41,6 +41,8 @@ enum eWGqueuenpctext
WG_NPCQUEUE_TEXT_A_QUEUE = 14791,
WG_NPCQUEUE_TEXT_A_WAR = 14781,
WG_NPCQUEUE_TEXTOPTION_JOIN = -1850507,
WG_GOSSIP_MENU_QUEUE = 10662,
};
enum Spells
@@ -295,7 +297,7 @@ public:
if (wintergrasp->IsWarTime())
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT_19, "Queue for Wintergrasp.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
AddGossipItemFor(player, WG_GOSSIP_MENU_QUEUE, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
SendGossipMenuFor(player, wintergrasp->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_WAR : WG_NPCQUEUE_TEXT_A_WAR, creature->GetGUID());
}
else
@@ -304,7 +306,7 @@ public:
player->SendUpdateWorldState(4354, GameTime::GetGameTime().count() + timer);
if (timer < 15 * MINUTE)
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Queue for Wintergrasp.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
AddGossipItemFor(player, WG_GOSSIP_MENU_QUEUE, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
SendGossipMenuFor(player, wintergrasp->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_QUEUE : WG_NPCQUEUE_TEXT_A_QUEUE, creature->GetGUID());
}
else

View File

@@ -19,7 +19,6 @@
#define ACORE_SHAREDDEFINES_H
#include "Define.h"
#include "DetourNavMesh.h"
#include "EnumFlag.h"
#include <cassert>

View File

@@ -1,91 +0,0 @@
#
# This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
#
# 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.
#
CollectSourceFiles(
${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE_SOURCES
# Exclude
${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
if( WIN32 )
list(APPEND PRIVATE_SOURCES ${winDebugging} ${winService})
if ( MSVC )
list(APPEND PRIVATE_SOURCES worldserver.rc)
endif()
endif()
if (USE_COREPCH)
set(PRIVATE_PCH_HEADER PrecompiledHeaders/worldPCH.h)
endif()
# Group sources
GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
add_executable(worldserver
${PRIVATE_SOURCES})
add_dependencies(worldserver revision.h)
if(UNIX AND NOT NOJEM)
set(worldserver_LINK_FLAGS "-pthread -lncurses ${worldserver_LINK_FLAGS}")
endif()
set_target_properties(worldserver PROPERTIES LINK_FLAGS "${worldserver_LINK_FLAGS}")
CollectIncludeDirectories(
${CMAKE_CURRENT_SOURCE_DIR}
PUBLIC_INCLUDES
# Exclude
${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
target_include_directories(worldserver
PUBLIC
${PUBLIC_INCLUDES}
PRIVATE
${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(worldserver
PRIVATE
acore-core-interface
PUBLIC
modules
scripts
game
gsoap
readline
gperftools)
set_target_properties(worldserver
PROPERTIES
FOLDER
"server")
# Add all dynamic projects as dependency to the worldserver
if(WORLDSERVER_DYNAMIC_SCRIPT_MODULES_DEPENDENCIES)
add_dependencies(worldserver ${WORLDSERVER_DYNAMIC_SCRIPT_MODULES_DEPENDENCIES})
endif()
# Install config
CopyDefaultConfig(worldserver)
if( UNIX )
install(TARGETS worldserver DESTINATION bin)
elseif( WIN32 )
install(TARGETS worldserver DESTINATION "${CMAKE_INSTALL_PREFIX}")
endif()
# Generate precompiled header
if( USE_COREPCH )
add_cxx_pch(worldserver ${PRIVATE_PCH_HEADER})
endif()
CU_RUN_HOOK("AFTER_WORLDSERVER_CMAKE")