Explorar o código

* Merged changes from trunk [14895:14966/trunk].

git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/renewal@14967 54d463be-8e91-2dee-dedb-b68131a5f0ec
ai4rei %!s(int64=13) %!d(string=hai) anos
pai
achega
6a6aa10721
Modificáronse 88 ficheiros con 2669 adicións e 1391 borrados
  1. 1 0
      3rdparty/CMakeLists.txt
  2. 47 0
      3rdparty/cmake/FindFunctionLibrary.cmake
  3. 2 0
      3rdparty/cmake/FindMYSQL.cmake
  4. 3 2
      3rdparty/cmake/FindPCRE.cmake
  5. 3 2
      3rdparty/msinttypes/CMakeLists.txt
  6. 4 0
      3rdparty/msinttypes/include/stdint.h
  7. 0 1
      3rdparty/mysql/CMakeLists.txt
  8. 0 1
      3rdparty/pcre/CMakeLists.txt
  9. BIN=BIN
      3rdparty/pcre/lib/libpcre.dll.a
  10. 383 43
      CMakeLists.txt
  11. 2 0
      Changelog-Renewal.txt
  12. 2 0
      conf/Changelog.txt
  13. 8 0
      conf/battle/client.conf
  14. 42 0
      conf/mapflag/reset.txt
  15. 41 0
      conf/mapflag/restricted.txt
  16. 49 0
      configure
  17. 16 0
      configure.in
  18. 17 0
      db/Changelog.txt
  19. 45 28
      db/item_noequip.txt
  20. 20 20
      db/mob_skill_db.txt
  21. 1 1
      db/packet_db.txt
  22. 1 1
      db/skill_cast_db.txt
  23. 27 9
      db/skill_nocast_db.txt
  24. 31 12
      doc/script_commands.txt
  25. 10 0
      npc/Changelog.txt
  26. 1 1
      npc/cities/alberta.txt
  27. 20 1
      npc/guides/guides_brasilis.txt
  28. 5 5
      npc/instances/NydhoggsNest.txt
  29. 1 1
      npc/jobs/2-1/blacksmith.txt
  30. 2 1
      npc/jobs/2-2/sage.txt
  31. 1 1
      npc/quests/first_class/tu_archer.txt
  32. 1 1
      npc/quests/quests_amatsu.txt
  33. 5 5
      npc/quests/quests_brasilis.txt
  34. 9 9
      npc/quests/quests_hugel.txt
  35. 1 0
      npc/scripts_mapflags.conf
  36. 477 393
      sql-files/item_db.sql
  37. 2 2
      sql-files/mob_db.sql
  38. 20 2
      src/CMakeLists.txt
  39. 29 27
      src/char/CMakeLists.txt
  40. 26 16
      src/char/char.c
  41. 12 11
      src/char_sql/CMakeLists.txt
  42. 86 39
      src/char_sql/char.c
  43. 3 2
      src/char_sql/int_quest.c
  44. 11 11
      src/common/CMakeLists.txt
  45. 39 0
      src/common/cbasetypes.h
  46. 0 4
      src/common/core.c
  47. 3 3
      src/common/db.h
  48. 4 4
      src/common/grfio.c
  49. 2 2
      src/common/grfio.h
  50. 82 51
      src/common/malloc.c
  51. 18 84
      src/common/malloc.h
  52. 1 1
      src/common/plugin.h
  53. 40 13
      src/common/socket.c
  54. 2 2
      src/common/strlib.c
  55. 3 1
      src/login/CMakeLists.txt
  56. 4 4
      src/login/account_txt.c
  57. 15 19
      src/login/sql/CMakeLists.txt
  58. 15 19
      src/login/txt/CMakeLists.txt
  59. 3 1
      src/map/CMakeLists.txt
  60. 11 7
      src/map/atcommand.c
  61. 1 0
      src/map/battle.c
  62. 1 0
      src/map/battle.h
  63. 2 0
      src/map/chrif.c
  64. 172 76
      src/map/clif.c
  65. 3 2
      src/map/clif.h
  66. 1 1
      src/map/itemdb.h
  67. 5 5
      src/map/map.c
  68. 1 0
      src/map/map.h
  69. 23 15
      src/map/mob.c
  70. 3 1
      src/map/npc.c
  71. 7 7
      src/map/npc_chat.c
  72. 29 57
      src/map/pc.c
  73. 0 2
      src/map/pc.h
  74. 46 27
      src/map/script.c
  75. 2 2
      src/map/searchstore.c
  76. 44 46
      src/map/skill.c
  77. 82 84
      src/map/sql/CMakeLists.txt
  78. 87 91
      src/map/status.c
  79. 2 1
      src/map/status.h
  80. 82 84
      src/map/txt/CMakeLists.txt
  81. 16 15
      src/map/unit.c
  82. 180 0
      src/plugins/CMakeLists.txt
  83. 6 1
      src/plugins/sig.c
  84. 11 10
      src/tool/CMakeLists.txt
  85. 1 1
      src/tool/mapcache.c
  86. 17 0
      src/txt-converter/CMakeLists.txt
  87. 76 0
      src/txt-converter/char/CMakeLists.txt
  88. 60 0
      src/txt-converter/login/CMakeLists.txt

+ 1 - 0
3rdparty/CMakeLists.txt

@@ -47,6 +47,7 @@ macro( CONFIGURE_WITH_LOCAL_OR_SYSTEM name )
 endmacro( CONFIGURE_WITH_LOCAL_OR_SYSTEM )
 
 
+set( CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake  CACHE INTERNAL "" )
 add_subdirectory( msinttypes )
 add_subdirectory( mt19937ar )
 add_subdirectory( mysql )

+ 47 - 0
3rdparty/cmake/FindFunctionLibrary.cmake

@@ -0,0 +1,47 @@
+# - Check which library is needed to link a C function
+# find_function_library( <function> <variable> [<library> ...] )
+#
+# Check which library provides the <function>.
+# Sets <variable> to 0 if found in the global libraries.
+# Sets <variable> to the library path if found in the provided libraries.
+# Raises a FATAL_ERROR if not found.
+#
+# The following variables may be set before calling this macro to
+# modify the way the check is run:
+#
+#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
+#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+#  CMAKE_REQUIRED_INCLUDES = list of include directories
+#  CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+include( CheckFunctionExists )
+
+macro( find_function_library FUNC VAR )
+	if( "${VAR}" MATCHES "^${VAR}$" )
+		CHECK_FUNCTION_EXISTS( ${FUNC} ${VAR} )
+		if( ${VAR} )
+			message( STATUS "Found ${FUNC} in global libraries" )
+			set( ${VAR} 0 CACHE INTERNAL "Found ${FUNC} in global libraries" )# global
+		else()
+			foreach( LIB IN ITEMS ${ARGN} )
+				message( STATUS "Looking for ${FUNC} in ${LIB}" )
+				find_library( ${LIB}_LIBRARY ${LIB} )
+				mark_as_advanced( ${LIB}_LIBRARY )
+				if( ${LIB}_LIBRARY )
+					unset( ${VAR} CACHE )
+					set( CMAKE_REQUIRED_LIBRARIES ${${LIB}_LIBRARY} )
+					CHECK_FUNCTION_EXISTS( ${FUNC} ${VAR} )
+					set( CMAKE_REQUIRED_LIBRARIES )
+					if( ${VAR} )
+						message( STATUS "Found ${FUNC} in ${LIB}: ${${LIB}_LIBRARY}" )
+						set( ${VAR} ${${LIB}_LIBRARY} CACHE INTERNAL "Found ${FUNC} in ${LIB}" )# lib
+						break()
+					endif()
+				endif()
+			endforeach()
+			if( NOT ${VAR} )
+				message( FATAL_ERROR "Function ${FUNC} not found" )
+			endif()
+		endif()
+	endif()
+endmacro( find_function_library )
+

+ 2 - 0
3rdparty/mysql/FindMYSQL.cmake → 3rdparty/cmake/FindMYSQL.cmake

@@ -10,6 +10,7 @@ find_path( MYSQL_INCLUDE_DIRS "mysql.h"
 	PATHS
 		"/usr/include/mysql"
 		"/usr/local/include/mysql"
+		"/usr/mysql/include/mysql"
 		"$ENV{PROGRAMFILES}/MySQL/*/include"
 		"$ENV{SYSTEMDRIVE}/MySQL/*/include" )
 
@@ -18,6 +19,7 @@ find_library( MYSQL_LIBRARIES
 	PATHS
 		"/usr/lib/mysql"
 		"/usr/local/lib/mysql"
+		"/usr/mysql/lib/mysql"
 		"$ENV{PROGRAMFILES}/MySQL/*/lib"
 		"$ENV{SYSTEMDRIVE}/MySQL/*/lib" )
 mark_as_advanced( MYSQL_LIBRARIES  MYSQL_INCLUDE_DIRS )

+ 3 - 2
3rdparty/pcre/FindPCRE.cmake → 3rdparty/cmake/FindPCRE.cmake

@@ -6,8 +6,9 @@
 #  PCRE_FOUND        - True if pcre found.
 
 
-find_path( PCRE_INCLUDE_DIR pcre.h )
-
+find_path( PCRE_INCLUDE_DIR pcre.h
+	PATHS
+		"/usr/include/pcre" )
 set( PCRE_NAMES pcre )
 find_library( PCRE_LIBRARY NAMES ${PCRE_NAMES} )
 mark_as_advanced( PCRE_LIBRARY PCRE_INCLUDE_DIR )

+ 3 - 2
3rdparty/msinttypes/CMakeLists.txt

@@ -1,8 +1,9 @@
 
-if( WIN32 )
+if( MSVC )
 find_path( MSINTTYPES_INCLUDE_DIRS "inttypes.h"
 	PATHS "${CMAKE_CURRENT_SOURCE_DIR}/include"
 	NO_DEFAULT_PATH )
 mark_as_advanced( MSINTTYPES_INCLUDE_DIRS )
-set( GLOBAL_INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ${MSINTTYPES_INCLUDE_DIRS} CACHE INTERNAL "" )
+message( STATUS "Adding global include directory: ${MSINTTYPES_INCLUDE_DIRS}" )
+set_property( CACHE GLOBAL_INCLUDE_DIRS  PROPERTY VALUE ${GLOBAL_INCLUDE_DIRS} ${MSINTTYPES_INCLUDE_DIRS} )
 endif()

+ 4 - 0
3rdparty/msinttypes/include/stdint.h

@@ -47,8 +47,12 @@
 // or compiler give many errors like this:
 //   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
 #ifdef __cplusplus
+#if _MSC_VER < 1300
+extern "C++" {
+#else
 extern "C" {
 #endif
+#endif
 #  include <wchar.h>
 #ifdef __cplusplus
 }

+ 0 - 1
3rdparty/mysql/CMakeLists.txt

@@ -44,7 +44,6 @@ endif( WIN32 )
 message( STATUS "Detecting system MYSQL" )
 unset( MYSQL_LIBRARIES CACHE )
 unset( MYSQL_INCLUDE_DIRS CACHE )
-set( CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_MODULE_PATH} )
 find_package( MYSQL )
 set( MYSQL_SYSTEM_LIBRARIES "${MYSQL_LIBRARIES}"
 	CACHE PATH "system mysql libraries" )

+ 0 - 1
3rdparty/pcre/CMakeLists.txt

@@ -39,7 +39,6 @@ endif( WIN32 )
 # system
 #
 message( STATUS "Detecting system PCRE" )
-set( CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_MODULE_PATH} )
 unset( PCRE_LIBRARIES CACHE )
 unset( PCRE_INCLUDE_DIRS CACHE )
 find_package( PCRE )

BIN=BIN
3rdparty/pcre/lib/libpcre.dll.a


+ 383 - 43
CMakeLists.txt

@@ -1,3 +1,5 @@
+#####################################################################
+#
 # "Getting Started with CMake", a tutorial video by Eric Wing.
 #   Part 1 of 6: http://www.youtube.com/watch?v=CLvZTyji_Uw
 #   Part 2 of 6: http://www.youtube.com/watch?v=gUW-RrRQjEg
@@ -11,8 +13,22 @@
 #   WITH_*   : option to use an external package or not
 #   ENABLE_* : option to use an internal feature/code or not
 #   HAVE_*   : internal variable indicating if we have and are using something
-cmake_minimum_required( VERSION 2.8.4 )
-project( eAthena )
+#
+#####################################################################
+
+
+#cmake_minimum_required( VERSION 2.8.4 )
+# Functional changes from 2.8.3 to 2.8.4:
+#   string(SUBSTRING) works with length -1 as "rest of string"
+#   changes to some CPack generators
+#   CYGWIN no longer defines WIN32
+#   CMP0017: Prefer files from the CMake module directory when including from there.
+set( CMAKE_LEGACY_CYGWIN_WIN32 0 )
+cmake_minimum_required( VERSION 2.8.3 )
+project( eAthena C )
+if( CYGWIN )
+	unset( WIN32 )
+endif()
 
 
 #
@@ -21,26 +37,48 @@ project( eAthena )
 if( ALLOW_SAME_DIRECTORY )
 elseif( "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}" )
 	option( ALLOW_SAME_DIRECTORY "Allow CMake to build in the source directory." OFF )
-	message( FATAL_ERROR "Do not use the source directory to build your files, instead create a separate folder and build there.\nExample:\n  mkdir build\n  cd build\n  cmake -G\"Unix Makefiles\" ..\n  make install\nTo skip this check, set ALLOW_SAME_DIRECTORY to 1 or ON" )
+	message( FATAL_ERROR
+		"Do not use the source directory to build your files, instead delete CMakeCache.txt, create a separate folder and build there.\n"
+		"Example: (build in subdir 'build' and install to source dir)\n"
+		"  rm -f CMakeCache.txt\n"
+		"  mkdir build\n"
+		"  cd build\n"
+		"  cmake -G\"Unix Makefiles\" -DINSTALL_TO_SOURCE=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo ..\n"
+		"  make install\n"
+		"  cd ..\n"
+		"  rm -rf build\n"
+		"To skip this check, set ALLOW_SAME_DIRECTORY to ON (-DALLOW_SAME_DIRECTORY=ON)" )
 endif()
 
 
 #
 # Global stuff
 #
-set( GLOBAL_LIBRARIES CACHE INTERNAL "" )
-set( GLOBAL_INCLUDE_DIRS CACHE INTERNAL "" )
-set( GLOBAL_DEFINITIONS CACHE INTERNAL "" )
+set( GLOBAL_LIBRARIES ${LINK_LIBRARIES}  CACHE INTERNAL "" )# list (comma separated values)
+set( GLOBAL_INCLUDE_DIRS ${INCLUDE_DIRECTORIES}  CACHE INTERNAL "" )# list (comma separated values)
+set( GLOBAL_DEFINITIONS ${COMPILE_DEFINITIONS}  CACHE INTERNAL "" )# string (space separated values -DFOO=bar)
 mark_as_advanced( GLOBAL_LIBRARIES  GLOBAL_INCLUDE_DIRS  GLOBAL_DEFINITIONS )
 if( WIN32 )
-	list( APPEND GLOBAL_DEFINITIONS  FD_SETSIZE=4096 )
-	list( APPEND GLOBAL_LIBRARIES  "oldnames.lib" "ws2_32.lib" )
+	set_property( CACHE GLOBAL_DEFINITIONS  PROPERTY VALUE "${GLOBAL_DEFINITIONS} -DFD_SETSIZE=4096" )
 endif()
 if( MSVC )
-	list( APPEND GLOBAL_DEFINITIONS  _CRT_SECURE_NO_DEPRECATE _CRT_NONSTDC_NO_DEPRECATE DB_MANUAL_CAST_TO_UNION )
+	set_property( CACHE GLOBAL_LIBRARIES    PROPERTY VALUE ${GLOBAL_LIBRARIES} "oldnames.lib" "ws2_32.lib" )
+	set_property( CACHE GLOBAL_DEFINITIONS  PROPERTY VALUE "${GLOBAL_DEFINITIONS} -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE" )
 endif()
 
 
+#
+# 3rd party
+#
+add_subdirectory( 3rdparty )
+include( CheckCSourceCompiles )
+include( CheckCSourceRuns )
+include( CheckIncludeFile )
+include( CheckFunctionExists )
+include( FindFunctionLibrary )
+include( TestBigEndian )
+
+
 #
 # Find svnversion
 #
@@ -60,20 +98,6 @@ message( STATUS "Detecting Subversion" )
 find_package( Subversion )
 message( STATUS "Detecting Subversion - done" )
 
-
-#
-# Find math library (FreeBSD)
-#
-message( STATUS "Detecting math library" )
-find_library( M_LIBRARIES m )
-mark_as_advanced( M_LIBRARIES )
-if( M_LIBRARIES )
-	message( STATUS "Found m: ${M_LIBRARIES}" )
-	list( APPEND GLOBAL_LIBRARIES ${M_LIBRARIES} )
-endif()
-message( STATUS "Detecting math library - done" )
-
-
 #
 # PACKETVER
 #
@@ -87,17 +111,285 @@ endif()
 # SVNVERSION
 #
 if( SVNVERSION_EXECUTABLE )
+	message( STATUS "Getting svn version" )
 	execute_process( COMMAND ${SVNVERSION_EXECUTABLE} ${PROJECT_SOURCE_DIR}
 		OUTPUT_VARIABLE SVNVERSION
 		OUTPUT_STRIP_TRAILING_WHITESPACE )
 	string( REGEX REPLACE "[^1234567890MSexported]" "_" SVNVERSION ${SVNVERSION} )
+	message( STATUS "Found version: ${SVNVERSION}" )
+	message( STATUS "Getting svn version - done" )
 endif()
 if( Subversion_FOUND AND SVNVERSION )
+	message( STATUS "Getting svn branch" )
 	Subversion_WC_INFO( ${PROJECT_SOURCE_DIR} eAthena )
 	if( eAthena_WC_URL )
 		string( REGEX MATCH "[^/]+$" BRANCH ${eAthena_WC_URL} )
 		set( SVNVERSION "${BRANCH}-${SVNVERSION}" )
+		message( STATUS "Found branch: ${BRANCH}" )
+	endif()
+	message( STATUS "Getting svn branch - done" )
+endif()
+
+
+#
+# math library (FreeBSD/Linux/Solaris)
+#
+message( STATUS "Detecting math library (m)" )
+CHECK_INCLUDE_FILE( math.h HAVE_MATH_H )
+if( NOT HAVE_MATH_H )
+	message( FATAL_ERROR "math.h not found" )
+endif()
+set( CMAKE_REQUIRED_LIBRARIES ${GLOBAL_LIBRARIES} )
+find_function_library( floor FUNCTION_FLOOR_LIBRARIES m )
+if( FUNCTION_FLOOR_LIBRARIES )
+	message( STATUS "Adding global library: ${FUNCTION_FLOOR_LIBRARIES}" )
+	set_property( CACHE GLOBAL_LIBRARIES  PROPERTY VALUE ${GLOBAL_LIBRARIES} ${FUNCTION_FLOOR_LIBRARIES} )
+endif()
+message( STATUS "Detecting math library (m) - done" )
+
+
+#
+# dynamic loading library (Linux)
+#
+if( NOT WIN32 )
+message( STATUS "Detecting dynamic loading library (dl)" )
+set( CMAKE_REQUIRED_LIBRARIES ${GLOBAL_LIBRARIES} )
+find_function_library( dlopen FUNCTION_DLOPEN_LIBRARIES dl )
+if( FUNCTION_DLOPEN_LIBRARIES )
+	message( STATUS "Adding global library: ${FUNCTION_DLOPEN_LIBRARIES}" )
+	set_property( CACHE GLOBAL_LIBRARIES  PROPERTY VALUE ${GLOBAL_LIBRARIES} ${FUNCTION_DLOPEN_LIBRARIES} )
+endif()
+message( STATUS "Detecting dynamic loading library (dl) - done" )
+endif()
+
+
+#
+# networking library (Solaris/MinGW)
+#
+if( NOT MSVC )
+message( STATUS "Detecting networking library (socket/nsl/ws2_32)" )
+set( CMAKE_REQUIRED_LIBRARIES ${GLOBAL_LIBRARIES} )
+find_function_library( bind FUNCTION_BIND_LIBRARIES socket ws2_32 )
+if( FUNCTION_BIND_LIBRARIES )
+	message( STATUS "Adding global library: ${FUNCTION_BIND_LIBRARIES}" )
+	set_property( CACHE GLOBAL_LIBRARIES  PROPERTY VALUE ${GLOBAL_LIBRARIES} ${FUNCTION_BIND_LIBRARIES} )
+endif()
+set( CMAKE_REQUIRED_LIBRARIES ${GLOBAL_LIBRARIES} )
+find_function_library( gethostbyname FUNCTION_GETHOSTBYNAME_LIBRARIES nsl )
+if( FUNCTION_GETHOSTBYNAME_LIBRARIES )
+	message( STATUS "Adding global library: ${FUNCTION_GETHOSTBYNAME_LIBRARIES}" )
+	set_property( CACHE GLOBAL_LIBRARIES  PROPERTY VALUE ${GLOBAL_LIBRARIES} ${FUNCTION_GETHOSTBYNAME_LIBRARIES} )
+endif()
+message( STATUS "Detecting networking library (socket/nsl/ws2_32) - done" )
+endif()
+
+
+#
+# Test for big endian
+#
+TEST_BIG_ENDIAN( BIG_ENDIAN )
+if( NOT DEFINED BIG_ENDIAN )
+	message( WARNING "unable to determine endianess, only LITTLE ENDIAN is supported" )
+elseif( BIG_ENDIAN )
+	message( FATAL_ERROR "bigendian is not supported" )
+endif()
+
+
+#
+# Test typecast to union
+#
+message( STATUS "Check for typecast to union" )
+set( SOURCECODE
+	"typedef union Foonion{\n"
+	"  int i;\n"
+	"  unsigned int ui;\n"
+	"  const char* s;\n"
+	"} Foonion;\n"
+	"int get_i(Foonion onion){ return onion.i; }\n"
+	"int main(int argc, char** argv){\n"
+	"  int i = 0;\n"
+	"  return get_i(((Foonion)(int)i));\n"
+	"}\n"
+	)
+CHECK_C_SOURCE_COMPILES( "${SOURCECODE}" HAVE_TYPECAST_TO_UNION )
+if( HAVE_TYPECAST_TO_UNION )
+	message( STATUS "Check for typecast to union - yes" )
+else()
+	message( STATUS "Check for typecast to union - no" )
+	set_property( CACHE GLOBAL_DEFINITIONS  PROPERTY VALUE "${GLOBAL_DEFINITIONS} -DDB_MANUAL_CAST_TO_UNION" )
+endif()
+
+
+#
+# Test monotonic clock
+#
+# CLOCK_MONOTONIC clock for clock_gettime
+# Normally defines _POSIX_TIMERS > 0 and _POSIX_MONOTONIC_CLOCK (for posix
+# compliant systems) and __FreeBSD_cc_version >= 500005 (for FreeBSD
+# >= 5.1.0, which does not have the posix defines (ref. r11983)) would be
+# checked but some systems define them even when they do not support it
+# (ref. bugreport:1003).
+#
+message( STATUS "Check for monotonic clock" )
+set( SOURCECODE
+	"#include <sys/time.h>\n"
+	"#include <time.h>\n"
+	"#include <unistd.h>\n"
+	"int main(int argc, char** argv){\n"
+	"  struct timespec tval;\n"
+	"  return clock_gettime(CLOCK_MONOTONIC, &tval);\n"
+	"}\n"
+	)
+find_library( RT_LIBRARY rt )# (optional, rt on Debian)
+mark_as_advanced( RT_LIBRARY )
+set( CMAKE_REQUIRED_LIBRARIES ${GLOBAL_LIBRARIES} ${RT_LIBRARY} )
+CHECK_C_SOURCE_RUNS( "${SOURCECODE}" HAVE_MONOTONIC_CLOCK )
+if( HAVE_MONOTONIC_CLOCK )
+	message( STATUS "Check for monotonic clock - yes" )
+	set_property( CACHE GLOBAL_LIBRARIES    PROPERTY VALUE ${GLOBAL_LIBRARIES} ${RT_LIBRARY} )
+	set_property( CACHE GLOBAL_DEFINITIONS  PROPERTY VALUE "${GLOBAL_DEFINITIONS} -DHAVE_MONOTONIC_CLOCK" )
+else()
+	message( STATUS "Check for monotonic clock - no" )
+endif()
+
+
+#
+# Test if function exists:
+#   setrlimit - used to set the socket limit
+#   strnlen - string length with upper scan bound
+#   getpid - process id
+#   gettid - thread id
+#
+CHECK_FUNCTION_EXISTS( setrlimit HAVE_SETRLIMIT )
+CHECK_FUNCTION_EXISTS( strnlen HAVE_STRNLEN )
+CHECK_FUNCTION_EXISTS( getpid HAVE_GETPID )
+CHECK_FUNCTION_EXISTS( gettid HAVE_GETTID )
+foreach( define HAVE_SETRLIMIT HAVE_STRNLEN HAVE_GETPID HAVE_GETTID )
+	if( ${define} )
+		set_property( CACHE GLOBAL_DEFINITIONS  PROPERTY VALUE "${GLOBAL_DEFINITIONS} -D${define}" )
+	endif()
+endforeach()
+
+
+#
+# Use RDTSC instruction as a timing source (time stamp counter on x86 since Pentium) (default=OFF)
+#
+# Enable it when you've timing issues. (ex: in conjunction with XEN or Other Virtualization mechanisms)
+# Please ensure that you've disabled dynamic CPU-Frequencys, such as power saving options.
+# (On the most modern Dedicated Servers cpufreq is preconfigured, see your distribution's manual how to disable it)
+#
+option( ENABLE_RDTSC "use RDTSC instruction as a timing source (default=OFF)" OFF )
+if( ENABLE_RDTSC )
+	set_property( CACHE GLOBAL_DEFINITIONS  PROPERTY VALUE "${GLOBAL_DEFINITIONS} -DENABLE_RDTSC" )
+	message( STATUS "Enabled RDTSC as a timing source" )
+endif()
+
+
+#
+# Enable extra debug code (default=OFF)
+#
+option( ENABLE_EXTRA_DEBUG_CODE "enable extra debug code (default=OFF)" OFF )
+if( ENABLE_EXTRA_DEBUG_CODE )
+	set_property( CACHE GLOBAL_DEFINITIONS  PROPERTY VALUE "${GLOBAL_DEFINITIONS} -DDEBUG" )
+	message( STATUS "Enabled extra DEBUG code" )
+endif()
+
+
+#
+# Enable builtin memory manager (default=default)
+#
+set( MEMMGR_OPTIONS "default;yes;no" )
+set( ENABLE_MEMMGR "default" CACHE STRING "enable builtin memory manager: ${MEMMGR_OPTIONS} (default=default)" )
+set_property( CACHE ENABLE_MEMMGR  PROPERTY STRINGS ${MEMMGR_OPTIONS} )
+if( ENABLE_MEMMGR STREQUAL "default" )
+	# use source code default
+elseif( ENABLE_MEMMGR STREQUAL "yes" )
+	set_property( CACHE GLOBAL_DEFINITIONS  PROPERTY VALUE "${GLOBAL_DEFINITIONS} -DUSE_MEMMGR" )
+	message( STATUS "Enabled the builtin memory manager" )
+elseif( ENABLE_MEMMGR STREQUAL "no" )
+	set_property( CACHE GLOBAL_DEFINITIONS  PROPERTY VALUE "${GLOBAL_DEFINITIONS} -DNO_MEMMGR" )
+	message( STATUS "Disabled the builtin memory manager" )
+else()
+	message( FATAL_ERROR "invalid option ENABLE_MEMMGR=${ENABLE_MEMMGR} (valid options: ${MEMMGR_OPTIONS})" )
+endif()
+
+
+#
+# Enable memory library (default=system)
+#
+set( MEMORY_OPTIONS "system;memwatch;dmalloc;gcollect" )
+set( ENABLE_MEMORY "system" CACHE STRING "enable memory library: ${MEMORY_OPTIONS} (default=system)" )
+set_property( CACHE ENABLE_MEMORY  PROPERTY STRINGS ${MEMORY_OPTIONS} )
+if( ENABLE_MEMORY STREQUAL "system" )
+	# use system functions
+
+elseif( ENABLE_MEMORY STREQUAL "memwatch" )
+	CHECK_INCLUDE_FILE( memwatch.h HAVE_MEMWATCH_H )
+	find_library( MEMWATCH_LIBRARY memwatch )
+	mark_as_advanced( MEMWATCH_LIBRARY )
+	if( HAVE_MEMWATCH_H AND MEMWATCH_LIBRARY )
+		message( STATUS "Adding global library: ${MEMWATCH_LIBRARY}" )
+		set_property( CACHE GLOBAL_LIBRARIES    PROPERTY VALUE ${GLOBAL_LIBRARIES} ${MEMWATCH_LIBRARY} )
+		set_property( CACHE GLOBAL_DEFINITIONS  PROPERTY VALUE "${GLOBAL_DEFINITIONS} -DMEMWATCH" )
+		message( STATUS "Enabled the memory library memwatch" )
+	else()
+		message( FATAL_ERROR "Failed to enable the memory library memwatch" )
+	endif()
+
+elseif( ENABLE_MEMORY STREQUAL "dmalloc" )
+	CHECK_INCLUDE_FILE( dmalloc.h HAVE_DMALLOC_H )
+	find_library( DMALLOC_LIBRARY dmalloc )
+	mark_as_advanced( DMALLOC_LIBRARY )
+	if( HAVE_DMALLOC_H AND DMALLOC_LIBRARY )
+		message( STATUS "Adding global library: ${DMALLOC_LIBRARY}" )
+		set_property( CACHE GLOBAL_LIBRARIES    PROPERTY VALUE ${GLOBAL_LIBRARIES} ${DMALLOC_LIBRARY} )
+		set_property( CACHE GLOBAL_DEFINITIONS  PROPERTY VALUE "${GLOBAL_DEFINITIONS} -DDMALLOC -DDMALLOC_FUNC_CHECK" )
+		message( STATUS "Enabled the memory library dmalloc" )
+	else()
+		message( FATAL_ERROR "Failed to enable the memory library dmalloc" )
+	endif()
+
+elseif( ENABLE_MEMORY STREQUAL "gcollect" )
+	CHECK_INCLUDE_FILE( gc.h HAVE_GC_H )
+	find_library( GC_LIBRARY gc )
+	mark_as_advanced( GC_LIBRARY )
+	if( HAVE_GC_H AND GC_LIBRARY )
+		message( STATUS "Adding global library: ${GC_LIBRARY}" )
+		set_property( CACHE GLOBAL_LIBRARIES    PROPERTY VALUE ${GLOBAL_LIBRARIES} ${GC_LIBRARY} )
+		set_property( CACHE GLOBAL_DEFINITIONS  PROPERTY VALUE "${GLOBAL_DEFINITIONS} -DGCOLLECT" )
+		message( STATUS "Enabled the memory library gcollect" )
+	else()
+		message( FATAL_ERROR "Failed to enable the memory library gcollect" )
+	endif()
+
+else()
+	message( FATAL_ERROR "invalid option ENABLE_MEMORY=${ENABLE_MEMORY} (valid options: ${MEMORY_OPTIONS})" )
+endif()
+
+
+#
+# Enable profiler (default=none)
+#
+set( PROFILER_OPTIONS "none;gprof" )
+set( ENABLE_PROFILER "none" CACHE STRING "enable profiler: ${PROFILER_OPTIONS} (default=none)" )
+set_property( CACHE ENABLE_PROFILER  PROPERTY STRINGS ${PROFILER_OPTIONS} )
+if( ENABLE_PROFILER STREQUAL "none" )
+	# no profiler
+
+elseif( ENABLE_PROFILER STREQUAL "gprof" )
+	if( CMAKE_C_COMPILER_ID STREQUAL "GNU" )
+		if( NOT HAVE_GPROF_FLAGS )
+			set_property( CACHE CMAKE_C_FLAGS  PROPERTY VALUE "${CMAKE_C_FLAGS} -pg" )
+			set_property( CACHE CMAKE_EXE_LINKER_FLAGS  PROPERTY VALUE "${CMAKE_EXE_LINKER_FLAGS} -pg" )
+			set( HAVE_GPROF_FLAGS ON  CACHE INTERNAL "" )
+		endif()
+		message( STATUS "Enabled the profiler gprof" )
+	else()
+		message( FATAL_ERROR "Failed to enable the profiler gprof - not GNU" )
 	endif()
+
+else()
+	message( FATAL_ERROR "invalid option ENABLE_PROFILER=${ENABLE_PROFILER} (valid options: ${PROFILER_OPTIONS})" )
 endif()
 
 
@@ -110,13 +402,16 @@ set( CPACK_PACKAGE_VERSION ${SVNVERSION} )
 set( CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE )
 #set( CPACK_MONOLITHIC_INSTALL ON )
 include( CPACK  OPTIONAL  RESULT_VARIABLE HAVE_CPACK )
-if( NOT HAVE_CPACK )
+if( HAVE_CPACK )
+	option( WITH_CPACK "enable building packages with CPack ('package' target)" ON )
+endif()
+if( NOT WITH_CPACK )
 	# empty replacements
 	macro( cpack_add_component_group )
 	endmacro()
 	macro( cpack_add_component )
 	endmacro()
-	message( STATUS "CPACK not found, package creation disabled" )
+	message( STATUS "Disabled package creation" )
 endif()
 
 set( Runtime "Runtime files"  CACHE INTERNAL "" )
@@ -135,8 +430,8 @@ cpack_add_component( Development_base DESCRIPTION ${Development_base} DISPLAY_NA
 #
 # install stuff
 #
-option( WITH_COMPONENT_RUNTIME "install/package files needed to run the project" ON )
-option( WITH_COMPONENT_DEVELOPMENT "install/package files needed to build the project" OFF )
+option( INSTALL_COMPONENT_RUNTIME "install/package files needed to run the project" ON )
+option( INSTALL_COMPONENT_DEVELOPMENT "install/package files needed to build the project" OFF )
 option( INSTALL_TO_PATH "copy files to INSTALL_PATH" OFF )
 option( INSTALL_TO_SOURCE "copy files to source directory, skips what is already there (${CMAKE_CURRENT_SOURCE_DIR})" OFF )
 option( INSTALL_TO_SUBDIR "copy files to subdirectory (${CMAKE_CURRENT_BINARY_DIR}/install)" OFF )
@@ -221,7 +516,7 @@ set( RUNTIME_DIRECTORIES
 	)
 if( INSTALL_TO_SOURCE )# skip, already in the source dir
 else()
-	if( WITH_COMPONENT_RUNTIME )
+	if( INSTALL_COMPONENT_RUNTIME )
 		install( FILES ${RUNTIME_FILES}
 			DESTINATION "."
 			COMPONENT Runtime_base )
@@ -232,8 +527,8 @@ else()
 				PATTERN ${SVN_FOLDER_PATTERN} EXCLUDE
 				PATTERN "conf/import-tmpl" EXCLUDE )
 		endforeach()
-	endif()
-	if( WITH_COMPONENT_DEVELOPMENT )
+	endif( INSTALL_COMPONENT_RUNTIME )
+	if( INSTALL_COMPONENT_DEVELOPMENT )
 		install( FILES ${DEVELOPMENT_FILES}
 			DESTINATION "."
 			COMPONENT Development_base )
@@ -243,23 +538,68 @@ else()
 				COMPONENT Development_base
 				PATTERN ${SVN_FOLDER_PATTERN} EXCLUDE )
 		endforeach()
-	endif()
+	endif( INSTALL_COMPONENT_DEVELOPMENT )
 endif()
-if( WITH_COMPONENT_RUNTIME )
+if( INSTALL_COMPONENT_RUNTIME )
 	# templates
-	install( DIRECTORY "save-tmpl/"
-		DESTINATION "save"
-		COMPONENT Runtime_templates
-		PATTERN ${SVN_FOLDER_PATTERN} EXCLUDE )
-	install( DIRECTORY "conf/import-tmpl/"
-		DESTINATION "conf/import"
-		COMPONENT Runtime_templates
-		PATTERN ${SVN_FOLDER_PATTERN} EXCLUDE )
-endif()
+	set( _TEMPLATES
+		"save-tmpl" "save"
+		"conf/import-tmpl" "conf/import"
+		)
+	set( INSTALL_TEMPLATES_FILE "${CMAKE_CURRENT_BINARY_DIR}/InstallTemplates.cmake" )
+	file( WRITE "${INSTALL_TEMPLATES_FILE}"
+		"macro( INSTALL_TEMPLATE _SRC _DST )\n"
+		"  set( SRC \"${CMAKE_CURRENT_SOURCE_DIR}/\${_SRC}\" )\n"
+		"  set( DST \"\${CMAKE_INSTALL_PREFIX}/\${_DST}\" )\n"
+		"  if( EXISTS \"\${DST}\" )\n"
+		"    message( \"-- Already exists: \${DST}\" )\n"
+		"  else()\n"
+		"    message( \"-- Installing template: \${DST}\" )\n"
+		"    execute_process( COMMAND \"${CMAKE_COMMAND}\" -E copy \"\${SRC}\" \"\${DST}\" )\n"
+		"  endif()\n"
+		"endmacro()\n"
+		)
+	while( _TEMPLATES )
+		list( GET _TEMPLATES 0 _SRC )
+		list( GET _TEMPLATES 1 _DST )
+		list( REMOVE_AT _TEMPLATES 0 1 )
+		if( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_SRC}" )
+			file( GLOB _PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${_SRC}/*" )
+			foreach( _PATH IN ITEMS ${_PATHS} )
+				string( REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/${_SRC}/" "" _PATH "${_PATH}" )
+				if( NOT "${_PATH}" MATCHES "${SVN_FOLDER_PATTERN}" )
+					list( APPEND _TEMPLATES "${_SRC}/${_PATH}" "${_DST}/${_PATH}" )
+				endif()
+			endforeach()
+		else()
+			file( APPEND "${INSTALL_TEMPLATES_FILE}" "INSTALL_TEMPLATE( \"${_SRC}\" \"${_DST}\" )\n" )
+		endif()
+	endwhile()
+	install( SCRIPT "${INSTALL_TEMPLATES_FILE}"
+		COMPONENT Runtime_templates )
+endif( INSTALL_COMPONENT_RUNTIME )
 
 
 #
-# subdirectories
+# sources
 #
-add_subdirectory( 3rdparty )
+set( TARGET_LIST  CACHE INTERNAL "" )
 add_subdirectory( src )
+
+
+#####################################################################
+# final checks and warnings
+#
+if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+	message( WARNING "64bit should work, but is not recommended." )
+elseif( NOT CMAKE_SIZEOF_VOID_P EQUAL 4 )
+	message( FATAL_ERROR "unexpected architecture (CMAKE_SIZEOF_VOID_P is ${CMAKE_SIZEOF_VOID_P})" )
+endif()
+list( LENGTH  TARGET_LIST  _LEN )
+if( _LEN EQUAL 0 )
+	message( FATAL_ERROR "no targets available" )
+endif()
+message( STATUS "Available targets:" )
+foreach( _TARGET IN ITEMS ${TARGET_LIST} )
+	message( STATUS "\t${_TARGET}" )
+endforeach()

+ 2 - 0
Changelog-Renewal.txt

@@ -1,5 +1,7 @@
 Date	Added
 
+2011/10/07
+	* Merged changes from trunk [14895:14966/trunk]. [Ai4rei]
 2011/09/30
 	* Rev. 14965 Forgot to increase MAX_ITEMDELAYs to 18. [L0ne_W0lf]
 	* Rev. 14964 Just a slew of back-logged source updates. [L0ne_W0lf]

+ 2 - 0
conf/Changelog.txt

@@ -1,5 +1,7 @@
 Date	Added
 
+2011/08/21
+	* Rev. 14938 Added setting 'client_limit_unit_lv' to control the unit types which are affected by 'max_lv' and 'aura_lv' settings. [Ai4rei]
 2011/08/10
 	* Rev. 14931 Upped max_lv and max_aura to 150, and max_aspd to 193.
 2011/07/09

+ 8 - 0
conf/battle/client.conf

@@ -17,6 +17,8 @@
 //--------------------------------------------------------------
 // Note 1: Value is a config switch (on/off, yes/no or 1/0)
 // Note 2: Value is in percents (100 means 100%)
+// Note 3: Value is a bit field. If no description is given,
+//         assume unit types (1: Pc, 2: Mob, 4: Pet, 8: Homun, 16: Mercenary)
 //--------------------------------------------------------------
 
 // Set here which client version do you accept. Add all values of clients:
@@ -86,6 +88,12 @@ max_lv: 150
 //          150 or more will be reported as having level 99 and show an aura.
 aura_lv: 150
 
+// Units types affected by max_lv and aura_lv settings. (Note 3)
+// Note: If an unit type, which normally does not show an aura, is
+//       set it will obtain an aura when it meets the level requirement.
+// Default: 0 (none)
+client_limit_unit_lv: 0
+
 // Will tuxedo and wedding dresses be shown when worn? (Note 1)
 wedding_modifydisplay: no
 

+ 42 - 0
conf/mapflag/reset.txt

@@ -0,0 +1,42 @@
+//===== eAthena Script =======================================
+//= Map flags that enable the use of Neuralizer
+//===== By: ==================================================
+//= Daegaladh
+//===== Current Version: =====================================
+//= 1.0 [Daegaladh]
+//===== Compatible With: =====================================
+//=
+//===== Description: =========================================
+//=
+//============================================================
+
+alberta	mapflag	reset
+aldebaran	mapflag	reset
+amatsu	mapflag	reset
+ayothaya	mapflag	reset
+brasilis	mapflag	reset
+comodo	mapflag	reset
+einbroch	mapflag	reset
+einbech	mapflag	reset
+geffen	mapflag	reset
+gonryun	mapflag	reset
+izlude	mapflag	reset
+jawaii	mapflag	reset
+hugel	mapflag	reset
+lighthalzen	mapflag	reset
+louyang	mapflag	reset
+manuk	mapflag	reset
+mid_camp	mapflag	reset
+moc_ruins	mapflag	reset
+morocc	mapflag	reset
+moscovia	mapflag	reset
+niflheim	mapflag	reset
+prontera	mapflag	reset
+payon	mapflag	reset
+pay_arche	mapflag	reset
+rachel	mapflag	reset
+splendide	mapflag	reset
+umbala	mapflag	reset
+veins	mapflag	reset
+xmas	mapflag	reset
+yuno	mapflag	reset

+ 41 - 0
conf/mapflag/restricted.txt

@@ -6,6 +6,7 @@
 //= 1.0 [Komurka]
 //= 1.1 Added WoE:SE Map restrictions. [L0ne_W0lf]
 //= 1.2 Added Endless Tower Restrictions. (bugreport:4707) [L0ne_W0lf]
+//= 1.3 Added Orc's Memory, Nidhoggur's Nest and towns restrictions [Daegaladh]
 //===== Current Version: =====================================
 
 //Aldebaran Turbo Track
@@ -54,3 +55,43 @@ arug_cas05	mapflag	restricted	4
 4@tower	mapflag	restricted	6
 5@tower	mapflag	restricted	6
 6@tower	mapflag	restricted	6
+
+//Orc's Memory ===================
+1@orcs	mapflag	restricted	6
+2@orcs	mapflag	restricted	6
+
+// Nidhoggr's Instance ===========
+1@nyd	mapflag	restricted	6
+2@nyd	mapflag	restricted	6
+
+//Towns
+alberta	mapflag	restricted	7
+aldebaran	mapflag	restricted	7
+amatsu	mapflag	restricted	7
+ayothaya	mapflag	restricted	7
+brasilis	mapflag	restricted	7
+comodo	mapflag	restricted	7
+einbroch	mapflag	restricted	7
+einbech	mapflag	restricted	7
+geffen	mapflag	restricted	7
+gonryun	mapflag	restricted	7
+izlude	mapflag	restricted	7
+jawaii	mapflag	restricted	7
+hugel	mapflag	restricted	7
+lighthalzen	mapflag	restricted	7
+louyang	mapflag	restricted	7
+manuk	mapflag	restricted	7
+mid_camp	mapflag	restricted	7
+moc_ruins	mapflag	restricted	7
+morocc	mapflag	restricted	7
+moscovia	mapflag	restricted	7
+niflheim	mapflag	restricted	7
+prontera	mapflag	restricted	7
+payon	mapflag	restricted	7
+pay_arche	mapflag	restricted	7
+rachel	mapflag	restricted	7
+splendide	mapflag	restricted	7
+umbala	mapflag	restricted	7
+veins	mapflag	restricted	7
+xmas	mapflag	restricted	7
+yuno	mapflag	restricted	7

+ 49 - 0
configure

@@ -3475,6 +3475,54 @@ rm -f conftest.err conftest.$ac_objext \
 
 
 
+#
+# -O2 implies -fstrict-aliasing, but the code is not safe for that
+#
+echo "$as_me:$LINENO: checking whether $CC supports -fno-strict-aliasing" >&5
+echo $ECHO_N "checking whether $CC supports -fno-strict-aliasing... $ECHO_C" >&6
+OLD_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -fno-strict-aliasing"
+cat >conftest.$ac_ext <<_ACEOF
+int foo;
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+		echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+		CFLAGS="$OLD_CFLAGS"
+
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
 #
 # DB_MANUAL_CAST_TO_UNION
 #
@@ -6178,6 +6226,7 @@ do
   # Handling of arguments.
   "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
   "src/common/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/common/Makefile" ;;
+  "3rdparty/mt19937ar/Makefile" ) CONFIG_FILES="$CONFIG_FILES 3rdparty/mt19937ar/Makefile" ;;
   "src/char/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/char/Makefile" ;;
   "src/login/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/login/Makefile" ;;
   "src/char_sql/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/char_sql/Makefile" ;;

+ 16 - 0
configure.in

@@ -424,6 +424,22 @@ AC_LINK_IFELSE(
 AC_SUBST([WITH_PLUGINS])
 
 
+#
+# -O2 implies -fstrict-aliasing, but the code is not safe for that
+#
+AC_MSG_CHECKING([whether $CC supports -fno-strict-aliasing])
+OLD_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -fno-strict-aliasing"
+AC_COMPILE_IFELSE(
+	[int foo;],
+	[AC_MSG_RESULT([yes])],
+	[
+		AC_MSG_RESULT([no])
+		CFLAGS="$OLD_CFLAGS"
+	]
+)
+
+
 #
 # DB_MANUAL_CAST_TO_UNION
 #

+ 17 - 0
db/Changelog.txt

@@ -19,12 +19,29 @@
 	* Added Rune Knight skills to skill_cast_db
 	* Updated Rune Knight skills, and Arch Bishop skills.
 	* Updated SP requirements in skill_require_db.
+2011/09/27
+	* Rev. 14963 Updated item_noequip.txt examples to reflect recent changes (follow up to r14961). [Ai4rei]
 2011/08/26
 	* Rev. 14941 Several updates in relation to 3rd jobs. [L0ne_W0lf]
 2011/08/10
 	* Rev. 14931 Added Brasilis database updates from trunk r14928. [L0ne_W0lf]
+2011/08/09
+	* Rev. 14928 Added remaining database modifications for Brasilis.
+	- Added the skills for the Brasilis monsters.
+	- Added remaining entries for Bathroom Ghost quest.
+	- Added stats for the Suspicious Hydra monsters.
+	- Corrected the capture rate for Suspicious Hydra.
 2011/08/07
 	* Rev. 14927 Merged database changes from trunk r14927. [L0ne_W0lf]
+	* Rev. 14926 Minor item-related updates, and a couple quest database updates. [L0ne_W0lf]
+2011/07/11
+	* Rev. 14901 Lots of updates. :] [L0ne_W0lf]
+	- Added several missing items to the item database, updated others.
+	- Raised level 10 Dec. AGI to be level 48, when used by mobs.
+	- Added missing mercenaries to the mercenary DB, and skills.
+	- Added missing monster_chat_db entries for Nydhoggr's Shadow.
+	- Added Brasilis pets to the pet DB, these pets are unhatchable on purpose.
+	- Added additional quests to the quest_db, mostly for RE.
 2011/04/16
 	* Rev. 14797 Added Archangel Wings (2573) and their respective Box (16998) item based on client-side kRO description. [Ai4rei]
 2011/03/19

+ 45 - 28
db/item_noequip.txt

@@ -2,42 +2,59 @@
 // here you define which items may not be used at PvP / GvG 
 // format: <item id>,<mode>
 // mode
-// 1- restricted in PVP
-// 2- restricted in GVG
-// 3- restricted in both PvP and GvG
+// 1    - restricted in normal maps
+// 2    - restricted in PVP
+// 4    - restricted in GVG
+// 8    - restricted in Battlegrounds
 // Restricted zones - they're configured by 'restricted <number>' mapflag
-// 4   - restricted in zone 1
-// 8   - restricted in zone 2
-// 16  - restricted in zone 3
-// 32  - restricted in zone 4
-// 64 -  restricted in zone 5
-// 128 - restricted in zone 6
-// 256 - restricted in zone 7
+// 32   - restricted in zone 1
+// 64   - restricted in zone 2
+// 128  - restricted in zone 3
+// 256  - restricted in zone 4
+// 512  - restricted in zone 5
+// 1024 - restricted in zone 6
+// 2048 - restricted in zone 7
 
 //Examples:
-//1201,1 you can't use KNIFE(ID 1201) on PvP and GvG
-//608,3 you can't use Yggdrasil Seed(ID 608) on both PvP & GvG & WoE Castles
-//4174,3 Forbid Deviling Card in every PVP or GVG map, and during woes.
-//501,4 you can't use Red Potion on map marked as 'restricted zone 1'
-//502,8 you can't use Orange Potion on map marked as 'restricted zone 2'
-//503,16 you can't use Yellow Potion on map marked as 'restricted zone 3'
+//1201,1 you can't use KNIFE(ID 1201) on normal maps
+//608,4 you can't use Yggdrasil Seed(ID 608) on both GvG and WoE Castles
+//4174,6 Forbid Deviling Card in every PVP or GVG map, and during woes.
+//501,32 you can't use Red Potion on map marked as 'restricted zone 1'
+//502,64 you can't use Orange Potion on map marked as 'restricted zone 2'
+//503,128 you can't use Yellow Potion on map marked as 'restricted zone 3'
 // you can even mix modes
-//519,41 (32+8+1) you can't use Milk on PVP, and maps marked as 'restricted zone 2' and 'restricted zone 4'
+//519,322 (256+64+2) you can't use Milk on PVP, and maps marked as 'restricted zone 2' and 'restricted zone 4'
+
+//PVP
+14529,2 //Greed Scroll
+
+//GVG
+12218,4 //LV5 Assumptio Scroll
+14529,4 //Greed Scroll
+14590,4 //Party Assumptio 5 Scroll
+
+//BATTLEGROUND
+12218,8 //LV5 Assumptio Scroll
+14590,8 //Party Assumptio 5 Scroll
 
 
 //Zone 1 - Aldebaran Turbo Track
-601,4 //Fly Wing
-506,4 //Green Potion
-525,4 //Panacea
+601,32 //Fly Wing
+605,32 //Anodyne
+506,32 //Green Potion
+525,32 //Panacea
 
 //Zone 2 - Jail
-601,8 //Fly Wing - not really needed here but ...
-602,8 //Butterfly Wing - also not needed
-12212,8 //Giant Fly Wing
-14582,8
-14583,8
-14584,8
-14585,8
+601,64 //Fly Wing - not really needed here but ...
+602,64 //Butterfly Wing - also not needed
+12212,64 //Giant Fly Wing
+14582,64
+14583,64
+14584,64
+14585,64
 
 //Zone 3 - Izlude Battle Arena
-601,16 //Fly Wing
+601,128 //Fly Wing
+
+//Zone 7 - Towns
+14529,2048 //Greed Scroll

+ 20 - 20
db/mob_skill_db.txt

@@ -250,8 +250,8 @@
 1046,Doppelganger@NPC_CRITICALSLASH,attack,170,1,2000,0,5000,yes,target,always,0,,,,,,,
 1046,Doppelganger@CR_AUTOGUARD,attack,249,10,2000,500,300000,no,self,always,0,,,,,,29,
 1046,Doppelganger@CR_AUTOGUARD,chase,249,10,2000,500,300000,no,self,longrangeattacked,,,,,,,29,
-1046,Doppelganger@AL_DECAGI,attack,30,11,500,0,20000,no,target,always,0,,,,,,5,
-1046,Doppelganger@AL_DECAGI,chase,30,11,500,0,20000,no,target,always,0,,,,,,5,
+1046,Doppelganger@AL_DECAGI,attack,30,48,500,0,20000,no,target,always,0,,,,,,5,
+1046,Doppelganger@AL_DECAGI,chase,30,48,500,0,20000,no,target,always,0,,,,,,5,
 1046,Doppelganger@NPC_SUMMONSLAVE,attack,196,1,10000,700,10000,no,self,slavele,3,1427,,,,,,
 1046,Doppelganger@NPC_SUMMONSLAVE,idle,196,1,10000,700,10000,no,self,slavele,3,1427,,,,,,
 1046,Doppelganger@BS_HAMMERFALL,chase,110,11,10000,0,5000,yes,target,skillused,18,,,,,,,
@@ -399,7 +399,7 @@
 1086,Golden Thief Bug@NPC_SUMMONSLAVE,idle,196,10,10000,0,0,no,self,onspawn,0,1054,,,,,,
 1086,Golden Thief Bug@TF_HIDING,attack,51,1,1000,0,5000,no,self,myhpltmaxrate,20,,,,,,19,
 1086,Golden Thief Bug@AL_HEAL,idle,28,11,10000,0,5000,yes,self,mystatuson,hiding,,,,,,,
-1087,Orc Hero@AL_DECAGI,chase,30,11,2000,0,300000,no,target,always,0,,,,,,6,
+1087,Orc Hero@AL_DECAGI,chase,30,48,2000,0,300000,no,target,always,0,,,,,,6,
 1087,Orc Hero@AL_TELEPORT,idle,26,1,10000,0,0,yes,self,rudeattacked,,,,,,,,
 1087,Orc Hero@AL_TELEPORT,idle,26,1,5000,0,5000,yes,self,rudeattacked,,,,,,,,
 1087,Orc Hero@AL_TELEPORT,walk,26,1,5000,0,5000,yes,self,rudeattacked,,,,,,,,
@@ -551,7 +551,7 @@
 1111,Drainliar@NPC_BLINDATTACK,attack,177,3,500,0,5000,yes,target,always,0,,,,,,,
 1111,Drainliar@NPC_BLOODDRAIN,attack,199,1,500,0,5000,yes,target,always,0,,,,,,,
 1111,Drainliar@NPC_DARKNESSATTACK,attack,190,1,2000,0,5000,yes,target,always,0,,,,,,,
-1112,Drake@AL_DECAGI,chase,30,11,2000,0,60000,no,target,always,0,,,,,,29,
+1112,Drake@AL_DECAGI,chase,30,48,2000,0,60000,no,target,always,0,,,,,,29,
 1112,Drake@NPC_ARMORBRAKE,attack,344,10,2000,0,60000,no,target,always,0,,,,,,,
 1112,Drake@AL_TELEPORT,idle,26,1,10000,0,0,yes,self,rudeattacked,,,,,,,,
 1112,Drake@BS_MAXIMIZE,attack,114,1,500,0,5000,no,self,always,0,,,,,,,
@@ -1151,7 +1151,7 @@
 1251,Stormy Knight@WZ_STORMGUST,chase,89,10,2000,500,5000,no,target,always,0,,,,,,21,
 1251,Stormy Knight@WZ_STORMGUST,chase,89,10,10000,500,5000,no,target,skillused,18,,,,,,21,
 1251,Stormy Knight@AL_HEAL,idle,28,11,10000,0,10000,yes,self,myhpltmaxrate,50,,,,,,,
-1252,Garm@AL_DECAGI,chase,30,11,2000,0,300000,no,target,always,0,,,,,,6,
+1252,Garm@AL_DECAGI,chase,30,48,2000,0,300000,no,target,always,0,,,,,,6,
 1252,Garm@AL_TELEPORT,idle,26,1,10000,0,0,yes,self,rudeattacked,,,,,,,,
 1252,Garm@AL_TELEPORT,idle,26,1,5000,0,5000,yes,self,rudeattacked,,,,,,,,
 1252,Garm@AL_TELEPORT,walk,26,1,5000,0,5000,yes,self,rudeattacked,,,,,,,,
@@ -1618,7 +1618,7 @@
 1372,Goat@NPC_EMOTION,chase,197,1,200,0,5000,yes,self,always,0,19,0x1089,,,,,
 1372,Goat@NPC_SPLASHATTACK,attack,174,1,2000,0,5000,yes,target,attackpcge,2,,,,,,,
 1372,Goat@NPC_STUNATTACK,attack,179,3,500,1500,5000,no,target,always,0,,,,,,6,
-1373,Lord of Death@AL_DECAGI,chase,30,11,2000,0,60000,no,target,always,0,,,,,,,
+1373,Lord of Death@AL_DECAGI,chase,30,48,2000,0,60000,no,target,always,0,,,,,,,
 1373,Lord of Death@AL_TELEPORT,idle,26,1,10000,0,0,yes,self,rudeattacked,,,,,,,,
 1373,Lord of Death@NPC_POWERUP,attack,349,5,10000,0,30000,yes,self,myhpltmaxrate,30,,,,,,6,
 1373,Lord of Death@NPC_HELLJUDGEMENT,chase,662,10,10000,1000,10000,no,self,always,0,,,,,,36,
@@ -1774,7 +1774,7 @@
 1388,Arc Angeling@NPC_SUMMONSLAVE,attack,196,7,10000,700,60000,no,self,slavele,3,1443,1246,1742,1743,1744,18,
 1388,Arc Angeling@NPC_SUMMONSLAVE,idle,196,7,10000,700,60000,no,self,slavele,3,1443,1246,1742,1743,1744,18,
 1388,Arc Angeling@RG_INTIMIDATE,attack,219,5,2000,0,5000,yes,target,always,0,,,,,,,
-1389,Dracula@AL_DECAGI,chase,30,11,2000,0,5000,no,target,always,0,,,,,,,
+1389,Dracula@AL_DECAGI,chase,30,48,2000,0,5000,no,target,always,0,,,,,,,
 1389,Dracula@AL_TELEPORT,idle,26,1,10000,0,0,yes,self,rudeattacked,,,,,,,,
 1389,Dracula@AL_TELEPORT,idle,26,1,5000,0,5000,yes,self,rudeattacked,,,,,,,,
 1389,Dracula@AL_TELEPORT,walk,26,1,5000,0,5000,yes,self,rudeattacked,,,,,,,,
@@ -2882,7 +2882,7 @@
 1637,Margaretha Sorin@AL_PNEUMA,idle,25,1,10000,0,0,yes,self,longrangeattacked,,,,,,,,
 1637,Margaretha Sorin@AL_INCAGI,attack,29,10,2000,0,240000,yes,self,always,0,,,,,,2,
 1637,Margaretha Sorin@AL_INCAGI,chase,29,10,2000,0,240000,yes,self,always,0,,,,,,2,
-1637,Margaretha Sorin@AL_DECAGI,chase,30,11,2000,0,10000,yes,target,always,0,,,,,,,
+1637,Margaretha Sorin@AL_DECAGI,chase,30,48,2000,0,10000,yes,target,always,0,,,,,,,
 1637,Margaretha Sorin@MG_SAFETYWALL,attack,12,10,1000,0,5000,yes,self,always,0,,,,,,,
 1637,Margaretha Sorin@AL_PNEUMA,attack,25,1,5000,0,10000,yes,self,longrangeattacked,,,,,,,19,
 1637,Margaretha Sorin@AL_PNEUMA,chase,25,1,5000,0,10000,yes,self,longrangeattacked,,,,,,,19,
@@ -3031,7 +3031,7 @@
 1643,High Priest Margaretha@AL_PNEUMA,idle,25,1,10000,0,0,yes,self,longrangeattacked,,,,,,,,
 1643,High Priest Margaretha@AL_INCAGI,attack,29,10,2000,0,240000,yes,self,always,0,,,,,,2,
 1643,High Priest Margaretha@AL_INCAGI,chase,29,10,2000,0,240000,yes,self,always,0,,,,,,2,
-1643,High Priest Margaretha@AL_DECAGI,chase,30,11,2000,0,10000,yes,target,always,0,,,,,,,
+1643,High Priest Margaretha@AL_DECAGI,chase,30,48,2000,0,10000,yes,target,always,0,,,,,,,
 1643,High Priest Margaretha@MG_SAFETYWALL,attack,12,10,1000,0,5000,yes,self,always,0,,,,,,,
 1643,High Priest Margaretha@AL_PNEUMA,attack,25,1,5000,0,10000,yes,self,longrangeattacked,,,,,,,19,
 1643,High Priest Margaretha@AL_PNEUMA,chase,25,1,5000,0,10000,yes,self,longrangeattacked,,,,,,,19,
@@ -3196,7 +3196,7 @@
 1649,High Priest Margaretha@AL_PNEUMA,idle,25,1,10000,0,0,yes,self,longrangeattacked,,,,,,,,
 1649,High Priest Margaretha@AL_INCAGI,attack,29,10,2000,0,240000,yes,self,always,0,,,,,,2,
 1649,High Priest Margaretha@AL_INCAGI,chase,29,10,2000,0,240000,yes,self,always,0,,,,,,2,
-1649,High Priest Margaretha@AL_DECAGI,chase,30,11,2000,0,10000,yes,target,always,0,,,,,,,
+1649,High Priest Margaretha@AL_DECAGI,chase,30,48,2000,0,10000,yes,target,always,0,,,,,,,
 1649,High Priest Margaretha@MG_SAFETYWALL,attack,12,10,1000,0,5000,yes,self,always,0,,,,,,,
 1649,High Priest Margaretha@AL_PNEUMA,attack,25,1,5000,0,10000,yes,self,longrangeattacked,,,,,,,19,
 1649,High Priest Margaretha@AL_PNEUMA,chase,25,1,5000,0,10000,yes,self,longrangeattacked,,,,,,,19,
@@ -3382,8 +3382,8 @@
 1661,Errende Ebecee@AL_HEAL,chase,28,11,10000,500,5000,yes,self,myhpltmaxrate,30,,,,,,3,
 1661,Errende Ebecee@NPC_HOLYATTACK,attack,189,3,1000,0,5000,yes,target,always,0,,,,,,,
 1661,Errende Ebecee@NPC_SILENCEATTACK,attack,178,4,1000,700,5000,no,target,always,0,,,,,,,
-1661,Errende Ebecee@AL_DECAGI,attack,30,11,500,1000,5000,no,target,always,0,,,,,,29,
-1661,Errende Ebecee@AL_DECAGI,chase,30,11,500,1000,5000,no,target,always,0,,,,,,29,
+1661,Errende Ebecee@AL_DECAGI,attack,30,48,500,1000,5000,no,target,always,0,,,,,,29,
+1661,Errende Ebecee@AL_DECAGI,chase,30,48,500,1000,5000,no,target,always,0,,,,,,29,
 1662,Kavach Icarus@AC_DOUBLE,attack,46,10,500,1000,5000,no,target,always,0,,,,,,,
 1662,Kavach Icarus@AC_DOUBLE,attack,46,10,10000,1000,1000,no,target,skillused,46,,,,,,,
 1662,Kavach Icarus@AC_DOUBLE,chase,46,10,2000,1000,5000,no,target,always,0,,,,,,,
@@ -3674,8 +3674,8 @@
 1707,Thanatos Dolor@NPC_MENTALBREAKER,chase,159,2,500,0,5000,yes,target,always,0,,,,,,30,
 1707,Thanatos Dolor@NPC_DARKTHUNDER,attack,341,9,500,1000,5000,no,target,always,0,,,,,,,
 1707,Thanatos Dolor@NPC_DARKTHUNDER,chase,341,9,500,1000,5000,no,target,always,0,,,,,,,
-1707,Thanatos Dolor@AL_DECAGI,chase,30,11,2000,0,10000,yes,target,always,0,,,,,,,
-1707,Thanatos Dolor@AL_DECAGI,attack,30,11,2000,0,10000,yes,target,always,0,,,,,,,
+1707,Thanatos Dolor@AL_DECAGI,chase,30,48,2000,0,10000,yes,target,always,0,,,,,,,
+1707,Thanatos Dolor@AL_DECAGI,attack,30,48,2000,0,10000,yes,target,always,0,,,,,,,
 1707,Thanatos Dolor@AL_HEAL,attack,28,8,1000,0,5000,yes,friend,friendhpltmaxrate,40,,,,,,3,
 1707,Thanatos Dolor@AL_HEAL,attack,28,8,1000,0,5000,yes,self,myhpltmaxrate,40,,,,,,3,
 1707,Thanatos Dolor@AL_HEAL,idle,28,8,1000,0,5000,yes,friend,friendhpltmaxrate,40,,,,,,3,
@@ -3740,8 +3740,8 @@
 1712,Thanatos Dolor@NPC_MENTALBREAKER,chase,159,2,500,1000,10000,no,target,always,0,,,,,,,
 1712,Thanatos Dolor@NPC_DARKTHUNDER,attack,341,9,500,1000,5000,no,target,always,0,,,,,,,
 1712,Thanatos Dolor@NPC_DARKTHUNDER,chase,341,9,500,1000,5000,no,target,always,0,,,,,,,
-1712,Thanatos Dolor@AL_DECAGI,chase,30,11,2000,0,10000,yes,target,always,0,,,,,,,
-1712,Thanatos Dolor@AL_DECAGI,attack,30,11,2000,0,10000,yes,target,always,0,,,,,,,
+1712,Thanatos Dolor@AL_DECAGI,chase,30,48,2000,0,10000,yes,target,always,0,,,,,,,
+1712,Thanatos Dolor@AL_DECAGI,attack,30,48,2000,0,10000,yes,target,always,0,,,,,,,
 1712,Thanatos Dolor@AL_HEAL,attack,28,11,1000,0,5000,yes,friend,friendhpltmaxrate,70,,,,,,3,
 1712,Thanatos Dolor@AL_HEAL,attack,28,11,1000,0,5000,yes,self,myhpltmaxrate,70,,,,,,3,
 1712,Thanatos Dolor@AL_HEAL,idle,28,9,1000,0,5000,yes,friend,friendhpltmaxrate,70,,,,,,3,
@@ -3982,8 +3982,8 @@
 1754,Skeggiold@AL_HEAL,idle,28,9,5000,500,5000,no,self,myhpltmaxrate,30,,,,,,18,
 1754,Skeggiold@MG_THUNDERSTORM,attack,21,7,1000,1500,10000,no,target,always,0,,,,,,,
 1754,Skeggiold@MG_THUNDERSTORM,chase,21,7,1000,1500,10000,no,target,always,0,,,,,,,
-1754,Skeggiold@AL_DECAGI,attack,30,11,500,0,30000,no,target,always,0,,,,,,29,
-1754,Skeggiold@AL_DECAGI,chase,30,11,500,0,30000,no,target,always,0,,,,,,29,
+1754,Skeggiold@AL_DECAGI,attack,30,48,500,0,30000,no,target,always,0,,,,,,29,
+1754,Skeggiold@AL_DECAGI,chase,30,48,500,0,30000,no,target,always,0,,,,,,29,
 1754,Skeggiold@NPC_PETRIFYATTACK,attack,180,2,500,500,5000,no,target,always,0,,,,,,3,
 1754,Skeggiold@NPC_PETRIFYATTACK,chase,180,2,500,500,5000,no,target,always,0,,,,,,3,
 1754,Skeggiold@RG_STRIPARMOR,attack,217,3,500,0,5000,yes,target,always,0,,,,,,6,
@@ -4116,7 +4116,7 @@
 1769,Agav@MG_SAFETYWALL,attack,12,10,2000,0,5000,yes,self,always,0,,,,,,,
 1769,Agav@NPC_CURSEATTACK,attack,181,5,500,800,5000,no,target,always,0,,,,,,30,
 1769,Agav@NPC_CURSEATTACK,chase,181,5,500,800,5000,no,target,always,0,,,,,,30,
-1769,Agav@AL_DECAGI,chase,30,11,2000,0,10000,yes,target,always,0,,,,,,,
+1769,Agav@AL_DECAGI,chase,30,48,2000,0,10000,yes,target,always,0,,,,,,,
 1769,Agav@PR_LEXDIVINA,attack,76,1,1000,0,5000,yes,target,always,0,,,,,,36,
 1769,Agav@PR_LEXDIVINA,chase,76,1,1000,0,5000,yes,target,always,0,,,,,,36,
 1769,Agav@PR_LEXDIVINA,attack,76,1,5000,0,5000,yes,target,casttargeted,0,,,,,,36,
@@ -4275,7 +4275,7 @@
 1786,Agav@MG_SAFETYWALL,attack,12,10,2000,0,5000,yes,self,always,0,,,,,,,
 1786,Agav@NPC_CURSEATTACK,attack,181,5,500,800,5000,no,target,always,0,,,,,,30,
 1786,Agav@NPC_CURSEATTACK,chase,181,5,500,800,5000,no,target,always,0,,,,,,30,
-1786,Agav@AL_DECAGI,chase,30,11,2000,0,10000,yes,target,always,0,,,,,,,
+1786,Agav@AL_DECAGI,chase,30,48,2000,0,10000,yes,target,always,0,,,,,,,
 1786,Agav@PR_LEXDIVINA,attack,76,1,1000,0,5000,yes,target,always,0,,,,,,36,
 1786,Agav@PR_LEXDIVINA,chase,76,1,1000,0,5000,yes,target,always,0,,,,,,36,
 1786,Agav@PR_LEXDIVINA,attack,76,1,5000,0,5000,yes,target,casttargeted,0,,,,,,36,

+ 1 - 1
db/packet_db.txt

@@ -909,7 +909,7 @@ packet_ver: 20
 0x0285,6
 0x0286,4
 0x0287,-1
-0x0288,6
+0x0288,6,cashshopbuy,2:4
 0x0289,8
 0x028a,18
 0x028b,-1

+ 1 - 1
db/skill_cast_db.txt

@@ -88,7 +88,7 @@
 //-- AL_HOLYWATER
 31,800,400,500,0,0,0,0
 //-- AL_CRUCIS
-32,350,150,2000,0,0,0,0
+32,350,150,2000,0,60000,0
 //-- AL ANGELUS
 33,350,150,3500,0,0,30000:60000:90000:120000:150000:180000:210000:240000:270000:300000,0
 //-- AL_BLESSING

+ 27 - 9
db/skill_nocast_db.txt

@@ -21,29 +21,39 @@
 // Example:
 // 8,6 = Endure cannot be used in PvP and GvG maps (2+4)
 
+//PVP
+1013,2	//BS_GREED
+
 //GVG
 26,4	//AL_TELEPORT
 27,4	//AL_WARP
 87,4	//WZ_ICEWALL
 150,4	//TF_BACKSLIDING
-290,4	//SA_ABRACADABRA
+219,4	//RG_INTIMIDATE
+336,4	//WE_CALLPARTNER
 361,4	//HP_ASSUMPTIO
 362,4	//HP_BASILICA
 395,4	//CG_MOONLIT
+409,4	//WE_CALLPARENT
+410,4	//WE_CALLBABY
 491,4	//CR_CULTIVATION
 530,4	//NJ_KIRIKAGE
 691,4	//CASH_ASSUMPTIO
+1013,2048	//BS_GREED
 
 //BATTLEGROUND
 26,8	//AL_TELEPORT
 27,8	//AL_WARP
 87,8	//WZ_ICEWALL
 150,8	//TF_BACKSLIDING
+219,8	//RG_INTIMIDATE
 264,8	//MO_BODYRELOCATION
+336,8	//WE_CALLPARTNER
 361,8	//HP_ASSUMPTIO
 362,8	//HP_BASILICA
 395,8	//CG_MOONLIT
-396,8	//CG_MARIONETTE
+409,8	//WE_CALLPARENT
+410,8	//WE_CALLBABY
 491,8	//CR_CULTIVATION
 411,8	//TK_RUN
 426,8	//TK_HIGHJUMP
@@ -72,19 +82,20 @@
 79,16	//PR_MAGNUS
 
 //Zone 1 - Aldebaran Turbo Track
-219,32	//RG_INTIMIDATE
+8,32	//SM_ENDURE
 26,32	//AL_TELEPORT
 27,32	//AL_WARP
-51,32	//TF_HIDING
-135,32	//AS_CLOAKING
-389,32	//ST_CHASEWALK
 35,32	//AL_CURE
+51,32	//TF_HIDING
 87,32	//WZ_ICEWALL
+135,32	//AS_CLOAKING
+219,32	//RG_INTIMIDATE
+264,32	//MO_BODYRELOCATION
+357,32	//LK_CONCENTRATION
 359,32	//LK_BERSERK
 362,32	//HP_BASILICA
+389,32	//ST_CHASEWALK
 395,32	//CG_MOONLIT
-357,32	//LK_CONCENTRATION
-264,32	//MO_BODYRELOCATION
 
 //Zone 2 - Jail
 421,64	//TK_JUMPKICK
@@ -96,6 +107,7 @@
 
 //Zone 4 - WoE:SE
 426,256 //TK_HIGHJUMP
+290,256	//SA_ABRACADABRA
 
 //Zone 5 - Sealed Shrine
 12,512	//MG_SAFETYWALL
@@ -104,9 +116,15 @@
 361,512	//HP_ASSUMPTIO
 691,512	//CASH_ASSUMPTIO
 
-//Zone 6 -Endless Tower
+//Zone 6 - Endless Tower, Orc's Memory, Nidhoggur's Nest
 26,1024	//AL_TELEPORT
 87,1024	//WZ_ICEWALL
 219,1024	//RG_INTIMIDATE
 405,1024	//PF_SPIDERWEB
 674,1024	//NPC_EXPULSION
+
+//Zone 7 - Towns
+232,2048	//AM_CANNIBALIZE
+233,2048	//AM_SPHEREMINE
+491,2048	//CR_CULTIVATION
+1013,2048	//BS_GREED

+ 31 - 12
doc/script_commands.txt

@@ -181,6 +181,8 @@
 //=       Documented special map names recognized by 'warpguild'. [Ai4rei]
 //= 3.45.20110709
 //=       Added 'getmercinfo' command. [Ai4rei]
+//= 3.46.20110810
+//=       Added information on OnTouchNPC and 'unitwarp' special case [Skotlex]
 //=========================================================
 
 This document is a reference manual for all the scripting commands and functions 
@@ -423,7 +425,8 @@ spanning triggerX cells in every direction across X and triggerY in every
 direction across Y. Walking into that area will trigger the NPC. If no 
 'OnTouch:' special label is present in the NPC code, the execution will start 
 from the beginning of the script, otherwise, it will start from the 'OnTouch:' 
-label.
+label. Monsters can also trigger the NPC, though the label 'OnTouchNPC:' is 
+used in this case.
 
 The code part is the script code that will execute whenever the NPC is 
 triggered. It may contain commands and function calls, descriptions of which 
@@ -574,7 +577,9 @@ Variables
 ---------
 
 The meat of every programming language is variables - places where you store 
-data. 
+data.
+
+In the eAthena scripting language, variable names are not case sensitive.
 
 Variables are divided into and uniquely identified by the combination of:
 prefix  - determines the scope and extent (or lifetime) of the variable
@@ -611,7 +616,9 @@ nothing  - A permanent variable attached to the character, the default variable
 "."      - A NPC variable.
            They exist in the NPC and disappear when the server restarts or the 
            NPC is reloaded. Can be accessed from inside the NPC or by calling 
-           'getvariableofnpc'.
+           'getvariableofnpc'. Function objects can also have .variables which 
+           are accessible from inside the function, however 'getvariableofnpc' 
+           does NOT work on function objects.
 ".@"     - A scope variable.
            They are unique to the instance and scope. Each instance has it's 
            own scope that ends when the script ends. Calling a function with 
@@ -1301,6 +1308,9 @@ Example(s):
 //This will set the .var variable of TargetNPC to 1.
 	set getvariableofnpc(.var,"TargetNPC"),1;
 
+Note: even though function objects can have .variables, 
+getvariableofnpc will not work on them.
+
 ---------------------------------------
 
 *goto <label>;
@@ -2164,6 +2174,7 @@ Whatever it returns is determined by type.
  1 - The visible part of the NPC's display name
  2 - The hidden part of the NPC's display name
  3 - The NPC's unique name (::name)
+ 4 - The name of the map the NPC is in.
 
 ---------------------------------------
 
@@ -2192,11 +2203,14 @@ This will make @arraysize == 6. But if you try this:
 This command retrieves the value of the element of given array at given index.
 This is equivalent to using:
 
-    array[index]
+    <array name>[<index>]
 
 The reason for this is, that this short form is internally converted into a call
 to getelementofarray, when the script is loaded.
 
+Also useful when passing arrays to functions.
+getelementofarray(getarg(0),<index>) will work, but getarg(0)[<index>] will not.
+
 ---------------------------------------
 
 *readparam(<parameter number>)
@@ -3687,7 +3701,7 @@ is executing this script, unless it's some kind of "chosen" script.
  
 Example:
  
-warpchar "prontera",150,100,20000001;
+warpchar "prontera",150,100,150001;
  
 ---------------------------------------
  
@@ -4014,7 +4028,7 @@ wall), the character is pushed only up to the obstacle.
 
 This command will give a specific amount of specified items to the target 
 character. If the character is not online, nothing will happen.
-If <character ID> is not specified, items will be created in the invoking 
+If <account ID> is not specified, items will be created in the invoking 
 character inventory instead.
 
 In the first and most commonly used version of this command, items are 
@@ -4056,7 +4070,7 @@ quite a few item scripts. For more examples check just about any official script
 *getitem2 "<Item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
 
 This command will give an amount of specified items to the invoking character. 
-If an optional character ID is specified, and that character is currently 
+If an optional account ID is specified, and the target character is currently 
 online, items will be created in their inventory instead. If they are not 
 online, nothing will happen. It works essentially the same as 'getitem' (it even 
 works for negative ID numbers the same way, which is kinda silly) but is a lot 
@@ -5241,6 +5255,10 @@ Example(s):
 
 Okay, these commands should be fairly self explaining.
 For the emotions, you can look in db/const.txt for prefixes with e_
+PS: unitwarp supports a <GID> of zero, which causes the executor of the script to be affected. This can be used with OnTouchNPC to warp monsters:
+
+OnTouchNPC:
+	unitwarp 0,"this",-1,-1;
 
 ---------------------------------------
 
@@ -6121,13 +6139,14 @@ the NPC with the said name.
 
 *rand(<number>{,<number>});
 
-This function returns a number, randomly positioned between 0 and the number you 
-specify (if you only specify one) and the two numbers you specify if you give it 
-two.
+This function returns a number ...
+(if you specify one) ... randomly positioned between 0 and the number you specify -1.
+(if you specify two) ... randomly positioned between the two numbers you specify.
 
-rand(10) would result in 0,1,2,3,4,5,6,7,8 or 9
+rand(10)  would result in 0,1,2,3,4,5,6,7,8 or 9
+rand(0,9) would result in 0,1,2,3,4,5,6,7,8 or 9
 
-rand(2,10) would result in 2,3,4,5,6,7,8,9 or 10
+rand(2,5) would result in 2,3,4 or 5
 
 ---------------------------------------
 

+ 10 - 0
npc/Changelog.txt

@@ -4,10 +4,20 @@ Date		Added
 	* Rev. 14941 Added Archbishop job quest, and missing Brasilis files. [L0ne_W0lf]
 2011/08/10
 	* Rev. 14931 Added scripts and NPC Brasilis updates from trunk r14928. [L0ne_W0lf]
+	* Updated the quests_brasilis ontouchNPC warp command to use unitwarp instead. [Skotlex]
+2011/08/09
+	* Rev. 14928 Implemented the rest of Brasilis, and updated existing Brasilis NPCs. [L0ne_W0lf]
 2011/07/26
 	* Rev. 14922 Added Renewal Guides, and made the filenames uniform. [L0ne_W0lf]
 2011/07/21
 	* Rev. 14920 Updated most active NPCs that give EXP to renewal standards. [L0ne_W0lf]
+2011/07/16
+	* Rev. 14912 Updated dialog in monster_race.txt [L0ne_W0lf]
+2011/07/16
+	* Rev. 14900 Have been working on this for months: Added Nidhoggr's Nest instance. [L0ne_W0lf]
+	* Tweaks to how checkquest is used in orc's memory and sealed shrine.
+2011/07/13
+	* Rev. 14905 Tweaked the sealed shrine entrance NPCs. Hopefully the damn thing works now. [L0ne_W0lf]
 2011/07/3
 	* Rev. 14884 Updated Tutorial quests, and added back NPCs needed for Priest quest. [L0ne_W0lf]
 2011/06/11

+ 1 - 1
npc/cities/alberta.txt

@@ -325,7 +325,7 @@ alberta,190,173,4	script	Phelix	85,{
 				case 2:
 					mes "[Phelix]";
 					mes "I'm not giving you more then 100 at a time so don't bother, OK? If you don't want any, just say '0'.";
-					mes "Right now, the most you can get is " + gap + " but remember, 100 at most, you want to break my back?.";
+					mes "Right now, the most you can get is " + .@max + " but remember, 100 at most, you want to break my back?.";
 					input .@amount;
 					next;
 					mes "[Phelix]";

+ 20 - 1
npc/guides/guides_brasilis.txt

@@ -3,7 +3,7 @@
 //===== By: ================================================== 
 //= L0ne_W0lf
 //===== Current Version: ===================================== 
-//= 1.0
+//= 1.1
 //===== Compatible With: ===================================== 
 //= eAthena  SVN
 //===== Description: ========================================= 
@@ -11,6 +11,7 @@
 //= Guide for the city of Brasilis
 //===== Additional Comments: ================================= 
 //= 1.0 First Version, Renewal guide.
+//= 1.1 Added a missing close.
 //============================================================ 
 
 brasilis,219,97,3	script	Brasilis Guide	478,{
@@ -74,5 +75,23 @@ brasilis,219,97,3	script	Brasilis Guide	478,{
 			mes "Wandering on your own is always the best way to explore. Anyway, take care.";
 			close;
 		}
+		close;
+		break;
+	case 2:
+		viewpoint 2,273,149,2,0xFF0000;
+		viewpoint 2,308,333,3,0xCC6600;
+		viewpoint 0,133,167,4,0x00FF00;
+		viewpoint 0,238,248,5,0x00FF00;
+		set .@compass_check,0;
+		mes "[Brasilis Guide]";
+		mes "I've deleted all marks on the mini-map.";
+		mes "Whenever you'd like to put marks";
+		mes "there, you can ask me.";
+		close;
+	case 3:
+		mes "[Brasilis Guide]";
+		mes "Exploring things here on your own can also be fun.";
+		mes "Anyway, take care.";
+		close;
 	}
 }

+ 5 - 5
npc/instances/NydhoggsNest.txt

@@ -1,5 +1,5 @@
 //===== eAthena Script ======================================= 
-//= Nidhoggr's Nest 
+//= Nidhoggr's Nest
 //===== By: ================================================== 
 //= L0ne_W0lf, various sources
 //===== Current Version: ===================================== 
@@ -11,7 +11,7 @@
 //= Nidhoggr's Nest Instance
 //===== Additional Comments: ================================= 
 //= 1.0 First version.
-//= 1.1 Updated dialog slightly, adjusted EXP gained.
+//= 1.1 Minor dialog updates.
 //= 1.2 No longer glitches when anyone but party leader talks to the first NPC.
 //============================================================ 
 
@@ -1188,7 +1188,7 @@ spl_in01,104,56,3	script	Aide Arioss#edq	437,3,3,{
 			next;
 			mes "[Aide Arioss]";
 			mes "It can't compare with the effort you have put in for us... but please accept our token of friendship.";
-			getexp 150000,35000;
+			getexp 1500000,350000;
 			getitem 6081,10; //Splendide_Coin
 			set ins_nyd,131;
 			mes "[Aide Arioss]";
@@ -2633,7 +2633,7 @@ OnTimer10000:
 }
 
 2@nyd,6,8,0	script	nyd_2f_yellow_c	-1,{
-OnInstanceInit:;
+OnInstanceInit:
 	disablenpc instance_npcname("nyd_2f_yellow_c", instance_id());
 	end;
 
@@ -2935,7 +2935,7 @@ OnTouch:
 }
 
 2@nyd,1,1,0	script	ins_nyd2_spawn_mobs	-1,{
-OnIntanceInit:
+OnInstanceInit:
 	areamonster "2@nyd",200,92,180,80,"Rhyncho",2020,20;
 	areamonster "2@nyd",200,92,180,80,"Phylla",2021,20;
 	areamonster "2@nyd",200,92,180,80,"Dark Shadow",2023,20;

+ 1 - 1
npc/jobs/2-1/blacksmith.txt

@@ -351,7 +351,7 @@ ein_in01,201,27,3	script	Guildsman#alberta	63,{
 					mes "1. Which one of the following regions is matched incorrectly";
 					mes "with its specialty item?";
 					next;
-					if (select("Morroc - Thief Clothes:Alberta - Two Hand Axe:Comodo - Berserk Potion:Alberta - Swordmace") == 2)
+					if (select("Morroc - Thief Clothes:Alberta - Two Hand Axe:Comodo - Berserk Potion:Alberta - Swordmace") == 4)
 						set .@black_q,.@black_q+10;
 					mes "[Geschupenschte]";
 					mes "2. What status can";

+ 2 - 1
npc/jobs/2-2/sage.txt

@@ -2680,7 +2680,8 @@ OnInit:
 
 OnEnable:
 	enablenpc "Arena#2";
-	disablenpc "Arena#1::OnReset";
+	donpcevent "Arena#1::OnReset";
+	disablenpc "Arena#1";
 	set .MyMobs,24;
 	monster "job_sage",111,102,"Numerical Value",1063,1,"Arena#2::OnMyMobDead";
 	monster "job_sage",111,102,"Physics",1063,1,"Arena#2::OnMyMobDead";

+ 1 - 1
npc/quests/first_class/tu_archer.txt

@@ -1876,7 +1876,7 @@ prt_castle,76,165,6	script	Minister#tu	55,{
 //=================================================Range NPC====================================================
 prt_castle,94,150,4	script	#sound_tu	139,10,10,{
 OnTouch_:
-	if(tu_archer02 != 6) {
+	if(tu_archer02 == 6) {
 		mes "[Minister]";
 		mes "Contact the";
 		mes "Prontera Church.";

+ 1 - 1
npc/quests/quests_amatsu.txt

@@ -367,7 +367,7 @@ OnInit:
 
 OnStartArena:
 	disablenpc "Coach#ama";
-	disablenpc "Am Mut::Onreset";
+	donpcevent "Am Mut#ama::Onreset";
 	donpcevent "Dokebi#ez::Onreset";
 	donpcevent "Dokebi#hd::Onreset";
 	enablenpc "Grandma#ama1";

+ 5 - 5
npc/quests/quests_brasilis.txt

@@ -51,7 +51,7 @@ brasilis,297,307,5	script	Angelo#br	50,{
 					mes "Oh, thank you. You found all of 3 puppies.";
 					mes "Thanks a lot.";
 					mes "I hope this is useful to you. hoho.";
-					getexp 50000,0;
+					getexp 500000,0;
 					erasequest 9031;
 					setquest 9032;
 					set .@bosang,rand(1,10);
@@ -1230,7 +1230,7 @@ brasilis,187,162,5	script	Candy Maker	476,{
 		set brazil_gua,11;
 		completequest 2200;
 		getitem 12414,1; //Guarana_Candy
-		getexp 70000,10000;
+		getexp 700000,100000;
 		close;
 	}
 	else if (brazil_gua == 11) {
@@ -1923,7 +1923,7 @@ brasilis,203,286,3	script	Botanist Karmen#bra	893,{
 		mes "The water lily must truly be a lucky flower. hahaha";
 		set brazil_regia,10;
 		completequest 2207;
-		getexp 50000,10000;
+		getexp 500000,100000;
 		close;
 	}
 	else {
@@ -2669,7 +2669,7 @@ bra_dun02,67,205,5	script	Recluse#bra	475,3,3,{
 	end;
 
 OnTouchNPC:
-	warp "bra_dun02",67,215;
+	unitwarp 0,"this",67,215;
 	end;
 }
 
@@ -4246,7 +4246,7 @@ bra_in01,206,188,1	script	Open Manhole#todunbra	844,{
 		set brazil_ghost,8;
 		//completequest 2208;
 		completequest 60355;
-		getexp 90000,0;
+		getexp 900000,0;
 		disablenpc "Ghost#bra_end";
 		close;
 	}

+ 9 - 9
npc/quests/quests_hugel.txt

@@ -3806,7 +3806,7 @@ hu_fild06,168,359,3	script	Moks Mushrooms#Mush1	111,{
 
 	if(hg_tre > 9 && hg_tre < 15)
 	{
-		mes "- You found mushrooms that is as big as your palm. -";
+		mes "- You found mushrooms that are as big as your palm. -";
 		next;
 		switch( select( "Gather them.","Pass." ) )
 		{
@@ -3843,7 +3843,7 @@ hu_fild06,168,359,3	script	Moks Mushrooms#Mush1	111,{
 			else if(hg_tre == 15)
 				mes "Collected Moks Mushroom Solution: 5ea ";
 			initnpctimer;
-			disablenpc "Moks Mushroom#Mush1";
+			disablenpc "Moks Mushrooms#Mush1";
 			close;
 		break;
 		case 2:
@@ -3860,7 +3860,7 @@ hu_fild06,168,359,3	script	Moks Mushrooms#Mush1	111,{
 	}
 
 OnTimer20000:
-	enablenpc "Moks Mushroom#Mush1";
+	enablenpc "Moks Mushrooms#Mush1";
 	stopnpctimer;
 	end;
 
@@ -3870,7 +3870,7 @@ hu_fild06,194,341,3	script	Moks Mushrooms#Mush2	111,{
 
 	if(hg_tre > 9 && hg_tre < 15)
 	{
-		mes "- You found mushrooms that is as big as your palm. -";
+		mes "- You found mushrooms that are as big as your palm. -";
 		next;
 		switch( select( "Gather them.","Pass." ) )
 		{
@@ -3907,7 +3907,7 @@ hu_fild06,194,341,3	script	Moks Mushrooms#Mush2	111,{
 			else if(hg_tre == 15)
 				mes "Collected Moks Mushroom Solution: 5ea ";
 			initnpctimer;
-			disablenpc "Moks Mushroom#Mush2";
+			disablenpc "Moks Mushrooms#Mush2";
 			close;
 		break;
 		case 2:
@@ -3924,7 +3924,7 @@ hu_fild06,194,341,3	script	Moks Mushrooms#Mush2	111,{
 	}
 
 OnTimer20000:
-	enablenpc "Moks Mushroom#Mush2";
+	enablenpc "Moks Mushrooms#Mush2";
 	stopnpctimer;
 	end;
 
@@ -3934,7 +3934,7 @@ hu_fild06,198,339,3	script	Moks Mushrooms#Mush3	111,{
 
 	if(hg_tre > 9 && hg_tre < 15)
 	{
-		mes "- You found mushrooms that is as big as your palm. -";
+		mes "- You found mushrooms that are as big as your palm. -";
 		next;
 		switch( select( "Gather them.","Pass." ) )
 		{
@@ -3971,7 +3971,7 @@ hu_fild06,198,339,3	script	Moks Mushrooms#Mush3	111,{
 			else if(hg_tre == 15)
 				mes "Collected Moks Mushroom Solution: 5ea ";
 			initnpctimer;
-			disablenpc "Moks Mushroom#Mush3";
+			disablenpc "Moks Mushrooms#Mush3";
 			close;
 		break;
 		case 2:
@@ -3988,7 +3988,7 @@ hu_fild06,198,339,3	script	Moks Mushrooms#Mush3	111,{
 	}
 
 OnTimer20000:
-	enablenpc "Moks Mushroom#Mush3";
+	enablenpc "Moks Mushrooms#Mush3";
 	stopnpctimer;
 	end;
 

+ 1 - 0
npc/scripts_mapflags.conf

@@ -27,4 +27,5 @@ npc: conf/mapflag/battleground.txt
 npc: conf/mapflag/fireworks.txt
 npc: conf/mapflag/novending.txt
 npc: conf/mapflag/town.txt
+npc: conf/mapflag/reset.txt
 // --------------------------------------------------------------

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 477 - 393
sql-files/item_db.sql


+ 2 - 2
sql-files/mob_db.sql

@@ -1177,7 +1177,7 @@ REPLACE INTO `mob_db` VALUES (2027,'G_DARK_SHADOW','Dark Shadow','Dark Shadow',1
 # REPLACE INTO `mob_db` VALUES (2054,'E_BATHORY','Bathory','Bathory',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
 # REPLACE INTO `mob_db` VALUES (2055,'E_INCUBUS','Incubus','Incubus',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
 # REPLACE INTO `mob_db` VALUES (2056,'E_ZHERLTHSH','Zherlthsh','Zealotus',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
-# REPLACE INTO `mob_db` VALUES (2057,'E_CRAMP','Cramp','Cramp',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (2057,'E_CRAMP','Cramp','Cramp',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
 # REPLACE INTO `mob_db` VALUES (2058,'M_MIMIC','Mimic','Mimic',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
 # REPLACE INTO `mob_db` VALUES (2059,'M_DISGUISE','Disguise','Disguise',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
 # REPLACE INTO `mob_db` VALUES (2060,'M_ALICE','Alice','Alice',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
@@ -1201,7 +1201,7 @@ REPLACE INTO `mob_db` VALUES (2074,'CURUPIRA','Curupira','Curupira',68,3096,0,62
 # REPLACE INTO `mob_db` VALUES (2078,'S_SUCCUBUS','Succubus','Succubus',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
 # REPLACE INTO `mob_db` VALUES (2079,'CRYSTAL_H','Crystal','Crystal',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
 # REPLACE INTO `mob_db` VALUES (2080,'CRYSTAL_L','Crystal','Crystal',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
-# REPLACE INTO `mob_db` VALUES (2081,'E_HYDRA','Hydra','Hydra',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (2081,'E_HYDRA','Suspicious Hydra','Strange Hydra',34,854,1,0,0,7,1,2,100,100,1,1,1,1,1,1,10,12,0,3,41,0x0,1000,800,432,600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
 REPLACE INTO `mob_db` VALUES (2082,'G_PIRANHA','Piranha','Piranha',75,4522,0,0,0,1,182,223,2,10,69,45,30,30,66,35,10,12,1,5,61,0x3295,200,768,768,384,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
 # REPLACE INTO `mob_db` VALUES (2083,'HORN_SCARABA','Scaraba','Scaraba',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
 # REPLACE INTO `mob_db` VALUES (2084,'HORN_SCARABA2','Scaraba','Scaraba',1,50,0,0,0,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x120,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);

+ 20 - 2
src/CMakeLists.txt

@@ -1,9 +1,27 @@
 
+#
+# setup and static libraries
+#
 add_subdirectory( common )
+if( HAVE_common_base )
+	option( BUILD_TXT_SERVERS "build txt server executables" ON )
+else()
+	message( STATUS "Disabled txt server targets (requires common_base)" )
+endif()
+if( HAVE_common_sql )
+	option( BUILD_SQL_SERVERS "build sql server executables" ON )
+else()
+	message( STATUS "Disabled sql server targets (requires common_sql)" )
+endif()
+
+
+#
+# targets
+#
 add_subdirectory( login )
 add_subdirectory( char )
 add_subdirectory( char_sql )
 add_subdirectory( map )
 add_subdirectory( tool )
-#add_subdirectory( txt-converter )
-#add_subdirectory( plugins )
+add_subdirectory( txt-converter )
+add_subdirectory( plugins )

+ 29 - 27
src/char/CMakeLists.txt

@@ -1,33 +1,39 @@
 
+#
+# setup
+#
+set( TXT_CHAR_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}  CACHE INTERNAL "" )
+
+
 #
 # char txt
 #
-if( HAVE_common_base )
+if( BUILD_TXT_SERVERS )
 message( STATUS "Creating target char-server" )
 set( TXT_CHAR_HEADERS
-	"${CMAKE_CURRENT_SOURCE_DIR}/char.h"
-	"${CMAKE_CURRENT_SOURCE_DIR}/int_guild.h"
-	"${CMAKE_CURRENT_SOURCE_DIR}/int_homun.h"
-	"${CMAKE_CURRENT_SOURCE_DIR}/int_party.h"
-	"${CMAKE_CURRENT_SOURCE_DIR}/int_pet.h"
-	"${CMAKE_CURRENT_SOURCE_DIR}/int_status.h"
-	"${CMAKE_CURRENT_SOURCE_DIR}/int_storage.h"
-	"${CMAKE_CURRENT_SOURCE_DIR}/inter.h"
+	"${TXT_CHAR_SOURCE_DIR}/char.h"
+	"${TXT_CHAR_SOURCE_DIR}/int_guild.h"
+	"${TXT_CHAR_SOURCE_DIR}/int_homun.h"
+	"${TXT_CHAR_SOURCE_DIR}/int_party.h"
+	"${TXT_CHAR_SOURCE_DIR}/int_pet.h"
+	"${TXT_CHAR_SOURCE_DIR}/int_status.h"
+	"${TXT_CHAR_SOURCE_DIR}/int_storage.h"
+	"${TXT_CHAR_SOURCE_DIR}/inter.h"
 	)
 set( TXT_CHAR_SOURCES
-	"${CMAKE_CURRENT_SOURCE_DIR}/char.c"
-	"${CMAKE_CURRENT_SOURCE_DIR}/int_guild.c"
-	"${CMAKE_CURRENT_SOURCE_DIR}/int_homun.c"
-	"${CMAKE_CURRENT_SOURCE_DIR}/int_party.c"
-	"${CMAKE_CURRENT_SOURCE_DIR}/int_pet.c"
-	"${CMAKE_CURRENT_SOURCE_DIR}/int_status.c"
-	"${CMAKE_CURRENT_SOURCE_DIR}/int_storage.c"
-	"${CMAKE_CURRENT_SOURCE_DIR}/inter.c"
+	"${TXT_CHAR_SOURCE_DIR}/char.c"
+	"${TXT_CHAR_SOURCE_DIR}/int_guild.c"
+	"${TXT_CHAR_SOURCE_DIR}/int_homun.c"
+	"${TXT_CHAR_SOURCE_DIR}/int_party.c"
+	"${TXT_CHAR_SOURCE_DIR}/int_pet.c"
+	"${TXT_CHAR_SOURCE_DIR}/int_status.c"
+	"${TXT_CHAR_SOURCE_DIR}/int_storage.c"
+	"${TXT_CHAR_SOURCE_DIR}/inter.c"
 	)
 set( DEPENDENCIES common_base )
 set( LIBRARIES ${GLOBAL_LIBRARIES} )
 set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} TXT_ONLY )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS} -DTXT_ONLY" )
 set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${TXT_CHAR_HEADERS} ${TXT_CHAR_SOURCES} )
 source_group( common FILES ${COMMON_BASE_HEADERS} )
 source_group( char FILES ${TXT_CHAR_HEADERS} ${TXT_CHAR_SOURCES} )
@@ -35,17 +41,13 @@ include_directories( ${INCLUDE_DIRS} )
 add_executable( char-server ${SOURCE_FILES} )
 add_dependencies( char-server ${DEPENDENCIES} )
 target_link_libraries( char-server ${LIBRARIES} ${DEPENDENCIES} )
-set_target_properties( char-server PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
-if( WITH_COMPONENT_RUNTIME )
+set_target_properties( char-server PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+if( INSTALL_COMPONENT_RUNTIME )
 	cpack_add_component( Runtime_charserver_txt DESCRIPTION "char-server (txt version)" DISPLAY_NAME "char-server" GROUP Runtime )
 	install( TARGETS char-server
 		DESTINATION "."
 		COMPONENT Runtime_charserver_txt )
-endif()
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} char-server  CACHE INTERNAL "" )
 message( STATUS "Creating target char-server - done" )
-set( HAVE_char-server ON  CACHE BOOL "char-server target is available" )
-mark_as_advanced( HAVE_char-server )
-else()
-message( STATUS "Skipping target char-server (requires common_base)" )
-unset( HAVE_char-server CACHE )
-endif()
+endif( BUILD_TXT_SERVERS )

+ 26 - 16
src/char/char.c

@@ -436,7 +436,7 @@ int search_character_online(int aid, int cid)
 {
 	//Look for online character.
 	struct online_char_data* character;
-	character = idb_get(online_char_db, aid);
+	character = (struct online_char_data*)idb_get(online_char_db, aid);
 	if(character &&
 		character->char_id == cid &&
 		character->server > -1) 
@@ -1804,33 +1804,33 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
 
 	buf = WBUFP(buffer,0);
 	WBUFL(buf,0) = p->char_id;
-	WBUFL(buf,4) = min(p->base_exp, LONG_MAX);
+	WBUFL(buf,4) = min(p->base_exp, INT32_MAX);
 	WBUFL(buf,8) = p->zeny;
-	WBUFL(buf,12) = min(p->job_exp, LONG_MAX);
+	WBUFL(buf,12) = min(p->job_exp, INT32_MAX);
 	WBUFL(buf,16) = p->job_level;
 	WBUFL(buf,20) = 0; // probably opt1
 	WBUFL(buf,24) = 0; // probably opt2
 	WBUFL(buf,28) = p->option;
 	WBUFL(buf,32) = p->karma;
 	WBUFL(buf,36) = p->manner;
-	WBUFW(buf,40) = min(p->status_point, SHRT_MAX);
+	WBUFW(buf,40) = min(p->status_point, INT16_MAX);
 #if PACKETVER > 20081217
 	WBUFL(buf,42) = p->hp;
 	WBUFL(buf,46) = p->max_hp;
 	offset+=4;
 	buf = WBUFP(buffer,offset);
 #else
-	WBUFW(buf,42) = min(p->hp, SHRT_MAX);
-	WBUFW(buf,44) = min(p->max_hp, SHRT_MAX);
+	WBUFW(buf,42) = min(p->hp, INT16_MAX);
+	WBUFW(buf,44) = min(p->max_hp, INT16_MAX);
 #endif
-	WBUFW(buf,46) = min(p->sp, SHRT_MAX);
-	WBUFW(buf,48) = min(p->max_sp, SHRT_MAX);
+	WBUFW(buf,46) = min(p->sp, INT16_MAX);
+	WBUFW(buf,48) = min(p->max_sp, INT16_MAX);
 	WBUFW(buf,50) = DEFAULT_WALK_SPEED; // p->speed;
 	WBUFW(buf,52) = p->class_;
 	WBUFW(buf,54) = p->hair;
 	WBUFW(buf,56) = p->option&0x20 ? 0 : p->weapon; //When the weapon is sent and your option is riding, the client crashes on login!?
 	WBUFW(buf,58) = p->base_level;
-	WBUFW(buf,60) = min(p->skill_point, SHRT_MAX);
+	WBUFW(buf,60) = min(p->skill_point, INT16_MAX);
 	WBUFW(buf,62) = p->head_bottom;
 	WBUFW(buf,64) = p->shield;
 	WBUFW(buf,66) = p->head_top;
@@ -1838,12 +1838,12 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
 	WBUFW(buf,70) = p->hair_color;
 	WBUFW(buf,72) = p->clothes_color;
 	memcpy(WBUFP(buf,74), p->name, NAME_LENGTH);
-	WBUFB(buf,98) = min(p->str, UCHAR_MAX);
-	WBUFB(buf,99) = min(p->agi, UCHAR_MAX);
-	WBUFB(buf,100) = min(p->vit, UCHAR_MAX);
-	WBUFB(buf,101) = min(p->int_, UCHAR_MAX);
-	WBUFB(buf,102) = min(p->dex, UCHAR_MAX);
-	WBUFB(buf,103) = min(p->luk, UCHAR_MAX);
+	WBUFB(buf,98) = min(p->str, UINT8_MAX);
+	WBUFB(buf,99) = min(p->agi, UINT8_MAX);
+	WBUFB(buf,100) = min(p->vit, UINT8_MAX);
+	WBUFB(buf,101) = min(p->int_, UINT8_MAX);
+	WBUFB(buf,102) = min(p->dex, UINT8_MAX);
+	WBUFB(buf,103) = min(p->luk, UINT8_MAX);
 	WBUFW(buf,104) = p->slot;
 #if PACKETVER >= 20061023
 	WBUFW(buf,106) = ( p->rename > 0 ) ? 0 : 1;
@@ -2208,7 +2208,7 @@ int parse_fromlogin(int fd)
 				memcpy(sd->email, RFIFOP(fd,6), 40);
 				sd->expiration_time = (time_t)RFIFOL(fd,46);
 				sd->gmlevel = RFIFOB(fd,50);
-				safestrncpy(sd->birthdate, RFIFOP(fd,51), sizeof(sd->birthdate));
+				safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,51), sizeof(sd->birthdate));
 
 				// continued from char_auth_ok...
 				if( max_connect_user && count_users() >= max_connect_user && sd->gmlevel < gm_allow_level )
@@ -2223,6 +2223,16 @@ int parse_fromlogin(int fd)
 				{
 					// send characters to player
 					mmo_char_send006b(i, sd);
+#if PACKETVER >=  20110309
+					// PIN code system, disabled
+					WFIFOHEAD(i, 12);
+					WFIFOW(i, 0) = 0x08B9;
+					WFIFOW(i, 2) = 0;
+					WFIFOW(i, 4) = 0;
+					WFIFOL(i, 6) = sd->account_id;
+					WFIFOW(i, 10) = 0;
+					WFIFOSET(i, 12);
+#endif
 				}
 			}
 			RFIFOSKIP(fd,62);

+ 12 - 11
src/char_sql/CMakeLists.txt

@@ -1,8 +1,14 @@
 
+#
+# setup
+#
+set( SQL_CHAR_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}  CACHE INTERNAL "" )
+
+
 #
 # char sql
 #
-if( HAVE_common_sql )
+if( BUILD_SQL_SERVERS )
 message( STATUS "Creating target char-server_sql" )
 set( SQL_CHAR_HEADERS
 	"${CMAKE_CURRENT_SOURCE_DIR}/char.h"
@@ -33,7 +39,7 @@ set( SQL_CHAR_SOURCES
 set( DEPENDENCIES common_sql )
 set( LIBRARIES ${GLOBAL_LIBRARIES} )
 set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS}" )
 set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} ${SQL_CHAR_HEADERS} ${SQL_CHAR_SOURCES} )
 source_group( common FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} )
 source_group( char FILES ${SQL_CHAR_HEADERS} ${SQL_CHAR_SOURCES} )
@@ -41,17 +47,12 @@ include_directories( ${INCLUDE_DIRS} )
 add_executable( char-server_sql ${SOURCE_FILES} )
 add_dependencies( char-server_sql ${DEPENDENCIES} )
 target_link_libraries( char-server_sql ${LIBRARIES} ${DEPENDENCIES} )
-set_target_properties( char-server_sql PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
-if( WITH_COMPONENT_RUNTIME )
+set_target_properties( char-server_sql PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+if( INSTALL_COMPONENT_RUNTIME )
 	cpack_add_component( Runtime_charserver_sql DESCRIPTION "char-server (sql version)" DISPLAY_NAME "char-server_sql" GROUP Runtime )
 	install( TARGETS char-server_sql
 		DESTINATION "."
 		COMPONENT Runtime_charserver_sql )
-endif()
+endif( INSTALL_COMPONENT_RUNTIME )
 message( STATUS "Creating target char-server_sql - done" )
-set( HAVE_char-server_sql ON  CACHE BOOL "char-server_sql target is available" )
-mark_as_advanced( HAVE_char-server_sql )
-else()
-message( STATUS "Skipping target char-server_sql (requires common_sql)" )
-unset( HAVE_char-server_sql CACHE )
-endif()
+endif( BUILD_SQL_SERVERS )

+ 86 - 39
src/char_sql/char.c

@@ -409,6 +409,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 	int diff = 0;
 	char save_status[128]; //For displaying save information. [Skotlex]
 	struct mmo_charstatus *cp;
+	int errors = 0; //If there are any errors while saving, "cp" will not be updated at the end.
 	StringBuf buf;
 
 	if (char_id!=p->char_id) return 0;
@@ -425,22 +426,28 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 	//map inventory data
 	if( memcmp(p->inventory, cp->inventory, sizeof(p->inventory)) )
 	{
-		memitemdata_to_sql(p->inventory, MAX_INVENTORY, p->char_id, TABLE_INVENTORY);
-		strcat(save_status, " inventory");
+		if (!memitemdata_to_sql(p->inventory, MAX_INVENTORY, p->char_id, TABLE_INVENTORY))
+			strcat(save_status, " inventory");
+		else
+			errors++;
 	}
 
 	//map cart data
 	if( memcmp(p->cart, cp->cart, sizeof(p->cart)) )
 	{
-		memitemdata_to_sql(p->cart, MAX_CART, p->char_id, TABLE_CART);
-		strcat(save_status, " cart");
+		if (!memitemdata_to_sql(p->cart, MAX_CART, p->char_id, TABLE_CART))
+			strcat(save_status, " cart");
+		else
+			errors++;
 	}
 
 	//map storage data
 	if( memcmp(p->storage.items, cp->storage.items, sizeof(p->storage.items)) )
 	{
-		memitemdata_to_sql(p->storage.items, MAX_STORAGE, p->account_id, TABLE_STORAGE);
-		strcat(save_status, " storage");
+		if (!memitemdata_to_sql(p->storage.items, MAX_STORAGE, p->account_id, TABLE_STORAGE))
+			strcat(save_status, " storage");
+		else
+			errors++;
 	}
 
 #ifdef TXT_SQL_CONVERT
@@ -452,9 +459,9 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 		char_db, p->char_id, p->account_id, p->slot, esc_name) )
 	{
 		Sql_ShowDebug(sql_handle);
-	}
-
-	strcat(save_status, " creation");
+		errors++;
+	} else
+		strcat(save_status, " creation");
 }
 #endif
 
@@ -499,8 +506,9 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 			p->account_id, p->char_id) )
 		{
 			Sql_ShowDebug(sql_handle);
-		}
-		strcat(save_status, " status");
+			errors++;
+		} else
+			strcat(save_status, " status");
 	}
 
 	//Values that will seldom change (to speed up saving)
@@ -525,9 +533,9 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 			p->account_id, p->char_id) )
 		{
 			Sql_ShowDebug(sql_handle);
-		}
-
-		strcat(save_status, " status2");
+			errors++;
+		} else
+			strcat(save_status, " status2");
 	}
 
 	/* Mercenary Owner */
@@ -536,8 +544,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 		(p->spear_calls != cp->spear_calls) || (p->spear_faith != cp->spear_faith) ||
 		(p->sword_calls != cp->sword_calls) || (p->sword_faith != cp->sword_faith) )
 	{
-		mercenary_owner_tosql(char_id, p);
-		strcat(save_status, " mercenary");
+		if (mercenary_owner_tosql(char_id, p))
+			strcat(save_status, " mercenary");
+		else
+			errors++;
 	}
 
 	//memo points
@@ -547,7 +557,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 
 		//`memo` (`memo_id`,`char_id`,`map`,`x`,`y`)
 		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", memo_db, p->char_id) )
+		{
 			Sql_ShowDebug(sql_handle);
+			errors++;
+		}
 
 		//insert here.
 		StringBuf_Clear(&buf);
@@ -566,9 +579,11 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 		if( count )
 		{
 			if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+			{
 				Sql_ShowDebug(sql_handle);
+				errors++;
+			}
 		}
-		
 		strcat(save_status, " memo");
 	}
 
@@ -583,7 +598,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 	{
 		//`skill` (`char_id`, `id`, `lv`)
 		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", skill_db, p->char_id) )
+		{
 			Sql_ShowDebug(sql_handle);
+			errors++;
+		}
 
 		StringBuf_Clear(&buf);
 		StringBuf_Printf(&buf, "INSERT INTO `%s`(`char_id`,`id`,`lv`) VALUES ", skill_db);
@@ -601,7 +619,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 		if( count )
 		{
 			if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+			{
 				Sql_ShowDebug(sql_handle);
+				errors++;
+			}
 		}
 
 		strcat(save_status, " skills");
@@ -619,7 +640,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 	if(diff == 1)
 	{	//Save friends
 		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", friend_db, char_id) )
+		{
 			Sql_ShowDebug(sql_handle);
+			errors++;
+		}
 
 		StringBuf_Clear(&buf);
 		StringBuf_Printf(&buf, "INSERT INTO `%s` (`char_id`, `friend_account`, `friend_id`) VALUES ", friend_db);
@@ -636,12 +660,12 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 		if( count )
 		{
 			if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+			{
 				Sql_ShowDebug(sql_handle);
-			else
-				strcat(save_status, " friends");
+				errors++;
+			}
 		}
-		else //Friend list cleared.
-			strcat(save_status, " friends");
+		strcat(save_status, " friends");
 	}
 
 #ifdef HOTKEY_SAVING
@@ -660,8 +684,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 	}
 	if(diff) {
 		if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+		{
 			Sql_ShowDebug(sql_handle);
-		else
+			errors++;
+		} else
 			strcat(save_status, " hotkeys");
 	}
 #endif
@@ -669,7 +695,8 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 	if (save_status[0]!='\0' && save_log)
 		ShowInfo("Saved char %d - %s:%s.\n", char_id, p->name, save_status);
 #ifndef TXT_SQL_CONVERT
-	memcpy(cp, p, sizeof(struct mmo_charstatus));
+	if (!errors)
+		memcpy(cp, p, sizeof(struct mmo_charstatus));
 #else
 	aFree(cp);
 #endif
@@ -688,6 +715,7 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
 	struct item item; // temp storage variable
 	bool* flag; // bit array for inventory matching
 	bool found;
+	int errors = 0;
 
 	switch (tableswitch) {
 	case TABLE_INVENTORY:     tablename = inventory_db;     selectoption = "char_id";    break;
@@ -770,7 +798,10 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
 					StringBuf_Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
 					
 					if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+					{
 						Sql_ShowDebug(sql_handle);
+						errors++;
+					}
 				}
 
 				found = flag[i] = true; //Item dealt with,
@@ -780,7 +811,10 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
 		if( !found )
 		{// Item not present in inventory, remove it.
 			if( SQL_ERROR == Sql_Query(sql_handle, "DELETE from `%s` where `id`='%d'", tablename, item.id) )
+			{
 				Sql_ShowDebug(sql_handle);
+				errors++;
+			}
 		}
 	}
 	SqlStmt_Free(stmt);
@@ -812,12 +846,15 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
 	}
 
 	if( found && SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+	{
 		Sql_ShowDebug(sql_handle);
+		errors++;
+	}
 
 	StringBuf_Destroy(&buf);
 	aFree(flag);
 
-	return 0;
+	return errors;
 }
 
 int mmo_char_tobuf(uint8* buf, struct mmo_charstatus* p);
@@ -1565,33 +1602,33 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
 
 	buf = WBUFP(buffer,0);
 	WBUFL(buf,0) = p->char_id;
-	WBUFL(buf,4) = min(p->base_exp, LONG_MAX);
+	WBUFL(buf,4) = min(p->base_exp, INT32_MAX);
 	WBUFL(buf,8) = p->zeny;
-	WBUFL(buf,12) = min(p->job_exp, LONG_MAX);
+	WBUFL(buf,12) = min(p->job_exp, INT32_MAX);
 	WBUFL(buf,16) = p->job_level;
 	WBUFL(buf,20) = 0; // probably opt1
 	WBUFL(buf,24) = 0; // probably opt2
 	WBUFL(buf,28) = p->option;
 	WBUFL(buf,32) = p->karma;
 	WBUFL(buf,36) = p->manner;
-	WBUFW(buf,40) = min(p->status_point, SHRT_MAX);
+	WBUFW(buf,40) = min(p->status_point, INT16_MAX);
 #if PACKETVER > 20081217
 	WBUFL(buf,42) = p->hp;
 	WBUFL(buf,46) = p->max_hp;
 	offset+=4;
 	buf = WBUFP(buffer,offset);
 #else
-	WBUFW(buf,42) = min(p->hp, SHRT_MAX);
-	WBUFW(buf,44) = min(p->max_hp, SHRT_MAX);
+	WBUFW(buf,42) = min(p->hp, INT16_MAX);
+	WBUFW(buf,44) = min(p->max_hp, INT16_MAX);
 #endif
-	WBUFW(buf,46) = min(p->sp, SHRT_MAX);
-	WBUFW(buf,48) = min(p->max_sp, SHRT_MAX);
+	WBUFW(buf,46) = min(p->sp, INT16_MAX);
+	WBUFW(buf,48) = min(p->max_sp, INT16_MAX);
 	WBUFW(buf,50) = DEFAULT_WALK_SPEED; // p->speed;
 	WBUFW(buf,52) = p->class_;
 	WBUFW(buf,54) = p->hair;
 	WBUFW(buf,56) = p->option&0x20 ? 0 : p->weapon; //When the weapon is sent and your option is riding, the client crashes on login!?
 	WBUFW(buf,58) = p->base_level;
-	WBUFW(buf,60) = min(p->skill_point, SHRT_MAX);
+	WBUFW(buf,60) = min(p->skill_point, INT16_MAX);
 	WBUFW(buf,62) = p->head_bottom;
 	WBUFW(buf,64) = p->shield;
 	WBUFW(buf,66) = p->head_top;
@@ -1599,12 +1636,12 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
 	WBUFW(buf,70) = p->hair_color;
 	WBUFW(buf,72) = p->clothes_color;
 	memcpy(WBUFP(buf,74), p->name, NAME_LENGTH);
-	WBUFB(buf,98) = min(p->str, UCHAR_MAX);
-	WBUFB(buf,99) = min(p->agi, UCHAR_MAX);
-	WBUFB(buf,100) = min(p->vit, UCHAR_MAX);
-	WBUFB(buf,101) = min(p->int_, UCHAR_MAX);
-	WBUFB(buf,102) = min(p->dex, UCHAR_MAX);
-	WBUFB(buf,103) = min(p->luk, UCHAR_MAX);
+	WBUFB(buf,98) = min(p->str, UINT8_MAX);
+	WBUFB(buf,99) = min(p->agi, UINT8_MAX);
+	WBUFB(buf,100) = min(p->vit, UINT8_MAX);
+	WBUFB(buf,101) = min(p->int_, UINT8_MAX);
+	WBUFB(buf,102) = min(p->dex, UINT8_MAX);
+	WBUFB(buf,103) = min(p->luk, UINT8_MAX);
 	WBUFW(buf,104) = p->slot;
 #if PACKETVER >= 20061023
 	WBUFW(buf,106) = ( p->rename > 0 ) ? 0 : 1;
@@ -1927,7 +1964,7 @@ int parse_fromlogin(int fd)
 				memcpy(sd->email, RFIFOP(fd,6), 40);
 				sd->expiration_time = (time_t)RFIFOL(fd,46);
 				sd->gmlevel = RFIFOB(fd,50);
-				safestrncpy(sd->birthdate, RFIFOP(fd,51), sizeof(sd->birthdate));
+				safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,51), sizeof(sd->birthdate));
 
 				// continued from char_auth_ok...
 				if( max_connect_user && count_users() >= max_connect_user && sd->gmlevel < gm_allow_level )
@@ -1942,6 +1979,16 @@ int parse_fromlogin(int fd)
 				{
 					// send characters to player
 					mmo_char_send006b(i, sd);
+#if PACKETVER >=  20110309
+					// PIN code system, disabled
+					WFIFOHEAD(i, 12);
+					WFIFOW(i, 0) = 0x08B9;
+					WFIFOW(i, 2) = 0;
+					WFIFOW(i, 4) = 0;
+					WFIFOL(i, 6) = sd->account_id;
+					WFIFOW(i, 10) = 0;
+					WFIFOSET(i, 12);
+#endif
 				}
 			}
 			RFIFOSKIP(fd,62);

+ 3 - 2
src/char_sql/int_quest.c

@@ -91,7 +91,7 @@ bool mapif_quest_update(int char_id, struct quest qd)
 //Save quests
 int mapif_parse_quest_save(int fd)
 {
-	int i, j, num2, num1 = (RFIFOW(fd,2)-8)/sizeof(struct quest);
+	int i, j, k, num2, num1 = (RFIFOW(fd,2)-8)/sizeof(struct quest);
 	int char_id = RFIFOL(fd,4);
 	struct quest qd1[MAX_QUEST_DB],qd2[MAX_QUEST_DB];
 	bool success = true;
@@ -106,7 +106,8 @@ int mapif_parse_quest_save(int fd)
 		ARR_FIND( 0, num2, j, qd1[i].quest_id == qd2[j].quest_id );
 		if( j < num2 ) // Update existed quests
 		{	// Only states and counts are changable.
-			if( qd1[i].state != qd2[j].state || qd1[i].count[0] != qd2[j].count[0] || qd1[i].count[1] != qd2[j].count[1] || qd1[i].count[2] != qd2[j].count[2] )
+			ARR_FIND( 0, MAX_QUEST_OBJECTIVES, k, qd1[i].count[k] != qd2[j].count[k] );
+			if( k != MAX_QUEST_OBJECTIVES || qd1[i].state != qd2[j].state )
 				success &= mapif_quest_update(char_id, qd1[i]);
 
 			if( j < (--num2) )

+ 11 - 11
src/common/CMakeLists.txt

@@ -12,11 +12,11 @@ endif()
 set( GLOBAL_INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "" )
 set( SVNVERSION ${SVNVERSION}
 	CACHE STRING "SVN version of the source code" )
-if( WITH_COMPONENT_DEVELOPMENT )
+if( INSTALL_COMPONENT_DEVELOPMENT )
 	install( FILES ${CMAKE_CURRENT_BINARY_DIR}/svnversion.h
 		DESTINATION "src/common"
 		COMPONENT Development_base )
-endif()
+endif( INSTALL_COMPONENT_DEVELOPMENT )
 message( STATUS "Creating svnversion.h - done" )
 
 
@@ -48,7 +48,7 @@ set( COMMON_MINI_SOURCES
 	"${COMMON_SOURCE_DIR}/showmsg.c"
 	"${COMMON_SOURCE_DIR}/strlib.c"
 	CACHE INTERNAL "" )
-set( COMMON_MINI_DEFINITIONS MINICORE CACHE INTERNAL "" )
+set( COMMON_MINI_DEFINITIONS "-DMINICORE" CACHE INTERNAL "" )
 
 
 #
@@ -95,17 +95,17 @@ set( COMMON_BASE_SOURCES
 	CACHE INTERNAL "common_base sources" )
 set( LIBRARIES ${ZLIB_LIBRARIES} )
 set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ${MT19937AR_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS}" )
 set( SOURCE_FILES ${MT19937AR_HEADERS} ${MT19937AR_SOURCES} ${COMMON_BASE_HEADERS} ${COMMON_BASE_SOURCES} )
 source_group( mt19937ar FILES ${MT19937AR_HEADERS} ${MT19937AR_SOURCES} )
 source_group( common FILES ${COMMON_BASE_HEADERS} ${COMMON_BASE_SOURCES} )
 add_library( common_base ${SOURCE_FILES} )
 target_link_libraries( common_base ${LIBRARIES} )
-set_target_properties( common_base PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
+set_target_properties( common_base PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
 include_directories( ${INCLUDE_DIRS} )
+set( HAVE_common_base ON  CACHE INTERNAL "" )
+set( TARGET_LIST ${TARGET_LIST} common_base  CACHE INTERNAL "" )
 message( STATUS "Creating target common_base - done" )
-set( HAVE_common_base ON  CACHE BOOL "common_base target is available" )
-mark_as_advanced( HAVE_common_base )
 else()
 message( STATUS "Skipping target common_base (requires ZLIB)" )
 unset( HAVE_common_base CACHE )
@@ -127,17 +127,17 @@ set( COMMON_SQL_SOURCES
 set( DEPENDENCIES common_base )
 set( LIBRARIES ${MYSQL_LIBRARIES} )
 set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ${MYSQL_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS}" )
 set( SOURCE_FILES ${COMMON_SQL_HEADERS} ${COMMON_SQL_SOURCES} )
 source_group( common FILES ${COMMON_SQL_HEADERS} ${COMMON_SQL_SOURCES} )
 add_library( common_sql ${SOURCE_FILES} )
 add_dependencies( common_sql ${DEPENDENCIES} )
 target_link_libraries( common_sql ${LIBRARIES} ${DEPENDENCIES} )
-set_target_properties( common_sql PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
+set_target_properties( common_sql PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
 include_directories( ${INCLUDE_DIRS} )
+set( HAVE_common_sql ON  CACHE INTERNAL "" )
+set( TARGET_LIST ${TARGET_LIST} common_sql  CACHE INTERNAL "" )
 message( STATUS "Creating target common_sql - done" )
-set( HAVE_common_sql ON  CACHE BOOL "common_sql target is available" )
-mark_as_advanced( HAVE_common_sql )
 else()
 message( STATUS "Skipping target common_sql (requires common_base and MYSQL)" )
 unset( HAVE_common_sql CACHE )

+ 39 - 0
src/common/cbasetypes.h

@@ -77,10 +77,26 @@
 // portable printf/scanf format macros and integer definitions
 // NOTE: Visual C++ uses <inttypes.h> and <stdint.h> provided in /3rdparty
 //////////////////////////////////////////////////////////////////////////
+#ifdef __cplusplus
+#define __STDC_CONSTANT_MACROS
+#define __STDC_FORMAT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+
 #include <inttypes.h>
 #include <stdint.h>
 #include <limits.h>
 
+// temporary fix for bugreport:4961 (unintended conversion from signed to unsigned)
+// (-20 >= UCHAR_MAX) returns true
+// (-20 >= USHRT_MAX) returns true
+#if defined(__FreeBSD__) && defined(__x86_64)
+#undef UCHAR_MAX
+#define UCHAR_MAX (unsigned char)0xff
+#undef USHRT_MAX
+#define USHRT_MAX (unsigned short)0xffff
+#endif
+
 // ILP64 isn't supported, so always 32 bits?
 #ifndef UINT_MAX
 #define UINT_MAX 0xffffffff
@@ -316,4 +332,27 @@ typedef char bool;
 #endif
 #endif
 
+
+//////////////////////////////////////////////////////////////////////////
+// Set a pointer variable to a pointer value.
+#ifdef __cplusplus
+template <typename T1, typename T2>
+void SET_POINTER(T1*&var, T2* p)
+{
+	var = static_cast<T1*>(p);
+}
+template <typename T1, typename T2>
+void SET_FUNCPOINTER(T1& var, T2 p)
+{
+	char ASSERT_POINTERSIZE[sizeof(T1) == sizeof(void*) && sizeof(T2) == sizeof(void*)?1:-1];// 1 if true, -1 if false
+	union{ T1 out; T2 in; } tmp;// /!\ WARNING casting a pointer to a function pointer is against the C++ standard
+	tmp.in = p;
+	var = tmp.out;
+}
+#else
+#define SET_POINTER(var,p) (var) = (p)
+#define SET_FUNCPOINTER(var,p) (var) = (p)
+#endif
+
+
 #endif /* _CBASETYPES_H_ */

+ 0 - 4
src/common/core.c

@@ -276,7 +276,3 @@ int main (int argc, char **argv)
 
 	return 0;
 }
-
-#ifdef BCHECK
-unsigned int __invalid_size_argument_for_IOC;
-#endif

+ 3 - 3
src/common/db.h

@@ -994,8 +994,8 @@ void  linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ...  );
 	do{ \
 		if( (__n) > VECTOR_CAPACITY(__vec) ) \
 		{ /* increase size */ \
-			if( VECTOR_CAPACITY(__vec) == 0 ) VECTOR_DATA(__vec) = aMalloc((__n)*sizeof(VECTOR_FIRST(__vec))); /* allocate new */ \
-			else VECTOR_DATA(__vec) = aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec))); /* reallocate */ \
+			if( VECTOR_CAPACITY(__vec) == 0 ) SET_POINTER(VECTOR_DATA(__vec), aMalloc((__n)*sizeof(VECTOR_FIRST(__vec)))); /* allocate new */ \
+			else SET_POINTER(VECTOR_DATA(__vec), aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec)))); /* reallocate */ \
 			memset(VECTOR_DATA(__vec)+VECTOR_LENGTH(__vec), 0, (VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec))*sizeof(VECTOR_FIRST(__vec))); /* clear new data */ \
 			VECTOR_CAPACITY(__vec) = (__n); /* update capacity */ \
 		} \
@@ -1007,7 +1007,7 @@ void  linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ...  );
 		} \
 		else if( (__n) < VECTOR_CAPACITY(__vec) ) \
 		{ /* reduce size */ \
-			VECTOR_DATA(__vec) = aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec))); /* reallocate */ \
+			SET_POINTER(VECTOR_DATA(__vec), aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec)))); /* reallocate */ \
 			VECTOR_CAPACITY(__vec) = (__n); /* update capacity */ \
 			if( VECTOR_LENGTH(__vec) > (__n) ) VECTOR_LENGTH(__vec) = (__n); /* update length */ \
 		} \

+ 4 - 4
src/common/grfio.c

@@ -223,17 +223,17 @@ unsigned long grfio_crc32 (const unsigned char* buf, unsigned int len)
 
 ///////////////////////////////////////////////////////////////////////////////
 ///	Grf data sub : zip decode
-int decode_zip(unsigned char* dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen)
+int decode_zip(void* dest, unsigned long* destLen, const void* source, unsigned long sourceLen)
 {
-	return uncompress(dest, destLen, source, sourceLen);
+	return uncompress((Bytef*)dest, destLen, (const Bytef*)source, sourceLen);
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
 ///	Grf data sub : zip encode 
-int encode_zip(unsigned char* dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen)
+int encode_zip(void* dest, unsigned long* destLen, const void* source, unsigned long sourceLen)
 {
-	return compress(dest, destLen, source, sourceLen);
+	return compress((Bytef*)dest, destLen, (const Bytef*)source, sourceLen);
 }
 
 

+ 2 - 2
src/common/grfio.h

@@ -14,7 +14,7 @@ char *grfio_find_file(char *fname);
 int grfio_size(char*);			// GRFIO data file size get
 unsigned long grfio_crc32(const unsigned char *buf, unsigned int len);
 
-int decode_zip(unsigned char* dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen);
-int encode_zip(unsigned char* dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen);
+int decode_zip(void* dest, unsigned long* destLen, const void* source, unsigned long sourceLen);
+int encode_zip(void* dest, unsigned long* destLen, const void* source, unsigned long sourceLen);
 
 #endif /* _GRFIO_H_ */

+ 82 - 51
src/common/malloc.c

@@ -10,9 +10,63 @@
 #include <string.h>
 #include <time.h>
 
-// no logging for minicore
-#if defined(MINICORE) && defined(LOG_MEMMGR)
-#undef LOG_MEMMGR
+////////////// Memory Libraries //////////////////
+
+#if defined(MEMWATCH)
+
+#	include <string.h> 
+#	include "memwatch.h"
+#	define MALLOC(n,file,line,func)	mwMalloc((n),(file),(line))
+#	define CALLOC(m,n,file,line,func)	mwCalloc((m),(n),(file),(line))
+#	define REALLOC(p,n,file,line,func)	mwRealloc((p),(n),(file),(line))
+#	define STRDUP(p,file,line,func)	mwStrdup((p),(file),(line))
+#	define FREE(p,file,line,func)		mwFree((p),(file),(line))
+#	define MEMORY_USAGE()	0
+#	define MEMORY_VERIFY(ptr)	mwIsSafeAddr(ptr, 1)
+#	define MEMORY_CHECK() CHECK()
+
+#elif defined(DMALLOC)
+
+#	include <string.h>
+#	include <stdlib.h>
+#	include "dmalloc.h"
+#	define MALLOC(n,file,line,func)	dmalloc_malloc((file),(line),(n),DMALLOC_FUNC_MALLOC,0,0)
+#	define CALLOC(m,n,file,line,func)	dmalloc_malloc((file),(line),(m)*(n),DMALLOC_FUNC_CALLOC,0,0)
+#	define REALLOC(p,n,file,line,func)	dmalloc_realloc((file),(line),(p),(n),DMALLOC_FUNC_REALLOC,0)
+#	define STRDUP(p,file,line,func)	strdup(p)
+#	define FREE(p,file,line,func)		free(p)
+#	define MEMORY_USAGE()	dmalloc_memory_allocated()
+#	define MEMORY_VERIFY(ptr)	(dmalloc_verify(ptr) == DMALLOC_VERIFY_NOERROR)
+#	define MEMORY_CHECK()	dmalloc_log_stats(); dmalloc_log_unfreed()
+
+#elif defined(GCOLLECT)
+
+#	include "gc.h"
+#	ifdef GC_ADD_CALLER
+#		define RETURN_ADDR 0,
+#	else
+#		define RETURN_ADDR
+#	endif
+#	define MALLOC(n,file,line,func)	GC_debug_malloc((n), RETURN_ADDR (file),(line))
+#	define CALLOC(m,n,file,line,func)	GC_debug_malloc((m)*(n), RETURN_ADDR (file),(line))
+#	define REALLOC(p,n,file,line,func)	GC_debug_realloc((p),(n), RETURN_ADDR (file),(line))
+#	define STRDUP(p,file,line,func)	GC_debug_strdup((p), RETURN_ADDR (file),(line))
+#	define FREE(p,file,line,func)		GC_debug_free(p)
+#	define MEMORY_USAGE()	GC_get_heap_size()
+#	define MEMORY_VERIFY(ptr)	(GC_base(ptr) != NULL)
+#	define MEMORY_CHECK()	GC_gcollect()
+
+#else
+
+#	define MALLOC(n,file,line,func)	malloc(n)
+#	define CALLOC(m,n,file,line,func)	calloc((m),(n))
+#	define REALLOC(p,n,file,line,func)	realloc((p),(n))
+#	define STRDUP(p,file,line,func)	strdup(p)
+#	define FREE(p,file,line,func)		free(p)
+#	define MEMORY_USAGE()	0
+#	define MEMORY_VERIFY(ptr)	true
+#	define MEMORY_CHECK()
+
 #endif
 
 void* aMalloc_(size_t size, const char *file, int line, const char *func)
@@ -26,17 +80,6 @@ void* aMalloc_(size_t size, const char *file, int line, const char *func)
 
 	return ret;
 }
-void* aMallocA_(size_t size, const char *file, int line, const char *func)
-{
-	void *ret = MALLOCA(size, file, line, func);
-	// ShowMessage("%s:%d: in func %s: aMallocA %d\n",file,line,func,size);
-	if (ret == NULL){
-		ShowFatalError("%s:%d: in func %s: aMallocA error out of memory!\n",file,line,func);
-		exit(EXIT_FAILURE);
-	}
-
-	return ret;
-}
 void* aCalloc_(size_t num, size_t size, const char *file, int line, const char *func)
 {
 	void *ret = CALLOC(num, size, file, line, func);
@@ -47,16 +90,6 @@ void* aCalloc_(size_t num, size_t size, const char *file, int line, const char *
 	}
 	return ret;
 }
-void* aCallocA_(size_t num, size_t size, const char *file, int line, const char *func)
-{
-	void *ret = CALLOCA(num, size, file, line, func);
-	// ShowMessage("%s:%d: in func %s: aCallocA %d %d\n",file,line,func,num,size);
-	if (ret == NULL){
-		ShowFatalError("%s:%d: in func %s: aCallocA error out of memory!\n",file,line,func);
-		exit(EXIT_FAILURE);
-	}
-	return ret;
-}
 void* aRealloc_(void *p, size_t size, const char *file, int line, const char *func)
 {
 	void *ret = REALLOC(p, size, file, line, func);
@@ -86,29 +119,6 @@ void aFree_(void *p, const char *file, int line, const char *func)
 	p = NULL;
 }
 
-#ifdef GCOLLECT
-
-void* _bcallocA(size_t size, size_t cnt)
-{
-	void *ret = MALLOCA(size * cnt);
-	if (ret) memset(ret, 0, size * cnt);
-	return ret;
-}
-void* _bcalloc(size_t size, size_t cnt)
-{
-	void *ret = MALLOC(size * cnt);
-	if (ret) memset(ret, 0, size * cnt);
-	return ret;
-}
-char* _bstrdup(const char *chr)
-{
-	int len = strlen(chr);
-	char *ret = (char*)MALLOC(len + 1);
-	if (ret) memcpy(ret, chr, len + 1);
-	return ret;
-}
-
-#endif
 
 #ifdef USE_MEMMGR
 
@@ -654,21 +664,32 @@ static void memmgr_init (void)
  *--------------------------------------
  */
 
-bool malloc_verify(void* ptr)
+
+/// Tests the memory for errors and memory leaks.
+void malloc_memory_check(void)
+{
+	MEMORY_CHECK();
+}
+
+
+/// Returns true if a pointer is valid.
+/// The check is best-effort, false positives are possible.
+bool malloc_verify_ptr(void* ptr)
 {
 #ifdef USE_MEMMGR
-	return memmgr_verify(ptr);
+	return memmgr_verify(ptr) && MEMORY_VERIFY(ptr);
 #else
-	return true;
+	return MEMORY_VERIFY(ptr);
 #endif
 }
 
+
 size_t malloc_usage (void)
 {
 #ifdef USE_MEMMGR
 	return memmgr_usage ();
 #else
-	return 0;
+	return MEMORY_USAGE();
 #endif
 }
 
@@ -677,10 +698,20 @@ void malloc_final (void)
 #ifdef USE_MEMMGR
 	memmgr_final ();
 #endif
+	MEMORY_CHECK();
 }
 
 void malloc_init (void)
 {
+#if defined(DMALLOC) && defined(CYGWIN)
+	// http://dmalloc.com/docs/latest/online/dmalloc_19.html
+	dmalloc_debug_setup(getenv("DMALLOC_OPTIONS"));
+#endif
+#ifdef GCOLLECT
+	// don't garbage collect, only report inaccessible memory that was not deallocated
+	GC_find_leak = 1;
+	GC_INIT();
+#endif
 #ifdef USE_MEMMGR
 	memmgr_init ();
 #endif

+ 18 - 84
src/common/malloc.h

@@ -6,26 +6,19 @@
 
 #include "../common/cbasetypes.h"
 
-// Q: What are the 'a'-variant allocation functions?
-// A: They allocate memory from the stack, which is automatically 
-//    freed when the invoking function returns.
-//    But it's not portable (http://c-faq.com/malloc/alloca.html)
-//    and I have doubts our implementation works.
-//    -> They should NOT be used, period.
-
 #define ALC_MARK __FILE__, __LINE__, __func__
 
-// disable built-in memory manager when using another manager
-#if defined(MEMWATCH) || defined(DMALLOC) || defined(GCOLLECT) || defined(BCHECK)
-#if !defined(NO_MEMMGR)
-#define NO_MEMMGR
-#endif
-#endif
 
-// Use built-in memory manager by default
+// default use of the built-in memory manager
 #if !defined(NO_MEMMGR) && !defined(USE_MEMMGR)
+#if defined(MEMWATCH) || defined(DMALLOC) || defined(GCOLLECT)
+// disable built-in memory manager when using another memory library
+#define NO_MEMMGR
+#else
+// use built-in memory manager by default
 #define USE_MEMMGR
 #endif
+#endif
 
 
 //////////////////////////////////////////////////////////////////////
@@ -35,10 +28,13 @@
 // Enable memory manager logging by default
 #define LOG_MEMMGR
 
+// no logging for minicore
+#if defined(MINICORE) && defined(LOG_MEMMGR)
+#undef LOG_MEMMGR
+#endif
+
 #	define aMalloc(n)		_mmalloc(n,ALC_MARK)
-#	define aMallocA(n)		_mmalloc(n,ALC_MARK)
 #	define aCalloc(m,n)		_mcalloc(m,n,ALC_MARK)
-#	define aCallocA(m,n)	_mcalloc(m,n,ALC_MARK)
 #	define aRealloc(p,n)	_mrealloc(p,n,ALC_MARK)
 #	define aStrdup(p)		_mstrdup(p,ALC_MARK)
 #	define aFree(p)			_mfree(p,ALC_MARK)
@@ -52,83 +48,23 @@
 #else
 
 #	define aMalloc(n)		aMalloc_((n),ALC_MARK)
-#	define aMallocA(n)		aMallocA_((n),ALC_MARK)
 #	define aCalloc(m,n)		aCalloc_((m),(n),ALC_MARK)
-#	define aCallocA(m,n)	aCallocA_(m,n,ALC_MARK)
 #	define aRealloc(p,n)	aRealloc_(p,n,ALC_MARK)
 #	define aStrdup(p)		aStrdup_(p,ALC_MARK)
 #	define aFree(p)			aFree_(p,ALC_MARK)
 
 	void* aMalloc_	(size_t size, const char *file, int line, const char *func);
-	void* aMallocA_	(size_t size, const char *file, int line, const char *func);
 	void* aCalloc_	(size_t num, size_t size, const char *file, int line, const char *func);
-	void* aCallocA_	(size_t num, size_t size, const char *file, int line, const char *func);
 	void* aRealloc_	(void *p, size_t size, const char *file, int line, const char *func);
 	char* aStrdup_	(const char *p, const char *file, int line, const char *func);
 	void  aFree_	(void *p, const char *file, int line, const char *func);
 
 #endif
 
-////////////// Memory Managers //////////////////
-
-#if defined(MEMWATCH)
-
-#	include "memwatch.h"
-#	define MALLOC(n,file,line,func)	mwMalloc((n),(file),(line))
-#	define MALLOCA(n,file,line,func)	mwMalloc((n),(file),(line))
-#	define CALLOC(m,n,file,line,func)	mwCalloc((m),(n),(file),(line))
-#	define CALLOCA(m,n,file,line,func)	mwCalloc((m),(n),(file),(line))
-#	define REALLOC(p,n,file,line,func)	mwRealloc((p),(n),(file),(line))
-#	define STRDUP(p,file,line,func)	mwStrdup((p),(file),(line))
-#	define FREE(p,file,line,func)		mwFree((p),(file),(line))
-
-#elif defined(DMALLOC)
-
-#	include "dmalloc.h"
-#	define MALLOC(n,file,line,func)	dmalloc_malloc((file),(line),(n),DMALLOC_FUNC_MALLOC,0,0)
-#	define MALLOCA(n,file,line,func)	dmalloc_malloc((file),(line),(n),DMALLOC_FUNC_MALLOC,0,0)
-#	define CALLOC(m,n,file,line,func)	dmalloc_malloc((file),(line),(m)*(n),DMALLOC_FUNC_CALLOC,0,0)
-#	define CALLOCA(m,n,file,line,func)	dmalloc_malloc((file),(line),(m)*(n),DMALLOC_FUNC_CALLOC,0,0)
-#	define REALLOC(p,n,file,line,func)	dmalloc_realloc((file),(line),(p),(n),DMALLOC_FUNC_REALLOC,0)
-#	define STRDUP(p,file,line,func)	strdup(p)
-#	define FREE(p,file,line,func)		free(p)
-
-#elif defined(GCOLLECT)
-
-#	include "gc.h"
-#	define MALLOC(n,file,line,func)	GC_MALLOC(n)
-#	define MALLOCA(n,file,line,func)	GC_MALLOC_ATOMIC(n)
-#	define CALLOC(m,n,file,line,func)	_bcalloc((m),(n))
-#	define CALLOCA(m,n,file,line,func)	_bcallocA((m),(n))
-#	define REALLOC(p,n,file,line,func)	GC_REALLOC((p),(n))
-#	define STRDUP(p,file,line,func)	_bstrdup(p)
-#	define FREE(p,file,line,func)		GC_FREE(p)
-
-	void * _bcalloc(size_t, size_t);
-	void * _bcallocA(size_t, size_t);
-	char * _bstrdup(const char *);
-
-#elif defined(BCHECK)
-
-#	define MALLOC(n,file,line,func)	malloc(n)
-#	define MALLOCA(n,file,line,func)	malloc(n)
-#	define CALLOC(m,n,file,line,func)	calloc((m),(n))
-#	define CALLOCA(m,n,file,line,func)	calloc((m),(n))
-#	define REALLOC(p,n,file,line,func)	realloc((p),(n))
-#	define STRDUP(p,file,line,func)	strdup(p)
-#	define FREE(p,file,line,func)		free(p)
-
-#else
-
-#	define MALLOC(n,file,line,func)	malloc(n)
-#	define MALLOCA(n,file,line,func)	malloc(n)
-#	define CALLOC(m,n,file,line,func)	calloc((m),(n))
-#	define CALLOCA(m,n,file,line,func)	calloc((m),(n))
-#	define REALLOC(p,n,file,line,func)	realloc((p),(n))
-#	define STRDUP(p,file,line,func)	strdup(p)
-#	define FREE(p,file,line,func)		free(p)
-
-#endif
+// deprecated, do not use
+#define aMallocA aMalloc
+#define aCallocA aCalloc
+#define CREATE_A CREATE
 
 /////////////// Buffer Creation /////////////////
 // Full credit for this goes to Shinomori [Ajarn]
@@ -148,14 +84,12 @@
 ////////////// Others //////////////////////////
 // should be merged with any of above later
 #define CREATE(result, type, number) (result) = (type *) aCalloc ((number), sizeof(type))
-
-#define CREATE_A(result, type, number) (result) = (type *) aCallocA ((number), sizeof(type))
-
 #define RECREATE(result, type, number) (result) = (type *) aRealloc ((result), sizeof(type) * (number))
 
 ////////////////////////////////////////////////
 
-bool malloc_verify(void* ptr);
+void malloc_memory_check(void);
+bool malloc_verify_ptr(void* ptr);
 size_t malloc_usage (void);
 void malloc_init (void);
 void malloc_final (void);

+ 1 - 1
src/common/plugin.h

@@ -50,7 +50,7 @@ typedef void Plugin_Event_Func(void);
 #define PLUGIN_MAP			8
 #define PLUGIN_CORE			16
 
-#define IMPORT_SYMBOL(s,n)	(s) = plugin_call_table[n]
+#define IMPORT_SYMBOL(s,n)	SET_FUNCPOINTER((s), plugin_call_table[n])
 
 #define SYMBOL_SERVER_TYPE				0
 #define SYMBOL_SERVER_NAME				1

+ 40 - 13
src/common/socket.c

@@ -32,6 +32,9 @@
 	#ifndef SIOCGIFCONF
 	#include <sys/sockio.h> // SIOCGIFCONF on Solaris, maybe others? [Shinomori]
 	#endif
+	#ifndef FIONBIO
+	#include <sys/filio.h> // FIONBIO on Solaris [FlavioJS]
+	#endif
 
 	#ifdef HAVE_SETRLIMIT
 	#include <sys/resource.h>
@@ -1245,16 +1248,23 @@ void socket_init(void)
 			rlp.rlim_cur = FD_SETSIZE;
 			if( 0 != setrlimit(RLIMIT_NOFILE, &rlp) )
 			{// failed, try setting the maximum too (permission to change system limits is required)
+				int err;
 				rlp.rlim_max = FD_SETSIZE;
-				if( 0 != setrlimit(RLIMIT_NOFILE, &rlp) )
+				err = setrlimit(RLIMIT_NOFILE, &rlp);
+				if( err != 0 )
 				{// failed
+					const char* errmsg = "unknown";
+					int rlim_ori;
 					// set to maximum allowed
 					getrlimit(RLIMIT_NOFILE, &rlp);
+					rlim_ori = (int)rlp.rlim_cur;
 					rlp.rlim_cur = rlp.rlim_max;
 					setrlimit(RLIMIT_NOFILE, &rlp);
 					// report limit
 					getrlimit(RLIMIT_NOFILE, &rlp);
-					ShowWarning("socket_init: failed to set socket limit to %d (current limit %d).\n", FD_SETSIZE, (int)rlp.rlim_cur);
+					if( err == EPERM )
+						errmsg = "permission denied";
+					ShowWarning("socket_init: failed to set socket limit to %d, setting to maximum allowed (original limit=%d, current limit=%d, maximum allowed=%d, error=%s).\n", FD_SETSIZE, rlim_ori, (int)rlp.rlim_cur, (int)rlp.rlim_max, errmsg);
 				}
 			}
 		}
@@ -1343,6 +1353,12 @@ void send_shortlist_add_fd(int fd)
 	if( (send_shortlist_set[i]>>bit)&1 )
 		return;// already in the list
 
+	if( send_shortlist_count >= ARRAYLENGTH(send_shortlist_array) )
+	{
+		ShowDebug("send_shortlist_add_fd: shortlist is full, ignoring... (fd=%d shortlist.count=%d shortlist.length=%d)\n", fd, send_shortlist_count, ARRAYLENGTH(send_shortlist_array));
+		return;
+	}
+
 	// set the bit
 	send_shortlist_set[i] |= 1<<bit;
 	// Add to the end of the shortlist array.
@@ -1352,12 +1368,30 @@ void send_shortlist_add_fd(int fd)
 // Do pending network sends and eof handling from the shortlist.
 void send_shortlist_do_sends()
 {
-	int i = 0;
+	int i;
 
-	while( i < send_shortlist_count )
+	for( i = send_shortlist_count-1; i >= 0; --i )
 	{
 		int fd = send_shortlist_array[i];
+		int idx = fd/32;
+		int bit = fd%32;
 
+		// Remove fd from shortlist, move the last fd to the current position
+		--send_shortlist_count;
+		send_shortlist_array[i] = send_shortlist_array[send_shortlist_count];
+		send_shortlist_array[send_shortlist_count] = 0;
+
+		if( fd <= 0 || fd >= FD_SETSIZE )
+		{
+			ShowDebug("send_shortlist_do_sends: fd is out of range, corrupted memory? (fd=%d)\n", fd);
+			continue;
+		}
+		if( ((send_shortlist_set[idx]>>bit)&1) == 0 )
+		{
+			ShowDebug("send_shortlist_do_sends: fd is not set, why is it in the shortlist? (fd=%d)\n", fd);
+			continue;
+		}
+		send_shortlist_set[idx]&=~(1<<bit);// unset fd
 		// If this session still exists, perform send operations on it and
 		// check for the eof state.
 		if( session[fd] )
@@ -1372,17 +1406,10 @@ void send_shortlist_do_sends()
 				session[fd]->func_parse(fd);
 
 			// If the session still exists, is not eof and has things left to
-			// be sent from it we'll keep it in the shortlist.
+			// be sent from it we'll re-add it to the shortlist.
 			if( session[fd] && !session[fd]->flag.eof && session[fd]->wdata_size )
-			{
-				++i;
-				continue;
-			}
+				send_shortlist_add_fd(fd);
 		}
-
-		// Remove fd from shortlist, move the last fd to the current position
-		send_shortlist_array[i] = send_shortlist_array[--send_shortlist_count];
-		send_shortlist_set[fd/32]&=~(1<<(fd%32));
 	}
 }
 #endif

+ 2 - 2
src/common/strlib.c

@@ -245,7 +245,7 @@ char* _strtok_r(char *s1, const char *s2, char **lasts)
    If no '\0' terminator is found in that many characters, return MAXLEN.  */
 size_t strnlen (const char* string, size_t maxlen)
 {
-  const char* end = memchr (string, '\0', maxlen);
+  const char* end = (const char*)memchr(string, '\0', maxlen);
   return end ? (size_t) (end - string) : maxlen;
 }
 #endif
@@ -980,7 +980,7 @@ bool sv_readdb(const char* directory, const char* filename, char delim, int minc
 
 	// allocate enough memory for the maximum requested amount of columns plus the reserved one
 	fields_length = maxcols+1;
-	fields = aMalloc(fields_length*sizeof(char*));
+	fields = (char**)aMalloc(fields_length*sizeof(char*));
 
 	// process rows one by one
 	while( fgets(line, sizeof(line), fp) )

+ 3 - 1
src/login/CMakeLists.txt

@@ -2,7 +2,9 @@
 #
 # setup
 #
-set( LOGIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
+set( LOGIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}  CACHE INTERNAL "" )
+set( TXT_LOGIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}  CACHE INTERNAL "" )
+set( SQL_LOGIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}  CACHE INTERNAL "" )
 
 
 #

+ 4 - 4
src/login/account_txt.c

@@ -283,7 +283,7 @@ static bool account_db_txt_create(AccountDB* self, struct mmo_account* acc)
 		return false;
 
 	// check if the account_id is free
-	tmp = idb_get(accounts, account_id);
+	tmp = (struct mmo_account*)idb_get(accounts, account_id);
 	if( tmp != NULL )
 	{// error condition - entry already present
 		ShowError("account_db_txt_create: cannot create account %d:'%s', this id is already occupied by %d:'%s'!\n", account_id, acc->userid, account_id, tmp->userid);
@@ -316,7 +316,7 @@ static bool account_db_txt_remove(AccountDB* self, const int account_id)
 	DBMap* accounts = db->accounts;
 
 	//TODO: find out if this really works
-	struct mmo_account* tmp = idb_remove(accounts, account_id);
+	struct mmo_account* tmp = (struct mmo_account*)idb_remove(accounts, account_id);
 	if( tmp == NULL )
 	{// error condition - entry not present
 		ShowError("account_db_txt_remove: no such account with id %d\n", account_id);
@@ -337,7 +337,7 @@ static bool account_db_txt_save(AccountDB* self, const struct mmo_account* acc)
 	int account_id = acc->account_id;
 
 	// retrieve previous data
-	struct mmo_acount* tmp = idb_get(accounts, account_id);
+	struct mmo_account* tmp = (struct mmo_account*)idb_get(accounts, account_id);
 	if( tmp == NULL )
 	{// error condition - entry not found
 		return false;
@@ -360,7 +360,7 @@ static bool account_db_txt_load_num(AccountDB* self, struct mmo_account* acc, co
 	DBMap* accounts = db->accounts;
 
 	// retrieve data
-	struct mmo_account* tmp = idb_get(accounts, account_id);
+	struct mmo_account* tmp = (struct mmo_account*)idb_get(accounts, account_id);
 	if( tmp == NULL )
 	{// entry not found
 		return false;

+ 15 - 19
src/login/sql/CMakeLists.txt

@@ -2,24 +2,24 @@
 #
 # login sql
 #
-if( HAVE_common_sql )
+if( BUILD_SQL_SERVERS )
 message( STATUS "Creating target login-server_sql" )
 set( SQL_LOGIN_HEADERS
-	"${LOGIN_SOURCE_DIR}/account.h"
-	"${LOGIN_SOURCE_DIR}/ipban.h"
-	"${LOGIN_SOURCE_DIR}/login.h"
-	"${LOGIN_SOURCE_DIR}/loginlog.h"
+	"${SQL_LOGIN_SOURCE_DIR}/account.h"
+	"${SQL_LOGIN_SOURCE_DIR}/ipban.h"
+	"${SQL_LOGIN_SOURCE_DIR}/login.h"
+	"${SQL_LOGIN_SOURCE_DIR}/loginlog.h"
 	)
 set( SQL_LOGIN_SOURCES
-	"${LOGIN_SOURCE_DIR}/account_sql.c"
-	"${LOGIN_SOURCE_DIR}/ipban_sql.c"
-	"${LOGIN_SOURCE_DIR}/login.c"
-	"${LOGIN_SOURCE_DIR}/loginlog_sql.c"
+	"${SQL_LOGIN_SOURCE_DIR}/account_sql.c"
+	"${SQL_LOGIN_SOURCE_DIR}/ipban_sql.c"
+	"${SQL_LOGIN_SOURCE_DIR}/login.c"
+	"${SQL_LOGIN_SOURCE_DIR}/loginlog_sql.c"
 	)
 set( DEPENDENCIES common_sql )
 set( LIBRARIES ${GLOBAL_LIBRARIES} )
 set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} WITH_SQL )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS} -DWITH_SQL" )
 set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} ${SQL_LOGIN_HEADERS} ${SQL_LOGIN_SOURCES} )
 source_group( common FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} )
 source_group( login FILES ${SQL_LOGIN_HEADERS} ${SQL_LOGIN_SOURCES} )
@@ -27,17 +27,13 @@ include_directories( ${INCLUDE_DIRS} )
 add_executable( login-server_sql ${SOURCE_FILES} )
 add_dependencies( login-server_sql ${DEPENDENCIES} )
 target_link_libraries( login-server_sql ${LIBRARIES} ${DEPENDENCIES} )
-set_target_properties( login-server_sql PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
-if( WITH_COMPONENT_RUNTIME )
+set_target_properties( login-server_sql PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+if( INSTALL_COMPONENT_RUNTIME )
 	cpack_add_component( Runtime_loginserver_sql DESCRIPTION "login-server (sql version)" DISPLAY_NAME "login-server_sql" GROUP Runtime )
 	install( TARGETS login-server_sql
 		DESTINATION "."
 		COMPONENT Runtime_loginserver_sql )
-endif()
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} login-server_sql  CACHE INTERNAL "" )
 message( STATUS "Creating target login-server_sql - done" )
-set( HAVE_login-server_sql ON  CACHE BOOL "login-server_sql target is available" )
-mark_as_advanced( HAVE_login-server_sql )
-else()
-message( STATUS "Skipping target login-server_sql (requires common_sql)" )
-unset( HAVE_login-server_sql CACHE )
-endif()
+endif( BUILD_SQL_SERVERS )

+ 15 - 19
src/login/txt/CMakeLists.txt

@@ -2,24 +2,24 @@
 #
 # login txt
 #
-if( HAVE_common_base )
+if( BUILD_TXT_SERVERS )
 message( STATUS "Creating target login-server" )
 set( TXT_LOGIN_HEADERS
-	"${LOGIN_SOURCE_DIR}/account.h"
-	"${LOGIN_SOURCE_DIR}/ipban.h"
-	"${LOGIN_SOURCE_DIR}/login.h"
-	"${LOGIN_SOURCE_DIR}/loginlog.h"
+	"${TXT_LOGIN_SOURCE_DIR}/account.h"
+	"${TXT_LOGIN_SOURCE_DIR}/ipban.h"
+	"${TXT_LOGIN_SOURCE_DIR}/login.h"
+	"${TXT_LOGIN_SOURCE_DIR}/loginlog.h"
 	)
 set( TXT_LOGIN_SOURCES
-	"${LOGIN_SOURCE_DIR}/account_txt.c"
-	"${LOGIN_SOURCE_DIR}/ipban_txt.c"
-	"${LOGIN_SOURCE_DIR}/login.c"
-	"${LOGIN_SOURCE_DIR}/loginlog_txt.c"
+	"${TXT_LOGIN_SOURCE_DIR}/account_txt.c"
+	"${TXT_LOGIN_SOURCE_DIR}/ipban_txt.c"
+	"${TXT_LOGIN_SOURCE_DIR}/login.c"
+	"${TXT_LOGIN_SOURCE_DIR}/loginlog_txt.c"
 	)
 set( DEPENDENCIES common_base )
 set( LIBRARIES ${GLOBAL_LIBRARIES} )
 set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} WITH_TXT )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS} -DWITH_TXT" )
 set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${TXT_LOGIN_HEADERS} ${TXT_LOGIN_SOURCES} )
 source_group( common FILES ${COMMON_BASE_HEADERS} )
 source_group( login FILES ${TXT_LOGIN_HEADERS} ${TXT_LOGIN_SOURCES} )
@@ -27,17 +27,13 @@ include_directories( ${INCLUDE_DIRS} )
 add_executable( login-server ${SOURCE_FILES} )
 add_dependencies( login-server ${DEPENDENCIES} )
 target_link_libraries( login-server ${LIBRARIES} ${DEPENDENCIES} )
-set_target_properties( login-server PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
-if( WITH_COMPONENT_RUNTIME )
+set_target_properties( login-server PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+if( INSTALL_COMPONENT_RUNTIME )
 	cpack_add_component( Runtime_loginserver_txt DESCRIPTION "login-server (txt version)" DISPLAY_NAME "login-server" GROUP Runtime )
 	install( TARGETS login-server
 		DESTINATION "."
 		COMPONENT Runtime_loginserver_txt )
-endif()
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} login-server  CACHE INTERNAL "" )
 message( STATUS "Creating target login-server - done" )
-set( HAVE_login-server ON  CACHE BOOL "login-server target is available" )
-mark_as_advanced( HAVE_login-server )
-else()
-message( STATUS "Skipping target login-server (requires common_base)" )
-unset( HAVE_login-server CACHE )
-endif()
+endif( BUILD_TXT_SERVERS )

+ 3 - 1
src/map/CMakeLists.txt

@@ -2,7 +2,9 @@
 #
 # setup
 #
-set( MAP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
+set( MAP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}  CACHE INTERNAL "" )
+set( TXT_MAP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}  CACHE INTERNAL "" )
+set( SQL_MAP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}  CACHE INTERNAL "" )
 
 
 #

+ 11 - 7
src/map/atcommand.c

@@ -416,7 +416,7 @@ ACMD_FUNC(mapmove)
 {
 	char map_name[MAP_NAME_LENGTH_EXT];
 	unsigned short mapindex;
-	int x = 0, y = 0;
+	short x = 0, y = 0;
 	int m = -1;
 
 	nullpo_retr(-1, sd);
@@ -424,8 +424,8 @@ ACMD_FUNC(mapmove)
 	memset(map_name, '\0', sizeof(map_name));
 
 	if (!message || !*message ||
-		(sscanf(message, "%15s %d %d", map_name, &x, &y) < 3 &&
-		 sscanf(message, "%15[^,],%d,%d", map_name, &x, &y) < 1)) {
+		(sscanf(message, "%15s %hd %hd", map_name, &x, &y) < 3 &&
+		 sscanf(message, "%15[^,],%hd,%hd", map_name, &x, &y) < 1)) {
 		 
 			clif_displaymessage(fd, "Please, enter a map (usage: @warp/@rura/@mapmove <mapname> <x> <y>).");
 			return -1;
@@ -443,7 +443,8 @@ ACMD_FUNC(mapmove)
 	if ((x || y) && map_getcell(m, x, y, CELL_CHKNOPASS))
   	{	//This is to prevent the pc_setpos call from printing an error.
 		clif_displaymessage(fd, msg_txt(2));
-		x = y = 0; //Invalid cell, use random spot.
+		if (!map_search_freecell(NULL, m, &x, &y, 10, 10, 1))
+			x = y = 0; //Invalid cell, use random spot.
 	}
 	if (map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
 		clif_displaymessage(fd, msg_txt(247));
@@ -548,13 +549,13 @@ ACMD_FUNC(jumpto)
  *------------------------------------------*/
 ACMD_FUNC(jump)
 {
-	int x = 0, y = 0;
+	short x = 0, y = 0;
 
 	nullpo_retr(-1, sd);
 
 	memset(atcmd_output, '\0', sizeof(atcmd_output));
 
-	sscanf(message, "%d %d", &x, &y);
+	sscanf(message, "%hd %hd", &x, &y);
 
 	if (map[sd->bl.m].flag.noteleport && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
 		clif_displaymessage(fd, msg_txt(248));	// You are not authorized to warp from your current map.
@@ -570,7 +571,8 @@ ACMD_FUNC(jump)
 	if ((x || y) && map_getcell(sd->bl.m, x, y, CELL_CHKNOPASS))
   	{	//This is to prevent the pc_setpos call from printing an error.
 		clif_displaymessage(fd, msg_txt(2));
-		x = y = 0; //Invalid cell, use random spot.
+		if (!map_search_freecell(NULL, sd->bl.m, &x, &y, 10, 10, 1))
+			x = y = 0; //Invalid cell, use random spot.
 	}
 
 	pc_setpos(sd, sd->mapindex, x, y, CLR_TELEPORT);
@@ -4499,6 +4501,8 @@ ACMD_FUNC(mapinfo)
 		strcat(atcmd_output, "NoIcewall | ");
 	if (map[m_id].flag.allowks)
 		strcat(atcmd_output, "AllowKS | ");
+	if (map[m_id].flag.reset)
+		strcat(atcmd_output, "Reset | ");
 	clif_displaymessage(fd, atcmd_output);
 
 	strcpy(atcmd_output,"Other Flags: ");

+ 1 - 0
src/map/battle.c

@@ -4046,6 +4046,7 @@ static const struct _battle_data {
 	{ "display_party_name",                 &battle_config.display_party_name,              0,      0,      1,              },
 	{ "cashshop_show_points",               &battle_config.cashshop_show_points,            0,      0,      1,              },
 	{ "mail_show_status",                   &battle_config.mail_show_status,                0,      0,      2,              },
+	{ "client_limit_unit_lv",               &battle_config.client_limit_unit_lv,            0,      0,      BL_ALL,         },
 // BattleGround Settings
 	{ "bg_update_interval",                 &battle_config.bg_update_interval,              1000,   100,    INT_MAX,        },
 	{ "bg_short_attack_damage_rate",        &battle_config.bg_short_damage_rate,            80,     0,      INT_MAX,        },

+ 1 - 0
src/map/battle.h

@@ -485,6 +485,7 @@ extern struct Battle_Config
 	int display_party_name;
 	int cashshop_show_points;
 	int mail_show_status;
+	int client_limit_unit_lv;
 
 	// [BattleGround Settings]
 	int bg_update_interval;

+ 2 - 0
src/map/chrif.c

@@ -311,8 +311,10 @@ int chrif_save(struct map_session_data *sd, int flag)
 		merc_save(sd->hd);
 	if( sd->md && mercenary_get_lifetime(sd->md) > 0 )
 		mercenary_save(sd->md);
+#ifndef TXT_ONLY
 	if( sd->save_quest )
 		intif_quest_save(sd);
+#endif
 
 	return 0;
 }

+ 172 - 76
src/map/clif.c

@@ -4,6 +4,7 @@
 #include "../common/cbasetypes.h"
 #include "../common/socket.h"
 #include "../common/timer.h"
+#include "../common/grfio.h"
 #include "../common/malloc.h"
 #include "../common/version.h"
 #include "../common/nullpo.h"
@@ -57,7 +58,7 @@ struct Clif_Config {
 struct s_packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB + 1];
 
 //Converts item type in case of pet eggs.
-inline int itemtype(int type)
+static inline int itemtype(int type)
 {
 	return ( type == IT_PETEGG ) ? IT_WEAPON : type;
 }
@@ -755,13 +756,37 @@ void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, un
 }
 
 //To make the assignation of the level based on limits clearer/easier. [Skotlex]
-static int clif_setlevel(int lv)
+static int clif_setlevel_sub(int lv)
 {
-   if( lv < battle_config.max_lv )
-	  return lv;
-   if( lv < battle_config.aura_lv )
-	  return battle_config.max_lv - 1;
-   return battle_config.max_lv;
+	if( lv < battle_config.max_lv )
+	{
+		;
+	}
+	else if( lv < battle_config.aura_lv )
+	{
+		lv = battle_config.max_lv - 1;
+	}
+	else
+	{
+		lv = battle_config.max_lv;
+	}
+
+	return lv;
+}
+
+static int clif_setlevel(struct block_list* bl)
+{
+	int lv = status_get_lv(bl);
+	if( battle_config.client_limit_unit_lv&bl->type )
+		return clif_setlevel_sub(lv);
+	switch( bl->type )
+	{
+		case BL_NPC:
+		case BL_PET:
+			// npcs and pets do not have level
+			return 0;
+	}
+	return lv;
 }
 
 /*==========================================
@@ -915,7 +940,7 @@ static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool
 		offset++;
 		buf = WBUFP(buffer,offset);
 	}
-	WBUFW(buf,51) = clif_setlevel(status_get_lv(bl));
+	WBUFW(buf,51) = clif_setlevel(bl);
 #if PACKETVER < 20091103
 	if (type) //End for non-player packet
 		return packet_len(WBUFW(buffer,0));
@@ -1026,7 +1051,7 @@ static int clif_set_unit_walking(struct block_list* bl, struct unit_data* ud, un
 	WBUFPOS2(buf,50,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
 	WBUFB(buf,56) = (sd)? 5 : 0;
 	WBUFB(buf,57) = (sd)? 5 : 0;
-	WBUFW(buf,58) = clif_setlevel(status_get_lv(bl));
+	WBUFW(buf,58) = clif_setlevel(bl);
 #if PACKETVER >= 20080102
 	WBUFW(buf,60) = sd?sd->user_font:0;
 #endif
@@ -1214,8 +1239,8 @@ int clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
 	WBUFW(buf,29)=hd->homunculus.hunger;
 	WBUFW(buf,31)=(unsigned short) (hd->homunculus.intimacy / 100) ;
 	WBUFW(buf,33)=0; // equip id
-	WBUFW(buf,35)=cap_value(status->rhw.atk2+status->batk, 0, SHRT_MAX);
-	WBUFW(buf,37)=cap_value(status->matk_max, 0, SHRT_MAX);
+	WBUFW(buf,35)=cap_value(status->rhw.atk2+status->batk, 0, INT16_MAX);
+	WBUFW(buf,37)=cap_value(status->matk_max, 0, INT16_MAX);
 	WBUFW(buf,39)=status->hit;
 	if (battle_config.hom_setting&0x10)
 		WBUFW(buf,41)=status->luk/3 + 1;	//crit is a +1 decimal value! Just display purpose.[Vicious]
@@ -1225,14 +1250,14 @@ int clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
 	WBUFW(buf,45)=status->mdef;
 	WBUFW(buf,47)=status->flee;
 	WBUFW(buf,49)=(flag)?0:status->amotion;
-	if (status->max_hp > SHRT_MAX) {
+	if (status->max_hp > INT16_MAX) {
 		WBUFW(buf,51) = status->hp/(status->max_hp/100);
 		WBUFW(buf,53) = 100;
 	} else {
 		WBUFW(buf,51)=status->hp;
 		WBUFW(buf,53)=status->max_hp;
 	}
-	if (status->max_sp > SHRT_MAX) {
+	if (status->max_sp > INT16_MAX) {
 		WBUFW(buf,55) = status->sp/(status->max_sp/100);
 		WBUFW(buf,57) = 100;
 	} else {
@@ -2824,18 +2849,18 @@ int clif_initialstatus(struct map_session_data *sd)
 	buf=WFIFOP(fd,0);
 
 	WBUFW(buf,0)=0xbd;
-	WBUFW(buf,2)=min(sd->status.status_point, SHRT_MAX);
-	WBUFB(buf,4)=min(sd->status.str, UCHAR_MAX);
+	WBUFW(buf,2)=min(sd->status.status_point, INT16_MAX);
+	WBUFB(buf,4)=min(sd->status.str, UINT8_MAX);
 	WBUFB(buf,5)=pc_need_status_point(sd,SP_STR,1);
-	WBUFB(buf,6)=min(sd->status.agi, UCHAR_MAX);
+	WBUFB(buf,6)=min(sd->status.agi, UINT8_MAX);
 	WBUFB(buf,7)=pc_need_status_point(sd,SP_AGI,1);
-	WBUFB(buf,8)=min(sd->status.vit, UCHAR_MAX);
+	WBUFB(buf,8)=min(sd->status.vit, UINT8_MAX);
 	WBUFB(buf,9)=pc_need_status_point(sd,SP_VIT,1);
-	WBUFB(buf,10)=min(sd->status.int_, UCHAR_MAX);
+	WBUFB(buf,10)=min(sd->status.int_, UINT8_MAX);
 	WBUFB(buf,11)=pc_need_status_point(sd,SP_INT,1);
-	WBUFB(buf,12)=min(sd->status.dex, UCHAR_MAX);
+	WBUFB(buf,12)=min(sd->status.dex, UINT8_MAX);
 	WBUFB(buf,13)=pc_need_status_point(sd,SP_DEX,1);
-	WBUFB(buf,14)=min(sd->status.luk, UCHAR_MAX);
+	WBUFB(buf,14)=min(sd->status.luk, UINT8_MAX);
 	WBUFB(buf,15)=pc_need_status_point(sd,SP_LUK,1);
 
 	WBUFW(buf,16) = sd->battle_status.batk;
@@ -2969,7 +2994,7 @@ int clif_statusupack(struct map_session_data *sd,int type,int ok,int val)
 	WFIFOW(fd,0)=0xbc;
 	WFIFOW(fd,2)=type;
 	WFIFOB(fd,4)=ok;
-	WFIFOB(fd,5)=cap_value(val,0,UCHAR_MAX);
+	WFIFOB(fd,5)=cap_value(val,0,UINT8_MAX);
 	WFIFOSET(fd,packet_len(0xbc));
 
 	return 0;
@@ -3103,7 +3128,7 @@ int clif_changeoption2(struct block_list* bl)
 	WBUFW(buf,0) = 0x28a;
 	WBUFL(buf,2) = bl->id;
 	WBUFL(buf,6) = sc->option;
-	WBUFL(buf,10) = clif_setlevel(status_get_lv(bl));
+	WBUFL(buf,10) = clif_setlevel(bl);
 	WBUFL(buf,14) = sc->opt3;
 	if(disguised(bl)) {
 		clif_send(buf,packet_len(0x28a),bl,AREA_WOS);
@@ -3834,7 +3859,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic
 		WBUFW(buf,22)=damage?div:0;
 		WBUFW(buf,27)=damage2?div:0;
 	} else {
-		WBUFW(buf,22)=min(damage, SHRT_MAX);
+		WBUFW(buf,22)=min(damage, INT16_MAX);
 		WBUFW(buf,27)=damage2;
 	}
 	WBUFW(buf,24)=div;
@@ -4191,10 +4216,7 @@ int clif_skillinfoblock(struct map_session_data *sd)
 		if( (id = sd->status.skill[i].id) != 0 )
 		{
 			WFIFOW(fd,len)   = id;
-			if( (id == MO_EXTREMITYFIST && sd->state.combo&1) || (id == TK_JUMPKICK && sd->state.combo&2) )
-				WFIFOW(fd,len+2) = INF_SELF_SKILL;
-			else
-				WFIFOW(fd,len+2) = skill_get_inf(id);
+			WFIFOW(fd,len+2) = skill_get_inf(id);
 			WFIFOW(fd,len+4) = 0;
 			WFIFOW(fd,len+6) = sd->status.skill[i].lv;
 			WFIFOW(fd,len+8) = skill_get_sp(id,sd->status.skill[i].lv);
@@ -4228,10 +4250,7 @@ int clif_addskill(struct map_session_data *sd, int id )
 	WFIFOHEAD(fd, packet_len(0x111));
 	WFIFOW(fd,0) = 0x111;
 	WFIFOW(fd,2) = id;
-	if( (id == MO_EXTREMITYFIST && sd->state.combo&1) || (id == TK_JUMPKICK && sd->state.combo&2) )
-		WFIFOW(fd,4) = INF_SELF_SKILL;
-	else
-		WFIFOW(fd,4) = skill_get_inf(id);
+	WFIFOW(fd,4) = skill_get_inf(id);
  	WFIFOW(fd,6) = 0;
 	WFIFOW(fd,8) = sd->status.skill[id].lv;
 	WFIFOW(fd,10) = skill_get_sp(id,sd->status.skill[id].lv);
@@ -4287,6 +4306,24 @@ int clif_skillup(struct map_session_data *sd,int skill_num)
 	return 0;
 }
 
+//PACKET_ZC_SKILLINFO_UPDATE2
+//Like packet 0x0x10e, but also contains inf information
+void clif_skillinfo(struct map_session_data *sd,int skill, int inf)
+{
+	const int fd = sd->fd;
+	WFIFOHEAD(fd,packet_len(0x7e1));
+	WFIFOW(fd,0) = 0x7e1;
+	WFIFOW(fd,2) = skill;
+	WFIFOL(fd,4) = inf?inf:skill_get_inf(skill);
+	WFIFOW(fd,8) = sd->status.skill[skill].lv;
+	WFIFOW(fd,10) = skill_get_sp(skill,sd->status.skill[skill].lv);
+	WFIFOW(fd,12) = skill_get_range2(&sd->bl,skill,sd->status.skill[skill].lv);
+	if( sd->status.skill[skill].flag == SKILL_FLAG_PERMANENT )
+		WFIFOB(fd,14) = (sd->status.skill[skill].lv < skill_tree_get_max(skill, sd->status.class_))? 1:0;
+	else
+		WFIFOB(fd,14) = 0;
+	WFIFOSET(fd,packet_len(0x7e1));
+}
 
 /// Notifies clients, that an object is about to use a skill (ZC_USESKILL_ACK/ZC_USESKILL_ACK2)
 /// 013e <src id>.L <dst id>.L <x pos>.W <y pos>.W <skill id>.W <property>.L <delaytime>.L
@@ -4627,7 +4664,7 @@ int clif_skill_nodamage(struct block_list *src,struct block_list *dst,int skill_
 
 	WBUFW(buf,0)=0x11a;
 	WBUFW(buf,2)=skill_id;
-	WBUFW(buf,4)=min(heal, SHRT_MAX);
+	WBUFW(buf,4)=min(heal, INT16_MAX);
 	WBUFL(buf,6)=dst->id;
 	WBUFL(buf,10)=src?src->id:0;
 	WBUFB(buf,14)=fail;
@@ -5085,7 +5122,7 @@ int clif_heal(int fd,int type,int val)
 	WFIFOHEAD(fd,packet_len(0x13d));
 	WFIFOW(fd,0)=0x13d;
 	WFIFOW(fd,2)=type;
-	WFIFOW(fd,4)=cap_value(val,0,SHRT_MAX);
+	WFIFOW(fd,4)=cap_value(val,0,INT16_MAX);
 	WFIFOSET(fd,packet_len(0x13d));
 
 	return 0;
@@ -5157,7 +5194,7 @@ int clif_pvpset(struct map_session_data *sd,int pvprank,int pvpnum,int type)
 		WBUFW(buf,0) = 0x19a;
 		WBUFL(buf,2) = sd->bl.id;
 		if(sd->sc.option&(OPTION_HIDE|OPTION_CLOAK))
-			WBUFL(buf,6) = ULONG_MAX; //On client displays as --
+			WBUFL(buf,6) = UINT32_MAX; //On client displays as --
 		else
 			WBUFL(buf,6) = pvprank;
 		WBUFL(buf,10) = pvpnum;
@@ -6075,7 +6112,7 @@ int clif_party_hp(struct map_session_data *sd)
 	WBUFW(buf,0)=cmd;
 	WBUFL(buf,2)=sd->status.account_id;
 #if PACKETVER < 20100126
-	if (sd->battle_status.max_hp > SHRT_MAX) { //To correctly display the %hp bar. [Skotlex]
+	if (sd->battle_status.max_hp > INT16_MAX) { //To correctly display the %hp bar. [Skotlex]
 		WBUFW(buf,6) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
 		WBUFW(buf,8) = 100;
 	} else {
@@ -6104,7 +6141,7 @@ void clif_hpmeter_single(int fd, int id, unsigned int hp, unsigned int maxhp)
 	WFIFOW(fd,0) = cmd;
 	WFIFOL(fd,2) = id;
 #if PACKETVER < 20100126
-	if( maxhp > SHRT_MAX )
+	if( maxhp > INT16_MAX )
 	{// To correctly display the %hp bar. [Skotlex]
 		WFIFOW(fd,6) = hp/(maxhp/100);
 		WFIFOW(fd,8) = 100;
@@ -6147,7 +6184,7 @@ int clif_hpmeter_sub(struct block_list *bl, va_list ap)
 	WFIFOW(tsd->fd,0) = cmd;
 	WFIFOL(tsd->fd,2) = sd->status.account_id;
 #if PACKETVER < 20100126
-	if( sd->battle_status.max_hp > SHRT_MAX )
+	if( sd->battle_status.max_hp > INT16_MAX )
 	{ //To correctly display the %hp bar. [Skotlex]
 		WFIFOW(tsd->fd,6) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
 		WFIFOW(tsd->fd,8) = 100;
@@ -6582,7 +6619,7 @@ int clif_mvp_exp(struct map_session_data *sd, unsigned int exp)
 	fd=sd->fd;
 	WFIFOHEAD(fd,packet_len(0x10b));
 	WFIFOW(fd,0)=0x10b;
-	WFIFOL(fd,2)=cap_value(exp,0,INT_MAX);
+	WFIFOL(fd,2)=cap_value(exp,0,INT32_MAX);
 	WFIFOSET(fd,packet_len(0x10b));
 	return 0;
 }
@@ -6608,27 +6645,30 @@ int clif_guild_created(struct map_session_data *sd,int flag)
 	WFIFOSET(fd,packet_len(0x167));
 	return 0;
 }
-/*==========================================
- * ギルド所属通知
- *------------------------------------------*/
-int clif_guild_belonginfo(struct map_session_data *sd, struct guild *g)
+
+
+/// Notifies the client that it is belonging to a guild (ZC_UPDATE_GDID)
+/// 016c <guild id>.L <emblem id>.L <mode>.L <ismaster>.B <inter sid>.L <guild name>.24B
+void clif_guild_belonginfo(struct map_session_data *sd, struct guild *g)
 {
 	int ps,fd;
-	nullpo_ret(sd);
-	nullpo_ret(g);
+	nullpo_retv(sd);
+	nullpo_retv(g);
 
 	fd=sd->fd;
 	ps=guild_getposition(g,sd);
 	WFIFOHEAD(fd,packet_len(0x16c));
-	memset(WFIFOP(fd,0),0,packet_len(0x16c));
 	WFIFOW(fd,0)=0x16c;
 	WFIFOL(fd,2)=g->guild_id;
 	WFIFOL(fd,6)=g->emblem_id;
 	WFIFOL(fd,10)=g->position[ps].mode;
+	WFIFOB(fd,14)=(bool)(sd->state.gmaster_flag==g);
+	WFIFOL(fd,15)=0;  // InterSID (unknown purpose)
 	memcpy(WFIFOP(fd,19),g->name,NAME_LENGTH);
 	WFIFOSET(fd,packet_len(0x16c));
-	return 0;
 }
+
+
 /*==========================================
  * ギルドメンバログイン通知
  *------------------------------------------*/
@@ -6729,7 +6769,7 @@ int clif_guild_basicinfo(struct map_session_data *sd)
 	WFIFOL(fd,10)=g->connect_member;
 	WFIFOL(fd,14)=g->max_member;
 	WFIFOL(fd,18)=g->average_lv;
-	WFIFOL(fd,22)=(uint32)cap_value(g->exp,0,INT_MAX);
+	WFIFOL(fd,22)=(uint32)cap_value(g->exp,0,INT32_MAX);
 	WFIFOL(fd,26)=g->next_exp;
 	WFIFOL(fd,30)=0;	// Tax Points
 	WFIFOL(fd,34)=0;	// Tendency: (left) Vulgar [-100,100] Famed (right)
@@ -6807,7 +6847,7 @@ int clif_guild_memberlist(struct map_session_data *sd)
 		WFIFOW(fd,c*104+16)=m->gender;
 		WFIFOW(fd,c*104+18)=m->class_;
 		WFIFOW(fd,c*104+20)=m->lv;
-		WFIFOL(fd,c*104+22)=(int)cap_value(m->exp,0,INT_MAX);
+		WFIFOL(fd,c*104+22)=(int)cap_value(m->exp,0,INT32_MAX);
 		WFIFOL(fd,c*104+26)=m->online;
 		WFIFOL(fd,c*104+30)=m->position;
 		memset(WFIFOP(fd,c*104+34),0,50);	// メモ?
@@ -10032,7 +10072,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
 	if( skillnotok(skillnum, sd) )
 		return;
 
-	if( sd->bl.id != target_id && (tmp&INF_SELF_SKILL || sd->state.combo) )
+	if( sd->bl.id != target_id && tmp&INF_SELF_SKILL )
 		target_id = sd->bl.id; // never trust the client
 	
 	if( target_id < 0 && -target_id == sd->bl.id ) // for disguises [Valaris]
@@ -11121,16 +11161,43 @@ void clif_parse_GuildRequestEmblem(int fd,struct map_session_data *sd)
 		clif_guild_emblem(sd,g);
 }
 
+
+/// Validates data of a guild emblem (compressed bitmap)
+static bool clif_validate_emblem(const uint8* emblem, unsigned long emblem_len)
+{
+	bool success;
+	uint8 buf[1800];  // no well-formed emblem bitmap is larger than 1782 (24 bit) / 1654 (8 bit) bytes
+	unsigned long buf_len = sizeof(buf);
+
+	success = ( decode_zip(buf, &buf_len, emblem, emblem_len) == 0 && buf_len >= 18 )  // sizeof(BITMAPFILEHEADER) + sizeof(biSize) of the following info header struct
+			&& RBUFW(buf,0) == 0x4d42   // BITMAPFILEHEADER.bfType (signature)
+			&& RBUFL(buf,2) == buf_len  // BITMAPFILEHEADER.bfSize (file size)
+			&& RBUFL(buf,10) < buf_len  // BITMAPFILEHEADER.bfOffBits (offset to bitmap bits)
+			;
+
+	return success;
+}
+
+
 /*==========================================
  * ギルドエンブレム変更
  * S 0153 <packet len>.W <emblem data>.?B
  *------------------------------------------*/
 void clif_parse_GuildChangeEmblem(int fd,struct map_session_data *sd)
 {
-	if(!sd->state.gmaster_flag)
+	unsigned long emblem_len = RFIFOW(fd,2)-4;
+	const uint8* emblem = RFIFOP(fd,4);
+
+	if( !emblem_len || !sd->state.gmaster_flag )
 		return;
 
-	guild_change_emblem(sd,RFIFOW(fd,2)-4,(char*)RFIFOP(fd,4));
+	if( !clif_validate_emblem(emblem, emblem_len) )
+	{
+		ShowWarning("clif_parse_GuildChangeEmblem: Rejected malformed guild emblem (size=%lu, accound_id=%d, char_id=%d, guild_id=%d).\n", emblem_len, sd->status.account_id, sd->status.char_id, sd->status.guild_id);
+		return;
+	}
+
+	guild_change_emblem(sd, emblem_len, (const char*)emblem);
 }
 
 /*==========================================
@@ -12496,17 +12563,17 @@ void clif_check(int fd, struct map_session_data* pl_sd)
 {
 	WFIFOHEAD(fd,packet_len(0x214));
 	WFIFOW(fd, 0) = 0x214;
-	WFIFOB(fd, 2) = min(pl_sd->status.str, UCHAR_MAX);
+	WFIFOB(fd, 2) = min(pl_sd->status.str, UINT8_MAX);
 	WFIFOB(fd, 3) = pc_need_status_point(pl_sd, SP_STR, 1);
-	WFIFOB(fd, 4) = min(pl_sd->status.agi, UCHAR_MAX);
+	WFIFOB(fd, 4) = min(pl_sd->status.agi, UINT8_MAX);
 	WFIFOB(fd, 5) = pc_need_status_point(pl_sd, SP_AGI, 1);
-	WFIFOB(fd, 6) = min(pl_sd->status.vit, UCHAR_MAX);
+	WFIFOB(fd, 6) = min(pl_sd->status.vit, UINT8_MAX);
 	WFIFOB(fd, 7) = pc_need_status_point(pl_sd, SP_VIT, 1);
-	WFIFOB(fd, 8) = min(pl_sd->status.int_, UCHAR_MAX);
+	WFIFOB(fd, 8) = min(pl_sd->status.int_, UINT8_MAX);
 	WFIFOB(fd, 9) = pc_need_status_point(pl_sd, SP_INT, 1);
-	WFIFOB(fd,10) = min(pl_sd->status.dex, UCHAR_MAX);
+	WFIFOB(fd,10) = min(pl_sd->status.dex, UINT8_MAX);
 	WFIFOB(fd,11) = pc_need_status_point(pl_sd, SP_DEX, 1);
-	WFIFOB(fd,12) = min(pl_sd->status.luk, UCHAR_MAX);
+	WFIFOB(fd,12) = min(pl_sd->status.luk, UINT8_MAX);
 	WFIFOB(fd,13) = pc_need_status_point(pl_sd, SP_LUK, 1);
 	WFIFOW(fd,14) = pl_sd->battle_status.batk+pl_sd->battle_status.rhw.atk+pl_sd->battle_status.lhw.atk;
 	WFIFOW(fd,16) = pl_sd->battle_status.rhw.atk2+pl_sd->battle_status.lhw.atk2;
@@ -13280,34 +13347,46 @@ void clif_parse_Auction_buysell(int fd, struct map_session_data* sd)
 /*==========================================
  * CASH/POINT SHOP
  *==========================================*/
+
+/// List of items offered in a cash shop (ZC_PC_CASH_POINT_ITEMLIST)
+/// 0287 <packet len>.W <cash point>.L { <sell price>.L <discount price>.L <item type>.B <name id>.W }*
+/// 0287 <packet len>.W <cash point>.L <kafra point>.L { <sell price>.L <discount price>.L <item type>.B <name id>.W }* (PACKETVER >= 20070711)
 void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd)
 {
 	int fd,i;
+#if PACKETVER < 20070711
+	const int offset = 8;
+#else
+	const int offset = 12;
+#endif
 
 	nullpo_retv(sd);
 	nullpo_retv(nd);
 
 	fd = sd->fd;
 	sd->npc_shopid = nd->bl.id;
-	WFIFOHEAD(fd, 200 * 11 + 12);
+	WFIFOHEAD(fd,offset+nd->u.shop.count*11);
 	WFIFOW(fd,0) = 0x287;
-	WFIFOW(fd,2) = 12 + nd->u.shop.count*11;
+	WFIFOW(fd,2) = offset+nd->u.shop.count*11;
 	WFIFOL(fd,4) = sd->cashPoints; // Cash Points
+#if PACKETVER >= 20070711
 	WFIFOL(fd,8) = sd->kafraPoints; // Kafra Points
+#endif
 
 	for( i = 0; i < nd->u.shop.count; i++ )
 	{
 		struct item_data* id = itemdb_search(nd->u.shop.shop_item[i].nameid);
-		WFIFOL(fd,12+i*11) = nd->u.shop.shop_item[i].value;
-		WFIFOL(fd,16+i*11) = nd->u.shop.shop_item[i].value; // Discount Price? Maybe a Discount item
-		WFIFOB(fd,20+i*11) = itemtype(id->type);
-		WFIFOW(fd,21+i*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
+		WFIFOL(fd,offset+0+i*11) = nd->u.shop.shop_item[i].value;
+		WFIFOL(fd,offset+4+i*11) = nd->u.shop.shop_item[i].value; // Discount Price
+		WFIFOB(fd,offset+8+i*11) = itemtype(id->type);
+		WFIFOW(fd,offset+9+i*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
 	}
 	WFIFOSET(fd,WFIFOW(fd,2));
 }
 
 /// Cashshop Buy Ack (ZC_PC_CASH_POINT_UPDATE)
-/// S 0289 <cash point>.L <kafra point>.L <error>.W
+/// S 0289 <cash point>.L <error>.W
+/// S 0289 <cash point>.L <kafra point>.L <error>.W (PACKETVER >= 20070711)
 ///
 /// @param error
 /// 0: The deal has successfully completed. (ERROR_TYPE_NONE)
@@ -13326,20 +13405,30 @@ void clif_cashshop_ack(struct map_session_data* sd, int error)
 	WFIFOHEAD(fd, packet_len(0x289));
 	WFIFOW(fd,0) = 0x289;
 	WFIFOL(fd,2) = sd->cashPoints;
+#if PACKETVER < 20070711
+	WFIFOW(fd,6) = TOW(error);
+#else
 	WFIFOL(fd,6) = sd->kafraPoints;
 	WFIFOW(fd,10) = TOW(error);
+#endif
 	WFIFOSET(fd, packet_len(0x289));
 }
 
+/// Request to buy item(s) from cash shop (CZ_PC_BUY_CASH_POINT_ITEM).
+/// 0288 <name id>.W <amount>.W
+/// 0288 <name id>.W <amount>.W <kafra points>.L (PACKETVER >= 20070711)
+/// 0288 <packet len>.W <kafra points>.L <count>.W { <amount>.W <name id>.W }.4B*count (PACKETVER >= 20100803)
 void clif_parse_cashshop_buy(int fd, struct map_session_data *sd)
 {
-	int fail = 0, amount, points;
+	int fail = 0, amount, points = 0;
 	short nameid;
 	nullpo_retv(sd);
 
 	nameid = RFIFOW(fd,2);
 	amount = RFIFOW(fd,4);
+#if PACKETVER >= 20070711
 	points = RFIFOL(fd,6); // Not Implemented. Should be 0
+#endif
 
 	if( sd->state.trading || !sd->npc_shopid )
 		fail = 1;
@@ -13662,11 +13751,11 @@ void clif_mercenary_updatestatus(struct map_session_data *sd, int type)
 		case SP_ATK1:
 			{
 				int atk = rand()%(status->rhw.atk2 - status->rhw.atk + 1) + status->rhw.atk;
-				WFIFOL(fd,4) = cap_value(atk, 0, SHRT_MAX);
+				WFIFOL(fd,4) = cap_value(atk, 0, INT16_MAX);
 			}
 			break;
 		case SP_MATK1:
-			WFIFOL(fd,4) = cap_value(status->matk_max, 0, SHRT_MAX);
+			WFIFOL(fd,4) = cap_value(status->matk_max, 0, INT16_MAX);
 			break;
 		case SP_HIT:
 			WFIFOL(fd,4) = status->hit;
@@ -13727,8 +13816,8 @@ void clif_mercenary_info(struct map_session_data *sd)
 
 	// Mercenary shows ATK as a random value between ATK ~ ATK2
 	atk = rand()%(status->rhw.atk2 - status->rhw.atk + 1) + status->rhw.atk;
-	WFIFOW(fd,6) = cap_value(atk, 0, SHRT_MAX);
-	WFIFOW(fd,8) = cap_value(status->matk_max, 0, SHRT_MAX);
+	WFIFOW(fd,6) = cap_value(atk, 0, INT16_MAX);
+	WFIFOW(fd,8) = cap_value(status->matk_max, 0, INT16_MAX);
 	WFIFOW(fd,10) = status->hit;
 	WFIFOW(fd,12) = status->cri/10;
 	WFIFOW(fd,14) = status->def;
@@ -13813,11 +13902,14 @@ void clif_rental_time(int fd, int nameid, int seconds)
 	WFIFOSET(fd,8);
 }
 
-void clif_rental_expired(int fd, int nameid)
+
+/// Deletes a rental item from client's inventory (ZC_CASH_ITEM_DELETE).
+/// 0299 <index>.W <nameid>.W
+void clif_rental_expired(int fd, int index, int nameid)
 { // '<ItemName>' item has been deleted from the Inventory
 	WFIFOHEAD(fd,6);
 	WFIFOW(fd,0) = 0x0299;
-	WFIFOW(fd,2) = 0;
+	WFIFOW(fd,2) = index+2;
 	WFIFOW(fd,4) = nameid;
 	WFIFOSET(fd,6);
 }
@@ -13850,7 +13942,7 @@ int clif_bg_hp(struct map_session_data *sd)
 	WBUFW(buf,0)=cmd;
 	WBUFL(buf,2) = sd->status.account_id;
 #if PACKETVER < 20100126
-	if( sd->battle_status.max_hp > SHRT_MAX )
+	if( sd->battle_status.max_hp > INT16_MAX )
 	{ // To correctly display the %hp bar. [Skotlex]
 		WBUFW(buf,6) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
 		WBUFW(buf,8) = 100;
@@ -14581,7 +14673,7 @@ void clif_search_store_info_ack(struct map_session_data* sd)
 	WFIFOW(fd,2) = 7+(end-start)*blocksize;
 	WFIFOB(fd,4) = !sd->searchstore.pages;
 	WFIFOB(fd,5) = searchstore_querynext(sd);
-	WFIFOB(fd,6) = (unsigned char)min(sd->searchstore.uses, UCHAR_MAX);
+	WFIFOB(fd,6) = (unsigned char)min(sd->searchstore.uses, UINT8_MAX);
 
 	for( i = start; i < end; i++ )
 	{
@@ -14650,7 +14742,7 @@ void clif_open_search_store_info(struct map_session_data* sd)
 	WFIFOW(fd,0) = 0x83a;
 	WFIFOW(fd,2) = sd->searchstore.effect;
 #if PACKETVER > 20100701
-	WFIFOB(fd,4) = (unsigned char)min(sd->searchstore.uses, UCHAR_MAX);
+	WFIFOB(fd,4) = (unsigned char)min(sd->searchstore.uses, UINT8_MAX);
 #endif
 	WFIFOSET(fd,packet_len(0x83a));
 }
@@ -14985,7 +15077,11 @@ static int packetdb_readdb(void)
 	    6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	    0,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	//#0x0280
-	    0,  0,  0,  6,  0,  0,  0,  0,  0, 12, 18,  0,  0,  0,  0,  0,
+#if PACKETVER < 20070711
+	    0,  0,  0,  6,  0,  0,  0, -1,  6,  8, 18,  0,  0,  0,  0,  0,
+#else
+	    0,  0,  0,  6,  0,  0,  0, -1, 10, 12, 18,  0,  0,  0,  0,  0, // 0x288, 0x289 increase by 4 (kafra points)
+#endif
 	    0,  4,  0, 70,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	   85, -1, -1,107,  6, -1,  7,  7, 22,191,  0,  0,  0,  0,  0,  0,
@@ -15096,7 +15192,7 @@ static int packetdb_readdb(void)
 #else // 0x7d9 changed
 	    6,  2, -1,  4,  4,  4,  4,  8,  8,268,  6,  8,  6, 54, 30, 54,
 #endif
-	    0,  0,  0,  0,  0,  8,  8, 32, -1,  5,  0,  0,  0,  0,  0,  0,
+	    0, 15,  0,  0,  0,  8,  8, 32, -1,  5,  0,  0,  0,  0,  0,  0,
 	    0,  0,  0,  0,  0,  0, 14, -1, -1, -1,  8, 25,  0,  0, 26,  0,
 	//#0x0800
 #if PACKETVER < 20091229

+ 3 - 2
src/map/clif.h

@@ -323,6 +323,7 @@ int clif_mob_equip(struct mob_data *md,int nameid); // [Valaris]
 
 int clif_skillinfoblock(struct map_session_data *sd);
 int clif_skillup(struct map_session_data *sd,int skill_num);
+void clif_skillinfo(struct map_session_data *sd,int skill, int inf);
 int clif_addskill(struct map_session_data *sd, int skill);
 int clif_deleteskill(struct map_session_data *sd, int skill);
 
@@ -419,7 +420,7 @@ int clif_hpmeter_sub(struct block_list *bl, va_list ap);
 
 // guild
 int clif_guild_created(struct map_session_data *sd,int flag);
-int clif_guild_belonginfo(struct map_session_data *sd,struct guild *g);
+void clif_guild_belonginfo(struct map_session_data *sd,struct guild *g);
 int clif_guild_masterormember(struct map_session_data *sd);
 int clif_guild_basicinfo(struct map_session_data *sd);
 int clif_guild_allianceinfo(struct map_session_data *sd);
@@ -584,7 +585,7 @@ void clif_mercenary_updatestatus(struct map_session_data *sd, int type);
 
 // RENTAL SYSTEM
 void clif_rental_time(int fd, int nameid, int seconds);
-void clif_rental_expired(int fd, int nameid);
+void clif_rental_expired(int fd, int index, int nameid);
 
 // BOOK READING
 void clif_readbook(int fd, int book_id, int page);

+ 1 - 1
src/map/itemdb.h

@@ -122,7 +122,7 @@ int itemdb_searchrandomid(int flags);
 
 #define itemdb_value_buy(n) itemdb_search(n)->value_buy
 #define itemdb_value_sell(n) itemdb_search(n)->value_sell
-#define itemdb_canrefine(n) itemdb_search(n)->flag.no_refine
+#define itemdb_canrefine(n) (!itemdb_search(n)->flag.no_refine)
 //Item trade restrictions [Skotlex]
 int itemdb_isdropable_sub(struct item_data *, int, int);
 int itemdb_cantrade_sub(struct item_data*, int, int);

+ 5 - 5
src/map/map.c

@@ -2305,7 +2305,7 @@ int map_random_dir(struct block_list *bl, short *x, short *y)
 	if (dist < 1) dist =1;
 	
 	do {
-		j = rand()%8; //Pick a random direction
+		j = 1 + 2*(rand()%4); //Pick a random diagonal direction
 		segment = 1+(rand()%dist); //Pick a random interval from the whole vector in that direction
 		xi = bl->x + segment*dirx[j];
 		segment = (short)sqrt((float)(dist2 - segment*segment)); //The complement of the previously picked segment
@@ -2676,7 +2676,7 @@ static char *map_init_mapcache(FILE *fp)
 	fseek(fp, 0, SEEK_SET);
 
 	// Allocate enough space
-	CREATE(buffer, unsigned char, size);
+	CREATE(buffer, char, size);
 
 	// No memory? Return..
 	nullpo_ret(buffer);
@@ -2699,7 +2699,7 @@ int map_readfromcache(struct map_data *m, char *buffer, char *decode_buffer)
 	int i;
 	struct map_cache_main_header *header = (struct map_cache_main_header *)buffer;
 	struct map_cache_map_info *info = NULL;
-	unsigned char *p = buffer + sizeof(struct map_cache_main_header);
+	char *p = buffer + sizeof(struct map_cache_main_header);
 
 	for(i = 0; i < header->map_count; i++) {
 		info = (struct map_cache_map_info *)p;
@@ -2906,8 +2906,8 @@ int map_readallmaps (void)
 	int i;
 	FILE* fp=NULL;
 	int maps_removed = 0;
-	unsigned char *map_cache_buffer = NULL; // Has the uncompressed gat data of all maps, so just one allocation has to be made
-	unsigned char map_cache_decode_buffer[MAX_MAP_SIZE];
+	char *map_cache_buffer = NULL; // Has the uncompressed gat data of all maps, so just one allocation has to be made
+	char map_cache_decode_buffer[MAX_MAP_SIZE];
 
 	if( enable_grf )
 		ShowStatus("Loading maps (using GRF files)...\n");

+ 1 - 0
src/map/map.h

@@ -535,6 +535,7 @@ struct map_data {
 		unsigned partylock :1;
 		unsigned guildlock :1;
 		unsigned src4instance : 1; // To flag this map when it's used as a src map for instances
+		unsigned reset :1; // [Daegaladh]
 	} flag;
 	struct point save;
 	struct npc_data *npc[MAX_NPC_PER_MAP];

+ 23 - 15
src/map/mob.c

@@ -2259,10 +2259,11 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 			int itemid = 0;
 			for (i = 0; i < ARRAYLENGTH(sd->add_drop) && (sd->add_drop[i].id || sd->add_drop[i].group); i++)
 			{
-				if ( ( sd->add_drop[i].race <= (1<<status->race) &&
-				       sd->add_drop[i].race & (1<<status->race) ||
-				       sd->add_drop[i].race & 1<<(status->mode&MD_BOSS?RC_BOSS:RC_NONBOSS) ) ||
-				     ( sd->add_drop[i].race > (1<<RC_MAX) && sd->add_drop[i].race == md->class_) )
+				if ( sd->add_drop[i].race == -md->class_ ||
+					( sd->add_drop[i].race > 0 && (
+						sd->add_drop[i].race & (1<<status->race) ||
+						sd->add_drop[i].race & (1<<(status->mode&MD_BOSS?RC_BOSS:RC_NONBOSS))
+					)))
 				{
 					//check if the bonus item drop rate should be multiplied with mob level/10 [Lupus]
 					if(sd->add_drop[i].rate < 0) {
@@ -3638,6 +3639,9 @@ static bool mob_parse_dbrow(char** str)
 	// Finally insert monster's data into the database.
 	if (mob_db_data[class_] == NULL)
 		mob_db_data[class_] = (struct mob_db*)aCalloc(1, sizeof(struct mob_db));
+	else
+		//Copy over spawn data
+		memcpy(&db->spawn, mob_db_data[class_]->spawn, sizeof(db->spawn));
 
 	memcpy(mob_db_data[class_], db, sizeof(struct mob_db));
 	return true;
@@ -3960,6 +3964,21 @@ static bool mob_parse_row_mobskilldb(char** str, int columns, int current)
 	static const struct {
 		char str[32];
 		enum MobSkillState id;
+	} state[] = {
+		{	"any",		MSS_ANY		}, //All states except Dead
+		{	"idle",		MSS_IDLE	},
+		{	"walk",		MSS_WALK	},
+		{	"loot",		MSS_LOOT	},
+		{	"dead",		MSS_DEAD	},
+		{	"attack",	MSS_BERSERK	}, //Retaliating attack
+		{	"angry",	MSS_ANGRY	}, //Preemptive attack (aggressive mobs)
+		{	"chase",	MSS_RUSH	}, //Chase escaping target
+		{	"follow",	MSS_FOLLOW	}, //Preemptive chase (aggressive mobs)
+		{	"anytarget",MSS_ANYTARGET	}, //Berserk+Angry+Rush+Follow
+	};
+	static const struct {
+		char str[32];
+		int id;
 	} cond1[] = {
 		{ "always",            MSC_ALWAYS            },
 		{ "myhpltmaxrate",     MSC_MYHPLTMAXRATE     },
@@ -3997,17 +4016,6 @@ static bool mob_parse_row_mobskilldb(char** str, int columns, int current)
 		{	"blind",		SC_BLIND		},
 		{	"hiding",		SC_HIDING		},
 		{	"sight",		SC_SIGHT		},
-	}, state[] = {
-		{	"any",		MSS_ANY		}, //All states except Dead
-		{	"idle",		MSS_IDLE	},
-		{	"walk",		MSS_WALK	},
-		{	"loot",		MSS_LOOT	},
-		{	"dead",		MSS_DEAD	},
-		{	"attack",	MSS_BERSERK	}, //Retaliating attack
-		{	"angry",	MSS_ANGRY	}, //Preemptive attack (aggressive mobs)
-		{	"chase",	MSS_RUSH	}, //Chase escaping target
-		{	"follow",	MSS_FOLLOW	}, //Preemptive chase (aggressive mobs)
-		{	"anytarget",MSS_ANYTARGET	}, //Berserk+Angry+Rush+Follow
 	}, target[] = {
 		{	"target",	MST_TARGET	},
 		{	"randomtarget",	MST_RANDOM	},

+ 3 - 1
src/map/npc.c

@@ -2340,7 +2340,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
 	nd->speed = 200;
 	nd->src_id = src_id;
 	nd->bl.type = BL_NPC;
-	nd->subtype = type;
+	nd->subtype = (enum npc_subtype)type;
 	switch( type )
 	{
 	case SCRIPT:
@@ -3117,6 +3117,8 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
 		map[m].flag.partylock=state;
 	else if (!strcmpi(w3,"guildlock"))
 		map[m].flag.guildlock=state;
+	else if (!strcmpi(w3,"reset"))
+		map[m].flag.reset=state;
 	else
 		ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer));
 

+ 7 - 7
src/map/npc_chat.c

@@ -73,8 +73,8 @@
 struct pcrematch_entry {
 	struct pcrematch_entry* next;
 	char* pattern;
-	pcre* pcre;
-	pcre_extra* pcre_extra;
+	pcre* pcre_;
+	pcre_extra* pcre_extra_;
 	char* label;
 };
 
@@ -108,8 +108,8 @@ struct npc_parse {
  */
 void finalize_pcrematch_entry(struct pcrematch_entry* e)
 {
-	pcre_free(e->pcre);
-	pcre_free(e->pcre_extra);
+	pcre_free(e->pcre_);
+	pcre_free(e->pcre_extra_);
 	aFree(e->pattern);
 	aFree(e->label);
 }
@@ -316,8 +316,8 @@ void npc_chat_def_pattern(struct npc_data* nd, int setid, const char* pattern, c
 	struct pcrematch_entry *e = create_pcrematch_entry(s);
 	e->pattern = aStrdup(pattern);
 	e->label = aStrdup(label);
-	e->pcre = pcre_compile(pattern, PCRE_CASELESS, &err, &erroff, NULL);
-	e->pcre_extra = pcre_study(e->pcre, 0, &err);
+	e->pcre_ = pcre_compile(pattern, PCRE_CASELESS, &err, &erroff, NULL);
+	e->pcre_extra_ = pcre_study(e->pcre_, 0, &err);
 }
 
 /**
@@ -373,7 +373,7 @@ int npc_chat_sub(struct block_list* bl, va_list ap)
 			int offsets[2*10 + 10]; // 1/3 reserved for temp space requred by pcre_exec
 			
 			// perform pattern match
-			int r = pcre_exec(e->pcre, e->pcre_extra, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets));
+			int r = pcre_exec(e->pcre_, e->pcre_extra_, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets));
 			if (r > 0)
 			{
 				// save out the matched strings

+ 29 - 57
src/map/pc.c

@@ -335,8 +335,8 @@ void pc_inventory_rentals(struct map_session_data *sd)
 
 		if( sd->status.inventory[i].expire_time <= time(NULL) )
 		{
-			clif_rental_expired(sd->fd, sd->status.inventory[i].nameid);
-			pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0);
+			clif_rental_expired(sd->fd, i, sd->status.inventory[i].nameid);
+			pc_delitem(sd, i, sd->status.inventory[i].amount, 1, 0);
 		}
 		else
 		{
@@ -347,48 +347,6 @@ void pc_inventory_rentals(struct map_session_data *sd)
 		}
 	}
 
-	for( i = 0; i < MAX_CART; i++ )
-	{ // Check for Rentals on Cart
-		if( sd->status.cart[i].nameid == 0 )
-			continue; // Nothing here
-		if( sd->status.cart[i].expire_time == 0 )
-			continue;
-
-		if( sd->status.cart[i].expire_time <= time(NULL) )
-		{
-			clif_rental_expired(sd->fd, sd->status.cart[i].nameid);
-			pc_cart_delitem(sd, i, 1, 0);
-		}
-		else
-		{
-			expire_tick = (unsigned int)(sd->status.cart[i].expire_time - time(NULL)) * 1000;
-			clif_rental_time(sd->fd, sd->status.cart[i].nameid, (int)(expire_tick / 1000));
-			next_tick = min(expire_tick, next_tick);
-			c++;
-		}
-	}
-
-	for( i = 0; i < MAX_STORAGE; i++ )
-	{ // Check for Rentals on Storage
-		if( sd->status.storage.items[i].nameid == 0 )
-			continue;
-		if( sd->status.storage.items[i].expire_time == 0 )
-			continue;
-
-		if( sd->status.storage.items[i].expire_time <= time(NULL) )
-		{
-			clif_rental_expired(sd->fd, sd->status.storage.items[i].nameid);
-			storage_delitem(sd, i, 1);
-		}
-		else
-		{
-			expire_tick = (unsigned int)(sd->status.storage.items[i].expire_time - time(NULL)) * 1000;
-			clif_rental_time(sd->fd, sd->status.storage.items[i].nameid, (int)(expire_tick / 1000));
-			next_tick = min(expire_tick, next_tick);
-			c++;
-		}
-	}
-
 	if( c > 0 ) // min(next_tick,3600000) 1 hour each timer to keep announcing to the owner, and to avoid a but with rental time > 15 days
 		sd->rental_timer = add_timer(gettick() + min(next_tick,3600000), pc_inventory_rental_end, sd->bl.id, 0);
 	else
@@ -762,13 +720,17 @@ int pc_isequip(struct map_session_data *sd,int n)
 		return 0;
 	if(item->sex != 2 && sd->status.sex != item->sex)
 		return 0;
-	if(map[sd->bl.m].flag.pvp && ((item->flag.no_equip&1) || !pc_isAllowedCardOn(sd,item->slot,n,1)))
+	if(!map_flag_vs(sd->bl.m) && ((item->flag.no_equip&1) || !pc_isAllowedCardOn(sd,item->slot,n,1)))
+		return 0;
+	if(map[sd->bl.m].flag.pvp && ((item->flag.no_equip&2) || !pc_isAllowedCardOn(sd,item->slot,n,2)))
+		return 0;
+	if(map_flag_gvg(sd->bl.m) && ((item->flag.no_equip&4) || !pc_isAllowedCardOn(sd,item->slot,n,4)))
+		return 0;
+	if(map[sd->bl.m].flag.battleground && ((item->flag.no_equip&8) || !pc_isAllowedCardOn(sd,item->slot,n,8)))
 		return 0;
-	if(map_flag_gvg(sd->bl.m) && ((item->flag.no_equip&2) || !pc_isAllowedCardOn(sd,item->slot,n,2)))
-		return 0; 
 	if(map[sd->bl.m].flag.restricted)
 	{
-		int flag =map[sd->bl.m].zone;
+		int flag =8*map[sd->bl.m].zone;
 		if (item->flag.no_equip&flag || !pc_isAllowedCardOn(sd,item->slot,n,flag))
 			return 0;
 	}
@@ -1608,7 +1570,8 @@ static int pc_bonus_item_drop(struct s_add_drop *drop, const short max, short id
 	for(i = 0; i < max && (drop[i].id || drop[i].group); i++) {
 		if(
 			((id && drop[i].id == id) ||
-			(group && drop[i].group == group)) && race < (1<<RC_MAX)
+			(group && drop[i].group == group)) 
+			&& race > 0
 		) {
 			drop[i].race |= race;
 			if(drop[i].rate > 0 && rate > 0)
@@ -2884,7 +2847,7 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
 		break;
 	case SP_ADD_CLASS_DROP_ITEM:
 		if(sd->state.lr_flag != 2)
-			pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, type3, val);
+			pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, -type3, val);
 		break;
 	case SP_AUTOSPELL:
 		if(sd->state.lr_flag != 2)
@@ -3731,6 +3694,11 @@ int pc_isUseitem(struct map_session_data *sd,int n)
 			if( nameid == 12243 && sd->md->db->lv < 80 )
 				return 0;
 			break;
+
+		case 12213: //Neuralizer
+			if( !map[sd->bl.m].flag.reset )
+				return 0;
+			break;
 	}
 
 	if( nameid >= 12153 && nameid <= 12182 && sd->md != NULL )
@@ -3738,9 +3706,11 @@ int pc_isUseitem(struct map_session_data *sd,int n)
 
 	//added item_noequip.txt items check by Maya&[Lupus]
 	if (
-		(map[sd->bl.m].flag.pvp && item->flag.no_equip&1) || // PVP
-		(map_flag_gvg(sd->bl.m) && item->flag.no_equip&2) || // GVG
-		(map[sd->bl.m].flag.restricted && item->flag.no_equip&map[sd->bl.m].zone) // Zone restriction
+		(!map_flag_vs(sd->bl.m) && item->flag.no_equip&1) || // Normal
+		(map[sd->bl.m].flag.pvp && item->flag.no_equip&2) || // PVP
+		(map_flag_gvg(sd->bl.m) && item->flag.no_equip&4) || // GVG
+		(map[sd->bl.m].flag.battleground && item->flag.no_equip&8) || // Battleground
+		(map[sd->bl.m].flag.restricted && item->flag.no_equip&(8*map[sd->bl.m].zone)) // Zone restriction
 	)
 		return 0;
 
@@ -7444,7 +7414,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
 	pos = pc_equippoint(sd,n); //With a few exceptions, item should go in all specified slots.
 
 	if(battle_config.battle_log)
-		ShowInfo("equip %d(%d) %x:%x\n",sd->status.inventory[n].nameid,n,id->equip,req_pos);
+		ShowInfo("equip %d(%d) %x:%x\n",sd->status.inventory[n].nameid,n,id?id->equip:0,req_pos);
 	if(!pc_isequip(sd,n) || !(pos&req_pos) || sd->status.inventory[n].equip != 0 || sd->status.inventory[n].attribute==1 ) { // [Valaris]
 		clif_equipitemack(sd,n,0,0);	// fail
 		return 0;
@@ -7752,9 +7722,11 @@ int pc_checkitem(struct map_session_data *sd)
 		if( it )
 		{ // check for forbiden items.
 			int flag =
-					(map[sd->bl.m].flag.restricted?map[sd->bl.m].zone:0)
-					| (map[sd->bl.m].flag.pvp?1:0)
-					| (map_flag_gvg(sd->bl.m)?2:0);
+					(map[sd->bl.m].flag.restricted?(8*map[sd->bl.m].zone):0)
+					| (!map_flag_vs(sd->bl.m)?1:0)
+					| (map[sd->bl.m].flag.pvp?2:0)
+					| (map_flag_gvg(sd->bl.m)?4:0)
+					| (map[sd->bl.m].flag.battleground?8:0);
 			if( flag && (it->flag.no_equip&flag || !pc_isAllowedCardOn(sd,it->slot,i,flag)) )
 			{
 				pc_unequipitem(sd, i, 2);

+ 0 - 2
src/map/pc.h

@@ -10,7 +10,6 @@
 #include "buyingstore.h"  // struct s_buyingstore
 #include "itemdb.h" // MAX_ITEMGROUP
 #include "map.h" // RC_MAX
-#include "pc.h" // struct map_session_data
 #include "script.h" // struct script_reg, struct script_regstr
 #include "searchstore.h"  // struct s_search_store_info
 #include "status.h" // OPTION_*, struct weapon_atk
@@ -102,7 +101,6 @@ struct map_session_data {
 		unsigned int lr_flag : 2;
 		unsigned int connect_new : 1;
 		unsigned int arrow_atk : 1;
-		unsigned int combo : 2; // 1:Asura, 2:Kick [Inkfish]
 		unsigned int gangsterparadise : 1;
 		unsigned int rest : 1;
 		unsigned int storage_flag : 2; //0: closed, 1: Normal Storage open, 2: guild storage open [Skotlex]

+ 46 - 27
src/map/script.c

@@ -348,7 +348,8 @@ enum {
 	MF_ALLOWKS,
 	MF_MONSTER_NOTELEPORT,
 	MF_PVP_NOCALCRANK,	//50
-	MF_BATTLEGROUND
+	MF_BATTLEGROUND,
+	MF_RESET
 };
 
 const char* script_op2name(int op)
@@ -901,7 +902,7 @@ int add_word(const char* p)
 		disp_error_message("script:add_word: invalid word. A word consists of undercores and/or alfanumeric characters, and valid variable prefixes/postfixes.", p);
 
 	// Duplicate the word
-	word = aMalloc(len+1);
+	word = (char*)aMalloc(len+1);
 	memcpy(word, p, len);
 	word[len] = 0;
 	
@@ -4559,7 +4560,7 @@ BUILDIN_FUNC(warpparty)
 	struct party_data* p;
 	int type;
 	int mapindex;
-	int i, j;
+	int i;
 
 	const char* str = script_getstr(st,2);
 	int x = script_getnum(st,3);
@@ -4579,9 +4580,27 @@ BUILDIN_FUNC(warpparty)
 		 : ( strcmp(str,"Leader")==0 ) ? 3
 		 : 4;
 
-	if( type == 2 && ( sd = script_rid2sd(st) ) == NULL )
-	{// "SavePoint" uses save point of the currently attached player
-		return 0;
+	switch (type)
+	{
+	case 3:
+		for(i = 0; i < MAX_PARTY && !p->party.member[i].leader; i++);
+		if (i == MAX_PARTY || !p->data[i].sd) //Leader not found / not online
+			return 0;
+		pl_sd = p->data[i].sd;
+		mapindex = pl_sd->mapindex;
+		x = pl_sd->bl.x;
+		y = pl_sd->bl.y;
+		break;
+	case 4:
+		mapindex = mapindex_name2id(str);
+		break;
+	case 2:
+		//"SavePoint" uses save point of the currently attached player
+		if (( sd = script_rid2sd(st) ) == NULL )
+			return 0;
+	default:
+		mapindex = 0;
+		break;
 	}
 
 	for (i = 0; i < MAX_PARTY; i++)
@@ -4610,25 +4629,9 @@ BUILDIN_FUNC(warpparty)
 				pc_setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
 		break;
 		case 3: // Leader
-			for(j = 0; j < MAX_PARTY && !p->party.member[j].leader; j++);
-			if (j == MAX_PARTY || !p->data[j].sd) //Leader not found / not online
-				return 0;
-			mapindex = p->data[j].sd->mapindex;
-			x = p->data[j].sd->bl.x;
-			y = p->data[j].sd->bl.y;
-			for (j = 0; j < MAX_PARTY; j++)
-			{
-				pl_sd = p->data[j].sd;
-				if (!pl_sd)
-					continue;
-				if(map[pl_sd->bl.m].flag.noreturn || map[pl_sd->bl.m].flag.nowarp)
-					continue;
-				pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
-			}
-		break;
 		case 4: // m,x,y
 			if(!map[pl_sd->bl.m].flag.noreturn && !map[pl_sd->bl.m].flag.nowarp) 
-				pc_setpos(pl_sd,mapindex_name2id(str),x,y,CLR_TELEPORT);
+				pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
 		break;
 		}
 	}
@@ -5568,8 +5571,8 @@ BUILDIN_FUNC(checkweight)
 }
 
 /*==========================================
- * getitem <item id>,<amount>{,<character ID>};
- * getitem "<item name>",<amount>{,<character ID>};
+ * getitem <item id>,<amount>{,<account ID>};
+ * getitem "<item name>",<amount>{,<account ID>};
  *------------------------------------------*/
 BUILDIN_FUNC(getitem)
 {
@@ -6574,6 +6577,9 @@ BUILDIN_FUNC(strnpcinfo)
 		case 3: // unique name
 			name = aStrdup(nd->exname);
 			break;
+		case 4: // map name
+			name = aStrdup(map[nd->bl.m].name);
+			break;
 	}
 
 	if(name)
@@ -9628,6 +9634,7 @@ BUILDIN_FUNC(getmapflag)
 			case MF_MONSTER_NOTELEPORT:	script_pushint(st,map[m].flag.monster_noteleport); break;
 			case MF_PVP_NOCALCRANK:		script_pushint(st,map[m].flag.pvp_nocalcrank); break;
 			case MF_BATTLEGROUND:		script_pushint(st,map[m].flag.battleground); break;
+			case MF_RESET:			script_pushint(st,map[m].flag.reset); break;
 		}
 	}
 
@@ -9697,6 +9704,7 @@ BUILDIN_FUNC(setmapflag)
 			case MF_MONSTER_NOTELEPORT:	map[m].flag.monster_noteleport=1; break;
 			case MF_PVP_NOCALCRANK:		map[m].flag.pvp_nocalcrank=1; break;
 			case MF_BATTLEGROUND:		map[m].flag.battleground = (!val || atoi(val) < 0 || atoi(val) > 2) ? 1 : atoi(val); break;
+			case MF_RESET:			map[m].flag.reset=1; break;
 		}
 	}
 
@@ -9763,6 +9771,7 @@ BUILDIN_FUNC(removemapflag)
 			case MF_MONSTER_NOTELEPORT:	map[m].flag.monster_noteleport=0; break;
 			case MF_PVP_NOCALCRANK:		map[m].flag.pvp_nocalcrank=0; break;
 			case MF_BATTLEGROUND:		map[m].flag.battleground=0; break;
+			case MF_RESET:			map[m].flag.reset=0; break;
 		}
 	}
 
@@ -13448,13 +13457,23 @@ BUILDIN_FUNC(unitwarp)
 	short x;
 	short y;
 	struct block_list* bl;
+	const char *mapname;
 
 	unit_id = script_getnum(st,2);
-	map = map_mapname2mapid(script_getstr(st, 3));
+	mapname = script_getstr(st, 3);
 	x = (short)script_getnum(st,4);
 	y = (short)script_getnum(st,5);
+	
+	if (!unit_id) //Warp the script's runner
+		bl = map_id2bl(st->rid);
+	else
+		bl = map_id2bl(unit_id);
+
+	if( strcmp(mapname,"this") == 0 )
+		map = bl?bl->m:-1;
+	else
+		map = map_mapname2mapid(mapname);
 
-	bl = map_id2bl(unit_id);
 	if( map >= 0 && bl != NULL )
 		script_pushint(st, unit_warp(bl,map,x,y,CLR_OUTSIGHT));
 	else

+ 2 - 2
src/map/searchstore.c

@@ -184,7 +184,7 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
 	searchstore_clear(sd);
 
 	// allocate max. amount of results
-	sd->searchstore.items = aMalloc(sizeof(struct s_search_store_info_item)*battle_config.searchstore_maxresults);
+	sd->searchstore.items = (struct s_search_store_info_item*)aMalloc(sizeof(struct s_search_store_info_item)*battle_config.searchstore_maxresults);
 
 	// search
 	s.search_sd  = sd;
@@ -215,7 +215,7 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
 	if( sd->searchstore.count )
 	{
 		// reclaim unused memory
-		sd->searchstore.items = aRealloc(sd->searchstore.items, sizeof(struct s_search_store_info_item)*sd->searchstore.count);
+		sd->searchstore.items = (struct s_search_store_info_item*)aRealloc(sd->searchstore.items, sizeof(struct s_search_store_info_item)*sd->searchstore.count);
 
 		// present results
 		clif_search_store_info_ack(sd);

+ 44 - 46
src/map/skill.c

@@ -270,8 +270,8 @@ int skill_get_range2 (struct block_list *bl, int id, int lv)
 int skill_calc_heal(struct block_list *src, struct block_list *target, int skill_id, int skill_lv, bool heal)
 {
 	int skill, hp, mod = 100;
-	struct map_session_data *sd = map_id2sd(src->id);
-	struct map_session_data *tsd = map_id2sd(target->id);
+	struct map_session_data *sd = BL_CAST(BL_PC, src);
+	struct map_session_data *tsd = BL_CAST(BL_PC, target);
 	struct status_change* sc;
 	struct status_data *status;
 	bool FullCalc = false;
@@ -1067,8 +1067,9 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 
 			tbl = (sd->autospell[i].id < 0) ? src : bl;
 
-			if( !battle_check_range(src, tbl, skill_get_range2(src, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)) && battle_config.autospell_check_range )
-				continue; // If autospell_check_range is yes, fail the autocast.
+			if( battle_config.autospell_check_range &&
+				!battle_check_range(src, tbl, skill_get_range2(src, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)) )
+				continue;
 
 			if (skill == AS_SONICBLOW)
 				pc_stop_attack(sd); //Special case, Sonic Blow autospell should stop the player attacking.
@@ -1172,7 +1173,8 @@ int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, int s
 			continue;
 		tbl = (sd->autospell3[i].id < 0) ? &sd->bl : bl;
 
-		if( !battle_check_range(&sd->bl, tbl, skill_get_range2(&sd->bl, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)) && battle_config.autospell_check_range )
+		if( battle_config.autospell_check_range &&
+			!battle_check_range(&sd->bl, tbl, skill_get_range2(&sd->bl, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)) )
 			continue;
 
 		sd->state.autocast = 1;
@@ -1699,13 +1701,10 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 
 			//Spirit of Wizard blocks Kaite's reflection
 			if( type == 2 && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD )
-			{	//Consume one Fragment per hit of the casted skill. Val3 is the skill id and val4 is the ID of the damage src.
-				//This should account for ground spells (and single target spells will be completed on castend_id) [Skotlex]
-			  	type = pc_search_inventory (tsd, 7321);
-				if (type >= 0)
-					pc_delitem(tsd, type, 1, 0, 1);
-
+			{	//Consume one Fragment per hit of the casted skill? [Skotlex]
+			  	type = tsd?pc_search_inventory (tsd, 7321):0;
 				if (type >= 0) {
+					if ( tsd ) pc_delitem(tsd, type, 1, 0, 1);
 					dmg.damage = dmg.damage2 = 0;
 					dmg.dmg_lv = ATK_MISS;
 					sc->data[SC_SPIRIT]->val3 = skillid;
@@ -1757,7 +1756,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 
 	if(sd) {
 		int flag = 0; //Used to signal if this skill can be combo'ed later on.
-		if (sd->sc.data[SC_COMBO])
+		struct status_change_entry *sce;
+		if ((sce = sd->sc.data[SC_COMBO]))
 		{	//End combo state after skill is invoked. [Skotlex]
 			switch (skillid) {
 			case TK_TURNKICK:
@@ -1766,13 +1766,10 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 			case TK_COUNTER:
 				if (pc_famerank(sd->status.char_id,MAPID_TAEKWON))
 			  	{	//Extend combo time.
-					sd->skillid_old = skillid; //Set as previous so you can't repeat
-					sd->skilllv_old = skilllv;
-					sd->sc.data[SC_COMBO]->val1 = skillid; //Update combo-skill
-					delete_timer(sd->sc.data[SC_COMBO]->timer, status_change_timer);
-					sd->sc.data[SC_COMBO]->timer = add_timer(
-						tick+sd->sc.data[SC_COMBO]->val4,
-					  	status_change_timer, src->id, SC_COMBO);
+					sce->val1 = skillid; //Update combo-skill
+					sce->val3 = skillid;
+					delete_timer(sce->timer, status_change_timer);
+					sce->timer = add_timer(tick+sce->val4, status_change_timer, src->id, SC_COMBO);
 					break;
 				}
 				unit_cancel_combo(src); // Cancel combo wait
@@ -1808,7 +1805,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 				if( (tstatus->race == RC_BRUTE || tstatus->race == RC_INSECT) && pc_checkskill(sd, HT_POWER))
 				{
 					//TODO: This code was taken from Triple Blows, is this even how it should be? [Skotlex]
-					sc_start4(src,SC_COMBO,100,HT_POWER,bl->id,0,0,2000);
+					sc_start2(src,SC_COMBO,100,HT_POWER,bl->id,2000);
 					clif_combo_delay(src,2000);
 				}
 				break;
@@ -1831,9 +1828,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 		}	//Switch End
 		if (flag) { //Possible to chain
 			flag = DIFF_TICK(sd->ud.canact_tick, tick);
-			if (flag < 0) flag = 0;
-			flag += 300 * battle_config.combo_delay_rate/100;
-			sc_start(src,SC_COMBO,100,skillid,flag);
+			if (flag < 1) flag = 1;
+			sc_start2(src,SC_COMBO,100,skillid,bl->id,flag);
 			clif_combo_delay(src, flag);
 		}
 	}
@@ -3337,7 +3333,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 			break;
 		{
 			int per = 0, sper = 0;
-			if (status_get_sc(bl)->data[SC_HELLPOWER])
+			if (tsc && tsc->data[SC_HELLPOWER])
 				break;
 
 			if (map[bl->m].flag.pvp && dstsd && dstsd->pvp_point < 0)
@@ -3385,7 +3381,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 
 	case AL_CRUCIS:
 		if (flag&1)
-			sc_start(bl,type, 23+skilllv*4 +status_get_lv(src) -status_get_lv(bl), skilllv,60000);
+			sc_start(bl,type, 23+skilllv*4 +status_get_lv(src) -status_get_lv(bl), skilllv,skill_get_time(skillid,skilllv));
 		else {
 			map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid, skilllv), BL_CHAR,
 				src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
@@ -3470,7 +3466,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 				break;
 			heal = status_percent_heal(bl, 100, 0);
 			clif_skill_nodamage(NULL, bl, AL_HEAL, heal, 1);
-			if( skillid == NPC_ALLHEAL && dstmd )
+			if( dstmd )
 			{ // Reset Damage Logs
 				memset(dstmd->dmglog, 0, sizeof(dstmd->dmglog));
 				dstmd->tdmg = 0;
@@ -3936,7 +3932,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 				mer->devotion_flag = 1; // Mercenary Devoting Owner
 
 			clif_skill_nodamage(src, bl, skillid, skilllv,
-				sc_start4(bl, type, 100, src->id, i, skill_get_range2(src,skillid,skilllv), skill_get_time2(skillid, skilllv), 1000));
+				sc_start4(bl, type, 100, src->id, i, skill_get_range2(src,skillid,skilllv),0, skill_get_time2(skillid, skilllv)));
 			clif_devotion(src, NULL);
 		}
 		break;
@@ -6479,7 +6475,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
 	case SA_VIOLENTGALE:
 	{	//Does not consumes if the skill is already active. [Skotlex]
 		struct skill_unit_group *sg;
-		if ((sg= skill_locate_element_field(&sd->bl)) != NULL && ( sg->skill_id == SA_VOLCANO || sg->skill_id == SA_DELUGE || sg->skill_id == SA_VIOLENTGALE ))
+		if ((sg= skill_locate_element_field(src)) != NULL && ( sg->skill_id == SA_VOLCANO || sg->skill_id == SA_DELUGE || sg->skill_id == SA_VIOLENTGALE ))
 		{
 			if (sg->limit - DIFF_TICK(gettick(), sg->tick) > 0)
 			{
@@ -6697,7 +6693,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
 			}
 		} else {
 			int i = skilllv%11 - 1;
-			struct item_data *item = itemdb_search(i);
+			struct item_data *item;
 			i = skill_db[skillid].itemid[i];
 			item = itemdb_search(i);
 			potion_flag = 1;
@@ -8566,7 +8562,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
 	require = skill_get_requirement(sd,skill,lv);
 
 	//Can only update state when weapon/arrow info is checked.
-	if (require.weapon) sd->state.arrow_atk = require.ammo?1:0;
+	sd->state.arrow_atk = require.ammo?1:0;
 
 	// perform skill-specific checks (and actions)
 	switch( skill )
@@ -8669,14 +8665,14 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
 			return 0; //Anti-Soul Linker check in case you job-changed with Stances active.
 		if(!(sc && sc->data[SC_COMBO]))
 			return 0; //Combo needs to be ready
-		if (pc_famerank(sd->status.char_id,MAPID_TAEKWON))
-		{	//Unlimited Combo
-			if (skill == sd->skillid_old) {
-				status_change_end(&sd->bl, SC_COMBO, INVALID_TIMER);
-				sd->skillid_old = sd->skilllv_old = 0;
-				return 0; //Can't repeat previous combo skill.
-			}
-			break;
+
+		if (sc->data[SC_COMBO]->val3)
+		{	//Kick chain
+			//Do not repeat a kick.
+			if (sc->data[SC_COMBO]->val3 != skill)
+				break;
+			status_change_end(&sd->bl, SC_COMBO, INVALID_TIMER);
+			return 0;
 		}
 		if(sc->data[SC_COMBO]->val1 != skill)
 		{	//Cancel combo wait.
@@ -8696,7 +8692,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
 			if (skill_get_time(
 				(sc->data[SC_DANCING]->val1&0xFFFF), //Dance Skill ID
 				(sc->data[SC_DANCING]->val1>>16)) //Dance Skill LV
-				- time <= skill_get_time2(skill,lv))
+				- time < skill_get_time2(skill,lv))
 			{
 				clif_skill_fail(sd,skill,0,0);
 				return 0;
@@ -9256,9 +9252,11 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, short
 
 	req.weapon = skill_db[j].weapon;
 
-	req.ammo = skill_db[j].ammo;
 	req.ammo_qty = skill_db[j].ammo_qty[lv-1];
-	if (req.weapon && !req.ammo && skill && skill_isammotype(sd, skill))
+	if (req.ammo_qty)
+		req.ammo = skill_db[j].ammo;
+
+	if (!req.ammo && skill && skill_isammotype(sd, skill))
 	{	//Assume this skill is using the weapon, therefore it requires arrows.
 		req.ammo = 0xFFFFFFFF; //Enable use on all ammo types.
 		req.ammo_qty = 1;
@@ -12088,9 +12086,9 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
 	for( j = 0; j < 32; j++ )
 	{
 		int l = atoi(p);
-		if( l == 99 ) // magic value?
+		if( l == 99 ) // Any weapon
 		{
-			skill_db[i].weapon = 0xffffffff;
+			skill_db[i].weapon = 0;
 			break;
 		}
 		else
@@ -12106,12 +12104,12 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
 	for( j = 0; j < 32; j++ )
 	{
 		int l = atoi(p);
-		if( l == 99 ) // magic value?
+		if( l == 99 ) // Any ammo type
 		{
-			skill_db[i].ammo = 0xffffffff;
+			skill_db[i].ammo = 0xFFFFFFFF;
 			break;
 		}
-		else if( l ) // 0 not allowed?
+		else if( l ) // 0 stands for no requirement
 			skill_db[i].ammo |= 1<<l;
 		p = strchr(p,':');
 		if( !p )

+ 82 - 84
src/map/sql/CMakeLists.txt

@@ -2,90 +2,92 @@
 #
 # map sql
 #
-if( HAVE_common_sql )
+if( BUILD_SQL_SERVERS )
 message( STATUS "Creating target map-server_sql" )
 set( SQL_MAP_HEADERS
-	"${MAP_SOURCE_DIR}/atcommand.h"
-	"${MAP_SOURCE_DIR}/battle.h"
-	"${MAP_SOURCE_DIR}/battleground.h"
-	"${MAP_SOURCE_DIR}/buyingstore.h"
-	"${MAP_SOURCE_DIR}/chat.h"
-	"${MAP_SOURCE_DIR}/chrif.h"
-	"${MAP_SOURCE_DIR}/clif.h"
-	"${MAP_SOURCE_DIR}/date.h"
-	"${MAP_SOURCE_DIR}/duel.h"
-	"${MAP_SOURCE_DIR}/guild.h"
-	"${MAP_SOURCE_DIR}/homunculus.h"
-	"${MAP_SOURCE_DIR}/instance.h"
-	"${MAP_SOURCE_DIR}/intif.h"
-	"${MAP_SOURCE_DIR}/itemdb.h"
-	"${MAP_SOURCE_DIR}/log.h"
-	"${MAP_SOURCE_DIR}/mail.h"
-	"${MAP_SOURCE_DIR}/map.h"
-	"${MAP_SOURCE_DIR}/mapreg.h"
-	"${MAP_SOURCE_DIR}/mercenary.h"
-	"${MAP_SOURCE_DIR}/mob.h"
-	"${MAP_SOURCE_DIR}/npc.h"
-	"${MAP_SOURCE_DIR}/party.h"
-	"${MAP_SOURCE_DIR}/path.h"
-	"${MAP_SOURCE_DIR}/pc.h"
-	"${MAP_SOURCE_DIR}/pet.h"
-	"${MAP_SOURCE_DIR}/quest.h"
-	"${MAP_SOURCE_DIR}/script.h"
-	"${MAP_SOURCE_DIR}/searchstore.h"
-	"${MAP_SOURCE_DIR}/skill.h"
-	"${MAP_SOURCE_DIR}/status.h"
-	"${MAP_SOURCE_DIR}/storage.h"
-	"${MAP_SOURCE_DIR}/trade.h"
-	"${MAP_SOURCE_DIR}/unit.h"
-	"${MAP_SOURCE_DIR}/vending.h"
+	"${SQL_MAP_SOURCE_DIR}/atcommand.h"
+	"${SQL_MAP_SOURCE_DIR}/battle.h"
+	"${SQL_MAP_SOURCE_DIR}/battleground.h"
+	"${SQL_MAP_SOURCE_DIR}/buyingstore.h"
+	"${SQL_MAP_SOURCE_DIR}/chat.h"
+	"${SQL_MAP_SOURCE_DIR}/chrif.h"
+	"${SQL_MAP_SOURCE_DIR}/clif.h"
+	"${SQL_MAP_SOURCE_DIR}/date.h"
+	"${SQL_MAP_SOURCE_DIR}/duel.h"
+	"${SQL_MAP_SOURCE_DIR}/guild.h"
+	"${SQL_MAP_SOURCE_DIR}/homunculus.h"
+	"${SQL_MAP_SOURCE_DIR}/instance.h"
+	"${SQL_MAP_SOURCE_DIR}/intif.h"
+	"${SQL_MAP_SOURCE_DIR}/itemdb.h"
+	"${SQL_MAP_SOURCE_DIR}/log.h"
+	"${SQL_MAP_SOURCE_DIR}/mail.h"
+	"${SQL_MAP_SOURCE_DIR}/map.h"
+	"${SQL_MAP_SOURCE_DIR}/mapreg.h"
+	"${SQL_MAP_SOURCE_DIR}/mercenary.h"
+	"${SQL_MAP_SOURCE_DIR}/mob.h"
+	"${SQL_MAP_SOURCE_DIR}/npc.h"
+	"${SQL_MAP_SOURCE_DIR}/party.h"
+	"${SQL_MAP_SOURCE_DIR}/path.h"
+	"${SQL_MAP_SOURCE_DIR}/pc.h"
+	"${SQL_MAP_SOURCE_DIR}/pet.h"
+	"${SQL_MAP_SOURCE_DIR}/quest.h"
+	"${SQL_MAP_SOURCE_DIR}/script.h"
+	"${SQL_MAP_SOURCE_DIR}/searchstore.h"
+	"${SQL_MAP_SOURCE_DIR}/skill.h"
+	"${SQL_MAP_SOURCE_DIR}/status.h"
+	"${SQL_MAP_SOURCE_DIR}/storage.h"
+	"${SQL_MAP_SOURCE_DIR}/trade.h"
+	"${SQL_MAP_SOURCE_DIR}/unit.h"
+	"${SQL_MAP_SOURCE_DIR}/vending.h"
 	)
 set( SQL_MAP_SOURCES
-	"${MAP_SOURCE_DIR}/atcommand.c"
-	"${MAP_SOURCE_DIR}/battle.c"
-	"${MAP_SOURCE_DIR}/battleground.c"
-	"${MAP_SOURCE_DIR}/buyingstore.c"
-	"${MAP_SOURCE_DIR}/chat.c"
-	"${MAP_SOURCE_DIR}/chrif.c"
-	"${MAP_SOURCE_DIR}/clif.c"
-	"${MAP_SOURCE_DIR}/date.c"
-	"${MAP_SOURCE_DIR}/duel.c"
-	"${MAP_SOURCE_DIR}/guild.c"
-	"${MAP_SOURCE_DIR}/homunculus.c"
-	"${MAP_SOURCE_DIR}/instance.c"
-	"${MAP_SOURCE_DIR}/intif.c"
-	"${MAP_SOURCE_DIR}/itemdb.c"
-	"${MAP_SOURCE_DIR}/log.c"
-	"${MAP_SOURCE_DIR}/mail.c"
-	"${MAP_SOURCE_DIR}/map.c"
-	"${MAP_SOURCE_DIR}/mapreg_sql.c"
-	"${MAP_SOURCE_DIR}/mercenary.c"
-	"${MAP_SOURCE_DIR}/mob.c"
-	"${MAP_SOURCE_DIR}/npc.c"
-	"${MAP_SOURCE_DIR}/npc_chat.c"
-	"${MAP_SOURCE_DIR}/party.c"
-	"${MAP_SOURCE_DIR}/path.c"
-	"${MAP_SOURCE_DIR}/pc.c"
-	"${MAP_SOURCE_DIR}/pet.c"
-	"${MAP_SOURCE_DIR}/quest.c"
-	"${MAP_SOURCE_DIR}/script.c"
-	"${MAP_SOURCE_DIR}/searchstore.c"
-	"${MAP_SOURCE_DIR}/skill.c"
-	"${MAP_SOURCE_DIR}/status.c"
-	"${MAP_SOURCE_DIR}/storage.c"
-	"${MAP_SOURCE_DIR}/trade.c"
-	"${MAP_SOURCE_DIR}/unit.c"
-	"${MAP_SOURCE_DIR}/vending.c"
+	"${SQL_MAP_SOURCE_DIR}/atcommand.c"
+	"${SQL_MAP_SOURCE_DIR}/battle.c"
+	"${SQL_MAP_SOURCE_DIR}/battleground.c"
+	"${SQL_MAP_SOURCE_DIR}/buyingstore.c"
+	"${SQL_MAP_SOURCE_DIR}/chat.c"
+	"${SQL_MAP_SOURCE_DIR}/chrif.c"
+	"${SQL_MAP_SOURCE_DIR}/clif.c"
+	"${SQL_MAP_SOURCE_DIR}/date.c"
+	"${SQL_MAP_SOURCE_DIR}/duel.c"
+	"${SQL_MAP_SOURCE_DIR}/guild.c"
+	"${SQL_MAP_SOURCE_DIR}/homunculus.c"
+	"${SQL_MAP_SOURCE_DIR}/instance.c"
+	"${SQL_MAP_SOURCE_DIR}/intif.c"
+	"${SQL_MAP_SOURCE_DIR}/itemdb.c"
+	"${SQL_MAP_SOURCE_DIR}/log.c"
+	"${SQL_MAP_SOURCE_DIR}/mail.c"
+	"${SQL_MAP_SOURCE_DIR}/map.c"
+	"${SQL_MAP_SOURCE_DIR}/mapreg_sql.c"
+	"${SQL_MAP_SOURCE_DIR}/mercenary.c"
+	"${SQL_MAP_SOURCE_DIR}/mob.c"
+	"${SQL_MAP_SOURCE_DIR}/npc.c"
+	"${SQL_MAP_SOURCE_DIR}/npc_chat.c"
+	"${SQL_MAP_SOURCE_DIR}/party.c"
+	"${SQL_MAP_SOURCE_DIR}/path.c"
+	"${SQL_MAP_SOURCE_DIR}/pc.c"
+	"${SQL_MAP_SOURCE_DIR}/pet.c"
+	"${SQL_MAP_SOURCE_DIR}/quest.c"
+	"${SQL_MAP_SOURCE_DIR}/script.c"
+	"${SQL_MAP_SOURCE_DIR}/searchstore.c"
+	"${SQL_MAP_SOURCE_DIR}/skill.c"
+	"${SQL_MAP_SOURCE_DIR}/status.c"
+	"${SQL_MAP_SOURCE_DIR}/storage.c"
+	"${SQL_MAP_SOURCE_DIR}/trade.c"
+	"${SQL_MAP_SOURCE_DIR}/unit.c"
+	"${SQL_MAP_SOURCE_DIR}/vending.c"
 	)
 set( DEPENDENCIES common_sql )
 set( LIBRARIES ${GLOBAL_LIBRARIES} )
 set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS}" )
 if( WITH_PCRE )
-	message( STATUS "Using PCRE" )
-	list( APPEND LIBRARIES ${PCRE_LIBRARIES} )
-	list( APPEND INCLUDE_DIRS ${PCRE_INCLUDE_DIRS} )
-	list( APPEND DEFINITIONS PCRE_SUPPORT )
+	message( STATUS "Enabled PCRE code" )
+	set( LIBRARIES ${LIBRARIES} ${PCRE_LIBRARIES} )
+	set( INCLUDE_DIRS ${INCLUDE_DIRS} ${PCRE_INCLUDE_DIRS} )
+	set( DEFINITIONS "${DEFINITIONS} -DPCRE_SUPPORT" )
+else()
+	message( STATUS "Disabled PCRE code" )
 endif()
 set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} ${SQL_MAP_HEADERS} ${SQL_MAP_SOURCES} )
 source_group( common FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} )
@@ -94,17 +96,13 @@ include_directories( ${INCLUDE_DIRS} )
 add_executable( map-server_sql ${SOURCE_FILES} )
 add_dependencies( map-server_sql ${DEPENDENCIES} )
 target_link_libraries( map-server_sql ${LIBRARIES} ${DEPENDENCIES} )
-set_target_properties( map-server_sql PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
-if( WITH_COMPONENT_RUNTIME )
+set_target_properties( map-server_sql PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+if( INSTALL_COMPONENT_RUNTIME )
 	cpack_add_component( Runtime_mapserver_sql DESCRIPTION "map-server (sql version)" DISPLAY_NAME "map-server_sql" GROUP Runtime )
 	install( TARGETS map-server_sql
 		DESTINATION "."
 		COMPONENT Runtime_mapserver_sql )
-endif()
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} map-server_sql  CACHE INTERNAL "" )
 message( STATUS "Creating target map-server_sql - done" )
-set( HAVE_map-server_sql ON  CACHE BOOL "map-server_sql target is available" )
-mark_as_advanced( HAVE_map-server_sql )
-else()
-message( STATUS "Skipping target map-server_sql (requires common_sql; optional PCRE)" )
-unset( HAVE_map-server_sql CACHE )
-endif()
+endif( BUILD_SQL_SERVERS )

+ 87 - 91
src/map/status.c

@@ -673,7 +673,7 @@ int status_charge(struct block_list* bl, int hp, int sp)
 //If flag&1, damage is passive and does not triggers cancelling status changes.
 //If flag&2, fail if target does not has enough to substract.
 //If flag&4, if killed, mob must not give exp/loot.
-//If flag&8, sp loss on dead target.
+//flag will be set to &8 when damaging sp of a dead character
 int status_damage(struct block_list *src,struct block_list *target,int hp, int sp, int walkdelay, int flag)
 {
 	struct status_data *status;
@@ -683,18 +683,15 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 		sp = 0; //Not a valid SP target.
 
 	if (hp < 0) { //Assume absorbed damage.
-		status_heal(target, cap_value(-hp, INT_MIN, INT_MAX), 0, 1);
+		status_heal(target, -hp, 0, 1);
 		hp = 0;
 	}
 
 	if (sp < 0) {
-		status_heal(target, 0, cap_value(-sp, INT_MIN, INT_MAX), 1);
+		status_heal(target, 0, -sp, 1);
 		sp = 0;
 	}
 
-	if (!hp && !sp)
-		return 0;
-
 	if (target->type == BL_SKILL)
 		return skill_unit_ondamaged((struct skill_unit *)target, src, hp, gettick());
 
@@ -702,6 +699,19 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 	if( status == &dummy_status )
 		return 0;
 
+	if ((unsigned int)hp >= status->hp) {
+		if (flag&2) return 0;
+		hp = status->hp;
+	}
+
+	if ((unsigned int)sp > status->sp) {
+		if (flag&2) return 0;
+		sp = status->sp;
+	}
+
+	if (!hp && !sp)
+		return 0;
+
 	if( !status->hp )
 		flag |= 8;
 
@@ -711,10 +721,10 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 //		return 0; //Cannot damage a bl not on a map, except when "charging" hp/sp
 
 	sc = status_get_sc(target);
-	if( battle_config.invincible_nodamage && src && sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
+	if( hp && battle_config.invincible_nodamage && src && sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
 		hp = 1;
 
-	if( hp && !(flag&(1|8)) ) {
+	if( hp && !(flag&1) ) {
 		if( sc ) {
 			struct status_change_entry *sce;
 			if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
@@ -748,16 +758,6 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 		unit_skillcastcancel(target, 2);
 	}
 
-	if ((unsigned int)hp >= status->hp) {
-		if (flag&2) return 0;
-		hp = status->hp;
-	}
-
-	if ((unsigned int)sp > status->sp) {
-		if (flag&2) return 0;
-		sp = status->sp;
-	}
-
 	status->hp-= hp;
 	status->sp-= sp;
 
@@ -778,7 +778,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 		case BL_MER: mercenary_damage((TBL_MER*)target,src,hp,sp); break;
 	}
 
-	if( status->hp || flag&8 )
+	if( status->hp || (flag&8) )
   	{	//Still lives or has been dead before this damage.
 		if (walkdelay)
 			unit_set_walkdelay(target, gettick(), walkdelay, 0);
@@ -822,11 +822,11 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 		}
 	}
    
-	if( !(flag&8) && sc && sc->data[SC_KAIZEL] )
+	if( sc && sc->data[SC_KAIZEL] )
 	{ //flag&8 = disable Kaizel
 		int time = skill_get_time2(SL_KAIZEL,sc->data[SC_KAIZEL]->val1);
 		//Look for Osiris Card's bonus effect on the character and revive 100% or revive normally
-		if ( target->type == BL_PC && BL_CAST(BL_PC,target)->special_state.restart_full_recover == 1 )
+		if ( target->type == BL_PC && BL_CAST(BL_PC,target)->special_state.restart_full_recover )
 			status_revive(target, 100, 100);
 		else
 			status_revive(target, sc->data[SC_KAIZEL]->val2, 0);
@@ -886,7 +886,8 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
 		sc = NULL;
 
 	if (hp < 0) {
-		status_damage(NULL, bl, cap_value(-hp, INT_MIN, INT_MAX), 0, 0, 1);
+		if (hp == INT_MIN) hp++; //-INT_MIN == INT_MIN in some architectures!
+		status_damage(NULL, bl, -hp, 0, 0, 1);
 		hp = 0;
 	}
 
@@ -899,7 +900,8 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
 	}
 
 	if(sp < 0) {
-		status_damage(NULL, bl, 0, cap_value(-sp, INT_MIN, INT_MAX), 0, 1);
+		if (sp==INT_MIN) sp++;
+		status_damage(NULL, bl, 0, -sp, 0, 1);
 		sp = 0;
 	}
 
@@ -1539,19 +1541,14 @@ int status_calc_mob_(struct mob_data* md, bool first)
 		gc=guild_mapname2gc(map[md->bl.m].name);
 		if (!gc)
 			ShowError("status_calc_mob: No castle set at map %s\n", map[md->bl.m].name);
-		else {
-			if(gc->castle_id > 23) {
-				if(md->class_ == MOBID_EMPERIUM) {
-					status->max_hp += 1000 * gc->defense;
-					status->max_sp += 200 * gc->defense;
-					status->hp = status->max_hp;
-					status->sp = status->max_sp;
-				}
-			}else{
-				status->max_hp += 1000 * gc->defense;
-				status->max_sp += 200 * gc->defense;
-				status->hp = status->max_hp;
-				status->sp = status->max_sp;
+		else
+		if(gc->castle_id < 24 || md->class_ == MOBID_EMPERIUM) {
+			status->max_hp += 1000 * gc->defense;
+			status->max_sp += 200 * gc->defense;
+			status->hp = status->max_hp;
+			status->sp = status->max_sp;
+			if( gc->castle_id < 24 )
+			{
 				status->def += (gc->defense+2)/3;
 				status->mdef += (gc->defense+2)/3;
 			}
@@ -2034,11 +2031,15 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
 				if(!data->script)
 					continue;
 				if(data->flag.no_equip) { //Card restriction checks.
-					if(map[sd->bl.m].flag.restricted && data->flag.no_equip&map[sd->bl.m].zone)
+					if(map[sd->bl.m].flag.restricted && data->flag.no_equip&(8*map[sd->bl.m].zone))
+						continue;
+					if(!map_flag_vs(sd->bl.m) && data->flag.no_equip&1)
+						continue;
+					if(map[sd->bl.m].flag.pvp && data->flag.no_equip&2)
 						continue;
-					if(map[sd->bl.m].flag.pvp && data->flag.no_equip&1)
+					if(map_flag_gvg(sd->bl.m) && data->flag.no_equip&4) 
 						continue;
-					if(map_flag_gvg(sd->bl.m) && data->flag.no_equip&2) 
+					if(map[sd->bl.m].flag.battleground && data->flag.no_equip&8)
 						continue;
 				}
 				if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L)
@@ -2466,6 +2467,11 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
 	status_cpy(&sd->battle_status, status);
 
 // ----- CLIENT-SIDE REFRESH -----
+	if(!sd->bl.prev) {
+		//Will update on LoadEndAck
+		calculating = 0;
+		return 0;
+	}
 	if(memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill)))
 		clif_skillinfoblock(sd);
 	if(b_weight != sd->weight)
@@ -2740,7 +2746,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
 	if (
 		sc->data[SC_DANCING]
 		|| (
-			(((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK &&
+			(bl->type == BL_PC && ((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK &&
 			(sc->data[SC_EXTREMITYFIST] || (sc->data[SC_EXPLOSIONSPIRITS] && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK)))
 			)
 		|| sc->data[SC_MAXIMIZEPOWER]
@@ -2773,7 +2779,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
 
 /// Recalculates parts of an object's battle status according to the specified flags.
 /// @param flag bitfield of values from enum scb_flag
-void status_calc_bl_main(struct block_list *bl, enum scb_flag flag)
+void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
 {
 	const struct status_data *b_status = status_get_base_status(bl);
 	struct status_data *status = status_get_status_data(bl);
@@ -5897,44 +5903,17 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 			//val1: Skill ID
 			//val2: When given, target (for autotargetting skills)
 			//val3: When set, this combo time should NOT delay attack/movement
-			//val4: Combo time
+			//val3: TK: Last used kick
+			//val4: TK: Combo time
 			struct unit_data *ud = unit_bl2ud(bl);
-			switch (val1) {
-				case TK_STORMKICK:
-					clif_skill_nodamage(bl,bl,TK_READYSTORM,1,1);
-					break;
-				case TK_DOWNKICK:
-					clif_skill_nodamage(bl,bl,TK_READYDOWN,1,1);
-					break;
-				case TK_TURNKICK:
-					clif_skill_nodamage(bl,bl,TK_READYTURN,1,1);
-					break;
-				case TK_COUNTER:
-					clif_skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
-					break;
-				case MO_COMBOFINISH:
-				case CH_TIGERFIST:
-				case CH_CHAINCRUSH:
-					if( sd )
-					{
-						sd->state.combo = 1;
-						clif_skillinfoblock(sd);
-					}
-					break;
-				case TK_JUMPKICK:
-					if( sd )
-					{
-						sd->state.combo = 2;
-						clif_skillinfoblock(sd);
-					}
-					break;		
-			}
 			if (ud && !val3) 
 			{
+				tick += 300 * battle_config.combo_delay_rate/100;
 				ud->attackabletime = gettick()+tick;
 				unit_set_walkdelay(bl, gettick(), tick, 1);
 			}
-			val4 = tick; //Store combo-time in val4.
+			val3 = 0;
+			val4 = tick;
 		}
 			break;
 		case SC_EARTHSCROLL:
@@ -6498,6 +6477,31 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 		case SC_MERC_SPUP:
 			status_percent_heal(bl, 0, 100); // Recover Full SP
 			break;
+		case SC_COMBO:
+			switch (sce->val1) {
+				case TK_STORMKICK:
+					clif_skill_nodamage(bl,bl,TK_READYSTORM,1,1);
+					break;
+				case TK_DOWNKICK:
+					clif_skill_nodamage(bl,bl,TK_READYDOWN,1,1);
+					break;
+				case TK_TURNKICK:
+					clif_skill_nodamage(bl,bl,TK_READYTURN,1,1);
+					break;
+				case TK_COUNTER:
+					clif_skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
+					break;
+				case MO_COMBOFINISH:
+				case CH_TIGERFIST:
+				case CH_CHAINCRUSH:
+					if (sd)
+						clif_skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL);
+					break;
+				case TK_JUMPKICK:
+					if (sd)
+						clif_skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL);
+					break;
+			}
 	}
 
 	if( opt_flag&2 && sd && sd->touching_id )
@@ -6836,16 +6840,17 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
 					bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,gettick());
 			}
 			break;
-		case SC_COMBO: //Clear last used skill when it is part of a combo.
+		case SC_COMBO:
 			if( sd )
-			{
-				if( sd->state.combo )
-				{
-					sd->state.combo = 0;
-					clif_skillinfoblock(sd);
-				}
-				if( sd->skillid_old == sce->val1 )
-					sd->skillid_old = sd->skilllv_old = 0;
+			switch (sce->val1) {
+				case MO_COMBOFINISH:
+				case CH_TIGERFIST:
+				case CH_CHAINCRUSH:
+					clif_skillinfo(sd, MO_EXTREMITYFIST, 0);
+					break;
+				case TK_JUMPKICK:
+					clif_skillinfo(sd, TK_JUMPKICK, 0);
+					break;
 			}
 			break;
 
@@ -7404,15 +7409,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
 		}
 		break;
 
-	case SC_DEVOTION:
-		//FIXME: use normal status duration instead of a looping timer
-		if( (sce->val4 -= 1000) > 0 )
-		{
-			sc_timer_next(1000+tick, status_change_timer, bl->id, data);
-			return 0;
-		}
-		break;
-		
 	case SC_BERSERK:
 		// 5% every 10 seconds [DracoRPG]
 		if( --( sce->val3 ) > 0 && status_charge(bl, sce->val2, 0) && status->hp > 100 )

+ 2 - 1
src/map/status.h

@@ -8,6 +8,7 @@ struct block_list;
 struct mob_data;
 struct pet_data;
 struct homun_data;
+struct mercenary_data;
 struct status_change;
 
 //Use this to refer the max refinery level [Skotlex]
@@ -1368,7 +1369,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap);
 int status_change_clear(struct block_list* bl, int type);
 int status_change_clear_buffs(struct block_list* bl, int type);
 
-#define status_calc_bl(bl, flag) status_calc_bl_(bl, flag, false)
+#define status_calc_bl(bl, flag) status_calc_bl_(bl, (enum scb_flag)(flag), false)
 #define status_calc_mob(md, first) status_calc_bl_(&(md)->bl, SCB_ALL, first)
 #define status_calc_pet(pd, first) status_calc_bl_(&(pd)->bl, SCB_ALL, first)
 #define status_calc_pc(sd, first) status_calc_bl_(&(sd)->bl, SCB_ALL, first)

+ 82 - 84
src/map/txt/CMakeLists.txt

@@ -2,90 +2,92 @@
 #
 # map txt
 #
-if( HAVE_common_base )
+if( BUILD_TXT_SERVERS )
 message( STATUS "Creating target map-server" )
 set( TXT_MAP_HEADERS
-	"${MAP_SOURCE_DIR}/atcommand.h"
-	"${MAP_SOURCE_DIR}/battle.h"
-	"${MAP_SOURCE_DIR}/battleground.h"
-	"${MAP_SOURCE_DIR}/buyingstore.h"
-	"${MAP_SOURCE_DIR}/chat.h"
-	"${MAP_SOURCE_DIR}/chrif.h"
-	"${MAP_SOURCE_DIR}/clif.h"
-	"${MAP_SOURCE_DIR}/date.h"
-	"${MAP_SOURCE_DIR}/duel.h"
-	"${MAP_SOURCE_DIR}/guild.h"
-	"${MAP_SOURCE_DIR}/homunculus.h"
-	"${MAP_SOURCE_DIR}/instance.h"
-	"${MAP_SOURCE_DIR}/intif.h"
-	"${MAP_SOURCE_DIR}/itemdb.h"
-	"${MAP_SOURCE_DIR}/log.h"
-	"${MAP_SOURCE_DIR}/mail.h"
-	"${MAP_SOURCE_DIR}/map.h"
-	"${MAP_SOURCE_DIR}/mapreg.h"
-	"${MAP_SOURCE_DIR}/mercenary.h"
-	"${MAP_SOURCE_DIR}/mob.h"
-	"${MAP_SOURCE_DIR}/npc.h"
-	"${MAP_SOURCE_DIR}/party.h"
-	"${MAP_SOURCE_DIR}/path.h"
-	"${MAP_SOURCE_DIR}/pc.h"
-	"${MAP_SOURCE_DIR}/pet.h"
-	"${MAP_SOURCE_DIR}/quest.h"
-	"${MAP_SOURCE_DIR}/script.h"
-	"${MAP_SOURCE_DIR}/searchstore.h"
-	"${MAP_SOURCE_DIR}/skill.h"
-	"${MAP_SOURCE_DIR}/status.h"
-	"${MAP_SOURCE_DIR}/storage.h"
-	"${MAP_SOURCE_DIR}/trade.h"
-	"${MAP_SOURCE_DIR}/unit.h"
-	"${MAP_SOURCE_DIR}/vending.h"
+	"${TXT_MAP_SOURCE_DIR}/atcommand.h"
+	"${TXT_MAP_SOURCE_DIR}/battle.h"
+	"${TXT_MAP_SOURCE_DIR}/battleground.h"
+	"${TXT_MAP_SOURCE_DIR}/buyingstore.h"
+	"${TXT_MAP_SOURCE_DIR}/chat.h"
+	"${TXT_MAP_SOURCE_DIR}/chrif.h"
+	"${TXT_MAP_SOURCE_DIR}/clif.h"
+	"${TXT_MAP_SOURCE_DIR}/date.h"
+	"${TXT_MAP_SOURCE_DIR}/duel.h"
+	"${TXT_MAP_SOURCE_DIR}/guild.h"
+	"${TXT_MAP_SOURCE_DIR}/homunculus.h"
+	"${TXT_MAP_SOURCE_DIR}/instance.h"
+	"${TXT_MAP_SOURCE_DIR}/intif.h"
+	"${TXT_MAP_SOURCE_DIR}/itemdb.h"
+	"${TXT_MAP_SOURCE_DIR}/log.h"
+	"${TXT_MAP_SOURCE_DIR}/mail.h"
+	"${TXT_MAP_SOURCE_DIR}/map.h"
+	"${TXT_MAP_SOURCE_DIR}/mapreg.h"
+	"${TXT_MAP_SOURCE_DIR}/mercenary.h"
+	"${TXT_MAP_SOURCE_DIR}/mob.h"
+	"${TXT_MAP_SOURCE_DIR}/npc.h"
+	"${TXT_MAP_SOURCE_DIR}/party.h"
+	"${TXT_MAP_SOURCE_DIR}/path.h"
+	"${TXT_MAP_SOURCE_DIR}/pc.h"
+	"${TXT_MAP_SOURCE_DIR}/pet.h"
+	"${TXT_MAP_SOURCE_DIR}/quest.h"
+	"${TXT_MAP_SOURCE_DIR}/script.h"
+	"${TXT_MAP_SOURCE_DIR}/searchstore.h"
+	"${TXT_MAP_SOURCE_DIR}/skill.h"
+	"${TXT_MAP_SOURCE_DIR}/status.h"
+	"${TXT_MAP_SOURCE_DIR}/storage.h"
+	"${TXT_MAP_SOURCE_DIR}/trade.h"
+	"${TXT_MAP_SOURCE_DIR}/unit.h"
+	"${TXT_MAP_SOURCE_DIR}/vending.h"
 	)
 set( TXT_MAP_SOURCES
-	"${MAP_SOURCE_DIR}/atcommand.c"
-	"${MAP_SOURCE_DIR}/battle.c"
-	"${MAP_SOURCE_DIR}/battleground.c"
-	"${MAP_SOURCE_DIR}/buyingstore.c"
-	"${MAP_SOURCE_DIR}/chat.c"
-	"${MAP_SOURCE_DIR}/chrif.c"
-	"${MAP_SOURCE_DIR}/clif.c"
-	"${MAP_SOURCE_DIR}/date.c"
-	"${MAP_SOURCE_DIR}/duel.c"
-	"${MAP_SOURCE_DIR}/guild.c"
-	"${MAP_SOURCE_DIR}/homunculus.c"
-	"${MAP_SOURCE_DIR}/instance.c"
-	"${MAP_SOURCE_DIR}/intif.c"
-	"${MAP_SOURCE_DIR}/itemdb.c"
-	"${MAP_SOURCE_DIR}/log.c"
-	"${MAP_SOURCE_DIR}/mail.c"
-	"${MAP_SOURCE_DIR}/map.c"
-	"${MAP_SOURCE_DIR}/mapreg_txt.c"
-	"${MAP_SOURCE_DIR}/mercenary.c"
-	"${MAP_SOURCE_DIR}/mob.c"
-	"${MAP_SOURCE_DIR}/npc.c"
-	"${MAP_SOURCE_DIR}/npc_chat.c"
-	"${MAP_SOURCE_DIR}/party.c"
-	"${MAP_SOURCE_DIR}/path.c"
-	"${MAP_SOURCE_DIR}/pc.c"
-	"${MAP_SOURCE_DIR}/pet.c"
-	"${MAP_SOURCE_DIR}/quest.c"
-	"${MAP_SOURCE_DIR}/script.c"
-	"${MAP_SOURCE_DIR}/searchstore.c"
-	"${MAP_SOURCE_DIR}/skill.c"
-	"${MAP_SOURCE_DIR}/status.c"
-	"${MAP_SOURCE_DIR}/storage.c"
-	"${MAP_SOURCE_DIR}/trade.c"
-	"${MAP_SOURCE_DIR}/unit.c"
-	"${MAP_SOURCE_DIR}/vending.c"
+	"${TXT_MAP_SOURCE_DIR}/atcommand.c"
+	"${TXT_MAP_SOURCE_DIR}/battle.c"
+	"${TXT_MAP_SOURCE_DIR}/battleground.c"
+	"${TXT_MAP_SOURCE_DIR}/buyingstore.c"
+	"${TXT_MAP_SOURCE_DIR}/chat.c"
+	"${TXT_MAP_SOURCE_DIR}/chrif.c"
+	"${TXT_MAP_SOURCE_DIR}/clif.c"
+	"${TXT_MAP_SOURCE_DIR}/date.c"
+	"${TXT_MAP_SOURCE_DIR}/duel.c"
+	"${TXT_MAP_SOURCE_DIR}/guild.c"
+	"${TXT_MAP_SOURCE_DIR}/homunculus.c"
+	"${TXT_MAP_SOURCE_DIR}/instance.c"
+	"${TXT_MAP_SOURCE_DIR}/intif.c"
+	"${TXT_MAP_SOURCE_DIR}/itemdb.c"
+	"${TXT_MAP_SOURCE_DIR}/log.c"
+	"${TXT_MAP_SOURCE_DIR}/mail.c"
+	"${TXT_MAP_SOURCE_DIR}/map.c"
+	"${TXT_MAP_SOURCE_DIR}/mapreg_txt.c"
+	"${TXT_MAP_SOURCE_DIR}/mercenary.c"
+	"${TXT_MAP_SOURCE_DIR}/mob.c"
+	"${TXT_MAP_SOURCE_DIR}/npc.c"
+	"${TXT_MAP_SOURCE_DIR}/npc_chat.c"
+	"${TXT_MAP_SOURCE_DIR}/party.c"
+	"${TXT_MAP_SOURCE_DIR}/path.c"
+	"${TXT_MAP_SOURCE_DIR}/pc.c"
+	"${TXT_MAP_SOURCE_DIR}/pet.c"
+	"${TXT_MAP_SOURCE_DIR}/quest.c"
+	"${TXT_MAP_SOURCE_DIR}/script.c"
+	"${TXT_MAP_SOURCE_DIR}/searchstore.c"
+	"${TXT_MAP_SOURCE_DIR}/skill.c"
+	"${TXT_MAP_SOURCE_DIR}/status.c"
+	"${TXT_MAP_SOURCE_DIR}/storage.c"
+	"${TXT_MAP_SOURCE_DIR}/trade.c"
+	"${TXT_MAP_SOURCE_DIR}/unit.c"
+	"${TXT_MAP_SOURCE_DIR}/vending.c"
 	)
 set( DEPENDENCIES common_base )
 set( LIBRARIES ${GLOBAL_LIBRARIES} )
 set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} TXT_ONLY )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS} -DTXT_ONLY" )
 if( WITH_PCRE )
-	message( STATUS "Using PCRE" )
-	list( APPEND LIBRARIES ${PCRE_LIBRARIES} )
-	list( APPEND INCLUDE_DIRS ${PCRE_INCLUDE_DIRS} )
-	list( APPEND DEFINITIONS PCRE_SUPPORT )
+	message( STATUS "Enabled PCRE code" )
+	set( LIBRARIES ${LIBRARIES} ${PCRE_LIBRARIES} )
+	set( INCLUDE_DIRS ${INCLUDE_DIRS} ${PCRE_INCLUDE_DIRS} )
+	set( DEFINITIONS "${DEFINITIONS} -DPCRE_SUPPORT" )
+else()
+	message( STATUS "Disabled PCRE code" )
 endif()
 set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${TXT_MAP_HEADERS} ${TXT_MAP_SOURCES} )
 source_group( common FILES ${COMMON_BASE_HEADERS} )
@@ -94,17 +96,13 @@ include_directories( ${INCLUDE_DIRS} )
 add_executable( map-server ${SOURCE_FILES} )
 add_dependencies( map-server ${DEPENDENCIES} )
 target_link_libraries( map-server ${LIBRARIES} ${DEPENDENCIES} )
-set_target_properties( map-server PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
-if( WITH_COMPONENT_RUNTIME )
+set_target_properties( map-server PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+if( INSTALL_COMPONENT_RUNTIME )
 	cpack_add_component( Runtime_mapserver_txt DESCRIPTION "map-server (txt version)" DISPLAY_NAME "map-server" GROUP Runtime )
 	install( TARGETS map-server
 		DESTINATION "."
 		COMPONENT Runtime_mapserver_txt )
-endif()
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} map-server  CACHE INTERNAL "" )
 message( STATUS "Creating target map-server - done" )
-set( HAVE_map-server ON  CACHE BOOL "map-server target is available" )
-mark_as_advanced( HAVE_map-server )
-else()
-message( STATUS "Skipping target map-server (requires common_base; optional PCRE)" )
-unset( HAVE_map-server CACHE )
-endif()
+endif( BUILD_TXT_SERVERS )

+ 16 - 15
src/map/unit.c

@@ -912,7 +912,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
 	struct map_session_data *sd = NULL;
 	struct block_list * target = NULL;
 	unsigned int tick = gettick();
-	int temp;
+	int temp = 0;
 
 	nullpo_ret(src);
 	if(status_isdead(src))
@@ -927,14 +927,21 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
 		sc = NULL; //Unneeded
 
 	//temp: used to signal combo-skills right now.
-	temp =	( target_id == src->id && 
-				( 
-					( !(skill_get_inf(skill_num)&INF_SELF_SKILL) && sd && sd->state.combo ) || 
-					( skill_get_inf(skill_num)&INF_SELF_SKILL && skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF ) 
-				) 
-			);
-	if (temp)
-		target_id = ud->target; //Auto-select skills. [Skotlex]
+	if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_num)
+	{
+		if (sc->data[SC_COMBO]->val2)
+			target_id = sc->data[SC_COMBO]->val2;
+		else
+			target_id = ud->target;
+		temp = 1;
+	} else
+	if ( target_id == src->id && 
+		skill_get_inf(skill_num)&INF_SELF_SKILL &&
+		skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF )
+	{
+		target_id = ud->target; //Auto-select target. [Skotlex]
+		temp = 1;
+	}
 
 	if (sd) {
 		//Target_id checking.
@@ -949,12 +956,6 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
 					return 0;
 			}
 			break;
-		case TK_JUMPKICK:
-		case TK_COUNTER:
-		case HT_POWER:
-			if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_num)
-				target_id = sc->data[SC_COMBO]->val2;
-			break;
 		case WE_MALE:
 		case WE_FEMALE:
 			if (!sd->status.partner_id)

+ 180 - 0
src/plugins/CMakeLists.txt

@@ -0,0 +1,180 @@
+
+#
+# setup
+#
+get_property( CAN_BUILD_SHARED_LIBS  GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS )
+if( NOT CAN_BUILD_SHARED_LIBS )
+	return()
+endif()
+
+#
+# console
+#
+option( BUILD_PLUGIN_console "build console plugin" OFF )
+if( BUILD_PLUGIN_console )
+message( STATUS "Creating target console" )
+set( CONSOLE_SOURCES
+	"${CMAKE_CURRENT_SOURCE_DIR}/console.c"
+	"${CMAKE_CURRENT_SOURCE_DIR}/console.def"
+	)
+set( LIBRARIES ${GLOBAL_LIBRARIES} )
+set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
+set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
+set( SOURCE_FILES ${CONSOLE_SOURCES} )
+source_group( console FILES ${CONSOLE_SOURCES} )
+include_directories( ${INCLUDE_DIRS} )
+add_library( console SHARED ${SOURCE_FILES} )
+target_link_libraries( console ${LIBRARIES} )
+set_target_properties( console PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+set_target_properties( console PROPERTIES PREFIX "" )
+if( INSTALL_COMPONENT_RUNTIME )
+	cpack_add_component( Runtime_console DESCRIPTION "console plugin" DISPLAY_NAME "console" GROUP Runtime )
+	install( TARGETS console
+		DESTINATION "plugins"
+		COMPONENT Runtime_console )
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} console  CACHE INTERNAL "" )
+message( STATUS "Creating target console - done" )
+endif( BUILD_PLUGIN_console )
+
+
+#
+# dbghelpplug
+#
+if( WIN32 )
+	find_path( HAVE_DBGHELP_H dbghelp.h )
+	mark_as_advanced( HAVE_DBGHELP_H )
+	if( HAVE_DBGHELP_H )
+		option( BUILD_PLUGIN_dbghelpplug "build dbghelpplug plugin" OFF )
+	endif()
+endif()
+if( NOT DEFINED BUILD_PLUGIN_dbghelpplug )
+	message( STATUS "Disabled dbghelpplug plugin target (requires WIN32 and HAVE_DBGHELP_H)" )
+endif()
+if( BUILD_PLUGIN_dbghelpplug )
+message( STATUS "Creating target dbghelpplug" )
+set( DBGHELPPLUG_SOURCES
+	"${CMAKE_CURRENT_SOURCE_DIR}/dbghelpplug.c"
+	"${CMAKE_CURRENT_SOURCE_DIR}/dbghelpplug.rc"
+	)
+set( LIBRARIES ${GLOBAL_LIBRARIES} )
+set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
+set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
+set( SOURCE_FILES ${DBGHELPPLUG_SOURCES} )
+source_group( dbghelpplug FILES ${DBGHELPPLUG_SOURCES} )
+include_directories( ${INCLUDE_DIRS} )
+add_library( dbghelpplug SHARED ${SOURCE_FILES} )
+target_link_libraries( dbghelpplug ${LIBRARIES} )
+set_target_properties( dbghelpplug PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+set_target_properties( dbghelpplug PROPERTIES PREFIX "" )
+if( INSTALL_COMPONENT_RUNTIME )
+	cpack_add_component( Runtime_dbghelpplug DESCRIPTION "dbghelpplug plugin" DISPLAY_NAME "dbghelpplug" GROUP Runtime )
+	install( TARGETS dbghelpplug
+		DESTINATION "plugins"
+		COMPONENT Runtime_dbghelpplug )
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} dbghelpplug  CACHE INTERNAL "" )
+message( STATUS "Creating target dbghelpplug - done" )
+endif( BUILD_PLUGIN_dbghelpplug )
+
+
+#
+# pid
+#
+if( WIN32 OR HAVE_GETPID )
+	option( BUILD_PLUGIN_pid "build pid plugin" OFF )
+else()
+	message( STATUS "Disabled pid plugin target (requires WIN32 or HAVE_GETPID)" )
+endif()
+if( BUILD_PLUGIN_pid )
+message( STATUS "Creating target pid" )
+set( PID_SOURCES
+	"${CMAKE_CURRENT_SOURCE_DIR}/pid.c"
+	"${CMAKE_CURRENT_SOURCE_DIR}/pid.def"
+	)
+set( LIBRARIES ${GLOBAL_LIBRARIES} )
+set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
+set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
+set( SOURCE_FILES ${PID_SOURCES} )
+source_group( pid FILES ${PID_SOURCES} )
+include_directories( ${INCLUDE_DIRS} )
+add_library( pid SHARED ${SOURCE_FILES} )
+target_link_libraries( pid ${LIBRARIES} )
+set_target_properties( pid PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+set_target_properties( pid PROPERTIES PREFIX "" )
+if( INSTALL_COMPONENT_RUNTIME )
+	cpack_add_component( Runtime_pid DESCRIPTION "pid plugin" DISPLAY_NAME "pid" GROUP Runtime )
+	install( TARGETS pid
+		DESTINATION "plugins"
+		COMPONENT Runtime_pid )
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} pid  CACHE INTERNAL "" )
+message( STATUS "Creating target pid - done" )
+endif( BUILD_PLUGIN_pid )
+
+
+#
+# sample
+#
+option( BUILD_PLUGIN_sample "build sample plugin" OFF )
+if( BUILD_PLUGIN_sample )
+message( STATUS "Creating target sample" )
+set( SAMPLE_SOURCES
+	"${CMAKE_CURRENT_SOURCE_DIR}/sample.c"
+	"${CMAKE_CURRENT_SOURCE_DIR}/sample.def"
+	)
+set( LIBRARIES ${GLOBAL_LIBRARIES} )
+set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
+set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
+set( SOURCE_FILES ${SAMPLE_SOURCES} )
+source_group( sample FILES ${SAMPLE_SOURCES} )
+include_directories( ${INCLUDE_DIRS} )
+add_library( sample SHARED ${SOURCE_FILES} )
+target_link_libraries( sample ${LIBRARIES} )
+set_target_properties( sample PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+set_target_properties( sample PROPERTIES PREFIX "" )
+if( INSTALL_COMPONENT_RUNTIME )
+	cpack_add_component( Runtime_sample DESCRIPTION "sample plugin" DISPLAY_NAME "sample" GROUP Runtime )
+	install( TARGETS sample
+		DESTINATION "plugins"
+		COMPONENT Runtime_sample )
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} sample  CACHE INTERNAL "" )
+message( STATUS "Creating target sample - done" )
+endif( BUILD_PLUGIN_sample )
+
+
+#
+# sig
+#
+option( BUILD_PLUGIN_sig "build sig plugin" OFF )
+if( BUILD_PLUGIN_sig )
+message( STATUS "Creating target sig" )
+set( SIG_SOURCES
+	"${COMMON_SOURCE_DIR}/malloc.c"
+	"${COMMON_SOURCE_DIR}/malloc.h"
+	"${COMMON_SOURCE_DIR}/showmsg.c"
+	"${COMMON_SOURCE_DIR}/showmsg.h"
+	"${COMMON_SOURCE_DIR}/strlib.c"
+	"${COMMON_SOURCE_DIR}/strlib.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/sig.c"
+	)
+set( LIBRARIES ${GLOBAL_LIBRARIES} )
+set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS} ${COMMON_MINI_DEFINITIONS} -DNO_MEMMGR" )
+set( SOURCE_FILES ${SIG_SOURCES} )
+source_group( sig FILES ${SIG_SOURCES} )
+include_directories( ${INCLUDE_DIRS} )
+add_library( sig SHARED ${SOURCE_FILES} )
+target_link_libraries( sig ${LIBRARIES} )
+set_target_properties( sig PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+set_target_properties( sig PROPERTIES PREFIX "" )
+if( INSTALL_COMPONENT_RUNTIME )
+	cpack_add_component( Runtime_sig DESCRIPTION "sig plugin" DISPLAY_NAME "sig" GROUP Runtime )
+	install( TARGETS sig
+		DESTINATION "plugins"
+		COMPONENT Runtime_sig )
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} sig  CACHE INTERNAL "" )
+message( STATUS "Creating target sig - done" )
+endif( BUILD_PLUGIN_sig )

+ 6 - 1
src/plugins/sig.c

@@ -88,7 +88,12 @@ sigfunc *compat_signal(int signo, sigfunc *func)
  */
 #ifdef CYGWIN
 	#define FOPEN_ freopen
+	#ifdef __cplusplus
+	extern "C" void cygwin_stackdump();
+	#else
 	extern void cygwin_stackdump();
+	#endif
+	
 #else
 	#define FOPEN_(fn,m,s) fopen(fn,m)
 #endif
@@ -186,7 +191,7 @@ int sig_final ()
  */
 int sig_init ()
 {
-	void (*func) = sig_dump;
+	void (*func)(int) = sig_dump;
 #ifdef CYGWIN	// test if dumper is enabled
 	char *buf = getenv ("CYGWIN");
 	if (buf && strstr(buf, "error_start") != NULL)

+ 11 - 10
src/tool/CMakeLists.txt

@@ -3,6 +3,11 @@
 # mapcache
 #
 if( WITH_ZLIB )
+	option( BUILD_MAPCACHE "build mapcache executable" ON )
+else()
+	message( STATUS "Disabled mapcache target (required ZLIB)" )
+endif()
+if( BUILD_MAPCACHE )
 message( STATUS "Creating target mapcache" )
 set( COMMON_HEADERS
 	${COMMON_MINI_HEADERS}
@@ -19,24 +24,20 @@ set( MAPCACHE_SOURCES
 	)
 set( LIBRARIES ${GLOBAL_LIBRARIES} ${ZLIB_LIBRARIES} )
 set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} ${COMMON_MINI_DEFINITIONS} )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS} ${COMMON_MINI_DEFINITIONS}" )
 set( SOURCE_FILES ${COMMON_HEADERS} ${COMMON_SOURCES} ${MAPCACHE_SOURCES} )
 source_group( common FILES ${COMMON_HEADERS} ${COMMON_SOURCES} )
 source_group( mapcache FILES ${MAPCACHE_SOURCES} )
 add_executable( mapcache ${SOURCE_FILES} )
 include_directories( ${INCLUDE_DIRS} )
 target_link_libraries( mapcache ${LIBRARIES} )
-set_target_properties( mapcache PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
-if( WITH_COMPONENT_RUNTIME )
+set_target_properties( mapcache PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+if( INSTALL_COMPONENT_RUNTIME )
 	cpack_add_component( Runtime_mapcache DESCRIPTION "mapcache generator" DISPLAY_NAME "mapcache" GROUP Runtime )
 	install( TARGETS mapcache
 		DESTINATION "."
 		COMPONENT Runtime_mapcache )
-endif()
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} mapcache  CACHE INTERNAL "" )
 message( STATUS "Creating target mapcache - done" )
-set( HAVE_mapcache ON  CACHE BOOL "mapcache target is available" )
-mark_as_advanced( HAVE_mapcache )
-else()
-message( STATUS "Skipping target mapcache (requires ZLIB)" )
-unset( HAVE_mapcache CACHE )
-endif()
+endif( BUILD_MAPCACHE )

+ 1 - 1
src/tool/mapcache.c

@@ -246,7 +246,7 @@ void process_args(int argc, char *argv[])
 
 }
 
-int do_init(int argc, char *argv[])
+int do_init(int argc, char** argv)
 {
 	FILE *list;
 	char line[1024];

+ 17 - 0
src/txt-converter/CMakeLists.txt

@@ -0,0 +1,17 @@
+
+#
+# setup
+#
+set( CONVERTER_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}  CACHE INTERNAL "" )
+if( WITH_MYSQL )
+	option( BUILD_CONVERTERS "build converter executables" OFF )
+else()
+	message( STATUS "Disabled converter targets  (requires MYSQL)" )
+endif()
+
+
+#
+# targets
+#
+add_subdirectory( login )
+add_subdirectory( char )

+ 76 - 0
src/txt-converter/char/CMakeLists.txt

@@ -0,0 +1,76 @@
+
+#
+# char-converter
+#
+if( BUILD_CONVERTERS )
+message( STATUS "Creating target char-converter" )
+set( COMMON_HEADERS
+	${COMMON_MINI_HEADERS}
+	"${COMMON_SOURCE_DIR}/mapindex.h"
+	"${COMMON_SOURCE_DIR}/sql.h"
+	"${COMMON_SOURCE_DIR}/timer.h"
+	)
+set( COMMON_SOURCES
+	${COMMON_MINI_SOURCES}
+	"${COMMON_SOURCE_DIR}/mapindex.c"
+	"${COMMON_SOURCE_DIR}/sql.c"
+	"${COMMON_SOURCE_DIR}/timer.c"
+	)
+set( TXT_HEADERS
+	"${TXT_CHAR_SOURCE_DIR}/char.h"
+	"${TXT_CHAR_SOURCE_DIR}/int_pet.h"
+	"${TXT_CHAR_SOURCE_DIR}/int_storage.h"
+	"${TXT_CHAR_SOURCE_DIR}/inter.h"
+	"${TXT_CHAR_SOURCE_DIR}/int_party.h"
+	"${TXT_CHAR_SOURCE_DIR}/int_guild.h"
+	)
+set( TXT_SOURCES
+	"${TXT_CHAR_SOURCE_DIR}/char.c"
+	"${TXT_CHAR_SOURCE_DIR}/int_pet.c"
+	"${TXT_CHAR_SOURCE_DIR}/int_storage.c"
+	"${TXT_CHAR_SOURCE_DIR}/inter.c"
+	"${TXT_CHAR_SOURCE_DIR}/int_party.c"
+	"${TXT_CHAR_SOURCE_DIR}/int_guild.c"
+	)
+set( SQL_HEADERS
+	"${SQL_CHAR_SOURCE_DIR}/char.h"
+	"${SQL_CHAR_SOURCE_DIR}/int_pet.h"
+	"${SQL_CHAR_SOURCE_DIR}/int_storage.h"
+	"${SQL_CHAR_SOURCE_DIR}/inter.h"
+	"${SQL_CHAR_SOURCE_DIR}/int_party.h"
+	"${SQL_CHAR_SOURCE_DIR}/int_guild.h"
+	"${SQL_CHAR_SOURCE_DIR}/int_mercenary.h"
+	)
+set( SQL_SOURCES
+	"${SQL_CHAR_SOURCE_DIR}/char.c"
+	"${SQL_CHAR_SOURCE_DIR}/int_pet.c"
+	"${SQL_CHAR_SOURCE_DIR}/int_storage.c"
+	"${SQL_CHAR_SOURCE_DIR}/inter.c"
+	"${SQL_CHAR_SOURCE_DIR}/int_party.c"
+	"${SQL_CHAR_SOURCE_DIR}/int_guild.c"
+	"${SQL_CHAR_SOURCE_DIR}/int_mercenary.c"
+	)
+set( CONVERTER_SOURCES
+	"${CONVERTER_SOURCE_DIR}/char-converter.c"
+	)
+set( LIBRARIES ${GLOBAL_LIBRARIES} ${MYSQL_LIBRARIES} )
+set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ${MYSQL_INCLUDE_DIRS} )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS} ${COMMON_MINI_DEFINITIONS} -DTXT_SQL_CONVERT" )
+set( SOURCE_FILES ${COMMON_HEADERS} ${COMMON_SOURCES} ${TXT_HEADERS} ${TXT_SOURCES} ${SQL_HEADERS} ${SQL_SOURCES} ${CONVERTER_SOURCES} )
+source_group( common FILES ${COMMON_HEADERS} ${COMMON_SOURCES} )
+source_group( txt FILES ${TXT_HEADERS} ${TXT_SOURCES} )
+source_group( sql FILES ${SQL_HEADERS} ${SQL_SOURCES} )
+source_group( converter FILES ${CONVERTER_SOURCES} )
+include_directories( ${INCLUDE_DIRS} )
+add_executable( char-converter ${SOURCE_FILES} )
+target_link_libraries( char-converter ${LIBRARIES} )
+set_target_properties( char-converter PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+if( INSTALL_COMPONENT_RUNTIME )
+	cpack_add_component( Runtime_charconverter DESCRIPTION "char-converter" DISPLAY_NAME "char-converter" GROUP Runtime )
+	install( TARGETS char-converter
+		DESTINATION "tools"
+		COMPONENT Runtime_charconverter )
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} char-converter  CACHE INTERNAL "" )
+message( STATUS "Creating target char-converter - done" )
+endif( BUILD_CONVERTERS )

+ 60 - 0
src/txt-converter/login/CMakeLists.txt

@@ -0,0 +1,60 @@
+
+#
+# login-converter
+#
+if( BUILD_CONVERTERS )
+message( STATUS "Creating target login-converter" )
+set( COMMON_HEADERS
+	${COMMON_MINI_HEADERS}
+	"${COMMON_SOURCE_DIR}/db.h"
+	"${COMMON_SOURCE_DIR}/ers.h"
+	"${COMMON_SOURCE_DIR}/lock.h"
+	"${COMMON_SOURCE_DIR}/sql.h"
+	"${COMMON_SOURCE_DIR}/timer.h"
+	"${COMMON_SOURCE_DIR}/utils.h"
+	)
+set( COMMON_SOURCES
+	${COMMON_MINI_SOURCES}
+	"${COMMON_SOURCE_DIR}/db.c"
+	"${COMMON_SOURCE_DIR}/ers.c"
+	"${COMMON_SOURCE_DIR}/lock.c"
+	"${COMMON_SOURCE_DIR}/sql.c"
+	"${COMMON_SOURCE_DIR}/timer.c"
+	"${COMMON_SOURCE_DIR}/utils.c"
+	)
+set( TXT_HEADERS
+	"${TXT_LOGIN_SOURCE_DIR}/account.h"
+	)
+set( TXT_SOURCES
+	"${TXT_LOGIN_SOURCE_DIR}/account_txt.c"
+	)
+set( SQL_HEADERS
+	"${SQL_LOGIN_SOURCE_DIR}/account.h"
+	)
+set( SQL_SOURCES
+	"${SQL_LOGIN_SOURCE_DIR}/account_sql.c"
+	)
+set( CONVERTER_SOURCES
+	"${CONVERTER_SOURCE_DIR}/login-converter.c"
+	)
+set( LIBRARIES ${GLOBAL_LIBRARIES} ${MYSQL_LIBRARIES} )
+set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ${MYSQL_INCLUDE_DIRS} )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS} ${COMMON_MINI_DEFINITIONS} -DWITH_TXT -DWITH_SQL" )
+set( SOURCE_FILES ${COMMON_HEADERS} ${COMMON_SOURCES} ${TXT_HEADERS} ${TXT_SOURCES} ${SQL_HEADERS} ${SQL_SOURCES} ${CONVERTER_SOURCES} )
+source_group( common FILES ${COMMON_HEADERS} ${COMMON_SOURCES} )
+source_group( txt FILES ${TXT_HEADERS} ${TXT_SOURCES} )
+source_group( sql FILES ${SQL_HEADERS} ${SQL_SOURCES} )
+source_group( converter FILES ${CONVERTER_SOURCES} )
+include_directories( ${INCLUDE_DIRS} )
+add_executable( login-converter ${SOURCE_FILES} )
+target_link_libraries( login-converter ${LIBRARIES} )
+set_target_properties( login-converter PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+if( INSTALL_COMPONENT_RUNTIME )
+	cpack_add_component( Runtime_loginconverter DESCRIPTION "login-converter" DISPLAY_NAME "login-converter" GROUP Runtime )
+	install( TARGETS login-converter
+		DESTINATION "tools"
+		COMPONENT Runtime_loginconverter )
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} login-converter  CACHE INTERNAL "" )
+message( STATUS "Creating target login-converter - done" )
+endif( BUILD_CONVERTERS )

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio