Compare commits

..

4 Commits

Author SHA1 Message Date
Ulu Kyn 810976f843 Merge branch 'main/gingo-test' into self-kill 3 years ago
Ben Saine 8c812ece15 self kill command 3 years ago
Ben Saine f998633767 Revert "self kill command"
This reverts commit 00597f9b18
3 years ago
Ben Saine 00597f9b18 self kill command 3 years ago

1
.gitignore vendored

@ -165,7 +165,6 @@ build/*
install/* install/*
win-build/ win-build/
build_* build_*
install_*
nel/tools/build_gamedata/configuration/buildsite.py nel/tools/build_gamedata/configuration/buildsite.py
# Linux nel compile # Linux nel compile

@ -34,37 +34,11 @@ IF(COMMAND cmake_policy)
ENDIF() ENDIF()
ENDIF() ENDIF()
#-----------------------------------------------------------------------------
# Downloads and install Hunger into HUNTER_ROOT directory.
OPTION(HUNTER_ENABLED "Enable Hunter package manager" OFF)
IF(HUNTER_ENABLED)
INCLUDE("CMakeModules/HunterGate.cmake")
HunterGate(
URL "https://github.com/cpp-pm/hunter/archive/v0.23.321.tar.gz"
SHA1 "5e53cbb0429037ea8e2592bfd92704b8ff3ab492"
FILEPATH "${CMAKE_CURRENT_LIST_DIR}/CMakeModules/HunterConfig.cmake"
)
# default options for hunterized build
SET(WITH_STATIC ON CACHE BOOL "static" FORCE)
SET(WITH_STATIC_DRIVERS ON CACHE BOOL "static drivers" FORCE)
SET(WITH_STATIC_CURL ON CACHE BOOL "static curl" FORCE)
SET(WITH_STATIC_LIBXML2 ON CACHE BOOL "static libxml2" FORCE)
SET(WITH_STATIC_EXTERNAL ON CACHE BOOL "static external" FORCE)
SET(WITH_EXTERNAL OFF CACHE BOOL "external libs" FORCE)
ENDIF()
#-----------------------------------------------------------------------------
INCLUDE(nel) INCLUDE(nel)
INCLUDE(ConfigureChecks) INCLUDE(ConfigureChecks)
INCLUDE(CheckDepends) INCLUDE(CheckDepends)
INCLUDE(${CMAKE_ROOT}/Modules/Documentation.cmake OPTIONAL) INCLUDE(${CMAKE_ROOT}/Modules/Documentation.cmake OPTIONAL)
MESSAGE("EXTERNAL ${WITH_EXTERNAL}")
# Force out of source builds. # Force out of source builds.
CHECK_OUT_OF_SOURCE() CHECK_OUT_OF_SOURCE()
@ -160,28 +134,6 @@ IF(WIN32)
ENDIF() ENDIF()
ENDIF() ENDIF()
IF(HUNTER_ENABLED)
## TODO: hack for freetype hunter package
SET(ON 1)
##
HUNTER_ADD_PACKAGE(ZLIB)
FIND_PACKAGE(ZLIB CONFIG REQUIRED)
SET(ZLIB_LIBRARY ZLIB::zlib)
HUNTER_ADD_PACKAGE(libxml2)
FIND_PACKAGE(libxml2 CONFIG REQUIRED)
SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} libxml2::libxml2)
HUNTER_ADD_PACKAGE(OpenSSL)
FIND_PACKAGE(OpenSSL REQUIRED)
# TODO: is OpenSSL::Crypto only needed for WIN32?
SET(OPENSSL_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
# for precompiled headers, not needed if using TARGET_PRECOMPILE_HEADERS() from cmake 3.16+
SET(ZLIB_INCLUDE_DIR ZLIB_ROOT/include)
SET(LIBXML2_INCLUDE_DIR ${LIBXML2_ROOT}/include/libxml2)
ELSE()
FIND_PACKAGE(ZLIB REQUIRED) FIND_PACKAGE(ZLIB REQUIRED)
FIND_PACKAGE(LibXml2 REQUIRED) FIND_PACKAGE(LibXml2 REQUIRED)
FIND_PACKAGE(PNG REQUIRED) FIND_PACKAGE(PNG REQUIRED)
@ -192,7 +144,6 @@ FIND_PACKAGE(Jpeg)
IF(WIN32) IF(WIN32)
SET(OPENSSL_LIBRARIES ${OPENSSL_LIBRARIES} Crypt32.lib) SET(OPENSSL_LIBRARIES ${OPENSSL_LIBRARIES} Crypt32.lib)
ENDIF() ENDIF()
ENDIF() #hunter
IF(WITH_LIBOVR) IF(WITH_LIBOVR)
FIND_PACKAGE(LibOVR) FIND_PACKAGE(LibOVR)
@ -286,7 +237,6 @@ ENDIF()
INCLUDE(FindHelpers) INCLUDE(FindHelpers)
#TODO: hunter qt package
IF(WITH_QT5) IF(WITH_QT5)
FIND_QT5() FIND_QT5()
ENDIF() ENDIF()
@ -298,7 +248,6 @@ IF(WITH_QT)
FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtXml QtOpenGL REQUIRED) FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtXml QtOpenGL REQUIRED)
ENDIF() ENDIF()
#TODO: hunter assimp package
IF(WITH_ASSIMP) IF(WITH_ASSIMP)
FIND_PACKAGE(assimp REQUIRED) FIND_PACKAGE(assimp REQUIRED)
ENDIF() ENDIF()
@ -308,20 +257,9 @@ IF(WITH_NEL)
FIND_PACKAGE(CppTest) FIND_PACKAGE(CppTest)
ENDIF() ENDIF()
IF(HUNTER_ENABLED) IF(WITH_GUI)
IF(WITH_GUI) FIND_PACKAGE(Luabind REQUIRED)
HUNTER_ADD_PACKAGE(luabind) ENDIF()
FIND_PACKAGE(Luabind REQUIRED)
ENDIF()
HUNTER_ADD_PACKAGE(CURL)
FIND_PACKAGE(CURL CONFIG REQUIRED)
# TODO: for nelgui
SET(CURL_LIBRARIES CURL::libcurl libxml2::libxml2)
ELSE()
IF(WITH_GUI)
FIND_PACKAGE(Luabind REQUIRED)
ENDIF()
FIND_PACKAGE(CURL REQUIRED) FIND_PACKAGE(CURL REQUIRED)
@ -372,7 +310,6 @@ IF(WITH_NEL)
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF() #hunter
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/nel/include) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/nel/include)
ADD_SUBDIRECTORY(nel) ADD_SUBDIRECTORY(nel)

@ -69,13 +69,7 @@ MACRO(FIND_CORRECT_LUA_VERSION)
ENDIF() ENDIF()
ELSE() ELSE()
# TODO: find a way to detect Lua version # TODO: find a way to detect Lua version
IF(HUNTER_ENABLED) IF(WITH_LUA53)
HUNTER_ADD_PACKAGE(Lua)
FIND_PACKAGE(Lua CONFIG REQUIRED)
SET(LUA_LIBRARIES Lua::lua_lib)
ELSEIF(WITH_LUA54)
FIND_PACKAGE(Lua54 REQUIRED)
ELSEIF(WITH_LUA53)
FIND_PACKAGE(Lua53 REQUIRED) FIND_PACKAGE(Lua53 REQUIRED)
ELSEIF(WITH_LUA52) ELSEIF(WITH_LUA52)
FIND_PACKAGE(Lua52 REQUIRED) FIND_PACKAGE(Lua52 REQUIRED)
@ -95,21 +89,6 @@ ENDIF()
SET(LIBRARY_NAME_RELEASE) SET(LIBRARY_NAME_RELEASE)
SET(LIBRARY_NAME_DEBUG) SET(LIBRARY_NAME_DEBUG)
IF(WITH_LUA54)
IF(WITH_STLPORT)
LIST(APPEND LIBRARY_NAME_RELEASE luabind_stlport_lua54)
LIST(APPEND LIBRARY_NAME_DEBUG luabind_stlport_lua54d)
ENDIF()
LIST(APPEND LIBRARY_NAME_RELEASE luabind_lua54)
LIST(APPEND LIBRARY_NAME_DEBUG luabind_lua54d)
ENDIF()
IF(HUNTER_ENABLED)
LIST(APPEND LIBRARY_NAME_RELEASE luabind luabind09)
LIST(APPEND LIBRARY_NAME_DEBUG luabindd luabind09-d)
ENDIF()
IF(WITH_LUA53) IF(WITH_LUA53)
IF(WITH_STLPORT) IF(WITH_STLPORT)
LIST(APPEND LIBRARY_NAME_RELEASE luabind_stlport_lua53) LIST(APPEND LIBRARY_NAME_RELEASE luabind_stlport_lua53)

@ -501,17 +501,6 @@ IF(WINSDK_INCLUDE_DIR)
IF(WINSDK_VERSION STREQUAL "7.1" AND (MSVC11 OR MSVC12 OR MSVC14)) IF(WINSDK_VERSION STREQUAL "7.1" AND (MSVC11 OR MSVC12 OR MSVC14))
ADD_DEFINITIONS(-D_USING_V110_SDK71_) ADD_DEFINITIONS(-D_USING_V110_SDK71_)
ENDIF() ENDIF()
IF(NOT DXSDK_DIR)
MESSAGE("Using DirectX from Windows SDK (${WINSDK_LIBRARY_DIRS})")
SET(DXSDK_DIR ${WINSDK_DIR})
FIND_LIBRARY(DXSDK_GUID_LIBRARY dxguid ${WINSDK_LIBRARY_DIRS})
FIND_LIBRARY(DXSDK_DINPUT_LIBRARY dinput8 ${WINSDK_LIBRARY_DIRS})
FIND_LIBRARY(DXSDK_DSOUND_LIBRARY dsound ${WINSDK_LIBRARY_DIRS})
FIND_LIBRARY(DXSDK_XAUDIO_LIBRARY xaudio2 ${WINSDK_LIBRARY_DIRS})
# TODO: FIND_LIBRARY(DXSDK_D3DX9_LIBRARY d3dx9)
FIND_LIBRARY(DXSDK_D3D9_LIBRARY d3d9 ${WINSDK_LIBRARY_DIRS})
ENDIF()
ELSE() ELSE()
IF(NOT WindowsSDK_FIND_QUIETLY) IF(NOT WindowsSDK_FIND_QUIETLY)
MESSAGE(STATUS "Warning: Unable to find Windows SDK!") MESSAGE(STATUS "Warning: Unable to find Windows SDK!")

@ -1,8 +0,0 @@
# This file is parsed by HunterGate command
hunter_config(luabind
VERSION 0.9.1
URL "https://github.com/nimetu/luabind/tarball/2fa4606"
SHA1 "3b4646bab9f0b2362d7b8d71d78e40deaf3cc747"
)

@ -1,537 +0,0 @@
# Copyright (c) 2013-2019, Ruslan Baratov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This is a gate file to Hunter package manager.
# Include this file using `include` command and add package you need, example:
#
# cmake_minimum_required(VERSION 3.2)
#
# include("cmake/HunterGate.cmake")
# HunterGate(
# URL "https://github.com/path/to/hunter/archive.tar.gz"
# SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d"
# )
#
# project(MyProject)
#
# hunter_add_package(Foo)
# hunter_add_package(Boo COMPONENTS Bar Baz)
#
# Projects:
# * https://github.com/hunter-packages/gate/
# * https://github.com/ruslo/hunter
option(HUNTER_ENABLED "Enable Hunter package manager support" ON)
if(HUNTER_ENABLED)
if(CMAKE_VERSION VERSION_LESS "3.2")
message(
FATAL_ERROR
"At least CMake version 3.2 required for Hunter dependency management."
" Update CMake or set HUNTER_ENABLED to OFF."
)
endif()
endif()
include(CMakeParseArguments) # cmake_parse_arguments
option(HUNTER_STATUS_PRINT "Print working status" ON)
option(HUNTER_STATUS_DEBUG "Print a lot info" OFF)
option(HUNTER_TLS_VERIFY "Enable/disable TLS certificate checking on downloads" ON)
set(HUNTER_ROOT "" CACHE FILEPATH "Override the HUNTER_ROOT.")
set(HUNTER_ERROR_PAGE "https://hunter.readthedocs.io/en/latest/reference/errors")
function(hunter_gate_status_print)
if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG)
foreach(print_message ${ARGV})
message(STATUS "[hunter] ${print_message}")
endforeach()
endif()
endfunction()
function(hunter_gate_status_debug)
if(HUNTER_STATUS_DEBUG)
foreach(print_message ${ARGV})
string(TIMESTAMP timestamp)
message(STATUS "[hunter *** DEBUG *** ${timestamp}] ${print_message}")
endforeach()
endif()
endfunction()
function(hunter_gate_error_page error_page)
message("------------------------------ ERROR ------------------------------")
message(" ${HUNTER_ERROR_PAGE}/${error_page}.html")
message("-------------------------------------------------------------------")
message("")
message(FATAL_ERROR "")
endfunction()
function(hunter_gate_internal_error)
message("")
foreach(print_message ${ARGV})
message("[hunter ** INTERNAL **] ${print_message}")
endforeach()
message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
message("")
hunter_gate_error_page("error.internal")
endfunction()
function(hunter_gate_fatal_error)
cmake_parse_arguments(hunter "" "ERROR_PAGE" "" "${ARGV}")
if("${hunter_ERROR_PAGE}" STREQUAL "")
hunter_gate_internal_error("Expected ERROR_PAGE")
endif()
message("")
foreach(x ${hunter_UNPARSED_ARGUMENTS})
message("[hunter ** FATAL ERROR **] ${x}")
endforeach()
message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
message("")
hunter_gate_error_page("${hunter_ERROR_PAGE}")
endfunction()
function(hunter_gate_user_error)
hunter_gate_fatal_error(${ARGV} ERROR_PAGE "error.incorrect.input.data")
endfunction()
function(hunter_gate_self root version sha1 result)
string(COMPARE EQUAL "${root}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("root is empty")
endif()
string(COMPARE EQUAL "${version}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("version is empty")
endif()
string(COMPARE EQUAL "${sha1}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("sha1 is empty")
endif()
string(SUBSTRING "${sha1}" 0 7 archive_id)
if(EXISTS "${root}/cmake/Hunter")
set(hunter_self "${root}")
else()
set(
hunter_self
"${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked"
)
endif()
set("${result}" "${hunter_self}" PARENT_SCOPE)
endfunction()
# Set HUNTER_GATE_ROOT cmake variable to suitable value.
function(hunter_gate_detect_root)
# Check CMake variable
if(HUNTER_ROOT)
set(HUNTER_GATE_ROOT "${HUNTER_ROOT}" PARENT_SCOPE)
hunter_gate_status_debug("HUNTER_ROOT detected by cmake variable")
return()
endif()
# Check environment variable
if(DEFINED ENV{HUNTER_ROOT})
set(HUNTER_GATE_ROOT "$ENV{HUNTER_ROOT}" PARENT_SCOPE)
hunter_gate_status_debug("HUNTER_ROOT detected by environment variable")
return()
endif()
# Check HOME environment variable
if(DEFINED ENV{HOME})
set(HUNTER_GATE_ROOT "$ENV{HOME}/.hunter" PARENT_SCOPE)
hunter_gate_status_debug("HUNTER_ROOT set using HOME environment variable")
return()
endif()
# Check SYSTEMDRIVE and USERPROFILE environment variable (windows only)
if(WIN32)
if(DEFINED ENV{SYSTEMDRIVE})
set(HUNTER_GATE_ROOT "$ENV{SYSTEMDRIVE}/.hunter" PARENT_SCOPE)
hunter_gate_status_debug(
"HUNTER_ROOT set using SYSTEMDRIVE environment variable"
)
return()
endif()
if(DEFINED ENV{USERPROFILE})
set(HUNTER_GATE_ROOT "$ENV{USERPROFILE}/.hunter" PARENT_SCOPE)
hunter_gate_status_debug(
"HUNTER_ROOT set using USERPROFILE environment variable"
)
return()
endif()
endif()
hunter_gate_fatal_error(
"Can't detect HUNTER_ROOT"
ERROR_PAGE "error.detect.hunter.root"
)
endfunction()
function(hunter_gate_download dir)
string(
COMPARE
NOTEQUAL
"$ENV{HUNTER_DISABLE_AUTOINSTALL}"
""
disable_autoinstall
)
if(disable_autoinstall AND NOT HUNTER_RUN_INSTALL)
hunter_gate_fatal_error(
"Hunter not found in '${dir}'"
"Set HUNTER_RUN_INSTALL=ON to auto-install it from '${HUNTER_GATE_URL}'"
"Settings:"
" HUNTER_ROOT: ${HUNTER_GATE_ROOT}"
" HUNTER_SHA1: ${HUNTER_GATE_SHA1}"
ERROR_PAGE "error.run.install"
)
endif()
string(COMPARE EQUAL "${dir}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("Empty 'dir' argument")
endif()
string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("HUNTER_GATE_SHA1 empty")
endif()
string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("HUNTER_GATE_URL empty")
endif()
set(done_location "${dir}/DONE")
set(sha1_location "${dir}/SHA1")
set(build_dir "${dir}/Build")
set(cmakelists "${dir}/CMakeLists.txt")
hunter_gate_status_debug("Locking directory: ${dir}")
file(LOCK "${dir}" DIRECTORY GUARD FUNCTION)
hunter_gate_status_debug("Lock done")
if(EXISTS "${done_location}")
# while waiting for lock other instance can do all the job
hunter_gate_status_debug("File '${done_location}' found, skip install")
return()
endif()
file(REMOVE_RECURSE "${build_dir}")
file(REMOVE_RECURSE "${cmakelists}")
file(MAKE_DIRECTORY "${build_dir}") # check directory permissions
# Disabling languages speeds up a little bit, reduces noise in the output
# and avoids path too long windows error
file(
WRITE
"${cmakelists}"
"cmake_minimum_required(VERSION 3.2)\n"
"project(HunterDownload LANGUAGES NONE)\n"
"include(ExternalProject)\n"
"ExternalProject_Add(\n"
" Hunter\n"
" URL\n"
" \"${HUNTER_GATE_URL}\"\n"
" URL_HASH\n"
" SHA1=${HUNTER_GATE_SHA1}\n"
" DOWNLOAD_DIR\n"
" \"${dir}\"\n"
" TLS_VERIFY\n"
" ${HUNTER_TLS_VERIFY}\n"
" SOURCE_DIR\n"
" \"${dir}/Unpacked\"\n"
" CONFIGURE_COMMAND\n"
" \"\"\n"
" BUILD_COMMAND\n"
" \"\"\n"
" INSTALL_COMMAND\n"
" \"\"\n"
")\n"
)
if(HUNTER_STATUS_DEBUG)
set(logging_params "")
else()
set(logging_params OUTPUT_QUIET)
endif()
hunter_gate_status_debug("Run generate")
# Need to add toolchain file too.
# Otherwise on Visual Studio + MDD this will fail with error:
# "Could not find an appropriate version of the Windows 10 SDK installed on this machine"
if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
get_filename_component(absolute_CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE)
set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=${absolute_CMAKE_TOOLCHAIN_FILE}")
else()
# 'toolchain_arg' can't be empty
set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=")
endif()
string(COMPARE EQUAL "${CMAKE_MAKE_PROGRAM}" "" no_make)
if(no_make)
set(make_arg "")
else()
# Test case: remove Ninja from PATH but set it via CMAKE_MAKE_PROGRAM
set(make_arg "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}")
endif()
execute_process(
COMMAND
"${CMAKE_COMMAND}"
"-H${dir}"
"-B${build_dir}"
"-G${CMAKE_GENERATOR}"
"${toolchain_arg}"
${make_arg}
WORKING_DIRECTORY "${dir}"
RESULT_VARIABLE download_result
${logging_params}
)
if(NOT download_result EQUAL 0)
hunter_gate_internal_error(
"Configure project failed."
"To reproduce the error run: ${CMAKE_COMMAND} -H${dir} -B${build_dir} -G${CMAKE_GENERATOR} ${toolchain_arg} ${make_arg}"
"In directory ${dir}"
)
endif()
hunter_gate_status_print(
"Initializing Hunter workspace (${HUNTER_GATE_SHA1})"
" ${HUNTER_GATE_URL}"
" -> ${dir}"
)
execute_process(
COMMAND "${CMAKE_COMMAND}" --build "${build_dir}"
WORKING_DIRECTORY "${dir}"
RESULT_VARIABLE download_result
${logging_params}
)
if(NOT download_result EQUAL 0)
hunter_gate_internal_error("Build project failed")
endif()
file(REMOVE_RECURSE "${build_dir}")
file(REMOVE_RECURSE "${cmakelists}")
file(WRITE "${sha1_location}" "${HUNTER_GATE_SHA1}")
file(WRITE "${done_location}" "DONE")
hunter_gate_status_debug("Finished")
endfunction()
# Must be a macro so master file 'cmake/Hunter' can
# apply all variables easily just by 'include' command
# (otherwise PARENT_SCOPE magic needed)
macro(HunterGate)
if(HUNTER_GATE_DONE)
# variable HUNTER_GATE_DONE set explicitly for external project
# (see `hunter_download`)
set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
endif()
# First HunterGate command will init Hunter, others will be ignored
get_property(_hunter_gate_done GLOBAL PROPERTY HUNTER_GATE_DONE SET)
if(NOT HUNTER_ENABLED)
# Empty function to avoid error "unknown function"
function(hunter_add_package)
endfunction()
set(
_hunter_gate_disabled_mode_dir
"${CMAKE_CURRENT_LIST_DIR}/cmake/Hunter/disabled-mode"
)
if(EXISTS "${_hunter_gate_disabled_mode_dir}")
hunter_gate_status_debug(
"Adding \"disabled-mode\" modules: ${_hunter_gate_disabled_mode_dir}"
)
list(APPEND CMAKE_PREFIX_PATH "${_hunter_gate_disabled_mode_dir}")
endif()
elseif(_hunter_gate_done)
hunter_gate_status_debug("Secondary HunterGate (use old settings)")
hunter_gate_self(
"${HUNTER_CACHED_ROOT}"
"${HUNTER_VERSION}"
"${HUNTER_SHA1}"
_hunter_self
)
include("${_hunter_self}/cmake/Hunter")
else()
set(HUNTER_GATE_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}")
string(COMPARE NOTEQUAL "${PROJECT_NAME}" "" _have_project_name)
if(_have_project_name)
hunter_gate_fatal_error(
"Please set HunterGate *before* 'project' command. "
"Detected project: ${PROJECT_NAME}"
ERROR_PAGE "error.huntergate.before.project"
)
endif()
cmake_parse_arguments(
HUNTER_GATE "LOCAL" "URL;SHA1;GLOBAL;FILEPATH" "" ${ARGV}
)
string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" _empty_sha1)
string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" _empty_url)
string(
COMPARE
NOTEQUAL
"${HUNTER_GATE_UNPARSED_ARGUMENTS}"
""
_have_unparsed
)
string(COMPARE NOTEQUAL "${HUNTER_GATE_GLOBAL}" "" _have_global)
string(COMPARE NOTEQUAL "${HUNTER_GATE_FILEPATH}" "" _have_filepath)
if(_have_unparsed)
hunter_gate_user_error(
"HunterGate unparsed arguments: ${HUNTER_GATE_UNPARSED_ARGUMENTS}"
)
endif()
if(_empty_sha1)
hunter_gate_user_error("SHA1 suboption of HunterGate is mandatory")
endif()
if(_empty_url)
hunter_gate_user_error("URL suboption of HunterGate is mandatory")
endif()
if(_have_global)
if(HUNTER_GATE_LOCAL)
hunter_gate_user_error("Unexpected LOCAL (already has GLOBAL)")
endif()
if(_have_filepath)
hunter_gate_user_error("Unexpected FILEPATH (already has GLOBAL)")
endif()
endif()
if(HUNTER_GATE_LOCAL)
if(_have_global)
hunter_gate_user_error("Unexpected GLOBAL (already has LOCAL)")
endif()
if(_have_filepath)
hunter_gate_user_error("Unexpected FILEPATH (already has LOCAL)")
endif()
endif()
if(_have_filepath)
if(_have_global)
hunter_gate_user_error("Unexpected GLOBAL (already has FILEPATH)")
endif()
if(HUNTER_GATE_LOCAL)
hunter_gate_user_error("Unexpected LOCAL (already has FILEPATH)")
endif()
endif()
hunter_gate_detect_root() # set HUNTER_GATE_ROOT
# Beautify path, fix probable problems with windows path slashes
get_filename_component(
HUNTER_GATE_ROOT "${HUNTER_GATE_ROOT}" ABSOLUTE
)
hunter_gate_status_debug("HUNTER_ROOT: ${HUNTER_GATE_ROOT}")
if(NOT HUNTER_ALLOW_SPACES_IN_PATH)
string(FIND "${HUNTER_GATE_ROOT}" " " _contain_spaces)
if(NOT _contain_spaces EQUAL -1)
hunter_gate_fatal_error(
"HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces."
"Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error"
"(Use at your own risk!)"
ERROR_PAGE "error.spaces.in.hunter.root"
)
endif()
endif()
string(
REGEX
MATCH
"[0-9]+\\.[0-9]+\\.[0-9]+[-_a-z0-9]*"
HUNTER_GATE_VERSION
"${HUNTER_GATE_URL}"
)
string(COMPARE EQUAL "${HUNTER_GATE_VERSION}" "" _is_empty)
if(_is_empty)
set(HUNTER_GATE_VERSION "unknown")
endif()
hunter_gate_self(
"${HUNTER_GATE_ROOT}"
"${HUNTER_GATE_VERSION}"
"${HUNTER_GATE_SHA1}"
_hunter_self
)
set(_master_location "${_hunter_self}/cmake/Hunter")
if(EXISTS "${HUNTER_GATE_ROOT}/cmake/Hunter")
# Hunter downloaded manually (e.g. by 'git clone')
set(_unused "xxxxxxxxxx")
set(HUNTER_GATE_SHA1 "${_unused}")
set(HUNTER_GATE_VERSION "${_unused}")
else()
get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE)
set(_done_location "${_archive_id_location}/DONE")
set(_sha1_location "${_archive_id_location}/SHA1")
# Check Hunter already downloaded by HunterGate
if(NOT EXISTS "${_done_location}")
hunter_gate_download("${_archive_id_location}")
endif()
if(NOT EXISTS "${_done_location}")
hunter_gate_internal_error("hunter_gate_download failed")
endif()
if(NOT EXISTS "${_sha1_location}")
hunter_gate_internal_error("${_sha1_location} not found")
endif()
file(READ "${_sha1_location}" _sha1_value)
string(TOLOWER "${_sha1_value}" _sha1_value_lower)
string(TOLOWER "${HUNTER_GATE_SHA1}" _HUNTER_GATE_SHA1_lower)
string(COMPARE EQUAL "${_sha1_value_lower}" "${_HUNTER_GATE_SHA1_lower}" _is_equal)
if(NOT _is_equal)
hunter_gate_internal_error(
"Short SHA1 collision:"
" ${_sha1_value} (from ${_sha1_location})"
" ${HUNTER_GATE_SHA1} (HunterGate)"
)
endif()
if(NOT EXISTS "${_master_location}")
hunter_gate_user_error(
"Master file not found:"
" ${_master_location}"
"try to update Hunter/HunterGate"
)
endif()
endif()
include("${_master_location}")
set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
endif()
endmacro()

@ -121,22 +121,6 @@ MACRO(NL_ADD_RUNTIME_FLAGS name)
ENDMACRO(NL_ADD_RUNTIME_FLAGS) ENDMACRO(NL_ADD_RUNTIME_FLAGS)
MACRO(NL_ADD_STATIC_VID_DRIVERS name) MACRO(NL_ADD_STATIC_VID_DRIVERS name)
IF(HUNTER_ENABLED)
IF(WIN32)
SET(drv_suffix "_win")
ELSE()
SET(drv_suffix "")
ENDIF()
IF(WIN32 AND WITH_DRIVER_DIRECT3D)
TARGET_LINK_LIBRARIES(${name} nel_drv_direct3d${drv_suffix})
ENDIF()
IF(WITH_DRIVER_OPENGL)
TARGET_LINK_LIBRARIES(${name} nel_drv_opengl${drv_suffix})
ENDIF()
IF(WITH_DRIVER_OPENGLES)
TARGET_LINK_LIBRARIES(${name} nel_drv_opengles${drv_suffix})
ENDIF()
ELSE()
IF(WITH_STATIC_DRIVERS) IF(WITH_STATIC_DRIVERS)
IF(WIN32) IF(WIN32)
IF(WITH_DRIVER_DIRECT3D) IF(WITH_DRIVER_DIRECT3D)
@ -160,29 +144,9 @@ ELSE()
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF()#hunter
ENDMACRO(NL_ADD_STATIC_VID_DRIVERS) ENDMACRO(NL_ADD_STATIC_VID_DRIVERS)
MACRO(NL_ADD_STATIC_SND_DRIVERS name) MACRO(NL_ADD_STATIC_SND_DRIVERS name)
IF(HUNTER_ENABLED)
IF(WIN32)
SET(drv_suffix "_win")
ELSE()
SET(drv_suffix "")
ENDIF()
IF(WIN32 AND WITH_DRIVER_DSOUND)
TARGET_LINK_LIBRARIES(${name} nel_drv_dsound${drv_suffix})
ENDIF()
IF(WIN32 AND WITH_DRIVER_XAUDIO2)
TARGET_LINK_LIBRARIES(${name} nel_drv_xaudio2${drv_suffix})
ENDIF()
IF(WITH_DRIVER_FMOD)
TARGET_LINK_LIBRARIES(${name} nel_drv_fmod${drv_suffix})
ENDIF()
IF(WITH_DRIVER_OPENAL)
TARGET_LINK_LIBRARIES(${name} nel_drv_openal${drv_suffix})
ENDIF()
ELSE()
IF(WITH_STATIC_DRIVERS) IF(WITH_STATIC_DRIVERS)
IF(WIN32) IF(WIN32)
IF(WITH_DRIVER_DSOUND) IF(WITH_DRIVER_DSOUND)
@ -211,7 +175,6 @@ ELSE()
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF() #hunter
ENDMACRO(NL_ADD_STATIC_SND_DRIVERS) ENDMACRO(NL_ADD_STATIC_SND_DRIVERS)
### ###
@ -286,8 +249,6 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS)
OPTION(WITH_ASSIMP "Use assimp exporter" OFF) OPTION(WITH_ASSIMP "Use assimp exporter" OFF)
OPTION(WITH_LIBGSF "Use libgsf for max file library" OFF) OPTION(WITH_LIBGSF "Use libgsf for max file library" OFF)
OPTION(WITH_FFMPEG "Use ffmpeg for audio decoder" OFF)
### ###
# GUI toolkits # GUI toolkits
### ###
@ -1232,11 +1193,7 @@ MACRO(SETUP_EXTERNAL)
ENDIF() ENDIF()
IF(WIN32) IF(WIN32)
IF (HUNTER_ENABLED) FIND_PACKAGE(External REQUIRED)
FIND_PACKAGE(External QUIET)
ELSE()
FIND_PACKAGE(External REQUIRED)
ENDIF()
# If using custom boost, we need to define the right variables used by official boost CMake module # If using custom boost, we need to define the right variables used by official boost CMake module
IF(DEFINED BOOST_DIR) IF(DEFINED BOOST_DIR)
@ -1279,7 +1236,7 @@ MACRO(SETUP_EXTERNAL)
IF(WIN32) IF(WIN32)
# Must include DXSDK before WINSDK # Must include DXSDK before WINSDK
FIND_PACKAGE(DirectXSDK) FIND_PACKAGE(DirectXSDK REQUIRED)
# IF(DXSDK_INCLUDE_DIR) # IF(DXSDK_INCLUDE_DIR)
# INCLUDE_DIRECTORIES(${DXSDK_INCLUDE_DIR}) # INCLUDE_DIRECTORIES(${DXSDK_INCLUDE_DIR})
# ENDIF() # ENDIF()
@ -1288,8 +1245,5 @@ MACRO(SETUP_EXTERNAL)
IF(MSVC) IF(MSVC)
FIND_PACKAGE(MSVC REQUIRED) FIND_PACKAGE(MSVC REQUIRED)
FIND_PACKAGE(WindowsSDK REQUIRED) FIND_PACKAGE(WindowsSDK REQUIRED)
IF(NOT DXSDK_DIR)
MESSAGE(FATAL_ERROR "DirectX SDK or DirectX files from Windows SDK not found.")
ENDIF()
ENDIF() ENDIF()
ENDMACRO() ENDMACRO()

@ -1,55 +1,59 @@
jobs: jobs:
- job: ubuntu18 - job: ubuntu16
timeoutInMinutes: 120 timeoutInMinutes: 120
pool: pool:
vmImage: 'ubuntu-18.04' vmImage: 'Ubuntu-16.04'
steps: steps:
- script: | - script: |
sudo apt update sudo apt-get update
sudo apt install -y software-properties-common sudo apt-get install -y software-properties-common
# sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update sudo apt-get update
sudo apt install cmake build-essential -y sudo apt-get install cmake build-essential -y
sudo apt install gcc-8 g++-8 -y sudo apt-get install gcc-8 g++-8 -y
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 60 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 60
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 60 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 60
sudo apt install bison autoconf automake -y sudo apt-get install bison autoconf automake -y
sudo apt install libpng-dev -y sudo apt-get install libpng12-dev -y
sudo apt install libjpeg-dev -y sudo apt-get install libjpeg-dev -y
sudo apt install libgif-dev libfreetype6-dev -y sudo apt-get install libgif-dev libfreetype6-dev -y
sudo apt install freeglut3-dev -y sudo apt-get install freeglut3-dev -y
sudo apt install liblua5.2-dev libluabind-dev libcpptest-dev -y sudo apt-get install liblua5.1-dev libluabind-dev libcpptest-dev -y
sudo apt install libogg-dev libvorbis-dev libopenal-dev -y sudo apt-get install libogg-dev libvorbis-dev libopenal-dev -y
sudo apt install libavcodec-dev libavformat-dev libavdevice-dev libswscale-dev libpostproc-dev -y sudo apt-get install libavcodec-dev libavformat-dev libavdevice-dev libswscale-dev libpostproc-dev -y
sudo apt install libmysqlclient-dev -y sudo apt-get install libmysqlclient-dev -y
sudo apt install libxml2-dev -y sudo apt-get install libxml2-dev -y
sudo apt install libcurl4-openssl-dev libssl-dev -y sudo apt-get install libcurl4-openssl-dev libssl-dev -y
sudo apt install libsquish-dev -y sudo apt-get install libsquish-dev -y
sudo apt install liblzma-dev -y sudo apt-get install liblzma-dev -y
sudo apt install libgsf-1-dev -y sudo apt-get install libgsf-1-dev -y
sudo apt install qtbase5-dev qttools5-dev qttools5-dev-tools sudo apt-get install qtbase5-dev qttools5-dev qttools5-dev-tools
displayName: 'Dependencies' displayName: 'Dependencies'
- script: | - script: |
mkdir build mkdir build
cmake --version cmake --version
cd build cd build
cmake -DWITH_STATIC=ON -DWITH_NEL_TESTS=OFF -DWITH_NEL_SAMPLES=ON -DWITH_LUA51=OFF -DWITH_LUA52=ON -DWITH_RYZOM=ON -DWITH_RYZOM_SERVER=ON -DWITH_RYZOM_CLIENT=ON -DWITH_RYZOM_TOOLS=ON -DWITH_NEL_TOOLS=ON -DWITH_NELNS=ON -DWITH_NELNS_LOGIN_SYSTEM=ON -DWITH_NELNS_SERVER=ON -DWITH_QT5=ON -DWITH_LIBGSF=ON .. cmake -DWITH_STATIC=ON -DWITH_NEL_TESTS=OFF -DWITH_NEL_SAMPLES=ON -DWITH_LUA51=ON -DWITH_RYZOM=ON -DWITH_RYZOM_SERVER=ON -DWITH_RYZOM_CLIENT=ON -DWITH_RYZOM_TOOLS=ON -DWITH_NEL_TOOLS=ON -DWITH_NELNS=ON -DWITH_NELNS_LOGIN_SYSTEM=ON -DWITH_NELNS_SERVER=ON -DWITH_QT5=ON -DWITH_LIBGSF=ON ..
cat CMakeCache.txt cat CMakeCache.txt
displayName: 'CMake' displayName: 'CMake'
- script: | - script: |
cd build cd build
make -j`nproc` make -j`nproc`
displayName: 'Make' displayName: 'Make'
- job: ubuntu20 - job: ubuntu18
timeoutInMinutes: 120 timeoutInMinutes: 120
pool: pool:
vmImage: 'ubuntu-20.04' vmImage: 'ubuntu-18.04'
steps: steps:
- script: | - script: |
sudo apt update sudo apt update
sudo apt install -y software-properties-common sudo apt install -y software-properties-common
# sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update sudo apt update
sudo apt install cmake build-essential -y sudo apt install cmake build-essential -y
sudo apt install gcc-8 g++-8 -y
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 60
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 60
sudo apt install bison autoconf automake -y sudo apt install bison autoconf automake -y
sudo apt install libpng-dev -y sudo apt install libpng-dev -y
sudo apt install libjpeg-dev -y sudo apt install libjpeg-dev -y
@ -77,88 +81,3 @@ jobs:
cd build cd build
make -j`nproc` make -j`nproc`
displayName: 'Make' displayName: 'Make'
- job: windows2019
timeoutInMinutes: 120
pool:
vmImage: 'windows-2019'
steps:
- checkout: self
fetchDepth: 1
- task: Cache@2
inputs:
key: 'hunter-win2019-x64-rel'
path: "c:/.hunter/_Base/Cache"
- task: CmdLine@2
inputs:
script: |
aria2c https://download.microsoft.com/download/A/E/7/AE743F1F-632B-4809-87A9-AA1BB3458E31/DXSDK_Jun10.exe
7z x DXSDK_Jun10.exe -oC:\ -r -y
del DXSDK_Jun10.exe
- task: CMake@1
inputs:
workingDirectory: build.release
cmakeArgs: '-DCMAKE_CONFIGURATION_TYPES=Release -DHUNTER_ENABLED=ON -DHUNTER_CONFIGURATION_TYPES=Release -DFINAL_VERSION=OFF -DWITH_NEL_TESTS=OFF -DWITH_NEL_SAMPLES=OFF -DWITH_NEL_TOOLS=OFF -DWITH_RYZOM_TOOLS=OFF -DWITH_RYZOM_SERVER=OFF -DWITH_RYZOM_CLIENT=ON -DWITH_DRIVER_OPENGL=ON -DWITH_DRIVER_OPENAL=ON -DWITH_DRIVER_DIRECT3D=ON -DWITH_DRIVER_XAUDIO2=ON -DDXSDK_DIR=C:/DXSDK ..'
- task: MSBuild@1
inputs:
solution: build.release/ALL_BUILD.vcxproj
maximumCpuCount: true
configuration: release
platform: 'x64'
- job: ubuntu18hunter
timeoutInMinutes: 120
pool:
vmImage: ubuntu-18.04
steps:
- checkout: self
fetchDepth: 0
- script: |
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends libasound2-dev libgl1-mesa-dev libjack-dev libpulse-dev libxrandr-dev libxrender-dev libxxf86vm-dev
displayName: 'Dependencies'
- task: Cache@2
inputs:
key: 'hunter317-ubuntu18-rel"'
path: "$(Pipeline.Workspace)/.hunter/_Base/Cache"
- script: |
mkdir build.release
cmake --version
cd build.release
unset SYSTEM
export MAKEFLAGS=-j`nproc`
cmake -DCMAKE_BUILD_TYPE=Release -DHUNTER_ENABLED=ON -DHUNTER_CONFIGURATION_TYPES=Release -DHUNTER_ROOT="$(Pipeline.Workspace)/.hunter" -DFINAL_VERSION=OFF -DWITH_NEL_TESTS=OFF -DWITH_NEL_SAMPLES=OFF -DWITH_NEL_TOOLS=OFF -DWITH_RYZOM_TOOLS=OFF -DWITH_RYZOM_SERVER=OFF -DWITH_RYZOM_CLIENT=ON -DWITH_DRIVER_OPENGL=ON -DWITH_DRIVER_OPENAL=ON ..
displayName: 'CMake, release'
- script: |
cd build.release
make -j`nproc`
displayName: 'Make, release'
#- task: PublishPipelineArtifact@1
# inputs:
# targetPath: build.release/bin
# artifactName: RyzomUbuntu18Release
- job: macOS11
timeoutInMinutes: 120
pool:
vmImage: 'macOS-11'
steps:
- checkout: self
fetchDepth: 0
- task: Cache@2
inputs:
key: 'hunter317-macOS11-rel"'
path: "$(Pipeline.Workspace)/.hunter/_Base/Cache"
- task: CMake@1
inputs:
workingDirectory: build.release
cmakeArgs: '-GXcode -DCMAKE_CONFIGURATION_TYPES=Release -DHUNTER_ENABLED=ON -DHUNTER_STATUS_DEBUG=ON -DHUNTER_CONFIGURATION_TYPES=Release -DHUNTER_ROOT="$(Pipeline.Workspace)/.hunter" -DWITH_LIBXML2_ICONV=OFF -DFINAL_VERSION=OFF -DWITH_NEL_TESTS=OFF -DWITH_NEL_SAMPLES=OFF -DWITH_NEL_TOOLS=OFF -DWITH_RYZOM_TOOLS=OFF -DWITH_RYZOM_SERVER=OFF -DWITH_RYZOM_CLIENT=ON -DWITH_DRIVER_OPENGL=ON -DWITH_DRIVER_OPENAL=ON -DWITH_DRIVER_DIRECT3D=OFF -DWITH_DRIVER_XAUDIO2=OFF ..'
- task: Xcode@5
inputs:
actions: 'build'
configuration: Release
sdk: macosx12.0
xcWorkspacePath: 'build.release/RyzomCore.xcodeproj'
scheme: 'ALL_BUILD'
packageApp: false
#- task: PublishPipelineArtifact@1
# inputs:
# targetPath: build.release/bin/
# artifactName: RyzomClientMacOS11Release

@ -10,25 +10,17 @@ IF(WIN32)
ENDIF() ENDIF()
IF(WITH_3D) IF(WITH_3D)
IF(HUNTER_ENABLED) FIND_PACKAGE(FreeType)
HUNTER_ADD_PACKAGE(freetype)
FIND_PACKAGE(freetype CONFIG REQUIRED)
SET(FREETYPE_LIBRARIES freetype::freetype)
ELSE()
FIND_PACKAGE(FreeType)
ENDIF() #hunter
IF(WITH_NEL_CEGUI) IF(WITH_NEL_CEGUI)
FIND_PACKAGE(CEGUI) FIND_PACKAGE(CEGUI)
ENDIF() ENDIF()
ENDIF() ENDIF()
IF(WITH_SOUND AND NOT HUNTER_ENABLED) IF(WITH_SOUND)
FIND_PACKAGE(Ogg) FIND_PACKAGE(Ogg)
FIND_PACKAGE(Vorbis) FIND_PACKAGE(Vorbis)
IF(WITH_FFMPEG) FIND_PACKAGE(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWRESAMPLE)
FIND_PACKAGE(FFmpeg REQUIRED COMPONENTS AVCODEC AVFORMAT AVUTIL SWRESAMPLE)
ENDIF()
IF(WITH_DRIVER_OPENAL) IF(WITH_DRIVER_OPENAL)
FIND_PACKAGE(OpenAL) FIND_PACKAGE(OpenAL)

@ -969,7 +969,6 @@ namespace NLGUI
// stop all curl downalods (html and data) // stop all curl downalods (html and data)
void releaseDownloads(); void releaseDownloads();
void releaseDataDownloads();
void checkDownloads(); void checkDownloads();
// _CurlWWW download finished // _CurlWWW download finished

@ -76,16 +76,16 @@ namespace NLGUI
void reindexChilds(); void reindexChilds();
// escape text tag or attribute value // escape text tag or attribute value
std::string htmlEscape(const std::string &val) const; std::string htmlEscape(std::string val, bool isAttribute = false) const;
// serialize element attributes as string // serialize element attributes as string
std::string serializeAttributes(bool escape = true) const; std::string serializeAttributes() const;
// serialize child elements as html string // serialize child elements as html string
std::string serializeChilds(bool escape = true) const; std::string serializeChilds() const;
// serialize itself and children as html string // serialize itself and children as html string
std::string serialize(bool escape = true) const; std::string serialize() const;
// debug // debug
std::string toString(bool tree = false, uint depth = 0) const; std::string toString(bool tree = false, uint depth = 0) const;

@ -119,8 +119,8 @@ namespace NLGUI
void enableStringSelection(uint start, uint end); void enableStringSelection(uint start, uint end);
void disableStringSelection(); void disableStringSelection();
/// Get displayed text /// Get
std::string getText() const { return _Text; } std::string getText() const { return _HardText.empty() ? _Text : _HardText; }
#ifdef RYZOM_LUA_UCSTRING #ifdef RYZOM_LUA_UCSTRING
ucstring getTextAsUtf16() const; // Compatibility ucstring getTextAsUtf16() const; // Compatibility
ucstring getHardTextAsUtf16() const; // Compatibility ucstring getHardTextAsUtf16() const; // Compatibility
@ -188,7 +188,6 @@ namespace NLGUI
/// From a line number, get the character at which it ends (not including any '\n' ), or -1 if invalid /// From a line number, get the character at which it ends (not including any '\n' ), or -1 if invalid
void getLineEndIndex(uint line, sint &index, bool &endOfPreviousLine) const; void getLineEndIndex(uint line, sint &index, bool &endOfPreviousLine) const;
/// If localized, return localization key (ie "uiLanguage"), else return displayed text.
std::string getHardText() const { return _HardText.empty() ? _Text : _HardText; } std::string getHardText() const { return _HardText.empty() ? _Text : _HardText; }
void setHardText (const std::string &ht); //< Localizes strings starting with "ui" void setHardText (const std::string &ht); //< Localizes strings starting with "ui"
#ifdef RYZOM_LUA_UCSTRING #ifdef RYZOM_LUA_UCSTRING
@ -283,10 +282,8 @@ namespace NLGUI
bool _FontSizeCoef; bool _FontSizeCoef;
bool _Embolden; bool _Embolden;
bool _Oblique; bool _Oblique;
// width of the font in pixel. // width of the font in pixel. Just a Hint for tabing format (computed with '_')
float _FontWidth; float _FontWidth;
// width of tabs
float _TabWidth;
// strings to use when computing font size // strings to use when computing font size
std::string _FontSizingChars; std::string _FontSizingChars;
std::string _FontSizingFallback; std::string _FontSizingFallback;

@ -96,7 +96,6 @@ public:
_Property = 0; _Property = 0;
_oldProperty = 0; _oldProperty = 0;
_Type = UNKNOWN; _Type = UNKNOWN;
m_Nullable = false;
_Changed = false; _Changed = false;
_LastChangeGC = 0; _LastChangeGC = 0;
} }
@ -236,9 +235,6 @@ private:
/// property type /// property type
EPropType _Type; EPropType _Type;
/// nullable
bool m_Nullable;
/// true if this value has changed /// true if this value has changed
bool _Changed; bool _Changed;

@ -380,7 +380,7 @@ extern bool _assertex_stop_1(bool &ignoreNextTime);
#define nlassume(exp) do { } while (0) #define nlassume(exp) do { } while (0)
#endif #endif
#ifdef NL_NO_ASSERT #ifdef NL_NO_DEBUG
# define nlassert(exp) nlassume(exp) # define nlassert(exp) nlassume(exp)
# define nlassertonce(exp) nlassume(exp) # define nlassertonce(exp) nlassume(exp)
# define nlassertex(exp, str) nlassume(exp) # define nlassertex(exp, str) nlassume(exp)

@ -174,6 +174,10 @@
# define NL_COMP_GCC # define NL_COMP_GCC
#endif #endif
#if defined(_HAS_CPP0X) || defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(NL_COMP_VC_VERSION) && NL_COMP_VC_VERSION >= 110)
# define NL_ISO_CPP0X_AVAILABLE
#endif
#if defined(NL_COMP_GCC) && (__cplusplus >= 201103L) #if defined(NL_COMP_GCC) && (__cplusplus >= 201103L)
# define NL_NO_EXCEPTION_SPECS # define NL_NO_EXCEPTION_SPECS
#endif #endif
@ -229,10 +233,6 @@
# endif # endif
#endif #endif
#if defined(_HAS_CPP0X) || defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(NL_COMP_VC_VERSION) && NL_COMP_VC_VERSION >= 110) || (defined(NL_COMP_GCC) && (GCC_VERSION >= 40400) && (__cplusplus >= 201103L))
# define NL_ISO_CPP0X_AVAILABLE
#endif
// Remove stupid Visual C++ warnings // Remove stupid Visual C++ warnings
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
# pragma warning (disable : 4503) // STL: Decorated name length exceeded, name was truncated # pragma warning (disable : 4503) // STL: Decorated name length exceeded, name was truncated
@ -274,7 +274,7 @@
//#define NL_NO_DEBUG //#define NL_NO_DEBUG
#undef NL_NO_DEBUG #undef NL_NO_DEBUG
#define NL_NO_ASSERT
// Standard types // Standard types

@ -34,7 +34,7 @@ class CCurlHttpClient
public: public:
/// Constructor /// Constructor
CCurlHttpClient() : _CurlStruct(NULL), m_Verify(true) {} CCurlHttpClient() : _CurlStruct(NULL) {}
/// Connect to an http server (string by val is intended). If you specify a whole URL, an attempt will be made to determine the server. /// Connect to an http server (string by val is intended). If you specify a whole URL, an attempt will be made to determine the server.
bool connect(const std::string &server); bool connect(const std::string &server);
@ -63,8 +63,6 @@ public:
/// Disconnect if connected (otherwise does nothing) /// Disconnect if connected (otherwise does nothing)
void disconnect(); void disconnect();
const char *lastError() { return &m_ErrorBuf[0]; }
protected: protected:
/// Helper /// Helper
@ -80,10 +78,6 @@ private:
std::vector<uint8> _ReceiveBuffer; std::vector<uint8> _ReceiveBuffer;
std::string _Auth; // must be kept here because curl only stores the char pointer std::string _Auth; // must be kept here because curl only stores the char pointer
std::vector<char> m_ErrorBuf;
bool m_Verify;
}; };
extern CCurlHttpClient CurlHttpClient; extern CCurlHttpClient CurlHttpClient;

@ -4,7 +4,6 @@ ADD_EXECUTABLE(nl_sample_font WIN32 ${SRC})
ADD_DEFINITIONS(-DFONT_DIR="\\"${NL_SHARE_ABSOLUTE_PREFIX}/nl_sample_font/\\"") ADD_DEFINITIONS(-DFONT_DIR="\\"${NL_SHARE_ABSOLUTE_PREFIX}/nl_sample_font/\\"")
# TODO: hunter TARGET_LINK_LIBRARIES(nl_sample_font PRIVATE nelmisc nel3d)
TARGET_LINK_LIBRARIES(nl_sample_font nelmisc nel3d) TARGET_LINK_LIBRARIES(nl_sample_font nelmisc nel3d)
NL_DEFAULT_PROPS(nl_sample_font "NeL, Samples, 3D: Font") NL_DEFAULT_PROPS(nl_sample_font "NeL, Samples, 3D: Font")
NL_ADD_RUNTIME_FLAGS(nl_sample_font) NL_ADD_RUNTIME_FLAGS(nl_sample_font)

@ -999,9 +999,6 @@ private:
bool createWindow(const GfxMode& mode); bool createWindow(const GfxMode& mode);
bool destroyWindow(); bool destroyWindow();
// Return monitor info and positon in multi monitor setup or false if monitor not found.
bool getMonitorByName(const std::string &name, sint32 &x, sint32 &y, uint32 &w, uint32 &h) const;
enum EWindowStyle { EWSWindowed, EWSFullscreen }; enum EWindowStyle { EWSWindowed, EWSFullscreen };
void setWindowSize(uint32 width, uint32 height); void setWindowSize(uint32 width, uint32 height);

@ -650,6 +650,8 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
_win = EmptyWindow; _win = EmptyWindow;
_CurrentMode = mode;
_WindowVisible = false; _WindowVisible = false;
_Resizable = resizeable; _Resizable = resizeable;
_DestroyWindow = false; _DestroyWindow = false;
@ -1192,8 +1194,6 @@ bool CDriverGL::saveScreenMode()
#ifdef HAVE_XRANDR #ifdef HAVE_XRANDR
// TODO: if using mode switching, save current xrandr mode to _OldSizeID
res = true;
if (!res && _xrandr_version > 0) if (!res && _xrandr_version > 0)
{ {
XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen)); XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen));
@ -1254,8 +1254,6 @@ bool CDriverGL::restoreScreenMode()
#ifdef HAVE_XRANDR #ifdef HAVE_XRANDR
// TODO: if using mode switching, then restore mode from _OldSizeID
res = true;
if (!res && _xrandr_version > 0) if (!res && _xrandr_version > 0)
{ {
Window root = RootWindow(_dpy, screen); Window root = RootWindow(_dpy, screen);
@ -1350,8 +1348,7 @@ bool CDriverGL::setScreenMode(const GfxMode &mode)
&& mode.Width == previousMode.Width && mode.Width == previousMode.Width
&& mode.Height == previousMode.Height && mode.Height == previousMode.Height
&& mode.Depth == previousMode.Depth && mode.Depth == previousMode.Depth
&& mode.Frequency == previousMode.Frequency && mode.Frequency == previousMode.Frequency)
&& mode.DisplayDevice == previousMode.DisplayDevice)
return true; return true;
#if defined(NL_OS_WINDOWS) #if defined(NL_OS_WINDOWS)
@ -1391,8 +1388,6 @@ bool CDriverGL::setScreenMode(const GfxMode &mode)
bool found = false; bool found = false;
#ifdef HAVE_XRANDR #ifdef HAVE_XRANDR
// TODO: implement mode switching using xrandr crts
found = true;
if (!found && _xrandr_version > 0) if (!found && _xrandr_version > 0)
{ {
@ -1916,92 +1911,8 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle)
return true; return true;
} }
bool CDriverGL::getMonitorByName(const std::string &name, sint32 &x, sint32 &y, uint32 &w, uint32 &h) const
{
bool found = false;
#if HAVE_XRANDR
int screen = DefaultScreen(_dpy);
// xrandr 1.5+
if (_xrandr_version >= 105)
{
int nmonitors = 0;
XRRMonitorInfo *monitor = XRRGetMonitors(_dpy, RootWindow(_dpy, screen), 1, &nmonitors);
if (!monitor)
return false;
for(sint i = 0; i< nmonitors; ++i)
{
char* pname = XGetAtomName(_dpy, monitor[i].name);
found = (nlstricmp(pname, name) == 0);
XFree(pname);
if (found)
{
x = monitor[i].x;
y = monitor[i].y;
w = monitor[i].width;
h = monitor[i].height;
break;
}
}
XRRFreeMonitors(monitor);
}
else
{
XRRScreenResources *resources = XRRGetScreenResourcesCurrent(_dpy, RootWindow(_dpy, screen));
if (!resources)
resources = XRRGetScreenResources(_dpy, RootWindow(_dpy, screen));
for(uint i = 0; i < resources->noutput; ++i)
{
XRROutputInfo *output = XRRGetOutputInfo(_dpy, resources, resources->outputs[i]);
if (!output)
continue;
if (output->crtc && output->connection == RR_Connected && nlstricmp(name, output->name) == 0)
{
// physical monitor
XRRCrtcInfo *crtc = XRRGetCrtcInfo(_dpy, resources, output->crtc);
if (crtc)
{
found = true;
x = crtc->x;
y = crtc->y;
// TODO: test rotation
if (crtc->rotation == RR_Rotate_0 || crtc->rotation == RR_Rotate_180)
{
w = crtc->width;
h = crtc->height;
}
else
{
w = crtc->height;
h = crtc->width;
}
XRRFreeCrtcInfo(crtc);
}
}
XRRFreeOutputInfo(output);
if (found)
break;
}
XRRFreeScreenResources(resources);
}
#endif
return found;
}
// -------------------------------------------------- // --------------------------------------------------
bool CDriverGL::setMode(const GfxMode& amode) bool CDriverGL::setMode(const GfxMode& mode)
{ {
H_AUTO_OGL(CDriverGL_setMode); H_AUTO_OGL(CDriverGL_setMode);
@ -2009,10 +1920,6 @@ bool CDriverGL::setMode(const GfxMode& amode)
if (!_DestroyWindow) if (!_DestroyWindow)
return true; return true;
#if !(HAVE_XRANDR)
const GfxMode &mode = amode;
#endif
#if defined(NL_OS_WINDOWS) #if defined(NL_OS_WINDOWS)
// save relative cursor // save relative cursor
POINT cursorPos; POINT cursorPos;
@ -2022,92 +1929,21 @@ bool CDriverGL::setMode(const GfxMode& amode)
BOOL cursorPosOk = isSystemCursorInClientArea() BOOL cursorPosOk = isSystemCursorInClientArea()
&& GetCursorPos(&cursorPos) && GetCursorPos(&cursorPos)
&& ScreenToClient(_win, &cursorPos); && ScreenToClient(_win, &cursorPos);
// FIXME: this probably needs to use _CurrentMode instead of mode
sint curX = (sint)cursorPos.x * (sint)mode.Width; sint curX = (sint)cursorPos.x * (sint)mode.Width;
sint curY = (sint)cursorPos.y * (sint)mode.Height; sint curY = (sint)cursorPos.y * (sint)mode.Height;
#endif #endif
#if HAVE_XRANDR
GfxMode mode = amode;
if (!mode.Windowed)
{
GfxMode current;
if (!getCurrentScreenMode(current))
nlinfo("3D: XrandR: Reading active monitor info failed");
sint newX = _WindowX;
sint newY = _WindowY;
// make sure resolution matches requested or currently active monitor's resolution
mode.Width = current.Width;
mode.Height = current.Height;
if (!mode.DisplayDevice.empty())
{
uint newW = current.Width;
uint newH = current.Height;
if (getMonitorByName(mode.DisplayDevice, newX, newY, newW, newH))
{
mode.Width = newW;
mode.Height = newH;
}
else
{
nlinfo("3D: XrandR: Reading requested monitor '%s' info failed, using '%s'", mode.DisplayDevice.c_str(), current.DisplayDevice.c_str());
mode.DisplayDevice = current.DisplayDevice;
}
}
// switching monitors.
// first move mouse pointer to target monitor and then move window.
// if window is visible, then also restore mouse relative position.
if (!mode.DisplayDevice.empty() && mode.DisplayDevice != current.DisplayDevice)
{
setWindowStyle(EWSWindowed);
int screen = DefaultScreen(_dpy);
Window root = RootWindow(_dpy, screen);
uint mouseX = mode.Width / 2;
uint mouseY = mode.Height / 2;
XWindowAttributes xwa;
XGetWindowAttributes(_dpy, _win, &xwa);
if (xwa.map_state != IsUnmapped)
{
Window root_win;
Window child_win;
sint root_x, root_y, win_x, win_y;
uint mask;
Bool res = XQueryPointer(_dpy, _win, &root_win, &child_win, &root_x, &root_y, &win_x, &win_y, &mask);
if (res)
{
mouseX = (uint)((float)win_x * mode.Width / current.Width);
mouseY = (uint)((float)win_y * mode.Height / current.Height);
}
}
XWarpPointer(_dpy, None, root, None, None, None, None, newX + mouseX, newY + mouseY);
XMoveWindow(_dpy, _win, newX, newY);
_WindowX = newX;
_WindowY = newY;
setWindowStyle(EWSFullscreen);
}
}
#endif
if (!setScreenMode(mode)) if (!setScreenMode(mode))
return false; return false;
_CurrentMode.Depth = mode.Depth;
_CurrentMode.Frequency = mode.Frequency;
_CurrentMode.DisplayDevice = mode.DisplayDevice;
// when changing window style, it's possible system change window size too // when changing window style, it's possible system change window size too
setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen); setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen);
setWindowPos(_WindowX, _WindowY);
if (!mode.Windowed)
_CurrentMode.Depth = mode.Depth;
setWindowSize(mode.Width, mode.Height); setWindowSize(mode.Width, mode.Height);
setWindowPos(_WindowX, _WindowY);
switch (_CurrentMode.Depth) switch (_CurrentMode.Depth)
{ {
@ -2284,66 +2120,6 @@ bool CDriverGL::getModes(std::vector<GfxMode> &modes)
int screen = DefaultScreen(_dpy); int screen = DefaultScreen(_dpy);
#if defined(HAVE_XRANDR) #if defined(HAVE_XRANDR)
if (_xrandr_version >= 105)
{
int nmonitors = 0;
// virtual monitors
XRRMonitorInfo *monitor = XRRGetMonitors(_dpy, RootWindow(_dpy, screen), 1, &nmonitors);
for(sint i = 0; i < nmonitors; ++i)
{
char * name = XGetAtomName(_dpy, monitor[i].name);
GfxMode mode;
mode.DisplayDevice = name;
mode.Width = monitor[i].width;
mode.Height = monitor[i].height;
mode.Frequency = 0;
modes.push_back(mode);
XFree(name);
}
XRRFreeMonitors(monitor);
}
else
{
XRRScreenResources *resources = XRRGetScreenResourcesCurrent(_dpy, RootWindow(_dpy, screen));
if (!resources)
resources = XRRGetScreenResources(_dpy, RootWindow(_dpy, screen));
std::map<int, int> resourceModeMap;
for(sint i = 0; i< resources->nmode; ++i)
resourceModeMap.insert(std::make_pair(resources->modes[i].id, i));
for(sint i = 0; i < resources->noutput; ++i)
{
XRROutputInfo *output = XRRGetOutputInfo(_dpy, resources, resources->outputs[i]);
if (!output)
continue;
if (output->crtc && output->connection == RR_Connected)
{
// physical monitor
XRRCrtcInfo *crtc = XRRGetCrtcInfo(_dpy, resources, output->crtc);
if (crtc)
{
std::map<int,int>::const_iterator it = resourceModeMap.find(crtc->mode);
if (it != resourceModeMap.end())
{
GfxMode mode;
mode.DisplayDevice = output->name;
mode.Width = resources->modes[it->second].width;
mode.Height = resources->modes[it->second].height;
mode.Frequency = 0;
modes.push_back(mode);
}
XRRFreeCrtcInfo(crtc);
}
}
XRRFreeOutputInfo(output);
}
XRRFreeScreenResources(resources);
}
found = modes.size() > 0;
if (!found && _xrandr_version >= 100) if (!found && _xrandr_version >= 100)
{ {
XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen)); XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen));
@ -2479,120 +2255,6 @@ bool CDriverGL::getCurrentScreenMode(GfxMode &mode)
int screen = DefaultScreen(_dpy); int screen = DefaultScreen(_dpy);
#ifdef HAVE_XRANDR #ifdef HAVE_XRANDR
int x = 0;
int y = 0;
Window child;
// get window position so we can compare monitors (or mouse position if window not visible yet)
XWindowAttributes xwa;
XGetWindowAttributes(_dpy, _win, &xwa);
if (xwa.map_state != IsUnmapped)
{
XTranslateCoordinates(_dpy, _win, xwa.root, xwa.x, xwa.y, &x, &y, &child);
}
else
{
sint rx, ry, wx, wy;
uint mask;
Bool res = XQueryPointer(_dpy, RootWindow(_dpy, screen), &child, &child, &rx, &ry, &wx, &wy, &mask);
if (res)
{
x = rx;
y = ry;
}
}
if (_xrandr_version >= 105)
{
int nmonitors = 0;
XRRMonitorInfo *monitor = XRRGetMonitors(_dpy, RootWindow(_dpy, screen), 1, &nmonitors);
if (monitor)
{
sint bestMatch = -1;
for(sint i = 0; i< nmonitors; ++i)
{
if ((x >= monitor[i].x && x < (monitor[i].x + monitor[i].width) &&
y >= monitor[i].y && y < (monitor[i].y + monitor[i].height)) ||
(monitor[i].primary && bestMatch == -1))
{
bestMatch = i;
}
}
// best match or primary monitor
if (bestMatch != -1)
{
found = true;
char* pname = XGetAtomName(_dpy, monitor[bestMatch].name);
mode.DisplayDevice = pname;
mode.Width = monitor[bestMatch].width;
mode.Height = monitor[bestMatch].height;
mode.Windowed = _CurrentMode.Windowed;
mode.OffScreen = false;
mode.Depth = (uint) DefaultDepth(_dpy, screen);
mode.Frequency = 0;
XFree(pname);
}
XRRFreeMonitors(monitor);
}
}
else
{
XRRScreenResources *resources = XRRGetScreenResourcesCurrent(_dpy, RootWindow(_dpy, screen));
if (!resources)
resources = XRRGetScreenResources(_dpy, RootWindow(_dpy, screen));
for(uint i = 0; i < resources->noutput; ++i)
{
XRROutputInfo *output = XRRGetOutputInfo(_dpy, resources, resources->outputs[i]);
if (!output)
continue;
if (output->crtc && output->connection == RR_Connected)
{
XRRCrtcInfo *crtc = XRRGetCrtcInfo(_dpy, resources, output->crtc);
if (crtc)
{
sint width, height;
bool match = false;
// TODO: test rotation
if (crtc->rotation == RR_Rotate_0 || crtc->rotation == RR_Rotate_180)
{
width = crtc->width;
height = crtc->height;
}
else
{
width = crtc->height;
height = crtc->width;
}
if (x >= crtc->x && y >= crtc->y && x < (crtc->x + width) && y < (crtc->y + height))
{
found = true;
mode.DisplayDevice = output->name;
mode.Width = width;
mode.Height = height;
mode.Windowed = _CurrentMode.Windowed;
mode.OffScreen = false;
mode.Depth = (uint) DefaultDepth(_dpy, screen);
mode.Frequency = 0;
}
XRRFreeCrtcInfo(crtc);
}
}
XRRFreeOutputInfo(output);
if (found)
break;
}
XRRFreeScreenResources(resources);
}
if (!found && _xrandr_version > 0) if (!found && _xrandr_version > 0)
{ {
@ -2770,6 +2432,7 @@ void CDriverGL::setWindowPos(sint32 x, sint32 y)
_DecorationWidth = -1; _DecorationWidth = -1;
_DecorationHeight = -1; _DecorationHeight = -1;
} }
XMoveWindow(_dpy, _win, x, y); XMoveWindow(_dpy, _win, x, y);
} }
@ -3108,24 +2771,13 @@ void CDriverGL::setWindowSize(uint32 width, uint32 height)
SetWindowPos(_win, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, flags); SetWindowPos(_win, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, flags);
// init window width and height // init window width and height
if (_CurrentMode.Windowed) RECT clientRect;
{ GetClientRect(_win, &clientRect);
// TODO: this gives wrong info for initial fullscreen window so limit for windowed only for now _CurrentMode.Width = uint16(clientRect.right-clientRect.left);
RECT clientRect; _CurrentMode.Height = uint16(clientRect.bottom-clientRect.top);
GetClientRect(_win, &clientRect); GetWindowRect(_win, &clientRect);
_CurrentMode.Width = uint16(clientRect.right-clientRect.left); _WindowX = clientRect.left;
_CurrentMode.Height = uint16(clientRect.bottom-clientRect.top); _WindowY = clientRect.top;
GetWindowRect(_win, &clientRect);
_WindowX = clientRect.left;
_WindowY = clientRect.top;
}
else
{
_CurrentMode.Width = width;
_CurrentMode.Height = height;
_WindowX = 0;
_WindowY = 0;
}
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)

@ -152,7 +152,7 @@ static NLMISC::TKey virtualKeycodeToNelKey(unsigned short keycode)
return NLMISC::KeyNOKEY; return NLMISC::KeyNOKEY;
} }
bool CCocoaEventEmitter::pasteTextFromClipboard(std::string &text) bool CCocoaEventEmitter::pasteTextFromClipboard(ucstring &text)
{ {
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
@ -163,17 +163,17 @@ bool CCocoaEventEmitter::pasteTextFromClipboard(std::string &text)
{ {
NSArray *objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options]; NSArray *objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options];
NSString *nstext = [objectsToPaste objectAtIndex:0]; NSString *nstext = [objectsToPaste objectAtIndex:0];
text = [nstext UTF8String]; text.fromUtf8([nstext UTF8String]);
return true; return true;
} }
return false; return false;
} }
bool CCocoaEventEmitter::copyTextToClipboard(const std::string &text) bool CCocoaEventEmitter::copyTextToClipboard(const ucstring &text)
{ {
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
[pasteboard clearContents]; [pasteboard clearContents];
NSArray *copiedObjects = [NSArray arrayWithObject:[NSString stringWithUTF8String:text.c_str()]]; NSArray *copiedObjects = [NSArray arrayWithObject:[NSString stringWithUTF8String:text.toUtf8().c_str()]];
[pasteboard writeObjects:copiedObjects]; [pasteboard writeObjects:copiedObjects];
return true; return true;
} }

@ -21,7 +21,6 @@
#ifndef NL_COCOA_EVENT_EMITTER_H #ifndef NL_COCOA_EVENT_EMITTER_H
#define NL_COCOA_EVENT_EMITTER_H #define NL_COCOA_EVENT_EMITTER_H
#include <string.h>
#include "nel/misc/event_emitter.h" #include "nel/misc/event_emitter.h"
#include "nel/misc/event_server.h" #include "nel/misc/event_server.h"
#include "nel/misc/events.h" #include "nel/misc/events.h"
@ -54,8 +53,8 @@ public:
virtual void submitEvents(CEventServer& server, bool allWindows); virtual void submitEvents(CEventServer& server, bool allWindows);
bool handleQuitRequest(); bool handleQuitRequest();
virtual bool copyTextToClipboard(const std::string &text); virtual bool copyTextToClipboard(const ucstring &text);
virtual bool pasteTextFromClipboard(std::string &text); virtual bool pasteTextFromClipboard(ucstring &text);
}; };
} }

@ -331,7 +331,6 @@ bool CDriverUser::getCurrentScreenMode(CMode &mode)
GfxMode gfxMode; GfxMode gfxMode;
bool res= _Driver->getCurrentScreenMode(gfxMode); bool res= _Driver->getCurrentScreenMode(gfxMode);
mode.Windowed= gfxMode.Windowed; mode.Windowed= gfxMode.Windowed;
mode.DisplayDevice= gfxMode.DisplayDevice;
mode.Width= gfxMode.Width; mode.Width= gfxMode.Width;
mode.Height= gfxMode.Height; mode.Height= gfxMode.Height;
mode.Depth= gfxMode.Depth; mode.Depth= gfxMode.Depth;

@ -299,11 +299,6 @@ namespace NLGUI
void CGroupHTML::ImageDownloadCB::finish() void CGroupHTML::ImageDownloadCB::finish()
{ {
// Image setTexture will remove itself from Images while iterating over it.
// Do the swap to keep iterator safe.
std::vector<SImageInfo> vec;
vec.swap(Images);
// tmpdest file does not exist if download skipped (ie cache was used) // tmpdest file does not exist if download skipped (ie cache was used)
if (CFile::fileExists(tmpdest) || CFile::getFileSize(tmpdest) == 0) if (CFile::fileExists(tmpdest) || CFile::getFileSize(tmpdest) == 0)
{ {
@ -327,7 +322,7 @@ namespace NLGUI
// to temp file temporarily. that forces driver to reload texture from disk // to temp file temporarily. that forces driver to reload texture from disk
// ITexture::touch() seem not to do this. // ITexture::touch() seem not to do this.
// cache was updated, first set texture as temp file // cache was updated, first set texture as temp file
for(std::vector<SImageInfo>::iterator it = vec.begin(); it != vec.end(); ++it) for(std::vector<SImageInfo>::iterator it = Images.begin(); it != Images.end(); ++it)
{ {
SImageInfo &img = *it; SImageInfo &img = *it;
Parent->setImage(img.Image, tmpdest, img.Type); Parent->setImage(img.Image, tmpdest, img.Type);
@ -344,7 +339,7 @@ namespace NLGUI
} }
// even if image was cached, incase there was 'http://' image set to CViewBitmap // even if image was cached, incase there was 'http://' image set to CViewBitmap
for(std::vector<SImageInfo>::iterator it = vec.begin(); it != vec.end(); ++it) for(std::vector<SImageInfo>::iterator it = Images.begin(); it != Images.end(); ++it)
{ {
SImageInfo &img = *it; SImageInfo &img = *it;
Parent->setImage(img.Image, dest, img.Type); Parent->setImage(img.Image, dest, img.Type);
@ -1058,13 +1053,6 @@ namespace NLGUI
_CurlWWW = NULL; _CurlWWW = NULL;
} }
releaseDataDownloads();
}
void CGroupHTML::releaseDataDownloads()
{
LOG_DL("Clear pointers to %d curls", Curls.size());
// remove all queued and already started downloads // remove all queued and already started downloads
for(std::list<CDataDownload*>::iterator it = Curls.begin(); it != Curls.end(); ++it) for(std::list<CDataDownload*>::iterator it = Curls.begin(); it != Curls.end(); ++it)
{ {
@ -3092,7 +3080,14 @@ namespace NLGUI
paragraphChange (); paragraphChange ();
releaseDataDownloads(); // clear the pointer to the current image download since all the button are deleted
LOG_DL("Clear pointers to %d curls", Curls.size());
// remove image refs from downloads
/*for(std::list<CDataDownload>::iterator it = Curls.begin(); it != Curls.end(); ++it)
{
it->imgs.clear();
}*/
} }
// *************************************************************************** // ***************************************************************************
@ -6798,7 +6793,7 @@ namespace NLGUI
_TextAreaTemplate = !templateName.empty() ? templateName : DefaultFormTextAreaGroup; _TextAreaTemplate = !templateName.empty() ? templateName : DefaultFormTextAreaGroup;
std::string content = strFindReplaceAll(elm.serializeChilds(false), std::string("\r"), std::string("")); std::string content = strFindReplaceAll(elm.serializeChilds(), std::string("\r"), std::string(""));
CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, content, _TextAreaMaxLength); CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, content, _TextAreaMaxLength);
if (textArea) if (textArea)
@ -6831,7 +6826,7 @@ namespace NLGUI
// if (!_ReadingHeadTag) return; // if (!_ReadingHeadTag) return;
// consume all child elements // consume all child elements
_TitleString = strFindReplaceAll(elm.serializeChilds(false), std::string("\t"), std::string(" ")); _TitleString = strFindReplaceAll(elm.serializeChilds(), std::string("\t"), std::string(" "));
_TitleString = strFindReplaceAll(_TitleString, std::string("\n"), std::string(" ")); _TitleString = strFindReplaceAll(_TitleString, std::string("\n"), std::string(" "));
setTitle(_TitleString); setTitle(_TitleString);
} }

@ -142,33 +142,30 @@ namespace NLGUI
} }
// *************************************************************************** // ***************************************************************************
std::string CHtmlElement::htmlEscape(const std::string &val) const std::string CHtmlElement::htmlEscape(std::string val, bool isAttribute) const
{ {
if (val.find_first_of("\"'&<>\xA0") == std::string::npos) static const std::string searchReplace[] = {
return val; "&", "&amp;",
"<", "&lt;",
std::string ret; ">", "&gt;",
// resize is quaranteed, make room for some free replacements "\xA0", "&nbsp;",
ret.reserve(val.size() + 24); };
for(size_t pos = 0; pos != val.size(); pos++)
for(uint i = 0; i < (sizeof(searchReplace) / sizeof(searchReplace[0])); i+=2)
val = strFindReplaceAll(val, searchReplace[i], searchReplace[i+1]);
if (isAttribute)
{ {
switch(val[pos]) static const std::string q = "\"";
{ static const std::string quot = "&quot;";
case '"': ret.append("&quot;"); break; val = strFindReplaceAll(val, q, quot);
case '\'': ret.append("&#39;"); break;
case '&': ret.append("&amp;"); break;
case '<': ret.append("&lt;"); break;
case '>': ret.append("&gt;"); break;
case '\xA0': ret.append("&nbsp;"); break;
default : ret.append(&val[pos],1); break;
}
} }
return ret; return val;
} }
// *************************************************************************** // ***************************************************************************
std::string CHtmlElement::serializeAttributes(bool escape) const std::string CHtmlElement::serializeAttributes() const
{ {
std::string result; std::string result;
for(std::map<std::string, std::string>::const_iterator it = Attributes.begin(); it != Attributes.end(); ++it) for(std::map<std::string, std::string>::const_iterator it = Attributes.begin(); it != Attributes.end(); ++it)
@ -182,30 +179,30 @@ namespace NLGUI
{ {
result += " "; result += " ";
} }
result += (escape ? htmlEscape(*it2) : *it2); result += htmlEscape(*it2, true);
} }
result += "\""; result += "\"";
} }
else else
{ {
result += " " + it->first + "=\"" + (escape ? htmlEscape(it->second) : it->second) + "\""; result += " " + it->first + "=\"" + htmlEscape(it->second, true) + "\"";
} }
} }
return result; return result;
} }
// *************************************************************************** // ***************************************************************************
std::string CHtmlElement::serializeChilds(bool escape) const std::string CHtmlElement::serializeChilds() const
{ {
std::string result; std::string result;
for(std::list<CHtmlElement>::const_iterator it = Children.begin(); it != Children.end(); ++it) for(std::list<CHtmlElement>::const_iterator it = Children.begin(); it != Children.end(); ++it)
result += it->serialize(escape); result += it->serialize();
return result; return result;
} }
// *************************************************************************** // ***************************************************************************
std::string CHtmlElement::serialize(bool escape) const std::string CHtmlElement::serialize() const
{ {
if (Type == TEXT_NODE) if (Type == TEXT_NODE)
{ {
@ -214,14 +211,12 @@ namespace NLGUI
parent->ID == HTML_NOSCRIPT)) parent->ID == HTML_NOSCRIPT))
{ {
return Value; return Value;
} else if (escape) {
return htmlEscape(Value);
} else { } else {
return Value; return htmlEscape(Value);
} }
} }
std::string result = "<" + Value + serializeAttributes(escape) + ">"; std::string result = "<" + Value + serializeAttributes() + ">";
if (ID == HTML_AREA || ID == HTML_BASE || ID == HTML_BR || if (ID == HTML_AREA || ID == HTML_BASE || ID == HTML_BR ||
ID == HTML_COL || ID == HTML_EMBED || ID == HTML_HR || ID == HTML_COL || ID == HTML_EMBED || ID == HTML_HR ||
@ -236,7 +231,7 @@ namespace NLGUI
result += "\n"; result += "\n";
if (!Children.empty()) if (!Children.empty())
result += serializeChilds(escape); result += serializeChilds();
result += "</" + Value + ">"; result += "</" + Value + ">";

@ -42,12 +42,6 @@
#define assert(x) #define assert(x)
#endif #endif
// Always use unique_ptr with ValyriaTear/luabind on Ubuntu 20,
// since the setting is not stored in build_information.hpp
#ifndef LUABIND_USE_CXX11
#define LUABIND_USE_CXX11
#endif
#include <luabind/luabind.hpp> #include <luabind/luabind.hpp>
#include <nel/misc/algo.h> #include <nel/misc/algo.h>
#include <nel/misc/path.h> #include <nel/misc/path.h>

@ -48,12 +48,6 @@
# define assert(x) # define assert(x)
#endif #endif
// Always use unique_ptr with ValyriaTear/luabind on Ubuntu 20,
// since the setting is not stored in build_information.hpp
#ifndef LUABIND_USE_CXX11
#define LUABIND_USE_CXX11
#endif
#include <luabind/luabind.hpp> #include <luabind/luabind.hpp>
// in luabind > 0.6, LUABIND_MAX_ARITY is set to 10 // in luabind > 0.6, LUABIND_MAX_ARITY is set to 10
#if LUABIND_MAX_ARITY == 10 #if LUABIND_MAX_ARITY == 10
@ -226,9 +220,7 @@ namespace NLGUI
void CLuaIHM::push(CLuaState &ls, const ucstring &value) void CLuaIHM::push(CLuaState &ls, const ucstring &value)
{ {
//H_AUTO(Lua_CLuaIHM_push) //H_AUTO(Lua_CLuaIHM_push)
#if defined(LUABIND_STACK_HPP_INCLUDED) #if LUABIND_VERSION > 600
luabind::push(ls.getStatePointer(), value);
#elif (LUABIND_VERSION > 600)
luabind::detail::push(ls.getStatePointer(), value); luabind::detail::push(ls.getStatePointer(), value);
#else #else
luabind::object obj(ls.getStatePointer(), value); luabind::object obj(ls.getStatePointer(), value);
@ -1123,6 +1115,7 @@ namespace NLGUI
if(!pIE) if(!pIE)
{ {
ls.pushNil(); ls.pushNil();
nlerror("getCurrentWindowUnder(): No UICaller found. return Nil");
} }
else else
{ {
@ -1163,9 +1156,7 @@ namespace NLGUI
case CInterfaceExprValue::RGBA: case CInterfaceExprValue::RGBA:
{ {
CRGBA color = value.getRGBA(); CRGBA color = value.getRGBA();
#if defined(LUABIND_STACK_HPP_INCLUDED) #if LUABIND_VERSION > 600
luabind::push(ls.getStatePointer(), color);
#elif (LUABIND_VERSION > 600)
luabind::detail::push(ls.getStatePointer(), color); luabind::detail::push(ls.getStatePointer(), color);
#else #else
luabind::object obj(ls.getStatePointer(), color); luabind::object obj(ls.getStatePointer(), color);
@ -1425,9 +1416,7 @@ namespace NLGUI
case CReflectedProperty::UCString: case CReflectedProperty::UCString:
{ {
ucstring str = (reflectedObject.*(property.GetMethod.GetUCString))(); ucstring str = (reflectedObject.*(property.GetMethod.GetUCString))();
#if defined(LUABIND_STACK_HPP_INCLUDED) #if LUABIND_VERSION > 600
luabind::push(ls.getStatePointer(), str);
#elif (LUABIND_VERSION > 600)
luabind::detail::push(ls.getStatePointer(), str); luabind::detail::push(ls.getStatePointer(), str);
#else #else
luabind::object obj(ls.getStatePointer(), str); luabind::object obj(ls.getStatePointer(), str);
@ -1438,9 +1427,7 @@ namespace NLGUI
case CReflectedProperty::UCStringRef: case CReflectedProperty::UCStringRef:
{ {
ucstring str = (reflectedObject.*(property.GetMethod.GetUCStringRef))(); ucstring str = (reflectedObject.*(property.GetMethod.GetUCStringRef))();
#if defined(LUABIND_STACK_HPP_INCLUDED) #if LUABIND_VERSION > 600
luabind::push(ls.getStatePointer(), str);
#elif (LUABIND_VERSION > 600)
luabind::detail::push(ls.getStatePointer(), str); luabind::detail::push(ls.getStatePointer(), str);
#else #else
luabind::object obj(ls.getStatePointer(), str); luabind::object obj(ls.getStatePointer(), str);
@ -1455,9 +1442,7 @@ namespace NLGUI
case CReflectedProperty::RGBA: case CReflectedProperty::RGBA:
{ {
CRGBA color = (reflectedObject.*(property.GetMethod.GetRGBA))(); CRGBA color = (reflectedObject.*(property.GetMethod.GetRGBA))();
#if defined(LUABIND_STACK_HPP_INCLUDED) #if LUABIND_VERSION > 600
luabind::push(ls.getStatePointer(), color);
#elif (LUABIND_VERSION > 600)
luabind::detail::push(ls.getStatePointer(), color); luabind::detail::push(ls.getStatePointer(), color);
#else #else
luabind::object obj(ls.getStatePointer(), color); luabind::object obj(ls.getStatePointer(), color);
@ -1671,7 +1656,7 @@ namespace NLGUI
ls.registerFunc("runFct", runFct); ls.registerFunc("runFct", runFct);
ls.registerFunc("runCommand", runCommand); ls.registerFunc("runCommand", runCommand);
ls.registerFunc("getPathContent", getPathContent); ls.registerFunc("getPathContent", getPathContent);
// Through LUABind API // Through LUABind API
lua_State *L= ls.getStatePointer(); lua_State *L= ls.getStatePointer();

@ -70,17 +70,7 @@ namespace NLGUI
} }
catch( const ELuaError &e ) catch( const ELuaError &e )
{ {
#if !FINAL_VERSION nlwarning( e.luaWhat().c_str() );
nlwarning("--- LUA ERROR ---");
nlwarning(e.luaWhat().c_str());
std::vector<std::string> res;
NLMISC::explode(luaScript, std::string("\n"), res);
for(uint k = 0; k < res.size(); ++k)
{
nlwarning("%.05u %s", k, res[k].c_str());
}
nlwarning("--- ********* ---");
#endif
return false; return false;
} }

@ -481,13 +481,7 @@ namespace NLGUI
} }
else else
{ {
if (_HtmlDownload) _HtmlDownload = NULL;
{
CGroupHTML *groupHtml = dynamic_cast<CGroupHTML*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:webig:content:html"));
if (groupHtml)
groupHtml->removeImageDownload(_HtmlDownload, dynamic_cast<CViewBase*>(this));
_HtmlDownload = NULL;
}
_TextureId.setTexture (TxName.c_str (), _TxtOffsetX, _TxtOffsetY, _TxtWidth, _TxtHeight, false); _TextureId.setTexture (TxName.c_str (), _TxtOffsetX, _TxtOffsetY, _TxtWidth, _TxtHeight, false);
} }
} }

@ -95,7 +95,6 @@ namespace NLGUI
_FontWidth= 0; _FontWidth= 0;
_FontHeight = 0; _FontHeight = 0;
_FontLegHeight = 0; _FontLegHeight = 0;
_TabWidth= 0;
_TextSelection= false; _TextSelection= false;
_TextSelectionStart= 0; _TextSelectionStart= 0;
@ -1285,7 +1284,7 @@ namespace NLGUI
px += firstSpace; px += firstSpace;
// skip tabulation before current word // skip tabulation before current word
if(currWord.Format.TabX) if(currWord.Format.TabX)
px= max(px, (float)(_XReal * _Scale + currWord.Format.TabX*_TabWidth)); px= max(px, (float)(_XReal * _Scale + currWord.Format.TabX*_FontWidth));
// draw. We take floorf px to avoid filtering of letters that are not located on a pixel boundary // draw. We take floorf px to avoid filtering of letters that are not located on a pixel boundary
float fx = px / _Scale; float fx = px / _Scale;
@ -1469,7 +1468,7 @@ namespace NLGUI
} }
} }
nlassert(_Text.empty() || ((_Localized && (NLMISC::startsWith(getHardText(), "ui"))) == (_HardText.empty() == _Text.empty()))); nlassert(_Text.empty() || ((_Localized && (NLMISC::startsWith(getText(), "ui"))) == (_HardText.empty() == _Text.empty())));
} }
// *************************************************************************** // ***************************************************************************
@ -1768,7 +1767,7 @@ namespace NLGUI
getFormatTagChange(i, formatTagIndex, wordFormat); getFormatTagChange(i, formatTagIndex, wordFormat);
// Ensure the line witdh count the tab // Ensure the line witdh count the tab
rWidthCurrentLine= max(rWidthCurrentLine, (float)wordFormat.TabX*_TabWidth); rWidthCurrentLine= max(rWidthCurrentLine, (float)wordFormat.TabX*_FontWidth);
} }
NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName);
@ -1952,7 +1951,7 @@ namespace NLGUI
// compute size of spaces/Tab + word // compute size of spaces/Tab + word
newLineWidth = lineWidth + numSpaces * _SpaceWidth; newLineWidth = lineWidth + numSpaces * _SpaceWidth;
newLineWidth = max(newLineWidth, (float)wordFormat.TabX*_TabWidth); newLineWidth = max(newLineWidth, (float)wordFormat.TabX*_FontWidth);
newLineWidth+= si.StringWidth; newLineWidth+= si.StringWidth;
} }
// //
@ -3114,6 +3113,8 @@ namespace NLGUI
TextContext->setEmbolden (_Embolden); TextContext->setEmbolden (_Embolden);
TextContext->setOblique (_Oblique); TextContext->setOblique (_Oblique);
#if 1
UTextContext::CStringInfo si = TextContext->getStringInfo("XO"); UTextContext::CStringInfo si = TextContext->getStringInfo("XO");
float xoHeight = si.StringHeight; float xoHeight = si.StringHeight;
@ -3144,14 +3145,34 @@ namespace NLGUI
si = TextContext->getStringInfo(" "); si = TextContext->getStringInfo(" ");
_SpaceWidth = si.StringWidth; _SpaceWidth = si.StringWidth;
// Font Width // Font Width (used for <tab>)
si = TextContext->getStringInfo("O"); si = TextContext->getStringInfo("O");
_FontWidth = si.StringWidth; _FontWidth = si.StringWidth;
// Tab Width (used for {Txx}) #else
// if not set to "_", breaks item help window
// Letter size
UTextContext::CStringInfo si = TextContext->getStringInfo(_FontSizingChars);
// font generator changes unknown glyphs to dot '.'. use fallback if it looks odd
if (_FontSize > (si.StringHeight + si.StringLine))
{
si = TextContext->getStringInfo(_FontSizingFallback);
}
// add a padding of 1 pixel else the top will be truncated
_FontHeight = si.StringHeight + 1;
_FontLegHeight = si.StringLine;
// Space width
si = TextContext->getStringInfo(" ");
_SpaceWidth = si.StringWidth;
// Font Width (used for <tab>)
si = TextContext->getStringInfo("_"); si = TextContext->getStringInfo("_");
_TabWidth = si.StringWidth; _FontWidth = si.StringWidth;
#endif
} }
@ -3620,7 +3641,6 @@ namespace NLGUI
f.serial(_Localized); f.serial(_Localized);
SERIAL_SINT(_FontSize); SERIAL_SINT(_FontSize);
SERIAL_UINT(_FontWidth); SERIAL_UINT(_FontWidth);
SERIAL_UINT(_TabWidth);
SERIAL_UINT(_FontHeight); SERIAL_UINT(_FontHeight);
SERIAL_UINT(_FontLegHeight); SERIAL_UINT(_FontLegHeight);
f.serial(_SpaceWidth); f.serial(_SpaceWidth);

@ -183,21 +183,6 @@ IF(WITH_GTK)
ENDIF() ENDIF()
ENDIF() ENDIF()
IF(HUNTER_ENABLED)
HUNTER_ADD_PACKAGE(Jpeg)
FIND_PACKAGE(JPEG CONFIG REQUIRED)
SET(JPEG_LIBRARY JPEG::jpeg)
HUNTER_ADD_PACKAGE(giflib)
FIND_PACKAGE(giflib CONFIG REQUIRED)
SET(GIF_LIBRARY giflib::giflib)
HUNTER_ADD_PACKAGE(PNG)
FIND_PACKAGE(PNG CONFIG REQUIRED)
SET(PNG_LIBRARY PNG::png)
SET(PNG_LIBRARIES PNG::png)
ENDIF()
IF(JPEG_FOUND) IF(JPEG_FOUND)
INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR})
ADD_DEFINITIONS(-DUSE_JPEG) ADD_DEFINITIONS(-DUSE_JPEG)
@ -217,7 +202,6 @@ ELSE()
TARGET_LINK_LIBRARIES(nelmisc ${PNG_LIBRARY}) TARGET_LINK_LIBRARIES(nelmisc ${PNG_LIBRARY})
ENDIF() ENDIF()
#TODO: needed for hunter aswell?
IF(UNIX) IF(UNIX)
TARGET_LINK_LIBRARIES(nelmisc -lc -ldl) TARGET_LINK_LIBRARIES(nelmisc -lc -ldl)
IF(APPLE) IF(APPLE)

@ -51,18 +51,6 @@ namespace NLMISC{
//----------------------------------------------- //-----------------------------------------------
void CCDBNodeLeaf::init( xmlNodePtr node, IProgressCallback &/* progressCallBack */, bool /* mapBanks */, CCDBBankHandler * /* bankHandler */ ) void CCDBNodeLeaf::init( xmlNodePtr node, IProgressCallback &/* progressCallBack */, bool /* mapBanks */, CCDBBankHandler * /* bankHandler */ )
{ {
// Read nullable
CXMLAutoPtr nullable((const char*)xmlGetProp (node, (xmlChar*)"nullable"));
if ((const char *) nullable != NULL)
{
m_Nullable = (nullable.getDatas()[0] == '1');
}
else
{
m_Nullable = false;
}
// Read type
CXMLAutoPtr type((const char*)xmlGetProp (node, (xmlChar*)"type")); CXMLAutoPtr type((const char*)xmlGetProp (node, (xmlChar*)"type"));
nlassert((const char *) type != NULL); nlassert((const char *) type != NULL);
@ -153,13 +141,6 @@ void CCDBNodeLeaf::readDelta(TGameCycle gc, CBitMemStream & f )
{ {
// Read the Property Value according to the Property Type. // Read the Property Value according to the Property Type.
uint64 recvd = 0; uint64 recvd = 0;
uint64 isNull = 0;
if (m_Nullable)
{
f.serial(isNull, 1);
}
uint bits; uint bits;
if (_Type == TEXT) if (_Type == TEXT)
bits = 32; bits = 32;

@ -90,23 +90,6 @@ SOURCE_GROUP("user_classes" FILES ${USER_CLASSES})
NL_TARGET_LIB(nelsound ${HEADERS} ${SRC}) NL_TARGET_LIB(nelsound ${HEADERS} ${SRC})
IF(HUNTER_ENABLED)
HUNTER_ADD_PACKAGE(libogg)
FIND_PACKAGE(libogg CONFIG REQUIRED)
SET(OGG_LIBRARY libogg::ogg)
SET(OGG_LIBRARIES libogg::ogg)
HUNTER_ADD_PACKAGE(vorbis)
FIND_PACKAGE(vorbis CONFIG REQUIRED)
SET(VORBIS_LIBRARY vorbis::vorbis)
SET(VORBISFILE_LIBRARY vorbis::vorbisfile)
IF(WITH_FFMPEG)
HUNTER_ADD_PACKAGE(ffmpeg)
FIND_PACKAGE(ffmpeg CONFIG REQUIRED)
SET(FFMPEG_LIBRARIES ffmpeg::avcodec ffmpeg::avformat ffmpeg::avutil ffmpeg::swresample)
ENDIF()
ENDIF()
INCLUDE_DIRECTORIES(${VORBIS_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${VORBIS_INCLUDE_DIR})
INCLUDE_DIRECTORIES(${OGG_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${OGG_INCLUDE_DIR})

@ -26,16 +26,9 @@ SOURCE_GROUP(util FILES
NL_TARGET_DRIVER(${NLDRV_AL_LIB} ${SRC}) NL_TARGET_DRIVER(${NLDRV_AL_LIB} ${SRC})
IF(HUNTER_ENABLED) INCLUDE_DIRECTORIES(${OPENAL_INCLUDE_DIR})
HUNTER_ADD_PACKAGE(OpenAL)
FIND_PACKAGE(OpenAL CONFIG REQUIRED)
SET(OPENAL_LIBRARY OpenAL::OpenAL)
ADD_DEFINITIONS(-DAL_LIBTYPE_STATIC)
ELSE()
INCLUDE_DIRECTORIES(${OPENAL_INCLUDE_DIR})
ENDIF()# hunter
TARGET_LINK_LIBRARIES(${NLDRV_AL_LIB} nelmisc nelsnd_lowlevel ${OPENAL_LIBRARY}) TARGET_LINK_LIBRARIES(${NLDRV_AL_LIB} ${OPENAL_LIBRARY} nelmisc nelsnd_lowlevel)
NL_DEFAULT_PROPS(${NLDRV_AL_LIB} "NeL, Driver, Sound: OpenAL") NL_DEFAULT_PROPS(${NLDRV_AL_LIB} "NeL, Driver, Sound: OpenAL")
NL_ADD_RUNTIME_FLAGS(${NLDRV_AL_LIB}) NL_ADD_RUNTIME_FLAGS(${NLDRV_AL_LIB})
NL_ADD_LIB_SUFFIX(${NLDRV_AL_LIB}) NL_ADD_LIB_SUFFIX(${NLDRV_AL_LIB})

@ -66,7 +66,6 @@ void alExtInitDevice(ALCdevice *device)
} }
} }
#if !defined(AL_LIBTYPE_STATIC)
// Windows and Mac OS always link to shared OpenAL library // Windows and Mac OS always link to shared OpenAL library
#if defined(NL_OS_WINDOWS) || defined(NL_OS_MAC) || !defined(NL_STATIC) #if defined(NL_OS_WINDOWS) || defined(NL_OS_MAC) || !defined(NL_STATIC)
// EFX // EFX
@ -115,7 +114,6 @@ void alExtInitDevice(ALCdevice *device)
} }
} }
#endif #endif
#endif
} }
#if EAX_AVAILABLE #if EAX_AVAILABLE
@ -139,7 +137,6 @@ EAXGetBufferMode eaxGetBufferMode = NULL;
// ALC_EXT_EFX // ALC_EXT_EFX
bool AlExtEfx = false; bool AlExtEfx = false;
// effect objects // effect objects
#if !defined(AL_LIBTYPE_STATIC)
#if defined(NL_OS_WINDOWS) || defined(NL_OS_MAC) || !defined(NL_STATIC) #if defined(NL_OS_WINDOWS) || defined(NL_OS_MAC) || !defined(NL_STATIC)
LPALGENEFXOBJECTS alGenEffects = NULL; LPALGENEFXOBJECTS alGenEffects = NULL;
LPALDELETEEFXOBJECTS alDeleteEffects = NULL; LPALDELETEEFXOBJECTS alDeleteEffects = NULL;
@ -177,7 +174,6 @@ LPALGETEFXOBJECTIV alGetAuxiliaryEffectSlotiv = NULL;
LPALGETEFXOBJECTF alGetAuxiliaryEffectSlotf = NULL; LPALGETEFXOBJECTF alGetAuxiliaryEffectSlotf = NULL;
LPALGETEFXOBJECTFV alGetAuxiliaryEffectSlotfv = NULL; LPALGETEFXOBJECTFV alGetAuxiliaryEffectSlotfv = NULL;
#endif #endif
#endif
} }
/* end of file */ /* end of file */

@ -75,9 +75,8 @@ static const std::string CAFilename = "cacert.pem"; // https://curl.haxx.se/docs
// *************************************************************************** // ***************************************************************************
bool CCurlHttpClient::verifyServer(bool verify) bool CCurlHttpClient::verifyServer(bool verify)
{ {
m_Verify = verify;
curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYPEER, verify ? 1 : 0);
curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYHOST, verify ? 2 : 0); curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYHOST, verify ? 2 : 0);
curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYPEER, verify ? 1 : 0);
// specify custom CA certs // specify custom CA certs
CCurlCertificates::addCertificateFile(CAFilename); CCurlCertificates::addCertificateFile(CAFilename);
@ -98,8 +97,8 @@ bool CCurlHttpClient::sendRequest(const std::string& methodWB, const std::string
curl_easy_setopt(_Curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(_Curl, CURLOPT_URL, url.c_str());
if (url.length() > 8 && (url[4] == 's' || url[4] == 'S')) // 01234 https if (url.length() > 8 && (url[4] == 's' || url[4] == 'S')) // 01234 https
{ {
curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYPEER, m_Verify ? 1L : 0); curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYHOST, m_Verify ? 2L : 0); curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYHOST, 2L);
} }
// Authentication // Authentication
@ -125,17 +124,15 @@ bool CCurlHttpClient::sendRequest(const std::string& methodWB, const std::string
curl_easy_setopt(_Curl, CURLOPT_WRITEFUNCTION, CCurlHttpClient::writeDataFromCurl); curl_easy_setopt(_Curl, CURLOPT_WRITEFUNCTION, CCurlHttpClient::writeDataFromCurl);
curl_easy_setopt(_Curl, CURLOPT_WRITEDATA, this); curl_easy_setopt(_Curl, CURLOPT_WRITEDATA, this);
if (!m_ErrorBuf.size()) char errorbuf [CURL_ERROR_SIZE+1];
m_ErrorBuf.resize(CURL_ERROR_SIZE + 1); curl_easy_setopt(_Curl, CURLOPT_ERRORBUFFER, errorbuf);
m_ErrorBuf[0] = '\0';
curl_easy_setopt(_Curl, CURLOPT_ERRORBUFFER, &m_ErrorBuf[0]);
// Send // Send
CURLcode res = curl_easy_perform(_Curl); CURLcode res = curl_easy_perform(_Curl);
if (res != 0) if (res != 0)
{ {
if (verbose) if (verbose)
nlwarning(&m_ErrorBuf[0]); nlwarning(errorbuf);
return false; return false;
} }

@ -629,11 +629,7 @@ void sqlInit ()
nlerror ("mysql_init() failed"); nlerror ("mysql_init() failed");
} }
#if LIBMYSQL_VERSION_ID < 80000
my_bool opt = true; my_bool opt = true;
#else
bool opt = true;
#endif
if (mysql_options (db, MYSQL_OPT_RECONNECT, &opt)) if (mysql_options (db, MYSQL_OPT_RECONNECT, &opt))
{ {
mysql_close(db); mysql_close(db);

@ -4553,20 +4553,13 @@ void CCharacterCL::applyBehaviourFlyingHPs(const CBehaviourContext &bc, const MB
{ {
nlassert(targetHitDates.size()==bc.Targets.Targets.size()); nlassert(targetHitDates.size()==bc.Targets.Targets.size());
if (behaviour.DeltaHP == 0 || bc.Targets.Targets.empty()) if(!bc.Targets.Targets.empty())
return;
CRGBA deltaHPColor(0, 0, 0);
for (size_t i=0; i<bc.Targets.Targets.size(); ++i)
{ {
if(bc.Targets.Targets[i].DeltaHP == 0) if(behaviour.DeltaHP != 0)
continue;
CEntityCL *target2 = EntitiesMngr.entity(bc.Targets.Targets[i].TargetSlot);
if(target2)
{ {
CRGBA deltaHPColor(0, 0, 0);
// if it's a hit // if it's a hit
if(bc.Targets.Targets[i].DeltaHP < 0) if( behaviour.DeltaHP < 0 )
{ {
// if the behaviour is casted by the user // if the behaviour is casted by the user
if( slot() == 0 ) if( slot() == 0 )
@ -4597,7 +4590,13 @@ void CCharacterCL::applyBehaviourFlyingHPs(const CBehaviourContext &bc, const MB
deltaHPColor = CRGBA(0,220,0); deltaHPColor = CRGBA(0,220,0);
} }
target2->addHPOutput(bc.Targets.Targets[i].DeltaHP, deltaHPColor, float(targetHitDates[i]-TimeInSec)); // Set the delta HP
for (size_t i=0; i<bc.Targets.Targets.size(); ++i)
{
CEntityCL *target2 = EntitiesMngr.entity(bc.Targets.Targets[i].TargetSlot);
if(target2)
target2->addHPOutput(behaviour.DeltaHP, deltaHPColor, float(targetHitDates[i]-TimeInSec));
}
} }
} }
} }
@ -6274,11 +6273,6 @@ void CCharacterCL::updateVisiblePostPos(const NLMISC::TTime &currentTimeInMs, CE
pos = (box().getMin() + box().getMax())/2; pos = (box().getMin() + box().getMax())/2;
pos.z = box().getMax().z; pos.z = box().getMax().z;
} }
CRaceStatsSheet *sheet = const_cast<CRaceStatsSheet*>(UserEntity->playerSheet());
float namePosZ = sheet->GenderInfos[UserEntity->getGender()].NamePosZNormal;
if (pos.z > box().getMin().z + namePosZ)
pos.z = box().getMin().z + namePosZ;
nlassert(isValidDouble(pos.x) && isValidDouble(pos.y) && isValidDouble(pos.z)); nlassert(isValidDouble(pos.x) && isValidDouble(pos.y) && isValidDouble(pos.z));
_CurrentBubble->Position = pos; _CurrentBubble->Position = pos;
} }
@ -6684,7 +6678,7 @@ ADD_METHOD(void CCharacterCL::updatePos(const TTime &currentTimeInMs, CEntityCL
updatePosCombatFloat(frameTimeRemaining, target); updatePosCombatFloat(frameTimeRemaining, target);
} }
// Compute the average speed to the destination. // Compute the average speed to the destination.
// double spd = // double spd =
computeSpeed(); computeSpeed();
@ -8238,14 +8232,14 @@ float CCharacterCL::getSheetScale() const // virtual
// getColRadius : // getColRadius :
// Return the entity collision radius. (return 0.5 if there is any problem). // Return the entity collision radius. (return 0.5 if there is any problem).
//--------------------------------------------------- //---------------------------------------------------
float CCharacterCL::getSheetColRadius() const float CCharacterCL::getSheetColRadius() const
{ {
if(!_Sheet) if(!_Sheet)
return 0.5f; return 0.5f;
else else
return _Sheet->ColRadius; return _Sheet->ColRadius;
} }
//--------------------------------------------------- //---------------------------------------------------
// getScale : // getScale :
@ -8364,7 +8358,7 @@ std::string CCharacterCL::shapeFromItem(const CItemSheet &itemSheet) const
sheet = itemSheet.getShape(); sheet = itemSheet.getShape();
return sheet; return sheet;
}// shapeFromItem // }// shapeFromItem //
@ -9152,7 +9146,7 @@ void CCharacterCL::setAuraFX(uint index, const CAnimationFX *sheet)
bi.DelayBeforeStart = 11.5f; bi.DelayBeforeStart = 11.5f;
_AttachedFXListToStart.push_front(bi); _AttachedFXListToStart.push_front(bi);
} }
else else
{ {
CAttachedFX::TSmartPtr fx = new CAttachedFX; CAttachedFX::TSmartPtr fx = new CAttachedFX;
fx->create(*this, bi, CAttachedFX::CTargeterInfo()); fx->create(*this, bi, CAttachedFX::CTargeterInfo());
@ -9711,7 +9705,7 @@ NLMISC_COMMAND(projectile, "Cast a projectile on another entity", "<spellID> <st
double dist = (target->pos() - ch->pos()).norm(); double dist = (target->pos() - ch->pos()).norm();
bool resist = false; bool resist = false;
if (args.size() > 4) fromString(args[4], resist); if (args.size() > 4) fromString(args[4], resist);
bc.Targets.Targets.push_back(CMultiTarget::CTarget(targetSlot, resist, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT)), -11)); bc.Targets.Targets.push_back(CMultiTarget::CTarget(targetSlot, resist, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT))));
} }
bc.BehavTime = TimeInSec; bc.BehavTime = TimeInSec;
ch->applyBehaviour(bc); ch->applyBehaviour(bc);
@ -9749,7 +9743,7 @@ NLMISC_COMMAND(mtProjectile, "Cast a projectile on one or several entities", "<c
if (mainTarget) if (mainTarget)
{ {
double dist = (mainTarget->pos() - ch->pos()).norm(); double dist = (mainTarget->pos() - ch->pos()).norm();
bc.Targets.Targets.push_back(CMultiTarget::CTarget(mainTargetSlot, false, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT)), 1)); bc.Targets.Targets.push_back(CMultiTarget::CTarget(mainTargetSlot, false, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT))));
for(sint k = 1; k < (sint) (args.size() - 4); ++k) for(sint k = 1; k < (sint) (args.size() - 4); ++k)
{ {
uint secondaryTargetSlot; uint secondaryTargetSlot;
@ -9759,7 +9753,7 @@ NLMISC_COMMAND(mtProjectile, "Cast a projectile on one or several entities", "<c
if (secondaryTarget) if (secondaryTarget)
{ {
dist = (secondaryTarget->pos() - mainTarget->pos()).norm(); dist = (secondaryTarget->pos() - mainTarget->pos()).norm();
bc.Targets.Targets.push_back(CMultiTarget::CTarget(secondaryTargetSlot, false, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT)), k+1)); bc.Targets.Targets.push_back(CMultiTarget::CTarget(secondaryTargetSlot, false, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT))));
} }
} }
} }
@ -9776,7 +9770,7 @@ NLMISC_COMMAND(mtProjectile, "Cast a projectile on one or several entities", "<c
if (target) if (target)
{ {
double dist = (target->pos() - ch->pos()).norm(); double dist = (target->pos() - ch->pos()).norm();
bc.Targets.Targets.push_back(CMultiTarget::CTarget(targetSlot, false, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT)), k+1)); bc.Targets.Targets.push_back(CMultiTarget::CTarget(targetSlot, false, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT))));
} }
} }
} }
@ -9793,7 +9787,7 @@ NLMISC_COMMAND(mtProjectile, "Cast a projectile on one or several entities", "<c
if (target) if (target)
{ {
double dist = (target->pos() - startSlot->pos()).norm(); double dist = (target->pos() - startSlot->pos()).norm();
bc.Targets.Targets.push_back(CMultiTarget::CTarget(targetSlot, false, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT)), k+1)); bc.Targets.Targets.push_back(CMultiTarget::CTarget(targetSlot, false, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT))));
startSlot = target; startSlot = target;
} }
} }
@ -10106,7 +10100,6 @@ NLMISC_COMMAND(attack, "simulate an attack", "<slot> <intensity> <hit_type> <loc
CMultiTarget::CTarget target; CMultiTarget::CTarget target;
target.TargetSlot = UserEntity->selection(); target.TargetSlot = UserEntity->selection();
target.Info = dsPower | (dsType << 3); target.Info = dsPower | (dsType << 3);
target.DeltaHP = -20;
bc.Targets.Targets.push_back(target); bc.Targets.Targets.push_back(target);
bc.BehavTime = TimeInSec; bc.BehavTime = TimeInSec;
bc.Behav.DeltaHP = -20; bc.Behav.DeltaHP = -20;
@ -10161,7 +10154,7 @@ NLMISC_COMMAND(rangeAttack, "simulate a range attack", "<slot> [intensity] [loca
CEntityCL *target = EntitiesMngr.entity(targetSlot); CEntityCL *target = EntitiesMngr.entity(targetSlot);
if (!target) return false; if (!target) return false;
double dist = (target->pos() - entity->pos()).norm(); double dist = (target->pos() - entity->pos()).norm();
bc.Targets.Targets.push_back(CMultiTarget::CTarget(targetSlot, false, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT)), -10)); bc.Targets.Targets.push_back(CMultiTarget::CTarget(targetSlot, false, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT))));
bc.Behav.DeltaHP = -10; bc.Behav.DeltaHP = -10;
entity->applyBehaviour(bc); entity->applyBehaviour(bc);
return true; return true;
@ -10195,7 +10188,7 @@ NLMISC_COMMAND(creatureAttack, "simulate a creature attack (2 attaques per creat
{ {
fromString(args[8], resist); fromString(args[8], resist);
} }
bc.Targets.Targets.push_back(CMultiTarget::CTarget(targetSlot, false, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT)), -15)); bc.Targets.Targets.push_back(CMultiTarget::CTarget(targetSlot, false, (uint8) ceilf((float) (dist / MULTI_TARGET_DISTANCE_UNIT))));
bc.Behav.CreatureAttack.ActionDuration = 0; bc.Behav.CreatureAttack.ActionDuration = 0;
uint magicImpactIntensity = 1; uint magicImpactIntensity = 1;
if (args.size() > 3) if (args.size() > 3)

@ -302,7 +302,6 @@ CClientConfig::CClientConfig()
SelectedSlot = 0; // Default is slot 0 SelectedSlot = 0; // Default is slot 0
Windowed = false; // Default is windowed mode. Windowed = false; // Default is windowed mode.
MonitorName = "";
Width = 0; // Default Width for the window (0 = current screen resolution). Width = 0; // Default Width for the window (0 = current screen resolution).
Height = 0; // Default Height for the window (0 = current screen resolution). Height = 0; // Default Height for the window (0 = current screen resolution).
Depth = 32; // Default Bit per Pixel. Depth = 32; // Default Bit per Pixel.
@ -413,7 +412,6 @@ CClientConfig::CClientConfig()
CameraRecorderPrefix = "cam_rec"; CameraRecorderPrefix = "cam_rec";
CameraRecorderBlend = true; CameraRecorderBlend = true;
ScreenShotDirectory = "screenshots";
ScreenShotWidth = 0; ScreenShotWidth = 0;
ScreenShotHeight = 0; ScreenShotHeight = 0;
ScreenShotFullDetail = true; ScreenShotFullDetail = true;
@ -849,8 +847,6 @@ void CClientConfig::setValues()
} }
else else
cfgWarning("Default value used for 'Fullscreen'"); cfgWarning("Default value used for 'Fullscreen'");
READ_STRING_FV(MonitorName);
// Width // Width
READ_INT_FV(Width) READ_INT_FV(Width)
// Height // Height
@ -1143,7 +1139,6 @@ void CClientConfig::setValues()
READ_BOOL_FV(CameraRecorderBlend) READ_BOOL_FV(CameraRecorderBlend)
// Screenshot // Screenshot
READ_STRING_FV(ScreenShotDirectory)
READ_INT_FV(ScreenShotWidth) READ_INT_FV(ScreenShotWidth)
READ_INT_FV(ScreenShotHeight) READ_INT_FV(ScreenShotHeight)
READ_BOOL_FV(ScreenShotFullDetail) READ_BOOL_FV(ScreenShotFullDetail)
@ -1299,6 +1294,7 @@ void CClientConfig::setValues()
if (varPtr) if (varPtr)
{ {
if (nlstricmp(varPtr->asString(), "Auto") == 0) ClientCfg.DriverSound = CClientConfig::SoundDrvAuto; if (nlstricmp(varPtr->asString(), "Auto") == 0) ClientCfg.DriverSound = CClientConfig::SoundDrvAuto;
else if (nlstricmp(varPtr->asString(), "FMod") == 0) ClientCfg.DriverSound = CClientConfig::SoundDrvFMod;
else if (nlstricmp(varPtr->asString(), "OpenAL") == 0) ClientCfg.DriverSound = CClientConfig::SoundDrvOpenAL; else if (nlstricmp(varPtr->asString(), "OpenAL") == 0) ClientCfg.DriverSound = CClientConfig::SoundDrvOpenAL;
else if (nlstricmp(varPtr->asString(), "DirectSound") == 0) ClientCfg.DriverSound = CClientConfig::SoundDrvDirectSound; else if (nlstricmp(varPtr->asString(), "DirectSound") == 0) ClientCfg.DriverSound = CClientConfig::SoundDrvDirectSound;
else if (nlstricmp(varPtr->asString(), "XAudio2") == 0) ClientCfg.DriverSound = CClientConfig::SoundDrvXAudio2; else if (nlstricmp(varPtr->asString(), "XAudio2") == 0) ClientCfg.DriverSound = CClientConfig::SoundDrvXAudio2;
@ -1997,11 +1993,6 @@ void CClientConfig::serial(NLMISC::IStream &f)
f.serial(Light); f.serial(Light);
f.xmlPop(); f.xmlPop();
f.xmlPushBegin("MonitorName");
f.xmlPushEnd();
f.serial(MonitorName);
f.xmlPop();
f.xmlPushBegin("Windowed"); f.xmlPushBegin("Windowed");
f.xmlPushEnd(); f.xmlPushEnd();
f.serial(Windowed); f.serial(Windowed);

@ -58,7 +58,7 @@ using std::string;
struct CClientConfig struct CClientConfig
{ {
enum TDriver3D { DrvAuto = 0, OpenGL, Direct3D, OpenGLES }; enum TDriver3D { DrvAuto = 0, OpenGL, Direct3D, OpenGLES };
enum TDriverSound { SoundDrvAuto = 0, SoundDrvOpenAL, SoundDrvDirectSound, SoundDrvXAudio2 }; enum TDriverSound { SoundDrvAuto = 0, SoundDrvFMod, SoundDrvOpenAL, SoundDrvDirectSound, SoundDrvXAudio2 };
enum TStageLCTUsage { StageUseNoLCT = 0, StageUseAllLCT, StageUsePosOnlyLCT }; enum TStageLCTUsage { StageUseNoLCT = 0, StageUseAllLCT, StageUsePosOnlyLCT };
// the config file must be always be available // the config file must be always be available
@ -137,8 +137,6 @@ struct CClientConfig
TDriver3D Driver3D; TDriver3D Driver3D;
/// Application start in a window or in fullscreen. /// Application start in a window or in fullscreen.
bool Windowed; bool Windowed;
/// Monitor to use for fullscreen
std::string MonitorName;
/// Width for the Application. /// Width for the Application.
uint16 Width; uint16 Width;
/// Height for the Application. /// Height for the Application.
@ -306,7 +304,6 @@ struct CClientConfig
bool CameraRecorderBlend; bool CameraRecorderBlend;
/// Screen shot /// Screen shot
string ScreenShotDirectory;
uint ScreenShotWidth; // If 0 : normal screen shot, else custom screen shot without interface uint ScreenShotWidth; // If 0 : normal screen shot, else custom screen shot without interface
uint ScreenShotHeight; uint ScreenShotHeight;
bool ScreenShotFullDetail; // If set to true, then load balancing will be disabled for the duration of the screenshot bool ScreenShotFullDetail; // If set to true, then load balancing will be disabled for the duration of the screenshot

@ -198,9 +198,38 @@ bool hasPrivilegeTESTER() { return (UserPrivileges.find(":TESTER:") != std::stri
// Restore the video mode (fullscreen for example) after the connection (done in a window) // Restore the video mode (fullscreen for example) after the connection (done in a window)
void connectionRestoreVideoMode () void connectionRestoreVideoMode ()
{ {
// Setup full screen if we have to
UDriver::CMode mode;
Driver->getCurrentScreenMode(mode);
if (mode.Windowed)
{
uint32 width, height;
Driver->getWindowSize(width, height);
mode.Width = width;
mode.Height = height;
}
// don't allow sizes smaller than 1024x768
if (ClientCfg.Width < 1024) ClientCfg.Width = 1024;
if (ClientCfg.Height < 768) ClientCfg.Height = 768;
if (StereoDisplay) if (StereoDisplay)
StereoDisplayAttached = StereoDisplay->attachToDisplay(); StereoDisplayAttached = StereoDisplay->attachToDisplay();
if (!StereoDisplayAttached && (
(ClientCfg.Windowed != mode.Windowed) ||
(ClientCfg.Width != mode.Width) ||
(ClientCfg.Height != mode.Height)))
{
mode.Windowed = ClientCfg.Windowed;
mode.Depth = uint8(ClientCfg.Depth);
mode.Width = ClientCfg.Width;
mode.Height = ClientCfg.Height;
mode.Frequency = ClientCfg.Frequency;
setVideoMode(mode);
}
// And setup hardware mouse if we have to // And setup hardware mouse if we have to
InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached); InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached);
SetMouseFreeLook (); SetMouseFreeLook ();
@ -1264,7 +1293,19 @@ TInterfaceState globalMenu()
// Restore video mode // Restore video mode
if (ClientCfg.SelectCharacter == -1) if (ClientCfg.SelectCharacter == -1)
{
if (ClientCfg.Windowed)
{
// if used changed window resolution in char select
// if we don't update ClientCfg, then UI from icfg is restored wrong
uint32 width, height;
Driver->getWindowSize(width, height);
ClientCfg.Width = width;
ClientCfg.Height = height;
}
connectionRestoreVideoMode (); connectionRestoreVideoMode ();
}
// Skip intro next time // Skip intro next time
ClientCfg.writeBool("SkipIntro", true); ClientCfg.writeBool("SkipIntro", true);

@ -466,7 +466,7 @@ void CLoginStateMachine::run()
/// check the data to check if patch needed /// check the data to check if patch needed
CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_PostLogin, "login_step_post_login")); CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_PostLogin, "login_step_post_login"));
if (!ClientCfg.PatchWanted || Args.haveLongArg("nopatch")) if (!ClientCfg.PatchWanted || (Args.haveArg("n") && Args.getLongArg("nopatch").front() == "1"))
{ {
// client don't want to be patched ! // client don't want to be patched !
_CurrentState = st_display_eula; _CurrentState = st_display_eula;

@ -1061,48 +1061,43 @@ void prelogInit()
return; return;
} }
UDriver::CMode mode; // used to determine screen default resolution
// first run (no client.cfg) if (ClientCfg.Width < 800 || ClientCfg.Height < 600)
if (ClientCfg.Width == 0 || ClientCfg.Height == 0)
{ {
if (Driver->getCurrentScreenMode(mode)) UDriver::CMode mode;
{
// fullscreen, using monitor resolution
mode.Windowed = false;
ClientCfg.MonitorName = mode.DisplayDevice; CConfigFile::CVar *varPtr = NULL;
ClientCfg.Windowed = mode.Windowed;
if (!ClientCfg.Windowed && Driver->getCurrentScreenMode(mode))
{
ClientCfg.Width = mode.Width; ClientCfg.Width = mode.Width;
ClientCfg.Height = mode.Height; ClientCfg.Height = mode.Height;
ClientCfg.Depth = mode.Depth; ClientCfg.Depth = mode.Depth;
ClientCfg.Frequency = mode.Frequency; ClientCfg.Frequency = mode.Frequency;
// update client.cfg with detected depth and frequency
varPtr = ClientCfg.ConfigFile.getVarPtr("Depth");
if(varPtr)
varPtr->forceAsInt(ClientCfg.Depth);
varPtr = ClientCfg.ConfigFile.getVarPtr("Frequency");
if(varPtr)
varPtr->forceAsInt(ClientCfg.Frequency);
} }
else else
{ {
// fallback
ClientCfg.Windowed = true;
ClientCfg.Width = 1024; ClientCfg.Width = 1024;
ClientCfg.Height = 768; ClientCfg.Height = 768;
} }
// update client.cfg with detected resolution // update client.cfg with detected resolution
ClientCfg.writeBool("FullScreen", !ClientCfg.Windowed, true); varPtr = ClientCfg.ConfigFile.getVarPtr("Width");
ClientCfg.writeString("MonitorName", ClientCfg.MonitorName, true); if(varPtr)
ClientCfg.writeInt("Width", ClientCfg.Width, true); varPtr->forceAsInt(ClientCfg.Width);
ClientCfg.writeInt("Height", ClientCfg.Height, true);
ClientCfg.writeInt("Depth", ClientCfg.Depth, true); varPtr = ClientCfg.ConfigFile.getVarPtr("Height");
ClientCfg.writeInt("Frequency", ClientCfg.Frequency, true); if(varPtr)
varPtr->forceAsInt(ClientCfg.Height);
ClientCfg.ConfigFile.save();
}
else
{
mode.DisplayDevice = ClientCfg.MonitorName;
mode.Windowed = ClientCfg.Windowed;
mode.Width = ClientCfg.Width;
mode.Height = ClientCfg.Height;
mode.Depth = ClientCfg.Depth;
mode.Frequency = ClientCfg.Frequency;
} }
CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetup, "login_step_video_mode_setup")); CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetup, "login_step_video_mode_setup"));
@ -1112,6 +1107,25 @@ void prelogInit()
// Check the driver is not is 16 bits // Check the driver is not is 16 bits
checkDriverDepth (); checkDriverDepth ();
UDriver::CMode mode;
if (Driver->getCurrentScreenMode(mode))
{
// use current mode if its smaller than 1024x768
// mode should be windowed already, but incase its not, use the mode as is
if (mode.Windowed && (mode.Width > 1024 && mode.Height > 768))
{
mode.Width = 1024;
mode.Height = 768;
}
}
else
{
mode.Width = 1024;
mode.Height = 768;
mode.Windowed = true;
}
// Disable Hardware Vertex Program. // Disable Hardware Vertex Program.
if(ClientCfg.DisableVtxProgram) if(ClientCfg.DisableVtxProgram)
Driver->disableHardwareVertexProgram(); Driver->disableHardwareVertexProgram();
@ -1246,11 +1260,10 @@ void prelogInit()
else else
{ {
// position is not saved in config so center the window // position is not saved in config so center the window
UDriver::CMode tmp; if (Driver->getCurrentScreenMode(mode))
if (Driver->getCurrentScreenMode(tmp))
{ {
posX = (tmp.Width - Driver->getWindowWidth())/2; posX = (mode.Width - Driver->getWindowWidth())/2;
posY = (tmp.Height - Driver->getWindowHeight())/2; posY = (mode.Height - Driver->getWindowHeight())/2;
} }
} }
@ -1443,15 +1456,6 @@ void prelogInit()
} }
} }
void stopSoundMngr()
{
if (SoundMngr)
{
delete SoundMngr;
SoundMngr = NULL;
}
}
// *************************************************************************** // ***************************************************************************
void initBotObjectSelection() void initBotObjectSelection()
@ -1584,39 +1588,6 @@ void postlogInit()
// set the primitive context // set the primitive context
CPrimitiveContext::instance().CurrentLigoConfig = &LigoConfig; CPrimitiveContext::instance().CurrentLigoConfig = &LigoConfig;
{
H_AUTO(InitRZSound)
if (!SoundMngr)
{
// Init the sound manager
nmsg = "Initializing sound manager...";
ProgressBar.newMessage(ClientCfg.buildLoadingString(nmsg));
if (ClientCfg.SoundOn)
{
SoundMngr = new CSoundManager(&ProgressBar);
try
{
SoundMngr->init(&ProgressBar);
}
catch (const Exception &e)
{
nlwarning("init : Error when creating 'SoundMngr' : %s", e.what());
delete SoundMngr;
SoundMngr = NULL;
}
if (SoundMngr)
{
// init the SoundMngr with backuped volume
SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume);
SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume);
}
}
}
}
{ {
H_AUTO(InitRZShIdI) H_AUTO(InitRZShIdI)

@ -1095,20 +1095,6 @@ public:
REGISTER_ACTION_HANDLER( CHandlerContextWebPage, "context_web_page"); REGISTER_ACTION_HANDLER( CHandlerContextWebPage, "context_web_page");
// ***************************************************************************
class CHandlerFullMap : public IActionHandler
{
public:
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
{
CInterfaceManager *pIM= CInterfaceManager::getInstance();
CLuaManager::getInstance().executeLuaScript("game:openFullMap()", true);
}
};
REGISTER_ACTION_HANDLER( CHandlerFullMap, "fullmap");
// *************************************************************************** // ***************************************************************************
@ -1972,7 +1958,7 @@ public:
bool womanTitle = false; bool womanTitle = false;
if (pChar != NULL) if (pChar != NULL)
womanTitle = pChar->getGender() == GSGENDER::female; womanTitle = pChar->getGender() == GSGENDER::female;
copyInout = STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(CEntityCL::getTitleFromName(copyInout), womanTitle); copyInout = STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(CEntityCL::getTitleFromName(copyInout), womanTitle);
// Sometimes translation contains another title // Sometimes translation contains another title
@ -2679,9 +2665,9 @@ class CAHAddShape : public IActionHandler
instance.setPos(CVector((float)x, (float)y, (float)z)); instance.setPos(CVector((float)x, (float)y, (float)z));
instance.setRotQuat(dir.getRot()); instance.setRotQuat(dir.getRot());
} }
instance.setTransformMode(UTransformable::RotEuler); instance.setTransformMode(UTransformable::RotEuler);
// if the shape is a particle system, additionnal parameters are user params // if the shape is a particle system, additionnal parameters are user params
UParticleSystemInstance psi; UParticleSystemInstance psi;
psi.cast (instance); psi.cast (instance);
@ -3416,7 +3402,7 @@ class CHandlerGameConfigVREnable : public IActionHandler
// VR_CONFIG // VR_CONFIG
CCtrlBaseButton *pBut = dynamic_cast<CCtrlBaseButton*>(CWidgetManager::getInstance()->getElementFromId(GAME_CONFIG_VR_ENABLE_BUTTON)); CCtrlBaseButton *pBut = dynamic_cast<CCtrlBaseButton*>(CWidgetManager::getInstance()->getElementFromId(GAME_CONFIG_VR_ENABLE_BUTTON));
if (pBut) if (pBut)
{ {
// hide or show device list depending on enabled or not // hide or show device list depending on enabled or not
updateVRDevicesComboUI(pBut->getPushed()); updateVRDevicesComboUI(pBut->getPushed());
@ -3472,7 +3458,6 @@ class CHandlerGameConfigApply : public IActionHandler
{ {
// Get W, H // Get W, H
sint w = 1024, h = 768; sint w = 1024, h = 768;
string name;
{ {
CDBGroupComboBox *pCB = dynamic_cast<CDBGroupComboBox*>(CWidgetManager::getInstance()->getElementFromId( GAME_CONFIG_VIDEO_MODES_COMBO )); CDBGroupComboBox *pCB = dynamic_cast<CDBGroupComboBox*>(CWidgetManager::getInstance()->getElementFromId( GAME_CONFIG_VIDEO_MODES_COMBO ));
if( pCB != NULL ) if( pCB != NULL )
@ -3482,11 +3467,6 @@ class CHandlerGameConfigApply : public IActionHandler
fromString(tmp, w); fromString(tmp, w);
tmp = vidModeStr.substr(vidModeStr.find('x')+2,vidModeStr.size()); tmp = vidModeStr.substr(vidModeStr.find('x')+2,vidModeStr.size());
fromString(tmp, h); fromString(tmp, h);
// extract monitor "1024x768 (VGA-1)"
string::size_type pos = vidModeStr.find('(');
if (pos != std::string::npos)
name = vidModeStr.substr(pos + 1, vidModeStr.find(")") - pos - 1);
} }
} }
@ -3529,7 +3509,6 @@ class CHandlerGameConfigApply : public IActionHandler
ClientCfg.Width = w; ClientCfg.Width = w;
ClientCfg.Height = h; ClientCfg.Height = h;
ClientCfg.MonitorName = name;
// Write the modified client.cfg // Write the modified client.cfg
ClientCfg.writeBool("FullScreen", bFullscreen); ClientCfg.writeBool("FullScreen", bFullscreen);
@ -3538,7 +3517,6 @@ class CHandlerGameConfigApply : public IActionHandler
if (bFullscreen) if (bFullscreen)
{ {
ClientCfg.writeString("MonitorName", name, true);
ClientCfg.writeInt("Depth", screenMode.Depth); ClientCfg.writeInt("Depth", screenMode.Depth);
ClientCfg.writeInt("Frequency", freq); ClientCfg.writeInt("Frequency", freq);
} }
@ -3555,7 +3533,7 @@ class CHandlerGameConfigApply : public IActionHandler
NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHAT:AUTO_CHANNEL")->setValue32(pCS->getPushed()); NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHAT:AUTO_CHANNEL")->setValue32(pCS->getPushed());
CCtrlBaseButton *pBut = dynamic_cast<CCtrlBaseButton*>(CWidgetManager::getInstance()->getElementFromId(GAME_CONFIG_VR_ENABLE_BUTTON)); CCtrlBaseButton *pBut = dynamic_cast<CCtrlBaseButton*>(CWidgetManager::getInstance()->getElementFromId(GAME_CONFIG_VR_ENABLE_BUTTON));
if (pBut) if (pBut)
{ {
// store the new config variables // store the new config variables
ClientCfg.VREnable = pBut->getPushed(); ClientCfg.VREnable = pBut->getPushed();

@ -208,7 +208,7 @@ void CInterfaceItemEdition::CItemEditionWindow::begin()
{ {
if(_CurrItemSheet && !WindowName.empty()) if(_CurrItemSheet && !WindowName.empty())
{ {
const CItemSheet *pIS = _CurrItemSheet->asItemSheet(); const CItemSheet *pIS = _CurrItemSheet->asItemSheet();
if ((pIS != NULL) && ITEMFAMILY::isTextCustomizable(pIS->Family) ) if ((pIS != NULL) && ITEMFAMILY::isTextCustomizable(pIS->Family) )
{ {
@ -342,7 +342,7 @@ void CInterfaceItemEdition::CItemEditionWindow::begin()
// ******************************************************************************************** // ********************************************************************************************
void CInterfaceItemEdition::CItemEditionWindow::end() void CInterfaceItemEdition::CItemEditionWindow::end()
{ {
CDBCtrlSheet *pCSItem = _CurrItemSheet; CDBCtrlSheet *pCSItem = _CurrItemSheet;
std::string windowName = WindowName; std::string windowName = WindowName;
if(pCSItem && !windowName.empty()) if(pCSItem && !windowName.empty())
@ -371,7 +371,7 @@ void CInterfaceItemEdition::CItemEditionWindow::end()
editBoxShort->setActive(false); editBoxShort->setActive(false);
editShort->setActive(false); editShort->setActive(false);
editBoxLarge->setActive(false); editBoxLarge->setActive(false);
editLarge->setActive(false); editLarge->setActive(false);
display->setActive(false); display->setActive(false);
editButtons->setActive(false); editButtons->setActive(false);
closeButton->setActive(false); closeButton->setActive(false);
@ -413,7 +413,7 @@ void CInterfaceItemEdition::CItemEditionWindow::validate()
textValid = editLarge->getActive(); textValid = editLarge->getActive();
text = editBoxLarge->getInputString(); text = editBoxLarge->getInputString();
} }
if (textValid) if (textValid)
{ {
CBitMemStream out; CBitMemStream out;
@ -562,7 +562,7 @@ static void openStackItem(CCtrlBase *pCaller, CDBCtrlSheet *pCSSrc, CDBCtrlSheet
//===================================================================================================================== //=====================================================================================================================
static void sendExchangeAddToServer(uint16 srcInvIndex, uint16 srcSlotIndex, uint16 destSlotIndex, uint16 quantitySrc) static void sendExchangeAddToServer(uint16 srcSlotIndex, uint16 destSlotIndex, uint16 quantitySrc)
{ {
CInterfaceManager *pIM= CInterfaceManager::getInstance(); CInterfaceManager *pIM= CInterfaceManager::getInstance();
@ -571,7 +571,6 @@ static void openStackItem(CCtrlBase *pCaller, CDBCtrlSheet *pCSSrc, CDBCtrlSheet
if(GenericMsgHeaderMngr.pushNameToStream(sMsg, out)) if(GenericMsgHeaderMngr.pushNameToStream(sMsg, out))
{ {
// Swap all the Src (quantity= quantitySrc) to dest // Swap all the Src (quantity= quantitySrc) to dest
out.serial(srcInvIndex);
out.serial(srcSlotIndex); out.serial(srcSlotIndex);
out.serial(destSlotIndex); out.serial(destSlotIndex);
out.serial(quantitySrc); out.serial(quantitySrc);
@ -616,7 +615,7 @@ static void openStackItem(CCtrlBase *pCaller, CDBCtrlSheet *pCSSrc, CDBCtrlSheet
NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:EXCHANGE:ACCEPTED")->setValue32(0); NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:EXCHANGE:ACCEPTED")->setValue32(0);
// send msg to server // send msg to server
sendExchangeAddToServer((uint16) src->getSecondIndexInDB(), (uint16)src->getIndexInDB(), (uint8)dest->getIndexInDB(), (uint16)quantitySrc); sendExchangeAddToServer((uint16)src->getIndexInDB(), (uint8)dest->getIndexInDB(), (uint16)quantitySrc);
} }
else else
{ {
@ -726,7 +725,7 @@ static void validateStackItem(CDBCtrlSheet *pCSSrc, CDBCtrlSheet *pCSDst, sint32
NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:EXCHANGE:ACCEPTED")->setValue32(0); NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:EXCHANGE:ACCEPTED")->setValue32(0);
// send msg to server // send msg to server
sendExchangeAddToServer((uint16)pCSSrc->getSecondIndexInDB(), (uint16)pCSSrc->getIndexInDB(), (uint8)pCSDst->getIndexInDB(), (uint16)val); sendExchangeAddToServer((uint16)pCSSrc->getIndexInDB(), (uint8)pCSDst->getIndexInDB(), (uint16)val);
} }
} }
} }
@ -747,10 +746,6 @@ public:
CInterfaceElement *pElt = CWidgetManager::getInstance()->getElementFromId(src); CInterfaceElement *pElt = CWidgetManager::getInstance()->getElementFromId(src);
CDBCtrlSheet *pCSSrc = dynamic_cast<CDBCtrlSheet*>(pElt); CDBCtrlSheet *pCSSrc = dynamic_cast<CDBCtrlSheet*>(pElt);
CDBCtrlSheet *pCSDst = dynamic_cast<CDBCtrlSheet*>(pCaller); CDBCtrlSheet *pCSDst = dynamic_cast<CDBCtrlSheet*>(pCaller);
// end drag
getInventory().endDrag();
if ((pCSSrc == NULL) || (pCSDst == NULL)) return; if ((pCSSrc == NULL) || (pCSDst == NULL)) return;
if (pCSSrc->getType() == CCtrlSheetInfo::SheetType_Item) if (pCSSrc->getType() == CCtrlSheetInfo::SheetType_Item)
@ -1054,21 +1049,9 @@ class CCanDropToExchange : public IActionHandler
if (!pCSSrc || !pCSDst) return; if (!pCSSrc || !pCSDst) return;
// Exchange can only be done from bag to exchange inventories // Exchange can only be done from bag to exchange inventories
uint32 srcInventory = pCSSrc->getSecondIndexInDB();
if ( if (pCSSrc->getSecondIndexInDB() == INVENTORIES::bag &&
(srcInventory == INVENTORIES::bag || pCSDst->getSecondIndexInDB() == INVENTORIES::exchange)
srcInventory == INVENTORIES::pet_animal1 ||
srcInventory == INVENTORIES::pet_animal2 ||
srcInventory == INVENTORIES::pet_animal3 ||
srcInventory == INVENTORIES::pet_animal4 ||
srcInventory == INVENTORIES::pet_animal5 ||
srcInventory == INVENTORIES::pet_animal6 ||
srcInventory == INVENTORIES::pet_animal7 ||
srcInventory == INVENTORIES::guild ||
srcInventory == INVENTORIES::player_room)
&& getInventory().isInventoryAvailable((INVENTORIES::TInventory) pCSSrc->getSecondIndexInDB())
&& pCSDst->getSecondIndexInDB() == INVENTORIES::exchange
)
{ {
if (checkCanExchangeItem(pCSSrc)) if (checkCanExchangeItem(pCSSrc))
{ {
@ -1739,7 +1722,7 @@ void CItemMenuInBagInfoWaiter::infoReceived()
void CItemMenuInBagInfoWaiter::infoValidated(CDBCtrlSheet* ctrlSheet) void CItemMenuInBagInfoWaiter::infoValidated(CDBCtrlSheet* ctrlSheet)
{ {
CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceManager *pIM = CInterfaceManager::getInstance();
// get the dialog stack // get the dialog stack
CInterfaceGroup* pMenu = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId("ui:interface:item_menu_in_bag") ); CInterfaceGroup* pMenu = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId("ui:interface:item_menu_in_bag") );
if(!pMenu) return; if(!pMenu) return;
@ -1885,7 +1868,7 @@ class CHandlerItemMenuCheck : public IActionHandler
} }
if (pItemTextDisplay && pIS->Family == ITEMFAMILY::SCROLL) if (pItemTextDisplay && pIS->Family == ITEMFAMILY::SCROLL)
{ {
if (pCS->getInventoryIndex()==INVENTORIES::bag && pIS->Scroll.Label.empty()) if (pCS->getInventoryIndex()==INVENTORIES::bag)
pItemTextDisplay->setActive(true); pItemTextDisplay->setActive(true);
pItemInfos->setActive(false); pItemInfos->setActive(false);
} }
@ -1977,15 +1960,16 @@ class CHandlerItemMenuCheck : public IActionHandler
for(i=0;i<MAX_INVENTORY_ANIMAL;i++) for(i=0;i<MAX_INVENTORY_ANIMAL;i++)
{ {
if (pMoveToPa[i]) if (pMoveToPa[i])
pMoveToPa[i]->setActive((uint)invId!=INVENTORIES::pet_animal+i && pMoveToPa[i]->setActive(invId!=INVENTORIES::guild &&
(uint)invId!=INVENTORIES::pet_animal+i &&
invMngr.isInventoryPresent((INVENTORIES::TInventory)(INVENTORIES::pet_animal+i)) ); invMngr.isInventoryPresent((INVENTORIES::TInventory)(INVENTORIES::pet_animal+i)) );
} }
if (pMoveToGuild) if (pMoveToGuild)
pMoveToGuild->setActive(invId!=INVENTORIES::guild && invMngr.isInventoryPresent(INVENTORIES::guild)); pMoveToGuild->setActive(invId==INVENTORIES::bag && invMngr.isInventoryPresent(INVENTORIES::guild));
if (pMoveToRoom) if (pMoveToRoom)
pMoveToRoom->setActive(invId!=INVENTORIES::player_room && invMngr.isInventoryPresent(INVENTORIES::player_room)); pMoveToRoom->setActive(invId==INVENTORIES::bag && invMngr.isInventoryPresent(INVENTORIES::player_room));
// std case: can drop / destroy // std case: can drop / destroy
if(pDrop) pDrop->setActive(invId!=INVENTORIES::guild); if(pDrop) pDrop->setActive(invId!=INVENTORIES::guild);
@ -2053,7 +2037,7 @@ class CHandlerItemMenuCheck : public IActionHandler
if (pMoveSubMenu) pMoveSubMenu->setActive(false); if (pMoveSubMenu) pMoveSubMenu->setActive(false);
} }
if (bIsLockedByOwner) if (bIsLockedByOwner)
{ {
if (pLockUnlock) pLockUnlock->setHardText("uimUnlockItem"); if (pLockUnlock) pLockUnlock->setHardText("uimUnlockItem");
// Cannot drop/destroy if locked by owner // Cannot drop/destroy if locked by owner
@ -2066,8 +2050,7 @@ class CHandlerItemMenuCheck : public IActionHandler
} }
// Only show lock menu item if inventory contains the info // Only show lock menu item if inventory contains the info
if (invId!=INVENTORIES::guild) if (pLockUnlock) pLockUnlock->setActive(pCS->canOwnerLock());
if (pLockUnlock) pLockUnlock->setActive(pCS->canOwnerLock());
// **** Gray Entries // **** Gray Entries
@ -2224,7 +2207,7 @@ class CHandlerItemMenuBaseCheck : public IActionHandler
CViewTextMenu *pDestroy = dynamic_cast<CViewTextMenu*>(pMenu->getView("destroy")); CViewTextMenu *pDestroy = dynamic_cast<CViewTextMenu*>(pMenu->getView("destroy"));
CViewTextMenu *pLockUnlock = dynamic_cast<CViewTextMenu*>(pMenu->getView("lockunlock")); CViewTextMenu *pLockUnlock = dynamic_cast<CViewTextMenu*>(pMenu->getView("lockunlock"));
if (pCS->getLockedByOwner()) if (pCS->getLockedByOwner())
{ {
pLockUnlock->setHardText("uimUnlockItem"); pLockUnlock->setHardText("uimUnlockItem");
// Cannot destroy if locked by owner // Cannot destroy if locked by owner
@ -2381,7 +2364,7 @@ class CHandlerItemTextDisplay : public IActionHandler
std::string const& windowName = sParams; std::string const& windowName = sParams;
CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceManager *pIM = CInterfaceManager::getInstance();
CDBCtrlSheet *pCSItem = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal()); CDBCtrlSheet *pCSItem = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
if (pCSItem == NULL || windowName.empty()) if (pCSItem == NULL || windowName.empty())
return; return;
const CItemSheet *pIS = pCSItem->asItemSheet(); const CItemSheet *pIS = pCSItem->asItemSheet();
@ -2402,7 +2385,7 @@ class CHandlerItemTextEdition : public IActionHandler
std::string const& windowName = sParams; std::string const& windowName = sParams;
CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceManager *pIM = CInterfaceManager::getInstance();
CDBCtrlSheet *pCSItem = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal()); CDBCtrlSheet *pCSItem = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
if (pCSItem == NULL || windowName.empty()) if (pCSItem == NULL || windowName.empty())
return; return;
CInterfaceItemEdition::getInstance()->setCurrWindow(pCSItem, windowName, true); CInterfaceItemEdition::getInstance()->setCurrWindow(pCSItem, windowName, true);

@ -62,6 +62,9 @@ extern NLMISC::CLog g_log;
//////////// ////////////
//static CCDBNodeLeaf *MenuColorWidgetValue = NULL; // db entry for the color menu widget (Red) //static CCDBNodeLeaf *MenuColorWidgetValue = NULL; // db entry for the color menu widget (Red)
static const string ScreenshotsDirectory("screenshots/"); // don't forget the final /
void preRenderNewSky (); void preRenderNewSky ();
// *************************************************************************** // ***************************************************************************
@ -599,6 +602,11 @@ void displayScreenShotSavedInfo(const string &filename)
pIM->displaySystemInfo(msg); pIM->displaySystemInfo(msg);
} }
void initScreenshot()
{
if (!CFile::isExists(ScreenshotsDirectory)) CFile::createDirectory(ScreenshotsDirectory);
}
bool screenshotZBuffer(const std::string &filename) bool screenshotZBuffer(const std::string &filename)
{ {
std::string::size_type pos = filename.find("."); std::string::size_type pos = filename.find(".");
@ -664,11 +672,6 @@ bool screenshotZBuffer(const std::string &filename)
static std::string findNewScreenShotFileName(std::string filename) static std::string findNewScreenShotFileName(std::string filename)
{ {
// make screenshot directory if it does not exist
if (!CFile::isExists(ClientCfg.ScreenShotDirectory))
CFile::createDirectory(ClientCfg.ScreenShotDirectory);
filename = CPath::standardizePath(ClientCfg.ScreenShotDirectory) + filename;
static char cstime[25]; static char cstime[25];
time_t dtime; time_t dtime;
time(&dtime); time(&dtime);
@ -695,7 +698,7 @@ void screenShotTGA()
CBitmap btm; CBitmap btm;
getBuffer (btm); getBuffer (btm);
string filename = findNewScreenShotFileName("screenshot.tga"); string filename = findNewScreenShotFileName(ScreenshotsDirectory+"screenshot.tga");
COFile fs(filename); COFile fs(filename);
if (!btm.writeTGA(fs, 24, false)) if (!btm.writeTGA(fs, 24, false))
@ -717,7 +720,7 @@ void screenShotPNG()
CBitmap btm; CBitmap btm;
getBuffer (btm); getBuffer (btm);
string filename = findNewScreenShotFileName("screenshot.png"); string filename = findNewScreenShotFileName(ScreenshotsDirectory+"screenshot.png");
COFile fs(filename); COFile fs(filename);
if (!btm.writePNG(fs, 24)) if (!btm.writePNG(fs, 24))
@ -739,7 +742,7 @@ void screenShotJPG()
CBitmap btm; CBitmap btm;
getBuffer (btm); getBuffer (btm);
string filename = findNewScreenShotFileName("screenshot.jpg"); string filename = findNewScreenShotFileName(ScreenshotsDirectory+"screenshot.jpg");
COFile fs(filename); COFile fs(filename);
if (!btm.writeJPG(fs)) if (!btm.writeJPG(fs))

@ -181,6 +181,7 @@ public:
/** Capture current content of framebuffer and save the result. If a custom size is asked in ClientCfg, then the scene is rendered again /** Capture current content of framebuffer and save the result. If a custom size is asked in ClientCfg, then the scene is rendered again
* instead (possibly multiple time) * instead (possibly multiple time)
*/ */
void initScreenshot();
void screenShotTGA(); void screenShotTGA();
void screenShotPNG(); void screenShotPNG();
void screenShotJPG(); void screenShotJPG();

@ -50,10 +50,6 @@ using namespace NLMISC;
// *************************************************************************** // ***************************************************************************
const std::string FaberPlanDB= "UI:PHRASE:FABER:FABER_PLAN:SHEET"; const std::string FaberPlanDB= "UI:PHRASE:FABER:FABER_PLAN:SHEET";
const std::string FaberPlanHpBuffDB= "UI:PHRASE:FABER:FABER_PLAN:HP_BUFF";
const std::string FaberPlanSapBuffDB= "UI:PHRASE:FABER:FABER_PLAN:SAP_BUFF";
const std::string FaberPlanStaBuffDB= "UI:PHRASE:FABER:FABER_PLAN:STA_BUFF";
const std::string FaberPlanFocusBuffDB= "UI:PHRASE:FABER:FABER_PLAN:FOCUS_BUFF";
const std::string MPFaberDB= "UI:PHRASE:FABER:MP_BUILD"; const std::string MPFaberDB= "UI:PHRASE:FABER:MP_BUILD";
const std::string MPSelectionDB= "UI:PHRASE:FABER:MP_SELECT"; const std::string MPSelectionDB= "UI:PHRASE:FABER:MP_SELECT";
const std::string MPQuantityDb= "UI:PHRASE:FABER:MP_QUANTITY"; const std::string MPQuantityDb= "UI:PHRASE:FABER:MP_QUANTITY";
@ -174,16 +170,6 @@ void CActionPhraseFaber::launchFaberCastWindow(sint32 memoryLine, uint memoryIn
if(node) if(node)
node->setValue32(0); node->setValue32(0);
// Reset buff values
node = NLGUI::CDBManager::getInstance()->getDbProp(FaberPlanHpBuffDB, false);
if (node) node->setValue32(0);
node = NLGUI::CDBManager::getInstance()->getDbProp(FaberPlanSapBuffDB, false);
if (node) node->setValue32(0);
node = NLGUI::CDBManager::getInstance()->getDbProp(FaberPlanStaBuffDB, false);
if (node) node->setValue32(0);
node = NLGUI::CDBManager::getInstance()->getDbProp(FaberPlanFocusBuffDB, false);
if (node) node->setValue32(0);
// Reset the result item // Reset the result item
node= NLGUI::CDBManager::getInstance()->getDbProp(ItemResultSheetDB, false); node= NLGUI::CDBManager::getInstance()->getDbProp(ItemResultSheetDB, false);
if(node) if(node)
@ -1579,14 +1565,6 @@ void CActionPhraseFaber::updateItemResult()
uint phraseSlot= pPM->getMemorizedPhrase(_ExecuteFromMemoryLine, _ExecuteFromMemoryIndex); uint phraseSlot= pPM->getMemorizedPhrase(_ExecuteFromMemoryLine, _ExecuteFromMemoryIndex);
const CSPhraseCom &phrase= pPM->getPhrase(phraseSlot); const CSPhraseCom &phrase= pPM->getPhrase(phraseSlot);
uint32 recommendedPropId= pBM->getBrickPropId("cr_recommended"); uint32 recommendedPropId= pBM->getBrickPropId("cr_recommended");
uint32 crHp = pBM->getBrickPropId("cr_hp");
uint32 crSap = pBM->getBrickPropId("cr_sap");
uint32 crSta = pBM->getBrickPropId("cr_sta");
uint32 crFocus = pBM->getBrickPropId("cr_focus");
sint32 hpBuff = 0;
sint32 sapBuff = 0;
sint32 staBuff = 0;
sint32 focusBuff = 0;
for(i=0;i<phrase.Bricks.size();i++) for(i=0;i<phrase.Bricks.size();i++)
{ {
CSBrickSheet *brick= pBM->getBrick(phrase.Bricks[i]); CSBrickSheet *brick= pBM->getBrick(phrase.Bricks[i]);
@ -1600,30 +1578,10 @@ void CActionPhraseFaber::updateItemResult()
// minimze the level // minimze the level
minLevel= min(minLevel, sint32(brick->Properties[j].Value)); minLevel= min(minLevel, sint32(brick->Properties[j].Value));
} }
if (brick->Properties[j].PropId == crHp)
hpBuff = sint32(brick->Properties[j].Value);
if (brick->Properties[j].PropId == crSap)
sapBuff = sint32(brick->Properties[j].Value);
if (brick->Properties[j].PropId == crSta)
staBuff = sint32(brick->Properties[j].Value);
if (brick->Properties[j].PropId == crFocus)
focusBuff = sint32(brick->Properties[j].Value);
} }
} }
} }
{
NLGUI::CDBManager *cdb = NLGUI::CDBManager::getInstance();
NLMISC::CCDBNodeLeaf *node = cdb->getDbProp(FaberPlanHpBuffDB, false);
if (node) node->setValue32(hpBuff);
node = cdb->getDbProp(FaberPlanSapBuffDB, false);
if (node) node->setValue32(sapBuff);
node = cdb->getDbProp(FaberPlanStaBuffDB, false);
if (node) node->setValue32(staBuff);
node = cdb->getDbProp(FaberPlanFocusBuffDB, false);
if (node) node->setValue32(focusBuff);
}
// **** Parse all MPs setuped, to compute level and stats // **** Parse all MPs setuped, to compute level and stats
uint totalItemPartMPReq= 0; uint totalItemPartMPReq= 0;

@ -1026,8 +1026,6 @@ void CChatGroupWindow::loadFreeTeller(NLMISC::IStream &f)
f.serial(sTitle); f.serial(sTitle);
title = sTitle.toUtf8(); title = sTitle.toUtf8();
} }
else
f.serial(title);
CGroupContainer *pGC = createFreeTeller(title, ""); CGroupContainer *pGC = createFreeTeller(title, "");

@ -309,6 +309,7 @@ CCtrlSheetInfo::CCtrlSheetInfo()
_InterfaceColor= true; _InterfaceColor= true;
_SheetSelectionGroup = -1; _SheetSelectionGroup = -1;
_UseQuality = true; _UseQuality = true;
_DisplayItemQuality = true;
_UseQuantity = true; _UseQuantity = true;
_DuplicateOnDrag = false; _DuplicateOnDrag = false;
_ItemSlot= SLOTTYPE::UNDEFINED; _ItemSlot= SLOTTYPE::UNDEFINED;
@ -1276,9 +1277,6 @@ void CDBCtrlSheet::setupItem ()
sint32 sheet = _SheetId.getSInt32(); sint32 sheet = _SheetId.getSInt32();
_DispQuality = -1;
_DispQuantity = -1;
// If this is the same sheet, need to resetup // If this is the same sheet, need to resetup
if (_LastSheetId != sheet || _NeedSetup) if (_LastSheetId != sheet || _NeedSetup)
{ {
@ -1292,6 +1290,13 @@ void CDBCtrlSheet::setupItem ()
{ {
_ItemSheet = (CItemSheet*)pES; _ItemSheet = (CItemSheet*)pES;
// Display the item quality?
_DisplayItemQuality= _UseQuality &&
_ItemSheet->Family != ITEMFAMILY::COSMETIC &&
_ItemSheet->Family != ITEMFAMILY::TELEPORT &&
_ItemSheet->Family != ITEMFAMILY::SERVICE
;
_DispSheetBmpId = rVR.getTextureIdFromName (_ItemSheet->getIconMain()); _DispSheetBmpId = rVR.getTextureIdFromName (_ItemSheet->getIconMain());
// if file not found or empty, replace by default icon // if file not found or empty, replace by default icon
if( _DispSheetBmpId == -1) if( _DispSheetBmpId == -1)
@ -1345,11 +1350,21 @@ void CDBCtrlSheet::setupItem ()
_DispQuantity = _Quantity.getSInt32(); _DispQuantity = _Quantity.getSInt32();
} }
} }
else
// do not display any number
_DispQuantity = -1;
} }
else _DispQuantity = -1;
// Setup quality // Setup quality
if(_UseQuality) if(_DisplayItemQuality)
{
_DispQuality= _Quality.getSInt32(); _DispQuality= _Quality.getSInt32();
}
else
{
_DispQuality= -1;
}
// special icon text // special icon text
if( _NeedSetup || _ItemSheet->getIconText() != _OptString ) if( _NeedSetup || _ItemSheet->getIconText() != _OptString )
@ -1388,7 +1403,7 @@ void CDBCtrlSheet::setupItem ()
} }
// update quality. NB: if quality change, the must updateItemCharacRequirement // update quality. NB: if quality change, the must updateItemCharacRequirement
if(_UseQuality) if(_DisplayItemQuality)
{ {
sint32 newQuality= _Quality.getSInt32(); sint32 newQuality= _Quality.getSInt32();
if(newQuality!=_DispQuality) if(newQuality!=_DispQuality)
@ -1397,6 +1412,10 @@ void CDBCtrlSheet::setupItem ()
updateItemCharacRequirement(_LastSheetId); updateItemCharacRequirement(_LastSheetId);
} }
} }
else
{
_DispQuality= -1;
}
// update armour color (if USER_COLOR db change comes after SHEET change) // update armour color (if USER_COLOR db change comes after SHEET change)
if(_ArmourColorFromDB && _UserColor) if(_ArmourColorFromDB && _UserColor)
@ -1409,31 +1428,6 @@ void CDBCtrlSheet::setupItem ()
} }
} }
if (_ItemSheet != NULL)
{
switch(_ItemSheet->Family)
{
case ITEMFAMILY::ARMOR:
case ITEMFAMILY::MELEE_WEAPON:
case ITEMFAMILY::RANGE_WEAPON:
case ITEMFAMILY::SHIELD:
case ITEMFAMILY::JEWELRY:
case ITEMFAMILY::CRAFTING_TOOL:
case ITEMFAMILY::HARVEST_TOOL:
case ITEMFAMILY::TAMING_TOOL:
case ITEMFAMILY::TRAINING_TOOL:
// hide 'x0' and 'x1' stack count for equipable items
if (_DispQuantity < 2)
_DispQuantity = -1;
break;
default:
// hide 'q0'and 'q1' quality for every other item
if (_DispQuality < 2)
_DispQuality = -1;
break;
}
}
// at each frame, must test for grayed. // at each frame, must test for grayed.
if(_AutoGrayed) if(_AutoGrayed)
{ {
@ -1899,6 +1893,8 @@ void CDBCtrlSheet::setupOutpostBuilding()
{ {
COutpostBuildingSheet *pOBSheet = (COutpostBuildingSheet*)pES; COutpostBuildingSheet *pOBSheet = (COutpostBuildingSheet*)pES;
_DisplayItemQuality = false;
_DispSheetBmpId = rVR.getTextureIdFromName (pOBSheet->getIconMain()); _DispSheetBmpId = rVR.getTextureIdFromName (pOBSheet->getIconMain());
// if file not found or empty, replace by default icon // if file not found or empty, replace by default icon
if( _DispSheetBmpId == -1) if( _DispSheetBmpId == -1)
@ -2538,8 +2534,7 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
// there is max 4 icons // there is max 4 icons
sint32 hArea = (hSheet / 4); sint32 hArea = (hSheet / 4);
sint32 xIcon = x; sint32 xIcon = x;
// move buff icons up a row, quantity text is displayed on bottom-left corner sint32 yIcon = y;
sint32 yIcon = y + (_DispQuantity > 0 ? hArea : 0);
for (uint i = 0; i < _BuffIcons.size(); ++i) for (uint i = 0; i < _BuffIcons.size(); ++i)
{ {
sint32 wIcon = _BuffIcons[i].IconW; sint32 wIcon = _BuffIcons[i].IconW;

@ -164,6 +164,7 @@ public:
bool _UseQuantity : 1; // is the quantity read and displayed ? bool _UseQuantity : 1; // is the quantity read and displayed ?
bool _ReadQuantityFromSheet : 1; // Read quantity from sheet rather than from database bool _ReadQuantityFromSheet : 1; // Read quantity from sheet rather than from database
bool _UseQuality : 1; // is the quality read and displayed ? bool _UseQuality : 1; // is the quality read and displayed ?
bool _DisplayItemQuality : 1; // Do we have to display the quality for the item (false for Cosmetics and Teleport and if _UseQuality==fasle)?
bool _DuplicateOnDrag : 1; // when dragged, the item is shown twice : one version at the mouse position. bool _DuplicateOnDrag : 1; // when dragged, the item is shown twice : one version at the mouse position.
// and another in the source slot. Useful for items to buy that are in infinite quantity. // and another in the source slot. Useful for items to buy that are in infinite quantity.
bool _AutoGrayed : 1; // if true then gray the ctrlSheeet if: 1/ Items: Is the Item Locked. 2/ Bricks: is the brick Latent. bool _AutoGrayed : 1; // if true then gray the ctrlSheeet if: 1/ Items: Is the Item Locked. 2/ Bricks: is the brick Latent.

@ -713,7 +713,7 @@ int CInterface3DScene::luaGetElement(CLuaState &ls)
} }
return 1; return 1;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
string CInterface3DScene::getCurrentCamera() const string CInterface3DScene::getCurrentCamera() const
{ {
@ -1288,7 +1288,7 @@ float CInterface3DShape::getBBoxSizeX () const
{ {
CAABBox bbox; CAABBox bbox;
_Instance.getShapeAABBox(bbox); _Instance.getShapeAABBox(bbox);
if (bbox.getCenter() == CVector::Null) if (bbox.getCenter() == CVector::Null)
return -0.5f; return -0.5f;
@ -1299,7 +1299,7 @@ float CInterface3DShape::getBBoxSizeY () const
{ {
CAABBox bbox; CAABBox bbox;
_Instance.getShapeAABBox(bbox); _Instance.getShapeAABBox(bbox);
if (bbox.getCenter() == CVector::Null) if (bbox.getCenter() == CVector::Null)
return -0.5f; return -0.5f;
@ -1310,7 +1310,7 @@ float CInterface3DShape::getBBoxSizeZ () const
{ {
CAABBox bbox; CAABBox bbox;
_Instance.getShapeAABBox(bbox); _Instance.getShapeAABBox(bbox);
if (bbox.getCenter() == CVector::Null) if (bbox.getCenter() == CVector::Null)
return -0.5f; return -0.5f;
@ -1437,34 +1437,6 @@ void CInterface3DShape::setName (const std::string &ht)
} }
} }
std::string CInterface3DShape::getTextures() const
{
return _Textures;
}
void CInterface3DShape::setTextures(const std::string &textures)
{
if (textures.empty())
return;
_Textures = textures;
vector<string> texList;
splitString(textures, " ", texList);
for(uint j=0;j<_Instance.getNumMaterials();j++)
{
sint numStages = _Instance.getMaterial(j).getLastTextureStage() + 1;
for(sint l = 0; l < numStages; l++)
{
if (_Instance.getMaterial(j).isTextureFile((uint) l))
{
_Instance.getMaterial(j).setTextureFileName(texList[std::min((int)j, (int)texList.size()-1)], (uint) l);
}
}
}
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// CInterface3DCamera // CInterface3DCamera
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

@ -87,7 +87,7 @@ public:
void setDistLimitMax(float limitMax) { _DistLimitMax = limitMax;} void setDistLimitMax(float limitMax) { _DistLimitMax = limitMax;}
int luaGetElement(CLuaState &ls); int luaGetElement(CLuaState &ls);
REFLECT_EXPORT_START(CInterface3DScene, CInterfaceGroup) REFLECT_EXPORT_START(CInterface3DScene, CInterfaceGroup)
REFLECT_LUA_METHOD ("getElement", luaGetElement); REFLECT_LUA_METHOD ("getElement", luaGetElement);
REFLECT_STRING ("curcam", getCurrentCamera, setCurrentCamera); REFLECT_STRING ("curcam", getCurrentCamera, setCurrentCamera);
@ -265,15 +265,11 @@ public:
std::string getName() const; std::string getName() const;
void setName (const std::string &ht); void setName (const std::string &ht);
std::string getTextures() const;
void setTextures (const std::string &textures);
float getBBoxSizeX () const; float getBBoxSizeX () const;
float getBBoxSizeY () const; float getBBoxSizeY () const;
float getBBoxSizeZ () const; float getBBoxSizeZ () const;
REFLECT_EXPORT_START(CInterface3DShape, CInterfaceElement) REFLECT_EXPORT_START(CInterface3DShape, CInterfaceElement)
REFLECT_FLOAT("getBBoxSizeX", getBBoxSizeX, setPosX); REFLECT_FLOAT("getBBoxSizeX", getBBoxSizeX, setPosX);
REFLECT_FLOAT("getBBoxSizeY", getBBoxSizeY, setPosX); REFLECT_FLOAT("getBBoxSizeY", getBBoxSizeY, setPosX);
@ -285,7 +281,6 @@ public:
REFLECT_FLOAT ("roty", getRotY, setRotY); REFLECT_FLOAT ("roty", getRotY, setRotY);
REFLECT_FLOAT ("rotz", getRotZ, setRotZ); REFLECT_FLOAT ("rotz", getRotZ, setRotZ);
REFLECT_STRING ("name", getName, setName); REFLECT_STRING ("name", getName, setName);
REFLECT_STRING("textures", getTextures, setTextures);
REFLECT_EXPORT_END REFLECT_EXPORT_END
protected: protected:
@ -294,7 +289,6 @@ protected:
NLMISC::CVector _Pos; NLMISC::CVector _Pos;
NLMISC::CVector _Rot; NLMISC::CVector _Rot;
std::string _Name; std::string _Name;
std::string _Textures;
}; };
/** /**
@ -403,15 +397,6 @@ public:
float getTgtY() const { return _Target.y; } float getTgtY() const { return _Target.y; }
float getTgtZ() const { return _Target.z; } float getTgtZ() const { return _Target.z; }
float getRotZ() const { return _Rot.z; }
void setRotZ(float f) { _Rot.z = f; }
float getRotY() const { return _Rot.y; }
void setRotY(float f) { _Rot.y = f; }
float getDist() const { return _Dist; }
void setDist(float f) { _Dist = f; }
REFLECT_EXPORT_START(CInterface3DCamera, CInterfaceElement) REFLECT_EXPORT_START(CInterface3DCamera, CInterfaceElement)
REFLECT_FLOAT ("posx", getPosX, setPosX); REFLECT_FLOAT ("posx", getPosX, setPosX);
REFLECT_FLOAT ("posy", getPosY, setPosY); REFLECT_FLOAT ("posy", getPosY, setPosY);
@ -419,13 +404,19 @@ public:
REFLECT_FLOAT ("tgtx", getTgtX, setTgtX); REFLECT_FLOAT ("tgtx", getTgtX, setTgtX);
REFLECT_FLOAT ("tgty", getTgtY, setTgtY); REFLECT_FLOAT ("tgty", getTgtY, setTgtY);
REFLECT_FLOAT ("tgtz", getTgtZ, setTgtZ); REFLECT_FLOAT ("tgtz", getTgtZ, setTgtZ);
REFLECT_FLOAT ("rotz", getRotZ, setRotZ);
REFLECT_FLOAT ("roty", getRotY, setRotY);
REFLECT_FLOAT ("dist", getDist, setDist);
REFLECT_FLOAT ("fov", getFOV, setFOV); REFLECT_FLOAT ("fov", getFOV, setFOV);
REFLECT_FLOAT ("roll", getRoll, setRoll); REFLECT_FLOAT ("roll", getRoll, setRoll);
REFLECT_EXPORT_END REFLECT_EXPORT_END
float getRotZ() const { return _Rot.z; }
void setRotZ(float f) { _Rot.z = f; }
float getRotY() const { return _Rot.y; }
void setRotY(float f) { _Rot.y = f; }
float getDist() const { return _Dist; }
void setDist(float f) { _Dist = f; }
void reset(); // Reset user interaction void reset(); // Reset user interaction
protected: protected:

@ -799,11 +799,7 @@ static DECLARE_INTERFACE_USER_FCT(getAnimalInventoryStateText)
// According to server status, change the inventory text // According to server status, change the inventory text
uint status= (uint)args[0].getInteger(); uint status= (uint)args[0].getInteger();
if(ANIMAL_STATUS::isInBag((ANIMAL_STATUS::EAnimalStatus)status)) if(ANIMAL_STATUS::isInStable((ANIMAL_STATUS::EAnimalStatus)status))
{
result.setString("uiAnimalInBag");
}
else if(ANIMAL_STATUS::isInStable((ANIMAL_STATUS::EAnimalStatus)status))
{ {
result.setString("uiAnimalInStable"); result.setString("uiAnimalInStable");
} }

@ -1899,12 +1899,9 @@ bool CInterfaceManager::loadConfig (const string &filename)
// NB: we are typically InGame here (even though the _InGame flag is not yet set) // NB: we are typically InGame here (even though the _InGame flag is not yet set)
// Use the screen size of the config file. Don't update current UI, just _Modes // Use the screen size of the config file. Don't update current UI, just _Modes
// //
uint32 width, height; // ClientCfg has W/H set to screen size, but interface expects scaled size
// get non-scaled width/height sint32 scaledW = ClientCfg.Width / ClientCfg.InterfaceScale;
Driver->getWindowSize(width, height); sint32 scaledH = ClientCfg.Height / ClientCfg.InterfaceScale;
// convert to scaled width/height for ui
sint32 scaledW = width / ClientCfg.InterfaceScale;
sint32 scaledH = height / ClientCfg.InterfaceScale;
CWidgetManager::getInstance()->moveAllWindowsToNewScreenSize(scaledW, scaledH, false); CWidgetManager::getInstance()->moveAllWindowsToNewScreenSize(scaledW, scaledH, false);
updateDesktops(scaledW, scaledH); updateDesktops(scaledW, scaledH);
} }

@ -2903,6 +2903,32 @@ class CHandlerInvCanDropTo : public IActionHandler
if ((pListDstText != NULL) || (pListDstIcon != NULL)) if ((pListDstText != NULL) || (pListDstIcon != NULL))
{ {
bool bCanDrop = true; bool bCanDrop = true;
// WE CANT DND if we want to dnd from other bag than BAG to guild bag
if (pListDstIcon != NULL)
{
if (pListDstIcon->getInvType() == CInventoryManager::InvGuild)
if (strnicmp(pCSSrc->getSheet().c_str(),"LOCAL:INVENTORY:BAG", 19) != 0)
bCanDrop = false;
}
if (pListDstText != NULL)
{
if (pListDstText->getInvType() == CInventoryManager::InvGuild)
if (strnicmp(pCSSrc->getSheet().c_str(),"LOCAL:INVENTORY:BAG", 19) != 0)
bCanDrop = false;
}
// WE CANT DND if we want to dnd from guild bag to other bag than BAG
if (pListDstIcon != NULL)
{
if (pListDstIcon->getInvType() != CInventoryManager::InvBag)
if (strnicmp(pCSSrc->getSheet().c_str(),"SERVER:GUILD:INVENTORY", 19) == 0)
bCanDrop = false;
}
if (pListDstText != NULL)
{
if (pListDstText->getInvType() != CInventoryManager::InvBag)
if (strnicmp(pCSSrc->getSheet().c_str(),"SERVER:GUILD:INVENTORY", 19) == 0)
bCanDrop = false;
}
// WE CANT DND when packer/mount is too far // WE CANT DND when packer/mount is too far
if (pListDstIcon != NULL) if (pListDstIcon != NULL)
@ -3074,6 +3100,7 @@ class CHandlerInvDropTo : public IActionHandler
else if (((pListDstText != NULL) && (pListDstText->getInvType() == CInventoryManager::InvGuild)) || else if (((pListDstText != NULL) && (pListDstText->getInvType() == CInventoryManager::InvGuild)) ||
((pListDstIcon != NULL) && (pListDstIcon->getInvType() == CInventoryManager::InvGuild))) ((pListDstIcon != NULL) && (pListDstIcon->getInvType() == CInventoryManager::InvGuild)))
{ {
if (strnicmp(pCSSrc->getSheet().c_str(), "LOCAL:INVENTORY:BAG", 19) == 0)
CAHManager::getInstance()->runActionHandler("proc", pCSSrc, "move_to_guild"); CAHManager::getInstance()->runActionHandler("proc", pCSSrc, "move_to_guild");
} }
else if (((pListDstText != NULL) && (pListDstText->getInvType() == CInventoryManager::InvRoom)) || else if (((pListDstText != NULL) && (pListDstText->getInvType() == CInventoryManager::InvRoom)) ||

@ -41,12 +41,6 @@
# define assert(x) # define assert(x)
#endif #endif
// Always use unique_ptr with ValyriaTear/luabind on Ubuntu 20,
// since the setting is not stored in build_information.hpp
#ifndef LUABIND_USE_CXX11
#define LUABIND_USE_CXX11
#endif
#include <luabind/luabind.hpp> #include <luabind/luabind.hpp>
// in luabind > 0.6, LUABIND_MAX_ARITY is set to 10 // in luabind > 0.6, LUABIND_MAX_ARITY is set to 10
#if LUABIND_MAX_ARITY == 10 #if LUABIND_MAX_ARITY == 10
@ -2420,13 +2414,15 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
texture = ""; texture = "";
} }
std::vector<string>texList;
if (!texture.empty())
splitString(texture, " ", texList);
for(uint j=0;j<instance.getNumMaterials();j++) for(uint j=0;j<instance.getNumMaterials();j++)
{ {
if (highlight) if (!highlight)
{
/*instance.getMaterial(j).setAmbient(CRGBA(0,0,0,255));
instance.getMaterial(j).setEmissive(CRGBA(255,255,255,255));
instance.getMaterial(j).setShininess(10.0f);*/
}
else
{ {
instance.getMaterial(j).setAmbient(CRGBA(0,0,0,255)); instance.getMaterial(j).setAmbient(CRGBA(0,0,0,255));
instance.getMaterial(j).setEmissive(CRGBA(255,0,0,255)); instance.getMaterial(j).setEmissive(CRGBA(255,0,0,255));
@ -2439,7 +2435,9 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
for(sint l = 0; l < numStages; l++) for(sint l = 0; l < numStages; l++)
{ {
if (instance.getMaterial(j).isTextureFile((uint) l)) if (instance.getMaterial(j).isTextureFile((uint) l))
instance.getMaterial(j).setTextureFileName(texList[std::min((int)j, (int)texList.size()-1)], (uint) l); {
instance.getMaterial(j).setTextureFileName(texture, (uint) l);
}
} }
} }
} }

@ -798,7 +798,7 @@ void CSPhraseManager::buildPhraseFromSheet(CSPhraseCom &phrase, sint32 sheetI
if(phraseSheet) if(phraseSheet)
{ {
// get localized Name // get localized Name
phrase.Name.fromUtf8(STRING_MANAGER::CStringManagerClient::getSPhraseLocalizedName(CSheetId(sheetId))); phrase.Name= STRING_MANAGER::CStringManagerClient::getSPhraseLocalizedName(CSheetId(sheetId));
// Build bricks // Build bricks
phrase.Bricks.clear(); phrase.Bricks.clear();
for(uint i=0;i<phraseSheet->Bricks.size();i++) for(uint i=0;i<phraseSheet->Bricks.size();i++)

@ -2218,7 +2218,6 @@ class CAHLessLod : public IActionHandler
REGISTER_ACTION_HANDLER (CAHLessLod, "less_lod"); REGISTER_ACTION_HANDLER (CAHLessLod, "less_lod");
// *************************************************************************** // ***************************************************************************
// TODO: remove resolution change from login screen
class CAHUninitResLod : public IActionHandler class CAHUninitResLod : public IActionHandler
{ {
virtual void execute (CCtrlBase * /* pCaller */, const string &/* sParams */) virtual void execute (CCtrlBase * /* pCaller */, const string &/* sParams */)
@ -2843,7 +2842,7 @@ string checkLogin(const string &login, const string &password, const string &cli
{ {
// ask server for salt // ask server for salt
if(!HttpClient.sendGet(url + "?cmd=ask&cp=2&login=" + login + "&lg=" + ClientCfg.LanguageCode, "", pPM->isVerboseLog())) if(!HttpClient.sendGet(url + "?cmd=ask&cp=2&login=" + login + "&lg=" + ClientCfg.LanguageCode, "", pPM->isVerboseLog()))
return std::string("Can't send (error code 60) ") + HttpClient.lastError(); return "Can't send (error code 60)";
if(pPM->isVerboseLog()) nlinfo("Sent request for password salt"); if(pPM->isVerboseLog()) nlinfo("Sent request for password salt");
@ -2917,13 +2916,13 @@ string checkLogin(const string &login, const string &password, const string &cli
std::string cryptedPassword = CCrypt::crypt(password, Salt); std::string cryptedPassword = CCrypt::crypt(password, Salt);
if(!HttpClient.sendGet(url + "?cmd=login&login=" + login + "&password=" + cryptedPassword + "&clientApplication=" + clientApp + "&cp=2" + "&lg=" + ClientCfg.LanguageCode + customParameters)) if(!HttpClient.sendGet(url + "?cmd=login&login=" + login + "&password=" + cryptedPassword + "&clientApplication=" + clientApp + "&cp=2" + "&lg=" + ClientCfg.LanguageCode + customParameters))
return std::string("Can't send (error code 2) ") + HttpClient.lastError(); return "Can't send (error code 2)";
} }
else else
{ {
// don't send login and password if empty // don't send login and password if empty
if(!HttpClient.sendGet(url + "?cmd=login&clientApplication=" + clientApp + "&cp=2" + "&lg=" + ClientCfg.LanguageCode + customParameters)) if(!HttpClient.sendGet(url + "?cmd=login&clientApplication=" + clientApp + "&cp=2" + "&lg=" + ClientCfg.LanguageCode + customParameters))
return std::string("Can't send (error code 2) ") + HttpClient.lastError(); return "Can't send (error code 2)";
} }
// the response should contains the result code and the cookie value // the response should contains the result code and the cookie value
@ -3033,7 +3032,7 @@ string checkLogin(const string &login, const string &password, const string &cli
std::string cryptedPassword = CCrypt::crypt(password, Salt); std::string cryptedPassword = CCrypt::crypt(password, Salt);
if(!HttpClient.sendGet(url + "?login=" + login + "&password=" + cryptedPassword + "&clientApplication=" + clientApp + "&cp=2")) if(!HttpClient.sendGet(url + "?login=" + login + "&password=" + cryptedPassword + "&clientApplication=" + clientApp + "&cp=2"))
return std::string("Can't send (error code 2) ") + HttpClient.lastError(); return "Can't send (error code 2)";
/* /*
if(!send(ClientCfg.ConfigFile.getVar("StartupPage").asString()+"?login="+login+"&password="+password+"&clientApplication="+clientApp)) if(!send(ClientCfg.ConfigFile.getVar("StartupPage").asString()+"?login="+login+"&password="+password+"&clientApplication="+clientApp))
return "Can't send (error code 2)"; return "Can't send (error code 2)";

@ -2605,7 +2605,7 @@ public:
} }
}; };
void stopSoundMngr();
// **************************************************************************** // ****************************************************************************
void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
@ -2618,12 +2618,6 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
// Destination File Name (in writable directory) // Destination File Name (in writable directory)
string DestinationName; string DestinationName;
if (NLMISC::startsWith(rFTP.FileName, "sound"))
{
// Stop sound playback
stopSoundMngr();
}
if (rFTP.ExtractPath.empty()) if (rFTP.ExtractPath.empty())
{ {
DestinationName = pPM->WritableClientDataPath + rFTP.FileName; DestinationName = pPM->WritableClientDataPath + rFTP.FileName;

@ -1000,6 +1000,9 @@ bool mainLoop()
// initialize the structure for the ping. // initialize the structure for the ping.
Ping.init(); Ping.init();
// initialize screenshots directory
initScreenshot();
// Call a function for a demo to init. // Call a function for a demo to init.
if (ClientCfg.Local) if (ClientCfg.Local)

@ -76,7 +76,7 @@ void updateFromClientCfg()
// set latest config display mode if not attached // set latest config display mode if not attached
if (!StereoDisplayAttached) if (!StereoDisplayAttached)
setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth,
ClientCfg.Windowed, ClientCfg.Frequency, -1, ClientCfg.MonitorName)); ClientCfg.Windowed, ClientCfg.Frequency));
// force software cursor when attached // force software cursor when attached
InitMouseWithCursor(ClientCfg.HardwareCursor && !StereoDisplayAttached); InitMouseWithCursor(ClientCfg.HardwareCursor && !StereoDisplayAttached);
} }
@ -87,13 +87,12 @@ void updateFromClientCfg()
(ClientCfg.Width != LastClientCfg.Width) || (ClientCfg.Width != LastClientCfg.Width) ||
(ClientCfg.Height != LastClientCfg.Height) || (ClientCfg.Height != LastClientCfg.Height) ||
(ClientCfg.Depth != LastClientCfg.Depth) || (ClientCfg.Depth != LastClientCfg.Depth) ||
(ClientCfg.Frequency != LastClientCfg.Frequency)|| (ClientCfg.Frequency != LastClientCfg.Frequency))
(ClientCfg.MonitorName != LastClientCfg.MonitorName))
{ {
if (!StereoDisplayAttached) if (!StereoDisplayAttached)
{ {
setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth,
ClientCfg.Windowed, ClientCfg.Frequency, -1, ClientCfg.MonitorName)); ClientCfg.Windowed, ClientCfg.Frequency));
} }
} }

@ -1408,7 +1408,6 @@ bool getRyzomModes(std::vector<NL3D::UDriver::CMode> &videoModes, std::vector<st
// **** Init Video Modes // **** Init Video Modes
Driver->getModes(videoModes); Driver->getModes(videoModes);
// TODO: for resolutions below 1024x768, could use automatic UI scaling like in login/outgame
// Remove modes under 1024x768 (outgame ui limitation) and get the unique strings // Remove modes under 1024x768 (outgame ui limitation) and get the unique strings
sint i, j; sint i, j;
for (i = 0; i < (sint)videoModes.size(); ++i) for (i = 0; i < (sint)videoModes.size(); ++i)
@ -1425,9 +1424,6 @@ bool getRyzomModes(std::vector<NL3D::UDriver::CMode> &videoModes, std::vector<st
// create string format with width and height // create string format with width and height
string res = toString(videoModes[i].Width)+" x "+toString(videoModes[i].Height); string res = toString(videoModes[i].Width)+" x "+toString(videoModes[i].Height);
if (!videoModes[i].DisplayDevice.empty())
res += toString(" (%s)", videoModes[i].DisplayDevice.c_str());
// check if video mode already found in list // check if video mode already found in list
for (j = 0; j < (sint)stringModeList.size(); ++j) for (j = 0; j < (sint)stringModeList.size(); ++j)
{ {

@ -468,7 +468,9 @@ void CSoundManager::init(IProgressCallback *progressCallBack)
_AudioMixer->setPackedSheetOption("", false); _AudioMixer->setPackedSheetOption("", false);
UAudioMixer::TDriver driverType= UAudioMixer::DriverAuto; UAudioMixer::TDriver driverType= UAudioMixer::DriverAuto;
if(ClientCfg.DriverSound==CClientConfig::SoundDrvOpenAL) if(ClientCfg.DriverSound==CClientConfig::SoundDrvFMod)
driverType= UAudioMixer::DriverFMod;
else if(ClientCfg.DriverSound==CClientConfig::SoundDrvOpenAL)
driverType= UAudioMixer::DriverOpenAl; driverType= UAudioMixer::DriverOpenAl;
else if(ClientCfg.DriverSound==CClientConfig::SoundDrvDirectSound) else if(ClientCfg.DriverSound==CClientConfig::SoundDrvDirectSound)
driverType= UAudioMixer::DriverDSound; driverType= UAudioMixer::DriverDSound;

@ -1630,7 +1630,7 @@ const char *CStringManagerClient::getSPhraseLocalizedDescription(NLMISC::CSheetI
const char *CStringManagerClient::getTitleLocalizedName(const string &titleId, bool women) const char *CStringManagerClient::getTitleLocalizedName(const string &titleId, bool women)
{ {
vector<string> listInfos = getTitleInfos(titleId, women); vector<string> listInfos = getTitleInfos(titleId, women);
if (!listInfos.empty()) if (!listInfos.empty())
{ {
_TitleWords.push_back(listInfos[0]); _TitleWords.push_back(listInfos[0]);
@ -1681,19 +1681,7 @@ vector<string> CStringManagerClient::getTitleInfos(const string &titleId, bool w
{ {
if (titleId[0] != '#') if (titleId[0] != '#')
{ {
// Check special case like SON_OF|jane|joe (with SON_OF = "Son of {1} and {2}") listInfos[0] = getSpecialWord(listInfos[0], women);
vector<string> titleReps;
splitString(listInfos[0], string("|"), titleReps);
if (titleReps.size() > 1)
{
listInfos[0] = getSpecialWord(titleReps[0], women);
for(uint i=1; i < titleReps.size(); ++i )
{
while(strFindReplace(listInfos[0], toString("{%d}", i), titleReps[i]));
}
}
else
listInfos[0] = getSpecialWord(listInfos[0], women);
} }
} }

@ -153,7 +153,7 @@ CUserEntity::CUserEntity()
_LateralVelocity = 0.0f; _LateralVelocity = 0.0f;
_SpeedServerAdjust = 1.0f; _SpeedServerAdjust = 1.0f;
// \todo GUIGUI : do it more generic. // \todo GUIGUI : do it more generic.
_First_Pos = false; _First_Pos = false;
@ -186,7 +186,7 @@ CUserEntity::CUserEntity()
_MoveToAction= CUserEntity::None; _MoveToAction= CUserEntity::None;
_MoveToDist= 0.0; _MoveToDist= 0.0;
_MoveToColStartTime= 0; _MoveToColStartTime= 0;
_HeadPitch = Pi/2;
_FollowForceHeadPitch= false; _FollowForceHeadPitch= false;
_ForceLookSlot= CLFECOMMON::INVALID_SLOT; _ForceLookSlot= CLFECOMMON::INVALID_SLOT;
@ -209,7 +209,7 @@ CUserEntity::~CUserEntity()
_MountSpeeds.release(); _MountSpeeds.release();
CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceManager *pIM = CInterfaceManager::getInstance();
{ {
CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:USER:IS_INVISIBLE", false); CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:USER:IS_INVISIBLE", false);
if (node) if (node)
@ -491,8 +491,8 @@ void CUserEntity::updateVisualPropertyBehaviour(const NLMISC::TGameCycle &/* gam
} }
CCDBNodeLeaf *targetList0 = dynamic_cast<CCDBNodeLeaf *>(_DBEntry->getNode(CLFECOMMON::PROPERTY_TARGET_LIST_0)); CCDBNodeLeaf *targetList0 = dynamic_cast<CCDBNodeLeaf *>(_DBEntry->getNode(CLFECOMMON::PROPERTY_TARGET_LIST_0));
CCDBNodeLeaf *targetList1 = dynamic_cast<CCDBNodeLeaf *>(_DBEntry->getNode(CLFECOMMON::PROPERTY_TARGET_LIST_1)); CCDBNodeLeaf *targetList1 = dynamic_cast<CCDBNodeLeaf *>(_DBEntry->getNode(CLFECOMMON::PROPERTY_TARGET_LIST_1));
CCDBNodeLeaf *targetList2 = dynamic_cast<CCDBNodeLeaf *>(_DBEntry->getNode(CLFECOMMON::PROPERTY_TARGET_LIST_2)); CCDBNodeLeaf *targetList2 = dynamic_cast<CCDBNodeLeaf *>(_DBEntry->getNode(CLFECOMMON::PROPERTY_TARGET_LIST_1));
CCDBNodeLeaf *targetList3 = dynamic_cast<CCDBNodeLeaf *>(_DBEntry->getNode(CLFECOMMON::PROPERTY_TARGET_LIST_3)); CCDBNodeLeaf *targetList3 = dynamic_cast<CCDBNodeLeaf *>(_DBEntry->getNode(CLFECOMMON::PROPERTY_TARGET_LIST_1));
if (targetList0 && targetList1 && targetList2 && targetList3) if (targetList0 && targetList1 && targetList2 && targetList3)
{ {
uint64 vp[4] = uint64 vp[4] =
@ -1220,7 +1220,7 @@ void CUserEntity::applyMotion(CEntityCL *target)
speed = getVelocity()*_SpeedFactor.getValue(); speed = getVelocity()*_SpeedFactor.getValue();
_SpeedFactor.addFactorValue(0.005f); _SpeedFactor.addFactorValue(0.005f);
} }
// SPEED VECTOR NULL -> NO MOVE // SPEED VECTOR NULL -> NO MOVE
if(speed == CVectorD::Null) if(speed == CVectorD::Null)
return; return;
@ -1402,6 +1402,18 @@ void CUserEntity::moveToCheckStartDist(CLFECOMMON::TCLEntityId slot, double dist
// disable afk mode // disable afk mode
setAFK(false); setAFK(false);
// if sufficiently near, launch the action
CEntityCL *target = EntitiesMngr.entity(slot);
if(target)
{
CVectorD dir2targ = target->pos() - pos();
dir2targ.z = 0.0;
if((dir2targ==CVectorD::Null) || (dir2targ.norm() < dist))
{
moveToAction(target);
}
}
} }
}// moveToCheckStartDist // }// moveToCheckStartDist //
@ -1674,11 +1686,11 @@ void CUserEntity::moveToAction(CEntityCL *ent)
case CUserEntity::Outpost: case CUserEntity::Outpost:
CLuaManager::getInstance().executeLuaScript("game:outpostBCOpenStateWindow()", 0); CLuaManager::getInstance().executeLuaScript("game:outpostBCOpenStateWindow()", 0);
break; break;
// BuildTotem // BuildTotem
case CUserEntity::BuildTotem: case CUserEntity::BuildTotem:
buildTotem(); buildTotem();
break; break;
// openArkUrl // openArkUrl
case CUserEntity::OpenArkUrl: case CUserEntity::OpenArkUrl:
CLuaManager::getInstance().executeLuaScript("getUI('ui:interface:web_transactions'):find('html'):browse(ArkTargetUrl)", 0); CLuaManager::getInstance().executeLuaScript("getUI('ui:interface:web_transactions'):find('html'):browse(ArkTargetUrl)", 0);
break; break;
@ -2552,9 +2564,9 @@ void CUserEntity::rotHeadVertically(float ang)
//----------------------------------------------- //-----------------------------------------------
void CUserEntity::setHeadPitch(double hp) void CUserEntity::setHeadPitch(double hp)
{ {
_HeadPitch = hp; _HeadPitch= hp;
// epsilon to avoid gimbal lock const double bound= Pi/2 - 0.01; // epsilon to avoid gimbal lock
clamp(_HeadPitch, -Pi/2 + 0.01, Pi/2 - 0.5); clamp(_HeadPitch, -bound, bound);
} }
//--------------------------------------------------- //---------------------------------------------------
@ -3616,7 +3628,7 @@ void CUserEntity::CSpeedFactor::update(ICDBNode *node) // virtual
CCDBNodeLeaf *leaf = safe_cast<CCDBNodeLeaf *>(node); CCDBNodeLeaf *leaf = safe_cast<CCDBNodeLeaf *>(node);
_Value = ((float)leaf->getValue64())/100.0f; _Value = ((float)leaf->getValue64())/100.0f;
//nlinfo("SpeedFactor changed to %f / %" NL_I64 "u", _Value, leaf->getValue64()); //nlinfo("SpeedFactor changed to %f / %" NL_I64 "u", _Value, leaf->getValue64());
// clamp the value (2.0 is the egg item or the level 6 speed up power up, nothing should be faster) // clamp the value (2.0 is the egg item or the level 6 speed up power up, nothing should be faster)
// commented because ring editor speed is in fact faster // commented because ring editor speed is in fact faster
//if(_Value > 2.0f) //if(_Value > 2.0f)

@ -19,22 +19,7 @@
<!-- ##### Root template matcher ####### --> <!-- ##### Root template matcher ####### -->
<!-- ######################################################### --> <!-- ######################################################### -->
<xsl:template match="generator"> <xsl:template match="generator">
<xsl:if test="$output != 'php'">// Ryzom - MMORPG Framework &lt;http://dev.ryzom.com/projects/ryzom/&gt; <xsl:if test="$output != 'php'">
// Copyright (C) 2010-2021 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// WARNING : this is a generated file, don't change it ! // WARNING : this is a generated file, don't change it !
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
@ -1691,14 +1676,13 @@ namespace <xsl:value-of select="@name"/>
<xsl:for-each select="child_class[@on-delete = 'cascade' and @cont='vector']"> <xsl:for-each select="child_class[@on-delete = 'cascade' and @cont='vector']">
{ {
// cascading deletion for vector child <xsl:value-of select="@name"/> // cascading deletion for vector child <xsl:value-of select="@name"/>
if (load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__)) nlassert(load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__));
{
const std::vector &lt; <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
while (!childs.empty()) const std::vector &lt; <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
{
get<xsl:value-of select="@name"/>ByIndex((uint32)childs.size()-1)->remove(connection); while (!childs.empty())
} {
get<xsl:value-of select="@name"/>ByIndex(childs.size()-1)->remove(connection);
} }
} }
@ -1706,77 +1690,72 @@ namespace <xsl:value-of select="@name"/>
<xsl:for-each select="child_class[@on-delete = 'cascade' and @cont='map']"> <xsl:for-each select="child_class[@on-delete = 'cascade' and @cont='map']">
{ {
// cascading deletion for map child <xsl:value-of select="@name"/> // cascading deletion for map child <xsl:value-of select="@name"/>
if (load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__)) nlassert(load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__));
{
const std::map &lt; uint32, <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
while (!childs.empty()) const std::map &lt; uint32, <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
{
get<xsl:value-of select="@name"/>ById(childs.begin()->first)->remove(connection); while (!childs.empty())
} {
get<xsl:value-of select="@name"/>ById(childs.begin()->first)->remove(connection);
} }
} }
</xsl:for-each> </xsl:for-each>
<xsl:for-each select="child_class[@on-delete = 'cascade' and @relation='one-to-one']"> <xsl:for-each select="child_class[@on-delete = 'cascade' and @relation='one-to-one']">
{ {
// cascading deletion for single child <xsl:value-of select="@name"/> // cascading deletion for single child <xsl:value-of select="@name"/>
if (load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__)) nlassert(load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__));
{
if (get<xsl:value-of select="@name"/>() != NULL) if (get<xsl:value-of select="@name"/>() != NULL)
get<xsl:value-of select="@name"/>()->remove(connection); get<xsl:value-of select="@name"/>()->remove(connection);
}
} }
</xsl:for-each> </xsl:for-each>
<xsl:for-each select="child_class[@on-delete = 'update' and @cont='vector']"> <xsl:for-each select="child_class[@on-delete = 'update' and @cont='vector']">
{ {
// unreference (and update) for vector child <xsl:value-of select="@name"/> // unreference (and update) for vector child <xsl:value-of select="@name"/>
if (load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__)) nlassert(load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__));
{
const std::vector &lt; <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
for (uint i=0; i &lt; childs.size(); ++i) const std::vector &lt; <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
{
<xsl:variable name="type" select="@type"/> for (uint i=0; i &lt; childs.size(); ++i)
<xsl:variable name="child_name" select="@name"/> {
<xsl:variable name="parent_prop" select="//class[@name = $type]/property[@db_col = //class[@name = $type]/parent[@class = $className]/@db_col]/@name"/> <xsl:variable name="type" select="@type"/>
get<xsl:value-of select="@name"/>ByIndex(i)->set<xsl:value-of select="$parent_prop"/>(0); <xsl:variable name="child_name" select="@name"/>
get<xsl:value-of select="@name"/>ByIndex(i)->update(connection); <xsl:variable name="parent_prop" select="//class[@name = $type]/property[@db_col = //class[@name = $type]/parent[@class = $className]/@db_col]/@name"/>
} get<xsl:value-of select="@name"/>ByIndex(i)->set<xsl:value-of select="$parent_prop"/>(0);
get<xsl:value-of select="@name"/>ByIndex(i)->update(connection);
} }
} }
</xsl:for-each> </xsl:for-each>
<xsl:for-each select="child_class[@on-delete = 'update' and @cont='map']"> <xsl:for-each select="child_class[@on-delete = 'update' and @cont='map']">
{ {
// unreference (and update) for map child <xsl:value-of select="@name"/> // unreference (and update) for map child <xsl:value-of select="@name"/>
if (load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__)) { nlassert(load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__));
const std::map &lt; uint32, <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>(); const std::map &lt; uint32, <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
std::map&lt; uint32, <xsl:value-of select="@type"/>Ptr &gt;::const_iterator first(childs.begin()), last(childs.end()); std::map&lt; uint32, <xsl:value-of select="@type"/>Ptr &gt;::const_iterator first(childs.begin()), last(childs.end());
for (; first != last; ++first) for (; first != last; ++first)
{ {
<xsl:variable name="type" select="@type"/> <xsl:variable name="type" select="@type"/>
<xsl:variable name="child_name" select="@name"/> <xsl:variable name="child_name" select="@name"/>
<xsl:variable name="parent_prop" select="//class[@name = $type]/property[@db_col = //class[@name = $type]/parent[@class = $className]/@db_col]/@name"/> <xsl:variable name="parent_prop" select="//class[@name = $type]/property[@db_col = //class[@name = $type]/parent[@class = $className]/@db_col]/@name"/>
get<xsl:value-of select="@name"/>ById(it->first)->set<xsl:value-of select="$parent_prop"/>(0); get<xsl:value-of select="@name"/>ById(it->first)->set<xsl:value-of select="$parent_prop"/>(0);
get<xsl:value-of select="@name"/>ById(it->first)->update(connection); get<xsl:value-of select="@name"/>ById(it->first)->update(connection);
}
} }
} }
</xsl:for-each> </xsl:for-each>
<xsl:for-each select="child_class[@on-delete = 'update' and @relation='one-to-one']"> <xsl:for-each select="child_class[@on-delete = 'update' and @relation='one-to-one']">
{ {
// unreference (and update) for single child <xsl:value-of select="@name"/> // unreference (and update) for single child <xsl:value-of select="@name"/>
if (load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__)) nlassert(load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__));
<xsl:variable name="type" select="@type"/>
<xsl:variable name="child_name" select="@name"/>
<xsl:variable name="parent_prop" select="//class[@name = $type]/property[@db_col = //class[@name = $type]/parent[@class = $className]/@db_col]/@name"/>
if (get<xsl:value-of select="@name"/>() != NULL)
{ {
<xsl:variable name="type" select="@type"/> get<xsl:value-of select="@name"/>()->set<xsl:value-of select="parent_prop"/>(0);
<xsl:variable name="child_name" select="@name"/> get<xsl:value-of select="@name"/>()->update(connection);
<xsl:variable name="parent_prop" select="//class[@name = $type]/property[@db_col = //class[@name = $type]/parent[@class = $className]/@db_col]/@name"/>
if (get<xsl:value-of select="@name"/>() != NULL)
{
get<xsl:value-of select="@name"/>()->set<xsl:value-of select="parent_prop"/>(0);
get<xsl:value-of select="@name"/>()->update(connection);
}
} }
} }
</xsl:for-each> </xsl:for-each>
@ -1907,7 +1886,7 @@ namespace <xsl:value-of select="@name"/>
} }
else if (cmd == NOPE::cc_instance_count) else if (cmd == NOPE::cc_instance_count)
{ {
return (uint32)_ObjectCache.size(); return _ObjectCache.size();
} }
// default return value // default return value
@ -1925,7 +1904,7 @@ namespace <xsl:value-of select="@name"/>
TReleasedObject::iterator first(_ReleasedObject.begin()), last(_ReleasedObject.end()); TReleasedObject::iterator first(_ReleasedObject.begin()), last(_ReleasedObject.end());
for (; first != last; ++first) for (; first != last; ++first)
{ {
nbReleased += (uint32)first->second.size(); nbReleased += first->second.size();
} }
nlinfo(" There are %u object instances in cache not referenced (waiting deletion or re-use))", nbReleased); nlinfo(" There are %u object instances in cache not referenced (waiting deletion or re-use))", nbReleased);
@ -2138,7 +2117,7 @@ ERROR : parent/child relation support only 'map' or 'vector' cont specification
return false; return false;
} }
CUniquePtr&lt;MSW::CStoreResult&gt; result(connection.storeResult()); std::auto_ptr&lt;MSW::CStoreResult&gt; result = connection.storeResult();
for (uint i=0; i&lt;result->getNumRows(); ++i) for (uint i=0; i&lt;result->getNumRows(); ++i)
{ {
@ -2216,7 +2195,7 @@ ERROR : parent/child relation support only 'map' or 'vector' cont specification
return false; return false;
} }
CUniquePtr&lt;MSW::CStoreResult&gt; result(connection.storeResult()); std::auto_ptr&lt;MSW::CStoreResult&gt; result = connection.storeResult();
// check that the data description is consistent with database content // check that the data description is consistent with database content
nlassert(result->getNumRows() &lt;= 1); nlassert(result->getNumRows() &lt;= 1);
@ -2321,9 +2300,9 @@ ERROR : parent/child relation support only 'map' or 'vector' cont specification
} }
// no object with this id, return a null pointer // no object with this id, return a null pointer
static <xsl:value-of select="@type"/>Ptr nilPtr; static <xsl:value-of select="@type"/>Ptr nil;
return nilPtr; return nil;
} }
</xsl:when> </xsl:when>
@ -2342,8 +2321,8 @@ ERROR : parent/child relation support only 'map' or 'vector' cont specification
if (it == _<xsl:value-of select="@name"/>->end()) if (it == _<xsl:value-of select="@name"/>->end())
{ {
// no object with this id, return a null pointer // no object with this id, return a null pointer
static <xsl:value-of select="@type"/>Ptr nilPtr; static <xsl:value-of select="@type"/>Ptr nil;
return nilPtr; return nil;
} }
return const_cast&lt; <xsl:value-of select="@type"/>Ptr &amp; &gt;(it->second); return const_cast&lt; <xsl:value-of select="@type"/>Ptr &amp; &gt;(it->second);

@ -22,16 +22,18 @@
// *********************************************************************** // ***********************************************************************
void CMultiTarget::pack(uint64 *destVP, uint numVP) void CMultiTarget::pack(uint64 *destVP, uint numVP)
{ {
nlassert(numVP * 2 >= Targets.size()); // not enough room to stores visual properties! nlassert(numVP * 4 >= Targets.size()); // not enough room to stores visual properties!
CTarget invalidTarget; CTarget invalidTarget;
uint index = 0; uint index = 0;
for(uint k = 0; k < numVP; ++k) for(uint k = 0; k < numVP; ++k)
{ {
destVP[k] = index < Targets.size() ? Targets[index].getPacked() : invalidTarget.getPacked(); uint16 parts[4];
++index; for(uint l = 0; l < 4; ++l)
{
destVP[k] |= uint64(index < Targets.size() ? Targets[index].getPacked() : invalidTarget.getPacked()) << 32; parts[l] = index < Targets.size() ? Targets[index].getPacked() : invalidTarget.getPacked();
++index; ++ index;
}
destVP[k] = (uint64) parts[0] | ((uint64) parts[1] << 16) | ((uint64) parts[2] << 32) | ((uint64) parts[3] << 48);
} }
} }
@ -41,15 +43,18 @@ void CMultiTarget::unpack(const uint64 *srcVP, uint numVP)
Targets.clear(); Targets.clear();
for(uint k = 0; k < numVP; ++k) for(uint k = 0; k < numVP; ++k)
{ {
CTarget t; for(uint l = 0; l < 4; ++l)
t.setPacked(uint32(srcVP[k])); {
if(t.TargetSlot == CLFECOMMON::INVALID_SLOT) CTarget t;
return; t.setPacked((uint16) ((srcVP[k] >> (16 * l)) & 0xffff));
Targets.push_back(t); if (t.TargetSlot != CLFECOMMON::INVALID_SLOT)
{
t.setPacked(uint32(srcVP[k] >> 32)); Targets.push_back(t);
if(t.TargetSlot == CLFECOMMON::INVALID_SLOT) }
return; else
Targets.push_back(t); {
return;
}
}
} }
} }

@ -39,21 +39,20 @@ public:
uint8 TargetSlot; // the slot that is targetted uint8 TargetSlot; // the slot that is targetted
uint8 Info; // Damage shield for melee 5:3 format (damage shield io : power ) uint8 Info; // Damage shield for melee 5:3 format (damage shield io : power )
// Distance for range attacks (that do not have damage shield) format is 7:1 // Distance for range attacks (that do not have damage shield) format is 7:1
sint16 DeltaHP; //
public: public:
CTarget(uint8 slot = CLFECOMMON::INVALID_SLOT, bool resist = false, uint8 dist = 0, sint16 deltaHp = 0) : TargetSlot(slot), DeltaHP(deltaHp) CTarget(uint8 slot = CLFECOMMON::INVALID_SLOT, bool resist = false, uint8 dist = 0) : TargetSlot(slot)
{ {
Info = (resist == 0 ? 0 : 0x80) | (dist & 0x7f); Info = (resist == 0 ? 0 : 0x80) | (dist & 0x7f);
} }
uint32 getPacked() const; uint16 getPacked() const;
void setPacked(uint32 value); void setPacked(uint16 value);
}; };
typedef std::vector<CTarget> TTargetVect; typedef std::vector<CTarget> TTargetVect;
// the list of targets // the list of targets
TTargetVect Targets; TTargetVect Targets;
public: public:
/** create packed version of targets (to store in visual properties) /** create packed version of targets (to store in visual properties)
* each VP encodes 2 targets * each VP encodes 4 targets
* caller must provide enough room to store the result (assertion is raised otherwise) * caller must provide enough room to store the result (assertion is raised otherwise)
*/ */
void pack(uint64 *destVP, uint numVP); void pack(uint64 *destVP, uint numVP);
@ -66,18 +65,19 @@ public:
//////////// ////////////
// ******************************************************************************************* // *******************************************************************************************
inline uint32 CMultiTarget::CTarget::getPacked() const inline uint16 CMultiTarget::CTarget::getPacked() const
{ {
//return (uint16) TargetSlot | ((uint16) (Resist ? 1 : 0) << 15) | ((uint16) Distance << 8); //return (uint16) TargetSlot | ((uint16) (Resist ? 1 : 0) << 15) | ((uint16) Distance << 8);
return ((uint32) TargetSlot) | ((uint32) Info << 8) | ((uint32) DeltaHP << 16); return (uint16) TargetSlot | (uint16(Info) << 8);
} }
// ******************************************************************************************* // *******************************************************************************************
inline void CMultiTarget::CTarget::setPacked(uint32 value) inline void CMultiTarget::CTarget::setPacked(uint16 value)
{ {
TargetSlot = uint8(value); TargetSlot = uint8(value & 0xff);
Info = uint8(value >> 8); /*Distance = (uint8) ((value >> 8) & 0x7f);
DeltaHP = sint16(value >> 16); Resist = (value & 0x8000) != 0;*/
Info = value >> 8;
} }
#endif #endif

@ -18,7 +18,6 @@
#define RYZOM_VERSION_H #define RYZOM_VERSION_H
#define RYZOM_VERSION "3.0.0" #define RYZOM_VERSION "3.0.0"
#define RYZOM_PRODUCT_VERSION "3.0.0"
#endif // RYZOM_VERSION_H #endif // RYZOM_VERSION_H

@ -37,10 +37,6 @@ void quitCrashReport()
{ {
} }
void stopSoundMngr()
{
}
/// domain server version for patch /// domain server version for patch
string R2ServerVersion; string R2ServerVersion;
/// name of the version (used to alias many version under the same name), /// name of the version (used to alias many version under the same name),

@ -30,13 +30,6 @@ extern "C"
#include <cassert> #include <cassert>
#undef assert #undef assert
#define assert nlassert #define assert nlassert
// Always use unique_ptr with ValyriaTear/luabind on Ubuntu 20,
// since the setting is not stored in build_information.hpp
#ifndef LUABIND_USE_CXX11
#define LUABIND_USE_CXX11
#endif
#include <luabind/luabind.hpp> #include <luabind/luabind.hpp>
using namespace std; using namespace std;

Loading…
Cancel
Save